10 个重大版本
0.11.0 | 2021 年 10 月 17 日 |
---|---|
0.10.0 | 2021 年 4 月 26 日 |
0.9.0 | 2021 年 4 月 26 日 |
0.8.0 | 2021 年 2 月 2 日 |
0.2.0 | 2019 年 3 月 5 日 |
#612 in 文件系统
57KB
1K SLoC
IF 文件系统事件 Then (IFFT)
当在监视文件夹中发生文件系统事件(创建、写入、删除、chmod)且不是由排除规则过滤掉时,执行 shell 命令。
使用此功能监视代码更改以触发:进程重启;代码编译;或测试运行。
安装
如果您已经在您的机器上安装了 rust
cargo install ifft
否则,请检查 发行版 以获取下载。
用法
你好,世界。
在目录中创建一个配置文件(例如 ifft.toml
),(假设 ~/src/ifft-test
)
[[ifft]]
# Matches everything including sub-folders
if = "**/*"
then = "echo hello, world."
使用包含您的配置的目录作为参数运行 ifft
$ ifft ~/src/ifft-test
Found config: "~/src/ifft-test/ifft.toml"
ifft
找到了您的配置文件。在后续的示例中,我们将看到多个配置文件可以嵌入到文件系统树中的多个位置。
现在让我们创建一个文件来触发您的 ifft
$ touch ~/src/ifft-test/test1
您将看到以下输出
[2019-05-12 14:55:57Z] Event: Create("~/src/ifft-test/test1")
Match from config in: "~/src/ifft-test"
Matched if-cond: "**/*"
[2019-05-12 14:55:57Z] Execute: "echo hello, world." from "~/src/ifft-test"
Exit code: 0
Stdout:
hello, world.
Stderr:
如你所见,触发命令的匹配条件、退出码、stdout 和 stderr 都被打印出来。
就这样。 ifft
只是监听文件更改并采取行动。
过滤器
使用 not
参数指定要过滤掉触发事件的文件模式
[[ifft]]
if = "**/*.{c,h}"
not = [
"*~",
"*.swp", # Filter out swap files
"dist/**/*", # Filter out outputs of compilation
]
then = "gcc main.c -o dist/prog"
not
也可以在配置级别指定,这将适用于所有 ifft
not = [
"*~",
"*.swp", # Filter out swap files
"dist/**/*", # Filter out outputs of compilation
]
[[ifft]]
if = "**/*"
then = "gcc main.c -o dist/prog"
路线图功能是提供一个标志以自动忽略 .gitignore
中的模式。
工作目录
默认情况下,执行then
子句的工作目录是触发ifft.toml
文件的文件夹。要覆盖默认设置,请使用working_dir
参数来指定[[ifft]]
。
路径替换
then
子句可以使用{{}}
占位符,该占位符将被触发ifft的修改文件的路径替换。
启动时
如果您希望在启动时自动触发ifft,而不需要任何文件事件,请使用-r
标志。该参数将触发所有匹配名称的ifft。例如
ifft ~/src/ifft-test -r build
匹配
[[ifft]]
name = "build" # Triggered by -r flag
not = ["target/*"]
then = "cargo build"
这确保了在启动时构建项目,而无需等待文件事件。
您还可以使用-q
标志在-r
标志触发完成后退出。这可以用来执行一次性的构建或清理,而不需要之后监听更改。
分发iffts
想象一下您有以下文件系统树
~/src/my-app
~/src/my-app/my-c-service
~/src/my-app/my-rust-service
虽然您可以创建一个包含所有项目ifft的配置文件~/src/my-app/ifft.toml
,但更好的方法是每个服务目录中创建一个ifft.toml
。
当调用ifft
时,它将报告已找到的配置
$ ifft ~/src/my-app
Found config: "~/src/my-app/ifft.toml"
Found config: "~/src/my-app/my-c-service/ifft.toml"
Found config: "~/src/my-app/my-rust-service/ifft.toml"
这允许您将配置文件分布在文件系统树中,这有利于保持它们的小型和与所在文件夹的相关性。
依赖项
如果您有跨项目依赖项,您可能希望根据另一个ifft触发ifft。这可以使用listen
和emit
实现。
假设以下文件系统树
~/src/my-app
~/src/my-app/my-c-service/ifft.toml
~/src/my-app/my-rust-service/ifft.toml
如果my-rust-service
依赖于my-c-service
,您可以编写以下内容
[[ifft]]
if = "listen:../my-c-service:built" # Listens for "built" from my-c-service
then = "cargo build"
my-c-service/ifft.toml
可以编写如下
[[ifft]]
if = "**/*.{c,h}"
then = "gcc *.c -o c-service"
emit = "built" # Emits "built" to listeners
对于“启动时”ifft,可以使用类似模式。使用on_start_listen
#
# my-rust-service/ifft.toml
#
[[ifft]]
name = "build"
if = "on_start_listen:../my-c-service:built"
then = "cargo build"
#
# my-c-service/ifft.toml
#
[[ifft]]
name = "build"
then = "gcc *.c -o c-service"
emit = "built"
使用启动语法(ifft my-app -r build -q
)将按照正确的顺序执行这些ifft:首先my-c-service
;其次my-rust-service
。
委派
IFFT还可以启动其他监视/重新编译程序。例如,使用npm
/yarn
(例如yarn watch
)的文件监视器设置很常见。要委派监视,请使用[[delegate]]
部分
[[delegate]]
cmd = "yarn watch"
委派是在“启动时”触发之后启动的。这种排序是有意为之,以便“启动时”可以执行委派所需的设置(例如yarn install
)。
可以设置可选的restart_on
字段,其值以listen:path:emit
格式给出,以触发委派进程的重新启动。
委派对于使IFFT成为大型多项目存储库中的主要文件监视工具非常有用。
特性
- 使用
toml
文件进行配置。 - 可以在文件系统树中分布配置文件。
- 为
if
和not
条件使用glob模式。 - 全局
not
过滤和每个触发器的not
过滤。 - 如果多个事件触发相同的
if
,则只有在触发then
后的事件才会执行then
。 - 在启动时,可以触发与名称匹配的 iffts,而无需任何文件事件。
- 具有符号链接组件的路径上的事件也会对其绝对路径等价物进行触发测试。
- 依赖项
- 可以通过监听来自另一个程序的发出标签来触发 ifft。
- 在启动时,可以通过依赖图对 iffts 进行排序。
- 在配置收集和文件夹监视过程中,尊重忽略文件(隐藏的,
.gitignore
,...)。
平台
已在 Linux 和 OS X 上进行测试。其他地方未测试。
与 VirtualBox 共享文件夹一起使用
在客户操作系统上,VirtualBox 共享文件夹不会生成文件系统事件通知。您需要使用单独的文件系统事件转发器,如 notify-forwarder。
替代方案
待办事项
- 尊重触发文件的忽略文件。
- 多级标志,用于控制打印的详细程度。
- 将连续发生的事件分组,并只触发一次。
- 允许自定义触发文件系统事件的类型。
- 低优先级:计算监视的最佳路径前缀。
- 性能:不要在每次使用之前编译 glob。当前黑客手段,如果发生错误,则易于访问 glob 模式字符串。
依赖项
~8–18MB
~240K SLoC