Skip to content

Instantly share code, notes, and snippets.

@jberger
Last active June 11, 2019 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jberger/401e6864e212480fda3412dfeabd39e8 to your computer and use it in GitHub Desktop.
Save jberger/401e6864e212480fda3412dfeabd39e8 to your computer and use it in GitHub Desktop.
#!perl
use strict;
use warnings;
use Archive::Tar;
use CPAN::Meta;
use ExtUtils::Manifest qw/mkmanifest maniread/;
use Module::CPANfile;
use Module::Metadata;
use Module::Build::Tiny ();
use Time::Piece;
my ($dist, $path, $module) = @ARGV;
die "distribution name is required\n"
unless $dist;
my $version = gmtime->strftime('%Y%m%d.%H%M%S');
my $re = $module ? qr/\Q$module\E/ : qr/([^\s;]+)/;
$re = qr/package\s++$re\K\s*;/;
unless ($path) {
$path = $dist;
$path =~ s[-][/]g;
$path = "lib/$path.pm";
}
die "Cannot find file $path\n"
unless -f $path;
# find main module and inject
{
my $found = 0;
local @ARGV = ($path);
local $^I = '';
while (<>) {
if (!$found && s/$re/ $version;/) {
$module = $1 unless $module;
$found = 1;
}
print;
}
die "Main module name was not found in $path\n"
unless $module;
die "Module version was not written into $path\n"
unless $found;
}
my $prereqs = Module::CPANfile->load('cpanfile')->prereq_specs;
$prereqs->{configure}{requires}{'Module::Build::Tiny'} //= $Module::Build::Tiny::VERSION;
my $provides = -d 'lib' ? Module::Metadata->provides(version => 2, dir => 'lib') : {};
my $meta = CPAN::Meta->create({
name => $dist,
author => ['Generated Author'],
version => $version,
abstract => "Generated abstract for $module",
dynamic_config => 0,
license => [ 'restricted' ],
prereqs => $prereqs,
provides => $provides,
release_status => 'stable',
});
$meta->save('META.json');
maybe_spurt('Build.PL', <<'FILE');
use Module::Build::Tiny;
Build_PL();
FILE
maybe_spurt('MANIFEST.SKIP', <<'FILE');
#!include_default
^debian/
^[^/]*\.tar\.gz$
FILE
$ExtUtils::Manifest::Quiet = 1;
$ExtUtils::Manifest::Verbose = 0;
mkmanifest();
my $files = maniread();
my $arch = Archive::Tar->new;
$arch->add_files(sort keys %$files);
my $file = "$dist-$version.tar.gz";
$arch->write($file, &Archive::Tar::COMPRESS_GZIP, $dist);
print "$file\n";
sub maybe_spurt {
my ($file, $text) = @_;
return if -f $file;
open my $fh, '>', $file or die "Cannot open $file for writing\n";
print $fh $text;
}
#!/usr/bin/env perl
use strict;
use warnings;
use App::cpm::CLI;
use File::Spec;
use Carton::CPANfile;
use Carton::Snapshot;
my $install_path = 'local';
my $darkpan = 'https://darkpan.myhost.com/combined';
# call the cli library directly rather than shelling out
# equivalent to running `$ cpm install ...`
App::cpm::CLI->new->run(
'install',
'-v',
'--color',
'--mirror', $darkpan,
'-L', $install_path,
'--exclude-vendor', # undocumented option that is needed for fully self-contained builds
'-r', "02packages,$darkpan",
'-r', 'metadb',
'--test', # run module tests
# features that carton snapshots by default
'--with-configure', '--with-build', '--with-runtime', '--with-test', '--with-develop',
@ARGV, # any additional cpm options can be passed as switches to this script
) && die "Installation failed\n";
my $cpanfile_path = File::Spec->rel2abs('cpanfile');
my $cpanfile = Carton::CPANfile->new(path => $cpanfile_path);
$cpanfile->load;
my $snapshot = Carton::Snapshot->new(path => "$cpanfile_path.snapshot");
$snapshot->find_installs($install_path, $cpanfile->requirements);
$snapshot->save;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment