xml-patch-accumulator
v1.0.0-alpha.0
Published
Accumulate versioned XML patches onto a baseline and validate drift
Downloads
101
Readme
xml-patch-accumulator
Accumulate versioned XML patches onto a baseline and validate drift.
xml-patch-accumulator takes a directory of baseline XML files and a directory of versioned patch releases, applies them chronologically to produce a merged "derived" snapshot, then optionally diffs the result against the baseline to surface discrepancies.
Installation
npm install xml-patch-accumulatorRequires Node.js ≥ 14.
Quick start
CLI
# Derive: apply all patches on top of baseline
xml-patch-accumulator derive --baseline ./baseline --patches ./patches --out ./derived
# Validate: diff derived output against baseline
xml-patch-accumulator validate --baseline ./baseline --out ./derived --report-out ./reports/report.jsonProgrammatic API
const { derive, validate, loadConfig } = require('xml-patch-accumulator');
const config = loadConfig('./my-project');
// Accumulate patches into derived output
await derive({
patchesRoot: './patches',
baselineRoot: './baseline',
outRoot: './derived',
config
});
// Validate derived output against baseline
const report = await validate({
derivedRoot: './derived',
baselineRoot: './baseline',
config,
reportOut: './reports/report.json' // optional
});
console.log(report.summary);
// { diverged: 0, onlyInDerived: 0, onlyInBaseline: 0 }Directory layout
Flat layout (no partitions)
patches/
2025.1/
dev/
preferences.xml
jobs.xml
2025.2/
dev/
preferences.xml
baseline/
preferences.xml
jobs.xmlPartition-split layout
patches/
2025.1/
AMER/
dev/
sites/US/preferences.xml
EMEA/
dev/
sites/EU/preferences.xmlPartition detection is automatic: if any immediate subdirectory of a release folder matches a configured partition name, the release is treated as partition-split.
Configuration
Place .xparc.json in your project root, or add an "xml-patch-accumulator" key to package.json.
{
"baseline": "./baseline",
"patches": "./patches",
"output": "./derived",
"partitions": ["AMER", "EMEA"],
"partitionMap": {
"AMER": ["sites-us", "sites-ca"],
"EMEA": ["sites-eu", "sites-uk"]
},
"primaryEnv": "dev",
"secondaryEnv": "stg",
"ignorePrefixes": ["temporary_"],
"ignoreFiles": ["prod-overrides"]
}| Key | Type | Default | Description |
|---|---|---|---|
| baseline | string | ./baseline | Path to the baseline XML directory |
| patches | string | ./patches | Path to the versioned patch directory |
| output | string | ./derived | Default output path for derive |
| partitions | string[] | [] | Known partition names |
| partitionMap | object | {} | Maps partition → owned path prefixes (for ownership validation) |
| primaryEnv | string | dev | Env subdirectory used as the patch source |
| secondaryEnv | string | stg | Env subdirectory to warn about when it has extra files |
| ignorePrefixes | string[] | ["temporary_"] | Release directory prefixes to skip entirely |
| ignoreFiles | string[] | [] | Directory/file names excluded from validation diffs |
CLI reference
xml-patch-accumulator derive
Applies all patch releases onto the baseline and writes merged output.
xml-patch-accumulator derive [options]
Options:
--baseline <path> Baseline XML directory (overrides config)
--patches <path> Versioned patch directory (overrides config)
--out <path> Output directory
--exclude <glob,...> Skip matching files (repeatable, comma-separated)
--diff-only Only write files that differ from baseline
--validate After deriving, validate derived output against baseline
--report-out <path> Write JSON + TXT report (only with --validate)
--config <path> Path to a .xparc.json config filexml-patch-accumulator validate
Diffs the derived output against the baseline and reports discrepancies.
xml-patch-accumulator validate [options]
Options:
--baseline <path> Baseline XML directory (overrides config)
--out <path> Derived output directory
--exclude <glob,...> Skip matching files
--report-out <path> Write JSON + TXT report to this path
--config <path> Path to a .xparc.json config filexml-patch-accumulator check
Derives to a temporary directory, validates against the baseline, then cleans up. Designed for CI gates where no persistent output is needed.
xml-patch-accumulator check [options]
Options:
--baseline <path> Baseline XML directory (overrides config)
--patches <path> Versioned patch directory (overrides config)
--exclude <glob,...> Skip matching files
--report-out <path> Write JSON + TXT report to this path
--out <path> Use this directory instead of a temp dir (not cleaned up)
--config <path> Path to a .xparc.json config fileExit code is 0 when no discrepancies are found, 1 otherwise.
Merge semantics
XML elements are matched by their full attribute set. When a patch element matches a baseline element by attributes, their contents are deep-merged. Patch elements not in the baseline are appended. Baseline elements not in the patch are preserved unchanged.
To delete a baseline element, add delete="true" to the patch element:
<preference preference-id="color" delete="true"/>Non-XML files (images, fonts, etc.) are binary-copied; the patch overwrites the baseline file.
Validation report
The JSON report produced by validate has this shape:
{
"summary": {
"diverged": 2,
"onlyInDerived": 1,
"onlyInBaseline": 0
},
"discrepancies": [
{
"type": "DIVERGED",
"file": "preferences.xml",
"elementKey": "preference-id=color",
"elementPath": "preferences::preference[preference-id=color]",
"derivedValue": "red",
"baselineValue": "blue"
}
]
}Discrepancy types:
| Type | Meaning |
|---|---|
| DIVERGED | Same file + same element key, different value |
| ONLY_IN_DERIVED | Element or file present in derived but not baseline |
| ONLY_IN_BASELINE | Element or file present in baseline but not derived |
Testing
npm test # run all tests
npm run test:coverage # run with coverage (thresholds: 100%)License
MIT
