Skip to content

api #

Description

After installing Clockwork, you can use it in a project by first creating a build.maple in the root of your codebase. Then, populate it with your plugins, configs, and tasks.

Here is an example config for a V project:

plugins = [ 'v' ]

task:doc = {
    help = 'Runs v doc for the API'
    run = 'v doc -m -f html -o doc/ api/'
}

task:clean_build = {
    help = 'Clean-builds the project'
    depends = [ 'clean', 'build' ]
}

task:release = {
    help = 'Bumps the version and builds the project in prod mode'
    run = [
        'v bump --minor v.mod',
        'v -prod build .'
    ]
}

Config Specification

Config files are wrote in Maple, a TOML-like config language made to be simple and fast to write in.

The parenthesis represent the type of the value. Text in [brackets] > represent text to be substituted with something else.

Tasks must be prefixed using task: and config values must be > prefixed using config:, otherwise Clockwork will not read them.

// Import other maple files, excluding the `.maple` extension. It will always
// search for files in this order:
//   - Local files (./some_plugin.maple)
//   - Global files (~/.config/plugins/some_plugin.maple)
//   - Global install (git-managed) files (~/.local/share/clockwork/config/plugins/some_plugin.maple)
// If all else fails, an error is thrown.
plugins ([]string)

// Allows you to configure how Clockwork displays its data. For the most part
// you should not use this, but some projects do prefer hiding some data or
// changing defaults. These settings are for said projects.
display (map) = {
    // The category to list tasks of when using `clockwork --tasks`.
    // No value means list all tasks.
    default_task_category (string)

    // How tasks should be listed in `clockwork --tasks`.
    // Values: `verbose` (default), `slim`
    default_task_list_mode (string)

    // A list of categories to exclude fron `clockwork --tasks`.
    task_list_exclude_categories ([]string)

    // A list of tasks to exclude fron `clockwork --tasks`.
    task_list_exclude_tasks ([]string)
}

// Declare a variable/configuration option.
config:[name] (string)

// Define a task. All fields within are optional.
task:[name] (map) = {
    // A help message for the task, displayed with `clockwork --tasks`
    help (string)

    // A category for the task, displayed with `clockwork --tasks`
    category (string)

    // A list of tasks that this one depends on. These are executed in the
    // same order they are defined. Duplicate entries are allowed.
    depends ([]string)

    // Allows you to define a custom working directory for this task.
    work_dir (string)

    // The command(s) to run. These are executed in your shell.
    run (string or []string)
}

Complex Tasks

For a task that may need more complex behaviour, you can use a .vsh file in another folder. For example:

// scripts/some_complex_task.vsh

println('Pretend this is really complex')

And in your config:

// build.maple

task:some_complex_task = {
    help = 'A really complex task'
    run = 'v scripts/some_complex_task.vsh'
}

Naming Scheme

Tasks and config values should use snake_case with periods (.) to denote a "variant" and using colons (:) for "namespaces."

Example for a "variant:" build vs build.prod

Example for a "namespace:" clockwork:update

Neither Maple or Clockwork support actual namespacing, so if you do want to > separate your tasks or configs, you can prefix them with something:.

Distribution for Projects

Clockwork is licensed very permissively, so if you want to you can just... include Clockwork with your project's source.

Although for most people, you do not want one Clockwork install per project, so there are two options for this:

  1. Include the install command in the readme for developers to copy and paste:

v download -RD https://raw.githubusercontent.com/EmmaTheMartian/clockwork/refs/heads/main/scripts/install.vsh

  1. Include the installation script (scripts/install.vsh) in your project.

I would just throw this script into a scripts folder and name it install-clockwork.vsh or something. Contributors will only need to use it once and Clockwork will be installed.

Constants #

const version = '1.2.0'
const global_data_dir = os.join_path_single(os.config_dir()!, 'clockwork')

global_data_dir is the path to the folder containing Clockwork's global data and configs.

const global_plugin_dir = os.join_path_single(global_data_dir, 'plugins')

global_plugin_dir is the path to the folder containing Clockwork's plugins.

const global_config_path = os.join_path_single(global_data_dir, 'global.maple')

global_config_path is the to the global config file (global.maple).

const install_path = $if debug || test {
	'./'
} $else {
	os.dir(os.dir(os.executable()))
}

install_path is the path to the location where Clockwork is installed (aka the "git-managed" path). We use os.dir twice here so that we get rid of the path to both the executable and the build/ folder containing it.

const installed_plugin_dir = os.join_path_single(install_path, 'config/plugins')

installed_plugin_dir is the path to the git-managed plugins.

const installed_script_dir = os.join_path_single(install_path, 'config/scripts')

installed_script_dir is the path to the git-managed scripts.

const installed_config_path = os.join_path_single(install_path, 'config/global.maple')

installed_config_path is the path to the git-managed config file (global.maple).

fn BuildContext.new #

fn BuildContext.new() BuildContext

new creates a new BuildContext with the default values.

fn Task.from_map #

fn Task.from_map(data map[string]maple.ValueT, task_name string) Task

from_map loads a task from a Maple map.

struct BuildContext #

struct BuildContext {
pub mut:
	tasks     map[string]Task
	variables map[string]string
	// allow_plugins toggles if plugins are allowed to load.
	allow_plugins bool = true
	// display contains display settings for Clockwork.
	display struct {
	pub mut:
		// default_task_category is the category to list tasks of when
		// using `clockwork --tasks`. No value means list all tasks.
		default_task_category string
		// list_tasks_mode is how tasks should be listed in
		// `clockwork --tasks`. Values: `verbose`, `slim`
		default_task_list_mode string = 'verbose'
		// task_list_exclude_categories is a list of categories to
		// exclude when using `clockwork --tasks`.
		task_list_exclude_categories []string = []
		// task_list_exclude_categories is a list of tasks to exclude
		// when using `clockwork --tasks`.
		task_list_exclude_tasks []string = []
	}
}

BuildContext represents loaded data for Clockwork, being tasks and variables.

fn (BuildContext) format #

fn (con BuildContext) format(str string) string

format formats a string to replace ${some_variable} with its corresponding value.

fn (BuildContext) run_task #

fn (con BuildContext) run_task(id string)

run_task runs a task with a given ID.

fn (BuildContext) load_config #

fn (mut con BuildContext) load_config(data map[string]maple.ValueT)

load_config loads a config file into the BuildContext.

fn (BuildContext) list_tasks #

fn (con BuildContext) list_tasks(options ListTaskOptions)

list_tasks lists all tasks in a context with the given options.

struct ListTaskOptions #

@[params]
struct ListTaskOptions {
pub:
	// category is the category to list tasks from. Using no value ('') will
	// list all.
	category ?string
	// mode is the mode to list tasks as. `'verbose'` will list tasks with
	// their descriptions and dependencies. `'slim'` will list only task
	// names.
	mode ?string
	// exclude_categories is a list of categories to exclude from the list.
	exclude_categories ?[]string
	// exclude_tasks is a list of tasks to exclude from the list.
	exclude_tasks ?[]string
}

ListTaskOptions represent options for list_tasks_verbose and list_tasks.

struct Task #

struct Task {
pub:
	depends  []string = []
	run      []string = []
	help     string
	work_dir ?string
	category string
}

Task represents an executable task in the BuildContext.