Skip to content

Commit

Permalink
feat: auto-detect distros and packages (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
aisuneko committed Oct 13, 2024
1 parent 7860d65 commit acf634f
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/config/distro_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use serde::Deserialize;

#[derive(Debug, Deserialize)]
pub struct DistroConfig {
pub enabled: bool,
pub testing_type: String, // 'locally' or 'remote' or 'qemu-based-remote'
#[serde(rename = "startup_script")]
#[serde(default, skip_serializing_if = "is_not_qemu_based_remote")]
Expand Down
1 change: 0 additions & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
pub mod connection_config;
pub mod distro_config;
pub mod root_config;
32 changes: 0 additions & 32 deletions src/config/root_config.rs

This file was deleted.

31 changes: 14 additions & 17 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod testenv_manager;
mod testscript_manager;
mod utils;

use crate::config::{distro_config::DistroConfig, root_config::Config};
use crate::config::distro_config::DistroConfig;
use crate::test_runner::{local::LocalTestRunner, remote::RemoteTestRunner, TestRunner};
use clap::{Arg, ArgAction, ArgMatches, Command};
use log::{debug, error, info, warn};
Expand Down Expand Up @@ -35,27 +35,24 @@ fn main() {
let aggr = matches.get_flag("aggr");
let summ = matches.get_flag("summ");
let skip_successful = matches.get_flag("skip-successful");
let config_file = matches
.get_one::<String>("config")
let cwd = env::current_dir().unwrap();
let working_directory = matches
.get_one::<String>("directory")
.map(|s| s.as_str())
.unwrap_or("config.toml");
let base_config: Config = match utils::read_toml_from_file(config_file) {
Ok(base_config) => base_config,
Err(e) => {
error!("Failed to load config from {}: {}", config_file, e);
return;
}
};
.unwrap_or(cwd.to_str().unwrap());

let discovered_distros = utils::get_distros(working_directory).unwrap_or_default();
let distros: Vec<&str> = matches
.get_one::<String>("distro")
.map(|s| s.as_str().split(',').collect::<Vec<&str>>())
.unwrap_or(base_config.distros.iter().map(|s| &**s).collect());
.unwrap_or(discovered_distros.iter().map(|s| s.as_str()).collect());
debug!("Distros: {:?}", distros);
let discovered_packages =
utils::get_all_packages(&distros, working_directory).unwrap_or_default();
let packages: Vec<&str> = matches
.get_one::<String>("package")
.map(|s| s.as_str().split(',').collect::<Vec<&str>>())
.unwrap_or(base_config.packages.iter().map(|s| &**s).collect());
.unwrap_or(discovered_packages.iter().map(|s| s.as_str()).collect());
debug!("Packages: {:?}", packages);

if test {
Expand Down Expand Up @@ -104,10 +101,10 @@ fn parse_args() -> ArgMatches {
.help("Generate a summary report"),
)
.arg(
Arg::new("config")
.long("config")
.value_name("Config file name")
.help("Specify a different base configuration file"),
Arg::new("directory")
.long("directory")
.value_name("Working directory")
.help("Specify working directory with preconfigured test files"),
)
.arg(
Arg::new("distro")
Expand Down
56 changes: 55 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
//! This module provides common structures and utilities used across the project,
//! including report structures, temporary file management, and command output handling.
use log::debug;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{error::Error, fs};
use std::{collections::HashSet, error::Error, fs, path::Path};

use crate::config::distro_config::DistroConfig;

/// The remote temporary directory used for operations.
pub static REMOTE_TMP_DIR: &str = "/tmp/lintestor";
Expand Down Expand Up @@ -115,3 +118,54 @@ where
let config: T = toml::de::from_str(&content)?;
Ok(config)
}

pub fn get_distros(dir: &str) -> Result<Vec<String>, Box<dyn Error>> {
let directory = Path::new(dir);
let mut distros = Vec::new();
for subdir in directory.read_dir()? {
let distro = subdir?;
let distro_dir_path = distro.path();
if distro_dir_path.is_dir() {
let distro_dir_name = distro.file_name().into_string().unwrap();
let distro_config_path = format!("{}/config.toml", distro_dir_path.display());
let distro_config: DistroConfig = match read_toml_from_file(&distro_config_path) {
Ok(config) => {
debug!("Discovered distro directory {}", distro_dir_path.display());
config
}
Err(_) => {
continue;
}
};
if distro_config.enabled {
distros.push(distro_dir_name);
}
}
}
Ok(distros)
}

pub fn get_packages(distro: &str, dir: &str) -> Result<Vec<String>, Box<dyn Error>> {
let directory = Path::new(dir).join(distro);
let mut packages = Vec::new();
for subdir in directory.read_dir()? {
let package = subdir?;
let package_dir_path = package.path();
if package_dir_path.is_dir() {
let package_dir_name = package.file_name().into_string().unwrap();
packages.push(package_dir_name);
}
}
Ok(packages)
}

pub fn get_all_packages(distros: &[&str], dir: &str) -> Result<Vec<String>, Box<dyn Error>> {
let mut packages = HashSet::new();
for distro in distros {
let current_packages = get_packages(distro, dir).unwrap_or_default();
packages.extend(current_packages);
}
let mut packages_vec: Vec<String> = packages.into_iter().collect();
packages_vec.sort(); // do we really need sorting?
Ok(packages_vec)
}

0 comments on commit acf634f

Please sign in to comment.