App-pause
view release on metacpan or search on metacpan
script/pause view on Meta::CPAN
#!perl
### begin code_after_shebang
### end code_after_shebang
# PERICMD_INLINE_SCRIPT: {"code_add_extra_log_outputs":"...","code_before_enable_logging":"...","config_filename":["pause.conf"],"env_name":"PAUSE_OPT","include":[],"log":1,"pack_deps":0,"pod":0,"read_config":1,"read_env":1,"script_name":"pause","scr...
# This script is generated by Perinci::CmdLine::Inline version 0.554 on Mon Feb 24 11:35:30 2025.
# Rinci metadata taken from these modules: WWW::PAUSE::Simple 0.457
# You probably should not manually edit this file.
## no critic: TestingAndDebugging::RequireUseStrict
# PODNAME: pause
# ABSTRACT: A CLI for PAUSE
package main;
use 5.010001;
use strict;
#use warnings;
# load modules
### declare global variables
our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2025-05-15'; # DATE
our $DIST = 'App-pause'; # DIST
our $VERSION = '0.662'; # VERSION
my $_pci_metas = do{my$var={cleanup=>{args=>{detail=>{cmdline_aliases=>{l=>{}},schema=>["bool",{}],summary=>"Whether to return detailed records"},exclude_dists=>{schema=>["array",{of=>["str",{req=>1}],req=>1}],summary=>"Exclude specified distribution...
our $_pci_log_outputs = {};
our $_pci_meta_result_stream = 0;
our $_pci_meta_result_type;
our $_pci_meta_result_type_is_simple;
our $_pci_meta_skip_format = 0;
our $_pci_r = {naked_res=>0,read_config=>1,read_env=>1,subcommand_name=>""};
our %_pci_args;
### begin code_before_enable_logging
require Log::ger::Layout::JSON;
### end code_before_enable_logging
### enable logging
$_pci_log_outputs->{Screen} = { conf => { colorize_tags => 1, formatter => sub { "pause: " . $_[0] } } };
#### begin code_add_extra_log_outputs
$_pci_log_outputs->{Screen}{category_level}{_access} = "off"; $_pci_log_outputs->{SimpleFile} = {conf=>{path => ($ENV{HOME} || ".")."/pause-access.log"}, level=>"off", layout=>[JSON=>{}], category_level=>{_access=>"info"}};
#### end code_add_extra_log_outputs
require Log::ger::Output; Log::ger::Output->set("Composite", outputs => $_pci_log_outputs);
require Log::ger; Log::ger->import;
### begin code_after_enable_logging
### end code_after_enable_logging
### declare subroutines
sub _pci_err {
my $res = shift;
print STDERR "ERROR $res->[0]: $res->[1]\n";
exit $res->[0]-300;
}
sub _pci_json {
state $json = do {
if (eval { require JSON::XS; 1 }) { JSON::XS->new->canonical(1)->allow_nonref }
else { require JSON::PP; JSON::PP->new->canonical(1)->allow_nonref }
};
$json;
}
### begin code_before_parse_cmdline_options
### end code_before_parse_cmdline_options
### get arguments (from config file, env, command-line args
{
my %mentioned_args;
require Getopt::Long::EvenLess;
log_trace("Parsing command-line arguments ...");
require Getopt::Long::Subcommand;
my $help_msg = "pause - A CLI for PAUSE\n\nUsage:\n pause --help (or -h, -?)\n pause --subcommands\n pause --version (or -v)\n pause [--cmd=subcommand_name] [(--config-path=path)+|--no-config]\n [--config-profile=profile] [--debug] [--format=n...
my $go_spec1 = {
'cmd=s' => sub { $_[2]{subcommand} = [$_[1]]; $_pci_r->{subcommand_name} = $_[1]; },
'config-path=s@' => sub { $_pci_r->{config_paths} //= []; push @{ $_pci_r->{config_paths} }, $_[1]; },
'config-profile=s' => sub { $_pci_r->{config_profile} = $_[1]; },
'debug' => sub { require Log::ger::Util; Log::ger::Util::set_level("debug"); $_pci_r->{log_level} = "debug"; },
'format=s' => sub { $_pci_r->{format} = $_[1]; },
'help|h|?' => sub { my $sc_name = $_pci_r->{subcommand_name}; my $first_non_opt_arg; for (@ARGV) { next if /^-/; $first_non_opt_arg = $_; last } if (!length $sc_name && defined $first_non_opt_arg) { $sc_name = $first_non_opt_arg } if (!length $sc_n...
'json' => sub { $_pci_r->{format} = (-t STDOUT) ? "json-pretty" : "json"; ## no critic InputOutput::ProhibitInteractiveTest
},
'log-level=s' => sub { if ($_[1] eq "trace") { require Log::ger::Util; Log::ger::Util::set_level("trace"); Log::ger::Output::Composite::set_level("trace") } if ($_[1] eq "debug") { require Log::ger::Util; Log::ger::Util::set_level("debug"); Log::ge...
'naked-res' => sub { $_pci_r->{naked_res} = 1; },
'no-config' => sub { $_pci_r->{read_config} = 0; },
'no-env' => sub { $_pci_r->{read_env} = 0; },
'no-naked-res|nonaked-res' => sub { $_pci_r->{naked_res} = 0; },
'page-result:s' => sub { $_pci_r->{page_result} = 1; },
'quiet' => sub { require Log::ger::Util; Log::ger::Util::set_level("error"); $_pci_r->{log_level} = "error"; },
'subcommands' => sub { print "Available subcommands:\n cleanup\n ls\n ls-dists\n ls-mods\n reindex\n rm\n undelete\n upload\n"; exit 0 },
'trace' => sub { require Log::ger::Util; Log::ger::Util::set_level("trace"); $_pci_r->{log_level} = "trace"; },
'verbose' => sub { require Log::ger::Util; Log::ger::Util::set_level("info" ); $_pci_r->{log_level} = "info" ; },
'version|v' => sub { no warnings 'once'; require WWW::PAUSE::Simple; print "pause version ", $main::VERSION // '?', ($main::DATE ? " ($main::DATE)" : ''), "\n"; print " Generated by Perinci::CmdLine::Inline version 0.554 (2022-01-16)\n"; exit 0 },
};
my $go_spec2 = {
options => {
'cmd=s' => {
handler => sub { $_[2]{subcommand} = [$_[1]]; $_pci_r->{subcommand_name} = $_[1]; },
},
'config-path=s@' => {
handler => sub {},
},
'config-profile=s' => {
handler => sub {},
},
'debug' => {
handler => sub {},
},
'format=s' => {
handler => sub {},
},
'help|h|?' => {
handler => sub {},
},
'json' => {
handler => sub {},
},
'log-level=s' => {
handler => sub {},
},
'naked-res' => {
handler => sub {},
},
'no-config' => {
handler => sub {},
},
'no-env' => {
handler => sub {},
},
'no-naked-res|nonaked-res' => {
handler => sub {},
},
'page-result:s' => {
handler => sub {},
},
'quiet' => {
handler => sub {},
},
'subcommands' => {
handler => sub {},
},
'trace' => {
handler => sub {},
},
'verbose' => {
handler => sub {},
},
'version|v' => {
handler => sub {},
},
script/pause view on Meta::CPAN
handler => sub { if ($mentioned_args{'files'}++) { push @{ $_pci_args{'files'} }, $_[1] } else { $_pci_args{'files'} = [$_[1]] } },
},
'files-json=s' => {
handler => sub { $_pci_args{'files'} = _pci_json()->decode($_[1]); },
},
'password=s' => {
handler => sub { $_pci_args{'password'} = $_[1]; },
},
'retries=s' => {
handler => sub { $_pci_args{'retries'} = $_[1]; },
},
'username=s' => {
handler => sub { $_pci_args{'username'} = $_[1]; },
},
},
},
'rm' => {
options => {
'file=s@' => {
handler => sub { if ($mentioned_args{'files'}++) { push @{ $_pci_args{'files'} }, $_[1] } else { $_pci_args{'files'} = [$_[1]] } },
},
'files-json=s' => {
handler => sub { $_pci_args{'files'} = _pci_json()->decode($_[1]); },
},
'password=s' => {
handler => sub { $_pci_args{'password'} = $_[1]; },
},
'protect-file=s@' => {
handler => sub { if ($mentioned_args{'protect_files'}++) { push @{ $_pci_args{'protect_files'} }, $_[1] } else { $_pci_args{'protect_files'} = [$_[1]] } },
},
'protect-files-json=s' => {
handler => sub { $_pci_args{'protect_files'} = _pci_json()->decode($_[1]); },
},
'retries=s' => {
handler => sub { $_pci_args{'retries'} = $_[1]; },
},
'username=s' => {
handler => sub { $_pci_args{'username'} = $_[1]; },
},
},
},
'undelete' => {
options => {
'file=s@' => {
handler => sub { if ($mentioned_args{'files'}++) { push @{ $_pci_args{'files'} }, $_[1] } else { $_pci_args{'files'} = [$_[1]] } },
},
'files-json=s' => {
handler => sub { $_pci_args{'files'} = _pci_json()->decode($_[1]); },
},
'password=s' => {
handler => sub { $_pci_args{'password'} = $_[1]; },
},
'retries=s' => {
handler => sub { $_pci_args{'retries'} = $_[1]; },
},
'username=s' => {
handler => sub { $_pci_args{'username'} = $_[1]; },
},
},
},
'upload' => {
options => {
'delay=s' => {
handler => sub { $_pci_args{'delay'} = $_[1]; },
},
'file=s@' => {
handler => sub { if ($mentioned_args{'files'}++) { push @{ $_pci_args{'files'} }, $_[1] } else { $_pci_args{'files'} = [$_[1]] } },
},
'files-json=s' => {
handler => sub { $_pci_args{'files'} = _pci_json()->decode($_[1]); },
},
'password=s' => {
handler => sub { $_pci_args{'password'} = $_[1]; },
},
'retries=s' => {
handler => sub { $_pci_args{'retries'} = $_[1]; },
},
'subdir=s' => {
handler => sub { $_pci_args{'subdir'} = $_[1]; },
},
'username=s' => {
handler => sub { $_pci_args{'username'} = $_[1]; },
},
},
},
},
default_subcommand => undef,
};
{
local @ARGV = @ARGV;
my $old_conf = Getopt::Long::EvenLess::Configure("pass_through");
Getopt::Long::EvenLess::GetOptions(%$go_spec1);
Getopt::Long::EvenLess::Configure($old_conf);
{ my $first_non_opt_arg; for (@ARGV) { next if /^-/; $first_non_opt_arg = $_; last } if (!length $_pci_r->{subcommand_name} && defined $first_non_opt_arg) { $_pci_r->{subcommand_name} = $first_non_opt_arg } }
}
{
last unless $_pci_r->{read_env};
my $env = $ENV{"PAUSE_OPT"};
last unless defined $env;
require Complete::Bash;
my ($words, undef) = @{ Complete::Bash::parse_cmdline($env, 0) };
unshift @ARGV, @$words;
}
if ($_pci_r->{read_config}) {
log_trace("Reading config file(s) ...");
require Perinci::CmdLine::Util::Config;
my $res = Perinci::CmdLine::Util::Config::read_config(
config_paths => $_pci_r->{config_paths},
config_filename => ["pause.conf"],
config_dirs => undef // ["$ENV{HOME}/.config", $ENV{HOME}, "/etc"],
program_name => "pause",
);
_pci_err($res) unless $res->[0] == 200;
$_pci_r->{config} = $res->[2];
$_pci_r->{read_config_files} = $res->[3]{"func.read_files"};
$_pci_r->{_config_section_read_order} = $res->[3]{"func.section_read_order"}; # we currently dont want to publish this request key
$res = Perinci::CmdLine::Util::Config::get_args_from_config(
r => $_pci_r,
config => $_pci_r->{config},
script/pause view on Meta::CPAN
my $res = Getopt::Long::Subcommand::GetOptions(%$go_spec2);
_pci_err([500, "GetOptions failed"]) unless $res->{success};
if (!length $_pci_r->{subcommand_name}) { print $help_msg; exit 0 }
}
### check arguments
{
my $res = _pci_check_args(\%_pci_args);
_pci_err($res) if $res->[0] != 200;
$_pci_r->{args} = \%_pci_args;
}
### call function
{
log_trace("Calling function ...");
my $sc_name = $_pci_r->{subcommand_name};
if ($sc_name eq "cleanup") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::delete_old_releases(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
elsif ($sc_name eq "ls") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::list_files(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
elsif ($sc_name eq "ls-dists") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::list_dists(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
elsif ($sc_name eq "ls-mods") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::list_modules(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
elsif ($sc_name eq "reindex") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::reindex_files(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
elsif ($sc_name eq "rm") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::delete_files(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
elsif ($sc_name eq "undelete") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::undelete_files(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
elsif ($sc_name eq "upload") {
$_pci_meta_result_type = "";
require WWW::PAUSE::Simple;
eval { $_pci_r->{res} = WWW::PAUSE::Simple::upload_files(%_pci_args) };
if ($@) { die if $ENV{PERINCI_CMDLINE_INLINE_DEBUG_DIE}; $_pci_r->{res} = [500, "Function died: $@"] }
}
}
### format & display result
{
log_trace("Displaying result ...");
my $fh;
if ($_pci_r->{page_result} // $ENV{PAGE_RESULT} // $_pci_r->{res}[3]{"cmdline.page_result"}) {
my $pager = $_pci_r->{pager} // $_pci_r->{res}[3]{"cmdline.pager"} // $ENV{PAGER} // "less -FRSX";
open $fh, "| $pager"; ## no critic InputOutput::ProhibitTwoArgOpen
} else {
$fh = \*STDOUT;
}
my $fres;
my $save_res; if (exists $_pci_r->{res}[3]{"cmdline.result"}) { $save_res = $_pci_r->{res}[2]; $_pci_r->{res}[2] = $_pci_r->{res}[3]{"cmdline.result"} }
my $is_success = $_pci_r->{res}[0] =~ /\A2/ || $_pci_r->{res}[0] == 304;
my $is_stream = $_pci_r->{res}[3]{stream} // $_pci_meta_result_stream // 0;
if ($is_success && (0 || $_pci_meta_skip_format || $_pci_r->{res}[3]{"cmdline.skip_format"})) { $fres = $_pci_r->{res}[2] }
elsif ($is_success && $is_stream) {}
else { require Perinci::Result::Format::Lite; $is_stream=0; $fres = Perinci::Result::Format::Lite::format($_pci_r->{res}, ($_pci_r->{format} // $_pci_r->{res}[3]{"cmdline.default_format"} // "text"), $_pci_r->{naked_res}, 0) }
my $use_utf8 = $_pci_r->{res}[3]{"x.hint.result_binary"} ? 0 : 0;
if ($use_utf8) { binmode STDOUT, ":encoding(utf8)" }
if ($is_stream) {
my $code = $_pci_r->{res}[2]; if (ref($code) ne "CODE") { die "Result is a stream but no coderef provided" } if ($_pci_meta_result_type_is_simple) { while(defined(my $l=$code->())) { print $fh $l; print $fh "\n" unless $_pci_meta_result_type eq "...
} else {
print $fh $fres;
}
if (defined $save_res) { $_pci_r->{res}[2] = $save_res }
}
### exit
{
my $status = $_pci_r->{res}[0];
my $exit_code = $_pci_r->{res}[3]{"cmdline.exit_code"} // ($status =~ /200|304/ ? 0 : ($status-300));
exit($exit_code);
}
# BEGIN Local::_pci_check_args
sub _pci_check_args {
my ($args) = @_;
my $sc_name = $_pci_r->{subcommand_name};
if ($sc_name eq "cleanup") {
FILL_FROM_POS: {
1;
}
my @check_argv = @ARGV;
# fill from cmdline_src
# fill defaults from "default" property and check against schema
no warnings ('void');
require List::Util;
require Scalar::Util::Numeric::PP;
my $_sahv_dpath;
my $_sahv_err;
if (exists $args->{"detail"}) {
$_sahv_dpath = [];
script/pause view on Meta::CPAN
&&
# check type 'str'
((!ref($args->{"files"}->[$_])) ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Not of type text"),0))
)}, 0..@{$args->{"files"}}-1))) ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Not of type text"),0))), pop(@{$_sahv_dpath})]->[1])
; if ($_sahv_err) { return [400, "Argument validation failed: $_sahv_err"] }
} # if date arg exists
if (exists $args->{"password"}) {
$_sahv_dpath = [];
# req #0
((defined($args->{"password"})) ? 1 : (($_sahv_err //= "Required but not specified"),0))
&&
# check type 'str'
((!ref($args->{"password"})) ? 1 : (($_sahv_err //= "Not of type text"),0))
; if ($_sahv_err) { return [400, "Argument validation failed: $_sahv_err"] }
} # if date arg exists
$args->{"retries"} //= 5;
if (exists $args->{"retries"}) {
$_sahv_dpath = [];
# req #0
((defined($args->{"retries"})) ? 1 : (($_sahv_err //= "Required but not specified"),0))
&&
# check type 'int'
((Scalar::Util::Numeric::PP::isint($args->{"retries"})) ? 1 : (($_sahv_err //= "Not of type integer"),0))
; if ($_sahv_err) { return [400, "Argument validation failed: $_sahv_err"] }
} # if date arg exists
if (exists $args->{"username"}) {
$_sahv_dpath = [];
# req #0
((defined($args->{"username"})) ? 1 : (($_sahv_err //= "Required but not specified"),0))
&&
# check type 'str'
((!ref($args->{"username"})) ? 1 : (($_sahv_err //= "Not of type text"),0))
&&
(# clause: match
(($args->{"username"} =~ qr((?:(?-)\A\w{2,9}\z))) ? 1 : (($_sahv_err //= "Must match regex pattern \\A\\w{2,9}\\z"),0)))
&&
(# clause: max_len
((length($args->{"username"}) <= 9) ? 1 : (($_sahv_err //= "Length must be at most 9"),0)))
; if ($_sahv_err) { return [400, "Argument validation failed: $_sahv_err"] }
} # if date arg exists
# check required args
return [400, "Missing required argument: files"] unless exists $args->{"files"};
return [400, "Missing required value for argument: files"] if exists($args->{"files"}) && !defined($args->{"files"});
return [400, "Missing required value for argument: password"] if exists($args->{"password"}) && !defined($args->{"password"});
return [400, "Missing required value for argument: retries"] if exists($args->{"retries"}) && !defined($args->{"retries"});
return [400, "Missing required value for argument: username"] if exists($args->{"username"}) && !defined($args->{"username"});
_pci_err([500, "Extraneous command-line argument(s): ".join(", ", @check_argv)]) if @check_argv;
[200];
} elsif ($sc_name eq "upload") {
FILL_FROM_POS: {
1;
if (@ARGV > 0) { if (exists $args->{"files"}) { return [400, "You specified --file but also argument #0"]; } else { $args->{"files"} = [splice(@ARGV, 0)]; } }
}
my @check_argv = @ARGV;
# fill from cmdline_src
# fill defaults from "default" property and check against schema
no warnings ('void');
require Time::Duration::Parse::AsHash;
require Scalar::Util;
require List::Util;
require Scalar::Util::Numeric::PP;
my $_sahv_dpath;
my $_sahv_err;
if (exists $args->{"delay"}) {
$_sahv_dpath = [];
# req #0
((defined($args->{"delay"})) ? 1 : (($_sahv_err //= "Required but not specified"),0))
&&
# coerce rule(s): From_str::hms, From_float::seconds, From_obj::datetime_duration, From_str::iso8601, From_str::human # coerce to: float(secs)
(($args->{"delay"} = ($args->{"delay"} =~ /\A([0-9]{1,2}):([0-9]{1,2})(?::([0-9]{1,2})(\.[0-9]{1,9})?)?\z/) ? (do { if ($1 > 23) { ["Invalid hour '$1', must be between 0-23"] } elsif ($2 > 59) { ["Invalid minute '$2', must be between 0-59...
&&
# check type 'duration'
((!ref($args->{"delay"}) && $args->{"delay"} =~ /\A[0-9]+(?:\.[0-9]+)?\z/) ? 1 : (($_sahv_err //= "Not of type duration"),0))
; if ($_sahv_err) { return [400, "Argument validation failed: $_sahv_err"] }
} # if date arg exists
if (exists $args->{"files"}) {
$_sahv_dpath = [];
# req #0
((defined($args->{"files"})) ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Required but not specified"),0))
&&
# check type 'array'
((ref($args->{"files"}) eq 'ARRAY') ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Not of type array"),0))
&&
(# clause: min_len
((@{$args->{"files"}} >= 1) ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Length must be at least 1"),0)))
&&
([push(@{$_sahv_dpath}, undef), scalar(# clause: of
((!defined(List::Util::first(sub {!(
($_sahv_dpath->[-1] = $_),
# req #0
((defined($args->{"files"}->[$_])) ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Required but not specified"),0))
&&
# check type 'str'
((!ref($args->{"files"}->[$_])) ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Not of type text"),0))
)}, 0..@{$args->{"files"}}-1))) ? 1 : (($_sahv_err //= (@$_sahv_dpath ? '@'.join("",map {"[$_]"} @$_sahv_dpath).": " : "") . "Not of type text"),0))), pop(@{$_sahv_dpath})]->[1])
; if ($_sahv_err) { return [400, "Argument validation failed: $_sahv_err"] }
script/pause view on Meta::CPAN
# req #0
((defined($args->{"username"})) ? 1 : (($_sahv_err //= "Required but not specified"),0))
&&
# check type 'str'
((!ref($args->{"username"})) ? 1 : (($_sahv_err //= "Not of type text"),0))
&&
(# clause: match
(($args->{"username"} =~ qr((?:(?-)\A\w{2,9}\z))) ? 1 : (($_sahv_err //= "Must match regex pattern \\A\\w{2,9}\\z"),0)))
&&
(# clause: max_len
((length($args->{"username"}) <= 9) ? 1 : (($_sahv_err //= "Length must be at most 9"),0)))
; if ($_sahv_err) { return [400, "Argument validation failed: $_sahv_err"] }
} # if date arg exists
# check required args
return [400, "Missing required value for argument: delay"] if exists($args->{"delay"}) && !defined($args->{"delay"});
return [400, "Missing required argument: files"] unless exists $args->{"files"};
return [400, "Missing required value for argument: files"] if exists($args->{"files"}) && !defined($args->{"files"});
return [400, "Missing required value for argument: password"] if exists($args->{"password"}) && !defined($args->{"password"});
return [400, "Missing required value for argument: retries"] if exists($args->{"retries"}) && !defined($args->{"retries"});
return [400, "Missing required value for argument: subdir"] if exists($args->{"subdir"}) && !defined($args->{"subdir"});
return [400, "Missing required value for argument: username"] if exists($args->{"username"}) && !defined($args->{"username"});
_pci_err([500, "Extraneous command-line argument(s): ".join(", ", @check_argv)]) if @check_argv;
[200];
} else { _pci_err([500, "Unknown subcommand1: $sc_name"]); }
}
1;
# END Local::_pci_check_args
### begin code_after_end
### end code_after_end
__END__
=pod
=encoding UTF-8
=head1 NAME
pause - A CLI for PAUSE
=head1 VERSION
This document describes version 0.662 of main (from Perl distribution App-pause), released on 2025-05-15.
=head1 SYNOPSIS
First create a config file C<~/pause.conf> containing:
username=<Your PAUSE ID>
password=<Your PAUSE password>
or if you have C<~/.pause> from L<cpan-upload>, C<pause> can read it too
(encrypted C<.pause> is currently not supported).
Then:
# upload one or more files
% pause upload Foo-Bar-0.12.tar.gz Baz-2.24.tar.gz
% pause upload Foo-Bar-0.12.tar.gz --subdir old/2014; # upload to a subdir
# list your files
% pause ls
% pause ls 'App-*'; # accept filenames/wildcard patterns, note: quote first
% pause ls -l ; # see file sizes/mtimes/etc instead of just names
# list your dists
% pause ls-dists
# delete files
% pause rm Foo-Bar-0.12.tar.gz Foo-Bar-0.12.readme Foo-Bar-0.12.meta
% pause rm 'Foo-Bar-*'; # accept wildcard patterns, but quote first
# undelete files scheduled for deletion (but not actually deleted yet)
% pause undelete Foo-Bar-0.12.tar.gz Foo-Bar-0.12.readme Foo-Bar-0.12.meta
% pause undelete 'Foo-Bar-*'; # accept wildcard patterns, but quote first
# force reindexing
% pause reindex Foo-Bar-0.12.tar.gz Foo-Bar-0.12.meta
% pause reindex 'Foo-Bar-*'; # accept wildcard patterns, but quote first
# clean old releases, by default will only leave the newest non-dev version
% pause cleanup
% pause cleanup -n 3 ; # keep 3 versions (newest + previous two)
To view permissions:
# list all modules that you have permissions of
% pause ls-mods
% pause ls-mods -l ; # show detail
# list all modules matching a wildcard
% pause ls-mods -l 'Unix*'
# list all modules you have co-maint of
% pause ls-mods -l --type co-maint
To change permissions (not yet implemented):
...
To change your password (not yet implemented):
...
To view your account info (not yet implemented):
...
To change your email forwarding (not yet implemented):
...
=head1 SUBCOMMANDS
=head2 B<cleanup>
Delete older versions of distributions.
Currently does not look for releases in subdirectories.
By default does not include developer (trial) releases. To include that, use
C<--include-dev>.
To only cleanup developer releases, you can use C<--include-dev> and
C<--exclude-nondev>.
=head2 B<ls>
List files.
=head2 B<ls-dists>
List distributions.
Distribution names will be extracted from tarball/zip filenames.
Unknown/unparseable filenames will be skipped.
=head2 B<ls-mods>
List modules (permissions).
=head2 B<reindex>
Force reindexing.
=head2 B<rm>
Delete files.
When a file is deleted, it is not immediately deleted but has
scheduled_for_deletion status for 72 hours, then deleted. During that time, the
file can be undeleted.
=head2 B<undelete>
Undelete files.
When a file is deleted, it is not immediately deleted but has
scheduled_for_deletion status for 72 hours, then deleted. During that time, the
file can be undeleted.
=head2 B<upload>
Upload file(s).
=head1 OPTIONS
C<*> marks required options.
=head2 Common options
=over
=item B<--config-path>=I<s>
Set path to configuration file.
Can actually be specified multiple times to instruct application to read from
multiple configuration files (and merge them).
Can be specified multiple times.
=item B<--config-profile>=I<s>
Set configuration profile to use.
A single configuration file can contain profiles, i.e. alternative sets of
values that can be selected. For example:
[profile=dev]
username=foo
pass=beaver
[profile=production]
username=bar
pass=honey
When you specify C<--config-profile=dev>, C<username> will be set to C<foo> and
C<password> to C<beaver>. When you specify C<--config-profile=production>,
C<username> will be set to C<bar> and C<password> to C<honey>.
=item B<--debug>
Shortcut for --log-level=debug.
=item B<--format>=I<s>
Choose output format, e.g. json, text.
Default value:
undef
Output can be displayed in multiple formats, and a suitable default format is
chosen depending on the application and/or whether output destination is
interactive terminal (i.e. whether output is piped). This option specifically
chooses an output format.
=item B<--help>, B<-h>, B<-?>
script/pause view on Meta::CPAN
Can also be specified as the 1st command-line argument and onwards.
=back
=head2 Options for subcommand rm
=over
=item B<--file>=I<s@>*
File name/wildcard pattern.
Can also be specified as the 1st command-line argument and onwards.
Can be specified multiple times.
=item B<--files-json>=I<s>
File names/wildcard patterns (JSON-encoded).
See C<--file>.
Can also be specified as the 1st command-line argument and onwards.
=item B<--protect-file>=I<s@>
Protect some files/wildcard patterns from delete/cleanup.
Can be specified multiple times.
=item B<--protect-files-json>=I<s>
Protect some files/wildcard patterns from delete/cleanup (JSON-encoded).
See C<--protect-file>.
=back
=head2 Options for subcommand undelete
=over
=item B<--file>=I<s@>*
File name/wildcard pattern.
Can also be specified as the 1st command-line argument and onwards.
Can be specified multiple times.
=item B<--files-json>=I<s>
File names/wildcard patterns (JSON-encoded).
See C<--file>.
Can also be specified as the 1st command-line argument and onwards.
=back
=head2 Options for subcommand upload
=over
=item B<--delay>=I<s>
Pause a number of seconds between files.
If you upload a lot of files (e.g. 7-10 or more) at a time, the PAUSE indexer
currently might choke with SQLite database locking problem and thus fail to
index your releases. Giving a delay of say 2-3 minutes (120-180 seconds) between
files will alleviate this problem.
=item B<--file>=I<s@>*
File name/wildcard pattern.
Can also be specified as the 1st command-line argument and onwards.
Can be specified multiple times.
=item B<--files-json>=I<s>
File names/wildcard patterns (JSON-encoded).
See C<--file>.
Can also be specified as the 1st command-line argument and onwards.
=item B<--subdir>=I<s>
Subdirectory to put the file(s) into.
Default value:
""
=back
=head1 COMPLETION
This script has shell tab completion capability with support for several
shells.
=head2 bash
To activate bash completion for this script, put:
complete -C pause pause
in your bash startup (e.g. C<~/.bashrc>). Your next shell session will then
recognize tab completion for the command. Or, you can also directly execute the
line above in your shell to activate immediately.
It is recommended, however, that you install modules using L<cpanm-shcompgen>
which can activate shell completion for scripts immediately.
=head2 tcsh
To activate tcsh completion for this script, put:
complete pause 'p/*/`pause`/'
in your tcsh startup (e.g. C<~/.tcshrc>). Your next shell session will then
recognize tab completion for the command. Or, you can also directly execute the
line above in your shell to activate immediately.
It is also recommended to install C<shcompgen> (see above).
script/pause view on Meta::CPAN
arg2=val2
which is equivalent to setting C<< -plugins=-DumpArgs@before_validate_args@99,-Foo@after_validate_args,arg1,val1,arg2,val2 >>.
List of available configuration parameters:
=head2 Common for all subcommands
=head2 Configuration for subcommand cleanup
detail (see --detail)
exclude_dists (see --exclude-dist)
include_dev (see --include-dev)
include_dists (see --include-dist)
include_nondev (see --exclude-nondev)
num_keep (see --num-keep)
protect_files (see --protect-file)
=head2 Configuration for subcommand ls
del (see --del)
detail (see --detail)
files (see --file)
mtime_max (see --mtime-max)
mtime_min (see --mtime-min)
size_max (see --size-max)
size_min (see --size-min)
=head2 Configuration for subcommand ls-dists
detail (see --detail)
exclude_dists (see --exclude-dist)
include_dev (see --include-dev)
include_dists (see --include-dist)
include_nondev (see --exclude-nondev)
newest (see --newest)
newest_n (see --newest-n)
=head2 Configuration for subcommand ls-mods
detail (see --detail)
modules (see --module)
type (see --type)
=head2 Configuration for subcommand reindex
files (see --file)
=head2 Configuration for subcommand rm
files (see --file)
protect_files (see --protect-file)
=head2 Configuration for subcommand undelete
files (see --file)
=head2 Configuration for subcommand upload
delay (see --delay)
files (see --file)
subdir (see --subdir)
=head1 ENVIRONMENT
=head2 PAUSE_OPT
String. Specify additional command-line options.
=head1 FILES
=head2 /home/u1/.config/pause.conf
=head2 /home/u1/pause.conf
=head2 /etc/pause.conf
F<~/.pause>
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/App-pause>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-App-pause>.
=head1 SEE ALSO
To clean up, there are also: L<pause-cleanup> (from L<App::PAUSE::cleanup>),
L<WWW::PAUSE::CleanUpHomeDir> (CLI in example).
=head1 AUTHOR
perlancar <perlancar@cpan.org>
=head1 CONTRIBUTING
To contribute, you can send patches by email/via RT, or send pull requests on
GitHub.
Most of the time, you don't need to build the distribution yourself. You can
simply modify the code, then test via:
% prove -l
If you want to build the distribution (e.g. to try to install it locally on your
system), you can install L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
that are considered a bug and can be reported to me.
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2025 by perlancar <perlancar@cpan.org>.
( run in 0.883 second using v1.01-cache-2.11-cpan-b16cb0d3907 )