cod*_*ons 11 command-line-interface rakudo zef raku
我想知道在 Raku 中创建 CLI 应用程序时推荐哪些步骤(例如 shebang 行和包装脚本)。我对将与 Zef 一起安装的脚本和将单独分发的脚本的信息都感兴趣。
文档提供了示例frobnicate程序:
# inside "frobnicate.raku" 
sub MAIN(Str $file where *.IO.f, Int  :$length = 24, Bool :$verbose) { #`(body omitted)}
我可以用它来运行raku frobnicate.raku——一个很好的脚本解决方案,但对真正的程序来说不是很好。
如果我想让它更像一个标准程序,我可以创建一个frobnicate这样的文件:
#!/usr/bin/env raku
sub MAIN(Str $file where *.IO.f, Int  :$length = 24, Bool :$verbose) { #`(body omitted)}
我可以使该文件可执行chmod +x并将其移动到我的目录中$PATH;然后我可以用命令 frobnicate frobnicate。到目前为止,所有这些都非常合理,就像任何其他脚本语言一样。
然而,这些都没有利用 Raku 的编译。因此,执行更多处理的 CLI 应用程序MAIN可能会变得有点慢(即使是生成--help输出)。因此,下一步是允许预编译应用程序,但我不太确定如何执行此操作。
当我查看使用 Zef 安装 Raku 程序后执行的脚本时,它们几乎都具有以下形式:
#!/usr/bin/env perl6
sub MAIN(:$name, :$auth, :$ver, *@, *%) {
    CompUnit::RepositoryRegistry.run-script("frobnicate", :$name, :$auth, :$ver);
}
而且,当我检查包的来源时,这CompUnit::RepositoryRegistry.run-script条线不存在。所以我猜Zef会添加它?如果是这样,在编写我的脚本时我需要做些什么来确保 Zef 将使用这个包装器并且包装器可以工作?
(此评论有助于理解发生了什么,尽管我仍然不确定我是否 100% 明白)。
我想编写用户无需通过 Zef 安装即可运行的脚本(尽管这是我推荐的安装方法)。有没有办法run-script在没有 Zef 的情况下使用上面显示的方法?或者我应该做以下类似的事情,我也看到过:
#!/usr/bin/env raku
use Frobnicate::CLI
(然后将实际功能移动到Frobnicate/CLI.rakumod文件中)。
如果我走这条路,我需要指示用户下载frobnicate上面的包装脚本和Frobnicate/CLI.rakumod文件,对吗?(也就是说,无法在单个文件中执行此操作,是吗?)
假设我确实需要让我的用户下载两个文件,我应该让他们在哪里安装这些文件?  frobnicate需要进入他们的目录PATH,但是呢Frobnicate/CLI.rakumod?是否需要将其复制到他们的 Raku 模块搜索路径中(如果需要,什么命令会向他们显示该路径是什么)?或者,我可以修改frobnicate以某种方式包装(可能通过改变raku到raku -Ilib的方式,将让他们两个目录上的安装或类似的东西?) PATH?
把所有这些都打出来后,让我震惊的是我想得太多了。如果是这样,也请让我知道!无论如何,如果我能更好地理解这一点,我很乐意在文档的相关部分添加更多细节。
所以我猜Zef会添加它?
CompUnit::Repository::Installation 添加它
为什么会在那里?一个原因是因为某些包装器需要管理同名的 bin 脚本,否则如果它们在同一目录中,则会发生冲突。
有没有办法在没有 Zef 的情况下使用上面显示的 run-script 方法?
run-script 仅用于 CompUnit::Repository::Installation -- 如果您不安装模块,则run-script不会感兴趣
假设我确实需要让我的用户下载两个文件,我应该让他们在哪里安装这些文件?
那么推荐/惯用的方法是使用核心 raku 功能来安装东西(即使用 zef)。否则你应该放一些代码的地方要么是 a) 无关紧要,要么 b) 主要取决于你的环境,什么是你的操作系统惯用的等等。
是否需要将其复制到他们的 Raku 模块搜索路径中(如果需要,什么命令会向他们显示该路径是什么)
echo $RAKULIB在大多数情况下,应该足以显示模块搜索路径,尤其是当他们对安装路径的位置不感兴趣时。因此,您可以指示用户设置例如RAKULIB=$FROB_LIB_DIR指向您的库所在的任何位置,如果您希望他们能够运行您的脚本而无需手动指定它raku -I../  frobnicate(因此他们不会将代码复制到任何特殊的地方,他们只是指向他们的任何位置例如克隆你的回购)。与$PATH.
或者我可以以某种方式修改 frobnicate 包装器(也许通过将 raku 更改为 raku -Ilib 或类似的东西?),让他们将两者都安装到他们的 PATH 目录中?
我建议不要根据$PATH. 指导用户设置$PATH,不要安装东西到$PATH.
从技术上讲,您可以添加use lib '../'到您的脚本中,但use lib在您还希望用户正常安装的脚本中使用并不理想,因为它在从此类安装运行时添加了未使用的、可能被劫持的模块搜索路径。
如果您希望您的代码进行预编译,那么我建议将它放在一个模块中,并指示您的用户,如果他们不打算安装它,则raku -I../  ./frobnicate在每次使用的基础上调用它,或者export RAKULIB="$FROB_LIB_DIR,$RAKULIB"通过类似的方式调用它以./frobnicate获取更多信息永恒的。或者,如果有人最终实现了脚本的预编译,那么您可以只使用单文件方法。