#env-var #command-line #task #tasks #automation #makefile #local-file

bin+lib devrc

devrc 是一款易于使用的强化型任务运行器工具,专为开发者设计

9 个版本 (重大变更)

0.6.0 2023 年 6 月 18 日
0.5.4 2023 年 6 月 3 日
0.5.2 2023 年 5 月 31 日
0.4.0 2022 年 9 月 14 日
0.0.1 2020 年 11 月 17 日

#1097开发工具

每月 30 次下载

MIT 许可证

195KB
4.5K SLoC

强化型开发者任务自动化工具

Crates.io Crates.io CI Security audit Minimum supported Rust version Lines Of Code LICENSE

概述


devrc 是一款易于使用的 强化型任务运行器。它是一个小巧快速的 Rust 编写的工具 🦀。

它适用于项目或常见流程的自动化,如压缩、编译、单元测试、代码检查等。

它只是一个单一的二进制文件,您不需要安装 pythonruby 或其他东西。

它允许您运行存储在名为 Devrcfile 的 YAML 文件中的任务。只需输入命令,例如 devrc task_name_1 task_name_2 task_name_3


快速介绍

定义任务的方式有多种,以下是常见的形式

  1. 无文档字符串的简单命令定义。

    task_name: echo "Hello world"
    
  2. 更复杂的定义,包含文档字符串。

    task_name:
      desc: "Task description"
      exec: echo "Hello world"
    

要运行任务,只需输入命令 devrc TASK_NAME,例如。

devrc task_name

更多详情请参阅 使用部分示例

功能

让我们先概述一下 devrc 中存在的一些功能

  • 可以通过命令行列出所有任务及其文档
  • 支持模板引擎和变量插值
  • 环境变量 定制
  • 命令行补全脚本
  • devrc 支持 dotenv 文件
  • 使用不同语言编写任务命令
  • 任务参数和用户输入
  • 从任务中设置全局变量和环境变量
  • 远程命令执行
  • 从 stdin 读取 Devrcfile 内容
  • 全局和局部定义的变量和环境变量
  • deno 运行时
  • 从本地和远程文件中包含 devrcfile
  • 从本地和远程文件中加载环境变量
  • 插件用于任务执行

为什么使用 YAML?

经过多年的使用Makefiles进行项目常规自动化,许多格式(例如TOML、Makefile、YAML、自定义格式)都已被检验。

使用YAML进行此目的的好处是什么,以及为什么选择它

  1. YAML被设计成易于人类阅读易于阅读
  2. 语法高亮显示是默认启用的
  3. YAML在声明性配置中被广泛使用。例如,它被gitlab-ci、GitHub actions和Ansible使用;
  4. 许多文本编辑器和平台都有插件或内置工具来为您检查YAML配置语法。
  5. 已经存在良好的YAML解析器,我无需浪费时间来实现和测试自己编写的解析器。

目录

安装

要安装devrc,您可以下载一个预编译的二进制文件,或者您可以从源码编译它。根据您的平台,您可能可以使用操作系统包管理器安装devrc

从crates.io安装

devrc是用Rust编写的。您需要1.48.0或更高版本的rustc。

安装Rust用于开发的推荐方法是使用官方下载页面,使用rustup。

如果您已经在本地系统上安装了Rust工具链,您可以使用cargo install命令

rustup update stable
cargo install devrc

Cargo将构建devrc二进制文件并将其放置在$HOME/.cargo中。

从源码编译

GitHub GitHub

克隆存储库并将其更改为您的工作目录。

git clone https://github.com/devrc-hub/devrc.git
cd devrc

rustup update stable
cargo install

二进制发布

macOS和Linux目标在github发布页面上有可用的二进制发布。
以下二进制文件在每个版本中可用

  • x86_64-unknown-linux-musl
  • x86_64-unknown-linux-gnu
  • x86_64-apple-darwin

用法

默认情况下,任务存储为YAML文件中名为Devrcfile的映射(散列/字典/键值对)。或者,您可以通过指定环境变量DEVRC_FILE使用不同的文件名。您还可以在您的家目录中的~/.devrc中存储全局任务,或通过本地Devrcfile.local文件覆盖共享项目任务或变量。

如果使用了命令行选项-f

  1. 如果存在并且命令行标志-g或选项devrc_config.global启用,则加载家目录中的~/.devrc
  2. 加载由命令行选项-f指定的文件;

如果没有使用命令行选项-f

  1. 如果存在,则在主目录中加载 ~/.devrc,如果启用了命令行标志 -gDevrcfile 中的选项 devrc_config.global
  2. 加载 Devrcfile 或当前目录中由环境变量 DEVRC_FILE 指定的文件名;
  3. 加载 Devrcfile.local

文件名区分大小写。

任务定义类似于 .gitlab-ci 文件中的作业定义。键用作任务名称,值用于创建任务逻辑。一些键名是保留的,以下将进行说明。

任务定义

存在不同类型的任务。

  1. 可执行任务
  2. 配置任务(尚未实现)。

存在三种任务定义风格。

无文档字符串的简单命令定义

variables:
  name: "Alex"

task_name: echo "Hello {{ name }}"

或一个任务中的多个命令


variables:
  first_name: "Alex"
  second_name: "Alice"

environment:
  ENV_NAME: "{{ second_name }}"

task_name:
  - echo "Hello {{ first_name }}!"
  - echo "Hello $ENV_NAME!"

这些任务可以重写为具有文档字符串和变量的更复杂定义形式。

variables:
  name: "Alex"
  task_name:
desc: "Task description"
  exec: echo "Hello {{ name }}"

variables:
  first_name: "Alex"
  second_name: "Alice"

environment:
  ENV_NAME: "{{ second_name }}"

task_name:
  desc: "Task description"
  exec:
    - echo "Hello {{ first_name }}!"
    - echo "Hello $ENV_NAME!"

如果我们向 Devrcfile 中编写代码并在控制台中输入命令 devrc task_name,它将输出到控制台

Hello Alex!
Hello Alice!

请注意,{{ first_name }} 将由模板引擎替换为 Alex,而 $ENV_NAME! 将由 bash 替换为 Alice

更复杂的示例可以在 examples 目录中找到。

保留关键字

有一些保留关键字不能用作任务名称

  • devrc_config - 全局选项,例如 shelllog_levelcurrent_directory
  • variables - 模板引擎使用的全局变量集;
  • environment - 传递给子进程环境的全局环境变量集;
  • before_script - 在第一个任务之前执行的任务;
  • after_script - 在最后一个任务之后执行的任务;
  • before_task - 在每个任务之前执行的任务;
  • after_task - 在每个任务之后执行的任务;
  • env_file - 用于 dotenv 文件

配置


devrc_config:
  global: true
  interpreter: /bin/bash -c
  default: [task_1, task_2]
  cache_ttl: 5m

变量

变量由模板引擎用于计算命令、另一个变量(全局或局部)或环境变量。如果存在全局和局部变量具有相同的名称,则局部将覆盖其值。

变量修饰符

在变量绑定定义中存在特殊关键字

  • +global - 如果指定了此关键字,则变量保存到全局作用域。

环境变量

传递给子进程环境的环境变量必须使用 $VARIABLE_NAME 在命令中访问。环境变量可以在任务中全局或局部定义。如果存在全局和环境变量具有相同的名称,则局部将覆盖其值。如果您在变量名称前放置美元符号 $,shell 将扩展或替换变量的值到命令行中。


tast_name:
  environment:
    name: "Alex"

  exec: Hello $name!

dotenv 文件支持

devrc可以从env(dotenv)文件中加载环境变量。这些变量是环境变量,而不是模板变量。默认情况下,如果在dotenv加载过程中出现错误,devrc将崩溃并退出。您可以通过使用选项ignore_errors来更改默认行为,如果出现错误,devrc将继续运行。

如果env文件包含

ENV_NAME=Alex

您可以使用以下任一方式从文件中加载环境变量

env_file:
  - ./.env
  - file: ./.env_3
    ignore_errors: true
  - file: ./.env_2

task_name: echo "Hello $ENV_NAME"

文件路径可以是绝对路径或相对路径。部分./代表当前目录。

执行和计算规则

devrc将命令、全局或局部任务定义的变量以及全局或局部任务定义的环境变量视为模板。在执行命令或变量赋值之前,它会对命令应用模板引擎。

devrc始终从文件中读取变量,并基于Jinja2/Django语法应用模板引擎。

在示例文本中variable_1 variable_2被分配给变量var_2,而文本env_var variable_1 variable_2被分配给环境变量ENV_VAR

variables:
    var_1: "variable 1"
    var_2: "variable_2 {{ var_1}}"

environment:
    ENV_VAR: "env_var {{ var_2 }}"

任务依赖

任务可能依赖于其他任务。任务的依赖总是在任务执行之前以及before_task钩子之前运行。这可以在给定任务之前执行一些工作,例如清理缓存、删除临时文件等。依赖项按顺序运行。


task_1: echo "Hello world!"

task_2:
  exec: echo "Hello $USER!"
  deps: [task_1]

模板引擎

任务参数和用户输入

任务可能有参数。当调用devrc时,任务参数是在任务名称之后传递的。参数可以是必需的或具有默认值。此外,参数值是一个模板字符串,可以使用之前定义的变量或参数。

devrc task_name arg1 arg2 "argument with spaces and {{ param1 }}" task_name2

参数定义有两种形式。

这是一个简单的形式,其中param1param2是必需的,而param2是可选的,具有默认值。

task_name param1 param2 param3="argument with spaces and {{ param1 }}": |
  echo "Hello {{ param1 }} and {{ param2 }}";
  echo "{{ param3 }}"

默认值必须用双引号括起来。如果需要在默认值中使用引号,可以通过\(反斜杠)符号进行转义。

这是一个更复杂的形式

在这个示例中,任务有一个必需的参数name,一个具有默认值Alice的可选参数other,以及一个用户输入后分配的宿主参数host


task_name:
  exec:
    - echo "Hello {{ name }} and {{ other}}"

  params:
    name: # this is required parameter
    other: "Alice"

这里是一个使用示例

$ devrc task_name name="Alex"
Hello Alex and Alice

$ devrc task_name "Alex"
Hello Alex and Alice

远程命令执行

也可以在远程主机上执行任务。

注意:此功能尚未实现。

task_name:
  exec: echo "Hello {{ name }} from $(hostname)"
  variables:
    name: "Alex"
    username: root

  remote:
    - "{{ username }}@hostname1:22"
    - root@hostname2:22
task_name:
  exec: echo "Hello {{ name }} from $(hostname)"
  variables:
    name: "Alex"
    username: root

  remote:
    hosts:
      - "{{ username }}@hostname1:22"
      - hostname2

使用不同语言编写任务命令


hello_1:
  desc: "Execute python script"
  exec: |
    #!/usr/bin/env python

    print("Hello from python")


hello_2:
  desc: "Execute javascript by node"
  exec: |
    #!/usr/bin/env node

    console.log("Hello from node")

命令devrc hello_1 hello_2输出

Hello from python
Hello from node

从stdin读取Devrcfile

除了读取文件,devrc还可以从stdin读取任务文件。要启用此行为,请传递--stdin标志。

cat ./Devrcfile | devrc --stdin task_name

devrc --stdin task_name < ./Devrcfile

插件用于任务执行

可以通过devrc_config.plugins选项加载的插件可以执行任务。


devrc_config:

  plugins:
    local-plugin-alias: ../path/to/dynamic/library.dylib

    interpreter:
      runtime: local-plugin-alias
      options:
        plugin-option-1: plugin-option-1-value

更多示例可以在这里找到。一个示例插件可以在存储库中找到。

嵌入式Deno运行时

Devrc通过插件嵌入式Deno运行时。Deno是一个简单、现代且安全的JavaScript和TypeScript运行时,它使用V8。此运行时可以在全局级别或任务级别启用。默认情况下,所有权限都已被禁用。除非明确启用,否则不访问文件、网络或环境。


devrc_config:
  interpreter:
    runtime: deno-runtime
    options:
      permissions:
        - allow-env
        - allow-net: [google.com, httpbin.org]

        # - disable-all
        # - allow-all
        # - allow-env
        # - allow-hrtime
        # - allow-net: [google.com, httpbin.org]
        # - allow-plugin
        # - allow-read: ["/tmp"]
        # - allow-run
        # - allow-write-all
        # - allow-write: ["/tmp"]

  plugins:
      deno-runtime: ../path/to/dynamic/library.dylib

colors: |
  import { bgBlue, bold, italic, red } from "https://deno.land/std/fmt/colors.ts";

  const name = prompt("What is your name?");

  confirm(`Are you sure ${name} is your name?`);

  if (import.meta.main) {
     console.log(bgBlue(italic(red(bold(`Hello ${name} !`)))));
  }

更多示例可以在这里找到。

文件包含和相对路径解析

devrc 允许您使用导入机制加载任务、变量和环境变量。可以通过指定绝对路径、URL地址或相对路径来包含文件。反过来,导入的 devrc 文件可以使用相对路径包含其他文件。有几种解决相对路径的策略。默认情况下,策略是使用加载文件的目录作为基础路径。可以使用 path_resolve 选项指定特定文件的连接策略。

假设我们位于目录 /projects/awesome_project 中,并执行命令 devrc -f devrcfiles/local_1.yml --list。在文件 /project/awesome_project/devrcfiles/local_1.yml 中,可以这样包含其他文件

include:
  - url: "https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/entry.yml"
    checksum: 1234

  # /projects/awesome_project/devrcfiles/local_2.yml
  - file: ./local_2.yml
    path_resolve: relative

  # /projects/awesome_project/local_3.yml
  - file: ./local_3.yml
    path_resolve: pwd

在文件 /project/awesome_project/devrcfiles/local_1.yml 中,我们从远程位置加载任务文件 https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/entry.yml。在这个文件中,其他文件包含如下

include:
  # https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/remote_1.yml
  - file: ./remote_1.yml

  # /projects/awesome_project/devrcfile/local_4.yml
  - file: ./devrcfiles/local_4.yml
    path_resolve: pwd
"

  1. 首先,将加载文件 /projects/awesome_project/devrcfiles/local_1.yml;
  2. 然后,从远程源 https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/entry.yml 加载 entry.yml 文件;
  3. 然后,从远程源 https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/remote_1.yml 加载 remote_1.yml 文件;
  4. 然后,从本地源 /projects/awesome_project/devrcfile/local_4.yml 加载 local_4.yml 文件;
  5. 然后,从本地源 /projects/awesome_project/devrcfiles/local_2.yml 加载 local_2.yml 文件;
  6. 最后,从本地源 /projects/awesome_project/local_3.yml 加载 local_3.yml 文件。

身份验证

devrc 支持使用 .netrc 文件中的授权数据下载受授权保护的 devrc 文件。例如,从 GitLab 或 GitHub 的私有仓库。

有几种使用授权的方式

  1. 使用载体令牌授权

    include:
        - url: "https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/entry.yml"
          checksum: 1234
          auth:
              machine: api.github.com
              login: api-token
              type: bearer
    

    下载 devrc 文件时,将发送头信息 Authorization: Bearer TOKEN-FROM-NET-RC

  2. 使用基本授权

    include:
        - url: "https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/entry.yml"
          checksum: 1234
          auth:
              machine: api.github.com
              login: username
              type: basic
    

    下载 devrc 文件时,将发送头信息 Authorization: Basic base64(username:password)

  3. 使用头信息

    include:
        - url: "https://raw.githubusercontent.com/devrc-hub/devrc/master/examples/remote/entry.yml"
          checksum: 1234
          auth:
             machine: api.github.com
             login: api-token
             header: "PRIVATE-TOKEN"
    
    

    下载 devrc 文件时,将发送头信息 PRIVATE-TOKEN: password

缓存

远程源中的 devrc 文件存储在文件系统中。如果缓存的文件生命周期超过 devrc_config.cache_ttl 选项中指定的时间,则从远程源下载文件。

替代方案

  • Bash 或 makefile :-)
  • just - 是保存和运行项目特定命令的便捷方式。命令存储在名为 justfile 的文件中,语法受 make 启发。
  • robo - 使用 Go 编写的简单基于 YAML 的任务运行器。看起来已经被遗弃。
  • go-task - 使用 Go 编写的更简单的 Make 替代品。它使用 Go 的模板引擎,其语法让我感到痛心。

贡献

任何建议、反馈或贡献都备受赞赏。

我特别非常感谢您的语法纠正贡献,因为英语不是我的母语。

感谢您的支持!

依赖项

~20–36MB
~599K SLoC