Calling one script from another is fairly straightforward, you can access scripts as “variables” the same as many other
activestate.yaml structures. Let’s let the code do the talking:
scripts: - name: hello language: python3 value: print("Hello World") - name: greeting language: python3 value: | $scripts.hello print("How are you doing?")
When you execute
state run greeting it will inject the value of the “hello” script into the “greeting” script. The resulting code that ends up being ran would look like this”
print("Hello World") print("How are you doing?")
The above example can be problematic when you are running scripts in various languages. For example the following code would certainly fail:
scripts: - name: hello language: python3 value: print("Hello World") - name: greeting value: | $scripts.hello echo "How are you doing?"
Note that the “greeting” script does not have a language defined, this means it runs as either Bash or Batch depending on your platform. But the “hello” script is still Python code, which is being embedded in bash code, which will lead to some sort of syntax error.
You work around such an issue by calling the script by its file, rather than just embedding the code. To do this you can use the
path() method that lives on all scripts. So the above code would become:
scripts: - name: hello language: python3 value: print("Hello World") - name: greeting value: | $scripts.hello.path() echo "How are you doing?"
Now the resulting script will look something like this:
/tmp/7979234.script.py echo "How are you doing?"
The file in question will have a shebang with our interpreter defined in it, so you don’t need to worry about providing the interpreter unless you are on Windows, which doesn’t support shebang. For cross-platform compatibility you could instead use:
- name: greeting value: | python3 $scripts.hello.path() echo "How are you doing?"
That way we’re explicitly saying Python is the interpreter for this file.
Scripts can use constants too, so for example you could instead use the following value:
value: echo $constants.HELLO
This also works for secrets, so instead of the above you could use
echo $secrets.user.HELLO. It gets more interesting though, because in the
activestate.yaml EVERYTHING is a “variable”, so you could create another command that references our first command:
scripts: - name: log-hello value: $scripts.hello > /tmp/hello.txt
You can see how used wisely this can quickly become very powerful.
The main use-case for scripts is to kick off builds, run tests, etc. But the sky’s the limit.
Scripts support arguments too! Using the hello world sample again, you could define your script like so:
scripts: - name: hello value: echo hello $1
Now you can run
hello world or
hello planet and it should print out the argument you passed.
You can constrain scripts to only run on certain platforms. If a language is not specified for the script, they will be run as either bash or batch scripts, depending on the shell that you run them from. This can be problematic because bash and batch are two very different languages, and you might have cross-platform requirements. You can add constraints to your script entries to ensure that the correct command runs based on the operating system identified at run time. For example:
scripts: - name: env language: bash value: printenv constraints: os: linux,macos - name: env language: batch value: set constraints: os: windows
Now when you run
state run env on Windows it will execute the windows constrained script, whereas when you run it on Linux or macOS it will run the script constrained to those platforms.
Constraints can also be negative, so if you would want to run a script on any platform except windows you could use
The possible values for the OS constraint are:
These values can be given in a comma separate fashion, and include a minus character to exclude them (e.g.