| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Alien::Build::Plugin::Download::GitLab; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 1 |  |  | 1 |  | 189526 | use strict; | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 24 |  | 
| 4 | 1 |  |  | 1 |  | 5 | use warnings; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 19 |  | 
| 5 | 1 |  |  | 1 |  | 30 | use 5.008004; | 
|  | 1 |  |  |  |  | 3 |  | 
| 6 | 1 |  |  | 1 |  | 5 | use Carp qw( croak ); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 55 |  | 
| 7 | 1 |  |  | 1 |  | 489 | use URI; | 
|  | 1 |  |  |  |  | 4061 |  | 
|  | 1 |  |  |  |  | 28 |  | 
| 8 | 1 |  |  | 1 |  | 689 | use JSON::PP qw( decode_json ); | 
|  | 1 |  |  |  |  | 12028 |  | 
|  | 1 |  |  |  |  | 59 |  | 
| 9 | 1 |  |  | 1 |  | 7 | use URI::Escape qw( uri_escape ); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 35 |  | 
| 10 | 1 |  |  | 1 |  | 402 | use Alien::Build::Plugin; | 
|  | 1 |  |  |  |  | 10166 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 11 | 1 |  |  | 1 |  | 81 | use File::Basename qw( basename ); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 84 |  | 
| 12 | 1 |  |  | 1 |  | 755 | use Path::Tiny qw( path ); | 
|  | 1 |  |  |  |  | 10265 |  | 
|  | 1 |  |  |  |  | 724 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | # ABSTRACT: Alien::Build plugin to download from GitLab | 
| 15 |  |  |  |  |  |  | our $VERSION = '0.01'; # VERSION | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | has gitlab_host    => 'https://gitlab.com'; | 
| 19 |  |  |  |  |  |  | has gitlab_user    => undef; | 
| 20 |  |  |  |  |  |  | has gitlab_project => undef; | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | has type => 'source';  # source or link | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | has format => 'tar.gz'; | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | has version_from    => 'tag_name'; # tag_name or name | 
| 30 |  |  |  |  |  |  | has convert_version => undef; | 
| 31 |  |  |  |  |  |  | has link_name       => undef; | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | sub init | 
| 34 |  |  |  |  |  |  | { | 
| 35 | 0 |  |  | 0 | 1 |  | my($self, $meta) = @_; | 
| 36 |  |  |  |  |  |  |  | 
| 37 | 0 | 0 |  |  |  |  | croak("No gitlab_user provided") unless defined $self->gitlab_user; | 
| 38 | 0 | 0 |  |  |  |  | croak("No gitlab_project provided") unless defined $self->gitlab_project; | 
| 39 | 0 | 0 |  |  |  |  | croak("Don't set set a start_url with the Download::GitLab plugin") if defined $meta->prop->{start_url}; | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 0 |  |  |  |  |  | $meta->add_requires('configure' => 'Alien::Build::Plugin::Download::GitLab' => 0 ); | 
| 42 |  |  |  |  |  |  |  | 
| 43 | 0 |  |  |  |  |  | my $url = URI->new($self->gitlab_host); | 
| 44 | 0 |  |  |  |  |  | $url->path("/api/v4/projects/@{[ uri_escape(join '/', $self->gitlab_user, $self->gitlab_project) ]}/releases"); | 
|  | 0 |  |  |  |  |  |  | 
| 45 | 0 |  | 0 |  |  |  | $meta->prop->{start_url} ||= "$url"; | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 0 |  |  |  |  |  | $meta->apply_plugin('Download'); | 
| 48 | 0 |  |  |  |  |  | $meta->apply_plugin('Extract', format => $self->format ); | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | # we assume that GitLab returns the releases in reverse | 
| 51 |  |  |  |  |  |  | # chronological order. | 
| 52 |  |  |  |  |  |  | $meta->register_hook( | 
| 53 |  |  |  |  |  |  | prefer => sub { | 
| 54 | 0 |  |  | 0 |  |  | my($build, $res) = @_; | 
| 55 | 0 |  |  |  |  |  | return $res; | 
| 56 |  |  |  |  |  |  | }, | 
| 57 | 0 |  |  |  |  |  | ); | 
| 58 |  |  |  |  |  |  |  | 
| 59 | 0 | 0 |  |  |  |  | croak "type must be one of source or link" if $self->type !~ /^(source|link)$/; | 
| 60 | 0 | 0 |  |  |  |  | croak "version_from must be one of tag_name or name" if $self->version_from !~ /^(tag_name|name)$/; | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | ## TODO insert tokens as header if possible | 
| 63 |  |  |  |  |  |  | ## This may help with rate limiting (or if not then don't bother) | 
| 64 |  |  |  |  |  |  | # curl --header "PRIVATE-TOKEN: " "https://gitlab.example.com/api/v4/projects/24/releases" | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | $meta->around_hook( | 
| 67 |  |  |  |  |  |  | fetch => sub { | 
| 68 | 0 |  |  | 0 |  |  | my $orig = shift; | 
| 69 | 0 |  |  |  |  |  | my($build, $url, @the_rest) = @_; | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | # only modify the response if we are using the GitLab API | 
| 72 |  |  |  |  |  |  | # to get the release list | 
| 73 |  |  |  |  |  |  | return $orig->($build, $url, @the_rest) | 
| 74 | 0 | 0 | 0 |  |  |  | if defined $url && $url ne $meta->prop->{start_url}; | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 0 |  |  |  |  |  | my $res = $orig->($build, $url, @the_rest); | 
| 77 |  |  |  |  |  |  |  | 
| 78 | 0 |  |  |  |  |  | my $res2 = { | 
| 79 |  |  |  |  |  |  | type => 'list', | 
| 80 |  |  |  |  |  |  | list => [], | 
| 81 |  |  |  |  |  |  | }; | 
| 82 |  |  |  |  |  |  |  | 
| 83 | 0 | 0 |  |  |  |  | $res2->{protocol} = $res->{protocol} if exists $res->{protocol}; | 
| 84 |  |  |  |  |  |  |  | 
| 85 | 0 |  |  |  |  |  | my $rel; | 
| 86 | 0 | 0 |  |  |  |  | if($res->{content}) | 
|  |  | 0 |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | { | 
| 88 | 0 |  |  |  |  |  | $rel = decode_json $res->{content}; | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  | elsif($res->{path}) | 
| 91 |  |  |  |  |  |  | { | 
| 92 | 0 |  |  |  |  |  | $rel = decode_json path($res->{path})->slurp_raw; | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  | else | 
| 95 |  |  |  |  |  |  | { | 
| 96 | 0 |  |  |  |  |  | croak("malformed response object: no content or path"); | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 | 0 |  |  |  |  |  | foreach my $release (@$rel) | 
| 100 |  |  |  |  |  |  | { | 
| 101 | 0 | 0 |  |  |  |  | my $version = $self->version_from eq 'name' ? $release->{name} : $release->{tag_name}; | 
| 102 | 0 | 0 |  |  |  |  | $version = $self->convert_version->($version) if $self->convert_version; | 
| 103 |  |  |  |  |  |  |  | 
| 104 | 0 | 0 |  |  |  |  | if($self->type eq 'source') | 
| 105 |  |  |  |  |  |  | { | 
| 106 | 0 |  |  |  |  |  | foreach my $source (@{ $release->{assets}->{sources} }) | 
|  | 0 |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | { | 
| 108 | 0 | 0 |  |  |  |  | next unless $source->{format} eq $self->format; | 
| 109 | 0 |  |  |  |  |  | my $url = URI->new($source->{url}); | 
| 110 | 0 |  |  |  |  |  | my $filename = basename $url->path; | 
| 111 | 0 |  |  |  |  |  | push @{ $res2->{list} }, { | 
| 112 |  |  |  |  |  |  | filename => $filename, | 
| 113 |  |  |  |  |  |  | url      => $source->{url}, | 
| 114 | 0 |  |  |  |  |  | version  => $version, | 
| 115 |  |  |  |  |  |  | }; | 
| 116 |  |  |  |  |  |  | } | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  | else # link | 
| 119 |  |  |  |  |  |  | { | 
| 120 | 0 |  |  |  |  |  | foreach my $link (@{ $release->{assets}->{links} }) | 
|  | 0 |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | { | 
| 122 | 0 |  |  |  |  |  | my $url = URI->new($link->{url}); | 
| 123 | 0 |  |  |  |  |  | my $filename => basename $url->path; | 
| 124 | 0 | 0 |  |  |  |  | if($self->link_name) | 
| 125 |  |  |  |  |  |  | { | 
| 126 | 0 | 0 |  |  |  |  | next unless $filename =~ $self->link_name; | 
| 127 |  |  |  |  |  |  | } | 
| 128 | 0 |  |  |  |  |  | push @{ $res2->{list} }, { | 
| 129 |  |  |  |  |  |  | filename => $filename, | 
| 130 |  |  |  |  |  |  | url      => $link->{url}, | 
| 131 | 0 |  |  |  |  |  | version  => $version, | 
| 132 |  |  |  |  |  |  | }; | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  | } | 
| 135 |  |  |  |  |  |  | } | 
| 136 |  |  |  |  |  |  |  | 
| 137 | 0 |  |  |  |  |  | return $res2; | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | }, | 
| 140 | 0 |  |  |  |  |  | ); | 
| 141 |  |  |  |  |  |  | } | 
| 142 |  |  |  |  |  |  |  | 
| 143 |  |  |  |  |  |  | 1; | 
| 144 |  |  |  |  |  |  |  | 
| 145 |  |  |  |  |  |  | __END__ |