Basic structure reworked
This commit is contained in:
parent
3e553e568b
commit
038b2160bc
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
/.idea
|
/.idea
|
||||||
|
contents/packages
|
||||||
72
Cargo.lock
generated
72
Cargo.lock
generated
@ -4,56 +4,68 @@
|
|||||||
name = "aur-helper"
|
name = "aur-helper"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-serialize",
|
"serde",
|
||||||
"toml-config",
|
"serde_derive",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "proc-macro2"
|
||||||
version = "0.1.10"
|
version = "1.0.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "log"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log 0.4.11",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "quote"
|
||||||
version = "0.4.11"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "serde"
|
||||||
version = "0.3.24"
|
version = "1.0.123"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.123"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.1.30"
|
version = "0.5.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
|
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-serialize",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml-config"
|
name = "unicode-xid"
|
||||||
version = "0.4.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3de5e51a3b687866a2af93d043ff056f797b8c49e2d9d93376eeeaaf66682871"
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
dependencies = [
|
|
||||||
"log 0.3.9",
|
|
||||||
"rustc-serialize",
|
|
||||||
"toml",
|
|
||||||
]
|
|
||||||
|
|||||||
@ -7,5 +7,6 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
toml-config = "0.4.0"
|
toml = "0.5.8"
|
||||||
rustc-serialize = "0.3.24"
|
serde = "1.0.123"
|
||||||
|
serde_derive = "1.0.123"
|
||||||
6
aur_config.toml
Normal file
6
aur_config.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
packages_directory = "contents/packages"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
authy = "https://aur.archlinux.org/authy.git"
|
||||||
|
|
||||||
|
[pre_install_script]
|
||||||
0
contents/.gitkeep
Normal file
0
contents/.gitkeep
Normal file
@ -1,14 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
|
|
||||||
pub struct Args {
|
|
||||||
pub(crate) operation: Option<String>,
|
|
||||||
pub(crate) argument: Option<String>
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_argument_settings() -> Args {
|
|
||||||
let args: Vec<String> = env::args().collect();
|
|
||||||
Args {
|
|
||||||
operation: args.get(1).cloned(),
|
|
||||||
argument: args.get(2).cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
extern crate rustc_serialize;
|
|
||||||
extern crate toml_config;
|
|
||||||
|
|
||||||
use std::path::Path;
|
|
||||||
use toml_config::ConfigFactory;
|
|
||||||
use std::fs::{create_dir_all, OpenOptions};
|
|
||||||
use std::{env, io};
|
|
||||||
use std::io::{ErrorKind, Write};
|
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
pub struct Config {
|
|
||||||
pub nested: NestedConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defaults will be used for missing/invalid configurations in the TOML config file
|
|
||||||
impl Default for Config {
|
|
||||||
fn default() -> Config {
|
|
||||||
Config {
|
|
||||||
nested: NestedConfig::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
const PATH: &'static str = "config.toml";
|
|
||||||
|
|
||||||
fn serialize(&self) -> String {
|
|
||||||
format!("[nested]\ninstall_directory = \"{}\"\ninstalled_packages = [\"{}\"]", self.nested.install_directory, self.nested.installed_packages.to_owned().join("\",\""))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write(&self) -> Result<(), io::Error> {
|
|
||||||
let path_string = Config::PATH;
|
|
||||||
let path = Path::new(path_string);
|
|
||||||
if path.exists() && !path.is_file() {
|
|
||||||
Err(io::Error::new(ErrorKind::InvalidInput, format!("The given path is not a file: {}", path_string).as_str()))
|
|
||||||
} else {
|
|
||||||
let dir = path.parent().expect(format!("Config path does not have a parent directory: {}", path_string).as_str());
|
|
||||||
|
|
||||||
create_dir_all(dir).expect(format!("Could not create directory {}", dir.display()).as_str());
|
|
||||||
|
|
||||||
let mut config_buffer = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.truncate(true)
|
|
||||||
.open(path)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
config_buffer.write_all(self.serialize().as_bytes()).expect(format!("Could not write to config file {}", path_string).as_str());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable)]
|
|
||||||
pub struct NestedConfig {
|
|
||||||
pub install_directory: String,
|
|
||||||
pub installed_packages: Vec<String>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for NestedConfig {
|
|
||||||
fn default() -> NestedConfig {
|
|
||||||
NestedConfig {
|
|
||||||
install_directory: "~/.cache/aur-helper/packages".to_owned(),
|
|
||||||
installed_packages: Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_config() -> Config {
|
|
||||||
let cfg: Config = ConfigFactory::load(Path::new(Config::PATH));
|
|
||||||
let home_env = env::var("HOME").expect("Could not find HOME environment variable.");
|
|
||||||
let relative_home_dir = home_env.as_str();
|
|
||||||
let absolute_home_dir = cfg.nested.install_directory.replace("~", relative_home_dir);
|
|
||||||
let package_path = Path::new(absolute_home_dir.as_str());
|
|
||||||
|
|
||||||
create_dir_all(package_path).expect(format!("Could not create package directory {}", package_path.display()).as_str());
|
|
||||||
|
|
||||||
cfg.write().expect("Cannot write configuration to file");
|
|
||||||
|
|
||||||
cfg
|
|
||||||
}
|
|
||||||
152
src/main.rs
152
src/main.rs
@ -1,47 +1,125 @@
|
|||||||
use crate::argument_parser::get_argument_settings;
|
use std::env::args;
|
||||||
use crate::config_file_actions::Config;
|
use std::fs::{File, create_dir_all, remove_dir_all};
|
||||||
|
use std::io::Read;
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
mod config_file_actions;
|
#[derive(Deserialize, Debug)]
|
||||||
mod argument_parser;
|
struct Config {
|
||||||
mod ops;
|
packages_directory: Option<String>,
|
||||||
|
packages: Option<HashMap<String, String>>,
|
||||||
|
pre_install_script: Option<HashMap<String, String>>
|
||||||
|
}
|
||||||
|
|
||||||
|
// git --version >= 2.25.0
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = get_argument_settings();
|
let config: Config = get_configuration();
|
||||||
|
|
||||||
let mut cfg: Config = config_file_actions::load_config();
|
let packages_directory_path = &config.packages_directory.clone().unwrap();
|
||||||
println!("{}", cfg.nested.install_directory);
|
let packages_directory = Path::new(packages_directory_path);
|
||||||
println!("{:?}", cfg.nested.installed_packages);
|
create_dir_all(packages_directory).unwrap();
|
||||||
|
|
||||||
if let Some(operation) = args.operation {
|
for (package_name, url) in &config.packages.unwrap() {
|
||||||
let argument = args.argument;
|
let result = process_package(&config.packages_directory.clone().unwrap(), package_name, url);
|
||||||
|
if result.is_err() {
|
||||||
match operation.to_lowercase().as_str() {
|
println!("Processing package '{}' threw an error: {}", package_name, result.err().unwrap())
|
||||||
"install" => {
|
|
||||||
require_argument(&argument);
|
|
||||||
ops::install(argument.unwrap());
|
|
||||||
},
|
|
||||||
"list" => {
|
|
||||||
ops::list_installed();
|
|
||||||
},
|
|
||||||
"update" => {
|
|
||||||
require_argument(&argument);
|
|
||||||
ops::update(argument.unwrap());
|
|
||||||
},
|
|
||||||
"remove" => {
|
|
||||||
require_argument(&argument);
|
|
||||||
ops::remove(argument.unwrap());
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
ops::help();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ops::help();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn require_argument(argument: &Option<String>) {
|
fn process_package(packages_path: &String, package_name: &String, url: &String) -> Result<(), String> {
|
||||||
if argument.is_none() {
|
println!("Processing package '{}' ({}) in directory {}", package_name, url, packages_path);
|
||||||
panic!("This option requires an additional argument.");
|
|
||||||
|
let folder_path = Path::new(packages_path).join(package_name);
|
||||||
|
let folder_exists = folder_path. exists();
|
||||||
|
let repo_exists = folder_path. join(".git") . exists();
|
||||||
|
|
||||||
|
if folder_exists && !repo_exists {
|
||||||
|
println!("Removing directory '{}' as it is not a valid git repository.", folder_path.clone().to_str().unwrap());
|
||||||
|
remove_dir_all(folder_path.clone()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if !folder_exists {
|
||||||
|
println!("Cloning package '{}' from '{}'.", package_name, url);
|
||||||
|
Command::new("git")
|
||||||
|
.arg("clone")
|
||||||
|
.arg(url)
|
||||||
|
.arg(folder_path.clone().to_str().unwrap())
|
||||||
|
.output()
|
||||||
|
.expect(&*format!("Could not clone '{}' to '{}'", url, package_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// let status_information = Command::new("git")
|
||||||
|
// .arg("-C")
|
||||||
|
// .arg(folder_path.clone().to_str().unwrap())
|
||||||
|
// .arg("status")
|
||||||
|
// .arg("--porcelain=v1")
|
||||||
|
// .output()
|
||||||
|
// .expect(&*format!("Could not get repository status for repository root at {}", folder_path.clone().to_str().unwrap()))
|
||||||
|
// .stdout;
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.arg("-C")
|
||||||
|
.arg(folder_path.clone().to_str().unwrap())
|
||||||
|
.arg("clean")
|
||||||
|
.arg("-f")
|
||||||
|
.arg("-x")
|
||||||
|
.output()
|
||||||
|
.expect(&*format!("Could not clean repository for repository root at {}", folder_path.clone().to_str().unwrap()));
|
||||||
|
|
||||||
|
Command::new("git")
|
||||||
|
.arg("-C")
|
||||||
|
.arg(folder_path.clone().to_str().unwrap())
|
||||||
|
.arg("restore")
|
||||||
|
.arg(".")
|
||||||
|
.output()
|
||||||
|
.expect(&*format!("Could not clean repository for repository root at {}", folder_path.clone().to_str().unwrap()));
|
||||||
|
|
||||||
|
// for file_status in std::str::from_utf8(&*status_information).unwrap().split('\n').into_iter() {
|
||||||
|
// if file_status.len() < 3 {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let status_code = file_status.chars().into_iter().take(2).collect::<String>();
|
||||||
|
// let status_path = file_status.chars().rev().into_iter().take(file_status.len() - 3).collect::<String>().chars().rev().collect::<String>();
|
||||||
|
//
|
||||||
|
// println!("{} {}", status_code, status_path);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
if !folder_path.join("PKGBUILD").is_file() {
|
||||||
|
return Err(format!("Package '{}' does not seem to have a PKGBUILD file, if this is a mistake, please delete/update the package manually.", package_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("This package does {}have a folder and does {}have a repository.", if folder_exists { "" } else { "not " }, if repo_exists { "" } else { "not " });
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_configuration_file_path() -> String {
|
||||||
|
args().nth(1).expect("Required parameter configuration file missing.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_configuration_file_contents() -> std::io::Result<String> {
|
||||||
|
let file_name = get_configuration_file_path();
|
||||||
|
let file = File::open(file_name)?;
|
||||||
|
let mut file_copy = file.try_clone()?;
|
||||||
|
|
||||||
|
let mut contents: Vec<u8> = vec![];
|
||||||
|
file_copy.read_to_end(&mut contents)?;
|
||||||
|
Ok(std::str::from_utf8(&*contents)
|
||||||
|
.expect("Found data in the configuration file that is not according to UTF8").to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_configuration() -> Config {
|
||||||
|
let configuration_contents = get_configuration_file_contents().unwrap();
|
||||||
|
let config: Config = toml::from_str(&*configuration_contents).unwrap();
|
||||||
|
|
||||||
|
config.packages_directory.clone().expect("Configuration does not contain string `packages_directory`.");
|
||||||
|
config.packages.clone().expect("Configuration does not contain array `packages`");
|
||||||
|
|
||||||
|
config
|
||||||
|
}
|
||||||
|
|||||||
19
src/ops.rs
19
src/ops.rs
@ -1,19 +0,0 @@
|
|||||||
pub fn install(argument: String) {
|
|
||||||
println!("Argument: {}", argument);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_installed() {
|
|
||||||
println!("Here's packages!");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(argument: String) {
|
|
||||||
println!("Argument: {}", argument);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove(argument: String) {
|
|
||||||
println!("Argument: {}", argument);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn help() {
|
|
||||||
println!("Help!");
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user