mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
fix(err): don't assume 1:1 mapping between chunk and sourcemap (#40065)
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
# posthog-cli
|
||||
|
||||
# 0.5.2
|
||||
|
||||
- Fixes a bug where chunks which shared a sourcemap were mishandled, leading to an error during upload in recent versions, and a silent
|
||||
failure in older versions. If you're using next, and saw an error message about "duplicate chunk IDs", this fix addresses that issue.
|
||||
|
||||
# 0.5.1
|
||||
|
||||
- Attempts to reduce impact of previous breaking changes - re-adds `--project` and `--version` arguments to sourcemap upload command, marking them as no longer used
|
||||
|
||||
71
cli/Cargo.lock
generated
71
cli/Cargo.lock
generated
@@ -169,9 +169,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.4"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
@@ -275,9 +275,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.49"
|
||||
version = "4.5.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f"
|
||||
checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -285,9 +285,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.49"
|
||||
version = "4.5.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730"
|
||||
checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -405,7 +405,7 @@ version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
"crossterm_winapi",
|
||||
"mio 1.0.4",
|
||||
"parking_lot",
|
||||
@@ -951,7 +951,7 @@ dependencies = [
|
||||
"http 1.3.1",
|
||||
"hyper 1.7.0",
|
||||
"hyper-util",
|
||||
"rustls 0.23.33",
|
||||
"rustls 0.23.34",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.4",
|
||||
@@ -1128,9 +1128,9 @@ checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.11.4"
|
||||
version = "2.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
|
||||
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.16.0",
|
||||
@@ -1138,9 +1138,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.6"
|
||||
version = "2.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
||||
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inquire"
|
||||
@@ -1148,7 +1151,7 @@ version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
"crossterm 0.25.0",
|
||||
"dyn-clone",
|
||||
"fuzzy-matcher",
|
||||
@@ -1196,9 +1199,9 @@ checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
@@ -1243,7 +1246,7 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@@ -1446,9 +1449,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.1"
|
||||
version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
@@ -1517,7 +1520,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "posthog-cli"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@@ -1611,7 +1614,7 @@ dependencies = [
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls 0.23.33",
|
||||
"rustls 0.23.34",
|
||||
"socket2 0.6.1",
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
@@ -1631,7 +1634,7 @@ dependencies = [
|
||||
"rand",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustls 0.23.33",
|
||||
"rustls 0.23.34",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.17",
|
||||
@@ -1710,7 +1713,7 @@ version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
"cassowary",
|
||||
"compact_str",
|
||||
"crossterm 0.28.1",
|
||||
@@ -1751,7 +1754,7 @@ version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1858,7 +1861,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls 0.23.33",
|
||||
"rustls 0.23.34",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -1908,7 +1911,7 @@ version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
@@ -1921,7 +1924,7 @@ version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.11.0",
|
||||
@@ -1942,9 +1945,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.33"
|
||||
version = "0.23.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c"
|
||||
checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"ring",
|
||||
@@ -2268,9 +2271,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
version = "2.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2476,7 +2479,7 @@ version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
|
||||
dependencies = [
|
||||
"rustls 0.23.33",
|
||||
"rustls 0.23.34",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -2514,7 +2517,7 @@ version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"bitflags 2.10.0",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.3.1",
|
||||
@@ -2636,9 +2639,9 @@ checksum = "81b79ad29b5e19de4260020f8919b443b2ef0277d242ce532ec7b7a2cc8b6007"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.19"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
|
||||
checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-linebreak"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "posthog-cli"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
authors = [
|
||||
"David <david@posthog.com>",
|
||||
"Olly <oliver@posthog.com>",
|
||||
|
||||
@@ -189,7 +189,7 @@ impl ReleaseBuilder {
|
||||
Ok(response)
|
||||
} else {
|
||||
let e = response.text()?;
|
||||
Err(anyhow::anyhow!("Failed to create release: {}", e))
|
||||
Err(anyhow::anyhow!("Failed to create release: {e}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ pub fn upload(input_sets: &[SymbolSetUpload], batch_size: usize) -> Result<()> {
|
||||
let start_response = start_upload(batch)?;
|
||||
|
||||
let id_map: HashMap<_, _> = batch
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|u| (u.chunk_id.as_str(), u))
|
||||
.collect();
|
||||
|
||||
@@ -151,7 +151,7 @@ fn upload_to_s3(presigned_url: PresignedUrl, data: &[u8]) -> Result<()> {
|
||||
}
|
||||
}
|
||||
Result::Err(e) => {
|
||||
last_err = Some(anyhow!("Failed to upload chunk: {}", e));
|
||||
last_err = Some(anyhow!("Failed to upload chunk: {e}"));
|
||||
}
|
||||
}
|
||||
if attempt < 3 {
|
||||
|
||||
@@ -64,7 +64,7 @@ pub fn inject(args: &InjectArgs) -> Result<()> {
|
||||
let mut created_release = None;
|
||||
if needs_release {
|
||||
let mut builder = get_git_info(Some(directory))?
|
||||
.map(|g| ReleaseBuilder::init_from_git(g))
|
||||
.map(ReleaseBuilder::init_from_git)
|
||||
.unwrap_or_default();
|
||||
|
||||
if let Some(project) = project {
|
||||
|
||||
@@ -17,7 +17,9 @@ use walkdir::WalkDir;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct SourceMapContent {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub release_id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub chunk_id: Option<String>,
|
||||
#[serde(flatten)]
|
||||
pub fields: BTreeMap<String, Value>,
|
||||
@@ -38,18 +40,14 @@ pub struct SourcePair {
|
||||
}
|
||||
|
||||
impl SourcePair {
|
||||
pub fn new(source: MinifiedSourceFile, sourcemap: SourceMapFile) -> Result<Self> {
|
||||
if sourcemap.get_chunk_id() != source.get_chunk_id() {
|
||||
anyhow::bail!(
|
||||
"Source chunk ID and sourcemap chunk ID disagree. Try re-running injection"
|
||||
)
|
||||
}
|
||||
|
||||
Ok(Self { source, sourcemap })
|
||||
pub fn has_chunk_id(&self) -> bool {
|
||||
// Minified chunks are the source of truth for their ID's, not sourcemaps,
|
||||
// because sometimes sourcemaps are shared across multiple chunks.
|
||||
self.source.get_chunk_id().is_some()
|
||||
}
|
||||
|
||||
pub fn has_chunk_id(&self) -> bool {
|
||||
self.sourcemap.get_chunk_id().is_some()
|
||||
pub fn get_chunk_id(&self) -> Option<String> {
|
||||
self.source.get_chunk_id()
|
||||
}
|
||||
|
||||
pub fn has_release_id(&self) -> bool {
|
||||
@@ -62,8 +60,13 @@ impl SourcePair {
|
||||
}
|
||||
|
||||
let adjustment = self.source.set_chunk_id(&chunk_id)?;
|
||||
self.sourcemap.apply_adjustment(adjustment)?;
|
||||
self.sourcemap.set_chunk_id(chunk_id);
|
||||
// In cases where sourcemaps are shared across multiple chunks,
|
||||
// we should only apply the adjustment if the sourcemap doesn't
|
||||
// have a chunk ID set (since otherwise, it's already been adjusted)
|
||||
if self.sourcemap.get_chunk_id().is_none() {
|
||||
self.sourcemap.apply_adjustment(adjustment)?;
|
||||
self.sourcemap.set_chunk_id(chunk_id);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -131,7 +134,6 @@ impl TryInto<SymbolSetUpload> for SourcePair {
|
||||
|
||||
fn try_into(self) -> Result<SymbolSetUpload> {
|
||||
let chunk_id = self
|
||||
.sourcemap
|
||||
.get_chunk_id()
|
||||
.ok_or_else(|| anyhow!("Chunk ID not found"))?;
|
||||
let source_content = self.source.inner.content;
|
||||
@@ -174,12 +176,12 @@ impl SourceMapFile {
|
||||
let new_content = {
|
||||
let content = serde_json::to_string(&self.inner.content)?.into_bytes();
|
||||
let mut original_sourcemap = match sourcemap::decode_slice(content.as_slice())
|
||||
.map_err(|err| anyhow!("Failed to parse sourcemap: {}", err))?
|
||||
.map_err(|err| anyhow!("Failed to parse sourcemap: {err}"))?
|
||||
{
|
||||
sourcemap::DecodedMap::Regular(map) => map,
|
||||
sourcemap::DecodedMap::Index(index_map) => index_map
|
||||
.flatten()
|
||||
.map_err(|err| anyhow!("Failed to parse sourcemap: {}", err))?,
|
||||
.map_err(|err| anyhow!("Failed to parse sourcemap: {err}"))?,
|
||||
sourcemap::DecodedMap::Hermes(_) => {
|
||||
// TODO(olly) - YES THEY ARE!!!!! WOOOOOOO!!!!! YIPEEEEEEEE!!!
|
||||
anyhow::bail!("Hermes source maps are not supported")
|
||||
@@ -224,7 +226,7 @@ impl MinifiedSourceFile {
|
||||
}
|
||||
|
||||
pub fn get_chunk_id(&self) -> Option<String> {
|
||||
let patterns = ["//#chunk_id"];
|
||||
let patterns = ["//# chunkId="];
|
||||
self.get_comment_value(&patterns)
|
||||
}
|
||||
|
||||
@@ -233,27 +235,27 @@ impl MinifiedSourceFile {
|
||||
// Update source content with chunk ID
|
||||
let source_content = &self.inner.content;
|
||||
let mut magic_source = MagicString::new(source_content);
|
||||
let code_snippet = CODE_SNIPPET_TEMPLATE.replace(CHUNKID_PLACEHOLDER, &chunk_id);
|
||||
let code_snippet = CODE_SNIPPET_TEMPLATE.replace(CHUNKID_PLACEHOLDER, chunk_id);
|
||||
magic_source
|
||||
.prepend(&code_snippet)
|
||||
.map_err(|err| anyhow!("Failed to prepend code snippet: {}", err))?;
|
||||
let chunk_comment = CHUNKID_COMMENT_PREFIX.replace(CHUNKID_PLACEHOLDER, &chunk_id);
|
||||
.map_err(|err| anyhow!("Failed to prepend code snippet: {err}"))?;
|
||||
let chunk_comment = CHUNKID_COMMENT_PREFIX.replace(CHUNKID_PLACEHOLDER, chunk_id);
|
||||
magic_source
|
||||
.append(&chunk_comment)
|
||||
.map_err(|err| anyhow!("Failed to append chunk comment: {}", err))?;
|
||||
.map_err(|err| anyhow!("Failed to append chunk comment: {err}"))?;
|
||||
let adjustment = magic_source
|
||||
.generate_map(GenerateDecodedMapOptions {
|
||||
include_content: true,
|
||||
..Default::default()
|
||||
})
|
||||
.map_err(|err| anyhow!("Failed to generate source map: {}", err))?;
|
||||
.map_err(|err| anyhow!("Failed to generate source map: {err}"))?;
|
||||
let adjustment_sourcemap = SourceMap::from_slice(
|
||||
adjustment
|
||||
.to_string()
|
||||
.map_err(|err| anyhow!("Failed to serialize source map: {}", err))?
|
||||
.map_err(|err| anyhow!("Failed to serialize source map: {err}"))?
|
||||
.as_bytes(),
|
||||
)
|
||||
.map_err(|err| anyhow!("Failed to parse adjustment sourcemap: {}", err))?;
|
||||
.map_err(|err| anyhow!("Failed to parse adjustment sourcemap: {err}"))?;
|
||||
(magic_source.to_string(), adjustment_sourcemap)
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user