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(clap::Args)]
42pub struct InjectArgs {
43    /// The directory containing the bundled chunks
44    #[arg(short, long)]
45    directory: PathBuf,
46
47    /// One or more directory glob patterns to ignore
48    #[arg(short, long)]
49    ignore: Vec<String>,
50}
51
52#[derive(clap::Args, Clone)]
53pub struct UploadArgs {
54    /// The directory containing the bundled chunks
55    #[arg(short, long)]
56    directory: PathBuf,
57
58    /// One or more directory glob patterns to ignore
59    #[arg(short, long)]
60    ignore: Vec<String>,
61
62    /// The project name associated with the uploaded chunks. Required to have the uploaded chunks associated with
63    /// a specific release, auto-discovered from git information on disk if not provided.
64    #[arg(long)]
65    project: Option<String>,
66
67    /// The version of the project - this can be a version number, semantic version, or a git commit hash. Required
68    /// to have the uploaded chunks associated with a specific release. Auto-discovered from git information on
69    /// disk if not provided.
70    #[arg(long)]
71    version: Option<String>,
72
73    /// Whether to delete the source map files after uploading them
74    #[arg(long, default_value = "false")]
75    delete_after: bool,
76
77    /// Whether to skip SSL verification when uploading chunks - only use when using self-signed certificates for
78    /// self-deployed instances
79    #[arg(long, default_value = "false")]
80    skip_ssl_verification: bool,
81
82    /// The maximum number of chunks to upload in a single batch
83    #[arg(long, default_value = "50")]
84    batch_size: usize,
85}
86
87#[derive(Subcommand)]
88pub enum SourcemapCommand {
89    /// Inject each bundled chunk with a posthog chunk ID
90    Inject(InjectArgs),
91    /// Upload the bundled chunks to PostHog
92    Upload(UploadArgs),
93    /// Run inject and upload in one command
94    Process(UploadArgs),
95}
96
97impl Cli {
98    pub fn run() -> Result<(), CapturedError> {
99        let command = Cli::parse();
100
101        match &command.command {
102            Commands::Login => {
103                login::login()?;
104            }
105            Commands::Sourcemap { cmd } => match cmd {
106                SourcemapCommand::Inject(input_args) => {
107                    sourcemap::inject::inject(&input_args.directory, &input_args.ignore)?;
108                }
109                SourcemapCommand::Upload(upload_args) => {
110                    sourcemap::upload::upload(command.host, upload_args.clone())?;
111                }
112                SourcemapCommand::Process(args) => {
113                    sourcemap::inject::inject(&args.directory, &args.ignore)?;
114                    sourcemap::upload::upload(command.host, args.clone())?;
115                }
116            },
117            Commands::Query { cmd } => query::query_command(command.host, cmd)?,
118        }
119
120        Ok(())
121    }
122}