Introduction to Technetium

The Shell Operator

Technetium is designed around making accessing shell commands as easy as possible. The core of this design is the shell operator ($). If you begin a line with the shell operator, it will be run on the command line:

my_name = "matt"
$ echo {my_name}

This code, when run, will invoke the echo command, substituting the value of the expression my_name, which has the effect of printing out matt to the console.

The shell operator makes it very easy to write long chains of commands in a similar style to a bash script. Similar to bash, each command will run synchronously and in the foreground. The sh function can be used to create process objects, which can be assigned to variables, spawned in the background, or even passed to functions:

delayed_command = sh("sleep 10 && echo Ten seconds have passed!")
delayed_command.spawn()
# ... do more work ...

Technetium makes it very easy to surround shell code by easy to understand syntax:

for n in range(10) {
        if n <= 5 {
                $ mkdir {n}
        } else {
                $ mkdir {n}_other
                $ touch {n}_other/index.html
        }
}

Technetium as a Build System

Technetium can be used as a build system. The -r flag recursively searches up directories until it finds a make.tc file (this filename is configurable in several ways). It might be helpful to either put scripts/tcmake in your path, or to alias tcmake to tech -r to make it easier to use this feature, so that tcmake will make your current project.

In using technetium as a build system, one command that will come in handy is the stale command, which can be used to emulate systems such as make which check to see if files have changed since you’ve last built your project:

stale([list(string)]) or stale([string], [string], ...)  [list(string)]

Returns a list of which of the files given as an argument have changed since the last time this function was called. This function also accepts Unix glob-patterns (i.e. ./src/**/*):

if stale(["src/**/*.c", "main.c"]) {
    println("performing build...")
} else {
    println("nothing needs to be done!")
}

This code will print “performing build…” whenever any of the C source code files underneath the source directory, or the main.c file have changed since the last run of the script. It keeps track using the file at ./.tcmake/stale.cache.

It might be helpful to add script_path() as one of the files to check, in case updating the script itself should be of interest (i.e., in a build script).

One other example use case of stale is to keep files in sync between two seperate directories, only copying those that need to be updated. For example, to copy any recently changed files from dir_A to dir_B:

for file in stale(["dir_A/**/*"]) {
        # Find the path to the file within dir_A
        relative_path = strip_path_prefix(canonicalize(file), canonicalize("dir_A"))
        # Copy this file into dir_B
        $ cp {file} dir_B/{relative_path}
}