1use std::process::ExitCode;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum CommandExitCode {
8 Success = 0,
10 GeneralError = 1,
12 InvalidArguments = 2,
14 ConfigError = 3,
16 GitError = 10,
18 RegistryError = 11,
20 VersionError = 12,
22 CheckFailed = 13,
24 SecurityError = 14,
26 NetworkError = 15,
28 PrePublishChecksFailed = 16,
30 PartialSuccess = 20,
32 RollbackFailed = 21,
34 CheckpointCreated = 30,
36 NoChanges = 31,
38 DriftDetected = 32,
40}
41
42impl From<CommandExitCode> for ExitCode {
43 fn from(code: CommandExitCode) -> Self {
44 Self::from(code as u8)
45 }
46}
47
48pub type Result<T> = std::result::Result<T, Error>;
50
51#[derive(Debug, thiserror::Error)]
53pub enum Error {
54 #[error("CLI error: {0}")]
55 Cli(String),
56
57 #[error("Config error: {0}")]
58 Config(String),
59
60 #[error("Invalid arguments: {0}")]
61 InvalidArguments(String),
62
63 #[error("Git error: {0}")]
64 Git(String),
65
66 #[error("Registry error: {0}")]
67 Registry(String),
68
69 #[error("Core error: {0}")]
70 Core(#[from] governor_core::Error),
71
72 #[error("IO error: {0}")]
73 StdIo(#[from] std::io::Error),
74
75 #[error("Serialization error: {0}")]
76 Serialization(String),
77}
78
79impl From<String> for Error {
80 fn from(s: String) -> Self {
81 Self::Cli(s)
82 }
83}
84
85impl From<governor_application::ApplicationError> for Error {
86 fn from(error: governor_application::ApplicationError) -> Self {
87 match error {
88 governor_application::ApplicationError::InvalidArguments(message) => {
89 Self::InvalidArguments(message)
90 }
91 governor_application::ApplicationError::Workspace(message) => Self::Config(message),
92 governor_application::ApplicationError::SourceControl(error) => {
93 Self::Git(error.to_string())
94 }
95 governor_application::ApplicationError::Registry(error) => {
96 Self::Registry(error.to_string())
97 }
98 governor_application::ApplicationError::Checkpoint(error) => {
99 Self::Config(error.to_string())
100 }
101 governor_application::ApplicationError::Io(error) => Self::StdIo(error),
102 }
103 }
104}
105
106impl Error {
107 #[must_use]
108 pub const fn exit_code(&self) -> CommandExitCode {
109 match self {
110 Self::Cli(_) | Self::InvalidArguments(_) => CommandExitCode::InvalidArguments,
111 Self::Config(_) => CommandExitCode::ConfigError,
112 Self::Git(_) => CommandExitCode::GitError,
113 Self::Registry(_) => CommandExitCode::RegistryError,
114 Self::Core(_) | Self::StdIo(_) | Self::Serialization(_) => {
115 CommandExitCode::GeneralError
116 }
117 }
118 }
119}