changepacks_python/
workspace.rs

1use anyhow::Result;
2use async_trait::async_trait;
3use changepacks_core::{Language, UpdateType, Workspace};
4use changepacks_utils::next_version;
5use std::path::{Path, PathBuf};
6use tokio::fs::{read_to_string, write};
7use toml_edit::DocumentMut;
8
9#[derive(Debug)]
10pub struct PythonWorkspace {
11    path: PathBuf,
12    relative_path: PathBuf,
13    version: Option<String>,
14    name: Option<String>,
15    is_changed: bool,
16}
17
18impl PythonWorkspace {
19    pub fn new(
20        name: Option<String>,
21        version: Option<String>,
22        path: PathBuf,
23        relative_path: PathBuf,
24    ) -> Self {
25        Self {
26            path,
27            relative_path,
28            name,
29            version,
30            is_changed: false,
31        }
32    }
33}
34
35#[async_trait]
36impl Workspace for PythonWorkspace {
37    fn name(&self) -> Option<&str> {
38        self.name.as_deref()
39    }
40
41    fn path(&self) -> &Path {
42        &self.path
43    }
44
45    fn version(&self) -> Option<&str> {
46        self.version.as_deref()
47    }
48
49    async fn update_version(&self, update_type: UpdateType) -> Result<()> {
50        let next_version = next_version(
51            self.version.as_ref().unwrap_or(&String::from("0.0.0")),
52            update_type,
53        )?;
54
55        let pyproject_toml = read_to_string(&self.path).await?;
56        let mut pyproject_toml: DocumentMut = pyproject_toml.parse::<DocumentMut>()?;
57        if pyproject_toml["project"].is_none() {
58            pyproject_toml["project"] = toml_edit::Item::Table(toml_edit::Table::new());
59        }
60        pyproject_toml["project"]["version"] = next_version.into();
61        write(&self.path, pyproject_toml.to_string()).await?;
62        Ok(())
63    }
64
65    fn language(&self) -> Language {
66        Language::Python
67    }
68
69    fn is_changed(&self) -> bool {
70        self.is_changed
71    }
72
73    fn set_changed(&mut self, changed: bool) {
74        self.is_changed = changed;
75    }
76
77    fn relative_path(&self) -> &Path {
78        &self.relative_path
79    }
80}