App-instopt

 view release on metacpan or  search on metacpan

lib/App/instopt.pm  view on Meta::CPAN

                log_info "Removing $dir ...";
                File::Path::remove_tree($dir);
            }
        }
    }
    $args{-dry_run} ? [304, "Dry-run"] : [200];
}

$SPEC{cleanup_download_dir} = {
    v => 1.1,
    summary => 'Remove older versions of downloaded software',
    args => {
        %args_common,
    },
    features => { dry_run=>1 },
};
sub cleanup_download_dir {
    require File::Path;

    my %args = @_;
    my $state = _init(\%args, {set_default_arch=>0});

    local $CWD = $args{download_dir};
    my $res = list_downloaded(%args, detail=>1);
    return $res unless $res->[0] == 200;
  SW:
    for my $row (@{ $res->[2] }) {
        my $sw = $row->{software};
        for my $arch (sort keys %{ $row->{downloaded_versions} }) {
            my @vers = @{ $row->{downloaded_versions}{$arch} };
            unless (@vers > 1) {
                log_trace "Skipping software '$sw' arch '$arch' (<2 versions)";
                next SW;
            }
            pop @vers; # remove latest version
            my $dir = sprintf "%s/%s", substr($sw, 0, 1), $sw;
            local $CWD = $dir;
          VER:
            for my $v (@vers) {
                if ($args{-dry_run}) {
                    log_info "[DRY-RUN] Cleaning up $sw-$v arch $arch ...";
                } else {
                    log_info "Cleaning up software $sw-$v arch $arch ...";
                    File::Path::remove_tree("$v/$arch");
                }
            }
        } # for arch
    }
    $args{-dry_run} ? [304, "Dry-run"] : [200];
}

$SPEC{update} = {
    v => 1.1,
    summary => 'Update a software to the latest version',
    args => {
        %args_common,
        %App::swcat::arg0_softwares_or_patterns,
        %argopt_download,
    },
};
sub update {
    require Archive::Any;
    require File::Util::Test;
    require File::Path;
    require Filename::Archive;
    require Filename::Executable;
    require IPC::System::Options;

    my %args = @_;
    my $state = _init(\%args);

    my ($sws, $is_single_software) =
        App::swcat::_get_arg_softwares_or_patterns(\%args);

    my $envres = envresmulti();
  SW:
    for my $sw (@$sws) {
        my $mod = App::swcat::_load_swcat_mod($sw);
        my $res = list_installed_versions(%args, software=>$sw);
        my $v0 = $res->[2] ? $res->[2][-1] : undef;

        my $v;
        my ($filepath, $filename);
      DOWNLOAD_OR_GET_DOWNLOADED: {
            if ($args{download}) {
              DOWNLOAD: {
                    my $dlres = download(%args, softwares_or_patterns=>[$sw]);
                    if ($dlres->[0] == 304) {
                        goto GET_DOWNLOADED;
                    }
                    unless ($dlres->[0] == 200) {
                        my $errmsg ="Can't download $sw: $dlres->[0] - $dlres->[1]";
                        log_error $errmsg;
                        $envres->add_result(500, $errmsg, {item_id=>$sw});
                        next SW;
                    }
                    $v = $dlres->[3]{'func.version'};
                    if (@{ $dlres->[3]{'func.files'} } != 1) {
                        my $errmsg = "Can't install $sw: Currently cannot handle software that has multiple downloaded files";
                        log_error $errmsg;
                        $envres->add_result(412, $errmsg, {item_id=>$sw});
                        next SW;
                    }
                    $filepath = $filename = $dlres->[3]{'func.files'}[0];
                    $filename =~ s!.+/!!;
                }
                last DOWNLOAD_OR_GET_DOWNLOADED;
            }
          GET_DOWNLOADED: {
                my $res = list_downloaded_versions(%args, software=>$sw);
                $v = $res->[2] ? $res->[2]{ $args{arch} }[-1] : undef;
                if (!defined $v) {
                    my $errmsg = "Can't install $sw: No downloaded version available";
                    log_error $errmsg;
                    $envres->add_result(412, $errmsg, {item_id=>$sw});
                    next SW;
                }
                {
                    local $CWD = sprintf(
                        "%s/%s/%s/%s/%s",
                        $args{download_dir},

lib/App/instopt.pm  view on Meta::CPAN

                IPC::System::Options::system(
                    {log=>1, die=>1},
                    "cp", "-la", $target_name, $sw,
                );
                File::Slurper::write_text("$sw/instopt.version", $v);
            }
        }

      SYMLINK_ARCHIVE_PROGRAMS: {
            last unless $fileformat eq 'archive';
            local $CWD = $args{program_dir};
            log_trace "Creating/updating program symlinks ...";
            my $programs = $aires->[2]{programs} // [];
            for my $e (@$programs) {
                if ((-l $e->{name}) || !File::Util::Test::file_exists($e->{name})) {
                    unlink $e->{name};
                    my $target = "$args{install_dir}/$sw$e->{path}/$e->{name}";
                    $target =~ s!//!/!g;
                    log_trace "Creating symlink $args{program_dir}/$e->{name} -> $target ...";
                    symlink $target, $e->{name} or do {
                        $envres->add_result(500, "Can't install $sw: Can't symlink $e->{name} -> $target: $!", {item_id=>$sw});
                        next SW;
                    };
                } else {
                    log_warn "%s/%s is not a symlink, skipping", $args{program_dir}, $e->{name};
                    next;
                }
            }
        }

      SYMLINK_EXEC_IN_PROGRAM_DIR: {
            last unless $fileformat eq 'executable';
            local $CWD = $args{program_dir};
            log_trace "Creating/updating program symlink ...";
            if ((-l $sw) || !File::Util::Test::file_exists($sw)) {
                unlink $sw;
                my $target = "$args{install_dir}/$sw/$filename";
                $target =~ s!//!/!g;
                log_trace "Creating symlink $args{program_dir}/$sw -> $target ...";
                symlink $target, $sw or do {
                    $envres->add_result(500, "Can't install $sw: Can't symlink $sw -> $target: $!", {item_id=>$sw});
                    next SW;
                };
            }
        }

        $envres->add_result(200, "OK", {item_id=>$sw});
    } # SW

    $envres->as_struct;
}

$SPEC{update_all} = {
    v => 1.1,
    summary => 'Update all installed software',
    args => {
        %args_common,
        %argopt_download,
    },
};
sub update_all {
    my %args = @_;
    my $state = _init(\%args);

    my $res = list_installed(%args);
    return $res unless $res->[0] == 200;

    update(%args, softwares_or_patterns=>$res->[2]);
}

1;
# ABSTRACT: Download and install software

__END__

=pod

=encoding UTF-8

=head1 NAME

App::instopt - Download and install software

=head1 VERSION

This document describes version 0.021 of App::instopt (from Perl distribution App-instopt), released on 2023-11-20.

=head1 SYNOPSIS

See L<instopt> script.

=head1 FUNCTIONS


=head2 cleanup_download_dir

Usage:

 cleanup_download_dir(%args) -> [$status_code, $reason, $payload, \%result_meta]

Remove older versions of downloaded software.

This function is not exported.

This function supports dry-run operation.


Arguments ('*' denotes required arguments):

=over 4

=item * B<download_dir> => I<dirname>

(No description)

=item * B<install_dir> => I<dirname>

(No description)

=item * B<program_dir> => I<dirname>



( run in 0.521 second using v1.01-cache-2.11-cpan-39bf76dae61 )