1package Module::Install::Admin::Metadata;
2
3use strict;
4use YAML::Tiny ();
5use Module::Install::Base;
6
7use vars qw{$VERSION @ISA};
8BEGIN {
9	$VERSION = '1.19';
10	@ISA     = 'Module::Install::Base';
11}
12
13sub read_meta {
14	(YAML::Tiny::LoadFile('META.yml'))[0];
15}
16
17sub meta_generated_by_us {
18	my $meta = $_[0]->read_meta;
19	my $want = ref($_[0]->_top);
20	if ( defined $_[1] ) {
21		$want .= " version $_[1]";
22	}
23	return $meta->{generated_by} =~ /^\Q$want\E/;
24}
25
26sub remove_meta {
27	my $self = shift;
28	my $ver  = $self->_top->VERSION;
29	return unless -f 'META.yml';
30	return unless $self->meta_generated_by_us($ver);
31	unless ( -w 'META.yml' ) {
32		warn "Can't remove META.yml file. Not writable.\n";
33		return;
34	}
35	# warn "Removing auto-generated META.yml\n";
36	unless ( unlink 'META.yml' ) {
37		die "Couldn't unlink META.yml:\n$!";
38	}
39	return;
40}
41
42sub write_meta {
43	my $self = shift;
44	if ( -f "META.yml" ) {
45		return unless $self->meta_generated_by_us();
46	} else {
47		$self->clean_files('META.yml');
48	}
49	print "Writing META.yml\n";
50	Module::Install::_write("META.yml", $self->dump_meta);
51	return;
52}
53
54sub dump_meta {
55	my $self = shift;
56	my $pkg  = ref( $self->_top );
57	my $ver  = $self->_top->VERSION;
58	my $val  = $self->Meta->{values};
59
60	delete $val->{sign};
61
62	# Dependencies MUST be assumed to be dynamic unless indicated
63	# otherwise, otherwise a negligent author who accidentally forgets
64	# to say which will release modules that break on some platforms.
65	unless ( defined $val->{dynamic_config} ) {
66		$val->{dynamic_config} = 1;
67	}
68
69	my $perl_version = delete $val->{perl_version};
70	if ( $perl_version ) {
71		$val->{requires} ||= [];
72		my $requires = $val->{requires};
73
74		# Issue warnings for unversioned core modules that are
75		# already satisfied by the Perl version dependency.
76		require Module::CoreList;
77		my $corelist = $Module::CoreList::version{$perl_version};
78		if ( $corelist ) {
79			my @bad = grep { exists $corelist->{$_} }
80			          map  { $_->[0]   }
81			          grep { ! $_->[1] }
82			          @$requires;
83			foreach ( @bad ) {
84				# print "WARNING: Unversioned dependency on '$_' is pointless when Perl minimum version is $perl_version\n";
85			}
86		}
87
88		# Canonicalize to three-dot version after Perl 5.6
89		if ( $perl_version >= 5.006 ) {
90			$perl_version =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e
91		}
92		unshift @$requires, [ perl => $perl_version ];
93	}
94
95	# Set a default 'unknown' license
96	unless ( $val->{license} ) {
97		warn "No license specified, setting license = 'unknown'\n";
98		$val->{license} = 'unknown';
99	}
100
101	# Most distributions are modules
102	$val->{distribution_type} ||= 'module';
103
104	# Check and derive names
105	if ( $val->{name} =~ /::/ ) {
106		my $name = $val->{name};
107		$name =~ s/::/-/g;
108		die "Error in name(): '$val->{name}' should be '$name'!\n";
109	}
110	if ( $val->{module_name} and ! $val->{name} ) {
111		$val->{name} = $val->{module_name};
112		$val->{name} =~ s/::/-/g;
113	}
114
115	# Apply default no_index entries
116	$val->{no_index}              ||= {};
117	$val->{no_index}->{directory} ||= [];
118	SCOPE: {
119		my %seen = ();
120		$val->{no_index}->{directory} = [
121			sort
122			grep { not $seen{$_}++ }
123			grep { -d $_ } (
124				@{$val->{no_index}->{directory}},
125				qw{
126					share inc t xt test
127					example examples demo
128				},
129			)
130		];
131	}
132
133	# Generate the structure we'll be dumping
134	my $meta = {
135		resources      => {},
136		license        => $val->{license},
137		dynamic_config => $val->{dynamic_config},
138	};
139	foreach my $key ( $self->Meta_ScalarKeys ) {
140		next if $key eq 'installdirs';
141		next if $key eq 'tests';
142		$meta->{$key} = $val->{$key} if exists $val->{$key};
143	}
144	foreach my $key ( $self->Meta_ArrayKeys ) {
145		$meta->{$key} = $val->{$key} if exists $val->{$key};
146	}
147	foreach my $key ( $self->Meta_TupleKeys ) {
148		next unless exists $val->{$key};
149		$meta->{$key} = { map { @$_ } @{ $val->{$key} } };
150	}
151
152	if ( $self->_cmp( $meta->{configure_requires}->{'ExtUtils::MakeMaker'}, '6.36' ) > 0 ) {
153		# After this version ExtUtils::MakeMaker requires perl 5.6
154	        unless ( $perl_version && $self->perl_version($perl_version) >= 5.006 ) {
155	                $meta->{requires}->{perl} = '5.006';
156	        }
157	}
158
159	$meta->{provides}     = $val->{provides} if $val->{provides};
160	$meta->{no_index}     = $val->{no_index};
161	$meta->{generated_by} = "$pkg version $ver";
162	$meta->{'meta-spec'}  = {
163		version => 1.4,
164		url     => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
165	};
166	unless ( scalar keys %{$meta->{resources}} ) {
167		delete $meta->{resources};
168	}
169
170	# Support version.pm versions
171	if ( UNIVERSAL::isa($meta->{version}, 'version') ) {
172		$meta->{version} = $meta->{version}->numify;
173	}
174
175	# extra metadata
176	foreach my $key (grep /^x_/, keys %$val) {
177		$meta->{$key} = $val->{$key};
178	}
179
180	YAML::Tiny::Dump($meta);
181}
182
183
184
185
186
187######################################################################
188# MYMETA.yml Support
189
190sub WriteMyMeta {
191	my $self = shift;
192	$self->configure_requires( 'YAML::Tiny' => 1.36 );
193	$self->write_mymeta;
194	return 1;
195}
196
1971;
198