Skip to main content

omni_dev/cli/atlassian/confluence/
mod.rs

1//! Confluence CLI subcommands.
2
3pub(crate) mod comment;
4pub(crate) mod create;
5pub(crate) mod delete;
6pub(crate) mod download;
7pub(crate) mod edit;
8pub(crate) mod label;
9pub(crate) mod read;
10pub(crate) mod search;
11pub(crate) mod user;
12pub(crate) mod write;
13
14use anyhow::Result;
15use clap::{Parser, Subcommand};
16
17/// Confluence page management, search, and more.
18#[derive(Parser)]
19pub struct ConfluenceCommand {
20    /// The Confluence subcommand to execute.
21    #[command(subcommand)]
22    pub command: ConfluenceSubcommands,
23}
24
25/// Confluence subcommands.
26#[derive(Subcommand)]
27pub enum ConfluenceSubcommands {
28    /// Manages comments on a Confluence page.
29    Comment(comment::CommentCommand),
30    /// Fetches a Confluence page and outputs it as JFM markdown or ADF JSON.
31    Read(read::ReadCommand),
32    /// Pushes content to a Confluence page.
33    Write(write::WriteCommand),
34    /// Interactive fetch-edit-push cycle for a Confluence page.
35    Edit(edit::EditCommand),
36    /// Searches Confluence pages using CQL.
37    Search(search::SearchCommand),
38    /// Creates a new Confluence page.
39    Create(create::CreateCommand),
40    /// Deletes a Confluence page.
41    Delete(delete::DeleteCommand),
42    /// Manages labels on Confluence pages.
43    Label(label::LabelCommand),
44    /// Recursively downloads a Confluence page tree.
45    Download(download::DownloadCommand),
46    /// Confluence user operations.
47    User(user::UserCommand),
48}
49
50impl ConfluenceCommand {
51    /// Executes the Confluence command.
52    pub async fn execute(self) -> Result<()> {
53        match self.command {
54            ConfluenceSubcommands::Comment(cmd) => cmd.execute().await,
55            ConfluenceSubcommands::Read(cmd) => cmd.execute().await,
56            ConfluenceSubcommands::Write(cmd) => cmd.execute().await,
57            ConfluenceSubcommands::Edit(cmd) => cmd.execute().await,
58            ConfluenceSubcommands::Search(cmd) => cmd.execute().await,
59            ConfluenceSubcommands::Create(cmd) => cmd.execute().await,
60            ConfluenceSubcommands::Label(cmd) => cmd.execute().await,
61            ConfluenceSubcommands::Delete(cmd) => cmd.execute().await,
62            ConfluenceSubcommands::Download(cmd) => cmd.execute().await,
63            ConfluenceSubcommands::User(cmd) => cmd.execute().await,
64        }
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use crate::cli::atlassian::format::{ContentFormat, OutputFormat};
72
73    #[test]
74    fn confluence_subcommands_comment_variant() {
75        let cmd = ConfluenceCommand {
76            command: ConfluenceSubcommands::Comment(comment::CommentCommand {
77                command: comment::CommentSubcommands::List(comment::ListCommand {
78                    id: "12345".to_string(),
79                    limit: 25,
80                    output: OutputFormat::Table,
81                }),
82            }),
83        };
84        assert!(matches!(cmd.command, ConfluenceSubcommands::Comment(_)));
85    }
86
87    #[test]
88    fn confluence_subcommands_read_variant() {
89        let cmd = ConfluenceCommand {
90            command: ConfluenceSubcommands::Read(read::ReadCommand {
91                id: "12345".to_string(),
92                output: None,
93                format: ContentFormat::Jfm,
94            }),
95        };
96        assert!(matches!(cmd.command, ConfluenceSubcommands::Read(_)));
97    }
98
99    #[test]
100    fn confluence_subcommands_write_variant() {
101        let cmd = ConfluenceCommand {
102            command: ConfluenceSubcommands::Write(write::WriteCommand {
103                id: "12345".to_string(),
104                file: None,
105                format: ContentFormat::Adf,
106                force: false,
107                dry_run: false,
108            }),
109        };
110        assert!(matches!(cmd.command, ConfluenceSubcommands::Write(_)));
111    }
112
113    #[test]
114    fn confluence_subcommands_edit_variant() {
115        let cmd = ConfluenceCommand {
116            command: ConfluenceSubcommands::Edit(edit::EditCommand {
117                id: "12345".to_string(),
118            }),
119        };
120        assert!(matches!(cmd.command, ConfluenceSubcommands::Edit(_)));
121    }
122
123    #[test]
124    fn confluence_subcommands_search_variant() {
125        let cmd = ConfluenceCommand {
126            command: ConfluenceSubcommands::Search(search::SearchCommand {
127                cql: Some("space = ENG".to_string()),
128                space: None,
129                title: None,
130                limit: 25,
131                output: OutputFormat::Table,
132            }),
133        };
134        assert!(matches!(cmd.command, ConfluenceSubcommands::Search(_)));
135    }
136
137    #[test]
138    fn confluence_subcommands_create_variant() {
139        let cmd = ConfluenceCommand {
140            command: ConfluenceSubcommands::Create(create::CreateCommand {
141                file: None,
142                format: ContentFormat::Jfm,
143                space: Some("ENG".to_string()),
144                title: Some("Test".to_string()),
145                parent: None,
146                dry_run: false,
147            }),
148        };
149        assert!(matches!(cmd.command, ConfluenceSubcommands::Create(_)));
150    }
151
152    #[test]
153    fn confluence_subcommands_label_variant() {
154        let cmd = ConfluenceCommand {
155            command: ConfluenceSubcommands::Label(label::LabelCommand {
156                command: label::LabelSubcommands::List(label::ListCommand {
157                    id: "12345".to_string(),
158                    output: OutputFormat::Table,
159                }),
160            }),
161        };
162        assert!(matches!(cmd.command, ConfluenceSubcommands::Label(_)));
163    }
164
165    #[test]
166    fn confluence_subcommands_delete_variant() {
167        let cmd = ConfluenceCommand {
168            command: ConfluenceSubcommands::Delete(delete::DeleteCommand {
169                id: "12345".to_string(),
170                force: true,
171                purge: false,
172            }),
173        };
174        assert!(matches!(cmd.command, ConfluenceSubcommands::Delete(_)));
175    }
176
177    #[test]
178    fn confluence_subcommands_user_variant() {
179        let cmd = ConfluenceCommand {
180            command: ConfluenceSubcommands::User(user::UserCommand {
181                command: user::UserSubcommands::Search(user::UserSearchCommand {
182                    query: "alice".to_string(),
183                    limit: 25,
184                    output: OutputFormat::Table,
185                }),
186            }),
187        };
188        assert!(matches!(cmd.command, ConfluenceSubcommands::User(_)));
189    }
190
191    #[test]
192    fn confluence_subcommands_download_variant() {
193        let cmd = ConfluenceCommand {
194            command: ConfluenceSubcommands::Download(download::DownloadCommand {
195                id: "12345".to_string(),
196                output_dir: std::path::PathBuf::from("."),
197                format: ContentFormat::Jfm,
198                concurrency: 8,
199                max_depth: 0,
200                resume: false,
201                on_conflict: download::OnConflict::Backup,
202            }),
203        };
204        assert!(matches!(cmd.command, ConfluenceSubcommands::Download(_)));
205    }
206}