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