Created
February 18, 2017 05:56
Star
You must be signed in to star a gist
Perl6 remote Distribution object access and installation over github http api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use Net::HTTP::GET; # Only dependency is IO::Socket::SSL (and indirectly OpenSSL) | |
| require IO::Socket::SSL; # Github requirement | |
| # Save this code as $PWD/HTTPDistribution.pm6 | |
| # | |
| # List meta data | |
| # perl6 -I. -MHTTPDistribution -e 'say HTTPDistribution.new.meta.perl' | |
| # | |
| # List all files | |
| # perl6 -I. -MHTTPDistribution -e 'say HTTPDistribution.new.ls-files' | |
| # | |
| # View the content of a file (this is how it is accessed by rakudo's CompUnit::Repoistory when installing) | |
| # perl6 -I. -MHTTPDistribution -e 'say HTTPDistribution.new.content("lib/Zef/Fetch.pm6").slurp-rest' | |
| # perl6 -I. -MHTTPDistribution -e 'say HTTPDistribution.new.content("resources/config.json").slurp-rest' | |
| # | |
| # View the content of a module by *name* by using its meta data | |
| # perl6 -I. -MHTTPDistribution -e 'HTTPDistribution.new andthen {.content(.meta<provides><Zef::Fetch>).slurp-rest.say}' | |
| # | |
| # Actually install (watch out for github rate limits!) | |
| # perl6 -I. -MHTTPDistribution -e 'say $*REPO.repo-chain[1].install(HTTPDistribution.new)' | |
| class HTTPDistribution does Distribution { | |
| has $.user = 'ugexe'; | |
| has $.repo = 'zef'; | |
| has $.rev = 'master'; | |
| has %!meta; | |
| method meta { | |
| state $meta-basename = self.ls-files.first(*.ends-with('META6.json' | 'META.info')) | |
| or die "No META6.json file found. Aborting"; | |
| %!meta ||= do { | |
| my $json = $.slurp-rest($meta-basename, :!bin); | |
| my %hash = %( Rakudo::Internals::JSON.from-json($json) ); | |
| %hash<files> = self.ls-files.grep(*.starts-with('bin/' | 'resources/')) | |
| .grep(!*.ends-with('/')).cache; | |
| %hash | |
| } | |
| } | |
| method content($name-path) { | |
| self but role :: { | |
| method open(|) { self } | |
| method close(|) { True } | |
| method slurp-rest(|c) { nextwith($name-path, |c) } | |
| method e { $name-path ~~ any($.ls-files) } | |
| method f { $name-path ~~ any($.ls-files) } | |
| method d { False } | |
| method r { True } | |
| method w { False } | |
| } | |
| } | |
| method !content-uri($name-path = '') { "https://raw.githubusercontent.com/{$.user}/{$.repo}/{$.rev}/{$name-path}" } | |
| method !ls-files-uri { "https://api.github.com/repos/{$.user}/{$.repo}/git/trees/{$.rev}?recursive=1" } | |
| method !https-request($url) { LEAVE sleep 1; Net::HTTP::GET($url, :header(self!header)) } | |
| method !header { | |
| my %header = User-Agent => 'perl6 HTTP::UserAgent'; | |
| with self.?api-key { %header<Authorization> = "token {$_}" } | |
| %header; | |
| } | |
| method slurp-rest($name-path, Bool :$bin) { | |
| my $response = self!https-request(self!content-uri($name-path)); | |
| $bin ?? $response.body !! $response.content; | |
| } | |
| method ls-files { | |
| state @paths = do { | |
| my $request = self!https-request(self!ls-files-uri); | |
| my $json = Rakudo::Internals::JSON.from-json($request.content)<tree>; | |
| $json.grep(*.<type>.?chars).grep({.<type>.lc eq 'blob'}).map(*.<path>) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment