From 5e24c2bd9d395afd422a9b0e406e03d4434d535c Mon Sep 17 00:00:00 2001 From: southerntofu Date: Wed, 23 Sep 2020 15:30:51 +0200 Subject: [PATCH] Draft specification --- README.md | 6 +++- spec.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 spec.md diff --git a/README.md b/README.md index 30bfd8a..89f47bc 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,13 @@ $ # Is the same as $ FORGEBUILD=/tmp/forgebuild.rb bats tests ``` -TODO: +Note: git and hg need to be configured in order to commit (require authorship). TODO: automate this, maybe? + +# Tests TODO - [x] basic function tests - [x] configurable forgebuild path, so we can test different implementations - [x] task settings (global/per-host settings) +- [x] multiple source backends (DVCS) +- [x] short/long flags for CLI - [ ] PGP signatures diff --git a/spec.md b/spec.md new file mode 100644 index 0000000..47dfcff --- /dev/null +++ b/spec.md @@ -0,0 +1,104 @@ +# forgebuild v0.5 + +forgebuild is a program to check for updates on remote repositories and trigger some tasks accordingly. There are different implementations available, and this document serves as a reference for the high-level interface these different programs should implement. + +If you are looking for a program you may use as an end user, check out [forge/build.rs](https://tildegit.org/forge/build.rs) (Rust) or [forge/build.sh](https://tildegit.org/forge/build.sh) (bash) instead. + +On a high-level, forgebuild is a lightweight and KISS system to start tasks when a remote repository was updated and/or when those tasks haven't run on the current machine yet. In most cases, forgebuild trigger tasks when a remote Git/Mercurial repository was updated, eg. to run a suite of tests or build your static website. But it can serve many other purposes, including setting up your dotfiles on a new machine. Your imagination is the limit! + +This is version 0.5 of this specification, published on September 22 2020. + +## Overview + +Any forgehook implementation **MUST** have the following features: + +- check for updates on remote repositories, and start corresponding tasks if there was any update (`forgebuild [tasks]`) +- run one or more tasks, regardless of remote updates (`Ì€forgebuild -f [tasks]`) +- configure settings [per task](#configuration) or [per host](#multihost-setup) +- run one-off tasks (sourceless tasks) + +forgebuild supports different source backends. Here's an overview of backends that forgehook implementations **MUST** support, and those that they **MAY** additionally support: + +- (REQUIRED) sourceless: no remote source, task is executed only once per host +- (REQUIRED) [git](https://git-scm.com/) +- [mercurial](https://mercurial-scm.org/) (hg) +- [pijul](https://pijul.org/) + +## Vocabulary + +- basedir: folder where forgebuild will look for tasks +- task: a program which may be run by forgebuild +- task parameter: a file in the basedir, which has the name of the task followed by a dot, and the name of the parameter (`t.s` for a parameter s on a task t) +- task/host setting: a file in the configuration directory + +## Summary + +If you can't afford to read the whole document, here's what you need to know. A task is an executable file, which may have additional parameters. For a given task `t`, there may be several parameters in the basedir (only `t` itself is mandatory): + +- `t`: the executable script +- `t.source`: the source URL for the repo to track +- `t.dvcs`: the source backend to clone the repository, can be either git or mercurial (default: git) +- `t.checkout`: a specific branch/commit to checkout +- `t.hosts`: line-separated list of hosts on which this task should run (opt-in, see below for opt-out) + +There may also be settings folders for consumption by tasks. This folder is either the `config` folder in the basedir, or a folder named after the current host (`$HOSTNAME`). If the settings folder contains a file named `t.skip` (skip setting), then the task will be skipped on this host (opt-out). + +## Command-Line Interface (CLI) + +### Base directory (basedir) + +forgebuild **MUST** support passing an arbitrary basedir (tasks directory) through the `-b|--basedir` flag. If no such directory is provided, forgebuild **MUST** use `$HOME/.forgebuild/`. In both cases, forgebuild **MUST** support relative paths and symlinks. + +### Running specific tasks + +forgebuild **MAY** receive an arbitrary number of task names to trigger (eg. `forgebuild run_tests deploy_site`). In this case, other tasks **MUST NOT** be triggered. If no such task names are passed as arguments, then all tasks **MUST** be triggered. + +### Forced run + +When the `-f|--force` flag is passed, forgebuild **MUST** run the requested tasks, whether the task source has received updates or not. However, if the task doesn't have a source, it **MUST** be skipped unless its name is specified. + +For example, `forgebuild -f` will run all tasks who have a source, ignoring sourceless tasks. `forgebuild -f foo bar` will run tasks foo and bar, even if they are sourceless tasks who have already run. + +## Tasks + +### Discovery + +All executable files within the basedir, as well as symlinks within the basedir pointing to an executable file, **MUST** be considered tasks. + +### Ordering + +Tasks **SHOULD** be run sequentially, in alphanumeric order. Additionally, a forgebuild implementation **MAY** implement an opt-in mechanism to run tasks in parallel, but **MUST** respect alphanumeric order for starting those parallel tasks. + +TODO: This could be standardized as a [task dependency](https://tildegit.org/forge/build/issues/7) system. + +### Settings + +Tasks **MUST** receive an environment variable `$FORGEBUILDCONF` pointing to a folder where they may find arbitrary files, usually containing settings/parameters. If the basedir contains a folder matching the current `$HOSTNAME`, then this folder **MUST** be considered the configuration folder. Otherwise, the `config/` folder in the basedir **MUST** be used, even if it does not exist. + +In this document, a task setting `s` for a task `t` refers to the presence/content of the file `t.s` in the basedir. + +## Sources + +### Defining sources + +Tasks **MAY** have associated parameters defining a remote source repository to track. These parameters are `source`, `dvcs` and `checkout`: + +- source: the URL of the source repository +- dvcs: the version control system (git|mercurial) to clone the repository +- checkout: which commit/branch to checkout after cloning + +Submodules of the source repository **MUST** be cloned when cloning said repository. + +### Managing submodules + +Tasks **MAY** have a `subupdates` setting. When they do, submodule updates will trigger the task. Otherwise, only source repository updates will trigger the task. + +TODO: The future version will more look like this: + +``` +Tasks **MAY** have a `subupdates` setting controlling how submodule updates affect the task. It can have the following values: + +- file does not exist: submodules are not updated automatically +- `update`: submodules are updated, but tasks are only run when the main repositories is updated +- `trigger`: submodule updates trigger tasks +```