changepacks_core/
workspace.rs1use std::path::Path;
2
3use crate::{Config, Language, Package, update_type::UpdateType};
4use anyhow::{Context, Result};
5use async_trait::async_trait;
6
7#[async_trait]
8pub trait Workspace: std::fmt::Debug + Send + Sync {
9 fn name(&self) -> Option<&str>;
10 fn path(&self) -> &Path;
11 fn relative_path(&self) -> &Path;
12 fn version(&self) -> Option<&str>;
13 async fn update_version(&mut self, update_type: UpdateType) -> Result<()>;
14 fn language(&self) -> Language;
15
16 fn check_changed(&mut self, path: &Path) -> Result<()> {
18 if self.is_changed() {
19 return Ok(());
20 }
21 if !path.to_string_lossy().contains(".changepacks")
22 && path.starts_with(self.path().parent().context("Parent not found")?)
23 {
24 self.set_changed(true);
25 }
26 Ok(())
27 }
28
29 fn is_changed(&self) -> bool;
30 fn set_changed(&mut self, changed: bool);
31
32 fn default_publish_command(&self) -> &'static str;
34
35 async fn publish(&self, config: &Config) -> Result<()> {
37 let command = self.get_publish_command(config);
38 let workspace_dir = self
40 .path()
41 .parent()
42 .context("Workspace directory not found")?;
43
44 let mut cmd = if cfg!(target_os = "windows") {
45 let mut c = tokio::process::Command::new("cmd");
46 c.arg("/C");
47 c.arg(command);
48 c
49 } else {
50 let mut c = tokio::process::Command::new("sh");
51 c.arg("-c");
52 c.arg(command);
53 c
54 };
55
56 cmd.current_dir(workspace_dir);
57 let output = cmd.output().await?;
58
59 if !output.status.success() {
60 anyhow::bail!(
61 "Publish command failed: {}",
62 String::from_utf8_lossy(&output.stderr)
63 );
64 } else {
65 Ok(())
66 }
67 }
68
69 fn get_publish_command(&self, config: &Config) -> String {
71 if let Some(cmd) = config
73 .publish
74 .get(self.relative_path().to_string_lossy().as_ref())
75 {
76 return cmd.clone();
77 }
78
79 let lang_key = match self.language() {
81 crate::Language::Node => "node",
82 crate::Language::Python => "python",
83 crate::Language::Rust => "rust",
84 crate::Language::Dart => "dart",
85 };
86 if let Some(cmd) = config.publish.get(lang_key) {
87 return cmd.clone();
88 }
89
90 self.default_publish_command().to_string()
92 }
93
94 async fn update_workspace_dependencies(&self, _packages: &[&dyn Package]) -> Result<()> {
95 Ok(())
96 }
97}