mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
124 lines
3.9 KiB
Rust
124 lines
3.9 KiB
Rust
use anyhow::{anyhow, bail, Ok, Result};
|
|
use std::path::PathBuf;
|
|
use tracing::info;
|
|
use uuid;
|
|
|
|
use crate::{
|
|
api::releases::ReleaseBuilder,
|
|
invocation_context::context,
|
|
sourcemaps::source_pair::{read_pairs, SourcePair},
|
|
utils::git::get_git_info,
|
|
};
|
|
|
|
#[derive(clap::Args)]
|
|
pub struct InjectArgs {
|
|
/// The directory containing the bundled chunks
|
|
#[arg(short, long)]
|
|
pub directory: PathBuf,
|
|
|
|
/// If your bundler adds a public path prefix to sourcemap URLs,
|
|
/// we need to ignore it while searching for them
|
|
/// For use alongside e.g. esbuilds "publicPath" config setting.
|
|
#[arg(short, long)]
|
|
pub public_path_prefix: Option<String>,
|
|
|
|
/// One or more directory glob patterns to ignore
|
|
#[arg(short, long)]
|
|
pub ignore: Vec<String>,
|
|
|
|
/// The project name associated with the uploaded chunks. Required to have the uploaded chunks associated with
|
|
/// a specific release. We will try to auto-derive this from git information if not provided. Strongly recommended
|
|
/// to be set explicitly during release CD workflows
|
|
#[arg(long)]
|
|
pub project: Option<String>,
|
|
|
|
/// The version of the project - this can be a version number, semantic version, or a git commit hash. Required
|
|
/// to have the uploaded chunks associated with a specific release. Overrides release information set during
|
|
/// injection. Strongly prefer setting release information during injection.
|
|
#[arg(long)]
|
|
pub version: Option<String>,
|
|
}
|
|
|
|
pub fn inject(args: &InjectArgs) -> Result<()> {
|
|
let InjectArgs {
|
|
directory,
|
|
public_path_prefix,
|
|
ignore,
|
|
project,
|
|
version,
|
|
} = args;
|
|
|
|
context().capture_command_invoked("sourcemap_inject");
|
|
|
|
let directory = directory.canonicalize().map_err(|e| {
|
|
anyhow!(
|
|
"Directory '{}' not found or inaccessible: {}",
|
|
directory.display(),
|
|
e
|
|
)
|
|
})?;
|
|
|
|
info!("Processing directory: {}", directory.display());
|
|
let mut pairs = read_pairs(&directory, ignore, public_path_prefix)?;
|
|
if pairs.is_empty() {
|
|
bail!("No source files found");
|
|
}
|
|
info!("Found {} pairs", pairs.len());
|
|
|
|
// We need to fetch or create a release if: the user specified one, any pair is missing one, or the user
|
|
// forced release overriding
|
|
let needs_release =
|
|
project.is_some() || version.is_some() || pairs.iter().any(|p| !p.has_release_id());
|
|
|
|
let mut created_release = None;
|
|
if needs_release {
|
|
let mut builder = get_git_info(Some(directory))?
|
|
.map(ReleaseBuilder::init_from_git)
|
|
.unwrap_or_default();
|
|
|
|
if let Some(project) = project {
|
|
builder.with_project(project);
|
|
}
|
|
if let Some(version) = version {
|
|
builder.with_version(version);
|
|
}
|
|
|
|
if builder.can_create() {
|
|
created_release = Some(builder.fetch_or_create()?);
|
|
}
|
|
}
|
|
|
|
let created_release_id = created_release.as_ref().map(|r| r.id.to_string());
|
|
|
|
pairs = inject_pairs(pairs, created_release_id)?;
|
|
|
|
// Write the source and sourcemaps back to disk
|
|
for pair in &pairs {
|
|
pair.save()?;
|
|
}
|
|
info!("Finished processing directory");
|
|
Ok(())
|
|
}
|
|
|
|
pub fn inject_pairs(
|
|
mut pairs: Vec<SourcePair>,
|
|
created_release_id: Option<String>,
|
|
) -> Result<Vec<SourcePair>> {
|
|
for pair in &mut pairs {
|
|
let current_release_id = pair.get_release_id();
|
|
// We only update release ids and chunk ids when the release id changed or is not present
|
|
if current_release_id != created_release_id || pair.get_chunk_id().is_none() {
|
|
pair.set_release_id(created_release_id.clone());
|
|
|
|
let chunk_id = uuid::Uuid::now_v7().to_string();
|
|
if let Some(previous_chunk_id) = pair.get_chunk_id() {
|
|
pair.update_chunk_id(previous_chunk_id, chunk_id)?;
|
|
} else {
|
|
pair.add_chunk_id(chunk_id)?;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(pairs)
|
|
}
|