diff --git a/example/basic/manifest.yaml b/example/basic/manifest.yaml index 4fa6155..7b66d8c 100644 --- a/example/basic/manifest.yaml +++ b/example/basic/manifest.yaml @@ -1,5 +1,6 @@ identifier: bsc display_name: Basic Project +setup_path_template: setup/${asset}/${shot}/${department} programs: blender: diff --git a/src/core/commands/command_setup.rs b/src/core/commands/command_setup.rs index 4d9770d..02e3e56 100644 --- a/src/core/commands/command_setup.rs +++ b/src/core/commands/command_setup.rs @@ -1,7 +1,7 @@ -use std::sync::RwLock; +use std::{collections::HashMap, sync::RwLock}; use clap::{command, Args}; -use log::warn; +use log::{info, warn}; use ts_rs::TS; use crate::core::{project::Project, shot::shot_resolver::ShotResolver}; @@ -43,25 +43,23 @@ impl Command for SetupArgs { return Err(CommandError::InvalidArguments); } + // shot is swapped for 'asset' if not in a shot + + const DEFAULT_PATH: &str = "setup/${shot}/${department}/${asset}"; + let department = self.common.department.clone().unwrap(); let asset = self.common.asset.clone().unwrap(); - let mut dir_path = project.read().unwrap().get_root_directory(); - dir_path.push("setup"); + + let mut map = HashMap::<&str, String>::new(); + map.insert("department", department.clone()); + map.insert("asset", asset.clone()); match &self.common.shot { Some(shot) => { - if project.read().unwrap().shot_exists(shot) { - dir_path.push("shot"); - for part in shot.split("/").into_iter() { - dir_path.push(part); - } - } else { - warn!("Invalid shot: {}", shot); - return Err(CommandError::InvalidArguments); - } + map.insert("shot", "shot/".to_owned() + &shot.clone()); } None => { - dir_path.push("asset"); + map.insert("shot", "asset".into()); } } @@ -80,16 +78,28 @@ impl Command for SetupArgs { None => format!("{}_{}", asset, department), }; - dir_path.push(&department); - dir_path.push(&asset); + let mut resolved_path: String = match &project.read().unwrap().setup_path_template { + Some(s) => s.clone(), + None => DEFAULT_PATH.to_string(), + }; + + for (key, value) in map.iter() { + let replace = "${".to_string() + &key.to_string() + "}"; + resolved_path = resolved_path.replace(&replace, value); + } + + let mut new_dir_path = project.read().unwrap().get_root_directory(); + for entry in resolved_path.split("/") { + new_dir_path.push(entry); + } if self.dry == false { - _ = std::fs::create_dir_all(&dir_path); + _ = std::fs::create_dir_all(&new_dir_path); } let file_name_with_ext = file_name.clone() + &self.file_format; - let mut path = dir_path.clone(); + let mut path = new_dir_path.clone(); path.push(&file_name_with_ext); if self.dry { @@ -109,7 +119,7 @@ impl Command for SetupArgs { serde_json::to_value(SetupResult { asset: self.common.asset.unwrap(), department: self.common.department.unwrap(), - folder: dir_path.to_str().unwrap().to_string(), + folder: new_dir_path.to_str().unwrap().to_string(), path: path.to_str().unwrap().to_string(), file_name: file_name, shot: shot_code, diff --git a/src/core/format.rs b/src/core/format.rs index 71ad31c..6d9f021 100644 --- a/src/core/format.rs +++ b/src/core/format.rs @@ -2,7 +2,13 @@ pub fn pretty_format_yaml(content: String) -> String { let mut result = "".to_string(); for line in content.lines().into_iter() { - let filter = [" ", "-", "identifier", "display_name"]; + let filter = [ + " ", + "-", + "identifier", + "display_name", + "setup_path_template", + ]; if !filter.iter().any(|f| line.starts_with(f)) { result.push_str("\n"); diff --git a/src/core/project.rs b/src/core/project.rs index b9a125f..90d86fa 100644 --- a/src/core/project.rs +++ b/src/core/project.rs @@ -25,6 +25,7 @@ pub struct Project { pub assets: AssetCategory, pub version_control: VersionControlConfig, pub shots: ShotEntry, + pub setup_path_template: Option, } impl Project { @@ -314,6 +315,16 @@ pub fn to_yaml(project: &Project) -> serde_yaml::Value { serde_yaml::Value::String(project.get_display_name()), ); + match &project.setup_path_template { + Some(template) => { + mapping.insert( + "setup_path_template".into(), + serde_yaml::to_value(template).unwrap(), + ); + } + None => (), + } + mapping.insert( "programs".into(), serde_yaml::Value::Mapping(program::to_yaml(project.programs.clone())), @@ -405,6 +416,16 @@ pub fn from_yaml(content: String, file_path: PathBuf) -> Project { None => ShotEntry::Subcategory(IndexMap::new()), }; + let mut setup_path_template: Option = None; + + match map.get("setup_path_template") { + Some(v) => match v { + serde_yaml::Value::String(v) => setup_path_template = Some(v.clone()), + _ => (), + }, + None => (), + } + let result = Project { manifest_file: file_path, identifier: identifier.to_string(), @@ -414,6 +435,7 @@ pub fn from_yaml(content: String, file_path: PathBuf) -> Project { version_control: config, programs: programs, shots: shots, + setup_path_template: setup_path_template, }; to_yaml(&result);