Scripts

Calling Scripts From Other Scripts

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?")

Calling Scripts by Their Path

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.

Using Constants and Secrets

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.

Script Arguments

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.

Constraining Scripts

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 os: -windows.

The possible values for the OS constraint are:

  • windows
  • macos
  • linux

These values can be given in a comma separate fashion, and include a minus character to exclude them (e.g. -windows).