Environment
With each execution, jko
creates an Independent environment—an entirely new instance that derives from either the system environment or the parent process environment.
The environment variables can be reached in various contexts:
- Function scripts:
process.env.NAME
- Traditional scripts:
$NAME
- Other processes: through mechanisms specific to each process (e.g., a Node.js process uses
process.env.NAME
)
For example:
export default {
scripts: {
functionScriptA: function (param1, param2) {
console.log('functionScriptA')
process.env.jko_return_0 = `1. ${param1}_${param2}`
return 'functionScriptB'
},
functionScriptB: function (param1, param2) {
console.log('functionScriptB')
process.env.jko_return_1 = `2. ${param1}_${param2}`
return 'scriptC'
},
scriptC: 'echo scriptC: $jko_arg_0, $jko_return_0, $jko_return_1',
scriptD: 'jko functionScriptA 2 3 && jko scriptC'
}
}
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, must add -l=e
options to all jko
executions)
When executed:
$ jko scriptD
$ functionScriptA
$ functionScriptB
$ scriptC: 2, 1. 2_3, 2. 2_3
$ scriptC: , ,
scriptD
chains two processes: jko functionScriptA 2 3
and jko scriptC
.
Each execution creates an "Independent" environment:
- In the first execution, being a chaining, the environment is shared, so when the tail script is invoked, it receives all the values. That's why you see
scriptC: 2, 1. 2_3, 2. 2_3
. - In the second execution, which operates in an "Independent" environment, both
jko_return_0
andjko_return_1
are empty. As a result, the output isscriptC: , ,
.
Let's change a few lines in functionScriptA
and scriptD
:
export default {
scripts: {
functionScriptA: function (param1, param2) {
console.log('functionScriptA')
process.env.jko_return_0 = `1. ${param1}_${param2}`
return 'scriptD'
},
functionScriptB: function (param1, param2) {
console.log('functionScriptB')
process.env.jko_return_1 = `2. ${param1}_${param2}`
return 'scriptC'
},
scriptC: 'echo scriptC: $jko_arg_0, $jko_return_0, $jko_return_1',
scriptD: 'jko functionScriptB && jko scriptC',
}
}
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, must add -l=e
options to all jko
executions)
When executed:
$ jko functionScriptA 2 3
$ functionScriptA
$ functionScriptB
$ scriptC: 2, 1. 2_3, 2. undefined_undefined
$ scriptC: 2, 1. 2_3,
-
Shared Environment Creation:
Executing
jko functionScriptA 2 3
creates a Shared environment used by the two chained processesjko functionScriptB
andjko scriptC
, and also by their descendants.- In this process,
jko_return_0
becomes available to both. - However, both
jko functionScriptB
andjko scriptC
operate within their own Independent environments.
- In this process,
-
Argument Availability:
Although the arguments
2
and3
are available inscriptD
, they are not accessible tofunctionScriptB
. This is why the output displaysundefined
for those values (scriptC: 2, 1. 2_3, 2. undefined_undefined
).- Nevertheless,
jko_arg_0
andjko_arg_1
belong to the Shared environment and remain available.
- Nevertheless,
-
Additionally,
jko_return_1
is defined in thefunctionScriptB
Independent environment and is not accessible to the initialscriptC
. This is why the output appears as:scriptC: 2, 1. 2_3,
.
Let's change a line in functionScriptB
:
export default {
scripts: {
functionScriptA: function (param1, param2) {
console.log('functionScriptA')
process.env.jko_return_0 = `1. ${param1}_${param2}`
return 'scriptD'
},
functionScriptB: function () {
console.log('functionScriptB')
process.env.jko_return_1 = `2. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`
return 'scriptC'
},
scriptC: 'echo scriptC: $jko_arg_0, $jko_return_0, $jko_return_1',
scriptD: 'jko functionScriptB && jko scriptC',
}
}
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, must add -l=e
options to all jko
executions)
When executed:
$ jko functionScriptA 2 3
$ functionScriptA
$ functionScriptB
$ scriptC: 2, 1. 2_3, 2. 2_3
$ scriptC: 2, 1. 2_3,
Using jko_arg_0
and jko_arg_1
, which belong to the Shared environment, allows functionScriptB
to access to original arguments.
Shared Environments
Chained processes share a common environment. As a result:
- The environment variables holding the initial arguments are accessible in every script.
- Newly added environment variables are available to subsequent scripts after their definition.
Review the following image that demonstrates how the environment evolves during the chaining calls:
See that:
- Initial arguments,
jko_arg_0
,jko_arg_1
, etc. are accessible in every script,functionScript1
,functionScript2
andfunctionScript3
.- Furthermore, they can be accessed as parameters these functions.
jko_return_0
is accessible tofunctionScript2
andfunctionScript3
.jko_return_1
is accessible tofunctionScript3
.
For example:
export default {
scripts: {
functionScript1: function (param1, param2) {
console.log('functionScript1:')
console.log(param1 === process.env.jko_arg_0)
console.log(param2 === process.env.jko_arg_1)
process.env.jko_return_0 = `1. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`
return 'functionScript2'
},
functionScript2: function (param1, param2) {
console.log('functionScript2:')
console.log(param1 === process.env.jko_arg_0)
console.log(param2 === process.env.jko_arg_1)
console.log(process.env.jko_return_0 === `1. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`)
process.env.jko_return_1 = `2. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`
return 'functionScript3'
},
functionScript3: function (param1, param2) {
console.log('functionScript3:')
console.log(param1 === process.env.jko_arg_0)
console.log(param2 === process.env.jko_arg_1)
console.log(process.env.jko_return_0 === `1. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`)
console.log(process.env.jko_return_1 === `2. ${process.env.jko_arg_0}_${process.env.jko_arg_1}`)
// End of the chaining
}
}
}
When executed:
$ jko functionScript1 1 2
$ functionScript1:
$ true
$ true
$ functionScript2:
$ true
$ true
$ true
$ functionScript3:
$ true
$ true
$ true
$ true
$ jko functionScript2 1 2
$ functionScript2:
$ true
$ true
$ false
$ functionScript3:
$ true
$ true
$ false
$ true
(Actually, the output will be longer, but it has been simplified to emphasize functionality over presentation. To get the exact same output as in the example, use the following command: jko -l=e functionScript1 1 2
)
Enhancing Environment
Use envFile
in jko.js
to specify the path of a .env
file, which provides required environment variables
to the new instance where the script will run.
jko.js
:
export default {
scripts: {
yourScript1: "someCommand",
},
envFile: './path/to/.env',
}
.env
:
SOME_ENV_VAR=VALUE1
Additionally, the .env
file can be specified using the CLI option --env-file
:
$ jko --env-file=./path/to/.env yourScript arg1 ... argN
command line option --env-file
takes precedence over envFile
.
Additional Environment Variables
In addition to generating environment variables for each command-line argument,
jko
creates environment variables for every field exported by jko.js
(package.json
,
or any configuration file specified via the --config-file
option) — excluding scripts
field.
These environment variables are generated with a jko_
prefix. Additionally, for compatibility reasons, variables prefixed with npm_package_
are also added.
For example, using the following jko.js
:
export default {
scripts: {
yourScript1: "someCommand",
},
envFile: './path/to/.env',
dependencies: {
packageName1: "1.0.0"
},
devDependencies: {
devPackageName1: "1.0.0"
},
packageManager: 'yarn',
logLevel: 'warn',
config: {
data: ['A', 'B']
},
version: '1.2.3',
name: 'theName'
}
jko
will generated the following variables:
jko_config_data_0
,npm_package_config_data_0
.jko_config_data_1
,npm_package_config_data_1
.jko_version
,npm_package_version
.jko_name
,npm_package_name
.- etc.
You can provide default jko_arg_
values using this mechanism—simply define an arg
field as an array:
export default {
scripts: {
yourScript1: "someCommand",
},
arg: ['arg1', 'argN']
}
Summary
- Each
jko
execution runs in a new Independent Environment. This environment may belong to a Shared Environment or not, and it is a Shared Environment among its descendant processes. - Chained function scripts run in a Shared Environment.
- Chained commands in traditional scripts run in a Shared Environment.
jko
introduces custom environment variables with ajko_
prefix (and, for compatibility, supports variables prefixed withnpm_package_
).- Environment variables will be reachable in multiple ways. For function scripts, use
process.env.NAME
; for traditional scripts, use$NAME
; and for other processes, the access method varies.