【问题标题】:compiling python file with Watchman使用 Watchman 编译 python 文件
【发布时间】:2015-11-28 22:15:42
【问题描述】:

从守望者那里捕获文件/路径信息以传递的最佳方法是什么 “制作”或其他应用程序?

这是我想要达到的目标:

当我在开发服务器上保存 .py(s) 文件时,我想检索文件名和路径,将 py 编译为 pyc,然后将 pyc 文件传输到暂存服务器。

我应该使用 watchman-make、'heredoc' 方法、ansible 等吗? 因为文档非常有用,有没有可用的示例?

还有,pywatchman 的用例是什么?

提前致谢

【问题讨论】:

标签: python compilation watchman


【解决方案1】:

希望这将有助于澄清一些事情:

Watchman 作为每用户服务运行以监控您的文件系统。它可以:

  1. 在文件更改发生时提供实时订阅
  2. 发生文件更改时触发在后台运行的命令
  3. 回答有关文件自给定时间点以来如何更改的查询

pywatchman 是一个 python 客户端实现,允许您构建使用来自 watchman 的信息的应用程序。 watchman-makewatchman-wait 工具是使用 pywatchman 实现的。

watchman-make 是一个工具,可帮助您在文件更改时调用make(或类似程序)。在您要运行的程序不需要刚刚更改的文件的特定列表的情况下,这是最合适的。 make 属于此类别; make 将分析您的 Makefile 中的依赖关系,然后仅构建更改的部分。您也可以执行 python distutils 或 setuptools setup.py 脚本。

本机守望者触发器比watchman-make 更难使用,因为它们是由守望者服务在后台生成的,并通过更改文件列表传递。这些最适合完全无人参与的进程,您不需要查看输出并且需要更改文件的精确列表。

根据您的描述,听起来最简单的解决方案是执行编译步骤然后执行同步的脚本,类似于以下内容;我们就叫它build-and-sync.sh

#!/bin/sh
python -m compileall .
rsync -avz . host:/path/

(如果您真的不需要.pyc 文件而只需要同步,那么您可以简单地从上面的脚本中删除python 行并让它运行rsync

然后您可以在事情发生变化时使用watchman-make 执行此操作:

watchman-make --make='build-and-sync.sh' -p '**/*.py' -t dummy

然后,在更改任何.py 文件(或一组.py 文件)后,watchman-make 将执行build-and-sync.sh dummy。这应该足够了,除非您有足够多的 python 文件,以至于每次进行更改时编译步骤都需要很长时间。 watchman-make 将继续运行,直到您按 CTRL-C 或以其他方式终止进程;它会在终端窗口的前台运行,除非您使用 nohuptmuxscreen 之类的东西来让它保持更长时间。

如果是这种情况,那么您可以尝试使用 make 和模式规则来仅编译更改的 python 文件,或者如果使用 make 表达起来很尴尬,那么也许值得使用 pywatchman 来建立一个订阅并编译更改的文件。这是一个更高级的用例,我建议查看watchman-wait 的代码以了解如何实现。除非您有大量文件或同步时间非常紧迫,否则可能不值得为此付出额外的努力。

我建议先尝试最简单的解决方案,看看是否满足您的需求,然后再尝试更复杂的选项之一。

使用原生触发器

作为替代方案,您可以使用触发器。它们在后台运行,其输出将发送到 watchman 日志文件。与使用 watchman-make 相比,它们更难使用。

您需要编写一个小程序,通常是一个脚本,来接收来自触发器的更改文件列表;最好的方法是通过脚本的标准输入。您可以接收每行一个文件的列表或具有更多结构化信息的 JSON 对象。我们称这个脚本为trigger-build-and-sync;由您来实现脚本的内容。假设您只需要 stdin 上的文件列表。

此命令将设置触发器;你调用它一次,它会一直持续到手表被移除:

watchman -j <<-EOT
["trigger", "/path/to/root", {
   "name": "build-and-sync",
   "expression": ["suffix", "py"],
   "command": "/path/to/trigger-build-and-sync",
   "append_files": false,
   "stdin": "NAME_PER_LINE"
}]
EOT

完整的文档可以在https://facebook.github.io/watchman/docs/cmd/trigger.html#extended-syntax找到

【讨论】:

  • "...这些最适合完全无人值守的进程,您不需要查看输出并且需要更改文件的精确列表"触发器是无人值守进程所需要的,但是如何我要检索守望者提供的文件名/路径列表吗?感谢您的快速回复
  • Watchman 将向您传递一个 JSON 对象,其中包含触发器程序标准输入上的文件列表。您需要为此使用extended trigger syntax,并在触发器定义中将stdin 属性设置为["name"]
  • "...我建议先尝试最简单的解决方案,看看是否满足您的需求,然后再尝试更复杂的选项之一。"文档使它变得复杂。我所看到的只是“heredoc”的例子。所以基本上,我创建了一个 .watchmanconfig 文件,将扩展的 json 触发器语法添加到它,等等。你提到“..on the stdin of your program”,建议我创建某种旨在将 stdin 读取为的脚本/应用程序命令放在我的触发器定义中?我还查看了 watchman-wait 命令。我更接近解决方案,但它似乎不是递归的。为什么?谢谢!
  • 我已经扩展了上面的答案以包含有关触发器的更多详细信息。手表绝对是递归的。我上面给出的使用watchman-make 的例子应该可以解决问题。请注意,watchman-make 在运行时捕获 pwd,因此您应该 cd 到您的根目录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 2016-08-10
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
相关资源
最近更新 更多