请求协助完善Waiver系统:实现错误文件与waiver.csv的匹配逻辑
需求说明
需要为工作场景构建一套Waiver系统,使用提供的waiver.csv文件。错误信息已输出至input.txt文件中,需将input.txt内的每条错误与waiver.csv按stage、process、block三个维度进行匹配,并生成指定格式的输出。现有一段Perl代码片段,需完善错误文件与waiver.csv的匹配逻辑。
waiver.csv示例
#process,#Block,#Stage name,#Waiver owner,#Justification,#Error msg process1,block1,stage1,Alex,testing,Error: Port 0 does not exist process1,block1,stage1,Alex,testing,Error: Port 1 does not exist process1,block1,stage1,Alex,testing,Error: Port a0 does not exist
错误文件input.txt示例
Stage: stage1 Process: process1 Block: block1 Error: Port 0 does not exist Error: Port 1 does not exist Error: Port a0 does not exist Error: Port a1 does not exist Error: Port b3 does not exist Error: Nothing matched for port_list (SEL-005) Error: Nothing matched for port_list (SEL-005) Error: Port c5 does not exist Error: Nothing matched for port_list (SEL-005) Error: Nothing matched for port_list (SEL-005)
预期输出
WAIVED (3 waiver, 0 errors) - stage1,process1,block1: Error: Port 0 does not exist Error: Port 1 does not exist Error: Port a0 does not exist Waiver Owner: Alex Justification: testing FAILED (No waiver, 4 errors) - stage1,process1,block1: Error: Nothing matched for port_list (SEL-005) Error: Port a1 does not exist Error: Port b3 does not exist Error: Port c5 does not exist
现有Perl代码片段
#!/usr/bin/perl use strict; use warnings; use Text::CSV; # Define the file paths my $input_file = 'input.txt'; my $waiver_file = 'waiver.csv'; # Read the waiver.csv file my @waiver_msgs; my $csv = Text::CSV->new({ binary => 1 }) or die "Cannot use CSV: " . Text::CSV->error_diag(); open(my $waiver_fh, '<', $waiver_file) or die "Cannot open $waiver_file: $!"; while (my $row = $csv->getline($waiver_fh)) { push @waiver_msgs, $row->[5]; # Assuming error messages are in the 6th column (index 5) } close($waiver_fh); # Read the input.txt file open(my $input_fh, '<', $input_file) or die "Cannot open $input_file: $!"; while (my $line = <$input_fh>) { chomp $line; if ($line =~ /^Error: (.+)$/) { my $error_msg = $1; print "$error_msg\n"; if (grep { $_ eq $error_msg } @waiver_msgs) { print "Error message '$error_msg' is waived.\n"; } else { print "Error message '$error_msg' is not waived.\n"; } } } close($input_fh);
完善后的Perl代码
现有代码仅匹配了错误消息,未考虑stage/process/block的维度匹配,以下是修复后的完整代码:
#!/usr/bin/perl use strict; use warnings; use Text::CSV; # Define file paths my $input_file = 'input.txt'; my $waiver_file = 'waiver.csv'; # 构建waiver数据结构:{ "stage|process|block" => { errors => {msg=>1}, owner=>'', justification=>'' } } my %waiver_data; my $csv = Text::CSV->new({ binary => 1 }) or die "Cannot use CSV: " . Text::CSV->error_diag(); open(my $waiver_fh, '<', $waiver_file) or die "Cannot open $waiver_file: $!"; # 跳过表头 my $header = $csv->getline($waiver_fh); while (my $row = $csv->getline($waiver_fh)) { my ($process, $block, $stage, $owner, $justification, $error_msg) = @$row; my $key = "$stage|$process|$block"; # 初始化分组数据 unless (exists $waiver_data{$key}) { $waiver_data{$key} = { errors => {}, owner => $owner, justification => $justification }; } # 标记该错误已豁免 $waiver_data{$key}{errors}{$error_msg} = 1; } close($waiver_fh); # 读取input.txt,提取上下文和错误信息 my ($current_stage, $current_process, $current_block); my @current_errors; open(my $input_fh, '<', $input_file) or die "Cannot open $input_file: $!"; while (my $line = <$input_fh>) { chomp $line; next if $line =~ /^\s*$/; # 跳过空行 if ($line =~ /^Stage: (.+)$/) { $current_stage = $1; } elsif ($line =~ /^Process: (.+)$/) { $current_process = $1; } elsif ($line =~ /^Block: (.+)$/) { $current_block = $1; } elsif ($line =~ /^Error: .+$/) { push @current_errors, $line; } } close($input_fh); # 生成输出 my $context_key = "$current_stage|$current_process|$current_block"; my $context_label = "$current_stage,$current_process,$current_block"; # 处理豁免的错误 my @waived_errors; my @failed_errors; if (exists $waiver_data{$context_key}) { my $waiver = $waiver_data{$context_key}; foreach my $err (@current_errors) { if (exists $waiver->{errors}{$err}) { push @waived_errors, $err; } else { push @failed_errors, $err; } } } else { @failed_errors = @current_errors; } # 去重失败的错误(因为示例中有重复的SEL-005错误) my %unique_failed = map { $_ => 1 } @failed_errors; @failed_errors = sort keys %unique_failed; # 输出WAIVED部分 if (@waived_errors) { my $waiver_count = scalar @waived_errors; print "WAIVED ($waiver_count waiver, 0 errors) - $context_label:\n"; foreach my $err (@waived_errors) { print " $err\n"; } if (exists $waiver_data{$context_key}) { print " Waiver Owner: $waiver_data{$context_key}{owner}\n"; print " Justification: $waiver_data{$context_key}{justification}\n"; } print "\n"; } # 输出FAILED部分 if (@failed_errors) { my $error_count = scalar @failed_errors; my $waiver_note = @waived_errors ? "No new waiver" : "No waiver"; print "FAILED ($waiver_note, $error_count errors) - $context_label:\n"; foreach my $err (@failed_errors) { print " $err\n"; } }
代码说明
- 数据结构优化:将waiver数据按
stage|process|block的复合键分组,每个分组存储豁免的错误集合、负责人和理由,确保维度匹配准确。 - 上下文提取:读取input.txt时先提取当前的stage、process、block信息,再收集所有错误。
- 错误匹配:根据当前上下文找到对应的豁免规则,将错误分为豁免和未豁免两类。
- 去重处理:对未豁免的错误进行去重,符合预期输出的格式。
- 格式输出:严格按照预期的格式输出结果,包含豁免数量、错误数量、上下文标签、错误列表及豁免信息。
内容的提问来源于stack exchange,提问作者user22081427
相关产品推荐
相关产品推荐

