HERE and ROOT Variables¶
When a worker runs a step, it defines several environment variables,
including HERE and ROOT, which can be relevant for writing advanced scripts.
(The workers also define variables starting with STEPUP_,
but these are only useful to StepUp itself, not to end users.)
The two variables are defined as follows:
HEREcontains the relative path from the directory where StepUp was started to the current working directory of the step.ROOTcontains the opposite: the relative directory from the current working directory to the directory where StepUp was started.
Hence, HERE/ROOT and ROOT/HERE normalize to the current directory: ./.
These variables can be useful in the following cases:
- For out-of-source builds, where you want to replicate the directory structure of the source material. (See example below.)
- To reference a local script that is stored in the top-level directory of your project:
${ROOT}/script.py
Example¶
Example source files: docs/advanced_topics/here_and_root/
This example represents a minimal out-of-source build, which is nevertheless involving several files, due to the inherent complexity of out-of-source builds.
Create a source/ directory with the following source/plan.py:
#!/usr/bin/env python3
from stepup.core.api import mkdir, plan, static
static("sub/", "sub/plan.py")
mkdir("../public/")
plan("sub/")
Also create a source/sub/ directory with a file source/sub/example.txt (arbitrary contents)
and the following source/sub/plan.py:
#!/usr/bin/env python3
from stepup.core.api import copy, mkdir, static
static("example.txt")
dst = "${ROOT}/../public/${HERE}/"
mkdir(dst)
copy("example.txt", dst)
Make the scripts executable and run everything as follows:
You should get the following terminal output:
0/0 | DIRECTOR │ Listening on /tmp/stepup-########/director (StepUp 3.0.0)
0/0 | STARTUP │ (Re)initialized boot script
0/0 | DIRECTOR │ Launched worker 0
0/1 | PHASE │ run
0/1 | START │ runpy ./plan.py
1/3 | SUCCESS │ runpy ./plan.py
1/3 | START │ mkdir ../public/
2/3 | SUCCESS │ mkdir ../public/
2/3 | START │ runpy ./plan.py # wd=sub/
3/5 | SUCCESS │ runpy ./plan.py # wd=sub/
3/5 | START │ mkdir ../../public/sub/ # wd=sub/
4/5 | SUCCESS │ mkdir ../../public/sub/ # wd=sub/
4/5 | START │ copy example.txt ../../public/sub/example.txt # wd=sub/
5/5 | SUCCESS │ copy example.txt ../../public/sub/example.txt # wd=sub/
5/5 | DIRECTOR │ Trying to delete 0 outdated output(s)
5/5 | DIRECTOR │ Stopping workers
5/5 | DIRECTOR │ See you!
The top-level plan.py provides some infrastructure:
some static files and creating the public directory where the outputs will be created.
The script sub/plan.py uses the ROOT and HERE variables in a way
that is independent of the location of this sub/plan.py.
It may therefore be fixed in an environment variable, for example:
Then you can get this path in any plan.py as follows:
The back=True option implies that the variable is a path defined globally.
If it is a relative path, it will be interpreted relative to the working directory where
StepUp was started and will be translated to the working directory of the script calling
getenv().
Any variables present in the environment variable will also be substituted once.
Try the Following¶
-
Modify the scripts
plan.pyandsub/plan.pyto utilize aDSTvariable as explained above. To achieve this, defineDSTexternally, for instance, by starting StepUp asDST='../public/${HERE}' stepup boot -n 1. -
As a follow-up to the previous point, run StepUp with a different
DSTvalue. For example:DST='../out/${HERE}' stepup boot -n 1. You will see that all old output files get cleaned up after the new output is created.