App-sbozyp
view release on metacpan or search on metacpan
if ($opt_help) { print command_help_msg('query'); return }
if (@argv > 1) { die command_usage('query') }
my $num_opts_set = 0; for ($opt_listinstalled,$opt_printpackagedir,$opt_printrepodir,$opt_slackdesc,$opt_info,$opt_pkgsnodependents,$opt_recdependents,$opt_directdependents,$opt_pkginstalled,$opt_printqueue,$opt_readme,$opt_slackbuild,$opt_listne...
if ($num_opts_set != 1) { sbozyp_die("must set exactly 1 query option but $num_opts_set were set") }
my $opt = $opt_listinstalled ? '-a' : $opt_printpackagedir ? '-b' : $opt_printrepodir ? '-c' : $opt_slackdesc ? '-d' : $opt_info ? '-i' : $opt_pkgsnodependents ? '-m' : $opt_recdependents ? '-n' : $opt_directdependents ? '-o' : $opt_pkginstalled ...
my $has_pkg_arg = $opt_printpackagedir || $opt_slackdesc || $opt_info || $opt_recdependents || $opt_directdependents || $opt_pkginstalled || $opt_printqueue || $opt_readme || $opt_slackbuild;
if ($has_pkg_arg) {
@argv == 1 or sbozyp_die("query option '$opt' requires single PKGNAME argument");
} else {
@argv == 0 or sbozyp_die("query option '$opt' does not take PKGNAME argument");
}
init_repo($repo_opts, @argv) or return;
my $pkg = $has_pkg_arg ? pkg($argv[0]) : undef;
# option implementations
if ($opt_listinstalled) {
my %installed_sbo_pkgs = installed_sbo_pkgs();
for my $pkgname (sort keys %installed_sbo_pkgs) {
print $pkgname, "\n";
}
} elsif ($opt_printpackagedir) {
print $pkg->{PKGDIR}, '/', "\n";
} elsif ($opt_printrepodir) {
print repo_dir(), "\n";
} elsif ($opt_slackdesc) {
sbozyp_print_file("$pkg->{PKGDIR}/slack-desc");
} elsif ($opt_info) {
sbozyp_print_file("$pkg->{PKGDIR}/$pkg->{PRGNAM}.info");
} elsif ($opt_pkgsnodependents) {
print "$_->{PKGNAME}\n" for pkgs_no_dependents();
} elsif ($opt_recdependents) {
print "$_->{PKGNAME}\n" for pkg_dependents_recursive($pkg);
} elsif ($opt_directdependents) {
print "$_->{PKGNAME}\n" for pkg_dependents_direct($pkg);
} elsif ($opt_pkginstalled) {
if (defined(my $version = pkg_installed($pkg))) {
print "$version\n";
}
} elsif ($opt_printqueue) {
print "$_->{PKGNAME}\n" for pkg_queue($pkg);
} elsif ($opt_readme) {
sbozyp_print_file("$pkg->{PKGDIR}/README");
} elsif ($opt_slackbuild) {
sbozyp_print_file("$pkg->{PKGDIR}/$pkg->{PRGNAM}.SlackBuild");
} elsif ($opt_listneedupdate) {
my %installed_sbo_pkgs = installed_sbo_pkgs();
for my $pkgname (sort keys %installed_sbo_pkgs) {
my $installed_version = $installed_sbo_pkgs{$pkgname};
my $available_version = pkg($pkgname)->{VERSION};
print $pkgname, "\n" if version_gt($available_version, $installed_version);
}
} elsif ($opt_listneedupdateversion) {
my %installed_sbo_pkgs = installed_sbo_pkgs();
for my $pkgname (sort keys %installed_sbo_pkgs) {
my $installed_version = $installed_sbo_pkgs{$pkgname};
my $available_version = pkg($pkgname)->{VERSION};
if (version_gt($available_version, $installed_version)) {
print "$pkgname $installed_version -> $available_version\n";
}
}
} elsif ($opt_listpkgsnotinrepo) {
print "$_\n" for sbo_pkgs_not_in_repo();
}
}
sub main_search {
my ($repo_opts, @argv) = @_;
sbozyp_getopts(
\@argv,
'h|help' => \my $opt_help,
'c' => \my $opt_casesensitive,
'n' => \my $opt_matchcategory,
'p' => \my $opt_prgnam,
'q' => \my $opt_quiet
);
if ($opt_help) { print command_help_msg('search'); return }
@argv == 1 or die command_usage('search');
init_repo($repo_opts) or return;
my $regex_arg = $argv[0];
my $regex = eval { $opt_casesensitive ? qr/$regex_arg/ : qr/$regex_arg/i };
sbozyp_die("invalid Perl regex: $regex_arg") if $@;
my @matches = grep {
$opt_matchcategory ? $_ =~ $regex : basename($_) =~ $regex;
} all_pkgnames();
if (@matches) {
if ($opt_prgnam) {
@matches = sort map { $_ = basename($_) } @matches;
}
print $_, "\n" for @matches;
} elsif (not $opt_quiet) {
sbozyp_print('no matches found', "\n");
}
}
sub main_null {
my ($repo_opts, @argv) = @_;
sbozyp_getopts(
\@argv,
'h|help' => \my $opt_help,
);
if ($opt_help) { print command_help_msg('null'); return }
@argv == 0 or die command_usage('null');
init_repo($repo_opts);
}
####################################################
# PACKAGE OPERATIONS #
####################################################
sub pkg {
my ($prgnam) = @_;
$prgnam = path_to_pkgname(Cwd::abs_path($prgnam)) if is_slackbuild_path($prgnam);
my $pkgname = prgnam_to_pkgname($prgnam) // sbozyp_die("could not find a package named $prgnam");
state %pkg_cache; if (my $pkg = $pkg_cache{$pkgname}) { return $pkg }
my $info_file = repo_dir()."$pkgname/@{[basename($pkgname)]}.info";
my %info = parse_info_file($info_file);
my $pkg = {
PKGNAME => $pkgname,
PKGDIR => repo_dir().$pkgname,
INFO_FILE => $info_file,
SLACKBUILD_FILE => repo_dir().$pkgname.'/'.basename($pkgname).'.SlackBuild',
DESC_FILE => repo_dir().$pkgname.'/slack-desc',
}
return;
}
sub pkg_installed_and_up_to_date {
my ($pkg) = @_;
my $installed_version = pkg_installed($pkg);
my (undef, $version) = parse_slackware_pkgname(pkg_package_name($pkg));
if (!defined $installed_version or !defined $version or version_gt($version, $installed_version)) {
return 0;
} else {
return 1;
}
}
sub pkg_matches_blacklist {
my ($pkg, $blacklist_file) = @_;
state %blacklist_cache;
my $pkgnames = $blacklist_cache{$blacklist_file};
if (!defined $pkgnames) {
my $fh = sbozyp_open('<', $blacklist_file);
my @pkgnames;
while (<$fh>) {
chomp;
s/#.*//; # no comments
s/^\s+//; # no leading whitespace
s/\s+$//; # no trailing whitespace
next unless length; # is there anything left?
if (my $pkgname = prgnam_to_pkgname($_)) {
push @pkgnames, $pkgname;
}
}
$pkgnames = $blacklist_cache{$blacklist_file} = \@pkgnames;
}
for my $pkgname (@$pkgnames) {
return 1 if $pkg->{PKGNAME} eq $pkgname;
}
return 0;
}
sub parse_slackware_pkgname {
my ($slackware_pkgname) = @_;
my ($prgnam, $version) = $slackware_pkgname =~ /^([\w.+-]+)-([^-]*)-[^-]*-\d+_SBo(?:\.t[blxg]z)?$/;
return ($prgnam => $version);
}
sub installed_sbo_pkgs {
my $root = $ENV{ROOT} // '/';
my %installed_sbo_pkgs;
if (-d "$root/var/lib/pkgtools/packages") {
%installed_sbo_pkgs = map {
my ($prgnam, $version) = parse_slackware_pkgname(basename($_));
# If $pkgname is undef then the current repo doesnt have the package. We only manage packages in the current repo.
my $pkgname = prgnam_to_pkgname($prgnam);
defined $pkgname ? ($pkgname, $version) : ();
} grep /_SBo$/, sbozyp_readdir("$root/var/lib/pkgtools/packages");
}
return %installed_sbo_pkgs;
}
sub sbo_pkgs_not_in_repo {
state @prgnams = do {
my $root = $ENV{ROOT} // '/';
-d "$root/var/lib/pkgtools/packages" ? sort grep { !prgnam_to_pkgname($_) } map {
my ($prgnam) = parse_slackware_pkgname(basename($_));
} grep /_SBo$/, sbozyp_readdir("$root/var/lib/pkgtools/packages") : ();
};
return @prgnams;
}
sub all_pkg_categories {
state @all_pkg_categories = do {
my $repo_dir = repo_dir();
sort map { basename($_) } grep {
basename($_) !~ /^\./ && -d $_;
} sbozyp_readdir($repo_dir);
};
return @all_pkg_categories;
}
sub all_pkgnames {
state @all_pkgnames = do {
my $repo_dir = repo_dir();
my @all_pkgnames;
for my $category (all_pkg_categories()) {
my @all_category_pkgnames = map { path_to_pkgname($_) } sbozyp_readdir("$repo_dir/$category");
push @all_pkgnames, @all_category_pkgnames;
}
sort @all_pkgnames;
};
return @all_pkgnames;
}
sub prgnam_to_pkgname { # if $prgnam is already a pkgname its just returned back
my ($prgnam) = @_; $prgnam or return;
state %pkgname_cache; if (my $pkgname = $pkgname_cache{$prgnam}) { return $pkgname }
my $pkgname;
if ($prgnam =~ m,^[^/]+/[^/]+$, && -d repo_dir().$prgnam) {
$pkgname = $prgnam;
} else {
for my $category (all_pkg_categories()) {
if (-d repo_dir()."$category/$prgnam") {
$pkgname = "$category/$prgnam";
last;
}
}
}
$pkgname_cache{$prgnam} = $pkgname;
return $pkgname;
}
sub is_slackbuild_dir {
my ($dir) = @_;
defined $dir && -d $dir or return 0;
my $pkg_dir = Cwd::abs_path($dir) // return 0;
my $prgnam = basename($pkg_dir);
return -f "$pkg_dir/$prgnam.info" && -f "$pkg_dir/$prgnam.SlackBuild";
}
sub is_slackbuild_path {
my ($path) = @_;
( run in 0.860 second using v1.01-cache-2.11-cpan-9789f410c06 )