From fdeca280e7b02c6befea9ca88980ac519021a552 Mon Sep 17 00:00:00 2001 From: Klimenty Titov Date: Wed, 18 Dec 2024 20:51:38 +0300 Subject: [PATCH 1/7] Change inner consts --- src/build.rs | 18 +++++++++--------- src/main.rs | 39 +++++++++++++++++++++------------------ src/rw.rs | 6 ++---- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/build.rs b/src/build.rs index 12d0273..232bfe9 100644 --- a/src/build.rs +++ b/src/build.rs @@ -2,7 +2,7 @@ use colored::Colorize; use std::path::PathBuf; use uuid::Uuid; -use crate::{DEPLOY_CACHE_SUBDIR, DEPLOY_ARTIFACTS_SUBDIR, DEPLOY_CONF_FILE}; +use crate::{CACHE_DIR, ARTIFACTS_DIR, PROJECT_CONF}; use crate::actions::*; use crate::entities::{ traits::Execute, @@ -19,7 +19,7 @@ fn enplace_artifacts( env: BuildEnvironment, panic_when_not_found: bool, ) -> anyhow::Result<()> { - let mut ignore = vec![DEPLOY_ARTIFACTS_SUBDIR]; + let mut ignore = vec![ARTIFACTS_DIR]; ignore.extend_from_slice(&(config.cache_files.iter().map(|c| c.as_str()).collect::>())); for (from, to) in &config.inplace_artifacts_into_project_root { @@ -37,7 +37,7 @@ fn enplace_artifacts( pub(crate) fn prepare_artifacts_folder( current_dir: &std::path::Path, ) -> anyhow::Result { - let artifacts_dir = current_dir.join(DEPLOY_ARTIFACTS_SUBDIR); + let artifacts_dir = current_dir.join(ARTIFACTS_DIR); std::fs::create_dir_all(artifacts_dir.as_path()).unwrap_or_else(|_| panic!("Can't create `{:?}` folder!", artifacts_dir)); Ok(artifacts_dir) @@ -54,7 +54,7 @@ pub(crate) fn prepare_build_folder( ) -> anyhow::Result { let mut build_path = PathBuf::new(); build_path.push(cache_dir); - build_path.push(DEPLOY_CACHE_SUBDIR); + build_path.push(CACHE_DIR); if !build_path.exists() { *new_build = true; } std::fs::create_dir_all(build_path.as_path()).unwrap_or_else(|_| panic!("Can't create `{:?}` folder!", build_path)); @@ -74,11 +74,11 @@ pub(crate) fn prepare_build_folder( build_path.push(uuid.clone()); - let mut ignore = vec![DEPLOY_ARTIFACTS_SUBDIR, &uuid]; + let mut ignore = vec![ARTIFACTS_DIR, &uuid]; ignore.extend_from_slice(&config.cache_files.iter().map(|v| v.as_str()).collect::>()); copy_all(get_current_working_dir().unwrap(), build_path.as_path(), &ignore)?; - write(get_current_working_dir().unwrap(), DEPLOY_CONF_FILE, &config); + write(get_current_working_dir().unwrap(), PROJECT_CONF, &config); if link_cache { for cache_item in &config.cache_files { @@ -201,7 +201,7 @@ fn execute_pipeline( enplace_artifacts(config, env, false)?; let mut modified_env = env; - let artifacts_dir = modified_env.build_dir.to_path_buf().join(DEPLOY_ARTIFACTS_SUBDIR); + let artifacts_dir = modified_env.build_dir.to_path_buf().join(ARTIFACTS_DIR); modified_env.artifacts_dir = &artifacts_dir; enplace_artifacts(config, modified_env, false)?; @@ -246,7 +246,7 @@ pub(crate) fn clean_builds( ) -> anyhow::Result<()> { let mut path = PathBuf::new(); path.push(cache_dir); - path.push(DEPLOY_CACHE_SUBDIR); + path.push(CACHE_DIR); config.last_build = None; for build in &config.builds { @@ -258,7 +258,7 @@ pub(crate) fn clean_builds( if args.include_artifacts { let curr_dir = std::env::current_dir()?; - let artifacts_dir = curr_dir.join(DEPLOY_ARTIFACTS_SUBDIR); + let artifacts_dir = curr_dir.join(ARTIFACTS_DIR); if artifacts_dir.as_path().exists() { let _ = std::fs::remove_dir_all(artifacts_dir); } diff --git a/src/main.rs b/src/main.rs index 25bf6ba..a111e43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,10 +39,13 @@ use mimalloc::MiMalloc; #[global_allocator] static GLOBAL: MiMalloc = MiMalloc; -static DEPLOY_CONF_FILE: &str = "deploy-config.json"; -static DEPLOY_GLOBAL_CONF_FILE: &str = "deploy-global.json"; -pub(crate) static DEPLOY_CACHE_SUBDIR: &str = "deploy-cache"; -pub(crate) static DEPLOY_ARTIFACTS_SUBDIR: &str = "artifacts"; +static PROJECT_CONF: &str = "deploy-config.json"; +static GLOBAL_CONF: &str = "deploy-global.json"; + +pub(crate) static CACHE_DIR: &str = "deploy-cache"; +// pub(crate) static LOGS_DIR: &str = "logs"; + +pub(crate) static ARTIFACTS_DIR: &str = "artifacts"; #[cfg(not(unix))] compile_error!("`deployer` can't work with non-Unix systems."); @@ -87,59 +90,59 @@ fn main() { }; // Чтение конфигов - let mut globals = read::(&config_folder, DEPLOY_GLOBAL_CONF_FILE); - let mut config = read::(&get_current_working_dir().unwrap(), DEPLOY_CONF_FILE); + let mut globals = read::(&config_folder, GLOBAL_CONF); + let mut config = read::(&get_current_working_dir().unwrap(), PROJECT_CONF); match args.r#type { DeployerExecType::Ls(ListType::Actions) => list_actions(&globals), DeployerExecType::New(NewType::Action(args)) => { let _ = new_action(&mut globals, &args).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); + write(&config_folder, GLOBAL_CONF, &globals); }, DeployerExecType::Cat(CatType::Action(args)) => cat_action(&globals, &args).unwrap(), DeployerExecType::Edit(EditType::Action(args)) => { edit_action(&mut globals, &args).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); + write(&config_folder, GLOBAL_CONF, &globals); }, DeployerExecType::Rm(RemoveType::Action) => { remove_action(&mut globals).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); + write(&config_folder, GLOBAL_CONF, &globals); }, DeployerExecType::Ls(ListType::Pipelines) => list_pipelines(&globals).unwrap(), DeployerExecType::New(NewType::Pipeline(args)) => { new_pipeline(&mut globals, &args).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); + write(&config_folder, GLOBAL_CONF, &globals); }, DeployerExecType::Cat(CatType::Pipeline(args)) => cat_pipeline(&globals, &args).unwrap(), DeployerExecType::Edit(EditType::Pipeline(args)) => { edit_pipeline(&mut globals, &args).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); + write(&config_folder, GLOBAL_CONF, &globals); }, DeployerExecType::Rm(RemoveType::Pipeline) => { remove_pipeline(&mut globals).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); + write(&config_folder, GLOBAL_CONF, &globals); }, DeployerExecType::Init(args) => { init(&mut globals, &mut config, &args).unwrap(); - write(get_current_working_dir().unwrap(), DEPLOY_CONF_FILE, &config); + write(get_current_working_dir().unwrap(), PROJECT_CONF, &config); }, DeployerExecType::With(args) => { assign_pipeline_to_project(&mut globals, &mut config, &args).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); - write(get_current_working_dir().unwrap(), DEPLOY_CONF_FILE, &config); + write(&config_folder, GLOBAL_CONF, &globals); + write(get_current_working_dir().unwrap(), PROJECT_CONF, &config); }, DeployerExecType::Cat(CatType::Project) => cat_project_pipelines(&config).unwrap(), DeployerExecType::Edit(EditType::Project) => { edit_project(&mut globals, &mut config).unwrap(); - write(&config_folder, DEPLOY_GLOBAL_CONF_FILE, &globals); - write(get_current_working_dir().unwrap(), DEPLOY_CONF_FILE, &config); + write(&config_folder, GLOBAL_CONF, &globals); + write(get_current_working_dir().unwrap(), PROJECT_CONF, &config); }, DeployerExecType::Build(mut args) => build(&mut config, &cache_folder, &mut args).unwrap(), DeployerExecType::Clean(args) => { clean_builds(&mut config, &cache_folder, &args).unwrap(); - write(get_current_working_dir().unwrap(), DEPLOY_CONF_FILE, &config); + write(get_current_working_dir().unwrap(), PROJECT_CONF, &config); }, #[cfg(feature = "tests")] diff --git a/src/rw.rs b/src/rw.rs index c1eb9f0..9cb7df3 100644 --- a/src/rw.rs +++ b/src/rw.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::{BufReader, BufWriter}; use std::sync::OnceLock; use std::path::{Path, PathBuf}; -use crate::DEPLOY_CONF_FILE; +use crate::PROJECT_CONF; pub(crate) static VERBOSE: OnceLock = OnceLock::new(); @@ -77,10 +77,8 @@ pub(crate) fn copy_all(src: impl AsRef, dst: impl AsRef, ignore: &[& let d = dst.as_ref().join(entry.file_name()); if ty.is_dir() { copy_all(entry.path(), d, ignore)?; - } else if name == DEPLOY_CONF_FILE { - + } else if name == PROJECT_CONF { log(format!("Symlinking `{}` from {:?} to {:?}", name, entry.path(), d)); - symlink(std::fs::canonicalize(entry.path())?, d); } else if ty.is_file() { std::fs::copy(entry.path(), d)?; From aff153f7497b4a3c76d3da82e74f7ae5a9c64968 Mon Sep 17 00:00:00 2001 From: Klimenty Titov Date: Wed, 18 Dec 2024 20:52:06 +0300 Subject: [PATCH 2/7] Remove build args mutability --- src/build.rs | 2 +- src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/build.rs b/src/build.rs index 232bfe9..b3a0849 100644 --- a/src/build.rs +++ b/src/build.rs @@ -104,7 +104,7 @@ pub(crate) fn prepare_build_folder( pub(crate) fn build( config: &mut DeployerProjectOptions, cache_dir: &str, - args: &mut BuildArgs, + args: &BuildArgs, ) -> anyhow::Result<()> { if *config == Default::default() { panic!("Config is invalid!"); } diff --git a/src/main.rs b/src/main.rs index a111e43..60f498d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -139,7 +139,7 @@ fn main() { write(&config_folder, GLOBAL_CONF, &globals); write(get_current_working_dir().unwrap(), PROJECT_CONF, &config); }, - DeployerExecType::Build(mut args) => build(&mut config, &cache_folder, &mut args).unwrap(), + DeployerExecType::Build(args) => build(&mut config, &cache_folder, &args).unwrap(), DeployerExecType::Clean(args) => { clean_builds(&mut config, &cache_folder, &args).unwrap(); write(get_current_working_dir().unwrap(), PROJECT_CONF, &config); From 63a8a257116de5a2d6d4e587d66729b363e114db Mon Sep 17 00:00:00 2001 From: Klimenty Titov Date: Wed, 18 Dec 2024 20:52:32 +0300 Subject: [PATCH 3/7] Silent option overrides verbose mode --- src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 60f498d..50a9124 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,7 +64,8 @@ fn main() { let args = Cli::parse(); if args.verbose { - VERBOSE.set(true).unwrap(); + if let DeployerExecType::Build(build_args) = &args.r#type && build_args.silent { VERBOSE.set(false).unwrap(); } + else { VERBOSE.set(true).unwrap(); } } else { VERBOSE.set(false).unwrap(); } From 16cb01f823965749bb0e28ec7718d5d5b2c4b216 Mon Sep 17 00:00:00 2001 From: Klimenty Titov Date: Wed, 18 Dec 2024 20:53:24 +0300 Subject: [PATCH 4/7] Add support of several specified pipelines + remove all pipelines execution when no specified or default --- src/build.rs | 29 ++++++++++++----------------- src/cmd.rs | 5 +++-- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/build.rs b/src/build.rs index b3a0849..c19e112 100644 --- a/src/build.rs +++ b/src/build.rs @@ -120,13 +120,6 @@ pub(crate) fn build( let mut new_build = false; - if - let Some(pipeline_tag) = &args.pipeline_tag && - !config.pipelines.iter().any(|p| p.title.as_str() == pipeline_tag.as_str()) - { - panic!("There is no such Pipeline set up for this project. Maybe, you've forgotten `deployer with {{pipeline-short-name-and-ver}}`?"); - } - let curr_dir = std::env::current_dir().expect("Can't get current dir!"); let artifacts_dir = prepare_artifacts_folder(&curr_dir)?; let build_path = if args.current { curr_dir } else { @@ -141,21 +134,23 @@ pub(crate) fn build( no_pipe: args.no_pipe, }; - if - let Some(pipeline_tag) = &args.pipeline_tag && - let Some(pipeline) = config.pipelines.iter().find(|p| p.title.as_str() == pipeline_tag) - { - execute_pipeline(config, env, pipeline)?; - } else { + if args.pipeline_tags.is_empty() { if config.pipelines.is_empty() { - anyhow::bail!("The pipelines' list is empty! Check the config file for errors.") + panic!("The pipelines' list is empty! Check the config file for errors."); } - if let Some(pipeline) = &config.pipelines.iter().find(|p| p.default.is_some_and(|v| v)) { execute_pipeline(config, env, pipeline)?; - } else { - for pipeline in &config.pipelines { + } + } else { + for pipeline_tag in &args.pipeline_tags { + if let Some(pipeline) = config.pipelines.iter().find(|p| p.title.as_str().eq(pipeline_tag)) { execute_pipeline(config, env, pipeline)?; + } else { + panic!( + "There is no such Pipeline `{}` set up for this project. Maybe, you've forgotten set up this Pipeline for project via `{}`?", + pipeline_tag.green(), + "deployer with {pipeline-short-name-and-ver}".green(), + ); } } } diff --git a/src/cmd.rs b/src/cmd.rs index 39e55e4..6c2d934 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -138,8 +138,9 @@ pub(crate) struct CleanArgs { #[derive(Args, Debug)] pub(crate) struct BuildArgs { - /// {short-name} - pub(crate) pipeline_tag: Option, + /// {short-name} or {short-name1},{short-name2},.. + #[arg(required = false, value_delimiter(','))] + pub(crate) pipeline_tags: Vec, /// Build in current folder #[arg(short('j'), long)] From 3f317efe51d47e0dc9bbcef5bd702d0f7a2a60f7 Mon Sep 17 00:00:00 2001 From: Klimenty Titov Date: Wed, 18 Dec 2024 21:38:11 +0300 Subject: [PATCH 5/7] Remove YAML mentions --- src/actions.rs | 4 ++-- src/pipelines.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/actions.rs b/src/actions.rs index 772056a..b695f1a 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -716,8 +716,8 @@ pub(crate) fn cat_action( Some(action) => action, }; - let action_yaml = serde_json::to_string_pretty(&action).unwrap(); - println!("{}", action_yaml); + let action_json = serde_json::to_string_pretty(&action).unwrap(); + println!("{}", action_json); Ok(()) } diff --git a/src/pipelines.rs b/src/pipelines.rs index 5aebaba..e87fde0 100644 --- a/src/pipelines.rs +++ b/src/pipelines.rs @@ -271,8 +271,8 @@ pub(crate) fn cat_pipeline( Some(pipeline) => pipeline, }; - let pipeline_yaml = serde_json::to_string_pretty(&pipeline).unwrap(); - println!("{}", pipeline_yaml); + let pipeline_json = serde_json::to_string_pretty(&pipeline).unwrap(); + println!("{}", pipeline_json); Ok(()) } From 260aa46ab33956d2aa942f0e0347e3a5ee682909 Mon Sep 17 00:00:00 2001 From: Klimenty Titov Date: Wed, 18 Dec 2024 21:39:56 +0300 Subject: [PATCH 6/7] Add build log + make `project_name` is no longer optional --- Cargo.toml | 2 ++ src/build.rs | 28 ++++++++++++++++++------- src/configs.rs | 3 +-- src/entities/environment.rs | 1 + src/main.rs | 20 +++++++----------- src/project.rs | 4 ++-- src/rw.rs | 42 +++++++++++++++++++++++++++++++++++-- 7 files changed, 74 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c656ef2..d604f86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] anyhow = "1.0" +chrono = "0.4" clap = { version = "4.5", features = ["derive"] } colored = "2" dirs = "5.0" @@ -13,6 +14,7 @@ mimalloc = "0.1.43" regex = "1.11" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +strip-ansi-escapes = "0.2" uuid = { version = "1.11", features = ["v4", "fast-rng"] } [features] diff --git a/src/build.rs b/src/build.rs index c19e112..a7d2cfc 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,5 +1,5 @@ use colored::Colorize; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use uuid::Uuid; use crate::{CACHE_DIR, ARTIFACTS_DIR, PROJECT_CONF}; @@ -11,7 +11,7 @@ use crate::entities::{ use crate::cmd::{BuildArgs, CleanArgs}; use crate::configs::DeployerProjectOptions; use crate::pipelines::DescribedPipeline; -use crate::rw::{copy_all, write, symlink, log}; +use crate::rw::{copy_all, write, symlink, log, generate_build_log_filepath, build_log}; use crate::utils::get_current_working_dir; fn enplace_artifacts( @@ -34,7 +34,7 @@ fn enplace_artifacts( Ok(()) } -pub(crate) fn prepare_artifacts_folder( +fn prepare_artifacts_folder( current_dir: &std::path::Path, ) -> anyhow::Result { let artifacts_dir = current_dir.join(ARTIFACTS_DIR); @@ -43,10 +43,10 @@ pub(crate) fn prepare_artifacts_folder( Ok(artifacts_dir) } -pub(crate) fn prepare_build_folder( +fn prepare_build_folder( config: &mut DeployerProjectOptions, current_dir: &std::path::Path, - cache_dir: &str, + cache_dir: &Path, mut fresh: bool, link_cache: bool, copy_cache: bool, @@ -103,7 +103,7 @@ pub(crate) fn prepare_build_folder( pub(crate) fn build( config: &mut DeployerProjectOptions, - cache_dir: &str, + cache_dir: &Path, args: &BuildArgs, ) -> anyhow::Result<()> { if *config == Default::default() { panic!("Config is invalid!"); } @@ -128,6 +128,7 @@ pub(crate) fn build( let env = BuildEnvironment { build_dir: &build_path, + cache_dir, artifacts_dir: &artifacts_dir, new_build, silent_build: args.silent, @@ -170,7 +171,15 @@ fn execute_pipeline( use std::io::{stdout, Write}; use std::time::Instant; + let log_file = generate_build_log_filepath( + &config.project_name, + &pipeline.title, + env.cache_dir, + ); + if !env.silent_build { println!("Starting the `{}` Pipeline...", pipeline.title); } + build_log(&log_file, &[format!("Starting the `{}` Pipeline...", pipeline.title)])?; + let mut cntr = 1usize; let total = pipeline.actions.len(); for action in &pipeline.actions { @@ -180,6 +189,7 @@ fn execute_pipeline( } else { println!("[{}/{}] `{}` Action... ", cntr, total, action.title.blue().italic()); } + build_log(&log_file, &[format!("[{}/{}] `{}` Action... ", cntr, total, action.title)])?; } stdout().flush()?; let now = Instant::now(); @@ -220,10 +230,14 @@ fn execute_pipeline( if !env.no_pipe { println!("{} ({}).", status_str, format!("{:.2?}", elapsed).green()); + build_log(&log_file, &output)?; for line in output { println!("{}", line); } } else { println!("[{}/{}] `{}` Action - {} ({}).", cntr, total, action.title.blue().italic(), status_str, format!("{:.2?}", elapsed).green()); } + build_log(&log_file, &[ + format!("[{}/{}] `{}` Action - {} ({:.2?}).", cntr, total, action.title, if status { "done" } else { "got an error!" }, elapsed), + ])?; } cntr += 1; @@ -236,7 +250,7 @@ fn execute_pipeline( pub(crate) fn clean_builds( config: &mut DeployerProjectOptions, - cache_dir: &str, + cache_dir: &Path, args: &CleanArgs, ) -> anyhow::Result<()> { let mut path = PathBuf::new(); diff --git a/src/configs.rs b/src/configs.rs index 6c497ca..a7cfca6 100644 --- a/src/configs.rs +++ b/src/configs.rs @@ -17,8 +17,7 @@ use crate::utils::ordered_map; #[derive(Deserialize, Serialize, PartialEq, Default, Debug)] pub(crate) struct DeployerProjectOptions { /// Название проекта. - #[serde(skip_serializing_if = "Option::is_none")] - pub(crate) project_name: Option, + pub(crate) project_name: String, /// Языки pub(crate) langs: Vec, /// Таргеты diff --git a/src/entities/environment.rs b/src/entities/environment.rs index 6374e79..caa54fc 100644 --- a/src/entities/environment.rs +++ b/src/entities/environment.rs @@ -3,6 +3,7 @@ use std::path::Path; #[derive(Clone, Copy)] pub(crate) struct BuildEnvironment<'a> { pub(crate) build_dir: &'a Path, + pub(crate) cache_dir: &'a Path, pub(crate) artifacts_dir: &'a Path, pub(crate) new_build: bool, pub(crate) silent_build: bool, diff --git a/src/main.rs b/src/main.rs index 50a9124..a3e2861 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ static PROJECT_CONF: &str = "deploy-config.json"; static GLOBAL_CONF: &str = "deploy-global.json"; pub(crate) static CACHE_DIR: &str = "deploy-cache"; -// pub(crate) static LOGS_DIR: &str = "logs"; +pub(crate) static LOGS_DIR: &str = "logs"; pub(crate) static ARTIFACTS_DIR: &str = "artifacts"; @@ -72,22 +72,16 @@ fn main() { // Определение рабочих директорий let cache_folder = if args.cache_folder.is_none() { - cache_dir() - .expect("Can't get `cache` directory's location automatically, please specify one.") - .to_str() - .expect("Can't convert `PathBuf` to `str` for `cache` folder!") - .to_string() + cache_dir().expect("Can't get `cache` directory's location automatically, please specify one.") } else { - args.cache_folder.as_ref().unwrap().to_string() + let path = std::path::PathBuf::new(); + path.join(args.cache_folder.as_ref().unwrap()) }; let config_folder = if args.config_folder.is_none() { - config_dir() - .expect("Can't get `config` directory's location automatically, please specify one.") - .to_str() - .expect("Can't convert `PathBuf` to `str` for `config` folder!") - .to_string() + config_dir().expect("Can't get `config` directory's location automatically, please specify one.") } else { - args.config_folder.as_ref().unwrap().to_string() + let path = std::path::PathBuf::new(); + path.join(args.config_folder.as_ref().unwrap()) }; // Чтение конфигов diff --git a/src/project.rs b/src/project.rs index a948290..817ce8d 100644 --- a/src/project.rs +++ b/src/project.rs @@ -13,7 +13,7 @@ impl DeployerProjectOptions { pub(crate) fn init_from_prompt(&mut self) -> anyhow::Result<()> { use inquire::Text; - self.project_name = Text::new("Enter the project's name (or hit `esc`):").prompt_skippable()?; + self.project_name = Text::new("Enter the project's name:").prompt()?; self.cache_files.push(".git".to_string()); println!("Please, specify the project's programming languages to setup default cache folders."); @@ -56,7 +56,7 @@ impl DeployerProjectOptions { actions.clone(), ).prompt_skippable()? { match action { - "Edit project name" => self.project_name = inquire::Text::new("Enter the project's name (or hit `esc`):").prompt_skippable()?, + "Edit project name" => self.project_name = inquire::Text::new("Enter the project's name:").prompt()?, "Edit cache files" => self.cache_files.edit_from_prompt()?, "Edit programming languages" => self.langs.edit_from_prompt()?, "Edit targets" => self.targets.edit_from_prompt()?, diff --git a/src/rw.rs b/src/rw.rs index 9cb7df3..cb1f6d0 100644 --- a/src/rw.rs +++ b/src/rw.rs @@ -3,9 +3,10 @@ use std::fs::File; use std::io::{BufReader, BufWriter}; use std::sync::OnceLock; use std::path::{Path, PathBuf}; -use crate::PROJECT_CONF; +use crate::{CACHE_DIR, LOGS_DIR, PROJECT_CONF}; pub(crate) static VERBOSE: OnceLock = OnceLock::new(); +const LOG_FILE_DELIMETER: &str = "================================================================"; pub(crate) fn read(folder: impl AsRef, file: impl AsRef) -> T { let mut path = PathBuf::new(); @@ -53,7 +54,6 @@ pub(crate) fn write(folder: impl AsRef, file: impl AsRef, dst: impl AsRef, ignore: &[&str]) -> anyhow::Result<()> { if src.as_ref().is_file() { if let Some(parent) = dst.as_ref().parent() { @@ -116,3 +116,41 @@ pub(crate) fn log(s: impl AsRef) { println!("{}", s.as_ref()); } } + +pub(crate) fn generate_build_log_filepath( + project_name: &str, + pipeline_short_name: &str, + cache_dir: &Path, +) -> PathBuf { + use chrono::Utc; + + let mut logs_path = PathBuf::new(); + logs_path.push(cache_dir); + logs_path.push(CACHE_DIR); + logs_path.push(LOGS_DIR); + if !logs_path.exists() { std::fs::create_dir_all(logs_path.as_path()).unwrap_or_else(|_| panic!("Can't create `{:?}` folder!", logs_path)); } + + let curr_dt = Utc::now(); + + let log_path = logs_path.join(format!("{}-{}-{}.txt", project_name, pipeline_short_name, curr_dt.format("%Y-%m-%d-%H:%M"))); + if log_path.exists() { build_log(&log_path, &[LOG_FILE_DELIMETER.to_string()]).expect("Current log file is unwriteable!"); } + + log_path +} + +pub(crate) fn build_log( + path: &Path, + output: &[String], +) -> anyhow::Result<()> { + use std::io::Write; + + let file = File::options().create(true).append(true).open(path)?; + let mut writer = BufWriter::new(file); + for line in output { + let line = strip_ansi_escapes::strip(line.as_bytes()); + writer.write_all(&line)?; + writer.write_all("\n".as_bytes())?; + } + + Ok(()) +} From 840f43e1737f8f6e87feee14295931c8161422cc Mon Sep 17 00:00:00 2001 From: Klimenty Titov Date: Wed, 18 Dec 2024 21:40:12 +0300 Subject: [PATCH 7/7] Bump to `beta-11` --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d604f86..95df3cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deployer" -version = "0.1.1-beta-10" +version = "0.1.1-beta-11" edition = "2021" [dependencies]