jsonnext

package module
v0.1.16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2021 License: Apache-2.0 Imports: 12 Imported by: 1

README

jsonnext

Extension libraries for go-jsonnet. The name jsonnext is a contraction of jsonnet and ext.

Documentation for this module is on pkg.go.dev.

Importer

foxygo.at/jsonnext.Importer is a jsonnet.Importer implementation that can import from the local filesystem and from https network sources. Normal paths, absolute and relative, are imported from the local filesystem. Paths starting with a double-slash (//) are imported as https URLs with an implicit https: prefix. For example, the path //github.com/grafana/grafonnet-lib/raw/master/grafonnet/grafana.libsonnet refers to the file grafana.libsonnet on the master branch of the grafana/grafonnet-lib repository on GitHub (using the "raw" path to retrieve the contents of the file instead of the GitHub web page for the file).

The Importer has a SearchPath of type []string that can be populated directly or by using the AppendSearchFromEnv() method. The method takes the name of an environment variable, splits it on the OS-specific ListSeparator and appends the elements to the existing search path.

The default Fetcher for the importer is the default http.Client, which is used for importing URLs. It can be replaced with any type that implements the Get method of http.Client. Most likely it will be overridden with a http.Client that has been constructed with a non-default configuration.

The importer maintains a cache of results as is required by the jsonnet.Importer interface description. Positive and negative results are cached and returned on subsequent calls to import the same path. Errors retrieving a path are not cached and are returned as an error results from the Import method.

Documentation

Overview

Package jsonnext makes it simpler to use jsonnet in a program.

jsonnet is a data templating language that can be considered an extension of JSON that makes it composable.

import "github.com/google/go-jsonnet"

jsonnext provides some go types and functions to make it easier to plug jsonnet into a program with minimal work and to extend some of the jsonnet abstractions to add capability.

Importer

Importer is an implementation of jsonnet.Importer that supports netpaths - paths that start with a double-slash - // - for network paths. Netpaths are retrieved via https using a URLFetcher. Other paths are read from the filesystem.

This form of netpath makes it simpler to use in a PATH-style, colon-separated environment variable where the colon in a URL would need to be escaped.

Config

A type to encapsulate the configurable properties of a jsonnet VM and extensions provided by this package. It is agnotistic to the source of the configuration - it could come from the command line, config files or constucted in code by an application.

Config uses the types VMVarMap and VMVar that provide a generic abstraction of the various variable types used on the jsonnet command line. These are the combination of:

  • external variables (extVars) vs top-level args (TLAs)
  • strings vs code
  • literals vs files

VMVarMap has a helper to parse string forms of entries with the option to take values from environment variables to support jsonnet command-line use cases.

Flag

Functions that wrap flag.Var to define the flags for the Config struct using types that implement flag.Value to suitably parse the CLI options.

The flag names and use align with the standard jsonnet CLI options as much as possible, with minor variations due to how the Go flag package works, such as single-hyphen long flag prefixes.

The simplest use of flags is to let it create the Config struct for you with flags bound to the fields of that instance:

cfg := jsonnext.ConfigFlags(flag.CommandLine)
flag.Parse()
cfg.ConfigureVM(vm)

However the functions that create the individual flag types are exported so they can be used to define different flag names for an application.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrMissingKey   = errors.New("missing key")
	ErrMissingValue = errors.New("missing value")
)

Sentinel errors returned by Config functions. Callers can use errors.Is with these sentinels to handle the specific types of errors.

Functions

func ConfigFlagsVar added in v0.1.10

func ConfigFlagsVar(fs *flag.FlagSet, c *Config)

ConfigFlagsVar defines a set of flags in the given FlagSet for a Config struct to populate the fields from the command line. The argument c points to the Config struct to populate. The set of flags defined is described in the ConfigFlags function description.

func ExtCodeFileVar added in v0.1.10

func ExtCodeFileVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

ExtCodeFileVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets an extVar code import in a jsonnet VM.

The flag value on the command line is parsed as "key[=filename]". If "=filename" is omitted then key is looked up in the environment for the value. It is an error if "=filename" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

func ExtCodeVar added in v0.1.10

func ExtCodeVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

ExtCodeVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets an extVar code literal in a jsonnet VM.

The flag value on the command line is parsed as "key[=code]". If "=code" is omitted then key is looked up in the environment for the value. It is an error if "=code" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

func ExtStrFileVar added in v0.1.10

func ExtStrFileVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

ExtStrFileVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets an extVar string import in a jsonnet VM.

The flag value on the command line is parsed as "key[=filename]". If "=filename" is omitted then key is looked up in the environment for the value. It is an error if "=filename" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

func ExtStrVar added in v0.1.10

func ExtStrVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

ExtStrVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets an extVar string literal in a jsonnet VM.

The flag value on the command line is parsed as "key[=string]". If "=string" is omitted then key is looked up in the environment for the value. It is an error if "=string" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

func StringSlice added in v0.1.10

func StringSlice(fs *flag.FlagSet, name, usage string) *[]string

StringSlice defines a flag in the given FlagSet with the given name and usage string. The return value is the address of a []string variable that stores the value of the flag. The value given to each instance of the flag is appended to the slice.

func StringSliceVar added in v0.1.10

func StringSliceVar(fs *flag.FlagSet, p *[]string, name, usage string)

StringSliceVar defines a flag in the given FlagSet with the given name and usage string. The argument p is a pointer to a []string variable in which to store the value of the flag. The value given to each instance of the flag is appended to the slice.

func TLACodeFileVar added in v0.1.10

func TLACodeFileVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

TLACodeFileVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets a top-level arg code import in a jsonnet VM.

The flag value on the command line is parsed as "key[=filename]". If "=filename" is omitted then key is looked up in the environment for the value. It is an error if "=filename" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

func TLACodeVar added in v0.1.10

func TLACodeVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

TLACodeVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets a top-level arg code literal in a jsonnet VM.

The flag value on the command line is parsed as "key[=code]". If "=code" is omitted then key is looked up in the environment for the value. It is an error if "=code" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

func TLAStrFileVar added in v0.1.10

func TLAStrFileVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

TLAStrFileVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets a top-level arg string import in a jsonnet VM.

The flag value on the command line is parsed as "key[=filename]". If "=filename" is omitted then key is looked up in the environment for the value. It is an error if "=filename" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

func TLAStrVar added in v0.1.10

func TLAStrVar(fs *flag.FlagSet, m VMVarMap, name, usage string)

TLAStrVar defines flag with the given name and usage string in the given FlagSet to set a VMVar in the given VMVarMap. The VMVar sets a top-level arg string literal in a jsonnet VM.

The flag value on the command line is parsed as "key[=string]". If "=string" is omitted then key is looked up in the environment for the value. It is an error if "=string" is not provided and the environment variable does not exist.

The flag can be repeated multiple times on the command line. Each instance adds a new value to the given VMVarMap.

Types

type Config added in v0.1.10

type Config struct {
	ImportPath []string `name:"jpath" sep:"none" short:"J" placeholder:"dir" help:"Add a library search dir"`
	ExtVars    VMVarMap `kong:"-"`
	TLAVars    VMVarMap `kong:"-"`
	MaxStack   int      `default:"500" help:"Number of allowed stack frames of jsonnet VM"`
	MaxTrace   int      `default:"20" help:"Maximum number of stack frames output on error"`
}

Config holds configuration for a jsonnet VM and the Importer defined in this jsonnext package. An application can populate this struct directly from whatever source of configuration it uses and use it to configure the jsonnet VM. This package provides two options for populating it from the command line (Go flags or Kong).

func ConfigFlags added in v0.1.10

func ConfigFlags(fs *flag.FlagSet) *Config

ConfigFlags defines a set of flags in the given FlagSet for a Config struct to populate its fields from the command line. The return value is a pointer to the Config struct that stores the values of the flags. The fields are populated with the following flags:

Config.ImportPath:
 -J, -jpath
Config.ExtVars:
 -V, -ext-str: ext var as string literal
 -ext-code: ext var as code literal
 -ext-str-file: ext var as string from file
 -ext-code-file: ext var as code from file
Config.TLAVars:
 -A, -tla-str: top-level arg as string literal
 -tla-code: top-level arg as code literal
 -tla-str-file: top-level arg as string from file
 -tla-code-file: top-level arg as code from file

func NewConfig added in v0.1.10

func NewConfig() *Config

NewConfig returns a new initialised but empty Config struct.

func (*Config) ConfigureImporter added in v0.1.10

func (c *Config) ConfigureImporter(i *Importer, envvar string)

ConfigureImporter sets up a jsonnext.Importer with the import path from the config and from a PATH-style environment variable. If envvar is the empty string, no paths are taken from the environment.

Example
package main

import (
	"fmt"
	"os"

	jsonnet "github.com/google/go-jsonnet"

	"foxygo.at/jsonnext"
)

func main() {
	vm := jsonnet.MakeVM()
	i := &jsonnext.Importer{}
	vm.Importer(i)

	// testdata/importer/hello.txt contains: hello world\n
	// testdata/importer/mellow.txt contains: mellow world\n
	_ = os.Setenv("EXAMPLE_PATH", "testdata/importer")
	cfg := jsonnext.NewConfig()
	cfg.ImportPath = []string{"testdata"}
	cfg.ConfigureImporter(i, "EXAMPLE_PATH")

	// "<literal>" is the filename for error reporting.
	str, _ := vm.EvaluateAnonymousSnippet("<literal>", `[importstr "hello.txt", importstr "importer/mellow.txt"]`)
	fmt.Println(str)
}
Output:

[
   "hello world\n",
   "mellow world\n"
]

func (*Config) ConfigureVM added in v0.1.10

func (c *Config) ConfigureVM(vm *jsonnet.VM)

ConfigureVM sets the ExtVars and TLAVars in the jsonnet VM.

Example
package main

import (
	"fmt"

	jsonnet "github.com/google/go-jsonnet"

	"foxygo.at/jsonnext"
)

func main() {
	vm := jsonnet.MakeVM()

	cfg := jsonnext.NewConfig()
	cfg.ExtVars["extvar"] = jsonnext.NewExtStr("hello")
	cfg.TLAVars["tlavar"] = jsonnext.NewTLACode(`" world"`)
	cfg.ConfigureVM(vm)

	// "<literal>" is the filename for error reporting.
	str, _ := vm.EvaluateAnonymousSnippet("<literal>", "function(tlavar) std.extVar('extvar') + tlavar")
	fmt.Println(str)
}
Output:

"hello world"

func (*Config) MakeVM added in v0.1.10

func (c *Config) MakeVM(pathEnvVar string) *jsonnet.VM

MakeVM returns a jsonnet.VM configured with the external vars and top-level args in Config, and sets its Importer to be a jsonnext.Importer also configured from Config. The importer search path is extended with elements from the environment variable pathEnvVar. pathEnvVar may be the empty string if no environment variable should be used.

type Importer

type Importer struct {
	// SearchPath is an ordered slice of paths (network or local filesystem)
	// that is prepended to the imported filename if the filename is not
	// found. Searching stops when it is found.
	SearchPath []string

	// Fetcher is the URLFetcher used to fetch paths. The default is
	// &http.Client{}
	Fetcher URLFetcher
	// contains filtered or unexported fields
}

Importer implements the jsonnet.Importer interface, allowing jsonnet code to be imported via https in addition to local files. Filenames starting with a double-slash (`//`) are fetched via HTTPS using the Fetcher of the Importer. Otherwise the path is treated as a local filesystem path. An empty path, a path of "-" and a path of "/dev/stdin" are treated as standard input. "/dev/stdin" is handled specially as any imports in the code read from stdin should not be searched relative to "/dev".

Once an import path is successfully fetched, either with data or a definitive not found result, that result is cached for the lifetime of the Importer. This is a requirement of the jsonnet.Importer interface so it is not possible for the same import statement from different files to result in different content. If an Importer is shared across multiple jsonnet.VM instances, the the cache will be shared too. There is no cache expiry logic.

func (*Importer) AppendSearchFromEnv

func (i *Importer) AppendSearchFromEnv(envvar string)

AppendSearchFromEnv appends a list of search paths specified in the given environment variable to the search path list. The elements of the path in the variable are separated by the filepath.SplitList() delimiter.

func (*Importer) Import

func (i *Importer) Import(source, imp string) (jsonnet.Contents, string, error)

Import loads imp from a file or a network location. If imp is a relative path, search for it relative to the directory of source and the search path elements. If the import found, return its contents and the absolute location where it was found. If it was not found, or there was an error reading the content, return the error.

Import will cache the result and return it the next time that path is requested.

This method is defined in the jsonnet.Importer interface:

https://godoc.org/github.com/google/go-jsonnet#Importer

type URLFetcher

type URLFetcher interface {
	Get(url string) (*http.Response, error)
}

A URLFetcher retrieves a URL returning a http.Response or an error. It is defined such that http.Client implements it, but allows a different implementation or a custom-configured http.Client to be provided to the Importer.

type VMVar added in v0.1.10

type VMVar interface {
	Set(key string, vm *jsonnet.VM)
}

VMVar is a variable that can be set in a jsonnet VM, either as an external variable (extVar) or a top-level arg (TLA), as a string or code. Variants of VMVars that take the string or code from a file are turned into jsonnet imports (jsonnet "importstr" or "import" statements) and added as a code VMVar. It maps to the --ext-* and --tla-* command line arguments to the standard jsonnet binary.

func NewExtCode added in v0.1.10

func NewExtCode(s string) VMVar

NewExtCode constructs a VMVar as a code external variable.

func NewExtCodeFile added in v0.1.10

func NewExtCodeFile(s string) VMVar

NewExtCodeFile constructs a VMVar as a code external variable to be read from a file.

func NewExtStr added in v0.1.10

func NewExtStr(s string) VMVar

NewExtStr constructs a VMVar as a string external variable.

func NewExtStrFile added in v0.1.10

func NewExtStrFile(s string) VMVar

NewExtStrFile constructs a VMVar as a string external variable to be read from a file.

func NewTLACode added in v0.1.10

func NewTLACode(s string) VMVar

NewTLACode constructs a VMVar as a code top-level arg.

func NewTLACodeFile added in v0.1.10

func NewTLACodeFile(s string) VMVar

NewTLACodeFile constructs a VMVar as a code top-level arg to be read from a file.

func NewTLAStr added in v0.1.10

func NewTLAStr(s string) VMVar

NewTLAStr constructs a VMVar as a string top-level arg.

func NewTLAStrFile added in v0.1.10

func NewTLAStrFile(s string) VMVar

NewTLAStrFile constructs a VMVar as a string top-level arg to be read from a file.

type VMVarMap added in v0.1.10

type VMVarMap map[string]VMVar

VMVarMap is a map of VMVars that contains a common namespace for variable names. The values of type VMVar know how to set themselves in a given VM.

func (VMVarMap) ConfigureVM added in v0.1.10

func (m VMVarMap) ConfigureVM(vm *jsonnet.VM)

ConfigureVM sets the vars from m in the givem jsonnet VM.

func (VMVarMap) SetVar added in v0.1.10

func (m VMVarMap) SetVar(v string, makevar func(string) VMVar) error

SetVar sets a variable in m parsing the key and value from the given string v, using makevar to construct the VMVar value. If the value is omitted from the string, the value is taken from an environment variable of the same name as the key. An error is returned if the environment variable does not exist, or if the value string cannot be parsed due to a missing key or value (when required).

makevar will typically be one of the VMVar constructor functions in this package - New{Ext,TLA}{Str,Code}{,File}.

Directories

Path Synopsis
cmd
jx
jx evaluates a jsonnet file and outputs it as JSON.
jx evaluates a jsonnet file and outputs it as JSON.
Package conformance is a test suite for testing CLI parsing into jsonnext data structures.
Package conformance is a test suite for testing CLI parsing into jsonnext data structures.
Package kong parses command line flags into jsonnext.Config using kong.
Package kong parses command line flags into jsonnext.Config using kong.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL