You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
amethyst/src/operations/aur_install.rs

189 lines
6.1 KiB
Rust

use std::env::set_current_dir;
use std::fs::remove_dir_all;
use std::path::Path;
use std::process::Command;
3 years ago
use std::{env, fs};
3 years ago
use crate::internal::commands::ShellCommand;
use crate::internal::error::SilentUnwrap;
use crate::internal::exit_code::AppExitCode;
use crate::internal::rpc::rpcinfo;
use crate::{crash, info, log, prompt, Options};
3 years ago
pub fn aur_install(a: Vec<String>, options: Options) {
// Initialise variables
let url = crate::internal::rpc::URL;
let cachedir = format!("{}/.cache/ame/", env::var("HOME").unwrap());
3 years ago
let verbosity = options.verbosity;
let noconfirm = options.noconfirm;
if verbosity >= 1 {
log!("Installing from AUR: {:?}", &a);
3 years ago
}
info!("Installing packages {} from the AUR", a.join(", "));
3 years ago
for package in a {
// Query AUR for package info
let rpcres = rpcinfo(package);
if !rpcres.found {
// If package isn't found, break
break;
}
// Get package name
let pkg = &rpcres.package.as_ref().unwrap().name;
if verbosity >= 1 {
log!("Cloning {} into cachedir", pkg);
}
info!("Cloning package source");
3 years ago
// Clone package into cachedir
set_current_dir(Path::new(&cachedir)).unwrap();
ShellCommand::git()
.arg("clone")
.arg(format!("{}/{}", url, pkg))
.wait()
.silent_unwrap(AppExitCode::GitError);
if verbosity >= 1 {
log!(
"Cloned {} into cachedir, moving on to resolving dependencies",
pkg
);
log!(
"Raw dependencies for package {} are:\n{:?}",
pkg,
rpcres.package.as_ref().unwrap().depends.join(", ")
);
log!(
3 years ago
"Raw makedepends for package {} are:\n{:?}",
pkg,
rpcres.package.as_ref().unwrap().make_depends.join(", ")
);
}
// Sort dependencies and makedepends
if verbosity >= 1 {
log!("Sorting dependencies and makedepends");
}
let sorted = crate::internal::sort(&rpcres.package.as_ref().unwrap().depends, options);
3 years ago
let md_sorted =
crate::internal::sort(&rpcres.package.as_ref().unwrap().make_depends, options);
if verbosity >= 1 {
log!("Sorted dependencies for {} are:\n{:?}", pkg, &sorted);
log!("Sorted makedepends for {} are:\n{:?}", pkg, &md_sorted);
}
// Create newopts struct for installing dependencies
let newopts = Options {
verbosity,
noconfirm,
asdeps: true,
};
// If dependencies are not found in AUR or repos, crash
3 years ago
if !sorted.nf.is_empty() || !md_sorted.nf.is_empty() {
crash!(
AppExitCode::MissingDeps,
"Could not find dependencies {} for package {}, aborting",
sorted.nf.join(", "),
pkg,
);
}
if !noconfirm {
// Prompt user to view PKGBUILD
let p1 = prompt!(default false,
"Would you like to review {}'s PKGBUILD (and any .install files if present)?",
pkg
3 years ago
);
3 years ago
let editor: &str = &env::var("PAGER").unwrap_or_else(|_| "less".parse().unwrap());
if p1 {
// Open PKGBUILD in pager
3 years ago
Command::new(editor)
.arg(format!("{}/PKGBUILD", pkg))
.spawn()
.unwrap()
.wait()
.unwrap();
3 years ago
// Check if any .install files are present
let status = ShellCommand::bash()
.arg("-c")
.arg(format!("ls {}/*.install &> /dev/null", pkg))
.wait()
.silent_unwrap(AppExitCode::Other);
if status.success() {
// If so, open them too
ShellCommand::bash()
.arg("-c")
.arg(format!("{} {}/*.install", editor, pkg))
.wait()
.silent_unwrap(AppExitCode::Other);
3 years ago
}
// Prompt user to continue
let p2 = prompt!(default true, "Would you still like to install {}?", pkg);
if !p2 {
// If not, crash
3 years ago
fs::remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap();
crash!(AppExitCode::UserCancellation, "Not proceeding");
}
3 years ago
}
}
info!("Moving on to install dependencies");
// Install dependencies and makedepends
if !sorted.repo.is_empty() {
crate::operations::install(sorted.repo, newopts);
3 years ago
crate::operations::install(md_sorted.repo, newopts);
}
if !sorted.aur.is_empty() {
crate::operations::aur_install(sorted.aur, newopts);
3 years ago
crate::operations::aur_install(md_sorted.aur, newopts);
}
// Build makepkg args
let mut makepkg_args = vec!["-rsci", "--skippgp"];
if options.asdeps {
makepkg_args.push("--asdeps")
}
if options.noconfirm {
makepkg_args.push("--noconfirm")
}
info!("Building time!");
// Enter cachedir and build package
set_current_dir(format!("{}/{}", cachedir, pkg)).unwrap();
let status = ShellCommand::makepkg()
.args(makepkg_args)
.wait()
.silent_unwrap(AppExitCode::MakePkgError);
if !status.success() {
// If build failed, crash
3 years ago
fs::remove_dir_all(format!("{}/{}", cachedir, pkg)).unwrap();
crash!(
AppExitCode::PacmanError,
"Error encountered while installing {}, aborting",
pkg,
3 years ago
);
}
// Return to cachedir
3 years ago
set_current_dir(&cachedir).unwrap();
// Remove package from cache
3 years ago
remove_dir_all(format!("{}/{}", cachedir, &pkg)).unwrap();
}
3 years ago
}