A fresh approach to managing common development tasks like running tests, checking code quality, or building documentation.
Mold is heavily built around a few core ideas:
By reusing parameterized modules, Mold enables new projects to rapidly get off the ground with a set of standard tasks. For example, python.mold provides tasks for general Python project maintenance: autoformatting with black, linting with flake8, documentation generation with Sphinx, etc.
      These modules can also provide consistency across projects from
      different teams, platforms, and toolchains: linting can generally be run with the
      lint recipe, tests can generally be run with the test
      recipe, etc. Consistency cuts down on time spent onboarding and adjusting after
      switching projects
    
      When consistency between projects can't be achieved completely, Mold makes your
      tasks discoverable and accessible without having
      to dig up the documentation. Simply running mold will list all of the
      magic spells in your project's grimoire.
    
Check the GitHub releases page for binaries, or get the ready-to-use shell script here:
curl -sSfL xtfc.org/mold.sh | sh
        mold.sh is a stand-in for the
        Mold binary. It's intended to be tracked by version control, so
        it's suitable for use in environments that don't already have Mold installed,
        like CI/CD or your coworker's computer. It does require the host environment to
        have internet access and wget or curl
        installed, as it transparently downloads a full binary to handle actual
        execution.
      
        Mold is so fun and easy to use. Just type mold (or
        maybe ./mold.sh, if you're doing it that way). It should present
        you with a list of tasks and helpful descriptions. If you append a task name to
        the command, like mold foo, it will execute the
        foo task for you. You can run many tasks in sequence, like
        mold foo bar.
      
        There's also some other junk sitting around if you run mold --help.
      
Mold reads a recipe file that describes the available incantations and all sorts of fun parameterization options. Recipe files are written in YAML. Maybe some day it will support XCL.
A recipe file describes tasks that can be executed, script runtimes, environment variable definitions, and conditional environment configurations. It may also define a required minimum version of Mold.
A recipe describes a task that can be executed and can take any of several forms:
A command is an executable and a list of arguments. It does not support any sort of variable substitution or interpolation; the list of arguments is used as a literal and passed straight to the OS for execution.
A script is an inline script file and a script runtime. The inline script will be written to a temporary file and invoked using the script runtime. This is suitable for small scripts on the order of ~10 lines.
          A file is a separate script file, located in the
          mold/ directory by default, and a script runtime. The file will
          be invoked using the script runtime. This is suitable for scripts of any size
          or language. The script file directory can be changed in the root of the
          recipe file.
        
A module is a reference to a remote Git repository that contains a separate Mold configuration. Modules can target a specific branch / tag as well as a specific recipe file inside the repo. Recipes inside the module can be accessed with a prefix.
All recipes can be configured with an optional help string, prerequisite tasks, environment variable definitions, and conditional environment variable definitions.
          A runtime defines an interpreter that can be used to execute
          scripts and files. Runtimes are defined by a name, command, and file
          extensions. The name is used as an identifier by scripts and files, so it must
          be unique. The command is a list of arguments that can be passed to the OS to
          execute the interpreter; any "?" elements will be replaced with
          the file to be executed. The file extensions are defined as a list of
          potential extensions to attach to a filename.
        
See std.mold for example runtime definitions.
An include is a reference to a module that is included at the top-level, rather than behind a namespace prefix. This is useful for things like std.mold that define general-purpose runtimes or recipes.
Environment variables are used to parameterize recipes. When using modules, it's often beneficial to use variables to ensure the module is generalized sufficiently. Variables can be configured at the root level or at an individual recipe level.
Mold automatically exports several environment variables that describe its runtime context:
$MOLD_ROOT: directory containing the recipe file$MOLD_FILE: recipe file path$MOLD_DIR: recipe directory path$MOLD_CLONE_DIR: directory containing module repositories$MOLD_SCRIPT_DIR: directory containing temporary script files$MOLD_SEARCH_DIR: directory searched for recipe files$MOLD_WORK_DIR: working directory$MOLD_MODULE_ROOT: directory containing recipe file for current recipe's moduleIn simple configurations, several of the directories will be identical, but they can be useful in more complicated configurations involving nested modules.
Conditional environments allow environment variables to be defined based on a runtime setting. Environments are defined as a test expression and a variable map. The test is a simple expression that checks for the presence or absence of values in the active Mold environment list. If a test evaluates to true, the corresponding variable map will be applied. Conditional environments are applied in-order, overwriting values defined in the non-conditional variables map and in previous conditional environments.
          Active environments are set as a comma-separated list of
          alphanumeric strings in the $MOLDENV
          environment variable or the --env / -e CLI flag.
          Additional environments can be appended one at a time using the
          --add / -a CLI flag.
        
          Test expressions are written in a minimal language designed
          for checking combinations of active environments. Any environment identifier
          evaluates to true if that identifier is active. Boolean
          and is expressed with the + operator, while boolean
          or and not are expressed with the | and
          ~ operators, respectively. Subexpressions can be grouped using
          ().
        
Environment identifiers can also have underscores and hyphens. Whatever.