Skip to content

Commit

Permalink
Merge branch 'unstable' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
markcda committed Dec 24, 2024
2 parents bb53e2f + 71d3845 commit 1497eab
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 67 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "deployer"
version = "0.1.1-beta-13"
version = "0.1.1-beta-14"
edition = "2024"

[dependencies]
Expand Down
4 changes: 0 additions & 4 deletions deploy-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
}
],
"deploy_toolkit": null,
"builds": [
"deploy-build-0bb0569a-c7f0-4786-aa7f-b1e17e13ecd9"
],
"last_build": "deploy-build-0bb0569a-c7f0-4786-aa7f-b1e17e13ecd9",
"cache_files": [
".git",
"Cargo.lock",
Expand Down
21 changes: 11 additions & 10 deletions src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,26 +397,27 @@ impl DescribedAction {
}

pub(crate) fn edit_action_from_prompt(&mut self) -> anyhow::Result<()> {
let mut actions = vec![
"Edit title",
"Edit description",
"Edit tags",
];
let mut actions = vec![];
match &self.action {
Action::Custom(_) | Action::Observe(_) => { actions.push("Edit command"); },
Action::Check(_) => { actions.extend_from_slice(&["Edit regexes", "Edit command"]); }
Action::ProjectClean(_) => { actions.extend_from_slice(&["Edit files and folders to remove", "Edit commands"]); },
Action::Check(_) => { actions.extend_from_slice(&["Edit command", "Edit regexes"]); }
Action::ProjectClean(_) => { actions.extend_from_slice(&["Edit commands", "Edit files and folders to remove"]); },
Action::PreBuild(_) | Action::Build(_) | Action::PostBuild(_) | Action::Test(_) => {
actions.extend_from_slice(&["Edit programming languages", "Edit commands"]);
actions.extend_from_slice(&["Edit commands", "Edit programming languages"]);
},
Action::Pack(_) | Action::Deliver(_) | Action::Install(_) => {
actions.extend_from_slice(&["Edit targets", "Edit commands"]);
actions.extend_from_slice(&["Edit commands", "Edit targets"]);
},
Action::ConfigureDeploy(_) | Action::Deploy(_) | Action::PostDeploy(_) => {
actions.extend_from_slice(&["Edit deploy toolkit", "Edit commands"]);
actions.extend_from_slice(&["Edit commands", "Edit deploy toolkit"]);
},
Action::Interrupt | Action::ForceArtifactsEnplace => {},
}
actions.extend_from_slice(&[
"Edit title",
"Edit description",
"Edit tags",
]);

while let Some(action) = inquire::Select::new(
"Select an edit action (hit `esc` when done):",
Expand Down
135 changes: 99 additions & 36 deletions src/build.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
use colored::Colorize;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
use uuid::Uuid;

use crate::{CACHE_DIR, ARTIFACTS_DIR, PROJECT_CONF};
use crate::entities::environment::BuildEnvironment;
use crate::cmd::{BuildArgs, CleanArgs};
use crate::configs::DeployerProjectOptions;
use crate::pipelines::execute_pipeline;
use crate::pipelines::{execute_pipeline, DescribedPipeline};
use crate::rw::{copy_all, write, symlink, log};
use crate::utils::get_current_working_dir;

/// Список всех билдов в системе
#[derive(Deserialize, Serialize, Default)]
pub(crate) struct Builds {
pub(crate) projects: Vec<ProjectBuilds>,
}

/// Билды определённого проекта
#[derive(Deserialize, Serialize, Clone)]
pub(crate) struct ProjectBuilds {
pub(crate) name: String,
pub(crate) builds: Vec<BuildStats>,
}

/// Информация о сборке
#[derive(Deserialize, Serialize, Clone)]
pub(crate) struct BuildStats {
/// Этот билд будет использоваться только для определённых пайплайнов
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) exclusive_tag: Option<String>,
/// Путь сборки
pub(crate) folder: PathBuf,
}

impl BuildStats {
pub(crate) fn works_with(&self, pipeline: &DescribedPipeline) -> bool {
self.exclusive_tag.as_ref().is_some_and(|a| pipeline.exclusive_exec_tag.as_ref().is_some_and(|b| a.as_str().eq(b.as_str()))) ||
(self.exclusive_tag.is_none() && pipeline.exclusive_exec_tag.is_none())
}
}

pub(crate) fn enplace_artifacts(
config: &DeployerProjectOptions,
env: BuildEnvironment,
Expand Down Expand Up @@ -40,39 +71,48 @@ fn prepare_artifacts_folder(
}

fn prepare_build_folder(
config: &mut DeployerProjectOptions,
config: &DeployerProjectOptions,
builds: &mut Builds,
selected_pipeline: &DescribedPipeline,
current_dir: &std::path::Path,
cache_dir: &Path,
args: &BuildArgs,
) -> anyhow::Result<(PathBuf, bool)> {
let mut fresh = args.fresh;

let build_path = if let Some(build_at) = args.build_at.as_ref() {
build_at.to_owned()
} else {
let mut build_path = PathBuf::new();
build_path.push(cache_dir);
build_path.push(CACHE_DIR);

if config.last_build.is_none() { fresh = true; }

let uuid = match fresh {
true => {
let uuid = format!("deploy-build-{}", Uuid::new_v4());
config.builds.push(uuid.clone());
config.last_build = Some(uuid.clone());
uuid
let mut project_builds = match builds.projects.iter().position(|p| p.name.as_str().eq(config.project_name.as_str())) {
None => ProjectBuilds { name: config.project_name.to_owned(), builds: vec![] },
Some(project_builds) => {
let copy = builds.projects.get(project_builds).unwrap().clone();
builds.projects.remove(project_builds);
copy
},
};

let folder = match project_builds.builds.iter().rev().find(|b| b.works_with(selected_pipeline)) {
Some(b_stats) if !args.fresh => {
b_stats.folder.to_owned()
},
false => {
config.last_build.as_ref().unwrap().to_owned()
_ => {
let uuid = format!("deploy-build-{}", Uuid::new_v4());
let folder = build_path.join(uuid);
let b_stats = BuildStats { exclusive_tag: selected_pipeline.exclusive_exec_tag.clone(), folder: folder.to_owned(), };
project_builds.builds.push(b_stats);
folder.to_owned()
},
};

build_path.push(uuid.clone());
build_path
builds.projects.push(project_builds);

folder
};

if !build_path.exists() { fresh = true; }
let fresh = !build_path.exists() || args.fresh;
std::fs::create_dir_all(build_path.as_path()).unwrap_or_else(|_| panic!("Can't create `{:?}` folder!", build_path));

let mut ignore = vec![ARTIFACTS_DIR, build_path.file_name().unwrap().to_str().unwrap()];
Expand Down Expand Up @@ -104,6 +144,7 @@ fn prepare_build_folder(

pub(crate) fn build(
config: &mut DeployerProjectOptions,
builds: &mut Builds,
cache_dir: &Path,
args: &BuildArgs,
) -> anyhow::Result<()> {
Expand All @@ -127,28 +168,52 @@ pub(crate) fn build(

let curr_dir = std::env::current_dir().expect("Can't get current dir!");
let artifacts_dir = prepare_artifacts_folder(&curr_dir)?;
let (build_path, new_build) = if args.current { (curr_dir, false) } else { prepare_build_folder(config, &curr_dir, cache_dir, args)? };

let env = BuildEnvironment {
build_dir: &build_path,
cache_dir,
artifacts_dir: &artifacts_dir,
new_build,
silent_build: args.silent,
no_pipe: args.no_pipe,
};

if args.pipeline_tags.is_empty() {
if config.pipelines.is_empty() {
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)) {
let (build_path, new_build) = if args.current {
(curr_dir.clone(), false)
} else {
prepare_build_folder(config, builds, pipeline, &curr_dir, cache_dir, args)?
};

let env = BuildEnvironment {
build_dir: &build_path,
cache_dir,
artifacts_dir: &artifacts_dir,
new_build,
silent_build: args.silent,
no_pipe: args.no_pipe,
};

execute_pipeline(config, env, pipeline)?;

enplace_artifacts(config, env, true)?;
}
} else {
for pipeline_tag in &args.pipeline_tags {
if let Some(pipeline) = config.pipelines.iter().find(|p| p.title.as_str().eq(pipeline_tag)) {
let (build_path, new_build) = if args.current {
(curr_dir.clone(), false)
} else {
prepare_build_folder(config, builds, pipeline, &curr_dir, cache_dir, args)?
};

let env = BuildEnvironment {
build_dir: &build_path,
cache_dir,
artifacts_dir: &artifacts_dir,
new_build,
silent_build: args.silent,
no_pipe: args.no_pipe,
};

execute_pipeline(config, env, pipeline)?;

enplace_artifacts(config, env, true)?;
} else {
panic!(
"There is no such Pipeline `{}` set up for this project. Maybe, you've forgotten set up this Pipeline for project via `{}`?",
Expand All @@ -159,27 +224,25 @@ pub(crate) fn build(
}
}

enplace_artifacts(config, env, true)?;

Ok(())
}

pub(crate) fn clean_builds(
config: &mut DeployerProjectOptions,
config: &DeployerProjectOptions,
builds: &mut Builds,
cache_dir: &Path,
args: &CleanArgs,
) -> anyhow::Result<()> {
let mut path = PathBuf::new();
path.push(cache_dir);
path.push(CACHE_DIR);

config.last_build = None;
for build in &config.builds {
let mut build_path = path.clone();
build_path.push(build);
let _ = std::fs::remove_dir_all(build_path);
if let Some(project_builds) = builds.projects.iter_mut().find(|p| p.name.as_str().eq(config.project_name.as_str())) {
for folder in project_builds.builds.iter().map(|b| b.folder.clone()) {
let _ = std::fs::remove_dir_all(folder);
}
project_builds.builds.clear();
}
config.builds.clear();

if args.include_artifacts {
let curr_dir = std::env::current_dir()?;
Expand Down
6 changes: 0 additions & 6 deletions src/configs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ pub(crate) struct DeployerProjectOptions {
/// Тулкит для развёртывания
pub(crate) deploy_toolkit: Option<String>,

/// Сборки
pub(crate) builds: Vec<String>,
/// Последняя (текущая сборка)
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) last_build: Option<String>,

/// Метки кэша
pub(crate) cache_files: Vec<String>,

Expand Down
12 changes: 9 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod entities;
mod project;

use crate::actions::{list_actions, new_action, remove_action, cat_action, edit_action};
use crate::build::Builds;
use crate::cmd::{Cli, DeployerExecType, ListType, NewType, RemoveType, CatType, EditType};
use crate::configs::{DeployerGlobalConfig, DeployerProjectOptions};
use crate::pipelines::{list_pipelines, new_pipeline, remove_pipeline, cat_pipeline, cat_project_pipelines, assign_pipeline_to_project, edit_pipeline};
Expand All @@ -41,6 +42,7 @@ static GLOBAL: MiMalloc = MiMalloc;

static PROJECT_CONF: &str = "deploy-config.json";
static GLOBAL_CONF: &str = "deploy-global.json";
static BUILD_CACHE_LIST: &str = "deploy-builds.json";

pub(crate) static CACHE_DIR: &str = "deploy-cache";
pub(crate) static LOGS_DIR: &str = "logs";
Expand Down Expand Up @@ -92,6 +94,7 @@ fn main() {
// Чтение конфигов
let mut globals = read::<DeployerGlobalConfig>(&config_folder, GLOBAL_CONF);
let mut config = read::<DeployerProjectOptions>(&get_current_working_dir().unwrap(), PROJECT_CONF);
let mut builds = read::<Builds>(&cache_folder, BUILD_CACHE_LIST);

match args.r#type {
DeployerExecType::Ls(ListType::Actions) => list_actions(&globals),
Expand Down Expand Up @@ -139,10 +142,13 @@ fn main() {
write(&config_folder, GLOBAL_CONF, &globals);
write(get_current_working_dir().unwrap(), PROJECT_CONF, &config);
},
DeployerExecType::Build(args) => build(&mut config, &cache_folder, &args).unwrap(),
DeployerExecType::Build(args) => {
build(&mut config, &mut builds, &cache_folder, &args).unwrap();
write(&cache_folder, BUILD_CACHE_LIST, &builds);
},
DeployerExecType::Clean(args) => {
clean_builds(&mut config, &cache_folder, &args).unwrap();
write(get_current_working_dir().unwrap(), PROJECT_CONF, &config);
clean_builds(&config, &mut builds, &cache_folder, &args).unwrap();
write(&cache_folder, BUILD_CACHE_LIST, &builds);
},

#[cfg(feature = "tests")]
Expand Down
21 changes: 15 additions & 6 deletions src/pipelines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::configs::{DeployerGlobalConfig, DeployerProjectOptions};
use crate::entities::{
environment::BuildEnvironment,
info::{PipelineInfo, info2str_simple, info2str, str2info},
targets::TargetDescription,
traits::{EditExtended, Execute},
};
use crate::hmap;
Expand All @@ -34,11 +33,11 @@ pub(crate) struct DescribedPipeline {
/// Если не установлен, считается как `false`.
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) default: Option<bool>,
/// Информация для проекта: зависит ли пайплайн от какого-либо таргета.
/// Информация для проекта: должен ли пайплайн выполняться в определённой среде (например, в отдельных папках сборки).
///
/// Если зависит, то пайплайн будет выполняться в зависимости от
/// Если зависит, то пайплайн будет выполняться в папках с указанным тегом сборки.
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) target_dependable: Option<TargetDescription>,
pub(crate) exclusive_exec_tag: Option<String>,
}

impl DescribedPipeline {
Expand All @@ -58,25 +57,28 @@ impl DescribedPipeline {
let selected_actions_unordered = collect_multiple_actions(globals)?;
let selected_actions_ordered = reorder_actions(selected_actions_unordered)?;

let exclusive_exec_tag = Text::new("Specify exclusive pipeline tag (or hit `esc`):").prompt_skippable()?;

let described_pipeline = DescribedPipeline {
title: name,
desc,
info,
tags,
actions: selected_actions_ordered,
default: None,
target_dependable: None,
exclusive_exec_tag,
};

Ok(described_pipeline)
}

pub(crate) fn edit_pipeline_from_prompt(&mut self, globals: &mut DeployerGlobalConfig) -> anyhow::Result<()> {
let actions = vec![
"Edit Pipeline's Actions",
"Edit title",
"Edit description",
"Edit tags",
"Edit Pipeline's Actions",
"Edit exclusive execution tag",
];

while let Some(action) = inquire::Select::new(
Expand All @@ -91,6 +93,13 @@ impl DescribedPipeline {
self.tags = tags_custom_type("Write Action's tags, if any:", if joined.is_empty() { None } else { Some(joined.as_str()) }).prompt()?
},
"Edit Pipeline's Actions" => self.actions.edit_from_prompt(globals)?,
"Edit exclusive execution tag" => self.exclusive_exec_tag = if self.exclusive_exec_tag.is_none() {
inquire::Text::new("Specify exclusive pipeline tag (or hit `esc`):").prompt_skippable()?
} else {
inquire::Text::new(
"Specify exclusive pipeline tag (or hit `esc`):"
).with_initial_value(self.exclusive_exec_tag.as_ref().unwrap()).prompt_skippable()?
},
_ => {},
}
}
Expand Down
Loading

0 comments on commit 1497eab

Please sign in to comment.