Update main.rs
removed hour counting stuff, because it was dumb, and re-worked how it finds the save folders so it doesn't dynamically build them, instead saves them in the settings. Also re-worked the install script to be better.
This commit is contained in:
@@ -3,9 +3,7 @@ use std::fs;
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::time;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
|
||||||
use std::time::SystemTime;
|
|
||||||
use clearscreen::clear;
|
use clearscreen::clear;
|
||||||
use directories::UserDirs;
|
use directories::UserDirs;
|
||||||
use clearscreen;
|
use clearscreen;
|
||||||
@@ -16,8 +14,6 @@ struct Project{
|
|||||||
project_name: String,
|
project_name: String,
|
||||||
notes_folder: PathBuf,
|
notes_folder: PathBuf,
|
||||||
files_folder: PathBuf,
|
files_folder: PathBuf,
|
||||||
activativation_time: SystemTime,
|
|
||||||
hour_count: Duration,
|
|
||||||
active: bool,
|
active: bool,
|
||||||
boxname: String,
|
boxname: String,
|
||||||
id: i32,
|
id: i32,
|
||||||
@@ -29,22 +25,45 @@ fn install(config_path: &PathBuf){
|
|||||||
let mut config_folder_path: PathBuf = config_path.clone();
|
let mut config_folder_path: PathBuf = config_path.clone();
|
||||||
config_folder_path.pop();
|
config_folder_path.pop();
|
||||||
let mut projects_conf_path = config_folder_path.clone();
|
let mut projects_conf_path = config_folder_path.clone();
|
||||||
|
let del_on_fail = config_folder_path.clone();
|
||||||
projects_conf_path.push("projects.conf");
|
projects_conf_path.push("projects.conf");
|
||||||
fs::create_dir_all(config_folder_path).expect("error creating config dir");
|
fs::create_dir_all(config_folder_path).expect("error creating config dir");
|
||||||
let mut config_file = fs::File::create(config_path).expect("error creating file");
|
let mut config_file = fs::File::create(config_path).expect("error creating file");
|
||||||
let mut projects_conf_file = fs::File::create(projects_conf_path).expect("error creating projects config file");
|
let mut projects_conf_file = fs::File::create(projects_conf_path).expect("error creating projects config file");
|
||||||
projects_conf_file.write_all(b"customer:name:time").expect("error writing default project info");
|
projects_conf_file.write_all(b"customer:name:notes:files:active:box_name\n").expect("error writing default project info");
|
||||||
let mut notes_response = String::new();
|
let mut notes_response = String::new();
|
||||||
let mut files_response = String::new();
|
let mut files_response = String::new();
|
||||||
let mut tools_response = String::new();
|
let mut tools_response = String::new();
|
||||||
|
let mut template_name = String::new();
|
||||||
|
let mut have_template = String::new();
|
||||||
println!("path to save project notes?");
|
println!("path to save project notes?");
|
||||||
std::io::stdin().read_line(&mut notes_response).unwrap();
|
std::io::stdin().read_line(&mut notes_response).unwrap();
|
||||||
println!("path to save project files?");
|
println!("path to save project files?");
|
||||||
std::io::stdin().read_line(&mut files_response).unwrap();
|
std::io::stdin().read_line(&mut files_response).unwrap();
|
||||||
println!("path to folder with your custom tools?");
|
println!("path to folder with your custom tools?");
|
||||||
std::io::stdin().read_line(&mut tools_response).unwrap();
|
std::io::stdin().read_line(&mut tools_response).unwrap();
|
||||||
|
print!("
|
||||||
|
This tool is mainly to handle distrobox creation and usage.
|
||||||
|
It's expecting you to have a distrobox that you will use as a template.
|
||||||
|
Do you have a distrobox set up to function as your template for all new projects?
|
||||||
|
");
|
||||||
|
std::io::stdin().read_line(&mut have_template).unwrap();
|
||||||
|
if have_template.contains("n"){
|
||||||
|
println!("please set up a distrobox with root as a template and re-run this tool");
|
||||||
|
println!("example distrobox setup command:");
|
||||||
|
println!("distrobox create --root --image archlinux --name template");
|
||||||
|
println!("then enter that distrobox and install all the tools you want and do what ever setup you need");
|
||||||
|
println!("and re-run this tool.");
|
||||||
|
process::Command::new("rm").arg(del_on_fail).spawn().expect("ERROR deleting config folder, please manually clean up");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
let _list = process::Command::new("distrobox").arg("list").arg("--root").status();
|
||||||
|
println!("distrobox template name?");
|
||||||
|
std::io::stdin().read_line(&mut template_name).unwrap();
|
||||||
let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end());
|
let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end());
|
||||||
config_file.write_all(config_string.as_bytes()).expect("error writing to config file");
|
config_file.write_all(config_string.as_bytes()).expect("error writing to config file");
|
||||||
|
let default_projectline = format!("default:default:{}:{}:yes:{}", ¬es_response.trim_end(), &files_response.trim_end(), &template_name.trim_end());
|
||||||
|
projects_conf_file.write_all(default_projectline.as_bytes()).expect("error writing default project line");
|
||||||
println!("config file generated and saved to {}\n", config_path.display());
|
println!("config file generated and saved to {}\n", config_path.display());
|
||||||
println!("please make sure to install distrobox:\nhttps://github.com/89luca89/distrobox\n\nthis will require either docker or podman as well.\n\n");
|
println!("please make sure to install distrobox:\nhttps://github.com/89luca89/distrobox\n\nthis will require either docker or podman as well.\n\n");
|
||||||
println!("please rerun the program");
|
println!("please rerun the program");
|
||||||
@@ -52,7 +71,7 @@ fn install(config_path: &PathBuf){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut PathBuf) -> Vec<Project>{
|
fn get_projects(config_path: &mut PathBuf) -> Vec<Project>{
|
||||||
config_path.pop();
|
config_path.pop();
|
||||||
config_path.push("projects.conf");
|
config_path.push("projects.conf");
|
||||||
let mut projects = Vec::new();
|
let mut projects = Vec::new();
|
||||||
@@ -66,22 +85,17 @@ fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut Pa
|
|||||||
let settings: Vec<&str> = line.split(":").collect();
|
let settings: Vec<&str> = line.split(":").collect();
|
||||||
let customer = settings[0].to_owned();
|
let customer = settings[0].to_owned();
|
||||||
let project = settings[1].to_owned();
|
let project = settings[1].to_owned();
|
||||||
let folder_name = format!("{}/{}", customer, project);
|
let notes_string = settings[2].to_owned();
|
||||||
let mut notes_folder = base_notes.clone();
|
let folder_string = settings[3].to_owned();
|
||||||
let mut project_folder = base_files.clone();
|
let notes_folder = PathBuf::from_str(¬es_string.trim_end()).expect("error reading notes string");
|
||||||
notes_folder.push(&folder_name);
|
let project_folder = PathBuf::from_str(&folder_string.trim_end()).expect("error reading folding sering");
|
||||||
project_folder.push(&folder_name);
|
|
||||||
let hours_count:u64 = settings[3].trim_end().parse().expect("error converting to u64");
|
|
||||||
let secs_count = hours_count * 60;
|
|
||||||
let hours = Duration::from_secs(secs_count);
|
|
||||||
let mut active = false;
|
let mut active = false;
|
||||||
let boxname = settings[4].to_owned();
|
let boxname = settings[5].to_owned();
|
||||||
if settings[2] == "yes"{
|
if settings[4] == "yes"{
|
||||||
env::set_var("CURRENT_PROJECT_BOX", boxname.clone());
|
env::set_var("CURRENT_PROJECT_BOX", boxname.clone());
|
||||||
active = true;
|
active = true;
|
||||||
}
|
}
|
||||||
let time = SystemTime::now();
|
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, active: active, id: first, boxname: boxname};
|
||||||
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, activativation_time: time, hour_count: hours, active: active, id: first, boxname: boxname};
|
|
||||||
println!("{} {} LOADED!", &new_project.customer, &new_project.project_name);
|
println!("{} {} LOADED!", &new_project.customer, &new_project.project_name);
|
||||||
projects.push(new_project);
|
projects.push(new_project);
|
||||||
}
|
}
|
||||||
@@ -127,16 +141,15 @@ fn save_projects(projects: &Vec<Project>, config_path: &PathBuf){
|
|||||||
save_file_path.pop();
|
save_file_path.pop();
|
||||||
save_file_path.push("projects.conf");
|
save_file_path.push("projects.conf");
|
||||||
let mut save_file = fs::File::create(save_file_path).expect("error creating save_file");
|
let mut save_file = fs::File::create(save_file_path).expect("error creating save_file");
|
||||||
save_file.write_all(b"customer:name:active:hours:box_name\n").expect("error writing first line to file");
|
save_file.write_all(b"customer:name:notes:files:active:time:box_name\n").expect("error writing first line to file");
|
||||||
for project in projects{
|
for project in projects{
|
||||||
let default = format!{"{}:{}:", project.customer, project.project_name};
|
let default = format!{"{}:{}:{}:{}:", project.customer, project.project_name, project.notes_folder.display(), project.files_folder.display()};
|
||||||
let mut _outline = String::new();
|
let mut _outline = String::new();
|
||||||
if project.active{
|
if project.active{
|
||||||
let hours = project.hour_count.as_secs()/60 + time::SystemTime::now().duration_since(project.activativation_time).expect("error caclucating hours").as_secs()/60;
|
_outline = format!("{}yes:{}\n", default, project.boxname);
|
||||||
_outline = format!("{}yes:{}:{}\n", default, hours, project.boxname);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
_outline = format!("{}no:{}:{}\n", default, project.hour_count.as_secs()/60, project.boxname);
|
_outline = format!("{}no:{}\n", default, project.boxname);
|
||||||
}
|
}
|
||||||
save_file.write_all(_outline.as_bytes()).expect("error writing outline");
|
save_file.write_all(_outline.as_bytes()).expect("error writing outline");
|
||||||
}
|
}
|
||||||
@@ -231,6 +244,10 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
|
|||||||
else{
|
else{
|
||||||
println!("failed to copy the notes folder, try to move it manually!");
|
println!("failed to copy the notes folder, try to move it manually!");
|
||||||
}
|
}
|
||||||
|
new_project_dir.push(&customer_name);
|
||||||
|
new_note_dir.push(&customer_name);
|
||||||
|
new_project_dir.push(&project_name);
|
||||||
|
new_note_dir.push(&project_name);
|
||||||
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -240,9 +257,12 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
|
|||||||
new_note_dir.push(&project_name);
|
new_note_dir.push(&project_name);
|
||||||
fs::create_dir_all(&new_project_dir).expect("error creating new files folder");
|
fs::create_dir_all(&new_project_dir).expect("error creating new files folder");
|
||||||
fs::create_dir_all(&new_note_dir).expect("error creating new notes folder");
|
fs::create_dir_all(&new_note_dir).expect("error creating new notes folder");
|
||||||
|
|
||||||
}
|
}
|
||||||
let box_name = format!("atarchbox_{}", customer_name);
|
let box_name = format!("atarchbox_{}", customer_name);
|
||||||
|
let mut box_name_path = new_project_dir.clone();
|
||||||
|
box_name_path.push("boxname");
|
||||||
|
let mut box_name_file = fs::File::create(box_name_path).expect("Error creating box name file");
|
||||||
|
box_name_file.write_all(&box_name.as_bytes()).expect("error writing boxname to box file");
|
||||||
let pentest_volume = format!("{}:/pentest:rw", new_project_dir.display());
|
let pentest_volume = format!("{}:/pentest:rw", new_project_dir.display());
|
||||||
let toold_volume = format!("{}:/tools:rw", tools_dir.display());
|
let toold_volume = format!("{}:/tools:rw", tools_dir.display());
|
||||||
println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, toold_volume, pentest_volume, box_name);
|
println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, toold_volume, pentest_volume, box_name);
|
||||||
@@ -265,6 +285,13 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
|
|||||||
.arg("enter")
|
.arg("enter")
|
||||||
.arg("--root")
|
.arg("--root")
|
||||||
.arg(&box_name)
|
.arg(&box_name)
|
||||||
|
.arg("--")
|
||||||
|
.arg("sudo")
|
||||||
|
.arg("-s")
|
||||||
|
.arg("ln")
|
||||||
|
.arg("-sf")
|
||||||
|
.arg("/pentest/boxname")
|
||||||
|
.arg("/etc/boxname")
|
||||||
.status()
|
.status()
|
||||||
.expect("error getting response from distrobox start");
|
.expect("error getting response from distrobox start");
|
||||||
if distrobox_start_result.success(){
|
if distrobox_start_result.success(){
|
||||||
@@ -281,8 +308,6 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
|
|||||||
project_name: project_name.trim_end().to_owned(),
|
project_name: project_name.trim_end().to_owned(),
|
||||||
notes_folder: new_note_dir,
|
notes_folder: new_note_dir,
|
||||||
files_folder:new_project_dir,
|
files_folder:new_project_dir,
|
||||||
activativation_time: SystemTime::now(),
|
|
||||||
hour_count: Duration::new(1, 1),
|
|
||||||
active: false,
|
active: false,
|
||||||
id: new_id,
|
id: new_id,
|
||||||
boxname: box_name,
|
boxname: box_name,
|
||||||
@@ -307,11 +332,12 @@ fn remove_project(projects: &mut Vec<Project>){
|
|||||||
if project.id == remove_id{
|
if project.id == remove_id{
|
||||||
println!("will remove {} {}", project.customer, project.project_name);
|
println!("will remove {} {}", project.customer, project.project_name);
|
||||||
project_set = true;
|
project_set = true;
|
||||||
|
let _distrobox_stop_status = process::Command::new("distrobox").arg("stop").arg("--root").arg(&project.boxname).status().expect("error stopping distrobox");
|
||||||
let distrobox_rm_status = process::Command::new("distrobox")
|
let distrobox_rm_status = process::Command::new("distrobox")
|
||||||
.arg("rm")
|
.arg("rm")
|
||||||
.arg("--root")
|
.arg("--root")
|
||||||
.arg("-f")
|
.arg("-f")
|
||||||
.arg(project.boxname)
|
.arg(&project.boxname)
|
||||||
.status().expect("error calling distrobox");
|
.status().expect("error calling distrobox");
|
||||||
if distrobox_rm_status.success(){
|
if distrobox_rm_status.success(){
|
||||||
println!("Distrobox Removal Successful!!!");
|
println!("Distrobox Removal Successful!!!");
|
||||||
@@ -410,14 +436,6 @@ fn print_report_information(project: Project){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_hour_counters(projects: &mut Vec<Project>){
|
|
||||||
println!("Clearing Counters, please esure these times are in sales force...");
|
|
||||||
for project in projects{
|
|
||||||
println!("{} {}: {}", project.customer, project.project_name, project.hour_count.as_secs()/60/60);
|
|
||||||
project.hour_count = Duration::ZERO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn project_standalone_terminal(project: Project){
|
fn project_standalone_terminal(project: Project){
|
||||||
@@ -430,6 +448,32 @@ fn project_inline_terminal(project: Project){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn gnerate_userpass(project: &Project){
|
||||||
|
let mut outlines = Vec::new();
|
||||||
|
let mut notes_file = project.notes_folder.clone();
|
||||||
|
notes_file.push("l00t/creds.md");
|
||||||
|
let loot_string = fs::read_to_string(notes_file).expect("error reading creds note");
|
||||||
|
let clear_text = loot_string.split("# hashed").collect::<Vec<&str>>()[0];
|
||||||
|
let clear_text_table = clear_text.split("| ----------------------------------- | ------------- | ----------------------------- |").collect::<Vec<&str>>()[1];
|
||||||
|
let table_vec: Vec<&str> = clear_text_table.split("\n").collect();
|
||||||
|
for line in table_vec{
|
||||||
|
if line.len() > 1{
|
||||||
|
let split_line: Vec<&str> = line.split("|").collect();
|
||||||
|
let user = split_line[2].trim_end().trim_start();
|
||||||
|
let password = split_line[3].trim_end().trim_start();
|
||||||
|
let outline = format!("{}:{}\n", user, password);
|
||||||
|
outlines.push(outline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut out_file_path = project.files_folder.clone();
|
||||||
|
out_file_path.push("working/userpass_fromnotes.txt");
|
||||||
|
let mut out_file = fs::File::create(out_file_path).expect("error creating userpass file");
|
||||||
|
for line in outlines{
|
||||||
|
out_file.write_all(line.as_bytes()).expect("error writing to userpass file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn main_menu(mut projects: Vec<Project>, config_path: &PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String){
|
fn main_menu(mut projects: Vec<Project>, config_path: &PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String){
|
||||||
let mut loopize = true;
|
let mut loopize = true;
|
||||||
loop {
|
loop {
|
||||||
@@ -487,27 +531,24 @@ NOTE SAVE PROJECT INFO BEFORE STOPPING THE APPLICATION, OR HOUR TRACKIGN WON'T B
|
|||||||
NOTE OPTION 10 WILL SAVE YOUR PROJECTS BEFORE QUITTING
|
NOTE OPTION 10 WILL SAVE YOUR PROJECTS BEFORE QUITTING
|
||||||
|
|
||||||
Current Project: {} {}
|
Current Project: {} {}
|
||||||
Current Minutes: {} minutes
|
|
||||||
|
|
||||||
Main Menu:
|
Main Menu:
|
||||||
1 .) Show Active Project
|
1 .) Show Active Project
|
||||||
2 .) List Projects
|
2 .) List Projects
|
||||||
3 .) Switch Active Project
|
3 .) Switch Active Project
|
||||||
4 .) Print Active Project Time
|
4 .) create new project with Pyro's default tool
|
||||||
5 .) Print All Proejct Times
|
5 .) Save Project Information
|
||||||
6 .) create new project with Pyro's default tool
|
6 .) Import New Project - and setup new Distrobox
|
||||||
7 .) Save Project Information
|
7 .) Remove Project
|
||||||
8 .) Import New Project - and setup new Distrobox
|
8 .) Open A New Terminal in Current Active Project
|
||||||
9 .) Remove Project
|
9 .) Open A Terminal In this windows for the current active project
|
||||||
10.) Open A New Terminal in Current Active Project
|
10.) Open Project Files Folder In Dolphin
|
||||||
11.) Open A Terminal In this windows for the current active project
|
11.) Open Project Notes Folder In Dolphin
|
||||||
12.) Open Project Files Folder In Dolphin
|
12.) generate userpass file from your obsidian notes
|
||||||
13.) Open Project Notes Folder In Dolphin
|
13.) Print Project Info For Report
|
||||||
14.) Print Project Info For Report
|
14.) Stop All Distroboxes
|
||||||
15.) Stop All Distroboxes
|
15.) Quit Application
|
||||||
16.) Reset Hour Counters
|
\n", active_project.customer, active_project.project_name);
|
||||||
17.) Quit Application
|
|
||||||
\n", active_project.customer, active_project.project_name, SystemTime::now().duration_since(active_project.activativation_time).unwrap().as_secs() / 60);
|
|
||||||
std::io::stdin().read_line(&mut response).expect("error getting menu input");
|
std::io::stdin().read_line(&mut response).expect("error getting menu input");
|
||||||
clear().expect("error clearing screen");
|
clear().expect("error clearing screen");
|
||||||
match response.as_str().trim_end(){
|
match response.as_str().trim_end(){
|
||||||
@@ -517,30 +558,18 @@ Current Minutes: {} minutes
|
|||||||
println!("++{}|{}++",project.customer ,project.project_name)}
|
println!("++{}|{}++",project.customer ,project.project_name)}
|
||||||
println!("++++++++++++++++++++")},
|
println!("++++++++++++++++++++")},
|
||||||
"3" => switch_project(&mut projects),
|
"3" => switch_project(&mut projects),
|
||||||
"4" => println!("current Hour Count: {}", active_project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(active_project.activativation_time).expect("error caclucating hours").as_secs()/3600),
|
"4" => start_pentest(),
|
||||||
"5" => {println!("++++++++++++++++++++");
|
"5" => save_projects(&projects, &config_path),
|
||||||
for project in &projects{
|
"6" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate),
|
||||||
if project.active == true{
|
"7" => remove_project(&mut projects),
|
||||||
println!("++{} {}: {}++", project.customer, project.project_name, project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(project.activativation_time).expect("error caclucating hours").as_secs()/3600);
|
"8" => project_standalone_terminal(active_project.clone()),
|
||||||
}
|
"9" => project_inline_terminal(active_project.clone()),
|
||||||
else{
|
"10" => open_in_dolphin("files", active_project.clone()),
|
||||||
println!("++{} {}:{}++", project.customer, project.project_name, project.hour_count.as_secs()/3600);
|
"11" => open_in_dolphin("notes", active_project.clone()),
|
||||||
}
|
"12" => gnerate_userpass(&active_project),
|
||||||
}
|
"13" => print_report_information(active_project.clone()),
|
||||||
println!("++++++++++++++++++++")
|
"14" => stop_all_boxes(&projects),
|
||||||
},
|
"15" => {save_projects(&projects, &config_path);
|
||||||
"6" => start_pentest(),
|
|
||||||
"7" => save_projects(&projects, &config_path),
|
|
||||||
"8" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate),
|
|
||||||
"9" => remove_project(&mut projects),
|
|
||||||
"10" => project_standalone_terminal(active_project.clone()),
|
|
||||||
"11" => project_inline_terminal(active_project.clone()),
|
|
||||||
"12" => open_in_dolphin("files", active_project.clone()),
|
|
||||||
"13" => open_in_dolphin("notes", active_project.clone()),
|
|
||||||
"14" => print_report_information(active_project.clone()),
|
|
||||||
"15" => stop_all_boxes(&projects),
|
|
||||||
"16" => reset_hour_counters(&mut projects),
|
|
||||||
"17" => {save_projects(&projects, &config_path);
|
|
||||||
let mut stop = String::new();
|
let mut stop = String::new();
|
||||||
println!("stop all boxes?\ny/n");
|
println!("stop all boxes?\ny/n");
|
||||||
std::io::stdin().read_line(&mut stop).unwrap();
|
std::io::stdin().read_line(&mut stop).unwrap();
|
||||||
@@ -613,7 +642,7 @@ fn main() {
|
|||||||
distrobox template: {}\n
|
distrobox template: {}\n
|
||||||
", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template);
|
", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template);
|
||||||
println!("loading project configs...");
|
println!("loading project configs...");
|
||||||
let projects = get_projects(&project_base_notes, &project_base_folder, &mut config_path);
|
let projects = get_projects(&mut config_path);
|
||||||
println!("Enter to start main menu");
|
println!("Enter to start main menu");
|
||||||
let mut enter = String::new();
|
let mut enter = String::new();
|
||||||
std::io::stdin().read_line(&mut enter).unwrap();
|
std::io::stdin().read_line(&mut enter).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user