App-rimetadb
view release on metacpan or search on metacpan
lib/App/rimetadb.pm view on Meta::CPAN
description => <<'_',
Note that some modules are already loaded before this option takes effect. To
make sure you use the right library, you can use `PERL5OPT` or explicitly use
`perl` and use its `-I` option.
_
cmdline_aliases => { I=>{} },
cmdline_on_getopt => sub {
my %args = @_;
require lib;
lib->import($args{value});
},
},
use => {
schema => ['array' => of => 'perl::modname*'],
summary => 'Use a Perl module, a la Perl\'s -M',
cmdline_aliases => {M=>{}},
cmdline_on_getopt => sub {
my %args = @_;
my $val = $args{value};
if (my ($mod, $imp) = $val =~ /(.+?)=(.+)/) {
log_debug("Loading module $mod ...");
load $mod;
$mod->import(split /,/, $imp);
} else {
log_debug("Loading module $val ...");
autoload $val;
}
},
},
require => {
schema => ['array' => of => 'perl::modname*'],
summary => 'Require a Perl module, a la Perl\'s -m',
cmdline_aliases => {m=>{}},
cmdline_on_getopt => sub {
my %args = @_;
my $val = $args{value};
log_debug("Loading module $val ...");
load $val;
},
},
force_update => {
summary => "Force update database even though module ".
"hasn't changed since last update",
schema => 'bool',
cmdline_aliases => { force=>{} }, # old alias
},
delete => {
summary => "Whether to delete packages from DB if no longer ".
"mentioned as arguments or found in filesystem",
schema => 'bool',
default => 1,
},
},
features => {
progress => 1,
dry_run => 1,
},
};
sub update_from_modules {
require Module::List;
require Module::Path::More;
require Package::Util::Lite;
my %args = @_;
my ($res, $dbh) = _connect_db(\%args);
return $res unless $res->[0] == 200;
my $exc = $args{exclude} // [];
my @pkgs;
for my $entry (@{ $args{module_or_package} }) {
if ($entry =~ /\A\+(.+)::\z/) {
# package prefix
log_debug("Listing all packages under $1 ...");
for my $p (Package::Util::Lite::list_subpackages($1, 1)) {
next if (grep { $_ eq $p } @pkgs) || _is_excluded($_, $exc);
push @pkgs, $_;
}
} elsif ($entry =~ /\A\+(.+)/) {
# package name
my $pkg = $1;
next if (grep { $_ eq $pkg } @pkgs) || _is_excluded($pkg, $exc);
push @pkgs, $pkg;
} elsif ($entry =~ /(.+::)\z/) {
# module prefix
log_debug("Listing all modules under $1 ...");
my $res = Module::List::list_modules(
$1, {list_modules=>1, recurse=>1});
for my $mod (sort keys %$res) {
next if (grep { $_ eq $mod } @pkgs) || _is_excluded($mod, $exc);
log_debug("Loading module $mod ...");
load $mod;
push @pkgs, $mod;
}
} else {
# module name
next if (grep { $_ eq $entry } @pkgs) || _is_excluded($entry, $exc);
log_debug("Loading module $entry ...");
load $entry;
push @pkgs, $entry;
}
}
my @excluded_pkgs;
my $progress = $args{-progress};
$progress->pos(0) if $progress;
$progress->target(scalar @pkgs) if $progress;
my $i = 0;
PKG:
for my $pkg (@pkgs) {
$i++;
$progress->update(pos=>$i, message => "Processing package $pkg ...") if $progress;
log_debug("Processing package $pkg ...");
#sleep 1;
my $rec = $dbh->selectrow_hashref("SELECT * FROM package WHERE name=?",
{}, $pkg);
my $mp = Module::Path::More::module_path(module=>$pkg);
my @st; @st = stat($mp) if $mp;
lib/App/rimetadb.pm view on Meta::CPAN
$dbh->do("INSERT INTO function (package, name, summary, metadata) VALUES (?,?,?,?)", {}, $pkg, $func, $funcmeta->{summary}, _json->encode($funcmeta));
}
}
$progress->finish if $progress;
@pkgs = grep { my $p = $_; !(grep { $_ eq $p } @excluded_pkgs) } @pkgs;
if ($args{delete} // 1) {
my @deleted_pkgs;
my $sth = $dbh->prepare("SELECT name FROM package");
$sth->execute;
while (my $row = $sth->fetchrow_hashref) {
next unless _package_in_list_of_modnames_or_prefixes($row->{name}, $args{module_or_package});
next if grep { $_ eq $row->{name} } @pkgs;
log_info("Package $row->{name} no longer exists, deleting from database ...");
push @deleted_pkgs, $row->{name};
}
if (@deleted_pkgs && !$args{-dry_run}) {
my $in = join(",", map {$dbh->quote($_)} @deleted_pkgs);
$dbh->do("DELETE FROM function WHERE package IN ($in)");
$dbh->do("DELETE FROM package WHERE name IN ($in)");
}
}
[200, "OK"];
}
$SPEC{update} = {
v => 1.1,
summary => 'Add/update a package or function metadata in the database',
description => <<'_',
This routine lets you add/update a package or function metadata in the database
with the specified metadata.
_
args => {
%args_common,
package => {
schema => 'perl::modname*',
req => 1,
completion => \&_complete_package,
},
function => {
schema => 'str*',
completion => \&_complete_func,
},
metadata => {
schema => 'hash*',
req => 1,
},
dist => {
schema => 'str*',
},
extra => {
schema => 'str*',
},
},
};
sub update {
require Perinci::Sub::Normalize;
my %args = @_;
my ($res, $dbh) = _connect_db(\%args);
return $res unless $res->[0] == 200;
my $pkg = $args{package};
my $func = $args{function};
my $meta = $args{metadata};
if ($func) {
$meta = Perinci::Sub::Normalize::normalize_function_metadata($meta);
}
my $pkgsummary;
$pkgsummary = $meta->{summary} unless $func;
if ($dbh->selectrow_array("SELECT name FROM package WHERE name=?", {}, $pkg)) {
$dbh->do("UPDATE package SET summary=?, metadata=?, mtime=?, dist=?, extra=? WHERE name=?",
{}, $pkgsummary, _json->encode($meta), time(), $args{dist}, $args{extra},
$pkg);
} else {
$dbh->do("INSERT INTO package (name, summary, metadata, mtime, extra) VALUES (?,?,?,?,?)",
{}, $pkg, $pkgsummary, _json->encode($meta), $args{dist}, $args{extra});
}
if ($func) {
my $funcsummary = $meta->{summary};
if ($dbh->selectrow_array("SELECT name FROM function WHERE package=? AND name=?", {}, $pkg, $func)) {
$dbh->do("UPDATE function SET summary=?, metadata=?, mtime=?, dist=?, extra=? WHERE package=? AND name=?",
{}, $funcsummary, _json->encode($meta), time(), $args{dist}, $args{extra},
$pkg, $func);
} else {
$dbh->do("INSERT INTO function (package, name, summary, metadata, mtime, dist, extra) VALUES (?,?,?,?,?,?,?)",
{}, $pkg, $func, $funcsummary, _json->encode($meta), time(), $args{dist}, $args{extra});
}
}
[200, "OK"];
}
$SPEC{delete} = {
v => 1.1,
summary => 'Delete a package or function metadata from the database',
args => {
%args_common,
package => {
schema => 'perl::modname*',
req => 1,
completion => \&_complete_package,
},
function => {
schema => 'str*',
completion => \&_complete_func,
},
},
};
sub delete {
my %args = @_;
( run in 2.797 seconds using v1.01-cache-2.11-cpan-98e64b0badf )