3 use warnings FATAL => 'all';
5 use ExtUtils::MakeMaker ();
9 our $VERSION = '0.002000';
10 $VERSION = eval $VERSION;
12 my $MM_VER = eval $ExtUtils::MakeMaker::VERSION;
15 author manifest_include readme_generator
20 warnings->import(FATAL => 'all');
21 shift->export_to_level(1,@_);
38 '' => qr{Changes|MANIFEST|README|LICENSE|META\.yml},
39 'maint' => qr{[^.].*},
42 sub manifest_include {
46 sub readme_generator {
47 die "readme_generator unsupported" if @_ && $_[0];
50 sub write_manifest_skip {
52 my @files = @Manifest;
54 while (my ($dir, $spec) = splice(@files, 0, 2)) {
55 my $re = ($dir ? $dir.'/' : '').
56 ((ref($spec) eq 'Regexp')
60 # print ref as well as stringification in case of overload ""
61 : die "spec must be string or regexp, was: ${spec} (${\ref $spec})");
64 my $dist_name = $mm->{DISTNAME};
65 my $include = join '|', map "${_}\$", @parts;
66 my $final = "^(?:\Q$dist_name\E-v?[0-9_.]+/|(?!$include))";
67 open my $skip, '>', 'MANIFEST.SKIP'
68 or die "can't open MANIFEST.SKIP: $!";
69 print $skip "${final}\n";
76 @MM::ISA = (__PACKAGE__);
79 my ($class, $args) = @_;
80 my %test = %{$args->{test}||{}};
81 my $tests = $test{TESTS} || 't/*.t';
82 $tests !~ /\b\Q$_\E\b/ and $tests .= " $_"
83 for 'xt/*.t', 'xt/*/*.t';
84 $test{TESTS} = $tests;
85 return $class->SUPER::new({
87 MIN_PERL_VERSION => '5.006',
88 AUTHOR => ($MM_VER >= 6.5702 ? $Distar::Author : join(', ', @$Distar::Author)),
89 (exists $args->{ABSTRACT} ? () : (ABSTRACT_FROM => $args->{VERSION_FROM})),
92 realclean => { FILES => (
93 ($args->{realclean}{FILES}||'')
94 . ' Distar/ MANIFEST.SKIP MANIFEST MANIFEST.bak'
101 `git ls-files --error-unmatch MANIFEST.SKIP 2>&1`;
102 my $maniskip_tracked = !$?;
104 Distar::write_manifest_skip($self)
105 unless $maniskip_tracked;
106 $self->SUPER::flush(@_);
109 sub special_targets {
111 my $targets = $self->SUPER::special_targets(@_);
112 my $phony_targets = join ' ', qw(
127 $targets =~ s/^(\.PHONY *:.*)/$1 $phony_targets/m;
135 if (open my $fh, '<', 'maint/Makefile.include') {
136 $include = "\n# --- Makefile.include:\n\n" . do { local $/; <$fh> };
137 $include =~ s/\n?\z/\n/;
141 grep { $include !~ /^bump$_(?: +\w+)*:/m } ('', 'minor', 'major');
143 my $distar = File::Spec->catdir(
144 File::Spec->catpath((File::Spec->splitpath(__FILE__))[0,1], ''),
147 my $helpers = File::Spec->catdir($distar, 'helpers');
150 DISTAR => $self->quote_literal($distar),
151 HELPERS => $self->quote_literal($helpers),
152 REMAKE => join(' ', '$(PERLRUN)', '-I$(DISTAR)/lib', '-mDistar', 'Makefile.PL', map { $self->quote_literal($_) } @ARGV),
153 BRANCH => $self->{BRANCH} ||= 'master',
154 CHANGELOG => $self->{CHANGELOG} ||= 'Changes',
155 DEV_NULL_STDOUT => ($self->{DEV_NULL} ? '>'.File::Spec->devnull : ''),
160 $self->SUPER::dist_test(@_),
161 "\n\n# --- Distar section:\n\n",
162 (map "$_ = $vars{$_}\n", sort keys %vars),
165 preflight: check-version check-manifest check-cpan-upload
166 $(ABSPERLRUN) $(HELPERS)/preflight $(VERSION) --changelog=$(CHANGELOG) --branch=$(BRANCH)
168 $(ABSPERLRUN) $(HELPERS)/check-version $(VERSION) $(TO_INST_PM) $(EXE_FILES)
170 $(ABSPERLRUN) $(HELPERS)/check-manifest
172 $(NOECHO) cpan-upload -h $(DEV_NULL_STDOUT)
174 $(MAKE) disttest RELEASE_TESTING=1 PASTHRU="$(PASTHRU) TEST_FILES=\"$(TEST_FILES)\""
177 git commit -a -m "Release commit for $(VERSION)"
178 git tag v$(VERSION) -m "release v$(VERSION)"
179 $(RM_RF) $(DISTVNAME)
180 $(MAKE) $(DISTVNAME).tar$(SUFFIX)
181 $(NOECHO) $(MAKE) pushrelease FAKE_RELEASE=$(FAKE_RELEASE)
184 pushrelease$(FAKE_RELEASE) ::
185 cpan-upload $(DISTVNAME).tar$(SUFFIX)
186 git push origin v$(VERSION) HEAD
188 readmefile: create_distdir
189 $(NOECHO) $(TEST_F) $(DISTVNAME)/README || $(MAKE) $(DISTVNAME)/README
190 $(DISTVNAME)/README: $(VERSION_FROM)
191 $(NOECHO) $(MKPATH) $(DISTVNAME)
192 pod2text $(VERSION_FROM) >$(DISTVNAME)/README
193 $(NOECHO) $(ABSPERLRUN) $(HELPERS)/add-to-manifest -d $(DISTVNAME) README
194 distsignature: readmefile
195 disttest: distmanicheck
196 distmanicheck: create_distdir
197 cd $(DISTVNAME) && $(ABSPERLRUN) "-MExtUtils::Manifest=manicheck" -e "exit manicheck"
199 $(ABSPERLRUN) $(HELPERS)/add-changelog-heading --git $(VERSION) $(CHANGELOG)
201 cd $(DISTAR) && git pull || $(TRUE)
202 $(RM_F) $(FIRST_MAKEFILE)
205 map(sprintf(<<'END', "bump$_", ($_ || '$(V)')), @bump_targets),
207 $(ABSPERLRUN) $(HELPERS)/bump-version --git $(VERSION) %s
208 $(RM_F) $(FIRST_MAKEFILE)
222 Distar - Additions to ExtUtils::MakeMaker for dist authors
228 use ExtUtils::MakeMaker;
229 (do './maint/Makefile.PL.include' or die $@) unless -f 'META.yml';
233 F<maint/Makefile.PL.include>:
235 BEGIN { -e 'Distar' or system("git clone git://git.shadowcat.co.uk/p5sagit/Distar.git") }
236 use lib 'Distar/lib';
239 author 'A. U. Thor <author@cpan.org>';
241 manifest_include t => 'test-helper.pl';
242 manifest_include corpus => '.txt';
247 $ make bump # bump version
248 $ make bump V=2.000000 # bump to specific version
249 $ make bumpminor # bump minor version component
250 $ make bumpmajor # bump major version component
251 $ make nextrelease # add version heading to Changes file
252 $ make releasetest # build dist and test (with xt/ and RELEASE_TESTING=1)
253 $ make preflight # check that repo and file state is release ready
254 $ make release # check releasetest and preflight, commits and tags,
255 # builds and uploads to CPAN, and pushes commits and
257 $ make release FAKE_RELEASE=1
258 # builds a release INCLUDING committing and tagging,
259 # but does not upload to cpan or push anything to git
263 L<ExtUtils::MakeMaker> works well enough as development tool for
264 builting and testing, but using it to release is annoying and error prone.
265 Distar adds just enough to L<ExtUtils::MakeMaker> for it to be a usable dist
266 author tool. This includes extra commands for releasing and safety checks, and
267 automatic generation of some files. It doesn't require any non-core modules and
268 is compatible with old versions of perl.
272 =head2 author( $author )
274 Set the author to include in generated META files. Can be a single entry, or
277 =head2 manifest_include( $dir, $pattern )
279 Add a pattern to include files in the MANIFEST file, and thus in the generated
282 The pattern can be either a regex, or a path suffix. It will be applied to the
283 full path past the directory specified.
285 The default files that are always included are: F<.pm> and F<.pod> files in
286 F<lib>, F<.t> files in F<t> and F<xt>, F<.pm> files in F<t/lib> and F<xt/lib>,
287 F<Changes>, F<MANIFEST>, F<README>, F<LICENSE>, F<META.yml>, and F<.PL> files in
288 the dist root, and all files in F<maint>.
290 =head1 AUTOGENERATED FILES
294 =item F<MANIFEST.SKIP>
296 The F<MANIFEST.SKIP> will be automatically generated to exclude any files not
297 explicitly allowed via C<manifest_include> or the included defaults. It will be
298 created (or updated) at C<perl Makefile.PL> time.
302 The F<README> file will be generated at dist generation time, inside the built
303 dist. It will be generated using C<pod2text> on the main module.
305 If a F<README> file exists in the repo, it will be used directly instead of
310 =head1 MAKE COMMMANDS
314 test will be adjusted to include F<xt/> tests by default. This will only apply
315 for authors, not users installing from CPAN.
319 Releases the dist. Before releasing, checks will be done on the dist using the
320 C<preflight> and C<releasetest> commands.
322 Releasing will generate a dist tarball and upload it to CPAN using cpan-upload.
323 It will also create a git tag for the release, and push the tag and branch.
327 If release is run with FAKE_RELEASE=1 set, it will skip uploading to CPAN and
328 pushing to git. A release commit will still be created and tagged locally.
332 Performs a number of checks on the files and repository, ensuring it is in a
333 sane state to do a release. The checks are:
337 =item * All version numbers match
339 =item * The F<MANIFEST> file is up to date
341 =item * The branch is correct
343 =item * There is no existing tag for the version
345 =item * There are no unmerged upstream changes
347 =item * There are no outstanding local changes
349 =item * There is an appropriate staged Changes heading
351 =item * cpan-upload is available
357 Test the dist preparing for a release. This generates a dist dir and runs the
358 tests from inside it. This ensures all appropriate files are included inside
359 the dist. C<RELEASE_TESTING> will be set in the environment.
363 Adds an appropriate changelog heading for the release, and prompts to stage the
368 Bumps the version number. This will try to preserve the length and format of
369 the version number. The least significant digit will be incremented. Versions
370 with underscores will preserve the underscore in the same position.
372 Optionally accepts a C<V> option to set the version to a specific value.
374 The version changes will automatically be committed. Unstaged modifications to
375 the files will be left untouched.
379 The V option will be passed along to the version bumping script. It can accept
380 a space separated list of options, including an explicit version number.
388 Updates version numbers even if they do not match the current expected version
393 Attempts to convert the updated version to a stable version, removing any
398 Attempts to convert the updated version to an alpha version, adding an
399 underscore in an appropriate place.
405 Like bump, but increments the minor segment of the version. This will treat
406 numeric versions as x.yyyzzz format, incrementing the yyy segment.
410 Like bumpminor, but bumping the major segment.
414 Updates Distar and re-runs C<perl Makefile.PL>
418 IRC: #web-simple on irc.perl.org
420 Git repository: L<git://git.shadowcat.co.uk/p5sagit/Distar>
422 Git browser: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/Distar.git;a=summary>
426 mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
430 haarg - Graham Knop (cpan:HAARG) <haarg@cpan.org>
432 ether - Karen Etheridge (cpan:ETHER) <ether@cpan.org>
434 frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com>
436 Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
440 Copyright (c) 2011-2015 the Distar L</AUTHOR> and L</CONTRIBUTORS>
445 This library is free software and may be distributed under the same terms
446 as perl itself. See L<http://dev.perl.org/licenses/>.