cargo-make

repository·master·Indexed 25 days ago

https://github.com/sagiegurari/cargo-make

A Rust-based task runner and build tool that enables developers to define complex, multi-platform task flows using a TOML configuration. It supports the execution of shell commands, scripts, and Rust code, and provides features such as task dependencies, platform-specific aliases, and integration with Duckscript for cross-platform scripting.

Tokens
35.5K
Snippets
128
Records
208
Agent score
83%

What's inside cargo-make

  1. Overview of cargo-make

    master

    cargo-make is a Rust task runner and build tool that allows you to define and configure sets of tasks and run them as a flow.

    Key concepts:

    • Task: A command, script, Rust code, or other sub-tasks to execute.
    • Dependencies: Tasks can have dependencies that execute before the task itself.
    • Configuration: Uses a TOML-based configuration file to define multi-platform build scripts (e.g., build, test, documentation, security validations).
  2. Overview of cargo-make task runner

    master

    cargo-make is a task runner that allows you to define and configure sets of tasks and execute them as a flow.

    Key concepts:

    • Task: A command, script, Rust code, or a collection of sub-tasks to execute.
    • Dependencies: Tasks can depend on other tasks, which will be executed before the dependent task.
    • Configuration: Uses a TOML-based configuration file to define multi-platform build scripts (e.g., for building, testing, generating documentation, or security validations) that can be triggered by a single command.
  3. Quickstart with cargo-make

    master

    To use cargo-make, define your tasks in a Makefile.toml file. By default, cargo-make looks for this file in your project root. You can execute tasks using the cargo make <task_name> command or the standalone makers command.

    Example Makefile.toml:

    [tasks.format]
    command = "cargo"
    args = ["fmt", "--", "--emit=files"]
    
    [tasks.clean]
    command = "cargo"
    args = ["clean"]
    
    [tasks.build]
    command = "cargo"
    args = ["build"]
    dependencies = ["clean"]
    
    [tasks.test]
    command = "cargo"
    args = ["test"]
    dependencies = ["clean"]
    
    [tasks.my-flow]
    dependencies = [
        "format",
        "build",
        "test"
    ]

    Execution:

    cargo make my-flow
    [tasks.format]
    install_crate = "rustfmt"
    command = "cargo"
    args = ["fmt", "--", "--emit=files"]
    
    [tasks.clean]
    command = "cargo"
    args = ["clean"]
    
    [tasks.build]
    command = "cargo"
    args = ["build"]
    dependencies = ["clean"]
    
    [tasks.test]
    command = "cargo"
    args = ["test"]
    dependencies = ["clean"]
    
    [tasks.my-flow]
    dependencies = [
        "format",
        "build",
        "test"
    ]
    cargo make my-flow
  4. Use shebang support for scripts

    master

    Instead of using script_runner, you can define the runner directly in the script's shebang line. This works for languages like bash, python3, or special runners like @duckscript.

    Warning for Windows users: Ensure the chosen runner supports the # character as a comment (e.g., cmd.exe does not), otherwise it will cause an error.

    [tasks.shebang-sh]
    script = '''
    #!/usr/bin/env bash
    echo hello
    '''
  5. Manage predefined tasks and flows

    master

    List all predefined tasks

    To see a full list of all predefined tasks, run:

    cargo make --list-all-steps

    Disable core tasks

    To prevent loading internal core tasks and flows to save resources, add this to your Makefile.toml:

    [config]
    skip_core_tasks = true

    Modify core tasks

    You can modify internal core tasks using the config.modify_core_tasks section:

    • private = true: Sets all core tasks to private (default is false).
    • namespace = "<name>": Prefixes all core tasks with the specified namespace (e.g., default::build).
    [config]
    skip_core_tasks = true
    
    [config.modify_core_tasks]
    private = true
    namespace = "default"
  6. Disable Workspace Support

    master

    To run a task on the workspace root instead of its members, use one of the following methods:

    1. CLI Flag: Use --no-workspace when running the command.
    2. Task Attribute: Set workspace = false in the task definition.
    3. Global Config: Set default_to_workspace = false in the [config] section of your Makefile.toml (this makes workspace support disabled by default unless explicitly enabled with workspace = true).

    Note: The --no-workspace flag and workspace = false attribute only apply to the task explicitly called on the command line; they are ignored for all subsequent tasks in the dependency flow.

    cargo make --no-workspace mytask
    [tasks.ignore-members]
    workspace = false
    [config]
    default_to_workspace = false
  7. Override or disable default tasks

    master

    cargo-make includes built-in tasks (like build, test, etc.). You can extend or modify them in your own Makefile.toml without redefining all their properties.

    • To override specific attributes: Only define the keys you want to change (e.g., args).
    • To disable a task: Set disabled = true (this also disables its dependencies).
    • To completely reset a task: Use clear = true to delete all original attributes before defining new ones.
    # Overriding only the args of the built-in build task
    [tasks.build]
    args = ["build", "--verbose"]
    
    # Disabling a task
    [tasks.build]
    disabled = true
    
    # Completely clearing and redefining a task
    [tasks.sometask]
    clear = true
    command = "echo"
    args = ["extended task"]
  8. Leverage automatic variable reordering

    master
    Unlike naive implementations, cargo-make automatically reorders environment variables based on their dependencies. If VAR1 references ${VAR2}, cargo-make ensures VAR2 is resolved before VAR1, even if VAR1 is defined before VAR2 in the configuration file. This allows for flexible variable referencing and redefining across different profiles.
  9. Configure a cleanup task for failed sub-tasks

    master

    You can define a cleanup_task that runs after a sub-task even if that sub-task fails. This requires setting fork = true in the run_task configuration.

    [tasks.echo1]
    command = "echo"
    args = ["1"]
    
    [tasks.echo2]
    command = "echo"
    args = ["2"]
    
    [tasks.fail]
    script =  "exit 1"
    
    [tasks.cleanup]
    command = "echo"
    args = ["cleanup"]
    
    [tasks.cleanup-example]
    run_task = { name = ["echo1", "echo2", "fail"], fork = true, cleanup_task = "cleanup" }
  10. Use Fig / Amazon CodeWhisperer for cargo-make

    master
    Fig and Amazon CodeWhisperer for command line support cargo-make automatically. Ensure cargo-make is installed globally by checking cargo --list. The completion will automatically load from your current directory's Makefile.toml or any directory specified via the --makefile <path> flag.
    cargo --list
  11. Use task aliases and platform-specific aliases

    master

    An alias is a task that points to another task using the alias attribute. All other definitions in an alias task are ignored. Aliases are useful for running the same task multiple times (since dependencies deduplicate, but an alias creates a new entry in the plan).

    Platform-specific aliases allow you to define different tasks based on the current operating system using linux_alias, windows_alias, or mac_alias. If a platform-specific alias is found, it takes precedence over the standard alias attribute.

    [tasks.my_task]
    linux_alias = "linux_my_task"
    windows_alias = "windows_my_task"
    mac_alias = "mac_my_task"
    
    [tasks.linux_my_task]
    # ...
    
    [tasks.my_task]
    linux_alias = "run"
    alias = "do_nothing"
    [tasks.D2]
    alias="D"
  12. Use environment setup scripts

    master

    The env_scripts attribute allows you to define global scripts that run after environment files and the [env] block are processed. This is useful for complex setup logic. If using duckscript, you can modify the cargo-make runtime environment variables directly using set_env.

    env_scripts = [
    '''
    #!@duckscript
    echo first env script...
    set_env COMPOSITE_2 some_value
    ''', 
    '''
    #!@duckscript
    echo second env script...
    ''
    ]