Documentation ¶
Overview ¶
Package envdef implements a parser for the runtime environment for alternative builds
Builds that are built with the alternative build environment, include runtime.json files that define which environment variables need to be set to install and use the provided artifacts. The schema of this file can be downloaded [here](https://drive.google.com/drive/u/0/my-drive)
The same parser and interpreter also exists in [TheHomeRepot](https://github.com/ActiveState/TheHomeRepot/blob/master/service/build-wrapper/wrapper/runtime.py)
Changes to the runtime environment definition schema should be synchronized between these two places. For now, this can be most easily accomplished by keeping the description of test cases in the [cli repo](https://github.com/ActiveState/cli/blob/master/pkg/platform/runtime/envdef/runtime_test_cases.json) and [TheHomeRepot](https://github.com/ActiveState/TheHomeRepot/blob/master/service/build-wrapper/runtime_test_cases.json) in sync.
Examples:
## Define a PATH and LD_LIBRARY_PATH variable
Assuming the runtime is installed to a directory `/home/user/.cache/installdir`, the following definition asks to set the PATH variables to `/home/user/.cache/installdir/bin:/home/user/.cache/installdir/usr/bin` and `LD_LIBRARY_PATH` to `/home/user/.cache/installdir/lib` The set `inherit` flag on the `PATH` variable ensures that the `PATH` value is prepended to the existing `PATH` that is already set in the environment.
```json
{ "env": [{ "env_name": "PATH", "values": ["${INSTALLDIR}/bin", "${INSTALLDIR}/usr/bin"], "join": "prepend", "inherit": true, "separator": ":" }, { "env_name": "LD_LIBRARY_PATH", "values": ["${INSTALLDIR}/lib"], "join": "prepend", "inherit": false, "separator": ":" }], "installdir": "installdir" }
```
The installdir is used during the unpacking step to identify the directory inside the artifact tarball that needs to be unpacked to `/home/user/.cache/installdir`
## Joining two definitions
Assume we have a second environment definition file exists with the following contents:
```json
{ "env": [{ "env_name": "PATH", "values": ["${INSTALLDIR}/bin", "${INSTALLDIR}/usr/local/bin"], "join": "prepend", "inherit": true, "separator": ":" }, { "env_name": "LD_LIBRARY_PATH", "values": ["${INSTALLDIR}/lib", "${INSTALLDIR}/lib64"], "join": "prepend", "inherit": false, "separator": ":" }], "installdir": "installdir" }
```
Merging this environment definition into the previous one sets the `PATH` to `/home/user/.cache/installdir/bin:/home/user/.cache/installdir/usr/local/bin:/home/user/.cache/installdir/usr/bin`. Note, that duplicate values are filtered out. Likewise the `LD_LIBRARY_PATH` will end up as `/home/user/.cache/installdir/lib:/home/user/.cache/installdir/lib64`
In this example, the values were joined by prepending the second definition to the first. Other join strategies are `append` and `disallowed`.
The `disallowed` join strategy can be used if a variable should have only ONE value, and this value needs to be the same or undefined between all artifacts that depend on it.
## Usage
- Environment definition files can be parsed from a file with the `NewEnvironmentDefinition()` function.
- Two environment definitions `ed1` and `ed2` can be merged like so: ed1.Merge(ed2)
- Once the installation directory is specified, the variable values can be expanded: ed.ExpandVariables("/home/user/.cache/installdir")
Index ¶
- func FilterPATH(env map[string]string, excludes ...string)
- type ConstTransform
- type Constants
- type EnvironmentDefinition
- func (ed *EnvironmentDefinition) ApplyFileTransforms(installDir string, constants Constants) error
- func (ed *EnvironmentDefinition) ExecutableDirs() (ExecutablePaths, error)
- func (ed *EnvironmentDefinition) ExecutablePaths() (ExecutablePaths, error)
- func (ed *EnvironmentDefinition) ExpandVariables(constants Constants) *EnvironmentDefinition
- func (ed *EnvironmentDefinition) FindBinPathFor(executable string) string
- func (ed *EnvironmentDefinition) GetEnv(inherit bool) map[string]string
- func (ed *EnvironmentDefinition) GetEnvBasedOn(envLookup func(string) (string, bool)) (map[string]string, error)
- func (ed *EnvironmentDefinition) Marshal() ([]byte, error)
- func (ed EnvironmentDefinition) Merge(other *EnvironmentDefinition) (*EnvironmentDefinition, error)
- func (ed *EnvironmentDefinition) ReplaceString(from string, replacement string) *EnvironmentDefinition
- func (ed *EnvironmentDefinition) WriteFile(filepath string) error
- type EnvironmentVariable
- func (ev EnvironmentVariable) Merge(other EnvironmentVariable) (*EnvironmentVariable, error)
- func (ev EnvironmentVariable) ReplaceString(from string, replacement string) EnvironmentVariable
- func (ev *EnvironmentVariable) UnmarshalJSON(data []byte) error
- func (ev *EnvironmentVariable) ValueString() string
- type ExecutablePaths
- type FileTransform
- type VariableJoin
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FilterPATH ¶
Types ¶
type ConstTransform ¶
type ConstTransform struct { In []string `json:"in"` // List of constants to apply this transform to Pattern string `json:"pattern"` With string `json:"with"` }
ConstTransform is a transformation that should be applied to substituted constants prior to substitution in files
type Constants ¶
Constants is a map of constants that are being expanded in environment variables and file transformations to their installation-specific values
func NewConstants ¶
NewConstants initializes a new map of constants that will need to be set to installation-specific values Currently it only has one field `INSTALLDIR`
type EnvironmentDefinition ¶
type EnvironmentDefinition struct { // Env is a list of environment variables to be set Env []EnvironmentVariable `json:"env"` // Transforms is a list of file transformations Transforms []FileTransform `json:"file_transforms"` // InstallDir is the directory (inside the artifact tarball) that needs to be installed on the user's computer InstallDir string `json:"installdir"` }
EnvironmentDefinition provides all the information needed to set up an environment in which the packaged artifact contents can be used.
func NewEnvironmentDefinition ¶
func NewEnvironmentDefinition(fp string) (*EnvironmentDefinition, error)
NewEnvironmentDefinition returns an environment definition unmarshaled from a file
func (*EnvironmentDefinition) ApplyFileTransforms ¶
func (ed *EnvironmentDefinition) ApplyFileTransforms(installDir string, constants Constants) error
ApplyFileTransforms applies all file transformations to the files in the base directory
func (*EnvironmentDefinition) ExecutableDirs ¶
func (ed *EnvironmentDefinition) ExecutableDirs() (ExecutablePaths, error)
func (*EnvironmentDefinition) ExecutablePaths ¶
func (ed *EnvironmentDefinition) ExecutablePaths() (ExecutablePaths, error)
func (*EnvironmentDefinition) ExpandVariables ¶
func (ed *EnvironmentDefinition) ExpandVariables(constants Constants) *EnvironmentDefinition
ExpandVariables expands substitution strings specified in the environment variable values. Right now, the only valid substition string is `${INSTALLDIR}` which is being replaced with the base of the installation directory for a given project
func (*EnvironmentDefinition) FindBinPathFor ¶
func (ed *EnvironmentDefinition) FindBinPathFor(executable string) string
FindBinPathFor returns the PATH directory in which the executable can be found. If the executable cannot be found, an empty string is returned. This function should be called after variables names are expanded with ExpandVariables()
func (*EnvironmentDefinition) GetEnv ¶
func (ed *EnvironmentDefinition) GetEnv(inherit bool) map[string]string
GetEnv returns the environment variable names and values defined by the EnvironmentDefinition. If an environment variable is configured to inherit from the OS environment (`Inherit==true`), the base environment defined by the `envLookup` method is joined with these environment variables.
func (*EnvironmentDefinition) GetEnvBasedOn ¶
func (ed *EnvironmentDefinition) GetEnvBasedOn(envLookup func(string) (string, bool)) (map[string]string, error)
GetEnvBasedOn returns the environment variable names and values defined by the EnvironmentDefinition. If an environment variable is configured to inherit from the base environment (`Inherit==true`), the base environment defined by the `envLookup` method is joined with these environment variables. This function is mostly used for testing. Use GetEnv() in production.
func (*EnvironmentDefinition) Marshal ¶
func (ed *EnvironmentDefinition) Marshal() ([]byte, error)
WriteFile marshals an environment definition to a file
func (EnvironmentDefinition) Merge ¶
func (ed EnvironmentDefinition) Merge(other *EnvironmentDefinition) (*EnvironmentDefinition, error)
Merge merges two environment definitions according to the join strategy of the second one.
- Environment variables that are defined in both definitions, are merged with EnvironmentVariable.Merge() and added to the result
- Environment variables that are defined in only one of the two definitions, are added to the result directly
func (*EnvironmentDefinition) ReplaceString ¶
func (ed *EnvironmentDefinition) ReplaceString(from string, replacement string) *EnvironmentDefinition
ReplaceString replaces the string `from` with its `replacement` value in every environment variable value
func (*EnvironmentDefinition) WriteFile ¶
func (ed *EnvironmentDefinition) WriteFile(filepath string) error
WriteFile marshals an environment definition to a file
type EnvironmentVariable ¶
type EnvironmentVariable struct { Name string `json:"env_name"` Values []string `json:"values"` Join VariableJoin `json:"join"` Inherit bool `json:"inherit"` Separator string `json:"separator"` }
EnvironmentVariable defines a single environment variable and its values
func (EnvironmentVariable) Merge ¶
func (ev EnvironmentVariable) Merge(other EnvironmentVariable) (*EnvironmentVariable, error)
Merge merges two environment variables according to the join strategy defined by the second environment variable If join strategy of the second variable is "prepend" or "append", the values are prepended or appended to the first variable. If join strategy is set to "disallowed", the variables need to have exactly one value, and both merged values need to be identical, otherwise an error is returned.
func (EnvironmentVariable) ReplaceString ¶
func (ev EnvironmentVariable) ReplaceString(from string, replacement string) EnvironmentVariable
ReplaceString replaces the string 'from' with 'replacement' in environment variable values
func (*EnvironmentVariable) UnmarshalJSON ¶
func (ev *EnvironmentVariable) UnmarshalJSON(data []byte) error
UnmarshalJSON unmarshals an environment variable It sets default values for Inherit, Join and Separator if they are not specified
func (*EnvironmentVariable) ValueString ¶
func (ev *EnvironmentVariable) ValueString() string
ValueString joins the environment variable values into a single string If duplicate values are found, only one of them is considered: for join strategy `prepend` only the first occurrence, for join strategy `append` only the last one.
type ExecutablePaths ¶
type ExecutablePaths []string
type FileTransform ¶
type FileTransform struct { Pattern string `json:"pattern"` In []string `json:"in"` With string `json:"with"` ConstTransforms []ConstTransform `json:"const_transforms"` PadWith *string `json:"pad_with"` }
FileTransform specifies a single transformation to be performed on files in artifacts post-installation
func (*FileTransform) ApplyTransform ¶
func (ft *FileTransform) ApplyTransform(baseDir string, constants Constants) error
ApplyTransform applies a file transformation to all specified files
type VariableJoin ¶
type VariableJoin int
VariableJoin defines a strategy to join environment variables together
const ( // Prepend indicates that new variables should be prepended Prepend VariableJoin = iota // Append indicates that new variables should be prepended Append // Disallowed indicates that there must be only one value for an environment variable Disallowed )
func (VariableJoin) MarshalText ¶
func (j VariableJoin) MarshalText() ([]byte, error)
MarshalText marshals a join directive for environment variables
func (*VariableJoin) UnmarshalText ¶
func (j *VariableJoin) UnmarshalText(text []byte) error
UnmarshalText un-marshals a join directive for environment variables