posthog_cli/sourcemaps/hermes/
upload.rs

1use std::path::PathBuf;
2
3use anyhow::{anyhow, Ok, Result};
4use tracing::{info, warn};
5
6use crate::api::symbol_sets::{self, SymbolSetUpload};
7use crate::invocation_context::context;
8
9use crate::sourcemaps::hermes::get_composed_map;
10use crate::sourcemaps::hermes::inject::is_metro_bundle;
11use crate::sourcemaps::source_pairs::read_pairs;
12
13#[derive(clap::Args, Clone)]
14pub struct Args {
15    /// The directory containing the bundled chunks
16    #[arg(short, long)]
17    pub directory: PathBuf,
18
19    /// One or more directory glob patterns to ignore
20    #[arg(short, long)]
21    pub ignore: Vec<String>,
22}
23
24pub fn upload(args: &Args) -> Result<()> {
25    context().capture_command_invoked("hermes_upload");
26    let Args { directory, ignore } = args;
27
28    let directory = directory.canonicalize().map_err(|e| {
29        anyhow!(
30            "Directory '{}' not found or inaccessible: {}",
31            directory.display(),
32            e
33        )
34    })?;
35
36    info!("Processing directory: {}", directory.display());
37    let pairs = read_pairs(&directory, ignore, is_metro_bundle, &None)?;
38
39    let maps: Result<Vec<_>> = pairs.iter().map(get_composed_map).collect();
40    let maps = maps?;
41
42    let mut uploads: Vec<SymbolSetUpload> = Vec::new();
43    for map in maps.into_iter() {
44        let Some(map) = map else {
45            continue;
46        };
47
48        if map.get_chunk_id().is_none() {
49            warn!("Skipping map {}, no chunk ID", map.inner.path.display());
50            continue;
51        }
52
53        uploads.push(map.try_into()?);
54    }
55
56    info!("Found {} bundles to upload", uploads.len());
57
58    symbol_sets::upload(&uploads, 100)?;
59
60    Ok(())
61}