posthog_cli/sourcemaps/hermes/
clone.rs1use std::path::PathBuf;
2
3use anyhow::{anyhow, bail, Result};
4use tracing::{info, warn};
5
6use crate::{
7 invocation_context::context,
8 sourcemaps::{
9 content::SourceMapFile,
10 hermes::{get_composed_map, inject::is_metro_bundle},
11 inject::get_release_for_pairs,
12 source_pairs::read_pairs,
13 },
14};
15
16#[derive(clap::Args)]
17pub struct CloneArgs {
18 #[arg(short, long)]
20 pub directory: PathBuf,
21
22 #[arg(short, long)]
24 pub ignore: Vec<String>,
25
26 #[arg(long)]
30 pub project: Option<String>,
31
32 #[arg(long)]
35 pub version: Option<String>,
36}
37
38pub fn clone(args: &CloneArgs) -> Result<()> {
39 context().capture_command_invoked("hermes_clone");
40
41 let CloneArgs {
42 directory,
43 ignore,
44 project,
45 version,
46 } = args;
47
48 let directory = directory.canonicalize().map_err(|e| {
49 anyhow!(
50 "Directory '{}' not found or inaccessible: {}",
51 directory.display(),
52 e
53 )
54 })?;
55
56 info!("Processing directory: {}", directory.display());
57 let pairs = read_pairs(&directory, ignore, is_metro_bundle, &None)?;
58
59 if pairs.is_empty() {
60 bail!("No source files found");
61 }
62
63 info!("Found {} pairs", pairs.len());
64
65 let release_id =
66 get_release_for_pairs(&directory, project, version, &pairs)?.map(|r| r.id.to_string());
67
68 let mut pairs = pairs;
77 for pair in &mut pairs {
78 if !pair.has_release_id() || pair.get_release_id() != release_id {
79 pair.set_release_id(release_id.clone());
80 pair.save()?;
81 }
82 }
83 let pairs = pairs;
84
85 let maps: Result<Vec<(&SourceMapFile, Option<SourceMapFile>)>> = pairs
86 .iter()
87 .map(|p| get_composed_map(p).map(|c| (&p.sourcemap, c)))
88 .collect();
89
90 let maps = maps?;
91
92 for (minified, composed) in maps {
93 let Some(mut composed) = composed else {
94 warn!(
95 "Could not find composed map for minified sourcemap {}",
96 minified.inner.path.display()
97 );
98 continue;
99 };
100
101 if let Some(chunk_id) = minified.get_chunk_id() {
103 composed.set_chunk_id(Some(chunk_id));
104 }
105
106 if let Some(release_id) = minified.get_release_id() {
107 composed.set_release_id(Some(release_id));
108 }
109
110 composed.save()?;
111 info!(
112 "Successfully cloned metadata to {}",
113 composed.inner.path.display()
114 );
115 }
116
117 info!("Finished cloning metadata");
118 Ok(())
119}