silk.cli.task.

Write a project's tasks in Silk: the program that silk task <name> and the manifest's [tasks] hooks run.

When to use#

Put a project's automation, such as code generation, fixtures, release steps or checks before silk pack, in src/tasks.silk instead of shell, Python or JavaScript scripts. The tasks are the variants of a union that describes the command line with silk.cli, so silk task with no name lists them, each task gets typed options, and a misspelled name gets a suggestion.

Details#

silk task builds the package's tasks profile, an executable for this machine whose root module is tasks.silk unless [profiles.tasks] says otherwise, and runs it from the package directory with the user's rights. The profile may add its own dependencies in [profiles.tasks.dependencies]; they are fetched only when the tasks build. A package's tasks never run where it is a dependency.

Task.main reads the command line, runs TaskSet.perform on the chosen task, and turns a TaskError into a one-line report and an exit status. Task.exec and Task.silk run other programs with the terminal and environment of the task. A task that needs another task calls it: tasks are ordinary functions.

The environment holds SILK_PROJECT_ROOT, the package directory; SILK_INVOCATION_DIRECTORY, where the command was typed; SILK_COMPILER, the compiler that built the tasks; and, in a hook, SILK_HOOK, such as before-build, and SILK_HOOK_RESULT, such as the silk pack --json object after silk pack.

Examples#

silk
import silk.cli.command { Command, CommandLine, Opt }
import silk.cli.task { Task, TaskError, TaskSet }
import silk.io.writer { WriterError }
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.system.child_process { ChildProcess, ProcessError }
import silk.system.filesystem { FileError, FileSystem }
import silk.system.host_input { HostInput, HostInputError }
import silk.text.string { String }

union Tasks {
  Codegen,
  Release { pub version: String },
}

impl CommandLine for Tasks {
  static fn command() -> Command<Tasks> {
    return Command<Tasks>.make("tasks", "This project's tasks")
      |> Command.variant("Codegen", "Regenerate the tables")
      |> Command.variant("Release", "Test and pack a release")
      |> Command.arg("version", Opt.about("The version") |> Opt.required)
  }
}

impl TaskSet for Tasks {
  effect fn perform(self: Tasks) -> ()
    ! TaskError | ProcessError | FileError | HostInputError | OutOfMemoryError | WriterError
    ? &mut HostInput | &mut Allocator | &mut ChildProcess | &mut FileSystem {
    match move self {
      Tasks.Codegen => run Task.exec("scripts/generate", &["--pinned"])
      Tasks.Release { version: _ } => {
        run Task.silk(&["test"])
        run Task.silk(&["pack"])
      }
    }
  }
}

pub effect fn main() -> i32 ? &mut HostInput {
  return run Task.main<Tasks>()
}

Import as Task with import silk.cli.task { Task }.

Public declarations: 3.

TaskError#

silk
pub struct TaskError

A task that failed: what to report, and the exit status the tasks program ends with.

Field message#

silk
pub message: String

The one line Task.main writes to standard error, after error: .

Field status#

silk
pub status: i32

The exit status, such as the status of a program that Task.exec ran. Never 0.

TaskSet#

silk
pub interface TaskSet

A command line whose variants are tasks.

Operation perform#

silk
effect fn perform(self: Self) -> ()
    ! TaskError | ProcessError | FileError | HostInputError | OutOfMemoryError | WriterError
    ? &mut HostInput | &mut Allocator | &mut ChildProcess | &mut FileSystem

Runs the task this value names, with its options.

Task#

silk
pub struct Task

The functions of a tasks program.

Implementation Task#

silk
impl Task

Associated function main#

silk
pub effect fn main<T: CommandLine + TaskSet>() -> i32 ? &mut HostInput

Reads the command line as T, runs the task it names, and answers the exit status: 0 when the task succeeded, 0 after --help, 2 after a command line error, and a failed task's TaskError.status after writing error: <message> to standard error. An unexpected failure, such as a file that cannot be read, is reported the same way with status 1.

Associated function abort#

silk
pub effect fn abort(message: string) -> never ! TaskError | OutOfMemoryError ? &mut Allocator

Fails the task with message and status 1.

Associated function exec#

silk
pub effect fn exec(program: string, arguments: &[string]) -> ()
    ! TaskError | HostInputError | OutOfMemoryError
    ? &mut HostInput | &mut Allocator | &mut FileSystem

Runs program with arguments and waits for it. The program shares the task's standard input, output and error, environment and working directory. A name without a / is looked up on PATH; a path is relative to the working directory, the package directory.

Errors#

TaskError when the program cannot be started, or ends with a nonzero status, which becomes the error's status.

Associated function execBytes#

silk
pub effect fn execBytes(program: &[u8], arguments: &[Bytes]) -> ()
    ! TaskError | HostInputError | OutOfMemoryError
    ? &mut HostInput | &mut Allocator | &mut FileSystem

Task.exec, for a program and arguments that need not be UTF-8.

Associated function silk#

silk
pub effect fn silk(arguments: &[string]) -> ()
    ! TaskError | HostInputError | OutOfMemoryError
    ? &mut HostInput | &mut Allocator | &mut FileSystem

Runs the compiler that built the tasks, SILK_COMPILER, with arguments, as Task.exec does, such as run Task.silk(&["test"]).

Errors#

TaskError when SILK_COMPILER is not set, or as Task.exec.

Associated function capture#

silk
pub effect fn capture(program: string, arguments: &[string]) -> Bytes
    ! TaskError | ProcessError | HostInputError | OutOfMemoryError | WriterError
    ? &mut HostInput | &mut Allocator | &mut ChildProcess | &mut FileSystem

Runs program with arguments to the end and answers its standard output. Its standard error is passed on to the task's. The program starts in the package directory with no environment but PATH, and a name without a / is looked up on PATH.

Errors#

TaskError when the program cannot be found, or ends with a nonzero status or a signal.

Associated function root#

silk
pub effect fn root() -> Path ! TaskError | HostInputError | OutOfMemoryError ? &mut HostInput | &mut Allocator

The package directory, SILK_PROJECT_ROOT, which is also the working directory a task starts in.

Errors#

TaskError when the variable is not set, as outside silk task.

Associated function invocationDirectory#

silk
pub effect fn invocationDirectory() -> Path ! TaskError | HostInputError | OutOfMemoryError ? &mut HostInput | &mut Allocator

The directory silk task was typed in, SILK_INVOCATION_DIRECTORY, for a task that takes paths relative to it.

Errors#

TaskError when the variable is not set, as outside silk task.

Category: Command line.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.

View the source of this page