You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写测试脚本检查Perl模块Makefile.PL的依赖声明完整性?

实现t/00-check-deps.t检查依赖是否在Makefile.PL中声明

推荐方案:使用现成CPAN模块

直接用Test::Dependencies模块即可完成需求,它会自动解析你的模块依赖并对比Makefile.PL中的声明,无需手动编写大量代码。

测试脚本代码(t/00-check-deps.t)

use strict;
use warnings;
use Test::More;
use Test::Dependencies exclude => [qw(strict warnings)];

# 检查所有依赖是否已声明
ok_dependencies();
done_testing();

配置测试依赖(Makefile.PL)

需要将Test::Dependencies添加到测试阶段的依赖中:

use ExtUtils::MakeMaker;

WriteMakefile(
    NAME          => 'MyModule',
    VERSION_FROM  => 'lib/MyModule.pm',
    TEST_REQUIRES => {
        'Test::More'          => '0.98',
        'Test::Dependencies'  => '0.12',
    },
    # 你的其他配置...
);

手动实现方案(无需额外测试模块依赖)

如果不想引入Test::Dependencies,可以手动解析模块和Makefile.PL的依赖信息,核心步骤是:解析模块中的use/require语句、提取Makefile.PL中声明的依赖、对比找出遗漏项。

手动实现的测试脚本

use strict;
use warnings;
use Test::More;
use PPI;
use JSON::PP;
use Module::CoreList;

# 1. 生成并读取MYMETA.json获取已声明的依赖
system('perl Makefile.PL') == 0 or die "Failed to execute Makefile.PL";
open my $mymeta_fh, '<', 'MYMETA.json' or die "Can't open MYMETA.json: $!";
my $mymeta = decode_json(do { local $/; <$mymeta_fh> });
close $mymeta_fh;

# 收集所有已声明的依赖(runtime、test、build阶段)
my %declared_deps;
for my $phase (qw(runtime test build)) {
    next unless exists $mymeta->{prereqs}{$phase}{requires};
    $declared_deps{$_} = 1 for keys %{$mymeta->{prereqs}{$phase}{requires}};
}

# 2. 解析目标模块获取实际使用的非核心依赖
my $module_doc = PPI::Document->new('lib/MyModule.pm') or die "Can't parse MyModule.pm: $!";
my %used_deps;

# 遍历所有use语句
my $use_statements = $module_doc->find('Statement::Include') or die "No use statements found";
for my $stmt (@$use_statements) {
    my $module = $stmt->module or next;
    # 排除核心pragma、Perl版本声明、核心模块
    next if $module =~ /^(strict|warnings)$/;
    next if $module =~ /^5\./;
    next if Module::CoreList::is_core($module, undef, $^V);
    $used_deps{$module} = 1;
}

# 3. 对比找出未声明的依赖
my @missing_deps = grep { !exists $declared_deps{$_} } keys %used_deps;

if (@missing_deps) {
    fail("Missing dependencies in Makefile.PL: " . join(', ', @missing_deps));
} else {
    pass("All non-core dependencies are properly declared");
}

done_testing();

手动实现的注意事项

  • 需要将PPI、JSON::PP、Module::CoreList添加到TEST_REQUIRES中
  • 测试时会生成MYMETA.json,可以在Makefile.PL的clean规则中添加删除逻辑
  • 可扩展解析更多模块文件(如lib/下的所有.pm)或脚本文件

内容的提问来源于stack exchange,提问作者KJ7LNW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:39:18