当前位置: 首页 > 知识库问答 >
问题:

如何为Raku CLI使用包装器脚本

景俊良
2023-03-14

我想知道在Raku中创建CLI应用程序时,建议使用哪些步骤(例如shebang行和包装脚本)。我对将与Zef一起安装的脚本和将单独分发的脚本的信息都感兴趣。

这些文件提供了示例frobnate程序:

# inside "frobnicate.raku" 
sub MAIN(Str $file where *.IO.f, Int  :$length = 24, Bool :$verbose) { #`(body omitted)}

我可以用rakufrobnicate.raku运行,这是脚本的一个很好的解决方案,但对真正的程序来说不是很好。

如果我想让它更像一个标准程序,我可以创建一个frobnite文件,如下所示:

#!/usr/bin/env raku
sub MAIN(Str $file where *.IO.f, Int  :$length = 24, Bool :$verbose) { #`(body omitted)}

我可以使用chmod x使该文件可执行,并将其移动到我的$PATH中的一个目录中;然后我可以使用命令frobnite进行frobnite。到目前为止,所有这些都是非常有意义的,就像任何其他脚本语言一样。

然而,这些都没有利用Raku的编译。因此,在MAIN中执行更多处理的CLI应用程序可能会变得有点慢(甚至对于生成--help输出也是如此)。因此,下一步是允许应用程序预编译,但我不太确定如何做到这一点。

当我看一下我在用Zef安装Raku程序后执行的脚本时,它们几乎都有以下形式:

#!/usr/bin/env perl6
sub MAIN(:$name, :$auth, :$ver, *@, *%) {
    CompUnit::RepositoryRegistry.run-script("frobnicate", :$name, :$auth, :$ver);
}

当我检查包的源代码时,这个CompUnit::RepositoryRegistry。运行脚本行不存在。所以我猜Zef加了它?如果是这样的话,在编写脚本时,我需要做些什么来确保Zef使用这个包装器,并且包装器可以工作?

(这个评论有助于理解发生了什么,尽管我仍然不确定我100%明白)。

我想编写用户无需通过Zef安装即可运行的脚本(尽管这是我推荐的安装方法)。有没有办法在没有Zef的情况下使用上面显示的运行脚本方法?或者我应该做下面的事情,我也看到了:

#!/usr/bin/env raku
use Frobnicate::CLI

(然后将实际功能移动到frobnite/CLI.rakumod文件中)。

如果我这样做,我需要指示用户下载上面的frobnite包装脚本和frobnite/CLI。rakumod文件,对吗?(也就是说,没有办法在单个文件中执行此操作,是吗?)

假设我确实需要让我的用户下载两个文件,我应该让他们在哪里安装文件frobnite需要进入其路径中的目录,但是frobnite/CLI呢。拉库莫德?是否需要将其复制到Raku模块搜索路径中(如果需要,什么命令会显示该路径)?或者我可以以某种方式修改frobnite包装器(可能通过将raku更改为raku-Ilib或类似的方式?)在某种程度上,他们可以将两者安装到其路径上的目录中

在把这些都打出来后,我觉得我可能戏剧性地过度思考了。如果是,请让我知道,以及!无论如何,如果我能更好地理解这一点,我很乐意在文档的相关部分添加更多的细节。


共有2个答案

姬存
2023-03-14

关于这个话题的一些评论。

>

  • 我认为,最好使用zef,因为zef也会加载依赖项。在不使用其他模块的情况下编写Raku程序已经很不寻常了,我希望随着更多Raku模块的开发,这将变得更加不寻常。

    我忘记了在我的系统上安装了哪些模块,以及包含在程序中的模块。通过在META6中指定所有内容。json,然后运行zef测试 ,确保其他人可以下载该模块的机会提高。实际上,我已经找到了确保这一点的最佳方法,即创建一个docker文件并尝试在docker映像/容器中安装一个新模块——但这是另一个主题。

    我发现(对于Linux,我不能评论Windows),如果我:

    • 用Raku编写一个可执行文件(见下文),让我们称之为MyWonder

    然后,当zef安装发行版时,MyWonder将在命令行上工作(假设zef本身在命令行上工作,这意味着PATH包含到zef的目录)。

    调用要在命令行上使用或由桌面调用的程序的最佳(对我来说)方式是:

    • 将以下内容放入MyWonder文件(无需扩展名)
    use v6.d;
    use MyWonderLife;
    
    • 将所有功能放入MyWonderLife。拉库莫德

    这个配方意味着所有的功能都是由zef预编译的,所以当用户调用可执行文件时,会有更快的响应。使用Raku时最慢的部分是编译程序。通过使用zef安装,这在安装过程中完成一次。所有语言的程序安装都很慢,所以Raku程序不会让用户在使用它的时候想知道发生了什么。

    其次,可以使用几个多个子MAIN来处理各种调用情况,并使用现在可以处理的命令行选项范围。虽然这在任何脚本中都是可能的,但将它们都放在一个. rakumod文件中(对我来说)似乎更自然。

    我发现在安装模块时,大量的测试是一个痛苦的过程,所以我已经开始将大部分开发和维护测试转移到xt/,并且只在t/中进行简单的安装测试。

    最后,根据此配方(假设您在META6.json文件中为发行版命名为MyWonderLife),MyWonder的安装说明(假设可以无参数调用程序)如下所示:

    使用zef安装MyWonderLife,例如。,

    zef install MyWonderLife
    

    并在命令行中使用它,如下所示:

    MyWonder
    

  • 仲孙飞文
    2023-03-14
    匿名用户

    所以我猜Zef加了它?

    CompUnit::Repository::Installation添加了它

    为什么会在那里?一个原因是,一些包装器需要管理bin脚本,如果它们在同一个目录中,则它们的名称会发生冲突。

    有没有办法在没有Zef的情况下使用上面显示的运行脚本方法?

    运行脚本仅用于CompUnit::Repository::安装——如果您不安装模块,则不会对运行脚本感兴趣

    假设我确实需要让我的用户下载两个文件,我应该让他们在哪里安装文件?

    推荐/惯用的方法是使用核心raku功能来安装东西(即使用zef)。否则,你应该把一些代码放在a)无关紧要的地方,或者b)主要依赖于你的环境,你的操作系统的习惯用法,等等。

    是否需要将其复制到他们的Raku模块搜索路径中(如果需要,什么命令将向他们显示该路径)

    echo$RAKULIB应该足以在大多数情况下显示模块搜索路径,特别是如果他们对安装路径的位置不感兴趣。因此,如果你想让用户能够运行你的脚本,而不需要通过raku-I手动指定它,你可以指示用户将例如RAKULIB=$FROB_LIB_DIR设置为指向你的库所在的任何地方.../frobnate(所以他们不会复制代码任何特殊的地方,他们只是指向他们例如克隆你的回购)。使用$PATH也是如此。

    或者我可以以某种方式修改frobnate包装(也许通过将raku更改为raku-Ilib或类似的方式?)在某种程度上可以让他们安装两个目录在他们的PATH?

    我建议不要基于$PATH中的某个值来安装东西。指导用户设置$PATH,不要将东西安装到$PATH

    从技术上讲,您可以添加使用lib'../' 添加到脚本中,但在您也希望用户正常安装的脚本中使用use lib并不理想,因为它在从此类安装运行时添加了一个未使用的、可能被劫持的模块搜索路径。

    如果你想让你的代码预编译,那么我建议把它放在一个模块中,并指示你的用户,如果他们不打算安装它,通过raku-I../调用它/Frobnite以每次使用为基础,或类似于导出RAKULIB=“$FROB_LIB_DIR,$RAKULIB”后接/Frobnite用于更持久的内容。或者,如果有人甚至实现了脚本的预编译,那么您可以使用单文件方法。

     类似资料:
    • 我们如何以编程的方式安装 Composer? 如下载页面所指出的,这个安装程序包含一个签名,当安装程序代码发生改变时,它会随之发生改变,因此不应该长期依赖。 还有另一种方法,就是使用只对 UNIX 实用程序工作的脚本: #!/bin/sh EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" p

    • 未能应用插件[id'com.android.application']需要版本2.10。当前版本是2.8。如果使用gradle包装器,请尝试将d:\android\swiperefreshlistfragment\gradle\wrapper\gradle-wrapper.properties中的distributionUrl编辑为gradle-2.10-all.zip 这个问题出现在分级同步..

    • 我对格拉德尔很陌生,我现在正在努力学习。我成功地将gradle配置为一个非常简单的项目。目前我正在努力学习gradle包装器。它规定我不需要在我的系统上下载gradle。我可以在构建中添加任务包装器。gradle文件并运行任务gradle包装器。它应该下载gradle并创建gradlew。蝙蝠档案。 对不起,我太天真了,但我不太明白。如果我的机器上没有安装gradle,将如何运行该任务。 谢谢

    • 如何描述tippy接受typescript将正确使用的任何子级的包装器? 这样使用: 打字稿给我错误的孩子在返回语句: 输入'string | number | true |{}| ReactElement(元件)

    • 我有段时间很疑惑。我现在不能为我的python35安装/升级任何包。我在mac上有python27和python35(通过anaconda)。每当我想通过pip安装python包时,就会调用与python2配对的那个包。 转到anaconda文件夹(安装了我的python35的地方):ls-al|grep pip我得到了结果: 在我的. bashrc文件中,我定义了: 当我键入python2时:

    • 我在jmeter中面临一个问题,我想知道我能否解决这个问题。我需要在远程计算机上运行一个脚本。当我在电脑上通过命令行运行脚本时,它正在工作。 我想在我的计算机上用Jmeter运行它(与脚本运行相同)。我尝试了ssh采样器,但没有成功。我想使用操作系统采样器。可以吗?我可以在远程计算机上运行脚本吗?我找到的唯一解释来自blazemeter网站,并提到:“同样,由于通过操作系统进程采样器运行“plin