From 9abe77a8dacd68ad83c35d681a83588d71d11da2 Mon Sep 17 00:00:00 2001 From: Cam Hutchison Date: Tue, 13 Jul 2021 21:11:11 +1000 Subject: [PATCH] cmd: Rename jx to jnx and split out flag version Rename `jx` to `jnx` as the jx binary name is already taken by jenkinsx. But jnx is also a better name since it sounds like jinx, and that's what you say when someone duplicates a word at the same time as you. jsonnet is about de-duplicating through templating, so jnx works. It can also be pronounced as a single syllable, which is also nice. Split the Go flag version of jnx into a completely separate program rather than having a `parseCLI()` function selected by build tags. The only reason for the flag version is to use the flag code path of jsonnext to demonstrate its use and to verify it works. jnx itself is going to evolve in future to contain subcommands which I do not intend to support in the flag version of jnx. So split it out so jnx can evolve on its own. Keep `jx.jsonnet` for now for backwards compatibility. It will be removed when I know I've removed all existing uses under that name. --- Makefile | 7 +- cmd/{jx => jnx}/doc.go | 4 +- cmd/jnx/jnxflag/main.go | 88 +++++++++++++++++++++++ cmd/{jx => jnx}/main.go | 12 ++-- cmd/jx/cli_flag.go | 26 ------- cmd/jx/cli_kong.go | 15 ---- kong/example_test.go | 8 +-- kong/kong_conformance_test.go | 4 +- lib/array_test.jsonnet | 2 +- lib/jnx.jsonnet | 9 +++ lib/{jx_test.jsonnet => jnx_test.jsonnet} | 12 ++-- lib/jx.jsonnet | 11 +-- lib/object_test.jsonnet | 2 +- lib/op_test.jsonnet | 2 +- lib/string_test.jsonnet | 2 +- lib/value_test.jsonnet | 2 +- 16 files changed, 128 insertions(+), 78 deletions(-) rename cmd/{jx => jnx}/doc.go (93%) create mode 100644 cmd/jnx/jnxflag/main.go rename cmd/{jx => jnx}/main.go (71%) delete mode 100644 cmd/jx/cli_flag.go delete mode 100644 cmd/jx/cli_kong.go create mode 100644 lib/jnx.jsonnet rename lib/{jx_test.jsonnet => jnx_test.jsonnet} (59%) diff --git a/Makefile b/Makefile index f635373..7775854 100644 --- a/Makefile +++ b/Makefile @@ -14,12 +14,11 @@ clean:: ## Remove generated files build: | $(O) ## Build binaries of directories in ./cmd to out/ go build -o $(O) ./cmd/... - go build -tags flag -o $(O)/jx-flag ./cmd/jx install: ## Build and install binaries in $GOBIN or $GOPATH/bin go install ./cmd/... -$(O)/jx: build +$(O)/jnx: build .PHONY: build install @@ -33,8 +32,8 @@ test: test-go test-jsonnet ## Run tests and generate a coverage file test-go: | $(O) go test -coverprofile=$(COVERFILE) ./... -test-jsonnet: $(O)/jx - $(O)/jx -J $(JSONNET_UNIT) lib/jx_test.jsonnet +test-jsonnet: $(O)/jnx + $(O)/jnx -J $(JSONNET_UNIT) lib/jnx_test.jsonnet check-coverage: test ## Check that test coverage meets the required level @go tool cover -func=$(COVERFILE) | $(CHECK_COVERAGE) || $(FAIL_COVERAGE) diff --git a/cmd/jx/doc.go b/cmd/jnx/doc.go similarity index 93% rename from cmd/jx/doc.go rename to cmd/jnx/doc.go index 8ebeeac..29d28ca 100644 --- a/cmd/jx/doc.go +++ b/cmd/jnx/doc.go @@ -1,6 +1,6 @@ -// jx evaluates a jsonnet file and outputs it as JSON. +// jnx evaluates a jsonnet file and outputs it as JSON. // -// Usage: jx [] +// Usage: jnx [] // // Arguments: // [] File to evaluate. stdin is used if omitted or "-" diff --git a/cmd/jnx/jnxflag/main.go b/cmd/jnx/jnxflag/main.go new file mode 100644 index 0000000..f28ca7f --- /dev/null +++ b/cmd/jnx/jnxflag/main.go @@ -0,0 +1,88 @@ +// jnxflag evaluates a jsonnet file and outputs it as JSON. +// +// Usage of ./jnxflag: +// -A var[=str] +// Add top-level arg var[=str] (from environment if is omitted) +// -J dir +// Add a library search dir +// -V var[=str] +// Add extVar var[=str] (from environment if is omitted) +// -ext-code var[=code] +// Add extVar var[=code] (from environment if is omitted) +// -ext-code-file var=file +// Add extVar var=file code from a file +// -ext-str var[=str] +// Add extVar var[=str] (from environment if is omitted) +// -ext-str-file var=file +// Add extVar var=file string from a file +// -jpath dir +// Add a library search dir +// -tla-code var[=code] +// Add top-level arg var[=code] (from environment if is omitted) +// -tla-code-file var=file +// Add top-level arg var=file code from a file +// -tla-str var=[=str] +// Add top-level arg var=[=str] (from environment if is omitted) +// -tla-str-file var=file +// Add top-level arg var=file string from a file +// +// This program exists just to implement the standard Go flag package parsing. +// The full jnx program uses the kong library and has more features. + +package main + +import ( + "flag" + "fmt" + "os" + + "foxygo.at/jsonnext" + jsonnet "github.com/google/go-jsonnet" +) + +type config struct { + jsonnext.Config + Filename string `arg:"" optional:"" help:"File to evaluate. stdin is used if omitted or \"-\""` +} + +func main() { + cli := parseCLI() + vm := cli.Config.MakeVM("JNXPATH") + + out, err := run(vm, cli.Filename) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + fmt.Print(out) +} + +// Parse CLI using Go's flag package and the helpers in jsonnext. +func parseCLI() *config { + c := &config{} + c.Config = *jsonnext.ConfigFlags(flag.CommandLine) + + flag.Parse() + if flag.NArg() > 1 { + flag.Usage() + os.Exit(1) + } else if flag.NArg() == 1 { + c.Filename = flag.Args()[0] + } + + return c +} + +func run(vm *jsonnet.VM, filename string) (string, error) { + node, _, err := vm.ImportAST("", filename) + if err != nil { + return "", err + } + + out, err := vm.Evaluate(node) + if err != nil { + return "", err + } + + return out, nil +} diff --git a/cmd/jx/main.go b/cmd/jnx/main.go similarity index 71% rename from cmd/jx/main.go rename to cmd/jnx/main.go index 2a086d4..d46eb71 100644 --- a/cmd/jx/main.go +++ b/cmd/jnx/main.go @@ -4,20 +4,22 @@ import ( "fmt" "os" - jxkong "foxygo.at/jsonnext/kong" + jnxkong "foxygo.at/jsonnext/kong" + "github.com/alecthomas/kong" jsonnet "github.com/google/go-jsonnet" ) type config struct { - jxkong.Config + jnxkong.Config Filename string `arg:"" optional:"" help:"File to evaluate. stdin is used if omitted or \"-\""` } func main() { - cli := parseCLI() - vm := cli.Config.MakeVM("JXPATH") + c := &config{Config: *jnxkong.NewConfig()} + kong.Parse(c) + vm := c.Config.MakeVM("JNXPATH") - out, err := run(vm, cli.Filename) + out, err := run(vm, c.Filename) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) diff --git a/cmd/jx/cli_flag.go b/cmd/jx/cli_flag.go deleted file mode 100644 index 3b0756b..0000000 --- a/cmd/jx/cli_flag.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build flag - -package main - -import ( - "flag" - "os" - - "foxygo.at/jsonnext" -) - -// Parse CLI using Go's flag package and the helpers in jsonnext. -func parseCLI() *config { - c := &config{} - c.Config.Config = jsonnext.ConfigFlags(flag.CommandLine) - - flag.Parse() - if flag.NArg() > 1 { - flag.Usage() - os.Exit(1) - } else if flag.NArg() == 1 { - c.Filename = flag.Args()[0] - } - - return c -} diff --git a/cmd/jx/cli_kong.go b/cmd/jx/cli_kong.go deleted file mode 100644 index c4f9969..0000000 --- a/cmd/jx/cli_kong.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build !flag - -package main - -import ( - jxkong "foxygo.at/jsonnext/kong" - "github.com/alecthomas/kong" -) - -// Parse CLI using Kong. -func parseCLI() *config { - c := &config{Config: *jxkong.NewConfig()} - kong.Parse(c) - return c -} diff --git a/kong/example_test.go b/kong/example_test.go index a0a4af3..d932603 100644 --- a/kong/example_test.go +++ b/kong/example_test.go @@ -4,19 +4,19 @@ import ( "fmt" "os" - jxkong "foxygo.at/jsonnext/kong" + jnxkong "foxygo.at/jsonnext/kong" "github.com/alecthomas/kong" ) func Example() { - // Define kong CLI struct embedding jxkong.Config, adding your own + // Define kong CLI struct embedding jnxkong.Config, adding your own // application-specific flags and args. cli := struct { - jxkong.Config + jnxkong.Config Verbose bool Filename string `arg:""` }{ - Config: *jxkong.NewConfig(), // foxygo.at/jsonnext/kong imported as jxkong + Config: *jnxkong.NewConfig(), // foxygo.at/jsonnext/kong imported as jnxkong } // Simulate command line arguments diff --git a/kong/kong_conformance_test.go b/kong/kong_conformance_test.go index bc76f5d..32b7eb4 100644 --- a/kong/kong_conformance_test.go +++ b/kong/kong_conformance_test.go @@ -7,13 +7,13 @@ import ( "foxygo.at/jsonnext" "foxygo.at/jsonnext/conformance" - jxkong "foxygo.at/jsonnext/kong" + jnxkong "foxygo.at/jsonnext/kong" ) type suite struct{} func (s *suite) Parse(t *testing.T, args []string) (*jsonnext.Config, error) { - kcfg := jxkong.NewConfig() + kcfg := jnxkong.NewConfig() parser, err := kong.New(kcfg) if err != nil { return nil, err diff --git a/lib/array_test.jsonnet b/lib/array_test.jsonnet index 1e6f058..c7540ba 100755 --- a/lib/array_test.jsonnet +++ b/lib/array_test.jsonnet @@ -1,4 +1,4 @@ -#!/usr/bin/env -S jx -J //github.com/yugui/jsonnetunit/raw/master +#!/usr/bin/env -S jnx -J //github.com/yugui/jsonnetunit/raw/master local array = import 'array.jsonnet'; local test = import 'jsonnetunit/test.libsonnet'; diff --git a/lib/jnx.jsonnet b/lib/jnx.jsonnet new file mode 100644 index 0000000..98ec4a2 --- /dev/null +++ b/lib/jnx.jsonnet @@ -0,0 +1,9 @@ +// Package jnx is a top-level package to import the subpackages of the +// jnx library. +{ + array:: import 'array.jsonnet', + object:: import 'object.jsonnet', + op:: import 'op.jsonnet', + string:: import 'string.jsonnet', + value:: import 'value.jsonnet', +} diff --git a/lib/jx_test.jsonnet b/lib/jnx_test.jsonnet similarity index 59% rename from lib/jx_test.jsonnet rename to lib/jnx_test.jsonnet index b58c923..b04926f 100755 --- a/lib/jx_test.jsonnet +++ b/lib/jnx_test.jsonnet @@ -1,22 +1,22 @@ -#!/usr/bin/env -S jx -J //github.com/yugui/jsonnetunit/raw/master +#!/usr/bin/env -S jnx -J //github.com/yugui/jsonnetunit/raw/master // // Roll-up all the tests in this directory // +local jnx = import 'jnx.jsonnet'; local test = import 'jsonnetunit/test.libsonnet'; -local jx = import 'jx.jsonnet'; -local jx_test = { name: 'jx.jsonnet test' } + test.suite({ +local jnx_test = { name: 'jnx.jsonnet test' } + test.suite({ testImport: { - // Force evaluation of imports in `jx.jsonnet` by using std.prune over + // Force evaluation of imports in `jnx.jsonnet` by using std.prune over // all fields. This will cause a failure if a file cannot be imported. - actual: std.prune(std.objectValuesAll(jx)), + actual: std.prune(std.objectValuesAll(jnx)), expect: [], // empty because all fields are hidden and thus pruned. }, }); [ - jx_test, + jnx_test, import 'array_test.jsonnet', import 'object_test.jsonnet', import 'op_test.jsonnet', diff --git a/lib/jx.jsonnet b/lib/jx.jsonnet index 03c531b..cb2a53d 100644 --- a/lib/jx.jsonnet +++ b/lib/jx.jsonnet @@ -1,9 +1,2 @@ -// Package jx is a top-level package to import the subpackages of the -// jx library. -{ - array:: import 'array.jsonnet', - object:: import 'object.jsonnet', - op:: import 'op.jsonnet', - string:: import 'string.jsonnet', - value:: import 'value.jsonnet', -} +// Kept for backwards compatibilty for now. Will be removed in the future. +import 'jnx.jsonnet' diff --git a/lib/object_test.jsonnet b/lib/object_test.jsonnet index 9316c68..8bd2bcb 100755 --- a/lib/object_test.jsonnet +++ b/lib/object_test.jsonnet @@ -1,4 +1,4 @@ -#!/usr/bin/env -S jx -J //github.com/yugui/jsonnetunit/raw/master +#!/usr/bin/env -S jnx -J //github.com/yugui/jsonnetunit/raw/master local test = import 'jsonnetunit/test.libsonnet'; local object = import 'object.jsonnet'; diff --git a/lib/op_test.jsonnet b/lib/op_test.jsonnet index fa27a1d..93cc87b 100755 --- a/lib/op_test.jsonnet +++ b/lib/op_test.jsonnet @@ -1,4 +1,4 @@ -#!/usr/bin/env -S jx -J //github.com/yugui/jsonnetunit/raw/master +#!/usr/bin/env -S jnx -J //github.com/yugui/jsonnetunit/raw/master local test = import 'jsonnetunit/test.libsonnet'; local op = import 'op.jsonnet'; diff --git a/lib/string_test.jsonnet b/lib/string_test.jsonnet index d23d826..570c45a 100755 --- a/lib/string_test.jsonnet +++ b/lib/string_test.jsonnet @@ -1,4 +1,4 @@ -#!/usr/bin/env -S jx -J //github.com/yugui/jsonnetunit/raw/master +#!/usr/bin/env -S jnx -J //github.com/yugui/jsonnetunit/raw/master local test = import 'jsonnetunit/test.libsonnet'; local string = import 'string.jsonnet'; diff --git a/lib/value_test.jsonnet b/lib/value_test.jsonnet index 51cb397..175ecbe 100755 --- a/lib/value_test.jsonnet +++ b/lib/value_test.jsonnet @@ -1,4 +1,4 @@ -#!/usr/bin/env -S jx -J //github.com/yugui/jsonnetunit/raw/master +#!/usr/bin/env -S jnx -J //github.com/yugui/jsonnetunit/raw/master local test = import 'jsonnetunit/test.libsonnet'; local value = import 'value.jsonnet';