From 1bb4c7b17189c8de7d0c267b9d5856701ff67b66 Mon Sep 17 00:00:00 2001 From: Toby Davis Date: Tue, 13 Aug 2024 10:16:36 +0200 Subject: [PATCH] Add dependent modules --- src/archive.rs | 6 +++- src/builders/builder_trait.rs | 47 +++++++++++++++++------- src/builders/cmake.rs | 67 +++++++++++++++++++++++------------ src/config.rs | 9 +++-- src/downloaders.rs | 2 +- src/file_manager.rs | 5 +-- src/info.rs | 17 +++++---- src/log.rs | 3 +- src/shell.rs | 16 ++++++--- 9 files changed, 119 insertions(+), 53 deletions(-) diff --git a/src/archive.rs b/src/archive.rs index 5ffc754..b38d800 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -5,7 +5,11 @@ use std::{path::Path, process::Command}; /// # Errors /// /// Errors if the directory cannot be created or the file extraction command fails -pub fn extract>(path: &P, name: &str, archive_type: &str) -> Result<(), String> { +pub fn extract>( + path: &P, + name: &str, + archive_type: &str, +) -> Result<(), String> { let mut command = match archive_type.to_lowercase().as_ref() { "tar" | "tar.gz" | "targz" | "tgz" => { let mut cmd = Command::new("tar"); diff --git a/src/builders/builder_trait.rs b/src/builders/builder_trait.rs index 651fcbd..6c243bd 100644 --- a/src/builders/builder_trait.rs +++ b/src/builders/builder_trait.rs @@ -1,8 +1,11 @@ +use std::{fmt::Debug, path::Path}; + +use pyo3::{ + prelude::{PyAnyMethods, PyTypeMethods}, + Bound, PyAny, +}; + use crate::builders::{cmake::CMake, make::Make}; -use pyo3::prelude::{PyAnyMethods, PyTypeMethods}; -use pyo3::{Bound, PyAny}; -use std::fmt::Debug; -use std::path::Path; pub trait BuilderImpl: Sized + Clone { /// Generate a builder object from a python object. @@ -27,7 +30,11 @@ pub trait BuilderImpl: Sized + Clone { /// - Source directory does not contain a valid build script configuration /// - The code fails to compile /// - The build files cannot be written to the build directory - fn build + Debug, P1: AsRef + Debug, P2: AsRef>( + fn build< + P0: AsRef + Debug, + P1: AsRef + Debug, + P2: AsRef, + >( &self, source_path: &P0, build_path: &P1, @@ -73,7 +80,11 @@ impl BuilderImpl for Builder { } } - fn build + Debug, P1: AsRef + Debug, P2: AsRef>( + fn build< + P0: AsRef + Debug, + P1: AsRef + Debug, + P2: AsRef, + >( &self, source_path: &P0, build_path: &P1, @@ -81,8 +92,12 @@ impl BuilderImpl for Builder { dependencies: &[String], ) -> Result<(), String> { match self { - Self::CMake(cmake) => cmake.build(source_path, build_path, install_path, dependencies), - Self::Make(make) => make.build(source_path, build_path, install_path, dependencies), + Self::CMake(cmake) => { + cmake.build(source_path, build_path, install_path, dependencies) + } + Self::Make(make) => { + make.build(source_path, build_path, install_path, dependencies) + } } } @@ -94,10 +109,18 @@ impl BuilderImpl for Builder { dependencies: &[String], ) -> Result<(), String> { match self { - Self::CMake(cmake) => { - cmake.install(source_path, build_path, install_path, dependencies) - } - Self::Make(make) => make.install(source_path, build_path, install_path, dependencies), + Self::CMake(cmake) => cmake.install( + source_path, + build_path, + install_path, + dependencies, + ), + Self::Make(make) => make.install( + source_path, + build_path, + install_path, + dependencies, + ), } } } diff --git a/src/builders/cmake.rs b/src/builders/cmake.rs index f9f5e60..07e96f6 100644 --- a/src/builders/cmake.rs +++ b/src/builders/cmake.rs @@ -1,8 +1,12 @@ -use crate::{builders::builder_trait::BuilderImpl, file_manager::PATH_SEP, log, shell::Shell}; -use pyo3::prelude::PyAnyMethods; -use pyo3::{Bound, PyAny}; use std::{fs, path, path::Path}; +use pyo3::{prelude::PyAnyMethods, Bound, PyAny}; + +use crate::{ + builders::builder_trait::BuilderImpl, file_manager::PATH_SEP, log, + shell::Shell, +}; + #[derive(Debug, Clone)] pub enum CMakeBuildType { Debug, @@ -20,14 +24,19 @@ pub struct CMake { } impl CMake { - fn configure + std::fmt::Debug, P1: AsRef + std::fmt::Debug>( + fn configure< + P0: AsRef + std::fmt::Debug, + P1: AsRef + std::fmt::Debug, + >( &self, source_path: &P0, output_path: &P1, dependencies: &[String], ) -> Result<(), String> { - let source_path = path::absolute(source_path).map_err(|err| err.to_string())?; - let output_path = path::absolute(output_path).map_err(|err| err.to_string())?; + let source_path = + path::absolute(source_path).map_err(|err| err.to_string())?; + let output_path = + path::absolute(output_path).map_err(|err| err.to_string())?; // Attempt to create the output directory if necessary fs::create_dir_all(&output_path).map_err(|e| e.to_string())?; @@ -47,7 +56,8 @@ impl CMake { } } - cmake_cmd.push_str(&format!(" -DCMAKE_BUILD_TYPE={:?}", self.build_type)); + cmake_cmd + .push_str(&format!(" -DCMAKE_BUILD_TYPE={:?}", self.build_type)); shell.add_command(&cmake_cmd); let (result, stdout, stderr) = shell.exec(); @@ -104,9 +114,13 @@ impl BuilderImpl for CMake { fn from_py(object: &Bound) -> Result { let build_type = match object .getattr("build_type") - .map_err(|_| "Failed to read attribute 'build_type' of Builder object")? + .map_err(|_| { + "Failed to read attribute 'build_type' of Builder object" + })? .extract::() - .map_err(|_| "Failed to convert attribute 'build_type' to Rust String")? + .map_err(|_| { + "Failed to convert attribute 'build_type' to Rust String" + })? .to_lowercase() .as_str() { @@ -131,16 +145,15 @@ impl BuilderImpl for CMake { let cmake_root: Option = object .getattr("cmake_root") - .map_err(|_| "Failed to read attribute 'cmake_root' of Builder object")? + .map_err(|_| { + "Failed to read attribute 'cmake_root' of Builder object" + })? .extract() - .map_err(|_| "Failed to convert attribute 'cmake_root' to Rust String")?; - - Ok(Self { - build_type, - jobs, - configure_flags, - cmake_root, - }) + .map_err(|_| { + "Failed to convert attribute 'cmake_root' to Rust String" + })?; + + Ok(Self { build_type, jobs, configure_flags, cmake_root }) } fn build< @@ -155,7 +168,9 @@ impl BuilderImpl for CMake { dependencies: &[String], ) -> Result<(), String> { let cmake_source_path = if let Some(root) = &self.cmake_root { - source_path.as_ref().to_str().unwrap().to_owned() + PATH_SEP.to_string().as_ref() + root + source_path.as_ref().to_str().unwrap().to_owned() + + PATH_SEP.to_string().as_ref() + + root } else { source_path.as_ref().to_str().unwrap().to_owned() }; @@ -172,13 +187,17 @@ impl BuilderImpl for CMake { install_path: &P2, dependencies: &[String], ) -> Result<(), String> { - let build_path = path::absolute(build_path).map_err(|err| err.to_string())?; - let install_path = path::absolute(install_path).map_err(|err| err.to_string())?; + let build_path = + path::absolute(build_path).map_err(|err| err.to_string())?; + let install_path = + path::absolute(install_path).map_err(|err| err.to_string())?; fs::create_dir_all(&install_path).map_err(|e| e.to_string())?; if !build_path.exists() { - return Err(format!("Build directory {build_path:?} does not exist")); + return Err(format!( + "Build directory {build_path:?} does not exist" + )); } let mut shell = Shell::default(); @@ -188,7 +207,9 @@ impl BuilderImpl for CMake { shell.add_command(&format!("module load {dep}")); } - shell.add_command(&format!("cmake --install . --prefix {install_path:?}")); + shell.add_command(&format!( + "cmake --install . --prefix {install_path:?}" + )); let (result, stdout, stderr) = shell.exec(); diff --git a/src/config.rs b/src/config.rs index be31851..7ae73dc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,9 @@ -use crate::module::Module; use std::fs; + use toml::Table; +use crate::module::Module; + #[derive(Debug)] pub struct Config { pub sccmod_module_paths: Vec, @@ -44,7 +46,10 @@ pub fn read() -> Result { .map(|item| { item.as_str() .map(std::string::ToString::to_string) - .ok_or_else(|| "`module_paths` must be an array of strings".to_string()) + .ok_or_else(|| { + "`module_paths` must be an array of strings" + .to_string() + }) }) .collect() })?; diff --git a/src/downloaders.rs b/src/downloaders.rs index f30028f..248e1bc 100644 --- a/src/downloaders.rs +++ b/src/downloaders.rs @@ -205,7 +205,7 @@ impl DownloaderImpl for GitClone { shell.set_current_dir(path); shell.add_command("mkdir -p sccmod_patches"); shell.add_command("cd sccmod_patches"); - shell.add_command(&format!("curl -Lo {patch}")); + shell.add_command(&format!("curl -LO {patch}")); let (result, stdout, stderr) = shell.exec(); diff --git a/src/file_manager.rs b/src/file_manager.rs index 00a7a21..20b5bfe 100644 --- a/src/file_manager.rs +++ b/src/file_manager.rs @@ -1,10 +1,11 @@ -use crate::log; -use std::fs::DirEntry; use std::{ + fs::DirEntry, path::{Path, PathBuf}, process::Command, }; +use crate::log; + /// Defines the path separator for a given operating system #[cfg(not(target_os = "windows"))] pub static PATH_SEP: char = '/'; diff --git a/src/info.rs b/src/info.rs index 3c7e25e..9d48549 100644 --- a/src/info.rs +++ b/src/info.rs @@ -1,7 +1,9 @@ use colored::Colorize; -use pyo3::prelude::PyAnyMethods; -use pyo3::types::{IntoPyDict, PyString}; -use pyo3::Python; +use pyo3::{ + prelude::PyAnyMethods, + types::{IntoPyDict, PyString}, + Python, +}; const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -27,10 +29,11 @@ pub fn print() { let locals = [("os", os)].into_py_dict_bound(py); let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'"; - let user = py - .eval_bound(code, None, Some(&locals)) - .unwrap_or_else(|_| { - crate::log::warn("Failed to extract user from Python environment variables"); + let user = + py.eval_bound(code, None, Some(&locals)).unwrap_or_else(|_| { + crate::log::warn( + "Failed to extract user from Python environment variables", + ); PyString::new_bound(py, "Unknown").into_any() }); diff --git a/src/log.rs b/src/log.rs index c5944a4..10e0221 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1,6 +1,7 @@ -use colored::Colorize; use std::io::Write; +use colored::Colorize; + fn remove_tabs(txt: &str) -> String { txt.replace('\t', " ") } diff --git a/src/shell.rs b/src/shell.rs index 789f642..bcb994a 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,10 +1,12 @@ // Long story short, Rust's std::process::Command doesn't let you do // what I need to do, so now this exists... +use std::{ + path::Path, + process::{Command, ExitStatus}, +}; + use crate::{cli::child_logger, config}; -use std::path::Path; -use std::process::Command; -use std::process::ExitStatus; pub enum ShellOutput { Success, @@ -43,7 +45,13 @@ impl Shell { self.commands.push(cmd.to_string()); } - pub fn exec(&self) -> (std::io::Result, Vec, Vec) { + pub fn get_commands(&self) -> &Vec { + &self.commands + } + + pub fn exec( + &self, + ) -> (std::io::Result, Vec, Vec) { // Instantiate shell let mut shell = Command::new(&self.shell); shell.stdin(std::process::Stdio::piped());