use std::collections::HashMap;
mod execution_context;
mod manifests;
mod projects;
mod utils;
pub use manifests::manifest::AbstractManifest;
pub use manifests::manifest::AbstractModule;
use std::env;
use std::fs;
use std::path;
const DEFAULT_CACHE_DIR: &str = ".panbuild/";
const DEFAULT_GIT_CACHE_DIR: &str = ".git/";
const DEFAULT_FLATPAK_BUILDER_CACHE_DIR: &str = ".flatpak-builder/";
const DEFAULT_FLATPAK_BUILD_CACHE_DIR: &str = ".build/";
const DEFAULT_PACKAGE_LIST_SEP: &str = ",";
struct PanbuilbArguments {
command_name: String,
arguments: Vec<String>,
input_format: String,
output_format: String,
}
pub fn run(command_name: &str, args: HashMap<String, String>) -> i32 {
let mut ctx = crate::execution_context::ExecutionContext::default();
if command_name == "lint" {
let input_file_path = match args.get("input_file") {
Some(input_file_path) => input_file_path,
None => {
eprintln!("an input file is required!");
return 1;
}
};
ctx.content = match fs::read_to_string(path::Path::new(input_file_path)) {
Ok(content) => content,
Err(e) => {
eprintln!("could not read file {}.", input_file_path);
return 1;
}
};
if args.contains_key("input_format") {
let source_type = args.get("input_format").unwrap();
if !crate::manifests::has_type(source_type.to_string()) {
eprintln!("{} is an invalid manifest type.", source_type);
return 1;
}
ctx.source_type = source_type.to_string();
} else {
let mut exit_code: i32 = manifests::detect_type(&mut ctx);
if exit_code != 0 {
eprintln!("Could not detect manifest type of {}.", ctx.source_filename);
return exit_code;
}
}
let mut exit_code: i32 = manifests::parse(&mut ctx);
if exit_code != 0 {
eprintln!("Error while parsing");
return exit_code;
}
eprintln!("Parsing finished. Resulting manifest is {:#?}", &ctx.manifest);
exit_code = manifests::dump(&mut ctx);
if exit_code != 0 {
eprintln!("Error while dumping");
return exit_code;
}
match fs::write(path::Path::new(input_file_path), ctx.content) {
Ok(content) => content,
Err(e) => {
eprintln!("could not write file {}.", input_file_path);
return 1;
}
};
eprintln!("Dumped the manifest!");
return 0;
}
if command_name == "get-package-list" {
let input_file_path = match args.get("input_file") {
Some(input_file_path) => input_file_path,
None => {
eprintln!("an input file is required!");
return 1;
}
};
ctx.content = match fs::read_to_string(path::Path::new(input_file_path)) {
Ok(content) => content,
Err(e) => {
eprintln!("could not read file {}.", input_file_path);
return 1;
}
};
if args.contains_key("input_format") {
let source_type = args.get("input_format").unwrap();
if !crate::manifests::has_type(source_type.to_string()) {
eprintln!("{} is an invalid manifest type.", source_type);
return 1;
}
ctx.source_type = source_type.to_string();
} else {
let mut exit_code: i32 = manifests::detect_type(&mut ctx);
if exit_code != 0 {
eprintln!("Could not detect manifest type of {}.", ctx.source_filename);
return exit_code;
}
}
let mut exit_code: i32 = manifests::parse(&mut ctx);
if exit_code != 0 {
eprintln!("Error while parsing");
return exit_code;
}
eprintln!("Parsing finished. Resulting manifest is {:#?}", &ctx.manifest);
let mut separator = DEFAULT_PACKAGE_LIST_SEP;
if args.contains_key("separator") {
separator = args.get("separator").unwrap();
}
exit_code = manifests::get_modules(&mut ctx);
if exit_code != 0 {
eprintln!("Error while getting modules");
return exit_code;
}
let mut output: String = String::from("");
for module in &ctx.manifest.depends_on {
if !output.is_empty() {
output.push_str(&separator)
}
output.push_str(&module.name);
}
println!("{}", output);
}
if command_name == "projects" {
let projects: Vec<crate::projects::project::Project> = crate::projects::db::get_all();
for project in projects {
println!("{0}: {1}", project.name, project.summary);
}
return 0;
}
if command_name == "install" {
let input_file_path = match args.get("input_file") {
Some(input_file_path) => input_file_path,
None => {
eprintln!("an input file is required!");
return 1;
}
};
ctx.content = match fs::read_to_string(path::Path::new(input_file_path)) {
Ok(content) => content,
Err(e) => {
eprintln!("could not read file {}.", input_file_path);
return 1;
}
};
if args.contains_key("input_format") {
let source_type = args.get("input_format").unwrap();
if !crate::manifests::has_type(source_type.to_string()) {
eprintln!("{} is an invalid manifest type.", source_type);
return 1;
}
ctx.source_type = source_type.to_string();
} else {
let mut exit_code: i32 = manifests::detect_type(&mut ctx);
if exit_code != 0 {
eprintln!("Could not detect manifest type of {}.", ctx.source_filename);
return exit_code;
}
}
let mut exit_code: i32 = manifests::parse(&mut ctx);
if exit_code != 0 {
eprintln!("Error while parsing");
return exit_code;
}
eprintln!("Parsing finished. Resulting manifest is {:#?}", &ctx.manifest);
let config = match crate::execution_context::read_or_init_config() {
Ok(c) => c,
Err(e) => panic!("Could not load or init config: {}", e),
};
let package_name = match args.get("package_name") {
Some(package_name) => package_name,
None => {
eprintln!("A package name to install is required!");
return 1;
}
};
if package_name.len() < 3 {
eprintln!("{} is too short for a package name!", package_name);
return 1;
}
eprintln!("Installing module {:#?}", &package_name);
let packages: Vec<crate::manifests::manifest::AbstractModule> = crate::projects::get_modules();
eprintln!("Searching in {:#?} packages for installation candidates 🕰", packages.len());
for package in &packages {
if package.name.contains(package_name) {
println!("found candidate artifact in {}.", package.name);
}
}
return 0;
}
if command_name == "ls" {
let git_cache_dir = path::Path::new(DEFAULT_GIT_CACHE_DIR);
if !git_cache_dir.is_dir() {
eprintln!("This does not seem like a git project (.git/ was not found).");
return 1;
}
let mut found_manifest = false;
let file_paths = match utils::get_all_paths(path::Path::new("./")) {
Ok(paths) => paths,
Err(message) => {
eprintln!("Could not get the file paths :sad: {}", message);
return 1;
}
};
for path in file_paths.iter() {
let file_path = path;
let file_path_str = file_path.to_str().unwrap();
if file_path.is_dir() {
continue;
}
if crate::manifests::debian::file_path_matches(file_path_str) {
found_manifest = true;
println!("debian ({})", file_path_str);
}
if crate::manifests::snap::file_path_matches(file_path_str) {
found_manifest = true;
println!("snap ({})", file_path_str);
}
if crate::manifests::flatpak::file_path_matches(file_path_str) {
found_manifest = true;
println!("flatpak ({})", file_path_str);
}
}
if !found_manifest {
eprintln!("No available workspace found for the project. Try running `ls -p`.");
} else {
println!("Use `checkout` to select a workspace.");
}
}
if command_name == "checkout" {
let mut config = match crate::execution_context::read_or_init_config() {
Ok(c) => c,
Err(e) => panic!("Could not load or init config: {}", e),
};
let env_name = match args.get("env_name") {
Some(n) => n,
None => panic!("An env name is required to checkout."),
};
config.current_workspace = Some(env_name.to_string());
match crate::execution_context::write_config(&config) {
Ok(c) => c,
Err(e) => panic!("Could not write config: {}", e),
};
}
if command_name == "create" {
let cache_dir = path::Path::new(DEFAULT_CACHE_DIR);
if !cache_dir.is_dir() {
match fs::create_dir(cache_dir) {
Ok(_) => {}
Err(e) => panic!("Could not create cache dir at {}", DEFAULT_CACHE_DIR),
};
}
let current_workspace_file_path = DEFAULT_CACHE_DIR.to_owned() + "/workspace";
let current_workspace_file_path = path::Path::new(¤t_workspace_file_path);
if current_workspace_file_path.is_file() {
let current_workspace = match fs::read_to_string(current_workspace_file_path) {
Ok(content) => content,
Err(e) => {
eprintln!("could not read workspace file {}.", e);
return 1;
}
};
} else {
println!("No active workspace. Call `ls` to show the available workspaces.");
}
}
if command_name == "status" {
let mut config = match crate::execution_context::read_or_init_config() {
Ok(c) => c,
Err(e) => panic!("Could not load or init config: {}", e),
};
match config.current_workspace {
Some(workspace) => println!("Current workspace is {}.", workspace),
None => println!("No current workspace. Call `ls` to list the available manifests."),
};
}
return 0;
}