#shell #attributes #script #macro #proc-macro #shellfn

shellfn-attribute

shellfn 包的属性宏

2个版本

0.1.1 2019年2月16日
0.1.0 2019年2月16日

#360#attributes

Download history 25/week @ 2023-12-06 30/week @ 2023-12-13 41/week @ 2023-12-20 22/week @ 2023-12-27 14/week @ 2024-01-03 43/week @ 2024-01-10 30/week @ 2024-01-17 51/week @ 2024-01-24 20/week @ 2024-01-31 46/week @ 2024-02-07 49/week @ 2024-02-14 45/week @ 2024-02-21 68/week @ 2024-02-28 45/week @ 2024-03-06 47/week @ 2024-03-13 45/week @ 2024-03-20

213 每月下载量
7 个包中使用 (通过 shellfn)

MIT 许可证

45KB
889

概览

这是一个类似于Rust属性的进程宏,它可以减少调用shell命令和解析结果所需的代码量。

它允许您使用强类型函数将任何语言的脚本包装起来。函数的参数被设置为环境变量,脚本的输出结果被解析为值或迭代器。

Crates.io license Build Status

文档

仓库

示例

基础

use shellfn::shell;
use std::error::Error;

#[shell]
fn list_modified(dir: &str) -> Result<impl Iterator<Item=String>, Box<Error>> { r#"
    cd $DIR
    git status | grep '^\s*modified:' | awk '{print $2}'
"# }

不同的解释器

use shellfn::shell;
use std::error::Error;

#[shell(cmd = "python -c")]
fn pretty_json(json: &str, indent: u8, sort_keys: bool) -> Result<String, Box<Error>> { r#"
import os, json

input = os.environ['JSON']
indent = int(os.environ['INDENT'])
sort_keys = os.environ['SORT_KEYS'] == 'true'
obj = json.loads(input)

print(json.dumps(obj, indent=indent, sort_keys=sort_keys))
 "# }

用法

您可以在具有以下属性的函数上使用 #[shell] 属性:

  • 包含单个表达式(表示要执行的脚本的字面量字符串)的函数体
  • 实现了 .to_string() 方法的类型
  • 返回值可以是 voidTResult<T, E>impl Iterator<Item=T>Result<impl Iterator<Item=T>>Result<impl Iterator<Item=Result<T, E>>> 的值,其中包含约束
T: FromStr,
<T as FromStr>::Err: StdError,
E: From<shellfn::Error<<T as FromStr>::Err>>,
  • 详细信息

#[shell] 属性执行以下操作:

  1. 将每个参数设置为环境变量
  2. 运行shell命令
  3. 使用 std::process::Command 启动命令。
  4. 根据返回类型,它可能会解析输出。

大多数步骤都可以调整。

  • 默认命令是 bash -c。您可以使用 cmd 参数来更改它。
#[shell(cmd = "python -c")]
  • 默认情况下,脚本作为最后一个参数添加。您可以使用 cmd 参数中的特殊变量 PROGRAM 来更改它。
#[shell(cmd = "bash -c PROGRAM -i")]
  • 您可以使用函数参数中设置的 env 变量,在 cmd 参数中以与脚本中相同的方式使用。
#[shell(cmd = "python -m $MODULE")]
fn run(module: &str)
  • 如果返回类型不是在 Result 中包装结果的一部分,您可以通过添加 no_panic 标志来决定抑制恐慌。
#[shell(no_panic)]

目前识别以下返回类型:

返回类型 标志 解析失败时 错误退出代码时 启动失败时 注意
- panic panic
no_panic -
() - panic panic
() no_panic -
Result<(), E> - 错误 错误
Result<(), E> no_panic - 错误 错误 1
T panic panic panic 2
T no_panic panic panic panic 1,2
Result 错误 错误 错误 2
Result no_panic 错误 错误 错误 1,2
Vec panic panic panic
Vec no_panic 跳过 忽略 空 Vec 3
Vec> 项错误 panic panic
Vec> no_panic 项错误 忽略 空 Vec
Result panic 错误 错误
Result no_panic 跳过 错误 错误
Result>, E2> 项错误 错误 错误
Result>, E2> no_panic 项错误 错误 错误 1
实现 Iterator panic panic panic
实现 Iterator no_panic 跳过 忽略 空迭代器 3
实现 Iterator> 项错误 panic panic 3
实现 Iterator> no_panic 项错误 忽略 空迭代器
Result, E> panic 忽略 错误
Result, E> no_panic 跳过 忽略 错误
Result>, E2> 项错误 忽略 错误
Result>, E2> no_panic 项错误 忽略 错误 1

术语表

动作 含义
panic panic (.expect 或 panic!)
消费并忽略错误 (let _ = ...)
错误 返回错误
跳过 产出所有成功解析的项目,忽略解析失败 (filter_map)
空迭代器/Vec 返回空迭代器 / 向量
项错误 解析失败时,产出 Err
忽略 忽略退出代码,对于退出代码 0 和 != 0 的行为相同

注意

  1. no_panic 属性没有影响。
  2. 它在产生任何失败之前读取所有 stdout。
  3. 它产出所有项目,直到遇到错误或退出代码。

Vector 与 iterator 的比较

具有 Vec 返回类型的变体与具有 impl Iterator 的变体非常相似。主要区别在于:

  • impl Iterator 只在每次只分配一个项目,并在解析后立即产出它,而 Vec 则逐行读取输出,但在临时 Vec 中存储已解析的输出。
  • Vec 了解退出代码。当子进程因错误而结束时,impl Iterator 将停止产出值,而 Vec 将返回错误或 panic。

贡献

所有贡献和评论都受到欢迎!如果您发现错误或想改进这个 crate,请随时打开问题或 PR。

许可证

MIT 许可证

版权所有 (c) 2017 Marcin Sas-Szymański

特此授予任何人免费使用、获得本软件及其相关文档文件(统称“软件”)的权利,无限制地处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许向其提供软件的个人进行上述操作,但需遵守以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何形式的保证,无论是明示的、暗示的,还是关于适销性、特定用途适用性或非侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论此类责任是基于合同行为、侵权行为或其他方式,也不论此类责任是否源于、产生于或与软件的使用或以任何其他方式参与软件有关。

依赖项

~6MB
~114K SLoC