Implement debug logging, they said. It'll be fun, they said.

main
Michal 2 years ago
parent efa953c43a
commit 229aa83e53
No known key found for this signature in database
GPG Key ID: A6A1A4DCB22279B9

@ -7,8 +7,8 @@ pub struct Args {
pub subcommand: Option<Operation>,
/// Sets the level of verbosity
#[clap(long, short, global(true), action = ArgAction::Count)]
pub verbose: u8,
#[clap(long, short, global(true), action = ArgAction::SetTrue)]
pub verbose: bool,
/// Complete operations without prompting user
#[clap(long = "noconfirm", global(true), action = ArgAction::SetTrue)]

@ -10,14 +10,14 @@ const ERR_SYMBOL: &str = "❌";
#[macro_export]
macro_rules! info {
($($arg:tt)+) => {
$crate::internal::strings::info_fn(format!($($arg)+))
$crate::internal::strings::info_fn(format!($($arg)+));
}
}
#[macro_export]
macro_rules! log {
($($arg:tt)+) => {
$crate::internal::strings::log_fn(format!($($arg)+))
($verbose:expr, $($arg:tt)+) => {
$crate::internal::strings::log_fn(format!($($arg)+), $verbose);
}
}
@ -28,15 +28,23 @@ macro_rules! crash {
}
}
pub fn info_fn<S: ToString>(msg: S) {
let msg = msg.to_string();
println!("{} {}", LOGO_SYMBOL.black(), msg.bold())
}
pub fn log_fn<S: ToString>(msg: S) {
pub fn log_fn<S: ToString>(msg: S, verbose: bool) {
let msg = msg.to_string();
eprintln!("{} {}", std::time::SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(), msg)
if verbose {
eprintln!(
"{} {}",
std::time::SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs(),
msg
);
}
}
pub fn crash_fn<S: ToString>(msg: S, exit_code: AppExitCode) {

@ -37,6 +37,7 @@ fn main() {
}
let exclude = &args.exclude;
let verbose = args.verbose;
if Path::exists("../.git".as_ref()) {
info!("Parent directory is a git directory, pulling latest mlc.toml. It is advised you run mlc pull/update in all malachite directories");
@ -52,13 +53,13 @@ fn main() {
}
match args.subcommand.unwrap_or(Operation::Clone) {
Operation::Clone => operations::clone(),
Operation::Clone => operations::clone(verbose),
Operation::Build {
packages, no_regen, ..
} => operations::build(packages, exclude.to_vec(), no_regen),
Operation::Pull { packages, .. } => operations::pull(packages, exclude.to_vec()),
} => operations::build(packages, exclude.to_vec(), no_regen, verbose),
Operation::Pull { packages, .. } => operations::pull(packages, exclude.to_vec(), verbose),
Operation::RepoGen => {
let config = read_cfg();
let config = read_cfg(verbose);
if config.mode != "repository" {
crash!(
AppExitCode::BuildInWorkspace,
@ -66,9 +67,9 @@ fn main() {
)
}
info!("Generating repository: {}", config.name.unwrap());
repository::generate();
repository::generate(verbose);
}
Operation::Config => operations::config(),
Operation::Clean => operations::clean(),
Operation::Config => operations::config(verbose),
Operation::Clean => operations::clean(verbose),
}
}

@ -1,31 +1,36 @@
use crate::internal::structs::{ErroredPackage, Repo};
use crate::internal::AppExitCode;
use crate::{crash, info, log, repository, workspace};
use crate::internal::AppExitCode;
use crate::internal::structs::{ErroredPackage, Repo};
pub fn build(packages: Vec<String>, exclude: Vec<String>, no_regen: bool) {
pub fn build(packages: Vec<String>, exclude: Vec<String>, no_regen: bool, verbose: bool) {
// Read config struct from mlc.toml
let config = workspace::read_cfg();
log!("Config: {:?}", config);
let config = workspace::read_cfg(verbose);
log!(verbose, "Config: {:?}", config);
let all = packages.is_empty();
log!("All: {:?}", all);
log!("Signing: {:?}", config.sign);
log!(verbose, "All: {:?}", all);
log!(verbose, "Signing: {:?}", config.sign);
// Get list of repos and subtract exclude
let mut repos: Vec<Repo> = config.repo;
log!("{} Repos: {:?}", repos.len(), repos );
log!(verbose, "{} Repos: {:?}", repos.len(), repos);
if !exclude.is_empty() {
log!("Exclude not empty: {:?}", exclude);
log!(verbose, "Exclude not empty: {:?}", exclude);
for ex in exclude {
repos.retain(|x| *x.name != ex);
}
}
log!("Exclusions parsed. Now {} Repos: {:?}", repos.len(), repos);
log!(
verbose,
"Exclusions parsed. Now {} Repos: {:?}",
repos.len(),
repos
);
// If packages is not empty and all isn't specified, build specified packages
let mut errored: Vec<ErroredPackage> = vec![];
if !packages.is_empty() && !all {
log!("Packages not empty: {:?}", packages);
log!(verbose, "Packages not empty: {:?}", packages);
for pkg in &packages {
// If repo is not in config, crash
if !repos.iter().map(|x| x.name.clone()).any(|x| x == *pkg) {
@ -36,9 +41,14 @@ pub fn build(packages: Vec<String>, exclude: Vec<String>, no_regen: bool) {
);
} else {
// Otherwise, build
log!("Building {}", pkg);
let code = repository::build(pkg, config.sign);
log!("Package {} finished with exit code: {:?}", pkg, code);
log!(verbose, "Building {}", pkg);
let code = repository::build(pkg, config.sign, verbose);
log!(
verbose,
"Package {} finished with exit code: {:?}",
pkg,
code
);
if code != 0 {
let error = ErroredPackage {
name: pkg.to_string(),
@ -52,16 +62,21 @@ pub fn build(packages: Vec<String>, exclude: Vec<String>, no_regen: bool) {
// If all is specified, attempt to build a package from all repos
if all {
log!("Proceeding to build all");
log!(verbose, "Proceeding to build all");
// Sort by package priority
log!("Sorting by priority: {:?}", repos);
log!(verbose, "Sorting by priority: {:?}", repos);
repos.sort_by(|a, b| b.priority.cmp(&a.priority));
log!("Sorted: {:?}", repos);
log!(verbose, "Sorted: {:?}", repos);
for pkg in repos {
log!("Building {}", pkg.name);
let code = repository::build(&pkg.name, config.sign);
log!("Package {} finished with exit code: {:?}", pkg.name, code);
log!(verbose, "Building {}", pkg.name);
let code = repository::build(&pkg.name, config.sign, verbose);
log!(
verbose,
"Package {} finished with exit code: {:?}",
pkg.name,
code
);
if code != 0 {
let error = ErroredPackage {
name: pkg.name,
@ -74,14 +89,14 @@ pub fn build(packages: Vec<String>, exclude: Vec<String>, no_regen: bool) {
// If all is not specified, but packages is empty, crash
if !all && packages.is_empty() {
log!("Packages empty. Crashing");
log!(verbose, "Packages empty. Crashing");
crash!(AppExitCode::NoPkgs, "No packages specified");
}
// If no_regen is passed, do not generate a repository
if !no_regen {
log!("Generating repository");
repository::generate();
log!(verbose, "Generating repository");
repository::generate(verbose);
}
// Map errored packages to a string for display
@ -92,10 +107,10 @@ pub fn build(packages: Vec<String>, exclude: Vec<String>, no_regen: bool) {
// If errored is not empty, let the user know which packages failed
if !errored.is_empty() {
log!("Errored packages: \n{:?}", error_strings);
log!(verbose, "Errored packages: \n{:?}", error_strings);
info!(
"The following packages build jobs returned a non-zero exit code: {}",
error_strings.join("\n")
)
);
}
}

@ -1,17 +1,17 @@
use crate::{info, log};
pub fn clean() {
pub fn clean(verbose: bool) {
info!("Resetting mlc repo, deleting all directories");
// Get a vec of all files/dirs in the current directory
let dir_paths = std::fs::read_dir("./").unwrap();
log!("Paths: {:?}", dir_paths);
log!(verbose, "Paths: {:?}", dir_paths);
let mut dirs = dir_paths
.map(|x| x.unwrap().path().display().to_string())
.collect::<Vec<String>>();
// Remove all files/dirs in the current directory, excluding ./mlc.toml
dirs.retain(|x| *x != "./mlc.toml");
log!("Paths with mlc.toml excluded: {:?}", dirs);
log!(verbose, "Paths with mlc.toml excluded: {:?}", dirs);
for dir in dirs {
std::fs::remove_dir_all(dir).unwrap();
}

@ -1,13 +1,13 @@
use std::process::Command;
use crate::{info, workspace, log};
use crate::{info, log, workspace};
pub fn clone() {
pub fn clone(verbose: bool) {
// Read config struct from mlc.toml
let config = workspace::read_cfg();
log!("Config: {:?}", config);
let config = workspace::read_cfg(verbose);
log!(verbose, "Config: {:?}", config);
let repos = &config.repo;
log!("Repos: {:?}", repos);
log!(verbose, "Repos: {:?}", repos);
// Get a vector of all files/dirs in the current directory, excluding config file
let dir_paths = std::fs::read_dir("./").unwrap();
@ -15,7 +15,7 @@ pub fn clone() {
.map(|x| x.unwrap().path().display().to_string())
.collect::<Vec<String>>();
dirs.retain(|x| *x != "./mlc.toml");
log!("Paths with mlc.toml excluded: {:?}", dirs);
log!(verbose, "Paths with mlc.toml excluded: {:?}", dirs);
// Creates a vector of the difference between cloned repos and repos defined in config
let mut repo_diff = vec![];
@ -29,10 +29,10 @@ pub fn clone() {
// Diff logic
if repo_diff.is_empty() {
// No diff, do nothing
log!("No diff");
log!(verbose, "No diff");
info!("All repos are already cloned");
} else {
log!("Diff: {:?}", repo_diff);
log!(verbose, "Diff: {:?}", repo_diff);
// This is just for pretty display purposes
let display = repo_diff
.iter()
@ -43,7 +43,7 @@ pub fn clone() {
// Clone all diff repos
for r in repo_diff {
log!("Cloning {}", r.name);
log!(verbose, "Cloning {}", r.name);
info!("Cloning ({} mode): {}", config.mode, r.name);
Command::new("git")
.args(&["clone", &r.url, &r.name])

@ -4,16 +4,16 @@ use std::process::Command;
use crate::{create_config, log};
pub fn config() {
pub fn config(verbose: bool) {
// Generate new config file if not already present
if !Path::exists("mlc.toml".as_ref()) {
log!("Creating mlc.toml");
create_config();
log!(verbose, "Creating mlc.toml");
create_config(verbose);
}
// Open config file in user's editor of choice
let editor = env::var("EDITOR").unwrap_or_else(|_| "nano".to_string());
log!("Opening mlc.toml in {}", editor);
log!(verbose, "Opening mlc.toml in {}", editor);
Command::new(editor)
.arg("mlc.toml")
.spawn()

@ -1,18 +1,18 @@
use std::env;
use std::process::Command;
use crate::info;
use crate::{crash, internal::AppExitCode, log};
use crate::info;
fn do_the_pulling(repos: Vec<String>) {
fn do_the_pulling(repos: Vec<String>, verbose: bool) {
for repo in repos {
// Set root dir to return after each git pull
let root_dir = env::current_dir().unwrap();
log!("Root dir: {:?}", root_dir);
log!(verbose, "Root dir: {:?}", root_dir);
info!("Entering working directory: {}", &repo);
env::set_current_dir(repo).unwrap();
log!("Current dir: {:?}", env::current_dir().unwrap());
log!("Pulling");
log!(verbose, "Current dir: {:?}", env::current_dir().unwrap());
log!(verbose, "Pulling");
Command::new("git")
.arg("pull")
.spawn()
@ -22,26 +22,30 @@ fn do_the_pulling(repos: Vec<String>) {
// Return to root dir
env::set_current_dir(root_dir).unwrap();
log!("Returned to root dir: {:?}", env::current_dir().unwrap());
log!(
verbose,
"Returned to root dir: {:?}",
env::current_dir().unwrap()
);
}
}
pub fn pull(packages: Vec<String>, exclude: Vec<String>) {
pub fn pull(packages: Vec<String>, exclude: Vec<String>, verbose: bool) {
// If no packages are specified, imply all
let all = packages.is_empty();
log!("All: {}", all);
log!(verbose, "All: {}", all);
// Read repos from config file
let repos = crate::workspace::read_cfg()
let repos = crate::workspace::read_cfg(verbose)
.repo
.iter()
.map(|x| x.name.clone())
.collect::<Vec<String>>();
log!("Repos: {:?}", repos);
log!(verbose, "Repos: {:?}", repos);
// Set repos_applicable for next function
let mut repos_applicable = if all { repos } else { packages };
log!("Repos applicable: {:?}", repos_applicable);
log!(verbose, "Repos applicable: {:?}", repos_applicable);
// Subtract exclude from repos_applicable
if !exclude.is_empty() {
@ -49,8 +53,8 @@ pub fn pull(packages: Vec<String>, exclude: Vec<String>) {
repos_applicable.retain(|x| *x != *ex);
}
}
log!("Exclude: {:?}", exclude);
log!("Repos applicable excluded: {:?}", repos_applicable);
log!(verbose, "Exclude: {:?}", exclude);
log!(verbose, "Repos applicable excluded: {:?}", repos_applicable);
// If all is not specified and packages is empty, crash
if repos_applicable.is_empty() {
@ -58,6 +62,6 @@ pub fn pull(packages: Vec<String>, exclude: Vec<String>) {
}
// Pull!
log!("Pulling {:?}", repos_applicable);
do_the_pulling(repos_applicable);
log!(verbose, "Pulling {:?}", repos_applicable);
do_the_pulling(repos_applicable, verbose);
}

@ -29,7 +29,7 @@ urls = [
""
]"#;
pub fn create_config() {
pub fn create_config(verbose: bool) {
// Ensure current directory is empty
if env::current_dir()
.unwrap()
@ -43,12 +43,12 @@ pub fn create_config() {
"Directory is not empty, please only create a repository in an empty directory"
);
}
log!("Creating config file");
log!(verbose, "Creating config file");
// If config file exists, create it
if !Path::exists("mlc.toml".as_ref()) {
let mut file = File::create("mlc.toml").unwrap();
file.write_all(DEFAULT_CONFIG.as_ref()).unwrap();
}
log!("Config file created");
log!(verbose, "Config file created");
}

@ -1,20 +1,20 @@
use std::{env, fs};
use std::path::Path;
use std::process::Command;
use std::{env, fs};
use crate::{crash, log};
use crate::internal::AppExitCode;
pub fn build(pkg: &str, sign: bool) -> i32 {
log!("Building {}", pkg);
log!("Signing: {}", sign);
pub fn build(pkg: &str, sign: bool, verbose: bool) -> i32 {
log!(verbose, "Building {}", pkg);
log!(verbose, "Signing: {}", sign);
// Set root dir to return after build
let dir = env::current_dir().unwrap();
log!("Root dir: {:?}", dir);
log!(verbose, "Root dir: {:?}", dir);
// Create out dir if not already present
if !Path::exists("out".as_ref()) {
log!("Creating out dir");
log!(verbose, "Creating out dir");
fs::create_dir_all("out").unwrap();
}
@ -29,7 +29,7 @@ pub fn build(pkg: &str, sign: bool) -> i32 {
// Enter build directory
env::set_current_dir(pkg).unwrap();
log!("Current dir: {:?}", env::current_dir().unwrap());
log!(verbose, "Current dir: {:?}", env::current_dir().unwrap());
// Build each package
let a = Command::new("makepkg")
@ -43,7 +43,7 @@ pub fn build(pkg: &str, sign: bool) -> i32 {
.unwrap()
.wait()
.unwrap();
log!("{} Build job returned: {:?}", pkg, a);
log!(verbose, "{} Build job returned: {:?}", pkg, a);
// Copy built package to out dir
Command::new("bash")
@ -52,11 +52,15 @@ pub fn build(pkg: &str, sign: bool) -> i32 {
.unwrap()
.wait()
.unwrap();
log!("Copied built package to out dir");
log!(verbose, "Copied built package to out dir");
// Return to root dir
env::set_current_dir(dir).unwrap();
log!("Returned to root dir: {:?}", env::current_dir().unwrap());
log!(
verbose,
"Returned to root dir: {:?}",
env::current_dir().unwrap()
);
// Return exit code
a.code().unwrap()

@ -1,27 +1,27 @@
use std::{env, fs};
use std::path::Path;
use std::process::Command;
use std::{env, fs};
use crate::{workspace::read_cfg, log};
use crate::{log, workspace::read_cfg};
pub fn generate() {
pub fn generate(verbose: bool) {
// Read config struct from mlc.toml
let config = read_cfg();
log!("Config: {:?}", config);
let config = read_cfg(verbose);
log!(verbose, "Config: {:?}", config);
// Get repository name from config
let name = config.name.unwrap();
log!("Name: {}", name);
log!(verbose, "Name: {}", name);
// If repository exists, delete it
if Path::exists(name.as_ref()) {
log!("Deleting {}", name);
log!(verbose, "Deleting {}", name);
fs::remove_dir_all(&name).unwrap();
}
// Create or recreate repository directory
fs::create_dir_all(&name).unwrap();
log!("Created {}", name);
log!(verbose, "Created {}", name);
// Copy out packages to repository directory
Command::new("bash")
@ -30,11 +30,11 @@ pub fn generate() {
.unwrap()
.wait()
.unwrap();
log!("Copied out packages to {}", name);
log!(verbose, "Copied out packages to {}", name);
// Enter repository directory
env::set_current_dir(&name).unwrap();
log!("Current dir: {:?}", env::current_dir().unwrap());
log!(verbose, "Current dir: {:?}", env::current_dir().unwrap());
let db = format!("{}.db", &name);
let files = format!("{}.files", &name);
@ -49,7 +49,7 @@ pub fn generate() {
.unwrap()
.wait()
.unwrap();
log!("Created {} and {}", db, files);
log!(verbose, "Created {} and {}", db, files);
// Replace repo.{db,files}.tar.gz with just repo.{db,files}
Command::new("bash")
@ -61,5 +61,12 @@ pub fn generate() {
.unwrap()
.wait()
.unwrap();
log!("Renamed {}.tar.gz to {} and {}.tar.gz to {}", db, db, files, files);
log!(
verbose,
"Renamed {}.tar.gz to {} and {}.tar.gz to {}",
db,
db,
files,
files
);
}

@ -1,11 +1,11 @@
use std::fs;
use std::path::Path;
use crate::crash;
use crate::internal::structs::{Config, Repo, SplitRepo, UnexpandedConfig};
use crate::{crash, log};
use crate::internal::AppExitCode;
use crate::internal::structs::{Config, Repo, SplitRepo, UnexpandedConfig};
pub fn read_cfg() -> Config {
pub fn read_cfg(verbose: bool) -> Config {
// Crash if mlc.toml doesn't exist
if !Path::exists("mlc.toml".as_ref()) {
crash!(
@ -17,6 +17,7 @@ pub fn read_cfg() -> Config {
// Reading the config file to an UnexpandedConfig struct
let file = fs::read_to_string("mlc.toml").unwrap();
let config: UnexpandedConfig = toml::from_str(&file).unwrap();
log!(verbose, "Config file read: {:?}", config);
// Crash if incorrect mode is set
if config.mode != "workspace" && config.mode != "repository" {
@ -30,12 +31,14 @@ pub fn read_cfg() -> Config {
// Parsing repos from the config file
for x in config.repo {
log!(verbose, "Parsing repo: {:?}", x);
// Splits the repo name and index inta a SplitRepo struct
let split: Vec<&str> = x.split("::").collect();
let split_struct = SplitRepo {
indx: split[0].parse().unwrap(),
name: split[1].parse().unwrap(),
};
log!(verbose, "Split repo: {:?}", split_struct);
// Parses all necessary values for expanding the repo to a Repo struct
let index = split_struct.indx;
@ -49,14 +52,17 @@ pub fn read_cfg() -> Config {
url,
priority: *priority,
};
log!(verbose, "Expanded repo: {:?}", repo);
expanded_repos.push(repo);
}
// Returns parsed config file
Config {
let conf = Config {
mode: config.mode,
sign: config.sign,
name: config.name,
repo: expanded_repos,
}
};
log!(verbose, "Config: {:?}", conf);
conf
}

Loading…
Cancel
Save