File Coverage

blib/lib/App/Toolforge/MixNMatch.pm
Criterion Covered Total %
statement 60 124 48.3
branch 1 26 3.8
condition 2 15 13.3
subroutine 15 21 71.4
pod 2 2 100.0
total 80 188 42.5


line stmt bran cond sub pod time code
1             package App::Toolforge::MixNMatch;
2              
3 4     4   114834 use strict;
  4         8  
  4         134  
4 4     4   15 use warnings;
  4         7  
  4         207  
5              
6 4     4   2375 use Error::Pure qw(err);
  4         48538  
  4         95  
7 4     4   2568 use Getopt::Std;
  4         8855  
  4         341  
8 4     4   3773 use IO::Barf qw(barf);
  4         2890  
  4         76  
9 4     4   2913 use JSON::XS;
  4         32073  
  4         283  
10 4     4   1868 use LWP::Simple qw(get);
  4         351665  
  4         52  
11 4     4   3125 use Perl6::Slurp qw(slurp);
  4         8398  
  4         26  
12 4     4   195 use Readonly;
  4         13  
  4         232  
13 4     4   2116 use Toolforge::MixNMatch::Diff;
  4         61313  
  4         163  
14 4     4   2126 use Toolforge::MixNMatch::Print::Catalog;
  4         21112  
  4         201  
15 4     4   2125 use Toolforge::MixNMatch::Struct::Catalog;
  4         13797  
  4         270  
16 4     4   1922 use Unicode::UTF8 qw(encode_utf8);
  4         2951  
  4         5894  
17              
18             # Constants
19             Readonly::Scalar our $URI_BASE => 'https://mix-n-match.toolforge.org/';
20             Readonly::Scalar our $URI_CATALOG_DETAIL => $URI_BASE.'api.php?query=catalog_details&catalog=%s';
21              
22             our $VERSION = 0.06;
23              
24             # Constructor.
25             sub new {
26 2     2 1 784228 my ($class, @params) = @_;
27              
28             # Create object.
29 2         8 my $self = bless {}, $class;
30              
31             # Object.
32 2         12 return $self;
33             }
34              
35             sub _catalog_json_file_to_obj {
36 0     0   0 my $json_file = shift;
37              
38 0         0 my $json = slurp($json_file);
39 0         0 my $struct_hr = decode_json($json);
40 0         0 my $obj = Toolforge::MixNMatch::Struct::Catalog::struct2obj($struct_hr->{'data'});
41              
42 0         0 return $obj;
43             }
44              
45             sub _command_diff {
46 0     0   0 my ($json_file1, $json_file2, $print_options) = @_;
47              
48 0 0 0     0 if (! defined $json_file1 || ! -r $json_file1) {
49 0         0 return (1, "Doesn't exist JSON file #1 for diff.");
50             }
51 0 0 0     0 if (! defined $json_file2 || ! -r $json_file2) {
52 0         0 return (1, "Doesn't exist JSON file #2 for diff.");
53             }
54              
55 0         0 my $opts_hr = _process_print_options($print_options);
56              
57 0         0 my $obj1 = _catalog_json_file_to_obj($json_file1);
58 0         0 my $obj2 = _catalog_json_file_to_obj($json_file2);
59              
60 0         0 my $diff = Toolforge::MixNMatch::Diff::diff($obj1, $obj2);
61              
62 0         0 my $ret = Toolforge::MixNMatch::Print::Catalog::print($diff, $opts_hr);
63 0         0 print encode_utf8($ret)."\n";
64              
65 0         0 return (0, undef);
66             }
67              
68             sub _command_download {
69 0     0   0 my ($catalog_id, $output_file) = @_;
70              
71 0 0 0     0 if (! defined $catalog_id || $catalog_id !~ m/^\d+$/ms) {
72 0         0 return (1, 'Missing or bad catalog ID.');
73             }
74 0 0       0 if (! defined $output_file) {
75 0         0 $output_file = $catalog_id.'.json';
76             }
77              
78 0         0 my $json = _download_catalog_detail($catalog_id);
79 0         0 barf($output_file, $json);
80              
81 0         0 print "Catalog with '$catalog_id' ID was saved to '$output_file'.\n";
82              
83 0         0 return (0, undef);
84             }
85              
86             sub _command_print {
87 0     0   0 my ($json_file_or_catalog_id, $print_options) = @_;
88              
89 0         0 my $json;
90 0 0       0 if (-r $json_file_or_catalog_id) {
    0          
91 0         0 $json = slurp($json_file_or_catalog_id);
92             } elsif ($json_file_or_catalog_id =~ m/^\d+$/ms) {
93 0         0 $json = _download_catalog_detail($json_file_or_catalog_id);
94             } else {
95 0         0 return (1, "Doesn't exist JSON file or catalog ID for print.");
96             }
97              
98 0         0 my $opts_hr = _process_print_options($print_options);
99              
100 0         0 my $struct_hr = decode_json($json);
101 0         0 my $obj = Toolforge::MixNMatch::Struct::Catalog::struct2obj($struct_hr->{'data'});
102 0         0 my $ret = Toolforge::MixNMatch::Print::Catalog::print($obj, $opts_hr);
103 0         0 print encode_utf8($ret)."\n";
104              
105 0         0 return (0, undef);
106             }
107              
108             sub _download_catalog_detail {
109 0     0   0 my $catalog_id = shift;
110              
111 0         0 my $uri = sprintf $URI_CATALOG_DETAIL, $catalog_id;
112 0         0 my $json = get($uri);
113 0 0       0 if (! defined $json) {
114 0         0 err "Cannot download '$uri'.";
115             }
116              
117 0         0 return $json;
118             }
119              
120             sub _process_print_options {
121 0     0   0 my $print_options = shift;
122              
123 0 0       0 if (! defined $print_options) {
124 0         0 return;
125             }
126              
127 0         0 my $opts_hr = {};
128 0         0 foreach my $print_option (split m/,/, $print_options) {
129 0         0 $opts_hr->{$print_option} = 1;
130             }
131              
132 0         0 return $opts_hr;
133             }
134              
135             # Run script.
136             sub run {
137 1     1 1 2 my $self = shift;
138              
139             # Process arguments.
140 1         9 $self->{'_opts'} = {
141             'h' => 0,
142             };
143 1 50 33     17 if (! getopts('h', $self->{'_opts'}) || $self->{'_opts'}->{'h'}
      33        
144             || @ARGV < 1) {
145              
146 1         134 print STDERR "Usage: $0 [-h] [--version] [command] [command_args ..]\n";
147 1         30 print STDERR "\t-h\t\tPrint help.\n";
148 1         14 print STDERR "\t--version\tPrint version.\n";
149 1         12 print STDERR "\tcommand\t\tCommand (diff, download, print).\n\n";
150 1         13 print STDERR "\tcommand 'diff' arguments:\n";
151 1         12 print STDERR "\t\tjson_file1 - JSON file #1\n";
152 1         12 print STDERR "\t\tjson_file2 - JSON file #2\n";
153 1         12 print STDERR "\t\t[print_options] - Print options (type, count, year_months, users)\n";
154 1         13 print STDERR "\tcommand 'download' arguments:\n";
155 1         11 print STDERR "\t\tcatalog_id - Catalog ID\n";
156 1         12 print STDERR "\t\t[output_file] - Output file (default is catalog_id.json)\n";
157 1         12 print STDERR "\tcommand 'print' arguments:\n";
158 1         11 print STDERR "\t\tjson_file or catalog_id - Catalog ID or JSON file\n";
159 1         11 print STDERR "\t\t[print_options] - Print options (type, count, year_months, users)\n";
160 1         5 return 1;
161             }
162 0           my $command = shift @ARGV;
163 0           my @command_args = @ARGV;
164              
165 0           my ($return, $error);
166 0 0         if ($command eq 'diff') {
    0          
    0          
167 0           ($return, $error) = _command_diff(@command_args);
168             } elsif ($command eq 'download') {
169 0           ($return, $error) = _command_download(@command_args);
170             } elsif ($command eq 'print') {
171 0           ($return, $error) = _command_print(@command_args);
172             } else {
173 0           print STDERR "Command '$command' doesn't supported.\n";
174 0           return 1;
175             }
176 0 0         if ($return == 1) {
177 0           print STDERR $error."\n";
178 0           return 1;
179             }
180              
181 0           return 0;
182             }
183              
184             1;
185              
186             __END__
187              
188             =pod
189              
190             =encoding utf8
191              
192             =head1 NAME
193              
194             App::Toolforge::MixNMatch - Perl class for mix-n-match application.
195              
196             =head1 SYNOPSIS
197              
198             use App::Toolforge::MixNMatch;
199              
200             my $obj = App::Toolforge::MixNMatch->new;
201             $obj->run;
202              
203             =head1 METHODS
204              
205             =over 8
206              
207             =item C<new()>
208              
209             Constructor.
210              
211             =item C<run()>
212              
213             Run.
214              
215             =back
216              
217             =head1 ERRORS
218              
219             new():
220             From Class::Utils:
221             Unknown parameter '%s'.
222              
223             =head1 EXAMPLE
224              
225             use strict;
226             use warnings;
227              
228             use App::Toolforge::MixNMatch;
229              
230             # Run.
231             exit App::Toolforge::MixNMatch->new->run;
232              
233             # Output:
234             # Usage: ./examples/ex1.pl [-h] [--version] [command] [command_args ..]
235             # -h Print help.
236             # --version Print version.
237             # command Command (diff, download, print).
238             #
239             # command 'diff' arguments:
240             # json_file1 - JSON file #1
241             # json_file2 - JSON file #2
242             # [print_options] - Print options (type, count, year_months, users)
243             # command 'download' arguments:
244             # catalog_id - Catalog ID
245             # [output_file] - Output file (default is catalog_id.json)
246             # command 'print' arguments:
247             # json_file or catalog_id - Catalog ID or JSON file
248             # [print_options] - Print options (type, count, year_months, users)
249              
250             =head1 DEPENDENCIES
251              
252             L<Error::Pure>,
253             L<Getopt::Std>,
254             L<IO::Barf>,
255             L<JSON::XS>,
256             L<LWP::Simple>,
257             L<Perl6::Slurp>,
258             L<Readonly>,
259             L<Toolforge::MixNMatch::Diff>,
260             L<Toolforge::MixNMatch::Print::Catalog>,
261             L<Toolforge::MixNMatch::Struct::Catalog>,
262             L<Unicode::UTF8>.
263              
264             =head1 REPOSITORY
265              
266             L<https://github.com/tupinek/App-Toolforge-MixNMatch>.
267              
268             =head1 AUTHOR
269              
270             Michal Josef Špaček L<mailto:skim@cpan.org>
271              
272             L<http://skim.cz>
273              
274             =head1 LICENSE AND COPYRIGHT
275              
276             © 2020-2024 Michal Josef Špaček
277              
278             BSD 2-Clause License
279              
280             =head1 VERSION
281              
282             0.06
283              
284             =cut