File Coverage

tools/update-deps
Criterion Covered Total %
statement 127 134 94.7
total 127 134 94.7


line stmt code
1   #!/usr/bin/env perl
2   # Copyright 2020 SUSE LLC
3   # SPDX-License-Identifier: MIT
4 1 use strict;
  1  
  1  
5 1 use warnings;
  1  
  1  
6 1 use 5.010;
  1  
7    
8 1 use YAML::PP;
  1  
  1  
9 1 use Data::Dumper;
  1  
  1  
10 1 use Mojo::File qw(path);
  1  
  1  
11 1 use Getopt::Long;
  1  
  1  
12 1 use FindBin qw($Bin);
  1  
  1  
13    
14 1 GetOptions(
15   "help|h" => \my $help,
16   "specfile=s" => \my $specfile,
17   "dockerfile=s" => \my $dockerfile,
18   );
19    
20 1 usage(0) if $help;
21 1 usage(1) unless $specfile;
22    
23 1 my $scriptname = path(__FILE__)->to_rel("$Bin/..");
24 1 my $yamlfile = "dependencies.yaml";
25 1 my $file = "$Bin/../$yamlfile";
26 1 my $cpanfile = "$Bin/../cpanfile";
27    
28 1 my $data = YAML::PP->new->load_file($file);
29 1 my $spec = path($specfile)->slurp;
30    
31 1 my $spectargets = $data->{targets}->{spec};
32 1 my $cpantargets = $data->{targets}->{cpanfile};
33 1 my $dockertargets = $data->{targets}->{docker};
34 1 my $cpantarget_mapping = $data->{targets}->{'cpanfile-targets'};
35    
36 1 my ($modules_by_target) = get_modules($data, $cpantargets, $cpantarget_mapping);
37    
38 1 update_spec();
39 1 update_cpanfile($modules_by_target);
40 1 update_dockerfile($dockerfile) if $dockerfile;
41    
42   my ($dockerfile) = @_;
43 1 my $docker = path($dockerfile)->slurp;
44 1 my @perl;
45 1 my @pkg;
46   for my $target (@$dockertargets) {
47 1 my $name = $target . '_requires';
48 11 my $deps = $data->{$name};
49 11 for my $key (sort keys %$deps) {
50 11 next if $key =~ m/^%/;
51 130 my $line = ' ';
52 121  
53   if ($key =~ m/\(/) {
54 121 $key = "'$key'";
55 97 }
56   $line .= $key;
57 121 $line .= " \\\n";
58 121 if ($key =~ m/perl\(/) {
59 121 push @perl, $line;
60 92 }
61   else {
62   push @pkg, $line;
63 29 }
64   }
65   }
66   @perl = sort @perl;
67 1 @pkg = sort @pkg;
68 1 my %seen;
69 1 my $dep = join '', grep { not $seen{$_}++ } @pkg, @perl;
70 1 my $begin = '# AUTODEPS START';
  121  
71 1 my $end = '# AUTODEPS END';
72 1 my $run = <<"EOM";
73 1 # This part is autogenerated by $scriptname from $yamlfile
74   # hadolint ignore=DL3034,DL3037
75   RUN zypper in -y -C \\
76   $dep && zypper clean
77   EOM
78   $docker =~ s/($begin\n)(.*)($end\n)/$1$run$3/s;
79 1 path($dockerfile)->spurt($docker);
80 1 say "Updated $dockerfile";
81 1 }
82    
83    
84   for my $target (@$spectargets) {
85   my $name = $target . '_requires';
86 1 my $deps = $data->{$name};
87 10 my $prefix = "%define $name";
88 10 my $specline = $prefix;
89 10 for my $key (sort keys %$deps) {
90 10 my $version = $deps->{$key};
91 10 if (ref $version) {
92 124 $version = $version->{rpm};
93 124 }
94 0 $specline .= " $key";
95   if ($key eq 'perl(Perl::Tidy)') {
96 124 undef $version;
97 124 }
98 1 if ($version) {
99   $specline .= " $version";
100 124 }
101 5 }
102   my $comment = "# The following line is generated from $yamlfile";
103   if ($spec =~ s/^# .*generated.*\n^$prefix.*/$comment\n$specline/m) {
104 10 next;
105 10 }
106 10 # No comment above the line yet
107   unless ($spec =~ s/^$prefix.*/$comment\n$specline/m) {
108   die "/^$prefix/ not found in $specfile";
109 0 }
110 0 }
111    
112   path($specfile)->spurt($spec);
113   say "Updated $specfile";
114 1 }
115 1  
116   my ($data, $cpantargets, $cpantarget_mapping) = @_;
117    
118   my %modules_by_target;
119 1 for my $target (@$cpantargets) {
120   my $name = $target . '_requires';
121 1 my $deps = $data->{$name};
122 1 for my $key (keys %$deps) {
123 7 my $module = $key;
124 7 next unless $module =~ s/^perl\((.*)\)$/$1/;
125 7 my $version = $deps->{$key};
126 114 if (ref $version) {
127 114 $version = $version->{perl};
128 93 }
129 93 my $cpantarget = $cpantarget_mapping->{$target} || 'main';
130 0 $modules_by_target{$cpantarget}->{$module} = $version;
131   }
132 93 }
133 93 return \%modules_by_target;
134   }
135    
136 1 # requires 'Archive::Extract', '> 0.7';
137   my ($hash, $module) = @_;
138   my $version = $hash->{$module};
139   my $line = "requires '$module'";
140   $line .= qq{, '$version'} if $version;
141 93 $line .= ";\n";
142 93 return $line;
143 93 }
144 93  
145 93 my ($modules_by_target) = @_;
146 93 my $cpan = <<"EOM";
147   ##################################################
148   # WARNING
149   # This file is autogenerated by $scriptname
150 1 # from $yamlfile
151 1 ##################################################
152    
153   EOM
154   for my $module (sort keys %{$modules_by_target->{main}}) {
155   $cpan .= _requires_line($modules_by_target->{main}, $module);
156   }
157   my $test_requires = '';
158   for my $module (sort keys %{$modules_by_target->{test}}) {
159 1 $test_requires .= ' ' . _requires_line($modules_by_target->{test}, $module);
  1  
160 64 }
161   my $cover_requires = '';
162 1 for my $module (sort keys %{$modules_by_target->{cover}}) {
163 1 $cover_requires .= ' ' . _requires_line($modules_by_target->{cover}, $module);
  1  
164 22 }
165   my $devel_requires = '';
166 1 for my $module (sort keys %{$modules_by_target->{devel}}) {
167 1 $devel_requires .= ' ' . _requires_line($modules_by_target->{devel}, $module);
  1  
168 2 }
169   $cpan .= <<"EOM";
170 1  
171 1 on 'test' => sub {
  1  
172 5 $test_requires
173   };
174 1  
175   on 'devel' => sub {
176   $devel_requires
177   };
178    
179   feature 'coverage', 'coverage for CI' => sub {
180   $cover_requires
181   };
182   EOM
183    
184   path($cpanfile)->spurt($cpan);
185   say "Updated $cpanfile";
186   }
187    
188   my ($exit) = @_;
189 1 print <<"EOM";
190 1 Usage:
191   # update cpanfile and dist/rpm/os-autoinst.spec
192   $0
193   $0 --specfile dist/rpm/os-autoinst.spec
194 0 $0 --dockerfile docker/ci/Dockerfile
195 0 EOM
196   exit $exit;
197   }