posthog_cli/sourcemaps/hermes/
upload.rs

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