Next: , Previous: , Up: API  


1.3 (maak dsl)

1.3.1 Macros

Macro: get-module-var x

Get a variable from the currently loaded maak file module.

Macro: job-command x

Undocumented macro.

Macro: job-pid x

Undocumented macro.

Macro: job? x

Undocumented macro.

Macro: pipeline-errors x

Undocumented macro.

Macro: pipeline-outputs x

Undocumented macro.

Macro: pipeline-result? x

Undocumented macro.

Macro: stage? x

Undocumented macro.

Macro: text x

Undocumented macro.

1.3.2 Parameters

Parameter: banner?

Default value:

#t
Parameter: dry-run?

Default value:

#f
Parameter: elevation-command

Default value:

"sudo"
Parameter: maak-load-path

Default value:

()
Parameter: quiet?

Default value:

#f

1.3.3 Procedures

Procedure: $ cmd-parts KEY: #:verbose? #:join #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Executes a shell command constructed from a list of strings.

($ '("echo -n" "hello-world"))

;; as root, in the background, quietly, and without caring whether it fails
($ '("systemctl daemon-reload")
   #:sudo? #t #:async? #t #:dev-null? #t #:allow-failure? #t)

ARGUMENTS:

  • cmd-parts (list): A list of strings that will be joined to form the command.
  • #:verbose? (boolean, default #f): If #t, logs the generated command before executing it.
  • #:join (string, default " "): A string to use as a separator when joining the command parts.
  • #:env (alist, list of strings, or string, default ’()): Environment variables to set for this command only, given as an alist ((("CI" . "1"))), as "KEY=VALUE" strings, or as one such string. They are passed through env and reach the command itself.
  • #:sudo? (boolean, default #f): If #t, the command runs through the configured privilege escalation command – doas when it is installed, sudo otherwise, or whatever MAAK_ELEVATE names. See elevation-command.
  • #:dev-null? (boolean, default #f): If #t, both standard output and standard error are discarded to /dev/null.
  • #:allow-failure? (boolean, default #f): If #t, a non-zero exit code does not raise: #f is returned instead, so a task can decide what a failure means. The command line itself is left alone, which is what lets the task be told the command failed.
  • #:async? (boolean, default #f): If #t, the command is started in the background and a job record is returned (see run), instead of a boolean.

RETURNS: The result of the syscall function: #t if the command completes with an exit code of 0, #f if it failed and #:allow-failure? was given, and a job record when #:async? was given.

Procedure: add-load-path! dir

Prepend DIR to Guile’s load path and record it as a maak load path.

Returns the canonical name of the directory that was added, which makes it usable in a ‘let’ when a task wants to report what it did. This is a procedure rather than the ‘add-to-load-path’ syntax because a task computes the directory at run time.

Procedure: add-load-paths! dirs

Prepend every directory of DIRS to the load path, in order.

Returns the list of directories that were added.

Procedure: blank-line? str

Return #t when STR is empty or only whitespace.

Procedure: bold-output x

Undocumented procedure.

Procedure: cat file KEY: #:verbose? #:expand?

Print FILE to standard output.

Procedure: command-on-path? command path

Return #t when COMMAND is an executable in one of the directories in PATH.

Procedure: cp x y KEY: #:recursive? #:force? #:verbose? #:verbose-copy? #:expand?

Copy a file or directory from X to Y.

ARGUMENTS: x: Source file or directory. y: Destination path.

recursive?: If #t, copy directories recursively (‘-r‘). Defaults to #t. force?: If #t, overwrite existing files without prompting (‘-f‘). Defaults to #f. verbose?: If #t, logs the final shell command before execution. Defaults to #f. verbose-copy?: If #t, enables verbose output from ‘cp‘ (‘-v‘). Defaults to #t. expand?: If #t, the shell expands X and Y, so a wildcard names the files it matches. Defaults to #f, which passes both as one argument each.

Constructs and executes a command of the form:

cp [OPTIONS] X Y

through ‘run‘, so X and Y reach ‘cp‘ as one argument each and a path with a space in it is copied rather than split.

RETURNS: #t if the copy succeeds.

ERRORS: Signals an error if the underlying ‘cp‘ command exits with a non-zero status.

Procedure: decorate-command cmd KEY: #:env #:sudo? #:dev-null?

Return CMD with the decorations a task asked for, applied in a fixed order.

The environment comes first and goes through ‘env’ rather than as a ‘KEY=VALUE’ prefix, because everything after a ‘guix shell –’ is executed directly: a prefix there would be looked up as a program name and fail with 127.

Whether a failure is allowed is not a decoration of the command line at all; ‘syscall’ reads the exit code, which a ‘|| true’ in the line would have hidden. Backgrounding is not one either: a trailing ‘&’ leaves nothing to wait on, so ‘#:async?’ forks instead and hands back a job (see ‘run’).

Procedure: dedent-string str

Remove the common leading indentation from a multiline STR.

Tabs are expanded to four spaces, leading and trailing blank lines are removed, and the smallest indentation shared by the remaining lines is stripped from all of them. Blank lines in the middle are preserved as empty lines.

(dedent-string "   hello world")
⇒ "hello world"
Procedure: delete-file-recursively dir KEY: #:verbose? #:expand?

Delete a directory and all its contents recursively. Runs ‘rm -rfv DIR‘ through ‘run‘, so DIR reaches ‘rm‘ as one argument however it is spelled. The deletion is recursive, forced and verbose.

With EXPAND? #t the shell expands DIR, so ‘build/*.o’ names every matching file; the same opt-in applies to the other file helpers via ‘run’.

ARGUMENTS:

  • dir (string): The path of the directory (or file) to delete.
  • #:verbose? (boolean, default #f): If #t, logs the generated command before executing it.

RETURNS: #t if the command succeeded.

ERRORS: Signals an error if the underlying shell command exits with a non-zero status.

Procedure: detect-elevation-command KEY: #:path #:preferred

Return the command maak should use to run something as root.

PREFERRED, when non-empty, wins unchanged, which is how ‘MAAK_ELEVATE’ lets a user name an escalation program maak has never heard of. Otherwise ‘doas’ is chosen when it is on PATH, and ‘sudo’ when it is not: ‘doas’ is the smaller tool and the one a machine that has it usually means, while ‘sudo’ remains the fallback every other system understands.

PATH is the search path, ‘PATH’ itself by default, so the function can be tested without changing the process environment.

(detect-elevation-command #:path "/usr/bin:/bin")     ;; => "sudo"
(detect-elevation-command #:preferred "doas -n")      ;; => "doas -n"
Procedure: environment-assignments env

Return ENV as a list of ‘KEY=VALUE’ strings.

ENV may be #f, a single string, a list of strings, or an alist of pairs, so a caller can pass whatever shape it already has. An entry that is not a pair is used as it stands, which is what makes the plain string list useful when a value cannot be written as a literal.

Procedure: environment-load-paths

Return the directories named by ‘MAAK_LOAD_PATH’.

‘GUILE_LOAD_PATH’ is already honoured by Guile itself and is deliberately not merged here; this is the maak-specific extra so a task can add paths without clobbering the user’s global setting.

Procedure: error-message-string key vals

Return the most descriptive string Guile attached to a caught error.

The shape of the arguments depends on who raised the error. A call to ‘error’ arrives as (#f MESSAGE () #f), where the message is the second element, while a primitive failure such as ‘(car 1)’ arrives as (#f MESSAGE (1) (1)) whose *first* string is only the name of the procedure – reporting that as the message would hide the one sentence the user needs. The second element is the message in both shapes, so it is preferred, and the remaining values are searched only when it is not a string, as when ‘throw’ is handed a key and a message but no irritants.

Procedure: exception->message key vals

Return a one-line human message for a caught error.

It prefers an attached exception message, then the message among the raising values, and only then falls back to the raw key. Guile raises many errors with a format *template* (for example ‘no code for module ~S’) plus the arguments; those are filled in here so the user never sees a bare ‘~S’.

Procedure: find-maak-error key vals

Return the ‘&maak-error’ among KEY and VALS, or ‘#f’.

Guile hands a ‘catch’ handler the raising key followed by its values; a ‘raise-exception’ of our condition type arrives as the first value, so both are searched. This is what lets ‘main’ tell our own messages apart from internal errors.

Procedure: guix-container cmd-parts KEY: #:manifest #:pure? #:network? #:share #:expose #:join #:verbose? #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Run CMD-PARTS in a Guix container defined by MANIFEST.

A container isolates the process from the host: no network unless NETWORK? is #t, no access to the home directory unless it is SHARE’d. SHARE and EXPOSE are lists of ‘HOST=DEST’ (or ‘HOST’) strings passed through as ‘-S’ and ‘-E’.

(guix-container '("maak test")
                #:manifest "manifest.scm"
                #:share '("/home/joe"))
Procedure: guix-pack cmd-parts KEY: #:file #:format #:image-tag #:symlinks #:extra-packages #:join #:verbose? #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Build a ‘guix pack’ of the program in FILE.

FORMAT is any ‘guix pack –format’ value ("docker", "squashfs", "tarball"). IMAGE-TAG names a docker image, SYMLINKS are ‘TARGET=SOURCE’ entries for ‘-S’, and EXTRA-PACKAGES are appended to the pack.

(guix-pack '() #:format "docker" #:image-tag "maak"
           #:symlinks '("/bin=bin") #:extra-packages '("bash"))
Procedure: guix-shell cmd-parts KEY: #:packages #:pure? #:manifest #:file #:join #:verbose? #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Run CMD-PARTS inside a Guix shell made of PACKAGES.

This is the package-list sibling of ‘manifest-shell’ and ‘program-shell’: the environment is described inline rather than in a manifest or a ‘guix.scm’. PACKAGES may be a list of strings ("guile", "coreutils") or a single string, which is used as-is.

(guix-shell '("guile -c '(+ 1 2)'") #:packages '("guile"))
Procedure: indent-string str KEY: #:by #:first?

Indent every line of STR by BY spaces.

When FIRST? is #f the first line is left flush, which is what aligning a continuation underneath an existing prefix needs.

Procedure: job-done? job

Return #t when JOB has finished, without waiting for it.

A finished job is reaped here, so a background process that a task never waits for does not stay a zombie for the rest of the run.

Procedure: job-exit-code job

Wait for JOB when needed and return its exit code.

Returns #f when the process was terminated by a signal, which is also what ‘status:exit-val’ says about such a status.

Procedure: leading-whitespace-count str

Return the number of leading space and tab characters in STR.

Procedure: log-error msg . args

Undocumented procedure.

Procedure: log-info msg . args

Undocumented procedure.

Procedure: log-message msg

Undocumented procedure.

Procedure: log-separator

Undocumented procedure.

Procedure: maak-error-hint obj

Undocumented procedure.

Procedure: maak-error-message obj

Undocumented procedure.

Procedure: maak-error? obj

Undocumented procedure.

Procedure: maak-proc? x

Predicate that indicates whether a procedure is a valid maak proc.

Procedure: maak-task? x

Predicate that indicates whether it is a valid maak task.

Procedure: make-maak-error a b

Undocumented procedure.

Procedure: manifest-shell cmd-parts KEY: #:verbose? #:pure? #:join #:manifest #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Execute a command inside a Guix shell defined by a manifest file.

ARGUMENTS:

cmd-parts: A list of strings representing the command to run inside the Guix shell environment.

#:verbose?: If #t, logs the fully constructed command before execution. Defaults to #f. #:pure?: If #t, it will run in a pure isolated shell (clean). Defaults to #f. #:join: The string separator used when joining command segments. Defaults to a single space. #:manifest: Path to the manifest file (in Scheme) describing the package environment. Defaults to "manifest.scm".

Constructs and executes a command of the form:

    guix shell -m MANIFEST -- <cmd ...>

using the ‘$‘ wrapper to enforce proper execution and error handling.

RETURNS: #t if the command succeeds.

ERRORS: Signals an error if the underlying shell command exits with a non-zero status.

Procedure: mkdir-p dir KEY: #:verbose? #:expand?

Create a directory and all necessary parent directories. Executes ‘mkdir -pv DIR‘ through ‘run‘. Parent directories are created as needed and each created directory is printed. A DIR that contains spaces is one directory, not several.

ARGUMENTS:

  • dir: The path of the directory to create.
  • #:verbose? (boolean, default #f): If #t, logs the generated command before executing it.

RETURNS: #t if the command completed successfully.

ERRORS: Signals an error if the underlying shell command exits with a non-zero code.

Procedure: mv x y KEY: #:verbose? #:expand?

Move or rename a file or directory. Executes ‘mv -v X Y‘ through ‘run‘, so X and Y reach ‘mv‘ as one argument each. The ‘-v‘ flag prints each move operation performed.

ARGUMENTS:

  • x (string): The source file or directory.
  • y (string): The destination path.
  • #:verbose? (boolean, default #f): If #t, logs the generated command before executing it.

RETURNS: #t if the command succeeds.

ERRORS: Signals an error if the underlying shell command returns a non-zero exit code.

Procedure: pipeline-ok? result

Return #t when every stage of the pipeline that produced RESULT succeeded.

RESULT is what ‘run-pipeline’ returns when asked to capture the output, whether or not failures were allowed.

Procedure: program-shell cmd-parts KEY: #:verbose? #:pure? #:join #:file #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Execute a command inside a Guix shell defined by a program file.

ARGUMENTS: cmd-parts: A list of strings representing the command to run inside the Guix shell environment.

#:verbose?: If #t, logs the full constructed command before execution. Defaults to #f.

#:join: String used to join command segments. Defaults to a single space. #:file: Path to the Guix program or manifest file defining the shell environment. Defaults to "guix.scm".

Constructs and executes a command of the form:

    guix shell -f FILE -- <cmd ...>

using the ‘$‘ wrapper to safely run the command and check for errors.

RETURNS: #t if the command succeeds.

ERRORS: Signals an error if the underlying shell command exits with a non-zero status.

Procedure: raise-maak-error message KEY: #:hint

Raise a ‘&maak-error’ with MESSAGE and an optional HINT.

MESSAGE is the single line the user reads; HINT, when given, is printed underneath as a suggestion for what to do next. Prefer this over ‘error’ in library code so the CLI can keep the report short.

Procedure: remkdir-p dir KEY: #:verbose? #:expand?

Remove a directory if it exists, then recreate it. This results in an empty directory, regardless of its previous state. Calls ‘delete-file-recursively‘ then ‘mkdir-p‘ on DIR.

ARGUMENTS:

  • dir: The path of the directory to recreate.
  • #:verbose? (boolean, default #f): If #t, logs the generated command before executing it.

RETURNS: #t if the operations succeed.

ERRORS: Signals an error if any underlying shell command fails.

Procedure: rm-rf path KEY: #:verbose? #:expand?

Delete PATH recursively, forcefully and verbosely.

A short spelling of delete-file-recursively, for the times a task says rm -rfv build in the shell. It is an alias rather than a second implementation, so it takes the same #:verbose? and #:expand? keywords and behaves the same way.

(rm-rf "build")
(rm-rf "build/*.o" #:expand? #t)
Procedure: run argv KEY: #:verbose? #:env #:sudo? #:dev-null? #:allow-failure? #:async? #:expand?

Run a program and its arguments without a shell.

ARGV is a list of strings: the program to run, followed by one string per argument. Nothing is split or interpolated, so a path with a space in it stays one argument. This is the default way to run a program; ‘$’ is for the lines that genuinely need a shell – pipes, redirections, globs, ‘$(...)’ and ‘VAR=value’ prefixes.

With #:expand? #t the arguments are joined with spaces and handed to the shell, so wildcards, ‘~’ and ‘$VAR’ are expanded the way a shell expands them. That is opt-in because the shell sees words rather than arguments: a path with a space in it becomes several words again, which is exactly what a caller asking for a pattern wants and exactly what the default prevents.

(run (list "mkdir" "-p" build-dir))
(run (list "git" "commit" "-m" message))

;; start a server in the background and wait for it later
(let ((server (run (list "guix" "shell" "--" "run-server")
                   #:async? #t)))
  (log-info "server started as ~a
" (job-pid server))
  (wait-job server))

ARGUMENTS:

  • argv (list): The program and its arguments, each a string.
  • #:verbose? (boolean, default #f): If #t, logs the command before running it.
  • #:env (alist, list of strings, or string, default ’()): Environment variables for this program only, in the shapes ‘$’ accepts.
  • #:sudo? (boolean, default #f): If #t, the program runs through the configured privilege escalation command – doas when it is installed, sudo otherwise, or whatever MAAK_ELEVATE names. See elevation-command.
  • #:dev-null? (boolean, default #f): If #t, standard output and standard error are connected to /dev/null.
  • #:allow-failure? (boolean, default #f): If #t, a non-zero exit code does not raise: #f is returned instead.
  • #:async? (boolean, default #f): If #t, the program is started in the background and a job record is returned.
  • #:expand? (boolean, default #f): If #t, ARGV is joined into one shell line and the shell expands wildcards, ‘~’ and ‘$VAR’ in it. The arguments are then words rather than literals.

RETURNS: #t if the program exits with code 0, #f if it failed and failures were allowed, and a job record when #:async? was given.

ERRORS: Signals a maak error when the program exits non-zero and failures are not allowed.

Procedure: run-pipeline stages KEY: #:verbose? #:allow-failure? #:env #:async? #:capture?

Run a pipeline of programs without a shell.

STAGES is a non-empty list of stages. A stage is an argument list shaped like the ARGV of ‘run’ – the program first, then one string per argument – or a stage form, which adds the options ‘run’ takes for that stage alone. The standard output of each stage is the standard input of the next, and the whole pipeline is done when every stage has finished.

(run-pipeline (list (list "cat" file)
                    (list "grep" "-v" "^#")
                    (list "sort" "-u")))

;; a stage with an environment and a file of its own, and one that needs root
(run-pipeline (list (stage (list "sort" "-u")
                           #:env '("LC_ALL=C")
                           #:tee "sorted.txt")
                    (stage (list "tee" log) #:sudo? #t)))

;; keep what every stage wrote for the task to look at
(define result (run-pipeline (list (list "git" "diff" "--cached")
                                   (list "grep" "^+"))
                             #:capture? #t
                             #:allow-failure? #t))
(pipeline-outputs result)   ;; one string per stage, in order
(pipeline-ok? result)       ;; #f when a stage failed

Unlike a shell’s ‘|’, which reports the exit status of the last stage alone, a pipeline that fails anywhere reports the stages that failed and raises; pass #:allow-failure? #t to get #f instead and decide in the task. This is the pipefail behaviour, and it is the one that does not let a failing producer hide behind a successful consumer.

A pipeline’s output can be looked at afterwards in two ways. A stage with #:tee keeps a copy of what it wrote in a file the task names, and the stage after it reads the same bytes while it runs: nothing is held back until the pipeline ends. #:capture? #t records every stage the same way, in temporary files, and hands the bytes back in the result instead of printing them; the last stage’s output is then the last entry of pipeline-outputs. Capturing is the way to make a decision from what a pipeline produced – a count of changed files, the list a ‘grep’ matched – without running the pipeline twice.

ARGUMENTS:

  • stages (list): The stages to run, each an argument list or a stage.
  • #:verbose? (boolean, default #f): If #t, logs the pipeline, decorations included, before running it.
  • #:allow-failure? (boolean, default #f): If #t, a failing stage does not raise: #f is returned instead (or the result, when the output was captured), so the task can decide what it means.
  • #:env (alist, list of strings, or string, default ’()): Environment variables for every stage of the pipeline, in the shapes ‘$’ accepts. A stage’s own #:env is added to these, later names winning.
  • #:capture? (boolean, default #f): If #t, every stage’s standard output is recorded and returned in a <pipeline-result>, and the pipeline prints nothing itself. The result’s pipeline-outputs holds one string per stage, in stage order, and pipeline-ok? says whether every stage succeeded. A stage that also has #:tee records into that file, which is left in place.
  • #:async? (boolean, default #f): If #t, the whole pipeline is started in the background and a job record is returned. It is the pipeline that becomes a job, not a stage: a stage cannot finish before the stage after it has read what it wrote. The job’s exit code is 0 when every stage succeeded and 1 otherwise, whatever #:allow-failure? said. An asynchronous pipeline cannot capture its output, because the bytes would be read in the background process; give the stage a #:tee file instead.

RETURNS: #t when every stage exits with code 0, #f when a stage failed and failures were allowed, a <pipeline-result> when #:capture? was given, and a job record when #:async? was given.

ERRORS: Signals a maak error naming the failing stage or stages when a pipeline fails and failures are not allowed, and when #:capture? and #:async? are asked for together.

Procedure: shell-quote str

Return STR quoted so that a shell reads it as one literal word.

The POSIX recipe: wrap the value in single quotes and turn every embedded single quote into the four characters backslash-quote-quote-quote. Unlike ‘~s’, this is safe for spaces, tabs, ‘$’, backticks and newlines.

Procedure: split-load-path str

Split a ‘PATH’-style colon separated STR into a list of directories.

An empty entry is dropped, so a trailing or doubled colon does not add the current directory twice.

Procedure: stage argv KEY: #:env #:sudo? #:tee

Describe one stage of a pipeline, with the options ‘run’ takes.

ARGV is a program and its arguments, in the shape ‘run’ takes them. ENV sets names for this stage alone, in the shapes ‘$’ accepts; they are added to the pipeline’s own environment, later names winning. With SUDO? the stage runs through the configured privilege escalation command (see ‘elevation-command’). TEE names a file that the stage’s standard output is also written to, the way ‘tee’ does it: the stage after this one reads the same bytes, and the file keeps them for the task to look at once the pipeline is done.

(run-pipeline (list (stage (list "grep" "-v" "^#")
                           #:env '("LC_ALL=C")
                           #:tee "clean.txt")
                    (stage (list "sort" "-u"))))

A stage is a description only; ‘run-pipeline’ starts it.

Procedure: string-lines str

Split STR on newlines into a list of lines.

Procedure: syscall cmd KEY: #:allow-failure? #:async?

Executes a shell command and checks its exit code.

ARGUMENTS:

  • cmd (string): The shell command to be executed.
  • #:allow-failure? (boolean, default #f): If #t, a non-zero exit code does not raise: it comes back as #f, the way ‘cmd || true’ would keep a shell going, except that the task also learns that the command failed.
  • #:async? (boolean, default #f): If #t, the command is started in the background and a job record is returned instead of a boolean. The command still runs through a shell, so pipes and redirections keep working, but the fork is maak’s: ‘job-pid’, ‘job-done?’, ‘wait-job’ and ‘job-exit-code’ can read the process.

RETURNS: #t if the command completes with an exit code of 0, #f if it failed and failures are allowed, and a job record when #:async? was given.

ERRORS: Signals an error if the command returns a non-zero exit code, providing the command and the exit code in the error message.

Procedure: task-error message KEY: #:hint #:args

Raise a user-facing error from a task.

This is what a task calls when it cannot do its job: the message is printed as one line, the hint (when given) underneath it, and no Guile backtrace follows. ARGS, when given, are handed to ‘format’ to build the message, so a task can report the value that made it give up.

(task-error "no compiled artefact for ~a" #:args (list host))
(task-error "the deploy key is missing"
            #:hint "Set DEPLOY_KEY, or run maak deploy --dry-run.")
Procedure: time-machine cmd-parts KEY: #:verbose? #:join #:channels #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Execute a command using a pinned Guix revision via ‘guix time-machine‘.

ARGUMENTS: cmd-parts: A list of strings representing the command to run after the ‘guix time-machine‘ invocation.

#:verbose?: If #t, logs the final constructed command before running it. Defaults to #f. #:join: The string used to join command segments when constructing the final command. Defaults to a single space. #:channels: Path to the channels file used to pin the Guix revision. Defaults to "channels.scm".

Constructs and executes a command of the form:

    guix time-machine --channels=CHANNELS -- <cmd ...>

using the ‘$‘ wrapper to run the resulting shell command safely.

RETURNS: #t if the command succeeds.

ERRORS: Signals an error if the underlying command exits with a non-zero status.

Procedure: time-machine-manifest-shell cmd-parts KEY: #:verbose? #:pure? #:join #:channels #:manifest #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Execute a command inside a Guix shell defined by a manifest file, using a pinned Guix revision via ‘guix time-machine‘.

ARGUMENTS: cmd-parts: A list of strings representing the command to run inside the pinned Guix shell environment.

#:verbose?: If #t, logs the composed command before execution. Defaults to #f. #:pure?: If #t, it will run in a pure isolated shell (clean). Defaults to #f. join: String used to join command segments. Defaults to a single space. #:channels: Path to the channels file used to pin the Guix revision. Defaults to "channels.scm". #:manifest: Path to the manifest file describing the package environment. Defaults to "manifest.scm".

Constructs and executes a command of the form:

    guix time-machine --channels=CHANNELS -- shell -m MANIFEST -- <cmd ...>

This provides a reproducible shell environment defined by the manifest file and pinned to the Guix revision specified in the channels file.

RETURNS: #t if the command succeeds.

ERRORS: Signals an error if any underlying shell command exits with a non-zero status.

Procedure: time-machine-program-shell cmd-parts KEY: #:verbose? #:pure? #:join #:channels #:file #:env #:sudo? #:dev-null? #:allow-failure? #:async?

Execute a command inside a Guix shell defined by a program file, using a pinned Guix revision via ‘guix time-machine‘.

ARGUMENTS: cmd-parts: A list of strings representing the command to run inside the pinned Guix shell environment.

#:verbose?: If #t, logs the composed command before execution. Defaults to #f. #:pure?: If #t, it will run in a pure isolated shell (clean). Defaults to #f. #:join: String used to join command segments. Defaults to a single space. #:channels: Path to the channels file used to pin the Guix revision. Defaults to "channels.scm". #:file: Path to the Guix program file (e.g. guix.scm) defining the environment. Defaults to "guix.scm".

Constructs and executes a command of the form:

    guix time-machine --channels=CHANNELS -- shell -f FILE -- <cmd ...>

This provides a reproducible development environment defined by the program file and pinned to the Guix revision specified in the channels file.

RETURNS: #t if the command succeeds.

ERRORS: Signals an error if any underlying shell command exits with a non-zero status.

Procedure: unlines lines

Join LINES with newlines, adding no trailing newline.

Procedure: unwords words

Join WORDS with single spaces.

Procedure: wait-job job

Wait for JOB to finish and return #t when it exited with code 0.

Returns #f for a non-zero exit or a signal. Waiting twice is fine: the status is remembered after the first wait.

Procedure: with-load-path dirs thunk

Call THUNK with DIRS added to the load path, restoring it afterwards.

DIRS is a list of directory names. The load path is saved and restored even when THUNK raises, so a failing task does not leave the process with a polluted search path.

(with-load-path '("./lib" "./src")
  (lambda () (use-modules (my project))))
Procedure: ~ . args

A utility function to format a string (interpolation). Alias for (apply format #f ARGS).

(~ "Hello world, my name is ~a and I am ~a years old"
    "Joe"
    30)

ARGUMENTS:

  • args (list): A list of arguments where the first element is the format string and the subsequent elements are the values to be substituted.

RETURNS: A newly allocated string resulting from the formatting operation.

1.3.4 Record Types

Record type: &maak-error

This record type has the following fields:

  • message
  • hint

Next: (maak git), Previous: (maak container), Up: API