Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

upconversion working from 1.0 to 2

  • Loading branch information...
commit 70ce9e1813ccf86a73af3c16d19bbebb1317a96b 1 parent 8d8adec
David Golden dagolden authored

Showing 2 changed files with 168 additions and 28 deletions. Show diff stats Hide diff stats

  1. +166 23 lib/CPAN/Meta/Converter.pm
  2. +2 5 t/converter.t
189 lib/CPAN/Meta/Converter.pm
@@ -24,6 +24,7 @@ optional fields.)
24 24 =cut
25 25
26 26 use Carp qw(carp confess);
  27 +use CPAN::Meta::Validator;
27 28
28 29 my %known_specs = (
29 30 '2' => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
@@ -50,6 +51,10 @@ sub _keep { $_[0] }
50 51
51 52 sub _keep_or_one { defined($_[0]) ? $_[0] : 1 }
52 53
  54 +sub _keep_or_zero { defined($_[0]) ? $_[0] : 0 }
  55 +
  56 +sub _keep_or_unknown { defined($_[0]) ? $_[0] : "unknown" }
  57 +
53 58 sub _generated_by { __PACKAGE__ . " version " . (__PACKAGE__->VERSION || "<dev>") }
54 59
55 60 sub _listify { ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]] }
@@ -82,6 +87,18 @@ sub _license_2 {
82 87 return $element;
83 88 }
84 89
  90 +sub _no_index_1_2 {
  91 + my (undef, undef, $meta) = @_;
  92 + return $meta->{private};
  93 +}
  94 +
  95 +sub _no_index_directory {
  96 + my ($element) = @_;
  97 + return unless $element;
  98 + return $element unless exists $element->{dir};
  99 + $element->{directory} = delete $element->{dir};
  100 + return $element;
  101 +}
85 102
86 103 sub _prereqs {
87 104 my (undef, undef, $meta) = @_;
@@ -111,6 +128,15 @@ sub _optional_features_2 {
111 128 return $features;
112 129 }
113 130
  131 +sub _optional_features_1_4 {
  132 + my ($element) = @_;
  133 + return unless $element;
  134 + for my $drop ( qw/requires_packages requires_os excluded_os/ ) {
  135 + delete $element->{$drop};
  136 + }
  137 + return $element;
  138 +}
  139 +
114 140 # resources => {
115 141 # license => [ 'http://dev.perl.org/licenses/' ],
116 142 # homepage => 'http://sourceforge.net/projects/module-build',
@@ -124,7 +150,7 @@ sub _optional_features_2 {
124 150 # type => 'git',
125 151 # },
126 152
127   -my $resource_conversion_spec = {
  153 +my $resource2_spec = {
128 154 license => \&_listify,
129 155 homepage => \&_keep,
130 156 bugtracker => sub { return $_[0] ? { web => $_[0] } : undef },
@@ -133,9 +159,15 @@ my $resource_conversion_spec = {
133 159 };
134 160
135 161 sub _resources_2 {
136   - my (undef, undef, $meta) = @_;
  162 + my (undef, undef, $meta, $version) = @_;
137 163 return undef unless exists $meta->{resources};
138   - return _convert($meta->{resources}, $resource_conversion_spec);
  164 + return _convert($meta->{resources}, $resource2_spec);
  165 +}
  166 +
  167 +sub _resources_1_2 {
  168 + my (undef, undef, $meta) = @_;
  169 + return undef unless exists $meta->{license_url};
  170 + return { license => $meta->{license_url} };
139 171 }
140 172
141 173 sub _release_status {
@@ -175,55 +207,157 @@ sub _convert {
175 207 # special ":custom" field is used for keys not recognized in spec
176 208 my %up_convert = (
177 209 '2-from-1.4' => {
178   - # MANDATORY
  210 + # PRIOR MANDATORY
179 211 'abstract' => \&_keep,
180 212 'author' => \&_listify,
181   - 'dynamic_config' => \&_keep_or_one,
182 213 'generated_by' => \&_generated_by,
183 214 'license' => \&_license_2,
184 215 'meta-spec' => \&_change_meta_spec,
185 216 'name' => \&_keep,
186   - 'release_status' => \&_release_status,
187 217 'version' => \&_keep,
188   - # OPTIONAL - from pre-existing
  218 + # CHANGED TO MANDATORY
  219 + 'dynamic_config' => \&_keep_or_one,
  220 + # ADDED MANDATORY
  221 + 'release_status' => \&_release_status,
  222 + # PRIOR OPTIONAL
189 223 'keywords' => \&_keep,
190 224 'no_index' => \&_keep,
191 225 'optional_features' => \&_optional_features_2,
192   - 'prereqs' => \&_prereqs,
193 226 'provides' => \&_keep,
194 227 'resources' => \&_resources_2,
  228 + # ADDED OPTIONAL
  229 + 'description' => \&_keep,
  230 + 'prereqs' => \&_prereqs,
195 231
196 232 # drop these deprecated fields, but only after we convert
197 233 ':drop' => [ qw(
198   - requires build_requires recommends conflicts configure_requires
199   - private distribution_type
  234 + build_requires
  235 + configure_requires
  236 + conflicts
  237 + distribution_type
  238 + license_url
  239 + private
  240 + recommends
  241 + requires
200 242 ) ],
201 243
202 244 # other random keys need x_ prefixing
203 245 ':custom' => \&_prefix_custom,
204 246 },
205 247 '1.4-from-1.3' => {
  248 + # PRIOR MANDATORY
  249 + 'abstract' => \&_keep,
  250 + 'author' => \&_keep,
  251 + 'generated_by' => \&_generated_by,
  252 + 'license' => \&_keep,
206 253 'meta-spec' => \&_change_meta_spec,
207 254 'name' => \&_keep,
208 255 'version' => \&_keep,
  256 + # PRIOR OPTIONAL
  257 + 'build_requires' => \&_keep,
  258 + 'conflicts' => \&_keep,
  259 + 'distribution_type' => \&_keep,
  260 + 'dynamic_config' => \&_keep_or_one,
  261 + 'keywords' => \&_keep,
  262 + 'no_index' => \&_keep,
  263 + 'optional_features' => \&_optional_features_1_4,
  264 + 'provides' => \&_keep,
  265 + 'recommends' => \&_keep,
  266 + 'requires' => \&_keep,
  267 + 'resources' => \&_keep,
  268 + # ADDED OPTIONAL
  269 + 'configure_requires' => \&_keep,
  270 +
  271 + # drop these deprecated fields, but only after we convert
  272 + ':drop' => [ qw(
  273 + license_url
  274 + private
  275 + )],
  276 +
  277 + # other random keys are OK if already valid
  278 + ':custom' => \&_keep
  279 + },
  280 + '1.3-from-1.2' => {
  281 + # PRIOR MANDATORY
209 282 'abstract' => \&_keep,
210 283 'author' => \&_keep,
211   - 'license' => \&_keep,
212 284 'generated_by' => \&_generated_by,
213   - 'dynamic_config' => \&_keep_or_one,
214   -# configure_requires -- didn't exist prior to 1.4
  285 + 'license' => \&_keep,
  286 + 'meta-spec' => \&_change_meta_spec,
  287 + 'name' => \&_keep,
  288 + 'version' => \&_keep,
  289 + # PRIOR OPTIONAL
215 290 'build_requires' => \&_keep,
216   - 'requires' => \&_keep,
217   - 'recommends' => \&_keep,
218 291 'conflicts' => \&_keep,
219   - 'optional_features' => \&_optional_features_1,
  292 + 'distribution_type' => \&_keep,
  293 + 'dynamic_config' => \&_keep_or_one,
  294 + 'keywords' => \&_keep,
  295 + 'no_index' => \&_no_index_directory,
  296 + 'optional_features' => \&_keep,
220 297 'provides' => \&_keep,
221   - 'no_index' => \&_keep,
  298 + 'recommends' => \&_keep,
  299 + 'requires' => \&_keep,
  300 + 'resources' => \&_keep,
  301 +
  302 + # drop these deprecated fields, but only after we convert
  303 + ':drop' => [ qw(
  304 + license_url
  305 + private
  306 + )],
  307 +
  308 + # other random keys are OK if already valid
  309 + ':custom' => \&_keep
  310 + },
  311 + '1.2-from-1.1' => {
  312 + # PRIOR MANDATORY
  313 + 'version' => \&_keep,
  314 + # CHANGED TO MANDATORY
  315 + 'license' => \&_keep,
  316 + 'name' => \&_keep,
  317 + 'generated_by' => \&_generated_by,
  318 + # ADDED MANDATORY
  319 + 'abstract' => \&_keep_or_unknown,
  320 + 'author' => sub { _listify( _keep_or_unknown( @_ ) ) },
  321 + 'meta-spec' => \&_change_meta_spec,
  322 + # PRIOR OPTIONAL
  323 + 'build_requires' => \&_keep,
  324 + 'conflicts' => \&_keep,
  325 + 'distribution_type' => \&_keep,
  326 + 'dynamic_config' => \&_keep_or_one,
  327 + 'recommends' => \&_keep,
  328 + 'requires' => \&_keep,
  329 + # ADDED OPTIONAL
222 330 'keywords' => \&_keep,
223   - 'resources' => \&_resources_1,
  331 + 'no_index' => \&_no_index_1_2,
  332 + 'optional_features' => \&_keep,
  333 + 'provides' => \&_keep,
  334 + 'resources' => \&_resources_1_2,
224 335
225 336 # drop these deprecated fields, but only after we convert
226   - ':drop' => [ qw/ private / ],
  337 + ':drop' => [ qw(
  338 + license_url
  339 + private
  340 + )],
  341 +
  342 + # other random keys are OK if already valid
  343 + ':custom' => \&_keep
  344 + },
  345 + '1.1-from-1.0' => {
  346 + # CHANGED TO MANDATORY
  347 + 'version' => \&_keep_or_zero,
  348 + # PRIOR OPTIONAL
  349 + 'build_requires' => \&_keep,
  350 + 'conflicts' => \&_keep,
  351 + 'distribution_type' => \&_keep,
  352 + 'dynamic_config' => \&_keep_or_one,
  353 + 'generated_by' => \&_generated_by,
  354 + 'license' => \&_keep,
  355 + 'name' => \&_keep,
  356 + 'recommends' => \&_keep,
  357 + 'requires' => \&_keep,
  358 + # ADDED OPTIONAL
  359 + 'license_url' => \&_keep,
  360 + 'private' => \&_keep,
227 361
228 362 # other random keys are OK if already valid
229 363 ':custom' => \&_keep
@@ -288,10 +422,19 @@ sub convert {
288 422 die "downconverting not yet supported";
289 423 }
290 424 else {
291   - my $conversion_spec = $up_convert{"${new_version}-from-${old_version}"};
292   - die "converting from $old_version to $new_version not supported"
293   - unless $conversion_spec;
294   - return _convert( $self->{data}, $conversion_spec, $new_version );
  425 + my @vers = sort { $a <=> $b } keys %known_specs;
  426 + my $converted = { %{$self->{data}} };
  427 + for my $i ( 0 .. $#vers-1 ) {
  428 + next if $vers[$i] < $old_version;
  429 + my $spec_string = "$vers[$i+1]-from-$vers[$i]";
  430 + $converted = _convert( $converted, $up_convert{$spec_string}, $vers[$i+1] );
  431 + my $cmv = CPAN::Meta::Validator->new( $converted );
  432 + unless ( $cmv->is_valid ) {
  433 + my $errs = join("\n", $cmv->errors);
  434 + confess "Failed to upconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
  435 + }
  436 + }
  437 + return $converted;
295 438 }
296 439 }
297 440
7 t/converter.t
@@ -15,18 +15,15 @@ sub _spec_version { return $_[0]->{'meta-spec'}{version} || "1.0" }
15 15
16 16 use Data::Dumper;
17 17
18   -for my $f ( @files ) {
  18 +for my $f ( reverse sort @files ) {
19 19 my $path = File::Spec->catfile('t','data',$f);
20 20 my $original = CPAN::Meta->_load_file( $path );
21 21 ok( $original, "loaded $f" );
22 22 my $original_v = _spec_version($original);
23 23 SKIP: {
24   - skip "upconverting $original_v not supported yet", 2
25   - unless $original_v > 1.3;
26   -
27 24 my $cmc = CPAN::Meta::Converter->new( $original );
28 25 my $converted = $cmc->convert( version => 2 );
29   - is ( _spec_version($converted), 2, "converted $original_v to spec version 2");
  26 + is ( _spec_version($converted), 2, "converted spec version $original_v to spec version 2");
30 27 my $cmv = CPAN::Meta::Validator->new( $converted );
31 28 ok ( $cmv->is_valid, "converted META is valid" )
32 29 or diag( "ERRORS:\n" . join( "\n", $cmv->errors )

0 comments on commit 70ce9e1

Please sign in to comment.
Something went wrong with that request. Please try again.