Skip to main content

wekan_cli/
commands.rs

1pub mod admin;
2pub mod api;
3pub mod attachments;
4pub mod auth;
5pub(crate) mod authenticated;
6pub mod boards;
7pub mod cards;
8pub mod checklist_items;
9pub mod checklists;
10pub(crate) mod client_error;
11pub mod comments;
12pub(crate) mod credential_ops;
13pub mod custom_field_items;
14pub mod custom_fields;
15pub mod dependencies;
16pub(crate) mod exports;
17pub(crate) mod imports;
18pub mod integrations;
19pub mod lists;
20pub mod profile;
21pub mod rules;
22pub mod self_management;
23pub mod skill;
24pub mod swimlanes;
25pub mod system;
26mod transfer;
27pub mod users;
28
29#[cfg(test)]
30mod tests;
31
32use clap::Subcommand;
33
34#[derive(Debug, Subcommand)]
35pub enum RootCommand {
36    /// Maintain this Wekan CLI installation.
37    #[command(name = "self")]
38    SelfManagement(self_management::SelfArgs),
39    /// Read agent guidance embedded in this CLI version.
40    Skill(skill::SkillArgs),
41    /// Inspect public Wekan system status.
42    System(system::SystemArgs),
43    /// Report domains and configure global settings, organizations, and teams.
44    Admin(Box<admin::AdminArgs>),
45    /// Inspect and manage board automation rules.
46    Rule(rules::RuleArgs),
47    /// Inspect and manage board integrations and webhook subscriptions.
48    Integration(integrations::IntegrationArgs),
49    /// Inspect and manage card dependency lines.
50    Dependency(dependencies::DependencyArgs),
51    /// Inspect, transfer and manage Wekan attachments.
52    Attachment(attachments::AttachmentArgs),
53    /// Send a low-level request to the selected Wekan server.
54    Api(api::ApiArgs),
55
56    /// Authenticate with a Wekan server.
57    Auth(auth::AuthArgs),
58
59    /// Manage named local Wekan server profiles.
60    Profile(profile::ProfileArgs),
61
62    /// Inspect and administer Wekan users.
63    User(users::UserArgs),
64
65    /// Inspect and manage Wekan boards.
66    Board(boards::BoardArgs),
67
68    /// Inspect and manage lists on Wekan boards.
69    List(lists::ListArgs),
70
71    /// Inspect and manage cards in Wekan board lists.
72    Card(Box<cards::CardArgs>),
73
74    /// Inspect and manage checklists on Wekan cards.
75    Checklist(checklists::ChecklistArgs),
76
77    /// Inspect and manage comments on Wekan cards.
78    Comment(comments::CommentArgs),
79
80    /// Inspect and manage custom-field definitions.
81    CustomField(custom_fields::CustomFieldArgs),
82
83    /// Inspect and manage swimlanes on Wekan boards.
84    Swimlane(swimlanes::SwimlaneArgs),
85}
86
87impl RootCommand {
88    pub fn supports_raw_output(&self) -> bool {
89        matches!(self, Self::Api(_))
90            || self.export_delivery().is_some_and(|d| d.is_stdout())
91            || matches!(self, Self::Attachment(args) if args.command.download_destination().is_some_and(|d| d.is_stdout()))
92    }
93
94    pub(crate) fn export_delivery(&self) -> Option<&exports::DeliveryArgs> {
95        match self {
96            Self::Board(a) => match &a.command {
97                boards::BoardCommand::Export(e) => Some(&e.delivery),
98                boards::BoardCommand::ExportAll(e) => Some(&e.delivery),
99                boards::BoardCommand::Chart(a) => a.delivery(),
100                _ => None,
101            },
102            Self::Card(a) => {
103                if let cards::CardCommand::Export(e) = &a.command {
104                    Some(&e.delivery)
105                } else {
106                    None
107                }
108            }
109            Self::Attachment(a) => {
110                if let attachments::AttachmentCommand::Export(e) = &a.command {
111                    Some(&e.delivery)
112                } else {
113                    None
114                }
115            }
116            _ => None,
117        }
118    }
119    pub(crate) fn validate_input(&self) -> Result<(), crate::error::AppError> {
120        if let Self::Board(a) = self {
121            if let boards::BoardCommand::Import(args) = &a.command {
122                args.validate()?;
123            }
124            if let boards::BoardCommand::ImportTrello(args) = &a.command {
125                args.validate()?;
126            }
127        }
128        if let Self::Board(a) = self {
129            if let boards::BoardCommand::Export(e) = &a.command {
130                e.validate()?;
131            }
132        }
133        if let Some(delivery) = self.export_delivery() {
134            delivery.validate()?;
135        }
136        Ok(())
137    }
138    pub fn validate_output(
139        &self,
140        format: crate::output::OutputFormat,
141    ) -> Result<(), crate::error::AppError> {
142        self.validate_input()?;
143        if let Some(delivery) = self.export_delivery() {
144            delivery.validate_output(format)?;
145        }
146        if let Self::Attachment(args) = self {
147            args.command.validate_input()?;
148            if let Some(destination) = args.command.download_destination() {
149                destination.validate_output(format)?;
150            }
151        }
152        if format == crate::output::OutputFormat::Raw && !self.supports_raw_output() {
153            return Err(crate::error::AppError::invalid_input(
154                "--output raw requires api request, an export, or an attachment download with --destination -",
155            ));
156        }
157        Ok(())
158    }
159}