如何使用 PPI 查找注释,然后在其前面插入代码?

发布于 2024-09-11 19:18:34 字数 1171 浏览 6 评论 0原文

我试图在 perl 源文件中找到注释 # VERSION 。然后我想在评论之前插入版本(或代替无关紧要)。谁能告诉我使用 PPI 执行此操作的正确方法?

之前,

use strict;
use warnings;
package My::Package;
# VERSION
...

之后

use strict;
use warnings;
package My::Package;
our $VERSION = 0.1;# VERSION
...

在维护最终结果中的 # VERSION

我实际上对如何查找 # VERSION 有一些想法,但其中一个是序列化 ppi 文档的正则表达式,这似乎不正确,并且另一个是在评论上使用 find_first ,但如果它不是第一个,我不知道该怎么做。

更新的代码 这似乎更接近正确的解决方案,因为它只查看注释。但我不确定如何使用或真正如何创建新变量。

#!/usr/bin/env perl
use 5.012;
use strict;
use warnings;

use PPI;

my $ppi = PPI::Document->new('test.pm');

my $comments = $ppi->find('PPI::Token::Comment');

my $version = PPI::Statement::Variable->new;

foreach ( @{$comments} ) {
    if ( /^\s*#\s+VERSION\b$/ ) {
        $_->replace($version);
    }
}

更新

这个问题的答案成为DZP::OurPkgVersion

I'm trying to find the comment # VERSION in a perl source file. I then want to insert the version before the comment (or in place of doesn't matter). Could anyone tell me the right way to do this with PPI?

before

use strict;
use warnings;
package My::Package;
# VERSION
...

after

use strict;
use warnings;
package My::Package;
our $VERSION = 0.1;# VERSION
...

maintaining the # VERSION in the end result is optional

I actually have a couple of ideas on how to find # VERSION but one is a regex of a serialized ppi doc which doesn't seem right, and the other is using find_first on a Comment but if it's not the first I'm not sure what to do.

Updated code This seems closer to a correct solution since it only looks at the comments. but I'm not sure how to use or really how to create a new variable.

#!/usr/bin/env perl
use 5.012;
use strict;
use warnings;

use PPI;

my $ppi = PPI::Document->new('test.pm');

my $comments = $ppi->find('PPI::Token::Comment');

my $version = PPI::Statement::Variable->new;

foreach ( @{$comments} ) {
    if ( /^\s*#\s+VERSION\b$/ ) {
        $_->replace($version);
    }
}

UPDATE

The answer to this question became the foundation for DZP::OurPkgVersion

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

﹏半生如梦愿梦如真 2024-09-18 19:18:36

这里有一些代码可以完成您所描述的操作 - 无论如何它都会让您开始。它是从 Catalyst::Helper::AuthDBIC (来源),这是使用 PPI 的完整示例(尽管其中一些可能不是最佳实践):

sub make_model {
    ### snip some stuff
    my $module = "lib/$user_schema_path.pm";
    my $doc = PPI::Document->new($module);
    my $digest_code = # some code
    my $comments = $doc->find(
        sub { $_[1]->isa('PPI::Token::Comment')}
    );
    my $last_comment = $comments->[$#{$comments}];
    $last_comment->set_content($digest_code);
    $doc->save($module);
}

我想在您的情况下,您会获取 $comments arrayref 并修改与 /VERSION/ 匹配的第一个项目与替换内容。

这是海报提供的最终代码:

#!/usr/bin/env perl
use 5.012;
use warnings;

use PPI;

my $ppi = PPI::Document->new('test.pm');

my $comments = $ppi->find('PPI::Token::Comment');

my $version = 0.01;

my $_;
foreach ( @{$comments} ) {
    if ( /^(\s*)(#\s+VERSION\b)$/ ) {
        my $code = "$1" . 'our $VERSION = ' . "$version;$2\n";
        $_->set_content("$code");
    }
}
$ppi->save('test1.pm');

Here's some code that does something like what you describe - It'll get you started anyway. It's edited from Catalyst::Helper::AuthDBIC (source), which is a full example of working with PPI (although bits of it may not be best practices):

sub make_model {
    ### snip some stuff
    my $module = "lib/$user_schema_path.pm";
    my $doc = PPI::Document->new($module);
    my $digest_code = # some code
    my $comments = $doc->find(
        sub { $_[1]->isa('PPI::Token::Comment')}
    );
    my $last_comment = $comments->[$#{$comments}];
    $last_comment->set_content($digest_code);
    $doc->save($module);
}

I suppose in your case you grab the $comments arrayref and modify the first item that matches /VERSION/ with the replacement content.

And here's the final code courtesy of the poster:

#!/usr/bin/env perl
use 5.012;
use warnings;

use PPI;

my $ppi = PPI::Document->new('test.pm');

my $comments = $ppi->find('PPI::Token::Comment');

my $version = 0.01;

my $_;
foreach ( @{$comments} ) {
    if ( /^(\s*)(#\s+VERSION\b)$/ ) {
        my $code = "$1" . 'our $VERSION = ' . "$version;$2\n";
        $_->set_content("$code");
    }
}
$ppi->save('test1.pm');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文