Create a gist now

Instantly share code, notes, and snippets.

@ugexe /dist.pl6
Last active Jan 12, 2016

# So a CompUnit::Repository could use $dist.meta to access provides, resources, etc and let the Distribution
# itself deal with the relative paths so the CU::R can recieve the data directly and save/install it somewhere
# Distribution::Local
# git clone https://github.com/User/repo.git && cd repo && echo $this-file > dist.pl6
# perl6 dist.pl6 --path=. --dir # same as above, but with a directory
# perl6 dist.pl6 --path=. --dir provides ModuleName lib/ModuleName.pm6 # ...
# perl6 test.pl6 --path=. --dir resources mylib # or direct access to "special paths" like resources, hooks, t, bin
# Distribution::Tar
# wget --no-check-certificate https://github.com/User/repo/archive/master.tar.gz && echo $this-file > dist.pl6
# perl6 dist.pl6 --path=master.tar.gz --tar # view meta data from tar archive distribution
# perl6 dist.pl6 --path=master.tar.gz --tar provides ModuleName lib/ModuleName.pm6 # get data from tar archive for meta item
# perl6 test.pl6 --path=master.tar.gz --tar resources mylib # or access to "special paths" like resources, hooks, t, bin
# https://design.perl6.org/S22.html#Distribution
role DistributionS22 {
# CU::R and installers access to meta data.
# Distribution itself would just be `method meta meta { $.hash } }`
method meta { ... }
# API access to meta items that represent a would be file
method content { ... }
# Not part of the spec. Really just verifies the entry exists for `.content`
method at-key(*@keys) {
my $wanted = @keys[*-1];
my $resource = +@keys == 1
?? $wanted
!! @keys[0..*-2].reduce(-> $n1 is rw, $n2 {
once $n1 = self.meta{$n1};
$n1{$n2}
});
$resource ne 'resources'
?? $wanted eq $resource
?? $wanted
!! die("Can't find requested meta file key {@keys[*-1]}")
!! ($resource ~ $*SPEC.dir-sep ~ $wanted);
}
}
# CompUnit::Repository::(FileSystem|Installer) could both use this
class Distribution::Local does DistributionS22 {
has $.path;
method new($path) { self.bless(:$path) }
method meta { %(from-json($!path.IO.child('META6.json').slurp)) }
method content(*@keys) {
my $abspath = $.at-key(|@keys).IO.abspath;
die "Can't find resource with path: {$abspath}" unless $abspath.IO.f;
$abspath.IO.slurp
}
}
# CompUnit::Repository::(FileSystem|Installer) could both use this
class Distribution::Tar is Distribution::Local does DistributionS22 {
has %!meta;
method meta {
once {
my $proc = run('tar', '--to-stdout', '--extract', '-zf', $.path, self!tar-path('META6.json'), :out, :bin);
%!meta = %(from-json($proc.out.slurp-rest));
$proc.out.close;
}
%!meta
}
method content(*@keys) {
my $tar-path = self!tar-path($.at-key(|@keys));
my $proc = run('tar', '--to-stdout', '--extract', '-zf', $.path, $tar-path, :out, :bin);
my $io = $proc.out.slurp-rest;
$proc.out.close;
$io;
}
method !tar-path($path-part) {
my $proc = run('tar', '--list', '-f', $.path, :out);
my @extracted-paths <== grep *.defined <== $proc.out.lines;
$proc.out.close;
@extracted-paths[0] ~ $path-part;
}
}
#| where --path=<dist directory containing META6json>
multi sub MAIN(*@keys, :$path! where *.IO.child('META6.json').e, Bool :$dir where *.so) {
say "Distribution from: $path";
my $dist-local = Distribution::Local.new($path);
say @keys.elems ?? $dist-local.content(|@keys) !! $dist-local.meta;
}
#| where --path=<.tar.gz archive containing root/META6.json, like from github>
multi sub MAIN(*@keys, :$path! where *.ends-with('.tar.gz'), Bool :$tar where *.so) {
say "Distribution from: $path";
my $dist-tar = Distribution::Tar.new($path);
say @keys.elems ?? $dist-tar.content(|@keys) !! $dist-tar.meta;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment