Script-fu:如何创建641个请求跟踪器工单

我大部分时间都在纽约Perl黑客马拉松(感谢彭博!)中编写Perl 6相关代码。在Will “Coke” Coleda的带领下,我们的一个任务是找到Perl 6测试套件中缺少请求跟踪器(RT)工单号的跳过/待办指令。

一个典型的跳过/待办指令看起来像这样

#?rakudo todo "doesn't work yet due to copying of arrays"

这告诉Rakudo跳过下面的测试块。对于每个跳过/待办指令,都需要创建一个新的RT工单,并将工单号添加到测试文件中相应的跳过指令行,如下所示

#?rakudo todo "doesn't work yet due to copying of arrays RT #99999"

这使得Rakudo团队更容易识别Rakudo中剩余的bug或缺失的功能。

我克隆了Perl 6测试套件,roast,并在完成单个工单的工作流程后,我开始想知道还有多少其他跳过/待办指令缺少RT工单号。为了找出答案,我使用了一些小的grep魔法

$ grep -rlP '#?rakudo.+?(?:skip|todo)(?:(?!RT).{2})+$' ./ | wc -l

这告诉grep在当前目录中递归搜索文件,并对于每个文件,如果Perl风格的正则表达式与文件中的文本匹配,则打印文件名。正则表达式匹配Rakudo中尚未有RT引用的跳过/待办指令。然后,grep的输出被传递到wc以计算文件数量。结果发现有236个文件受到影响,这种方法甚至没有计算文件内部的出现次数。即使为每个文件创建工单、更新文件、提交更改和发布拉取请求需要5分钟,那也是20小时的工作。当需要将这项工作分配给多个人时,事情变得更加复杂。这时,我的蜘蛛感应开始作祟……你能说“自动化”吗?

用机器创建RT工单“像机器一样”

我写了一个快速脚本再次查找所有的跳过/待办指令,但这次我会捕获文件名、行号和描述

use strict;
use warnings;

scan_directory('.');

sub scan_directory
{
  my ($dir) = @_;

  opendir(my $dh, "$dir") or die $!;

  while (readdir $dh)
  {
    my $newpath = "$dir/$_";

    next if $newpath !~ qr/^\.\/S/ || -l $newpath;

    if (-d $newpath && $newpath !~ /\.$/)
    {
      scan_directory($newpath);
    }
    elsif (-f $newpath)
    {
      open my $file, '<', $newpath or die "failed to open $newpath $!\n";
      my $line_num = 1;·
      while (<$file>)
      {
        chomp;
        if (/^#\?rakudo.+?(?:skip|todo)((?:(?!RT).)+)$/)
        {
          my $subject = sprintf "Roast rakudo skip/todo test:%s line:%s reason:%s",
            $newpath, $line_num, $1;

         $subject =~ s/"//g;

          my $response = `rt create -t ticket set subject="$subject" queue=perl6 priority=0`;
          if ($response =~ /([0-9]+)/)
          {
            printf "%s RT#:%s\n", $subject, $1;
          }
          else
          {
            die "Failed to capture ticket # for $subject response: $response";
          }
        }
        $line_num++;
      }
      close $file;
    }
  }
}

这个脚本相当简单:它是一个递归目录扫描器,用于扫描文件中的Rakudo跳过/待办块。该脚本使用以下带有反引号的代码行执行rt命令行程序,在Perl 6队列中创建一个工单,并捕获响应

my $response = `rt create -t ticket set subject="$subject" queue=perl6 priority=0`;

脚本从$response中提取RT工单号,并打印包含文件名、行号、描述和RT工单号的行。我将这些输出保存在一个单独的文件中

.

关于配置RT CLI的简要说明

配置和使用RT命令行客户端很简单,但了解如何操作可能很困难 - 大多数我看到的资料都过时了,RT CPAN命名空间有太多的“烧毁的尸体”,连《Mad Max》也会感到自在。要使用命令行客户端,首先安装RT::Client::CLI

$ cpan RT::Client::CLI

然后登录到RT Perl 网站,转到用户 首选项 并设置CLI密码。最后,在你的主目录中创建文件.rtrc。该文件应包含

server https://rt.perl.org/
user rt_username
passwd rt_cli_password

rt_username替换为RT屏幕顶部显示的名称。对我而言,是我的电子邮件地址。也将rt_cli_password替换为你刚刚设置的CLI密码。或者,你也可以使用以下环境变量而不是配置文件:RTSERVER、RTUSER和RTPASSWD。

这就完成了,RT现在已配置!尝试一些命令。RT Essentials书籍的第4章也很有用。

更新roast

既然我已经有了所需的RT票号,我需要回到roast中的单元测试文件,将它们添加到跳过/待办指令中。我也为这个过程编写了脚本。

use strict;
use warnings;

open my $tickets, '<', './tickets';

while (my $line = <$tickets>)
{
  chomp $line;
  if (my ($filename, $line_num, $reason, $ticket_num) = $line =~ /:(.+?) .+?:(.+?) .+?:(.+?) .+?:(.+?)$/)
  {
    open my $file, '<', $filename or die "failed to open $filename $!\n";
    my $counter = 1;
    my @lines;
    while (my $line = <$file>)
    {
      if ($counter == $line_num)
      {
        chomp $line;
        $line =~ s/('|")\s*$/ RT #$ticket_num$1\n/;
      }
      push @lines, $line;
      $counter++;
    }
    close $file;

    open my $output_file, '>', $filename or die "failed to open $filename $!\n";
    for (@lines)
    {
      print $output_file $_;
    }
    close $output_file;
  }
  else
  {
    die "failed to match $line!\n";
  }
}

这需要几次尝试才能正确完成。一开始我想尝试使用open和一个使用+<的惊人的读写文件句柄,但这似乎比它所值得的麻烦要多。另一个挑战是将RT票号插入到该行的引号字符串内,而不是外面。所以这

#?rakudo todo "doesn't work yet due to copying of arrays"

变成了这样

#?rakudo todo "doesn't work yet due to copying of arrays RT #124652"

这里的挑战在于不同的描述使用不同的分隔符来捕获描述,无论是单引号还是双引号。在脚本中,这一行处理了这个问题

$line =~ s/('|")\s*$/ RT #$ticket_num$1\n/;

这是一个替换正则表达式,它捕获行上最后的引号分隔符,并用RT票号加上捕获的分隔符($1)来替换它。它成功了!

总结

最终,我在roast中的236个测试文件中创建了641个票,大约花费了2小时的工作时间。其中大部分时间花在尝试配置RT命令行客户端上。提出数百个票时需要记住的一件事是电子邮件通知。幸运的是,Robert Spier拦截了邮件发送(感谢Robert!),但如果有可能避免在提出票时创建数百个通知,那就太好了。如果有办法,我很乐意知道如何。

感谢Will “Coke” Coleda、Tobias Leich(FROGGS)和Christian Bartolomäus(usev6)审阅了这个pull request并完成了合并工作。如果您有兴趣支持Perl 6,Rakudo团队有一个页面解释了如何贡献。我还建议您查看Perl 6社区页面

如果您在纽约或北美东北部,我将于6月6日在Miniconf黑客马拉松上,带领一个团队将Perl 5模块转换为Perl 6。希望在那里见到每个人!


这篇文章最初发布在PerlTricks.com

标签

David Farrell

David是一位专业程序员,他经常推文并在博客上写关于代码和编程艺术的博客。

浏览他们的文章

反馈

这篇文章有什么问题吗?请在GitHub上打开一个issue或pull request来帮助我们。