mycodee-project_manager 0.1.1

A tool for management of projects
Documentation
use {
    super::{configuration, fs, parser, Path},
    std::io::Read,
    std::process::{Command, Output},
};

pub fn get_templates(path: String) -> Vec<configuration::Template> {
    let mut templates: Vec<configuration::Template> = Vec::new();
    let files = fs::read_dir(path);

    if files.is_err() {
        eprintln!("File is error {:?}", files.expect_err(""));
        return templates;
    }

    let files = files.expect("");

    for file in files {
        if file.is_err() {
            continue;
        }

        let file = file.expect("");

        let metadata = file.metadata().expect("Can not get the metadata");

        if metadata.is_dir().clone() {
            let temps = get_templates(
                file.path()
                    .to_str()
                    .expect("Failed to get path")
                    .to_string(),
            );

            for temp in temps {
                templates.push(temp);
            }
        }

        if metadata.is_file() {
            let content = fs::read(file.path());

            if content.is_err() {
                continue;
            }

            let template = configuration::Template::from_binary(&content.expect(""));

            if template.is_none() {
                continue;
            }

            templates.push(template.expect(""));
        }
    }

    templates
}

pub fn get_config(path: String) -> Option<configuration::Configuration> {
    let file = fs::File::open(&path);
    let mut buffer: Vec<u8> = Vec::new();

    if file.is_err() {
        return None;
    }

    let read_result = file.expect("").read_to_end(&mut buffer);

    if read_result.is_err() {
        return None;
    }

    configuration::Configuration::from_binary(&buffer)
}

pub fn get_project_names(config: configuration::Template) -> Vec<String> {
    let mut project_names: Vec<String> = Vec::new();
    let dir = Path::new(&config.projects_dir);

    match fs::read_dir(dir) {
        Ok(files) => {
            for file in files {
                if file.is_err() {
                    continue;
                }

                let file = file.expect("Failed to get metadata");

                if file.metadata().expect("").is_dir() != true {
                    continue;
                }

                project_names.push(
                    file.file_name()
                        .into_string()
                        .expect("Failed to convert")
                        .to_string(),
                );
            }
        }
        Err(err) => {
            eprintln!("Error while reading dir: {:?}", err)
        }
    };

    project_names
}

pub fn get_arguments(
    fullname: String,
    alias: String,
    args: parser::Arguments,
) -> Option<parser::ArgumentTypes> {
    if args.contains_key(&fullname).clone() {
        let result = args.get(&fullname);

        if result.is_some() {
            return Some(result.expect("").clone());
        }

        return None;
    }

    let result = args.get(&alias);

    if result.is_some() {
        return Some(result.expect("").clone());
    }

    return None;
}

pub fn save_template(path: String, template: configuration::Template) {
    let path = format!("{}\\{}.template", path, template.language.clone());
    let path = Path::new(&path);

    fs::write(
        path,
        template
            .to_binary()
            .expect("Failed to convert template to save format"),
    )
    .expect("Failed to save template");
}

pub fn delete_template(path: String, name: String) {
    let path = format!("{}\\{}.template", path, name);
    let path = Path::new(&path);

    if !path.exists() {
        return;
    }

    fs::remove_file(path).expect("Failed to delete template")
}

pub fn create_project(name: String, template: configuration::Template) {
    let path = Path::new(&template.projects_dir);
    let project_dir = path.join(name.clone());

    if !path.exists() {
        fs::create_dir_all(&path).expect("Failed to create directory")
    }

    if project_dir.exists() {
        println!("Project exists already");
        return;
    }

    fs::create_dir_all(&project_dir).expect("Failed to create directory");

    for command in template.clone().commands {
        execute_command_in_directory(project_dir.clone().display().to_string(), command);
    }

    for (from, to) in template.clone().copy_files {
        fs::copy(from, project_dir.join(to)).expect("Failed to copy files");
    }

    open_project(
        project_dir
            .to_str()
            .expect("Failed to parse String")
            .to_string(),
        template.editor_open,
    );
}

fn execute_command_in_directory(path: String, cmd: String) -> Output {
    let mut command = if cfg!(target_os = "windows") {
        let mut command = Command::new("cmd.exe");
        command.arg("/C");

        command
    } else {
        let mut command = Command::new("bash");
        command.arg("-C");

        command
    };

    command.current_dir(path);

    command.arg(cmd);

    command.output().expect("Failed to spawn a process")
}

pub fn open_project(path: String, editor: String) {
    println!("{} {}", &path, &editor);
    execute_command_in_directory(path, editor);
}

pub fn delete_project(name: String, template: configuration::Template) {
    let path = Path::new(&template.projects_dir).join(name);

    if !path.exists() {
        return;
    }

    fs::remove_dir_all(path).expect("Failed to remove the project");
}