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