Skip to main content

ytcli/cli/
portfolio.rs

1//! Portfolio commands. A portfolio groups projects and other portfolios; the
2//! entity endpoints treat it as one more type, so only the word differs.
3
4use clap::Subcommand;
5
6use crate::cli::{Session, entity};
7use crate::exit::ExitCode;
8
9#[derive(Debug, Subcommand)]
10pub enum PortfolioCommand {
11    /// List portfolios.
12    #[command(long_about = crate::cli::help::md(crate::cli::help::PORTFOLIO_LIST))]
13    List {
14        /// Free-text search over names and descriptions.
15        #[arg(long, short = 'Q')]
16        query: Option<String>,
17        /// 1-based page number.
18        #[arg(long, default_value_t = 1)]
19        page: u32,
20    },
21    /// Show one portfolio.
22    #[command(long_about = crate::cli::help::md(crate::cli::help::PORTFOLIO_GET))]
23    Get {
24        /// Portfolio id as returned by `portfolio list`.
25        id: String,
26    },
27    /// List the portfolios and projects inside one.
28    #[command(long_about = crate::cli::help::md(crate::cli::help::PORTFOLIO_CONTENTS))]
29    Contents {
30        /// Portfolio id as returned by `portfolio list`.
31        id: String,
32        /// 1-based page number.
33        #[arg(long, default_value_t = 1)]
34        page: u32,
35    },
36    /// Put it inside a portfolio, or take it out of one.
37    #[command(long_about = crate::cli::help::md(crate::cli::help::PORTFOLIO_PLACE))]
38    Place {
39        /// The portfolio to move, by the id `portfolio list` prints.
40        id: String,
41        /// Portfolio to put it in.
42        #[arg(long, conflicts_with = "out")]
43        into: Option<String>,
44        /// Take it out of whichever portfolio it is in.
45        #[arg(long, conflicts_with = "into")]
46        out: bool,
47    },
48    /// Create a portfolio.
49    #[command(long_about = crate::cli::help::md(crate::cli::help::ENTITY_CREATE))]
50    Create {
51        #[command(flatten)]
52        fields: entity::Fields,
53    },
54    /// Change the fields of one.
55    #[command(long_about = crate::cli::help::md(crate::cli::help::ENTITY_UPDATE))]
56    Update {
57        /// The id `portfolio list` prints.
58        id: String,
59        #[command(flatten)]
60        fields: entity::Fields,
61    },
62    /// Delete one. Needs --yes, and nothing puts it back.
63    #[command(long_about = crate::cli::help::md(crate::cli::help::ENTITY_DELETE))]
64    Delete {
65        /// The id `portfolio list` prints.
66        id: String,
67    },
68}
69
70pub async fn run(command: &PortfolioCommand, session: &Session) -> ExitCode {
71    match command {
72        PortfolioCommand::List { query, page } => {
73            entity::list("portfolio", query.as_deref(), *page, session).await
74        }
75        PortfolioCommand::Get { id } => entity::get("portfolio", id, session).await,
76        PortfolioCommand::Contents { id, page } => entity::contents(id, *page, session).await,
77        PortfolioCommand::Place { id, into, out } => {
78            if into.is_none() && !*out {
79                return crate::cli::report(
80                    &"say where: --into <portfolio>, or --out to remove it from one",
81                    crate::exit::ExitCode::ConfirmationRequired,
82                );
83            }
84            entity::place("portfolio", id, into.as_deref(), session).await
85        }
86        PortfolioCommand::Create { fields } => entity::create("portfolio", fields, session).await,
87        PortfolioCommand::Update { id, fields } => {
88            entity::update("portfolio", id, fields, session).await
89        }
90        PortfolioCommand::Delete { id } => entity::remove("portfolio", id, session).await,
91    }
92}