posthog_cli/commands/
mod.rs

1pub mod login;
2pub mod query;
3pub mod sourcemap;
4
5use clap::{Parser, Subcommand};
6use query::QueryCommand;
7use std::path::PathBuf;
8
9use crate::error::CapturedError;
10
11#[derive(Parser)]
12#[command(version, about, long_about = None)]
13pub struct Cli {
14    /// The PostHog host to connect to
15    #[arg(long)]
16    host: Option<String>,
17
18    #[command(subcommand)]
19    command: Commands,
20}
21
22#[derive(Subcommand)]
23pub enum Commands {
24    /// Interactively authenticate with PostHog, storing a personal API token locally. You can also use the
25    /// environment variables `POSTHOG_CLI_TOKEN` and `POSTHOG_CLI_ENV_ID`
26    Login,
27
28    /// Run a SQL query against any data you have in posthog. This is mostly for fun, and subject to change
29    Query {
30        #[command(subcommand)]
31        cmd: QueryCommand,
32    },
33
34    #[command(about = "Upload a directory of bundled chunks to PostHog")]
35    Sourcemap {
36        #[command(subcommand)]
37        cmd: SourcemapCommand,
38    },
39}
40
41#[derive(Subcommand)]
42pub enum SourcemapCommand {
43    /// Inject each bundled chunk with a posthog chunk ID
44    Inject {
45        /// The directory containing the bundled chunks
46        #[arg(short, long)]
47        directory: PathBuf,
48    },
49    /// Upload the bundled chunks to PostHog
50    Upload {
51        /// The directory containing the bundled chunks
52        #[arg(short, long)]
53        directory: PathBuf,
54
55        /// The project name associated with the uploaded chunks. Required to have the uploaded chunks associated with
56        /// a specific release, auto-discovered from git information on disk if not provided.
57        #[arg(long)]
58        project: Option<String>,
59
60        /// The version of the project - this can be a version number, semantic version, or a git commit hash. Required
61        /// to have the uploaded chunks associated with a specific release. Auto-discovered from git information on
62        /// disk if not provided.
63        #[arg(long)]
64        version: Option<String>,
65
66        /// Whether to delete the source map files after uploading them
67        #[arg(long, default_value = "false")]
68        delete_after: bool,
69    },
70}
71
72impl Cli {
73    pub fn run() -> Result<(), CapturedError> {
74        let command = Cli::parse();
75
76        match &command.command {
77            Commands::Login => {
78                login::login()?;
79            }
80            Commands::Sourcemap { cmd } => match cmd {
81                SourcemapCommand::Inject { directory } => {
82                    sourcemap::inject::inject(directory)?;
83                }
84                SourcemapCommand::Upload {
85                    directory,
86                    project,
87                    version,
88                    delete_after,
89                } => {
90                    sourcemap::upload::upload(
91                        command.host,
92                        directory,
93                        project.clone(),
94                        version.clone(),
95                        *delete_after,
96                    )?;
97                }
98            },
99            Commands::Query { cmd } => query::query_command(command.host, cmd)?,
100        }
101
102        Ok(())
103    }
104}