GitLab-API-v4
view release on metacpan or search on metacpan
- More contextual JSON decoding error messages.
0.22 2019-09-13T15:02:28Z
- Add the statistics method.
- The delete_user method can now take parameters, allowing for use of
the hard_delete parameter.
0.21 2019-08-24T18:56:13Z
- The release endpoint returns a 403 on an unknown tag rather than a
404 like it should. This condition is now detected and treated
like a 404.
0.20 2019-07-23T21:42:37Z
- The preexisting create_release and edit_release methods have been
renamed to create_tag_release and update_tag_release to make room
for the new releases API.
- Added methods for the new (added in GitLab 11.7) releases and
release links APIs.
- Enable and fix upload_file_to_project by using
HTTP::Tiny::Multipart.
- Individual methods may now have a custom note added to their POD.
- Added a self-contained unit test, unit.t, which can be expanded on
in the future. This is unlike regression.t which requires that a
GitLab installation be available.
- Added the rest_client_class argument.
0.08 2018-05-14
- Many API endpoints which return lists and did not support
parameters now do in order for pagination arguments, and the
paginator, to be used with them.
- Add project_languages method.
- Remove upload_file_to_project since it doesn't work. Will re-add
when it is made to work later.
0.07 2018-05-10
- Completely overhaul ::RestClient to use HTTP::Tiny instead of
Role::REST::Client. This change will make it much easier to alter
Note that many API calls require a `$project_id`. This can be
specified as a numeric project `ID` or, in many cases, maybe all cases,
as a `NAMESPACE_PATH/PROJECT_PATH` string. The GitLab documentation on
this point is vague.
# REQUIRED ARGUMENTS
## url
The URL to your v4 API endpoint. Typically this will be something
like `https://git.example.com/api/v4`.
# OPTIONAL ARGUMENTS
## access\_token
A GitLab API OAuth2 token. If set then ["private\_token"](#private_token) may not be set.
See [https://docs.gitlab.com/ce/api/#oauth2-tokens](https://docs.gitlab.com/ce/api/#oauth2-tokens).
author/README.pod view on Meta::CPAN
generating the documentation. If no return variable is declared
then the subroutine will return an empty list no matter what
the API response returns.
=head2 HTTP_METHOD
One of GET, POST, PUT, or DELETE.
=head2 PATH
The path to the API endpoint (after the /api/v4 bit).
The path is a list of static and dynamic strings separate by
forward slashes. So, if you have:
/foo/:bar/baz
Then the API subroutine would require one argument which would
be injected in place of C<:bar>.
=head2 ?
If the PATH ends with a C<?> then this signifies that the API
endpoint accepts query parameters.
=head1 GENERATING
To generate C<lib/GitLab/API/v4.pm> do this:
cd author
perl generate.pl > ../lib/GitLab/API/v4.pm
=cut
author/generate.pl view on Meta::CPAN
print $header;
print "=head1 API METHODS\n\n";
foreach my $section_pack (@{ $config->{sections} }) {
foreach my $section_name (keys %$section_pack) {
my $section = $section_pack->{$section_name};
my $file = $dir->child("$section_name.yml");
my $endpoints = YAML::XS::Load( $file->slurp() );
print "=head2 $section->{head}\n\n";
print "See L<$section->{doc_url}>.\n\n";
print "=over\n\n";
foreach my $endpoint (@$endpoints) {
if (keys(%$endpoint) == 1) {
my ($method) = keys %$endpoint;
$endpoint = {
method => $method,
spec => $endpoint->{$method},
};
}
my $method = $endpoint->{method};
my $spec = $endpoint->{spec};
my ($return, $verb, $path, $params_ok);
if ($spec =~ m{^(?:(\S+) = |)(GET|POST|PUT|DELETE) ([^/\s]\S*?[^/\s]?)(\??)$}) {
($return, $verb, $path, $params_ok) = ($1, $2, $3, $4);
}
else {
die "Invalid spec ($method): $spec";
}
my $no_decode = 0;
$no_decode = 1 if !$return;
$no_decode = 1 if $endpoint->{no_decode};
print "=item $method\n\n";
print ' ';
print "my \$$return = " if $return;
print "\$api->$method(";
my @args = (
map { ($_ =~ m{^:(.+)$}) ? "\$$1" : () }
author/generate.pl view on Meta::CPAN
@args
);
print ' ';
}
print ");\n\n";
print "Sends a C<$verb> request to C<$path>";
print ' and returns the ' . ($no_decode ? 'raw' : 'decoded') . ' response content' if $return;
print ".\n\n";
print "$endpoint->{note}\n" if $endpoint->{note};
print "=cut\n\n";
print "sub $method {\n";
print " my \$self = shift;\n";
if (@args) {
my $min_args = @args;
my $max_args = @args;
$min_args-- if $params_ok;
author/header.pm view on Meta::CPAN
# causing circular references. Don't ever pass it a ref.
sub _make_safe_closure {
my ($ret) = @_;
return sub{ $ret };
}
=head1 REQUIRED ARGUMENTS
=head2 url
The URL to your v4 API endpoint. Typically this will be something
like C<https://git.example.com/api/v4>.
=cut
has url => (
is => 'ro',
isa => NonEmptySimpleStr,
required => 1,
);
lib/GitLab/API/v4.pm view on Meta::CPAN
# causing circular references. Don't ever pass it a ref.
sub _make_safe_closure {
my ($ret) = @_;
return sub{ $ret };
}
=head1 REQUIRED ARGUMENTS
=head2 url
The URL to your v4 API endpoint. Typically this will be something
like C<https://git.example.com/api/v4>.
=cut
has url => (
is => 'ro',
isa => NonEmptySimpleStr,
required => 1,
);
lib/GitLab/API/v4/Mock/RESTClient.pm view on Meta::CPAN
use URI;
use Moo;
use strictures 2;
use namespace::clean;
extends 'GitLab::API::v4::RESTClient';
my @ENDPOINTS;
sub has_endpoint {
my ($method, $path_re, $sub) = @_;
push @ENDPOINTS, [
$method, $path_re, $sub,
];
return;
}
sub _http_tiny_request {
my ($self, $req_method, $req) = @_;
die "req_method may only be 'request' at this time"
if $req_method ne 'request';
my ($http_method, $url, $options) = @$req;
my $path = URI->new( $url )->path();
$path =~ s{^.*api/v4/}{};
foreach my $endpoint (@ENDPOINTS) {
my ($endpoint_method, $path_re, $sub) = @$endpoint;
next if $endpoint_method ne $http_method;
next if $path !~ $path_re;
my @captures = ($path =~ $path_re);
my ($status, $content) = $sub->(
$self,
[$http_method, $url, $options],
@captures,
);
$content = encode_json( $content ) if ref $content;
return {
status => $status,
success => ($status =~ m{^2\d\d$}) ? 1 : 0,
defined( $content ) ? (content=>$content) : (),
};
}
die "No endpoint matched the $http_method '$path' endpoint";
}
=head1 ATTRIBUTES
=head2 engine
The L<GitLab::API::v4::Mock::Engine> used behind the hood.
=cut
lib/GitLab/API/v4/Mock/RESTClient.pm view on Meta::CPAN
}
=head1 USER ENDPOINTS
=head2 GET users
Handles L<GitLab::API::v4/users>.
=cut
has_endpoint GET => qr{^users$}, sub{
my ($self) = @_;
return 200, $self->engine->users();
};
=head2 GET user/:id
Handles L<GitLab::API::v4/user>.
=cut
has_endpoint GET => qr{^users/(\d+)$}, sub{
my ($self, $req, $id) = @_;
my $user = $self->engine->user( $id );
return 404 if !$user;
return 200, $user;
};
=head2 POST users
Handles L<GitLab::API::v4/create_user>.
=cut
has_endpoint POST => qr{^users$}, sub{
my ($self, $req) = @_;
my $user = decode_json( $req->[2]->{content} );
$self->engine->create_user( $user );
return 204;
};
=head2 PUT user/:id
Handles L<GitLab::API::v4/edit_user>.
=cut
has_endpoint PUT => qr{^users/(\d+)$}, sub{
my ($self, $req, $id) = @_;
my $data = decode_json( $req->[2]->{content} );
my $user = $self->engine->update_user( $id, $data );
return 404 if !$user;
return 204;
};
=head2 DELETE user/:id
Handles L<GitLab::API::v4/delete_user>.
=cut
has_endpoint DELETE => qr{^users/(\d+)$}, sub{
my ($self, $req, $id) = @_;
my $user = $self->engine->delete_user( $id );
return 404 if !$user;
return 204;
};
1;
__END__
( run in 1.372 second using v1.01-cache-2.11-cpan-2b1a40005be )