【问题标题】:Installing additional files at install time with ExtUtils::MakeMaker/Dist::Zilla (dzil)在安装时使用 ExtUtils::MakeMaker/Dist::Zilla (dzil) 安装附加文件
【发布时间】:2019-04-05 03:47:10
【问题描述】:

tl;dr 我想用我的 Perl 库发送一个 package.json,运行 yarn install(或在安装过程中的 npm install)并使用 Perl 模块安装下载的 JavaScript 依赖项。

我有以下dist.ini

name = Foobar
version = 1.2.3
license = Perl_5
copyright_holder = Yours Truly
copyright_year   = 2018

[@Filter]
-bundle = @Basic
-remove = GatherDir
[Git::GatherDir]

[Web::FileHeader]
header_filename = EMM-include.pm
file_match = ^Makefile\.PL$

文件EMM-include.pm 包含一个MY::postamble 方法:

package MY;

use strict;

use Cwd qw(abs_path);
use File::Spec;

sub postamble {
    my ($self) = @_;

    my $here = Cwd::abs_path();
    my $libdir = File::Spec->catdir($here, 'lib', 'Foobar');
    chdir $libdir or die;
    0 == system 'yarn', 'install' or die;
    chdir $here or die;

    return '';
}

插件[Web::FileHeader] 获取文件并将其修补到Makefile.PL 的开头。

然后有一个lib/Foobar/package.json

{
  "name": "foobar",
  "version": "1.2.3",
  "main": "index.js",
  "dependencies": {
    "ajv": "^6.5.4"
  }
}

来自EMM-include.pmMY::postamble 部分调用yarn install(如果没有yarn,则将其替换为npm install)并使用ajv 及其依赖项填充目录lib/Foobar/node_modules

最后,必须有一个模块lib/Foobar.pm

package Foobar;
# ABSTRACT: Just a test.
1;

几乎按预期工作:可以使用dzil build 创建分发。在分发目录中,perl Makefile.PL 调用yarn install,目录lib/Foobar/node_modules 被填充,但其中的文件没有与make install 一起安装。

如果我第二次运行 perl Makefile.PL,一切正常,JavaScript 依赖项将其变为 blib/make install 将安装 JavaScript 模块和 Perl 模块。

将 JavaScript 依赖项与分发一起提供不是一种选择。它们已经太多了,而且它们可能有冲突的许可证(我在这里使用的是 GPLv3)。在运行时下载deps,安装后大多会因为缺少权限而失败。

的确,这与Dist::Zilla 没有太大关系,而是ExtUtils::MakeMaker 的问题。但我实际上在这里使用Dist::Zilla

如果重要的话,真正的分布是https://github.com/gflohr/qgoda,而在撰写本文时的最后一次提交是https://github.com/gflohr/qgoda/commit/3f34a3dfec8da665061432c3a8f7bd8eef28b95e

【问题讨论】:

  • 我明天的下一个尝试是查找由yarn/npm 安装的所有文件,然后将它们添加到Makefile 变量TO_INST_PM。我在正确的轨道上吗?还是有更简单的方法?

标签: perl makemaker dist-zilla


【解决方案1】:

首先,不要使用 [Web::FileHeader] 来修改 Makefile.PL,而是将 [MakeMaker](@Basic 使用)替换为 [MakeMaker::Awesome],这样您就可以直接修改 Makefile.PL,并且正确启用 dynamic_config 因为您的发行版需要它。另外,不要给你的包含文件一个 .pm 扩展名,因为它不是一个 perl 模块,并且将它排除在被收集到生成的发行版中,这样它就不会被意外安装。

[@Filter]
-bundle = @Basic
-remove = GatherDir
-remove = MakeMaker
[Git::GatherDir]
exclude_filename = EMM-include
[MakeMaker::Awesome]
header_file = EMM-include

我强烈建议使用我的@Starter bundle 而不是过时的@Basic,但如果不是至少添加 [MetaJSON] 以便您拥有现代元数据。

[@Starter::Git]
revision = 3
installer = MakeMaker::Awesome
Git::GatherDir.exclude_filename[] = EMM-include
MakeMaker::Awesome.header_file = EMM-include

关于安装时需要做什么。首先我要提醒的是,需要互联网连接来安装并不是你总是可以依赖的,当然也没有可用的纱线。但是用于安装外部库的Alien 系列模块经常做这种事情。由于您不需要编译此代码,您可能不需要整个 Alien::Build/Alien::Base 设置,但它可能比下面描述的 Makefile hacking 更容易解决您的问题。基本上你会首先发布一个 Alien 发行版,它会在必要时安装你的 javascript 库,然后这个发行版可以依赖它来加载库。如果您决定追求这个方向,请查看 Alien::Build 和 IRC 频道 #native on irc.perl.org


ExtUtils::MakeMaker 的后序部分不适用于运行任意代码;它用于向它生成的 Makefile 添加自定义规则;这是您需要影响制作过程的方式。我对 Makefile 知之甚少,所以在这里我无法为您提供进一步帮助,我只能建议阅读所有 EUMM docs 并注意 postamble 是 MM_Any 中的一个函数,您可以覆盖它以添加文本,其中MM_Any 和 MM_Unix 的其他选项。您也许可以在 IRC 频道#toolchain on irc.perl.org 上找到帮助您朝这个方向发展的人。

【讨论】:

  • 我知道安装需要互联网连接,但就是这样,如果我需要外部文件,我无能为力。
  • 我已经进行了快速检查,您的建议将起作用。当然,关于 postamble,你是对的,我将把代码移到方法之外。我的例子只是为了重现这个问题。我已经有一个META.json 并且EMM-include.pm 已经从安装中排除。 Alien::Build 似乎不适合我的用例,但这是另一个问题。感谢您的精彩回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 2014-11-20
相关资源
最近更新 更多