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;
133 my $out = $self->SUPER::tarfile_target(@_);
134 my $verify = <<'END_FRAG';
135 $(ABSPERLRUN) $(HELPERS)/verify-tarball $(DISTVNAME).tar $(DISTVNAME)/MANIFEST --tar="$(TAR)"
137 $out =~ s{(\$\(TAR\).*\n)}{$1$verify};
145 if (open my $fh, '<', 'maint/Makefile.include') {
146 $include = "\n# --- Makefile.include:\n\n" . do { local $/; <$fh> };
147 $include =~ s/\n?\z/\n/;
151 grep { $include !~ /^bump$_(?: +\w+)*:/m } ('', 'minor', 'major');
153 my $distar = File::Spec->catdir(
154 File::Spec->catpath((File::Spec->splitpath(__FILE__))[0,1], ''),
157 my $helpers = File::Spec->catdir($distar, 'helpers');
160 DISTAR => $self->quote_literal($distar),
161 HELPERS => $self->quote_literal($helpers),
162 REMAKE => join(' ', '$(PERLRUN)', '-I$(DISTAR)/lib', '-mDistar', 'Makefile.PL', map { $self->quote_literal($_) } @ARGV),
163 BRANCH => $self->{BRANCH} ||= 'master',
164 CHANGELOG => $self->{CHANGELOG} ||= 'Changes',
165 DEV_NULL_STDOUT => ($self->{DEV_NULL} ? '>'.File::Spec->devnull : ''),
167 DISTTEST_MAKEFILE_PARAMS => '',
170 my $dist_test = $self->SUPER::dist_test(@_);
171 $dist_test =~ s/(\bMakefile\.PL\b)/$1 \$(DISTTEST_MAKEFILE_PARAMS)/;
175 "\n\n# --- Distar section:\n\n",
176 (map "$_ = $vars{$_}\n", sort keys %vars),
179 preflight: check-version check-manifest check-cpan-upload
180 $(ABSPERLRUN) $(HELPERS)/preflight $(VERSION) --changelog=$(CHANGELOG) --branch=$(BRANCH)
182 $(ABSPERLRUN) $(HELPERS)/check-version $(VERSION) $(TO_INST_PM) $(EXE_FILES)
184 $(ABSPERLRUN) $(HELPERS)/check-manifest
186 $(NOECHO) cpan-upload -h $(DEV_NULL_STDOUT)
188 $(MAKE) disttest RELEASE_TESTING=1 DISTTEST_MAKEFILE_PARAMS="PREREQ_FATAL=1" PASTHRU="$(PASTHRU) TEST_FILES=\"$(TEST_FILES)\""
191 git commit -a -m "Release commit for $(VERSION)"
192 git tag v$(VERSION) -m "release v$(VERSION)"
193 $(RM_RF) $(DISTVNAME)
194 $(MAKE) $(DISTVNAME).tar$(SUFFIX)
195 $(NOECHO) $(MAKE) pushrelease FAKE_RELEASE=$(FAKE_RELEASE)
198 pushrelease$(FAKE_RELEASE) ::
199 cpan-upload $(DISTVNAME).tar$(SUFFIX)
200 git push origin v$(VERSION) HEAD
202 readmefile: create_distdir
203 $(NOECHO) $(TEST_F) $(DISTVNAME)/README || $(MAKE) $(DISTVNAME)/README
204 $(DISTVNAME)/README: $(VERSION_FROM)
205 $(NOECHO) $(MKPATH) $(DISTVNAME)
206 pod2text $(VERSION_FROM) >$(DISTVNAME)/README
207 $(NOECHO) $(ABSPERLRUN) $(HELPERS)/add-to-manifest -d $(DISTVNAME) README
208 distsignature: readmefile
209 disttest: distmanicheck
210 distmanicheck: create_distdir
211 cd $(DISTVNAME) && $(ABSPERLRUN) "-MExtUtils::Manifest=manicheck" -e "exit manicheck"
213 $(ABSPERLRUN) $(HELPERS)/add-changelog-heading --git $(VERSION) $(CHANGELOG)
215 cd $(DISTAR) && git pull || $(TRUE)
216 $(RM_F) $(FIRST_MAKEFILE)
219 map(sprintf(<<'END', "bump$_", ($_ || '$(V)')), @bump_targets),
221 $(ABSPERLRUN) $(HELPERS)/bump-version --git $(VERSION) %s
222 $(RM_F) $(FIRST_MAKEFILE)
236 Distar - Additions to ExtUtils::MakeMaker for dist authors
242 use ExtUtils::MakeMaker;
243 (do './maint/Makefile.PL.include' or die $@) unless -f 'META.yml';
247 F<maint/Makefile.PL.include>:
249 BEGIN { -e 'Distar' or system("git clone git://git.shadowcat.co.uk/p5sagit/Distar.git") }
250 use lib 'Distar/lib';
253 author 'A. U. Thor <author@cpan.org>';
255 manifest_include t => 'test-helper.pl';
256 manifest_include corpus => '.txt';
261 $ make bump # bump version
262 $ make bump V=2.000000 # bump to specific version
263 $ make bumpminor # bump minor version component
264 $ make bumpmajor # bump major version component
265 $ make nextrelease # add version heading to Changes file
266 $ make releasetest # build dist and test (with xt/ and RELEASE_TESTING=1)
267 $ make preflight # check that repo and file state is release ready
268 $ make release # check releasetest and preflight, commits and tags,
269 # builds and uploads to CPAN, and pushes commits and
271 $ make release FAKE_RELEASE=1
272 # builds a release INCLUDING committing and tagging,
273 # but does not upload to cpan or push anything to git
277 L<ExtUtils::MakeMaker> works well enough as development tool for
278 builting and testing, but using it to release is annoying and error prone.
279 Distar adds just enough to L<ExtUtils::MakeMaker> for it to be a usable dist
280 author tool. This includes extra commands for releasing and safety checks, and
281 automatic generation of some files. It doesn't require any non-core modules and
282 is compatible with old versions of perl.
286 =head2 author( $author )
288 Set the author to include in generated META files. Can be a single entry, or
291 =head2 manifest_include( $dir, $pattern )
293 Add a pattern to include files in the MANIFEST file, and thus in the generated
296 The pattern can be either a regex, or a path suffix. It will be applied to the
297 full path past the directory specified.
299 The default files that are always included are: F<.pm> and F<.pod> files in
300 F<lib>, F<.t> files in F<t> and F<xt>, F<.pm> files in F<t/lib> and F<xt/lib>,
301 F<Changes>, F<MANIFEST>, F<README>, F<LICENSE>, F<META.yml>, and F<.PL> files in
302 the dist root, and all files in F<maint>.
304 =head1 AUTOGENERATED FILES
308 =item F<MANIFEST.SKIP>
310 The F<MANIFEST.SKIP> will be automatically generated to exclude any files not
311 explicitly allowed via C<manifest_include> or the included defaults. It will be
312 created (or updated) at C<perl Makefile.PL> time.
316 The F<README> file will be generated at dist generation time, inside the built
317 dist. It will be generated using C<pod2text> on the main module.
319 If a F<README> file exists in the repo, it will be used directly instead of
324 =head1 MAKE COMMMANDS
328 test will be adjusted to include F<xt/> tests by default. This will only apply
329 for authors, not users installing from CPAN.
333 Releases the dist. Before releasing, checks will be done on the dist using the
334 C<preflight> and C<releasetest> commands.
336 Releasing will generate a dist tarball and upload it to CPAN using cpan-upload.
337 It will also create a git tag for the release, and push the tag and branch.
341 If release is run with FAKE_RELEASE=1 set, it will skip uploading to CPAN and
342 pushing to git. A release commit will still be created and tagged locally.
346 Performs a number of checks on the files and repository, ensuring it is in a
347 sane state to do a release. The checks are:
351 =item * All version numbers match
353 =item * The F<MANIFEST> file is up to date
355 =item * The branch is correct
357 =item * There is no existing tag for the version
359 =item * There are no unmerged upstream changes
361 =item * There are no outstanding local changes
363 =item * There is an appropriate staged Changes heading
365 =item * cpan-upload is available
371 Test the dist preparing for a release. This generates a dist dir and runs the
372 tests from inside it. This ensures all appropriate files are included inside
373 the dist. C<RELEASE_TESTING> will be set in the environment.
377 Adds an appropriate changelog heading for the release, and prompts to stage the
382 Bumps the version number. This will try to preserve the length and format of
383 the version number. The least significant digit will be incremented. Versions
384 with underscores will preserve the underscore in the same position.
386 Optionally accepts a C<V> option to set the version to a specific value.
388 The version changes will automatically be committed. Unstaged modifications to
389 the files will be left untouched.
393 The V option will be passed along to the version bumping script. It can accept
394 a space separated list of options, including an explicit version number.
402 Updates version numbers even if they do not match the current expected version
407 Attempts to convert the updated version to a stable version, removing any
412 Attempts to convert the updated version to an alpha version, adding an
413 underscore in an appropriate place.
419 Like bump, but increments the minor segment of the version. This will treat
420 numeric versions as x.yyyzzz format, incrementing the yyy segment.
424 Like bumpminor, but bumping the major segment.
428 Updates Distar and re-runs C<perl Makefile.PL>
432 IRC: #web-simple on irc.perl.org
434 Git repository: L<git://git.shadowcat.co.uk/p5sagit/Distar>
436 Git browser: L<http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/Distar.git;a=summary>
440 mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
444 haarg - Graham Knop (cpan:HAARG) <haarg@cpan.org>
446 ether - Karen Etheridge (cpan:ETHER) <ether@cpan.org>
448 frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com>
450 Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
454 Copyright (c) 2011-2015 the Distar L</AUTHOR> and L</CONTRIBUTORS>
459 This library is free software and may be distributed under the same terms
460 as perl itself. See L<http://dev.perl.org/licenses/>.