Skip to main content

governor_application/
ports.rs

1//! Ports used by application use cases.
2
3use async_trait::async_trait;
4use governor_core::domain::changelog::Changelog;
5use governor_core::domain::version::SemanticVersion;
6use governor_owners::{PackageOwnersConfig, WorkspaceOwnersConfig};
7use serde::{Deserialize, Serialize};
8use std::path::{Path, PathBuf};
9
10use crate::error::ApplicationResult;
11
12/// Release workspace snapshot loaded from Cargo metadata and manifests.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct ReleaseWorkspace {
15    /// Absolute workspace root.
16    pub root: PathBuf,
17    /// Human-readable workspace name.
18    pub name: String,
19    /// Shared workspace version.
20    pub current_version: SemanticVersion,
21    /// Workspace packages.
22    pub packages: Vec<ReleasePackage>,
23}
24
25/// Package info needed by release orchestration.
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct ReleasePackage {
28    /// Crate name.
29    pub name: String,
30    /// Crate version.
31    pub version: SemanticVersion,
32    /// Cargo.toml path for the crate.
33    pub manifest_path: PathBuf,
34    /// Internal workspace dependencies.
35    pub dependencies: Vec<String>,
36    /// Whether the crate should be published.
37    pub publish: bool,
38}
39
40/// Owners workspace snapshot loaded from Cargo metadata and package manifests.
41#[derive(Debug, Clone)]
42pub struct OwnersWorkspace {
43    /// Absolute workspace root.
44    pub root: PathBuf,
45    /// Workspace-level owners config.
46    pub workspace: Option<WorkspaceOwnersConfig>,
47    /// Package configs.
48    pub packages: Vec<OwnerPackage>,
49}
50
51/// Package owners config.
52#[derive(Debug, Clone)]
53pub struct OwnerPackage {
54    /// Crate name.
55    pub name: String,
56    /// Package-level owners config.
57    pub owners: Option<PackageOwnersConfig>,
58}
59
60/// Result of updating Cargo manifests.
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct VersionUpdate {
63    /// Files touched by the update.
64    pub modified_files: Vec<String>,
65}
66
67/// Result of updating changelog.
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct ChangelogUpdate {
70    /// Whether the changelog was updated.
71    pub updated: bool,
72    /// Changed files.
73    pub modified_files: Vec<String>,
74}
75
76/// Result of running a local command.
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct CommandReport {
79    /// Logical check or command name.
80    pub name: String,
81    /// Exit status.
82    pub success: bool,
83    /// Exit code when available.
84    pub exit_code: Option<i32>,
85    /// Captured stdout.
86    pub stdout: String,
87    /// Captured stderr.
88    pub stderr: String,
89}
90
91/// Port for workspace inspection and mutation.
92#[async_trait]
93pub trait WorkspacePort: Send + Sync {
94    /// Name of the adapter.
95    fn name(&self) -> &str;
96
97    /// Load workspace release metadata.
98    async fn load_release_workspace(
99        &self,
100        workspace_path: &Path,
101    ) -> ApplicationResult<ReleaseWorkspace>;
102
103    /// Load workspace owners metadata.
104    async fn load_owners_workspace(
105        &self,
106        workspace_path: &Path,
107    ) -> ApplicationResult<OwnersWorkspace>;
108
109    /// Update shared workspace version and optional lockfile.
110    async fn update_workspace_version(
111        &self,
112        workspace_path: &Path,
113        version: &SemanticVersion,
114        dry_run: bool,
115    ) -> ApplicationResult<VersionUpdate>;
116
117    /// Update CHANGELOG.md using the target version.
118    async fn update_changelog(
119        &self,
120        workspace_path: &Path,
121        changelog: &Changelog,
122        dry_run: bool,
123    ) -> ApplicationResult<ChangelogUpdate>;
124}
125
126/// Port for local cargo/build checks.
127#[async_trait]
128pub trait CommandPort: Send + Sync {
129    /// Name of the adapter.
130    fn name(&self) -> &str;
131
132    /// Run a named pre-publish check inside the workspace.
133    async fn run_check(
134        &self,
135        workspace_path: &Path,
136        check: &str,
137        capture_output: bool,
138    ) -> ApplicationResult<CommandReport>;
139}