Skip to main content

omni_dev/cli/atlassian/confluence/
mod.rs

1//! Confluence CLI subcommands.
2
3pub(crate) mod create;
4pub(crate) mod delete;
5pub(crate) mod download;
6pub(crate) mod edit;
7pub(crate) mod read;
8pub(crate) mod search;
9pub(crate) mod write;
10
11use anyhow::Result;
12use clap::{Parser, Subcommand};
13
14/// Confluence page management, search, and more.
15#[derive(Parser)]
16pub struct ConfluenceCommand {
17    /// The Confluence subcommand to execute.
18    #[command(subcommand)]
19    pub command: ConfluenceSubcommands,
20}
21
22/// Confluence subcommands.
23#[derive(Subcommand)]
24pub enum ConfluenceSubcommands {
25    /// Fetches a Confluence page and outputs it as JFM markdown or ADF JSON.
26    Read(read::ReadCommand),
27    /// Pushes content to a Confluence page.
28    Write(write::WriteCommand),
29    /// Interactive fetch-edit-push cycle for a Confluence page.
30    Edit(edit::EditCommand),
31    /// Searches Confluence pages using CQL.
32    Search(search::SearchCommand),
33    /// Creates a new Confluence page.
34    Create(create::CreateCommand),
35    /// Deletes a Confluence page.
36    Delete(delete::DeleteCommand),
37    /// Recursively downloads a Confluence page tree.
38    Download(download::DownloadCommand),
39}
40
41impl ConfluenceCommand {
42    /// Executes the Confluence command.
43    pub async fn execute(self) -> Result<()> {
44        match self.command {
45            ConfluenceSubcommands::Read(cmd) => cmd.execute().await,
46            ConfluenceSubcommands::Write(cmd) => cmd.execute().await,
47            ConfluenceSubcommands::Edit(cmd) => cmd.execute().await,
48            ConfluenceSubcommands::Search(cmd) => cmd.execute().await,
49            ConfluenceSubcommands::Create(cmd) => cmd.execute().await,
50            ConfluenceSubcommands::Delete(cmd) => cmd.execute().await,
51            ConfluenceSubcommands::Download(cmd) => cmd.execute().await,
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use crate::cli::atlassian::format::{ContentFormat, OutputFormat};
60
61    #[test]
62    fn confluence_subcommands_read_variant() {
63        let cmd = ConfluenceCommand {
64            command: ConfluenceSubcommands::Read(read::ReadCommand {
65                id: "12345".to_string(),
66                output: None,
67                format: ContentFormat::Jfm,
68            }),
69        };
70        assert!(matches!(cmd.command, ConfluenceSubcommands::Read(_)));
71    }
72
73    #[test]
74    fn confluence_subcommands_write_variant() {
75        let cmd = ConfluenceCommand {
76            command: ConfluenceSubcommands::Write(write::WriteCommand {
77                id: "12345".to_string(),
78                file: None,
79                format: ContentFormat::Adf,
80                force: false,
81                dry_run: false,
82            }),
83        };
84        assert!(matches!(cmd.command, ConfluenceSubcommands::Write(_)));
85    }
86
87    #[test]
88    fn confluence_subcommands_edit_variant() {
89        let cmd = ConfluenceCommand {
90            command: ConfluenceSubcommands::Edit(edit::EditCommand {
91                id: "12345".to_string(),
92            }),
93        };
94        assert!(matches!(cmd.command, ConfluenceSubcommands::Edit(_)));
95    }
96
97    #[test]
98    fn confluence_subcommands_search_variant() {
99        let cmd = ConfluenceCommand {
100            command: ConfluenceSubcommands::Search(search::SearchCommand {
101                cql: Some("space = ENG".to_string()),
102                space: None,
103                title: None,
104                limit: 25,
105                output: OutputFormat::Table,
106            }),
107        };
108        assert!(matches!(cmd.command, ConfluenceSubcommands::Search(_)));
109    }
110
111    #[test]
112    fn confluence_subcommands_create_variant() {
113        let cmd = ConfluenceCommand {
114            command: ConfluenceSubcommands::Create(create::CreateCommand {
115                file: None,
116                format: ContentFormat::Jfm,
117                space: Some("ENG".to_string()),
118                title: Some("Test".to_string()),
119                parent: None,
120                dry_run: false,
121            }),
122        };
123        assert!(matches!(cmd.command, ConfluenceSubcommands::Create(_)));
124    }
125
126    #[test]
127    fn confluence_subcommands_delete_variant() {
128        let cmd = ConfluenceCommand {
129            command: ConfluenceSubcommands::Delete(delete::DeleteCommand {
130                id: "12345".to_string(),
131                force: true,
132                purge: false,
133            }),
134        };
135        assert!(matches!(cmd.command, ConfluenceSubcommands::Delete(_)));
136    }
137
138    #[test]
139    fn confluence_subcommands_download_variant() {
140        let cmd = ConfluenceCommand {
141            command: ConfluenceSubcommands::Download(download::DownloadCommand {
142                id: "12345".to_string(),
143                output_dir: std::path::PathBuf::from("."),
144                format: ContentFormat::Jfm,
145                concurrency: 8,
146                max_depth: 0,
147                resume: false,
148                on_conflict: download::OnConflict::Backup,
149            }),
150        };
151        assert!(matches!(cmd.command, ConfluenceSubcommands::Download(_)));
152    }
153}