Commit e6040f54 authored by Roman Lacko's avatar Roman Lacko
Browse files

GitLab::Projects added

parent 7ac95366
Loading
Loading
Loading
Loading
+39 −0
Original line number Original line Diff line number Diff line
@@ -9,6 +9,7 @@ use Carp;
use GitLab::API;
use GitLab::API;
use GitLab::Groups;
use GitLab::Groups;
use GitLab::Namespaces;
use GitLab::Namespaces;
use GitLab::Projects;
use GitLab::Users;
use GitLab::Users;
use Try::Tiny;
use Try::Tiny;


@@ -18,6 +19,7 @@ our @EXPORT_OK = ();
our %EXPORT_TAGS    = (
our %EXPORT_TAGS    = (
    group_visibility => [ qw|GROUP_VISIBILITY    GROUP_PRIVATE GROUP_INTERNAL  GROUP_PUBLIC | ],
    group_visibility => [ qw|GROUP_VISIBILITY    GROUP_PRIVATE GROUP_INTERNAL  GROUP_PUBLIC | ],
    member_access    => [ qw|MEMBER_ACCESS       MEMBER_GUEST  MEMBER_REPORTER MEMBER_DEVELOPER MEMBER_MASTER MEMBER_OWNER | ],
    member_access    => [ qw|MEMBER_ACCESS       MEMBER_GUEST  MEMBER_REPORTER MEMBER_DEVELOPER MEMBER_MASTER MEMBER_OWNER | ],
    project_visibility => [ qw|PROJECT_PRIVATE PROJECT_INTERNAL PROJECT_PUBLIC| ],
    utils            => [ qw|group_visibility_name   member_access_name| ],
    utils            => [ qw|group_visibility_name   member_access_name| ],
);
);


@@ -39,12 +41,19 @@ use constant {
    MEMBER_DEVELOPER    => 30,
    MEMBER_DEVELOPER    => 30,
    MEMBER_MASTER       => 40,
    MEMBER_MASTER       => 40,
    MEMBER_OWNER        => 50,
    MEMBER_OWNER        => 50,

    # Project visibility
    PROJECT_PRIVATE     =>  0,
    PROJECT_INTERNAL    => 10,
    PROJECT_PUBLIC      => 20,
};
};


use constant GROUP_VISIBILITY
use constant GROUP_VISIBILITY
    => (GROUP_PRIVATE, GROUP_INTERNAL, GROUP_PUBLIC);
    => (GROUP_PRIVATE, GROUP_INTERNAL, GROUP_PUBLIC);
use constant MEMBER_ACCESS
use constant MEMBER_ACCESS
    => (MEMBER_GUEST, MEMBER_REPORTER, MEMBER_DEVELOPER, MEMBER_MASTER, MEMBER_OWNER);
    => (MEMBER_GUEST, MEMBER_REPORTER, MEMBER_DEVELOPER, MEMBER_MASTER, MEMBER_OWNER);
use constant PROJECT_VISIBILITY
    => (PROJECT_PRIVATE, PROJECT_INTERNAL, PROJECT_PUBLIC);


#===============================================================================
#===============================================================================
#   Utilities
#   Utilities
@@ -74,6 +83,17 @@ sub member_access_name {
    return $member_access_map{$code} // "Invalid";
    return $member_access_map{$code} // "Invalid";
}
}


my %project_visibility_map = (
     "0" => "Private",
    "10" => "Internal",
    "20" => "Public",
);

sub project_visibility_name {
    my ($code) = @_;
    return $project_visibility_map{$code} // "Invalid";
}

1;
1;


__END__
__END__
@@ -114,6 +134,14 @@ Import with C<:member_access> tag.
    40 MEMBER_MASTER
    40 MEMBER_MASTER
    50 MEMBER_OWNER
    50 MEMBER_OWNER


=head3 Project Visibility

Import with C<:project_visibility> tag.

     0 PROJECT_PRIVATE
    10 PROJECT_INTERNAL
    20 PROJECT_PUBLIC

=head2 Utilities
=head2 Utilities


Import with C<:utils> tag.
Import with C<:utils> tag.
@@ -134,6 +162,13 @@ If the parameter does not represent a valid GitLab Group Visibility code, return
Translates a Member Access code to its string representation, i.e. I<Guest>, I<Reporter>, I<Developer>, I<Master> and I<Owner>.
Translates a Member Access code to its string representation, i.e. I<Guest>, I<Reporter>, I<Developer>, I<Master> and I<Owner>.
If the parameter does not represent a valid GitLab Member Access code, returns I<Invalid>.
If the parameter does not represent a valid GitLab Member Access code, returns I<Invalid>.


=item project_visibility_name()

    $name = GitLab::project_visibility_name($code);

Translates a Project Visibility code to its string representation, i.e. I<Private>, I<Internal> and I<Public>.
If the parameter does not represent a valid GitLab Project Visibility code, returns I<Invalid>.

=back
=back


=head1 AUTHOR
=head1 AUTHOR
@@ -164,4 +199,8 @@ L<GitLab Namespaces|http://docs.gitlab.com/ce/api/namespaces.html> methods.


L<GitLab Users|http://docs.gitlab.com/ce/api/users.html> methods.
L<GitLab Users|http://docs.gitlab.com/ce/api/users.html> methods.


=item L<GitLab::Projects>

L<GitLab Users|http://docs.gitlab.com/ce/api/projects.html> methods.

=back
=back
+40 −3
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@ use LWP::UserAgent;
use Log::Any        qw($log);
use Log::Any        qw($log);
use Scalar::Util    qw(blessed);
use Scalar::Util    qw(blessed);
use URI;
use URI;
use URI::Encode;
use URI::QueryParam;
use URI::QueryParam;


use parent "Exporter";
use parent "Exporter";
@@ -135,12 +136,16 @@ sub create_uri {
    # creare URI path
    # creare URI path
    my $path     = substr $tmpl->{path}, 0;
    my $path     = substr $tmpl->{path}, 0;
    my %patharg  = map { $_ => 1 } ($path =~ m!<([^<]*)>!g);
    my %patharg  = map { $_ => 1 } ($path =~ m!<([^<]*)>!g);
    my %encode   = map { $_ => 1 } @{$tmpl->{encode}};


    foreach my $arg (keys %patharg) {
    foreach my $arg (keys %patharg) {
        croak "Argument '$arg' is required for '$tmpl->{name}'"
        croak "Argument '$arg' is required for '$tmpl->{name}'"
            unless defined $args->{$arg};
            unless defined $args->{$arg};


        $path =~ s!<$arg>!$args->{$arg}!g;
        my $val = URI::Encode::uri_encode($args->{$arg},
            $encode{$arg} ? { encode_reserved => 1 } : {});

        $path =~ s!<$arg>!$val!g;
        delete $args->{$arg};
        delete $args->{$arg};
    }
    }


@@ -278,6 +283,12 @@ sub exec_request {
        croak "Unsupported method '$tmpl->{method}'";
        croak "Unsupported method '$tmpl->{method}'";
    }
    }


    if ($log->is_trace) {
        $log->trace("--  HTTP REQUEST  --\n", $response->request->as_string);
        $log->trace("--  HTTP RESPONSE --\n", $response->as_string);
        $log->trace("--------------------");
    }

    $log->debug("status: " . $response->status_line);
    $log->debug("status: " . $response->status_line);
    $data = undef if !$response->is_success;
    $data = undef if !$response->is_success;
    $self->{response} = $response;
    $self->{response} = $response;
@@ -588,6 +599,7 @@ The I<request template> is a hashref with the following keys:
    required    arrayref of required arguments
    required    arrayref of required arguments
    optional    optional arguments
    optional    optional arguments
    ret         hashref of HTTP codes whose values will be used as status messages
    ret         hashref of HTTP codes whose values will be used as status messages
    encode      arrayref of path components that should be URI-encoded


The C<path> value can contain placeholders in the format C<< <name> >>, e.g. C<< /groups/<gid>/projects/<projid> >> is a path that contains placeholders C<gid> and C<projid>.
The C<path> value can contain placeholders in the format C<< <name> >>, e.g. C<< /groups/<gid>/projects/<projid> >> is a path that contains placeholders C<gid> and C<projid>.
When processing the template, these placeholders will automatically become I<required arguments>.
When processing the template, these placeholders will automatically become I<required arguments>.
@@ -601,8 +613,14 @@ The value of this key is an arrayref with strings.


As the name suggests, I<required arguments> must be provided, otherwise the L</exec_request> will croak.
As the name suggests, I<required arguments> must be provided, otherwise the L</exec_request> will croak.


All values for C<path> placeholders are encoded before replacement.
However, if the value can contain reserved URI characters (e.g. C</>), the encoding must be forced.
This can be done by specifying this placeholder in the C<encode> arrayref.

=head2 Examples
=head2 Examples


=head3 Simple

Consider the following template hashref:
Consider the following template hashref:


    my $user_by_id = {
    my $user_by_id = {
@@ -622,7 +640,7 @@ The C<uid> argument is required; the method will croak if it is not present.
If the given user is not found, the method will return status C<404> with reason C<User not found>.
If the given user is not found, the method will return status C<404> with reason C<User not found>.
For other status codes it will return the reason provided either by GitLab or underlying HTTP client.
For other status codes it will return the reason provided either by GitLab or underlying HTTP client.


Another example:
=head3 Required arguments


    my $user_add_ssh_key = {
    my $user_add_ssh_key = {
        name        => "user_add_ssh_key",
        name        => "user_add_ssh_key",
@@ -634,7 +652,26 @@ Another example:
This request requires arguments C<title>, C<key> and C<uid> (since it appears in the C<path>).
This request requires arguments C<title>, C<key> and C<uid> (since it appears in the C<path>).
The latter argument will be substituted in the path, the former two will be passed in the body of the request.
The latter argument will be substituted in the path, the former two will be passed in the body of the request.


The third example uses pagination:
=head3 Encoding

    my $project_by_id = {
        method      => "GET",
        path        => "/projects/<id>",
        encode      => [ qw(id) ],
    };

From API documentation, this operation returns a project with the given C<id>, which can be a numerical value or a string C<"NAMESPACE/PROJECT_NAME">.

Without the C<encode> parameter in the template, the following request

    $gitlab->project_by_id("user/project");

would result in the path C<gitlab_url/projects/user/project> which is invalid.
The slash, as a reserved character, needs to be encoded using C<encode_required> parameter for L<URI::Encode>.
This option is enabled by specifying C<id> in the C<encode> parameter in the template.
Final URL in this case would be C<gitlab_url/projects/user%2Fproject>.

=head3 Pagination and optional arguments


    my $groups  = {
    my $groups  = {
        name        => "groups",
        name        => "groups",

GitLab/Projects.pm

0 → 100644
+440 −0
Original line number Original line Diff line number Diff line
package GitLab::Projects;

use utf8;
use strict;
use warnings;
use vars qw($VERSION);

use GitLab::API;
use Log::Any        qw($log);

our $VERSION = v8.12.1;

my $requests = {
    projects => {
        method      => "GET",
        path        => "/projects",
        query       => [ qw(archived visibility order_by sort search) ],
        paginated   => 1,
    },

    projects_owned => {
        method      => "GET",
        path        => "/projects/owned",
        query       => [ qw(archived visibility order_by sort search) ],
        paginated   => 1,
    },

    projects_starred => {
        method      => "GET",
        path        => "/projects/starred",
        query       => [ qw(archived visibility order_by sort search) ],
        paginated   => 1,
    },

    projects_all => {
        method      => "GET",
        path        => "/projects/all",
        query       => [ qw(archived visibility order_by sort search) ],
        paginated   => 1,
    },

    project_by_id => {
        method      => "GET",
        path        => "/projects/<id>",
        encode      => [ qw(id) ],
    },

    project_events => {
        method      => "GET",
        path        => "/projects/<id>/events",
        encode      => [ qw(id) ],
        paginated   => 1,
    },

    projects_search => {
        method      => "GET",
        path        => "/projects/search/<query>",
        encode      => [ qw(query) ],
        optional    => [ qw(order_by sort) ],
        paginated   => 1,
    },

    project_create => {
        method      => "POST",
        path        => "/projects",
        required    => [ qw(name) ],
        optional    => [ qw(path namespace_id description issues_enabled
            merge_requests_enabled builds_enabled wiki_enabled snippets_enabled
            container_registry_enabled shared_runners_enabled public
            visibility_level import_url public_builds
            only_allow_merge_if_build_succeeds lfs_enabled
            request_access_enabled) ],
    },

    project_create_for_user => {
        method      => "POST",
        path        => "/projects/user/<uid>",
        required    => [ qw(name) ],
        optional    => [ qw(path namespace_id description issues_enabled
            merge_requests_enabled builds_enabled wiki_enabled snippets_enabled
            container_registry_enabled shared_runners_enabled public
            visibility_level import_url public_builds
            only_allow_merge_if_build_succeeds lfs_enabled
            request_access_enabled) ],
    },

    project_edit => {
        method      => "PUT",
        path        => "/projects/<id>",
        optional    => [ qw(name path namespace_id description issues_enabled
            merge_requests_enabled builds_enabled wiki_enabled snippets_enabled
            container_registry_enabled shared_runners_enabled public
            visibility_level import_url public_builds
            only_allow_merge_if_build_succeeds lfs_enabled
            request_access_enabled) ],
    },

    project_fork => {
        method      => "POST",
        path        => "/projects/fork/<id>",
        encode      => [ qw(id namespace) ],
        optional    => [ qw(namespace) ],
    },

    project_star => {
        method      => "POST",
        path        => "/projects/<id>/star",
        encode      => [ qw(id) ],
    },

    project_unstar => {
        method      => "DELETE",
        path        => "/projects/<id>/unstar",
        encode      => [ qw(id) ],
    },

    project_archive => {
        method      => "POST",
        path        => "/projects/<id>/archive",
        encode      => [ qw(id) ],
    },

    project_unarchive => {
        method      => "DELETE",
        path        => "/projects/<id>/unarchive",
        encode      => [ qw(id) ],
    },

    project_delete => {
        method      => "DELETE",
        path        => "/projects/<id>",
        encode      => [ qw(id) ],
    },

#   DO NOT USE, not sure how this is supposed to work
#   project_upload_file => {
#       method      => "POST",
#       path        => "/projects/<id>/uploads",
#       encode      => [ qw(id) ],
#       required    => [ qw(file) ],
#   },

    project_share => {
        method      => "POST",
        path        => "/projects/<id>/share",
        required    => [ qw(group_id group_access) ],
        optional    => [ qw(expires_at) ],
        encode      => [ qw(id) ],
    },

    project_hooks => {
        method      => "GET",
        path        => "/projects/<id>/hooks",
        encode      => [ qw(id) ],
        paginated   => 1,
    },

    project_get_hook => {
        method      => "GET",
        path        => "/projects/<id>/hooks/<hook_id>",
        encode      => [ qw(id) ],
    },

    project_add_hook => {
        method      => "POST",
        path        => "/projects/<id>/hooks",
        encode      => [ qw(id) ],
        required    => [ qw(url) ],
        optional    => [ qw(push_events issues_events merge_requests_events
            tag_push_events note_events build_events pipeline_events
            wiki_page_events enable_ssl_verification ) ],
    },

    project_edit_hook => {
        method      => "PUT",
        path        => "/projects/<id>/hooks/<hook_id>",
        encode      => [ qw(id) ],
        optional    => [ qw(push_events issues_events merge_requests_events
            tag_push_events note_events build_events pipeline_events
            wiki_page_events enable_ssl_verification ) ],
    },

    project_delete_hook => {
        method      => "DELETE",
        path        => "/projects/<id>/hooks/<hook_id>",
        encode      => [ qw(id) ],
    },

    project_create_forked_relationship => {
        method      => "POST",
        path        => "/projects/<id>/fork/<forked_from_id>",
        encode      => [ qw(id forked_from_id) ],
    },

    project_delete_forked_relationship => {
        method      => "DELETE",
        path        => "/projects/<id>/fork",
        encode      => [ qw(id) ],
    },
};

sub import {
    $log->debug("initializing " . __PACKAGE__);
    while (my ($name, $tmpl) = each(%$requests)) {
        $tmpl->{name} = $name unless exists $tmpl->{name};
        GitLab::API->register($tmpl);
    }
}

1;

__END__

=head1 NAME

GitLab::Projects - implements projects API calls

See L<GitLab API -- Projects|http://doc.gitlab.com/ce/api/projects.html> for details and
response formats.

=head1 VERSION

Implements API calls for GitLab CE C<v8.10.0>.
Checked 2016-09-29 for GitLab CE C<v8.12.1>.

=head1 DESCRIPTION

=head2 Notation

Please see the documentation for the L<GitLab::Users> module.

Note that not all optional arguments are listed.
Please refer to the official documentation for the full list.

=head2 Project listing

=over

=item projects()

    $gitlab->projects([...]);

Returns a list of projects accessible to the authenticated user.

=item projects_owned()

    $gitlab->projects_owned([...]);

Returns a list of projects owned by the authenticated user.

=item projects_starred()

    $gitlab->projects_starred([...]);

Returns a list of projects starred by the authenticated user.

=item projects_all()

    $gitlab->projects_all([...]);

Returns all projects.
B<This method is available only for administrators.>

=item project_by_id()

    $gitlab->project_by_id( :id );

Returns the project with the given ID, which can be either a number or a string C<"namespace/project_name">.

=item project_events()

    $gitlab->project_events( :id );

Returns the list of events for the given project.

=item projects_search()

    $gitlab->projects_serach( :query, [...] );

Search for projects by name which are accessible to the authenticated user.

=back

=head2 Create, edit and delete projects

=over

=item project_create()

    $gitlab->project_create( :name, [...] );

Creates a new project in the authenticated user's namespace.
Other namespaces can be specified by the optional C<namespace_id> parameter if the user can access it.

=item project_create_for_user()

    $gitlab->project_create_for_user( :uid, :name );

Creates a new project for the user with the given C<uid>.
B<This method is available only for administrators.>

=item project_edit()

    $gitlab->project_edit( :id, [...] );

Edits the project.
Takes the same arguments as L<project_create>, except they are all optional.

=item project_fork()

    $gitlab->project_fork( :id, [:namespace ] );

Forks the project to the authenticated user's namespace or the namespace specified by the C<namespace> as an id or path.

=item project_star()

    $gitlab->project_star( :id );

Stars a given project.
Returns C<304 Not Modified> if already stared.

=item project_unstar()

    $gitlab->project_unstar( :id );

Unstars a given project.
Returns C<304 Not Modified> if not stared.

=item project_archive()

    $gitlab->project_archive( :id );

Archives the given project.
The user must be either an administrator or the owner of the project.

=item project_unarchive()

    $gitlab->project_unarchive( :id );

Unarchives the given project.
The user must be either an administrator or the owner of the project.

=item project_delete()

    $gitlab->project_delete( :id );

Deletes the project with the given C<id>.

=back

=head2 Uploads

=over

=item project_upload_file()

B<NOT SUPPORTED YET>

=back

=head2 Project Members

See L<GitLab::Members> package.

=head2 Hooks

=over

=item project_hooks()

    $gitlab->project_hooks( :id );

Get a list of project hooks.

=item project_get_hook()

    $gitlab->project_get_hook( :id, :hook_id )

Get a specific hook for a project.

=item project_add_hook()

    $gitlab->project_add_hook( :id, :url, [...]);

Adds a hook to a specified project.

=item project_edit_hook()

    $gitlab->project_edit_hook( :id, :hook_id, [...]);

Edits a hook for a specified project.

=item project_delete_hook()

    $gitlab->project_delete_hook( :id, :hook_id );

Removes a hook from a project.
This is an idempotent method and can be called multiple times.

Note the JSON response differs if the hook is available or not.
If the project hook is available before it is returned in the JSON response or an empty response is returned.

=back

=head2 Branches

See L<GitLab::Branches> module.

=head2 Miscellaneous

=over

=item project_create_forked_relationship()

    $gitlab->project_create_forked_relationship( :id :forked_from_id );

Create a I<forked from> relation between existing projects.
B<Available only for admins.>

=item project_delete_forked_relationship()

    $gitlab->project_delete_forked_relationship( :id );

Delete an existing I<forked from> relationship.

=back

=head1 AUTHOR

Roman Lacko <L<xlacko1@fi.muni.cz>>

=head1 SEE ALSO

=over

=item L<GitLab>

Wrapper around L<GitLab::API> and other C<GitLab::*> modules.

=back

pod-GitLab-Projects.md

0 → 100644
+203 −0
Original line number Original line Diff line number Diff line
# NAME

GitLab::Projects - implements projects API calls

See [GitLab API -- Projects](http://doc.gitlab.com/ce/api/projects.html) for details and
response formats.

# VERSION

Implements API calls for GitLab CE `v8.10.0`.
Checked 2016-09-29 for GitLab CE `v8.12.1`.

# DESCRIPTION

## Notation

Please see the documentation for the [GitLab::Users](https://metacpan.org/pod/GitLab::Users) module.

Note that not all optional arguments are listed.
Please refer to the official documentation for the full list.

## Project listing

- projects()

        $gitlab->projects([...]);

    Returns a list of projects accessible to the authenticated user.

- projects\_owned()

        $gitlab->projects_owned([...]);

    Returns a list of projects owned by the authenticated user.

- projects\_starred()

        $gitlab->projects_starred([...]);

    Returns a list of projects starred by the authenticated user.

- projects\_all()

        $gitlab->projects_all([...]);

    Returns all projects.
    **This method is available only for administrators.**

- project\_by\_id()

        $gitlab->project_by_id( :id );

    Returns the project with the given ID, which can be either a number or a string `"namespace/project_name"`.

- project\_events()

        $gitlab->project_events( :id );

    Returns the list of events for the given project.

- projects\_search()

        $gitlab->projects_serach( :query, [...] );

    Search for projects by name which are accessible to the authenticated user.

## Create, edit and delete projects

- project\_create()

        $gitlab->project_create( :name, [...] );

    Creates a new project in the authenticated user's namespace.
    Other namespaces can be specified by the optional `namespace_id` parameter if the user can access it.

- project\_create\_for\_user()

        $gitlab->project_create_for_user( :uid, :name );

    Creates a new project for the user with the given `uid`.
    **This method is available only for administrators.**

- project\_edit()

        $gitlab->project_edit( :id, [...] );

    Edits the project.
    Takes the same arguments as [project\_create](https://metacpan.org/pod/project_create), except they are all optional.

- project\_fork()

        $gitlab->project_fork( :id, [:namespace ] );

    Forks the project to the authenticated user's namespace or the namespace specified by the `namespace` as an id or path.

- project\_star()

        $gitlab->project_star( :id );

    Stars a given project.
    Returns `304 Not Modified` if already stared.

- project\_unstar()

        $gitlab->project_unstar( :id );

    Unstars a given project.
    Returns `304 Not Modified` if not stared.

- project\_archive()

        $gitlab->project_archive( :id );

    Archives the given project.
    The user must be either an administrator or the owner of the project.

- project\_unarchive()

        $gitlab->project_unarchive( :id );

    Unarchives the given project.
    The user must be either an administrator or the owner of the project.

- project\_delete()

        $gitlab->project_delete( :id );

    Deletes the project with the given `id`.

## Uploads

- project\_upload\_file()

    **NOT SUPPORTED YET**

## Project Members

See [GitLab::Members](https://metacpan.org/pod/GitLab::Members) package.

## Hooks

- project\_hooks()

        $gitlab->project_hooks( :id );

    Get a list of project hooks.

- project\_get\_hook()

        $gitlab->project_get_hook( :id, :hook_id )

    Get a specific hook for a project.

- project\_add\_hook()

        $gitlab->project_add_hook( :id, :url, [...]);

    Adds a hook to a specified project.

- project\_edit\_hook()

        $gitlab->project_edit_hook( :id, :hook_id, [...]);

    Edits a hook for a specified project.

- project\_delete\_hook()

        $gitlab->project_delete_hook( :id, :hook_id );

    Removes a hook from a project.
    This is an idempotent method and can be called multiple times.

    Note the JSON response differs if the hook is available or not.
    If the project hook is available before it is returned in the JSON response or an empty response is returned.

## Branches

See [GitLab::Branches](https://metacpan.org/pod/GitLab::Branches) module.

## Miscellaneous

- project\_create\_forked\_relationship()

        $gitlab->project_create_forked_relationship( :id :forked_from_id );

    Create a _forked from_ relation between existing projects.
    **Available only for admins.**

- project\_delete\_forked\_relationship()

        $gitlab->project_delete_forked_relationship( :id );

    Delete an existing _forked from_ relationship.

# AUTHOR

Roman Lacko <[xlacko1@fi.muni.cz](https://metacpan.org/pod/xlacko1@fi.muni.cz)>

# SEE ALSO

- [GitLab](https://metacpan.org/pod/GitLab)

    Wrapper around [GitLab::API](https://metacpan.org/pod/GitLab::API) and other `GitLab::*` modules.
+1 −1

File changed.

Contains only whitespace changes.

+1 −1

File changed.

Contains only whitespace changes.

Loading