—————————package
GitLab::API::v4::Config;
our
$VERSION
=
'0.27'
;
=encoding utf8
=head1 NAME
GitLab::API::v4::Config - Load configuration from a file, environment,
and/or CLI options.
=head1 SYNOPSIS
use GitLab::API::v4;
use GitLab::API::v4::Config;
my $config = GitLab::API::v4::Config->new();
my $api = GitLab::API::v4->new( $config->args() );
=head1 DESCRIPTION
This module is used by L<gitlab-api-v4> to load configuration.
If you are using L<GitLab::API::v4> directly then this module will not be
automatically used, but you are welcome to explicitly use it as shown in the
L</SYNOPSIS>.
=cut
use
Getopt::Long;
use
IO::Prompter;
use
JSON::MaybeXS;
use
Path::Tiny;
use
Types::Common::String -types;
use
Types::Standard -types;
use
Moo;
use
strictures 2;
use
namespace::clean;
sub
_filter_args {
my
(
$self
,
$args
) =
@_
;
return
{
map
{
$_
=>
$args
->{
$_
} }
grep
{
$args
->{
$_
} }
keys
%$args
};
}
=head1 ARGUMENTS
=head2 file
The file to load configuration from. The file should hold valid JSON.
By default this will be set to C<.gitlab-api-v4-config> in the current
user's home directory.
This can be overridden with the C<GITLAB_API_V4_CONFIG_FILE> environment
variable or the C<--config-file=...> command line argument.
=cut
has
file
=> (
is
=>
'lazy'
,
isa
=> NonEmptySimpleStr,
);
sub
_build_file {
my
(
$self
) =
@_
;
my
$file
=
$self
->opt_args->{config_file}
||
$self
->env_args->{config_file};
return
$file
if
$file
;
my
(
$home
) = (
getpwuid
($<) )[7];
return
''
. path(
$home
)->child(
'.gitlab-api-v4-config'
);
}
=head1 ATTRIBUTES
=head2 opt_args
Returns a hashref of arguments derived from command line options.
Supported options are:
--config_file=...
--url=...
--private-token=...
--access-token=...
--retries=...
Note that the options are read from, and removed from, C<@ARGV>. Due
to this the arguments are saved internally and re-used for all instances
of this class so that there are no weird race conditions.
=cut
has
opt_args
=> (
is
=>
'rwp'
,
isa
=> HashRef,
default
=>
sub
{ {} },
);
=head2 env_args
Returns a hashref of arguments derived from environment variables.
Supported environment variables are:
GITLAB_API_V4_CONFIG_FILE
GITLAB_API_V4_URL
GITLAB_API_V4_PRIVATE_TOKEN
GITLAB_API_V4_ACCESS_TOKEN
GITLAB_API_V4_RETRIES
=cut
has
env_args
=> (
is
=>
'lazy'
,
isa
=> HashRef,
);
sub
_build_env_args {
my
(
$self
) =
@_
;
return
$self
->_filter_args({
config_file
=>
$ENV
{GITLAB_API_V4_CONFIG_FILE},
url
=>
$ENV
{GITLAB_API_V4_URL},
private_token
=>
$ENV
{GITLAB_API_V4_PRIVATE_TOKEN},
access_token
=>
$ENV
{GITLAB_API_V4_ACCESS_TOKEN},
retries
=>
$ENV
{GITLAB_API_V4_RETRIES},
});
}
=head2 file_args
Returns a hashref of arguments gotten by decoding the JSON in the L</file>.
=cut
has
file_args
=> (
is
=>
'lazy'
,
isa
=> HashRef,
);
sub
_build_file_args {
my
(
$self
) =
@_
;
my
$file
=
$self
->file();
return
{}
if
!-r
$file
;
$file
= path(
$file
);
$log
->debugf(
'Loading configuration for GitLab::API::v4 from: %s'
,
$file
->absolute() );
my
$json
=
$file
->slurp();
my
$data
= decode_json(
$json
);
return
$self
->_filter_args(
$data
);
}
=head2 args
Returns a final, combined, hashref of arguments containing everything in
L</opt_args>, L</env_args>, and L</file_args>. If there are any duplicate
arguments then L</opt_args> has highest precedence, L</env_args> is next, and
at the bottom is L</file_args>.
=cut
sub
args {
my
(
$self
) =
@_
;
return
{
%{
$self
->file_args() },
%{
$self
->env_args() },
%{
$self
->opt_args() },
};
}
=head1 METHODS
=head2 get_options
=cut
sub
get_options {
my
(
$self
,
@extra
) =
@_
;
Getopt::Long::Configure(
qw(
gnu_getopt no_ignore_case
)
);
my
$opt_args
= {};
GetOptions(
'config-file=s'
=> \
$opt_args
->{config_file},
'url=s'
=> \
$opt_args
->{url},
'private-token=s'
=> \
$opt_args
->{private_token},
'access-token=s'
=> \
$opt_args
->{access_token},
'retries=i'
=> \
$opt_args
->{retries},
@extra
,
) or
die
(
'Unable to process options!'
);
$opt_args
=
$self
->_filter_args(
$opt_args
);
$self
->_set_opt_args(
$opt_args
);
return
;
}
=head2 configure
When called this method interactively prompts the user for argument values
and then encodes them as JSON and stores them in L</file>. The file will
be chmod'ed C<0600> so that only the current user may read or write to the
file.
=cut
sub
configure {
my
(
$self
) =
@_
;
my
$url
= prompt(
'Full URL to a v4 GitLab API:'
,
'-stdio'
,
'-verbatim'
,
);
my
$private_token
= prompt(
'Private Token:'
,
-echo
=>
''
,
'-stdio'
,
'-verbatim'
,
);
my
$access_token
= prompt(
'Access Token:'
,
-echo
=>
''
,
'-stdio'
,
'-verbatim'
,
);
my
$json
= JSON::MaybeXS->new(
pretty
=> 1,
canonical
=> 1)
->encode({
$url
? (
url
=>
$url
) : (),
$private_token
? (
private_token
=>
$private_token
) : (),
$access_token
? (
access_token
=>
$access_token
) : (),
});
my
$file
= path(
$self
->file() );
$file
->touch();
$file
->
chmod
( 0600 );
$file
->append( {
truncate
=>1},
$json
);
$log
->infof(
'Configuration for GitLab::API::v4 saved to: %s'
,
$file
->absolute() );
return
;
}
1;
__END__
=head1 SUPPORT
See L<GitLab::API::v4/SUPPORT>.
=head1 AUTHORS
See L<GitLab::API::v4/AUTHORS>.
=head1 LICENSE
See L<GitLab::API::v4/LICENSE>.
=cut