File Coverage

blib/lib/Test/Smoke/App/RepostFromArchive.pm
Criterion Covered Total %
statement 45 73 61.6
branch 6 20 30.0
condition 1 5 20.0
subroutine 9 10 90.0
pod 2 2 100.0
total 63 110 57.2


line stmt bran cond sub pod time code
1             package Test::Smoke::App::RepostFromArchive;
2 1     1   131632 use warnings;
  1         10  
  1         33  
3 1     1   13 use strict;
  1         2  
  1         38  
4              
5             our $VERSION = '0.002';
6              
7 1     1   6 use base 'Test::Smoke::App::Base';
  1         3  
  1         491  
8              
9 1     1   472 use File::Spec::Functions qw(catfile curdir);
  1         929  
  1         61  
10 1     1   422 use Test::Smoke::Poster;
  1         6  
  1         45  
11 1     1   6 use POSIX qw(strftime);
  1         2  
  1         11  
12              
13             =head1 NAME
14              
15             Test::Smoke::App::RepostFromArchive - The tsrepostjsn.pl application.
16              
17             =head1 SYNOPSIS
18              
19             Interactive:
20              
21             $ tsrepostjsn.pl -c smokecurrent
22             Show the last 10 reports:
23             1 jsn7a29e8d2c80588346422b4b6b936e6f8b56a3af4.jsn (2022-09-04 05:16:49 +0200)
24             2 jsn69bc7167fa24b1e8d3f810ce465d84bdddf413f6.jsn (2022-09-03 05:15:11 +0200)
25             3 jsncd55125d69f5f698ef7cbdd650cda7d2e59fc388.jsn (2022-09-02 05:14:42 +0200)
26             4 jsn0c33882a943825845dde164b60900bf224b131cc.jsn (2022-09-01 05:15:05 +0200)
27             5 jsnb885e42dc2078e29df142cfcefaa86725199d15b.jsn (2022-08-31 05:15:16 +0200)
28             6 jsne772cf349a3609ba583f441d10e1e92c5e338377.jsn (2022-08-30 05:15:01 +0200)
29             7 jsnf603e191e0bea582034a16f05909a56bcc05a564.jsn (2022-08-29 05:15:14 +0200)
30             8 jsn51634b463845a03d4f22b9d23f6c5e2fb98af9c8.jsn (2022-08-28 05:15:47 +0200)
31             9 jsn305697f3995f7ddfba2e200c5deb2e274e1136c0.jsn (2022-08-27 05:15:34 +0200)
32             10 jsn18fa8a6f818cbe2838cfe9b1bfa0c5d9c311930c.jsn (2022-08-26 05:15:41 +0200)
33             Type the numbers (with white space inbetween): 1 2 3
34              
35             Or direct:
36              
37             $ tsrepostjsn.pl -c smokecurrent --sha 7a29e8d2c8058 --sha 69bc7167fa2 --sha cd55125d69f5f698ef7cbdd6
38              
39             =head1 OPTIONS
40              
41             --max-reports Number of reports to choose from (10)
42              
43             --sha Commit SHA for the smoke (repeat for more reports)
44              
45             --jsonreport The actual json-file to re-post
46              
47             Override the config:
48              
49             --adir Archive directory
50             --smokedb_url Where to POST to for CoreSmokeDB
51             --poster Use another poster
52              
53             =head1 DESCRIPTION
54              
55             =head2 Test::Smoke::App::RepostFromArchive->new()
56              
57             Creates a new attribute C of class L.
58              
59             =cut
60              
61             sub new {
62 3     3 1 8 my $class = shift;
63 3         17 my $self = $class->SUPER::new(@_);
64              
65 3         18 $self->{_poster} = Test::Smoke::Poster->new(
66             $self->option('poster') => $self->options,
67              
68             # We will need to fake 'ddir' in order to get the reports from the
69             # archive
70             ddir => $self->option('adir'),
71             v => $self->option('verbose'),
72             );
73              
74 3         12 return $self;
75             }
76              
77             =head2 $reposter->run()
78              
79             Get a list of C<< jsn.jsn >> filenames from the C archive
80             directory an try to send them to the report server at C again.
81              
82             =cut
83              
84             sub run {
85 3     3 1 4315 my $self = shift;
86              
87 3         11 my @to_post = $self->pick_reports();
88 3         22 for my $report (@to_post) {
89 13         39 $self->log_info("Reposting '%s' to %s\n", $report, $self->option('smokedb_url'));
90 13         67 $self->poster->jsnfile($report);
91 13         50 my $id = $self->poster->post($report);
92 13   50     61 $self->log_info("Report posted with id: %s", $id || "");
93             }
94             }
95              
96             =head2 $reposter->pick_reports()
97              
98             First checks for reports passed on the command line with C<< --sha
99             >>. If none were passed it fetches the latest reports C<--max-reports> from the
100             archive directory C and lets you pick 1 or more.
101              
102             =head3 Returns
103              
104             A list of filenames representing the json files from the archive.
105              
106             =cut
107              
108             sub pick_reports {
109 3     3   1092 my $self = shift;
110              
111 3 100       12 if (my $jsonreport = $self->option('jsonreport')) {
112 2 50       38 die("Cannot find '$jsonreport'") unless -f $jsonreport;
113 2 50       19 if ($jsonreport =~ m{^ / }x) {
114 2         15 $self->poster->ddir('');
115             }
116             else {
117 0         0 $self->poster->ddir(curdir());
118             }
119 2         9 return ($jsonreport);
120             }
121              
122 1         10 my $entries = $self->fetch_jsn_from_archive;
123 1         44 my $max_entries = scalar(keys %$entries);
124              
125 1         6 my $commits = $self->option('commit_sha');
126 1 50       13 if (@$commits) {
127             # tranlate (partial) sha into filenames
128 1         2 my @reports;
129 1         4 for my $commit (@$commits) {
130 5         16 my @candidates = grep { $_ =~ m{^ jsn $commit [0-9a-f]* \.jsn $}x } keys %$entries;
  55         267  
131 5 50       20 push @reports, $candidates[0] if @candidates;
132             }
133 1         12 return @reports;
134             }
135              
136 0           my $max = $self->option('max_reports');
137 0 0         $max > $max_entries and $max = $max_entries;
138              
139             my @short_list = (
140             sort {
141 0           $entries->{$b}{mtime} <=> $entries->{$a}{mtime}
142 0           } keys %$entries
143             )[0..$max - 1];
144              
145 0           $max = @short_list;
146 0           my @reports;
147 0           printf "Show the last %u reports:\n", $max;
148 0           for my $cnt (1..$max) {
149             printf
150             "%3u %-35s (%s)\n",
151             $cnt, $short_list[$cnt - 1],
152             strftime(
153             "%Y-%m-%d %H:%M:%S %z",
154             localtime($entries->{ $short_list[$cnt - 1] }{mtime})
155 0           );
156             }
157 0           print "Type the numbers (with white space inbetween): ";
158 0           chomp(my $input = );
159 0 0 0       my @picks = grep { m{^ [0-9]+ $}x && $_ >= 1 && $_ <= $max } split(" ", $input);
  0            
160 0           for my $pick (@picks) {
161 0           push @reports, $short_list[$pick - 1];
162             }
163 0           return @reports;
164             }
165              
166             sub fetch_jsn_from_archive {
167 0     0     my $self = shift;
168              
169 0           my %entries;
170 0           my $adir = $self->option('adir');
171 0 0         opendir(my $dh, $adir) or die "Cannot opendir($adir): $!";
172 0           while (my $entry = readdir($dh)) {
173 0           my $fn = catfile($adir, $entry);
174 0 0         next unless -f $fn;
175 0 0         next unless $entry =~ m{^ jsn [0-9a-f]+ \.jsn $}x;
176 0           $entries{$entry} = {
177             mtime => (stat $fn)[9],
178             fullname => $fn,
179             };
180             }
181 0           closedir($dh);
182              
183 0           return \%entries;
184             }
185              
186             1;
187              
188             =head1 COPYRIGHT
189              
190             E 2002-2022, Abe Timmerman All rights reserved.
191              
192             With contributions from Jarkko Hietaniemi, Merijn Brand, Campo
193             Weijerman, Alan Burlison, Allen Smith, Alain Barbet, Dominic Dunlop,
194             Rich Rauenzahn, David Cantrell.
195              
196             This library is free software; you can redistribute it and/or modify
197             it under the same terms as Perl itself.
198              
199             See:
200              
201             =over 4
202              
203             =item * L
204              
205             =item * L
206              
207             =back
208              
209             This program is distributed in the hope that it will be useful,
210             but WITHOUT ANY WARRANTY; without even the implied warranty of
211             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
212              
213             =cut
214