#!/usr/bin/perl
our
$VERSION
=
'1.01'
;
sub
PKGBUILD_ERRCODE() { 2 }
sub
NEEDLWP_ERRCODE() { 3 }
sub
COOKIE_NAME() {
'AURSID'
}
sub
CAT_LIB() { 10 };
my
$TT_NAME_PREFIX
=
'# CPAN Name : '
;
my
$BAD_LOGIN_MSG
=
'Bad username or password.'
;
my
$NEED_LOGIN_MSG
=
'You must create an account before you can upload packages.'
;
my
$PKG_EXISTS_MSG
=
qr{You are not allowed to overwrite the <b>.*?</b> package.}
;
my
$CFGPATH
=
"$ENV{HOME}/.cpan2aur"
;
my
$NEED_LOGIN_ERR
=
'Login session was invalid.'
;
my
$PKG_EXISTS_ERR
=
'You tried to submit a package you do not own.'
;
my
(
$DIRECTORY
,
$VERBOSE
,
$UPLOAD
,
$FORCE
,
$HELP
,
$NAME
,
$PASSWD
,
$REVERSE
,
$CHECK
,
$MONO
);
sub
_is_interactive
{
return
-t STDIN && -t STDOUT;
}
sub
prompt_ask
{
my
$question
=
join
q{}
,
@_
;
chomp
$question
;
$question
.=
q{ }
;
local
$OUTPUT_AUTOFLUSH
= 1;
my
$prefix
=
q{ }
x 4;
print
wrap(
$prefix
,
$prefix
,
$question
);
return
undef
if
$FORCE
|| ! _is_interactive();
my
$line
= <STDIN>;
chomp
$line
;
return
$line
;
}
sub
prompt_yn
{
my
(
$question
,
$default
) =
@_
;
$default
||=
'y'
;
my
$first
=
lc
substr
$default
, 0, 1;
$default
= (
$first
eq
'y'
? 1 :
$first
eq
'n'
? 0 : 1 );
chomp
$question
;
$question
.=
q{ }
. (
$default
?
'[Yn]'
:
'[yN]'
);
my
$answer
;
QUESTION: {
$answer
= prompt_ask(
$question
);
if
(
$FORCE
|| !
defined
$answer
) {
printf
"%s\n"
, (
$default
?
'y'
:
'n'
);
return
$default
}
return
$default
if
(
length
$answer
== 0 );
redo
QUESTION
unless
$answer
=~ /\A[yYnN]/;
}
return
0
if
$answer
=~ /\A[nN]/;
return
1;
}
sub
prompt_password
{
my
$termios
= POSIX::Termios->new;
$termios
->getattr( 0 );
my
$c_lflag
=
$termios
->getlflag;
$termios
->setlflag(
$c_lflag
& ~POSIX::ECHO );
$termios
->setattr( 0, POSIX::TCSANOW );
my
$passwd
= prompt_ask(
'Password:'
);
$termios
->setlflag(
$c_lflag
);
$termios
->setattr( 0, POSIX::TCSANOW );
print
"\n"
;
return
$passwd
;
}
sub
_color_wrap
{
my
(
$color
,
$prefix
,
@messages
) =
@_
;
my
$msg
=
join
q{}
,
@messages
;
$msg
=~ s/\s*\n\s*/ /g;
my
$result
= wrap(
$prefix
,
q{ }
x
length
(
$prefix
),
$msg
);
my
$prefix_match
=
quotemeta
$prefix
;
return
$result
if
(
$MONO
);
$result
=~ s{ \A
$prefix_match
}
{ color(
"BOLD $color"
) .
$prefix
.
"\033[0;1m"
}exms;
$result
.= color(
'RESET'
);
return
$result
;
}
sub
msg
{
my
$prefix
=
q{ }
x 4;
print
wrap(
$prefix
,
$prefix
,
join
q{}
,
@_
),
"\n"
;
}
sub
status
{
print
_color_wrap(
'GREEN'
=>
q{==> }
,
@_
),
"\n"
;
}
sub
substatus
{
print
_color_wrap(
'BLUE'
=>
q{ -> }
,
@_
),
"\n"
;
}
sub
warning
{
my
@args
=
@_
;
chomp
$args
[-1];
warn
_color_wrap(
'YELLOW'
=>
q{==> WARNING: }
,
@args
),
"\n"
;
}
sub
error
{
my
@args
=
@_
;
chomp
$args
[-1];
die
_color_wrap(
'RED'
=>
q{==> ERROR: }
,
@args
),
"\n"
;
}
sub
pkgdir
{
my
$dist_obj
=
shift
;
return
$dist_obj
->status->pkgname;
}
sub
pkgdir_file
{
my
(
$dist_obj
,
$file
) =
@_
;
return
catfile( pkgdir(
$dist_obj
),
$file
);
}
sub
find_module
{
my
$mod_or_dist
=
shift
;
our
$CB
||= CPANPLUS::Backend->new;
substatus
"Looking up module for $mod_or_dist on CPAN..."
;
my
$modobj
=
$CB
->parse_module(
module
=>
$mod_or_dist
);
warning(
"Unable to find $mod_or_dist on CPAN"
)
unless
(
$modobj
);
return
$modobj
;
}
sub
confirm_overwrite
{
my
(
$file_path
) =
@_
;
return
1
unless
( -f
$file_path
);
my
$answer
= prompt_yn(
"$file_path already exists, overwrite?"
=>
'yes'
);
return
0
if
(
$answer
== 0 );
unlink
$file_path
or
die
qq{Failed to "rm $file_path": $!}
;
return
1;
}
sub
new_pkgdir_file
{
my
(
$distobj
,
$pkgfile
) =
@_
;
my
$pkgdir
= pkgdir (
$distobj
);
my
$file_path
= pkgdir_file(
$distobj
,
$pkgfile
);
if
( -f
$file_path
) {
return
0
unless
confirm_overwrite(
$file_path
);
return
1;
}
unless
( -d
$pkgdir
) {
mkdir
$pkgdir
or
die
qq{failed to "mkdir $pkgdir": $!}
;
}
return
1;
}
sub
create_dist_arch
{
my
(
$mod_obj
,
$target
) =
@_
;
$mod_obj
->fetch (
verbose
=> 0 ) or
return
0;
$mod_obj
->extract(
verbose
=> 0 ) or
return
0;
my
$dist_obj
=
$mod_obj
->dist(
target
=>
$target
,
format
=>
'CPANPLUS::Dist::Arch'
,
args
=> {
verbose
=>
$VERBOSE
,
pkg
=>
'src'
,
destdir
=> getcwd(),
nocolor
=> (
$MONO
? 1 : 0 ),
})
or
die
"Failed to create CPANPLUS::Dist::Arch object"
;
$dist_obj
->set_tt_init_args(
RELATIVE
=> 1 );
return
$dist_obj
;
}
sub
create_pkgdir_pkg
{
my
$pkgdir
=
shift
;
my
$oldcwd
= getcwd();
chdir
$pkgdir
unless
(
$pkgdir
eq
q{.}
);
status
sprintf
'Creating source package for %s directory...'
,
getcwd();
my
$pkgpath
;
eval
{
tt_to_pkgbuild()
if
( -f
'PKGBUILD.tt'
);
error(
<<'END_ERR' ) unless ( -f 'PKGBUILD' );
There is no PKGBUILD in the directory and no file or module names specified on
the command line. Unable to upload anything.
END_ERR
my
$makepkg_cmd
=
'makepkg --source --force --clean'
;
substatus
qq{Running '$makepkg_cmd'...}
;
my
$output
= `
$makepkg_cmd
2>&1`;
my
@pkginfo
=
$output
=~ /Making
package
: ([\w-]+) ([\d.-]+)/
or error(
"makepkg returned unexpected output: $output"
);
$pkgpath
= (
join
q{-}
,
@pkginfo
) .
'.src.tar.gz'
;
};
chdir
$oldcwd
;
die
$EVAL_ERROR
if
(
$EVAL_ERROR
);
$pkgpath
=
"$pkgdir/$pkgpath"
;
status
"Created $pkgpath source package..."
;
return
$pkgpath
;
}
sub
create_new_pkgdir
{
my
$mod_name
=
shift
;
status
"Creating a new package directory for $mod_name..."
;
my
$mod_obj
= find_module(
$mod_name
) or
return
;
my
$dist_obj
= create_dist_arch(
$mod_obj
,
'prepare'
);
new_tt_file(
$dist_obj
);
status(
sprintf
'Created %s source package directory.'
,
pkgdir(
$dist_obj
));
return
;
}
sub
_load_last_login
{
return
()
unless
( -f
$CFGPATH
);
die
q{Please 'chmod 600 ~/.cpan2aur', it is not readable}
unless
( -r
$CFGPATH
);
open
my
$cfgfile
,
q{<}
,
$CFGPATH
or
die
"open $CFGPATH: $!"
;
my
(
$user
,
$sid
) =
split
/:/, <
$cfgfile
>;
close
$cfgfile
;
return
()
unless
(
$user
&&
$sid
&&
$sid
=~ /\A[A-F0-9]+\Z/ );
return
()
if
(
$NAME
&& (
lc
$user
ne
lc
$NAME
));
chomp
$sid
;
return
(
$user
,
$sid
);
}
sub
_save_last_login
{
my
(
$username
,
$sid
) =
@_
;
my
$oldmask
=
umask
0077;
$username
=
lc
$username
;
open
my
$cfgfile
,
'>'
,
$CFGPATH
or
die
"open $CFGPATH: $!"
;
print
$cfgfile
"$username:$sid\n"
;
close
$cfgfile
or
die
"close $CFGPATH: $!"
;
umask
$oldmask
;
return
;
}
sub
_new_login_sid
{
my
(
$ua
,
$username
,
$passwd
) =
@_
;
$ua
->cookie_jar( HTTP::Cookies->new() );
my
$resp
=
$ua
->post( AUR_LOGIN_URI,
[
user
=>
$username
,
passwd
=>
$passwd
,
remember_me
=> 1,
] );
error(
'Bad username or password'
)
if
(
$resp
->content =~ /
$BAD_LOGIN_MSG
/ );
error( "AUR login expected status code 302.
Got status: ",
$resp
->status_line )
if
!(
$resp
->code == 302 && !
$resp
->is_success );
my
$sid
;
$ua
->cookie_jar()->scan(
sub
{
$sid
=
$_
[2]
if
$_
[1] eq COOKIE_NAME; } );
die
"ERROR Login did not supply us with an AURSID cookie\n"
unless
(
$sid
);
return
$sid
;
}
sub
_mk_session_cookie
{
my
(
$sid
) =
@_
;
my
%cookies
= ( COOKIE_NAME() =>
$sid
,
AURLANG
=>
'en'
, );
my
$cookie_obj
= HTTP::Cookies->new();
for
my
$name
(
keys
%cookies
) {
$cookie_obj
->set_cookie(
q{}
,
$name
,
$cookies
{
$name
},
q{/}
,
'aur.archlinux.org'
);
}
return
$cookie_obj
;
}
sub
_post_upload
{
my
(
$ua
,
$pkg_path
) =
@_
;
my
$resp
=
$ua
->post( AUR_UPLOAD_URI,
'Content-Type'
=>
'form-data'
,
'Content'
=> [
category
=> CAT_LIB(),
submit
=>
'Upload'
,
pkgsubmit
=> 1,
pfile
=> [
$pkg_path
],
] );
return
if
(
$resp
->code() == 302 );
error(
"When uploading file, got http status "
,
$resp
->status_line )
unless
(
$resp
->is_success );
die
$NEED_LOGIN_ERR
if
(
$resp
->content =~ /
$NEED_LOGIN_MSG
/ );
error(
$PKG_EXISTS_ERR
)
if
(
$resp
->content =~ /
$PKG_EXISTS_MSG
/ );
return
;
}
sub
_load_web_modules
{
my
$loaded
=
eval
{
1;
};
unless
(
$loaded
) {
my
$answer
= 1;
$answer
= prompt_yn(
<<'END_PROMPT' => 'yes' );
You need the perl-libwww package installed to upload to the AUR.
Do you want to install it now?
END_PROMPT
exit
NEEDLWP_ERRCODE
unless
(
$answer
);
status
'Installing perl-libwww for uploads to the AUR...'
;
my
$modobj
= find_module(
'LWP'
);
$modobj
->install(
type
=>
'install'
,
format
=>
'CPANPLUS::Dist::Arch'
, );
$loaded
=
eval
{
1;
};
error(
"Unable to load LWP::UserAgent and HTTP::Cookies"
)
unless
$loaded
;
}
return
;
}
sub
upload_pkgfile
{
my
(
$pkg_path
) =
@_
;
_load_web_modules();
status
"Uploading $pkg_path to the AUR..."
;
my
(
$username
,
$sid
) = _load_last_login();
$username
||=
$NAME
|| prompt_ask(
'Username:'
);
if
( !
defined
$username
) {
print
"\n"
;
error(
'Unable to read username in uninteractive mode.'
);
}
my
$ua
= LWP::UserAgent->new();
if
(
$sid
) {
substatus
"Sending package as $username..."
;
$ua
->cookie_jar( _mk_session_cookie(
$sid
));
eval
{ _post_upload(
$ua
,
$pkg_path
) };
unless
(
$EVAL_ERROR
) {
msg
'Success.'
;
return
;
}
die
$EVAL_ERROR
unless
(
$EVAL_ERROR
=~ /
$NEED_LOGIN_ERR
/ );
substatus
'Old session ID failed. Starting new session...'
;
}
my
$passwd
=
$PASSWD
|| prompt_password();
unless
(
defined
$passwd
) {
error(
'Unable to read password in uninteractive mode. '
.
'Upload a file manually first or use the -p option.'
);
}
$sid
= _new_login_sid(
$ua
,
$username
,
$passwd
);
_save_last_login(
$username
,
$sid
);
substatus
"Sending package as $username..."
;
_post_upload(
$ua
,
$pkg_path
);
msg
'Success.'
;
return
;
}
sub
upload_pkgdir
{
my
(
$pkgdir
) =
@_
;
status
"Uploading package directory $pkgdir..."
;
my
$srcpkg_path
= create_pkgdir_pkg(
$pkgdir
);
upload_pkgfile(
$srcpkg_path
);
return
;
}
sub
upload_thing
{
my
(
$thing
) =
@_
;
if
( -d
$thing
) {
upload_pkgdir(
$thing
);
return
;
}
if
( -f
$thing
) {
error(
"$thing file is not named like a source package file."
)
unless
(
$thing
=~ /[.]src[.]tar[.]gz$/ );
upload_pkgfile(
$thing
);
return
;
}
my
$mod_obj
= find_module(
$thing
);
my
$dist_obj
= create_dist_arch(
$mod_obj
);
upload_pkgfile(
$dist_obj
->status->dist );
return
;
}
sub
new_tt_file
{
my
(
$dist_obj
) =
@_
;
substatus(
'Creating new PKGBUILD.tt template file...'
);
error(
'Aborted.'
)
unless
new_pkgdir_file(
$dist_obj
,
'PKGBUILD.tt'
);
open
my
$templ_file
,
'>'
, pkgdir_file(
$dist_obj
,
'PKGBUILD.tt'
)
or
die
"open PKGBUILD.tt failed: $!"
;
print
$templ_file
$TT_NAME_PREFIX
,
$dist_obj
->parent->package_name,
"\n"
;
print
$templ_file
$dist_obj
->get_pkgbuild_templ;
close
$templ_file
or
die
"close PKGBUILD.tt failed: $!"
;
}
sub
pkgbuild_to_tt
{
status
'Reverse-engineering PKGBUILD file to a PKGBUILD.tt template...'
;
error(
<<'END_ERR' ) unless ( -f 'PKGBUILD' );
There is no PKGBUILD in the current directory that we can reverse into a
template.
END_ERR
return
unless
confirm_overwrite(
'PKGBUILD.tt'
);
open
my
$pkgbuild_file
,
'<'
,
'PKGBUILD'
or
die
"open PKGBUILD: $!"
;
my
$pkgbuild_txt
=
do
{
local
$/; <
$pkgbuild_file
> };
close
$pkgbuild_file
;
my
(
$distname
) =
$pkgbuild_txt
=~ m{^ source = \s* [^\n]* / ( [-\w]+ ) -\d }xms;
error(
"Failed to determine the distribution name from the "
.
"existing PKGBUILD"
)
unless
(
$distname
);
$pkgbuild_txt
=~ s{^
$TT_NAME_PREFIX
.*?\n}{}ms;
$pkgbuild_txt
=~ s{^
$pkgbuild_txt
=~ s{^
{
my
$var_match
=
join
'|'
,
qw/ pkgname pkgver pkgdesc url source md5sums source /
;
$pkgbuild_txt
=~ s{(
$var_match
) = \s* [
"] .*? [^\\] ["
] }
{$1=
"\[% $1 \%]"
}gxms;
$pkgbuild_txt
=~ s{(
$var_match
) = \s* [
'] .*? ['
] }
{$1=
'\[% $1 \%]'
}gxms;
$pkgbuild_txt
=~ s{(
$var_match
) = \s* [(][
'] .*? ['
][)] }
{$1=(
'\[% $1 \%]'
)}gxms;
$pkgbuild_txt
=~ s{(
$var_match
) = \s* [(][
"] .*? [^\\] ["
][)] }
{$1=(
"\[% $1 \%]"
)}gxms;
$pkgbuild_txt
=~ s{ ^depends = \s* [(] (.*?) [)] }
{ (
sprintf
q{depends=([%% depends %%]%s)}
,
map
{
$_
?
" $_"
:
q{}
}
join
q{ }
,
grep
{ !/perl/ }
split
/\s+/, $1 ) }xmse;
$pkgbuild_txt
=~ s{(DIST_|_DIST)DIR=
".*?"
}{DIST_DIR=
"\${srcdir}/[% distdir %]"
};
$pkgbuild_txt
=~ s{\
$_DISTDIR
}{\
$DIST_DIR
}g;
open
my
$templ_file
,
'>'
,
'PKGBUILD.tt'
or
die
"open PKGBUILD.tt: $!"
;
print
$templ_file
$TT_NAME_PREFIX
,
$distname
,
"\n"
;
print
$templ_file
$pkgbuild_txt
;
close
$templ_file
;
substatus
"Success."
;
return
;
}
sub
tt_to_pkgbuild
{
substatus
"Converting PKGBUILD.tt template to PKGBUILD..."
;
my
%old_info
;
if
( -f
'PKGBUILD'
) {
open
my
$pkgbuild_file
,
'<'
,
'PKGBUILD'
or
die
"open PKGBUILD: $!"
;
my
$pkgbuild_txt
=
do
{
local
$/; <
$pkgbuild_file
> };
close
$pkgbuild_file
;
%old_info
= get_pkgbuild_info(
$pkgbuild_txt
);
unless
( confirm_overwrite(
'PKGBUILD'
)) {
warning(
'Skipping template and doing a simple re-package...'
);
return
;
}
}
open
my
$templ_file
,
'<'
,
'PKGBUILD.tt'
or
die
"open PKGBUILD.tt: $!"
;
my
$templ_text
=
do
{
local
$/; <
$templ_file
> };
close
$templ_file
or
die
"close PKGBUILD.tt: $!"
;
$templ_text
=~ s/ [[] % \s* FI \s* % []] /[% END %]/gxms;
my
(
$distname
) =
$templ_text
=~ /^
$TT_NAME_PREFIX
(.*)$/m;
error(
qq{"$TT_NAME_PREFIX" line is missing from the
PKGBUILD.tt template. This template file may not have been generated by
cpan2aur.
In order to use this .tt file with cpan2aur, insert the CPAN distribution's
name into the file prefixed with the above comment in quotes.
}
)
unless
(
$distname
);
my
$modobj
= find_module(
$distname
);
my
$distobj
= create_dist_arch(
$modobj
=>
'prepare'
);
REL_CHECK:
{
last
REL_CHECK
unless
(
$old_info
{pkgver} );
my
$old_ver
= version->new(
$old_info
{pkgver} );
my
$new_ver
= version->new(
$distobj
->get_pkgver );
last
REL_CHECK
unless
(
$old_ver
==
$new_ver
);
my
$new_pkgrel
=
$old_info
{pkgrel} + 1;
my
$answer
= prompt_yn(
<<"END_QUESTION" => 'no' );
A PKGBUILD already exists for this version ($new_ver).
Would you like to increment the pkgrel to $new_pkgrel?
END_QUESTION
$distobj
->set_pkgrel(
$answer
?
$new_pkgrel
:
$old_info
{pkgrel} );
}
$distobj
->set_pkgbuild_templ(
$templ_text
);
$distobj
->create_pkgbuild(
q{.}
);
return
$distobj
;
}
sub
get_pkgbuild_info
{
my
(
$pkgbuild_txt
) =
@_
;
my
(
$dist_name
,
$dist_ver
) =
$pkgbuild_txt
=~ m{ DIST_DIR=
"\${srcdir}/ ( [\w-]+ ) - ( [\d.]+ ) /? "
}xms;
my
(
$pkgrel
) =
$pkgbuild_txt
=~ m{ ^ pkgrel = [
'"]? ( \d+ ) ['
"]? }xms;
my
(
$pkgver
) =
$pkgbuild_txt
=~ m{ ^ pkgver = ['"]? ( [-._0-9]+ ) }xms;
return
(
dist_name
=>
$dist_name
,
dist_ver
=>
$dist_ver
,
pkgrel
=>
$pkgrel
,
pkgver
=>
$pkgver
,
);
}
sub
get_pkgfile_info
{
my
(
$pkg_path
) =
@_
;
my
(
$pkg_filename
) =
reverse
splitpath(
$pkg_path
);
my
(
$pkg_name
) =
$pkg_filename
=~ / \A ( [\w-]+ ) - \d /xms;
my
$pkg_file
= Archive::Tar->new(
$pkg_path
)
or
die
"Failed to open $pkg_path source package file."
;
error(
"$pkg_path does not contain the $pkg_name/PKGBUILD file."
)
unless
$pkg_file
->contains_file(
"$pkg_name/PKGBUILD"
);
my
$pkgbuild
=
$pkg_file
->get_content(
"$pkg_name/PKGBUILD"
);
my
%info
= get_pkgbuild_info(
$pkgbuild
);
error(
<<"END_ERROR" ) unless ( $info{dist_name} );
${pkg_path}'s PKGBUILD does not seem to be made by cpan2aur.
We are unable to extract the CPAN distribution name from it.
END_ERROR
return
%info
;
}
sub
pkgdir_srcpkg
{
my
(
$pkg_dir
) =
@_
;
my
(
$pkg_name
) =
reverse
splitdir(
$pkg_dir
)
or error(
"Failed to extract pkgname from dir $pkg_dir"
);
my
(
$src_pkgpath
) =
reverse
sort
glob
"$pkg_dir/$pkg_name-*.src.tar.gz"
;
return
$src_pkgpath
;
}
sub
get_pkgdir_info
{
my
(
$pkg_dir
) =
@_
;
my
$srcpkg
= pkgdir_srcpkg(
$pkg_dir
);
return
get_pkgfile_info(
$srcpkg
)
if
(
$srcpkg
);
error(
"$pkg_dir does not contain a PKGBUILD or source package file."
)
unless
( -f
"$pkg_dir/PKGBUILD"
);
open
my
$pkgbuild_file
,
'<'
,
"$pkg_dir/PKGBUILD"
or
die
"open $pkg_dir/PKGBUILD: $!"
;
my
$pkgbuild
=
do
{
local
$/; <
$pkgbuild_file
> };
close
$pkgbuild_file
;
my
%info
= get_pkgbuild_info(
$pkgbuild
);
error(
<<'END_ERROR' ) unless ( $info{dist_name} );
$pkg_dir/PKGBUILD does not seem to be made by cpan2aur.
We are unable to extract the CPAN distribution name from it.
END_ERROR
return
%info
;
}
sub
update_if_old
{
my
(
$thing
) =
@_
;
status
"Checking if $thing is up to date..."
;
my
$type
= ( -f
$thing
?
'file'
: -d
$thing
?
'dir'
:
undef
);
unless
(
$type
) {
error(
<<"END_ERROR" );
$thing does not seem to be a source package file or directory!
END_ERROR
}
my
%pkg_info
= (
$type
eq
'file'
? get_pkgfile_info(
$thing
) :
$type
eq
'dir'
? get_pkgdir_info(
$thing
) :
die
);
my
$mod_obj
= find_module(
$pkg_info
{ dist_name } );
return
unless
(
$mod_obj
);
my
$cpan_ver
= version->new( dist_pkgver(
$mod_obj
->package_version ));
my
$dist_ver
= version->new(
$pkg_info
{ dist_ver } );
if
(
$cpan_ver
<
$dist_ver
) {
error(
<<"END_WARN" );
CPAN version $cpan_ver is less than package version $dist_ver!
END_WARN
}
elsif
(
$cpan_ver
==
$dist_ver
) {
msg
"$thing is up to date."
;
return
;
}
if
(
$type
eq
'file'
) {
my
$dist_obj
= create_dist_arch(
$mod_obj
=>
'create'
);
my
$pkg_path
=
$dist_obj
->status->dist
or
die
'Unable to find path of created source package'
;
if
( prompt_yn(
'Delete the old package file?'
=>
'yes'
)) {
status
"Deleting old package file: $thing"
;
unlink
$thing
or warning(
"Failed to delete $thing ($!)"
);
}
upload_pkgfile(
$pkg_path
);
return
;
}
upload_pkgdir(
$thing
);
return
;
}
GetOptions(
'directory'
=> \
$DIRECTORY
,
'verbose'
=> \
$VERBOSE
,
'reverse'
=> \
$REVERSE
,
'upload'
=> \
$UPLOAD
,
'force'
=> \
$FORCE
,
'check'
=> \
$CHECK
,
'name=s'
=> \
$NAME
,
'pass=s'
=> \
$PASSWD
,
'mono'
=> \
$MONO
,
'help'
=> \
$HELP
,
);
$VERBOSE
||= 0;
pod2usage(
-message
=>
'-u[pload] and -d[irectory cannot be used together'
)
if
(
$UPLOAD
&&
$DIRECTORY
);
pod2usage(
-message
=>
'The -r[everse] flag must be used by itself.'
)
if
(
$REVERSE
&& (
$UPLOAD
||
$DIRECTORY
));
pod2usage(
-verbose
=> 1 )
if
(
$HELP
);
if
(
$REVERSE
) {
pkgbuild_to_tt();
exit
0;
}
if
(
$UPLOAD
&& !
@ARGV
) {
push
@ARGV
,
q{.}
;
}
pod2usage(
-verbose
=> 0 )
unless
(
@ARGV
);
my
@flagacts
= ( [
sub
{
$CHECK
}, \
&update_if_old
],
[
sub
{
$UPLOAD
}, \
&upload_thing
],
[
sub
{
$DIRECTORY
}, \
&create_new_pkgdir
],
[
sub
{ -d
shift
}, \
&create_pkgdir_pkg
],
);
sub
find_action
{
my
$thing
=
shift
;
my
$match
= first {
$_
->[0]->(
$thing
) }
@flagacts
;
return
$match
->[1];
}
ARG_LOOP:
for
my
$arg
(
@ARGV
) {
my
$action
= find_action(
$arg
);
if
(
$action
) {
eval
{
$action
->(
$arg
) };
print
$EVAL_ERROR
if
(
$EVAL_ERROR
);
next
ARG_LOOP;
}
status(
'Creating new source package for '
.
$arg
.
'...'
);
my
$modobj
= find_module(
$arg
) or
next
ARG_LOOP;
my
$distobj
= create_dist_arch(
$modobj
, (
$DIRECTORY
?
'prepare'
:
'create'
))
or
die
'Failed to create CPANPLUS::Dist::Arch object'
;
}