From 0e2c933ce0142a5189f9cee09f07104596c60195 Mon Sep 17 00:00:00 2001 From: Airyzz <36567925+Airyzz@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:30:36 +0930 Subject: [PATCH 1/2] make setup path configurable --- example/basic/manifest.yaml | 1 + src/core/commands/command_setup.rs | 54 ++++++++++++++++++------------ src/core/format.rs | 2 +- src/core/project.rs | 23 +++++++++++++ 4 files changed, 58 insertions(+), 22 deletions(-) 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..7cca95b 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,26 +43,25 @@ 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()); + }, } let mut shot_code: Option = None; @@ -79,17 +78,30 @@ impl Command for SetupArgs { } None => format!("{}_{}", asset, department), }; + + let mut resolved_path: String = match &project.read().unwrap().setup_path_template { + Some(s) => s.clone(), + None => DEFAULT_PATH.to_string(), + }; - dir_path.push(&department); - dir_path.push(&asset); + 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 +121,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..cf0805e 100644 --- a/src/core/format.rs +++ b/src/core/format.rs @@ -2,7 +2,7 @@ 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..7f25e3b 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,13 @@ 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 +413,20 @@ 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 +436,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); From 925d20c56b9f98f08637af4e41cd130273dd1281 Mon Sep 17 00:00:00 2001 From: Airyzz <36567925+Airyzz@users.noreply.github.com> Date: Fri, 28 Aug 2026 21:34:38 +0930 Subject: [PATCH 2/2] formatting --- src/core/commands/command_setup.rs | 12 +++++------- src/core/format.rs | 8 +++++++- src/core/project.rs | 31 +++++++++++++++--------------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/core/commands/command_setup.rs b/src/core/commands/command_setup.rs index 7cca95b..02e3e56 100644 --- a/src/core/commands/command_setup.rs +++ b/src/core/commands/command_setup.rs @@ -44,24 +44,23 @@ impl Command for SetupArgs { } // 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 map = HashMap::<&str, String>::new(); map.insert("department", department.clone()); map.insert("asset", asset.clone()); - + match &self.common.shot { Some(shot) => { map.insert("shot", "shot/".to_owned() + &shot.clone()); - }, + } None => { map.insert("shot", "asset".into()); - }, + } } let mut shot_code: Option = None; @@ -78,7 +77,7 @@ impl Command for SetupArgs { } None => format!("{}_{}", asset, department), }; - + let mut resolved_path: String = match &project.read().unwrap().setup_path_template { Some(s) => s.clone(), None => DEFAULT_PATH.to_string(), @@ -98,7 +97,6 @@ impl Command for SetupArgs { _ = std::fs::create_dir_all(&new_dir_path); } - let file_name_with_ext = file_name.clone() + &self.file_format; let mut path = new_dir_path.clone(); diff --git a/src/core/format.rs b/src/core/format.rs index cf0805e..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", "setup_path_template"]; + 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 7f25e3b..90d86fa 100644 --- a/src/core/project.rs +++ b/src/core/project.rs @@ -25,7 +25,7 @@ pub struct Project { pub assets: AssetCategory, pub version_control: VersionControlConfig, pub shots: ShotEntry, - pub setup_path_template: Option + pub setup_path_template: Option, } impl Project { @@ -317,8 +317,11 @@ pub fn to_yaml(project: &Project) -> serde_yaml::Value { match &project.setup_path_template { Some(template) => { - mapping.insert("setup_path_template".into(), serde_yaml::to_value(template).unwrap()); - }, + mapping.insert( + "setup_path_template".into(), + serde_yaml::to_value(template).unwrap(), + ); + } None => (), } @@ -413,19 +416,15 @@ 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 => () - } + + 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, @@ -436,7 +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 + setup_path_template: setup_path_template, }; to_yaml(&result);