Examples

Building a command tree

julia> using ComposableCommands
julia> show_cmd = Command("show", [ShortFlag("n")], ["origin"], [])show -n origin
julia> remote_cmd = Command("remote", [LongFlag("verbose")], [], [show_cmd])remote --verbose └─ show -n origin
julia> git_cmd = Command("git", [], [], [remote_cmd])git └─ remote --verbose └─ show -n origin
julia> git_cmdgit └─ remote --verbose └─ show -n origin
julia> interpret(git_cmd)`git remote --verbose show -n origin`

Redirecting input and output

julia> using ComposableCommands
julia> sort_cmd = Command("sort", [ShortFlag("n")], [], [])sort -n
julia> redirected_in = RedirectedCommand("numbers.txt", sort_cmd)< numbers.txt └─ sort -n
julia> redirected_out = RedirectedCommand(sort_cmd, "sorted.txt")> sorted.txt └─ sort -n
julia> interpret(redirected_in)pipeline(`sort -n`, stdin<Base.FileRedirect("numbers.txt", false))
julia> interpret(redirected_out)pipeline(`sort -n`, stdout>Base.FileRedirect("sorted.txt", false))

Pipelining and parallel composition

julia> using ComposableCommands
julia> cut_cmd = Command("cut", [ShortOption("d", ":"), ShortOption("f", 3)], ["/etc/passwd"], [])cut -d : -f 3 /etc/passwd
julia> sort_cmd = Command("sort", [ShortFlag("n")], [], [])sort -n
julia> tail_cmd = Command("tail", [ShortOption("n", 5)], [], [])tail -n 5
julia> pipeline_cmd = OrCommands(OrCommands(cut_cmd, sort_cmd), tail_cmd)| ├─ | │ ├─ cut -d : -f 3 /etc/passwd │ └─ sort -n └─ tail -n 5
julia> left_echo = Command("echo", [], ["hello"], [])echo hello
julia> right_echo = Command("echo", [], ["world"], [])echo world
julia> parallel_cmd = AndCommands(left_echo, right_echo)&& ├─ echo hello └─ echo world
julia> interpret(pipeline_cmd)pipeline(pipeline(`cut -d : -f 3 /etc/passwd`, stdout=`sort -n`), stdout=`tail -n 5`)
julia> interpret(parallel_cmd)`echo hello` & `echo world`

Traversing and printing

julia> using ComposableCommands
julia> using AbstractTrees
julia> vasp_cmd = Command("vasp", [], [], [])vasp
julia> ibrun_cmd = Command("ibrun", [ShortOption("n", 8)], [], [vasp_cmd])ibrun -n 8 └─ vasp
julia> job_cmd = RedirectedCommand(ibrun_cmd, "output.log")> output.log └─ ibrun -n 8 └─ vasp
julia> collectnodes(job_cmd)3-element Vector{ComposableCommands.AbstractCommand}: > output.log └─ ibrun -n 8 └─ vasp ibrun -n 8 └─ vasp vasp
julia> print_tree(job_cmd)> output.log └─ ibrun -n 8 └─ vasp

Other examples

The following snippets show how you can build commands equivalent to common slurm invocations and a singularity shell command. The goal is to construct the same argument lists programmatically.

julia> using ComposableCommands
julia> srun1 = Command("srun", [ShortOption("N", 2), ShortOption("B", "4-4:2-2")], ["a.out"], []) # srun -N2 -B 4-4:2-2 a.outsrun -N 2 -B 4-4:2-2 a.out
julia> interpret(srun1)`srun -N 2 -B 4-4:2-2 a.out`
julia> server = Command("server", [ShortOption("n", 16), LongOption("mem-per-cpu", "1gb")], [], [])server -n 16 --mem-per-cpu=1gb
julia> client = Command("client", [], [], [])client
julia> srun2 = Command("srun", [ShortOption("n", 1), ShortOption("c", 8), LongOption("mem-per-cpu", "2gb")], [], [server, client]) # srun -n1 -c8 --mem-per-cpu=2gb server : -n16 --mem-per-cpu=1gb clientsrun -n 1 -c 8 --mem-per-cpu=2gb ├─ server -n 16 --mem-per-cpu=1gb └─ client
julia> interpret(srun2)`srun -n 1 -c 8 --mem-per-cpu=2gb server -n 16 --mem-per-cpu=1gb client`
julia> srun3 = Command("srun", [LongOption("nodes", [1, 5, 9, 13])], ["./test"], []) # srun --nodes=1,5,9,13 ./testsrun --nodes=1,5,9,13 ./test
julia> interpret(srun3)`srun --nodes=1,5,9,13 ./test`
julia> sinfo = Command("sinfo", [ShortFlag("N"), ShortOption("O", ("nodelist", "partition", "cpusstate", "memory", "allocmem", "freemem"))], [], []) # sinfo -N -O nodelist,partition,cpusstate,memory,allocmem,freememsinfo -N -O nodelist,partition,cpusstate,memory,allocmem,freemem
julia> interpret(sinfo)`sinfo -N -O nodelist,partition,cpusstate,memory,allocmem,freemem`
julia> sbatch = Command("sbatch", [LongOption("time", "25-00:00:00")], ["my_short_script.sh"], []) # sbatch --time 25-00:00:00 my_short_script.shsbatch --time=25-00:00:00 my_short_script.sh
julia> interpret(sbatch)`sbatch --time=25-00:00:00 my_short_script.sh`
julia> scontrol = Command("scontrol", [], ["update", "JobId=12345678", "TimeLimit=25-00:00:00"], []) # scontrol update JobId=12345678 TimeLimit=25-00:00:00scontrol update JobId=12345678 TimeLimit=25-00:00:00
julia> interpret(scontrol)`scontrol update JobId=12345678 TimeLimit=25-00:00:00`
julia> squeue = Command("squeue", [ShortOption("o", "%.18i %.9P %.70j %.8u %.2t %.10M %.6D %4C %10m %15R %20p %7q %Z")], [], []) # squeue -o "%.18i %.9P %.70j %.8u %.2t %.10M %.6D %4C %10m %15R %20p %7q %Z"squeue -o %.18i %.9P %.70j %.8u %.2t %.10M %.6D %4C %10m %15R %20p %7q %Z
julia> interpret(squeue)`squeue -o '%.18i %.9P %.70j %.8u %.2t %.10M %.6D %4C %10m %15R %20p %7q %Z'`
julia> srun_gpu = Command("srun", [LongOption("gpus", 1), ShortOption("p", "gpu"), LongFlag("pty")], ["bash"], []) # srun --gpus 1 -p gpu --pty bashsrun --gpus=1 -p gpu --pty bash
julia> interpret(srun_gpu)`srun --gpus=1 -p gpu --pty bash`