Skip to content

Commit

Permalink
Add dependent modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Pencilcaseman committed Aug 13, 2024
1 parent aab1ed2 commit 1bb4c7b
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 53 deletions.
6 changes: 5 additions & 1 deletion src/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<P: AsRef<Path>>(path: &P, name: &str, archive_type: &str) -> Result<(), String> {
pub fn extract<P: AsRef<Path>>(
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");
Expand Down
47 changes: 35 additions & 12 deletions src/builders/builder_trait.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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<P0: AsRef<Path> + Debug, P1: AsRef<Path> + Debug, P2: AsRef<Path>>(
fn build<
P0: AsRef<Path> + Debug,
P1: AsRef<Path> + Debug,
P2: AsRef<Path>,
>(
&self,
source_path: &P0,
build_path: &P1,
Expand Down Expand Up @@ -73,16 +80,24 @@ impl BuilderImpl for Builder {
}
}

fn build<P0: AsRef<Path> + Debug, P1: AsRef<Path> + Debug, P2: AsRef<Path>>(
fn build<
P0: AsRef<Path> + Debug,
P1: AsRef<Path> + Debug,
P2: AsRef<Path>,
>(
&self,
source_path: &P0,
build_path: &P1,
install_path: &P2,
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)
}
}
}

Expand All @@ -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,
),
}
}
}
67 changes: 44 additions & 23 deletions src/builders/cmake.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -20,14 +24,19 @@ pub struct CMake {
}

impl CMake {
fn configure<P0: AsRef<Path> + std::fmt::Debug, P1: AsRef<Path> + std::fmt::Debug>(
fn configure<
P0: AsRef<Path> + std::fmt::Debug,
P1: AsRef<Path> + 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())?;
Expand All @@ -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();
Expand Down Expand Up @@ -104,9 +114,13 @@ impl BuilderImpl for CMake {
fn from_py(object: &Bound<PyAny>) -> Result<Self, String> {
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::<String>()
.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()
{
Expand All @@ -131,16 +145,15 @@ impl BuilderImpl for CMake {

let cmake_root: Option<String> = 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<
Expand All @@ -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()
};
Expand All @@ -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();
Expand All @@ -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();

Expand Down
9 changes: 7 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -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<String>,
Expand Down Expand Up @@ -44,7 +46,10 @@ pub fn read() -> Result<Config, String> {
.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()
})?;
Expand Down
2 changes: 1 addition & 1 deletion src/downloaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
5 changes: 3 additions & 2 deletions src/file_manager.rs
Original file line number Diff line number Diff line change
@@ -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 = '/';
Expand Down
17 changes: 10 additions & 7 deletions src/info.rs
Original file line number Diff line number Diff line change
@@ -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");

Expand All @@ -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()
});

Expand Down
3 changes: 2 additions & 1 deletion src/log.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use colored::Colorize;
use std::io::Write;

use colored::Colorize;

fn remove_tabs(txt: &str) -> String {
txt.replace('\t', " ")
}
Expand Down
16 changes: 12 additions & 4 deletions src/shell.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -43,7 +45,13 @@ impl Shell {
self.commands.push(cmd.to_string());
}

pub fn exec(&self) -> (std::io::Result<ExitStatus>, Vec<String>, Vec<String>) {
pub fn get_commands(&self) -> &Vec<String> {
&self.commands
}

pub fn exec(
&self,
) -> (std::io::Result<ExitStatus>, Vec<String>, Vec<String>) {
// Instantiate shell
let mut shell = Command::new(&self.shell);
shell.stdin(std::process::Stdio::piped());
Expand Down

0 comments on commit 1bb4c7b

Please sign in to comment.