cirup is a command-line tool for working with localization resource files.
It supports .json, .resx, and .restext files.
Install cirup globally as a .NET tool:
dotnet tool install -g Devolutions.Cirup.ToolBuild the workspace:
cargo build --workspaceRun help:
cargo run -p cirup_cli -- --helpUse an installed binary:
cirup --help--output-format <jsonl|json|table>: control stdout format. Default isjsonl.--dry-run: compute results without writing output files. If a command normally writes to a file, the result is rendered to stdout instead.--check: imply--dry-runand exit with code2when the command would produce changes.--summary: print a structured execution summary instead of full result rows. Combine it with--dry-runfor inspect-only workflows.--count-only: print only the number of matching results to stdout.--key-filter <pattern>: keep only results whose key matches a simple regex-style pattern. Repeatable. Supported syntax: literals,^,$,., and.*.--value-filter <pattern>: keep only results whose value matches the same simple regex-style syntax. Repeatable.--limit <n>: keep only the firstnmatching results.--quiet: only print errors to stderr.--log-level <error|warn|info|debug|trace>: set stderr verbosity explicitly.-v,-vv, ...: increase log verbosity starting from the defaultwarnlevel.-C,--show-changes: forfile-diff, include keys that exist in both files but have different values.--touch: force writing output files even when generated bytes are identical.--output-encoding <utf8-no-bom|utf8-bom|utf8>: control output file encoding.utf8behaves likeutf8-no-bom.
By default, cirup writes JSONL to stdout, logs at warn level, and avoids rewriting output files when content has not changed.
--summary emits compact metadata such as counts, write intent, and whether output would be truncated. --check is intended for automation and returns exit code 2 when a command would produce changes.
--key-filter and --value-filter are intentionally limited to a SQL-translatable subset. Unsupported syntax such as |, (), [], {m,n}, +, and lookarounds is rejected instead of being interpreted as full regex.
cirup file-print input.resxShow a human-readable table instead:
cirup --output-format table file-print input.resxWrite the printed content to a file:
cirup file-print input.resx output.jsonPreview the same operation without writing the output file:
cirup --dry-run file-print input.resx output.jsoncirup file-convert input.resx output.json
cirup file-convert input.json output.restextSort in place:
cirup file-sort strings.jsonSort to a separate file:
cirup file-sort strings.json strings.sorted.jsonShow keys present in file1 but missing in file2:
cirup file-diff file1.resx file2.resxCount missing keys without writing the full result set:
cirup --count-only file-diff file1.resx file2.resxAsk only whether differences exist:
cirup --check file-diff file1.resx file2.resxWrite diff to file:
cirup file-diff file1.resx file2.resx diff.resxInclude value changes as well:
cirup --show-changes file-diff file1.resx file2.resxMerge values from file2 into file1:
cirup file-merge file1.resx file2.resx merged.resxKeep only exact key/value pairs common to both files:
cirup file-intersect file1.json file2.json intersect.jsonKeep values from file1 whose keys are not in file2:
cirup file-subtract file1.restext file2.restext result.restextShow keys that are in new, not in old, and also present in base:
cirup diff-with-base old.resx new.resx base.resxLimit stdout to a subset of keys:
cirup --key-filter ^lbl --limit 25 diff-with-base old.resx new.resx base.resxMatch keys containing a simple wildcard sequence:
cirup --key-filter 'User.*Name' file-print input.resxFilter by translated value content:
cirup --value-filter '^Hello' file-print input.resxEmit a structured summary for an in-place sort without modifying the file:
cirup --dry-run --summary file-sort strings.json- Default: if output bytes are unchanged, cirup does not rewrite the file.
- With
--touch: cirup always rewrites output files.
Examples:
cirup file-sort strings.resx
cirup --touch file-sort strings.resxThe Devolutions.Cirup.Build package can run cirup operations during MSBuild.
Example project setup:
<ItemGroup>
<PackageReference Include="Devolutions.Cirup.Build" Version="1.2.3" PrivateAssets="all" />
<CirupResources Include="Properties\Resources.resx" />
<CirupResources Include="Properties\Resources.fr.resx" />
</ItemGroup>Run local end-to-end validation:
pwsh ./nuget/test-e2e.ps1cirup is also available as a RID-specific dotnet tool package: Devolutions.Cirup.Tool.
Install globally:
dotnet tool install -g Devolutions.Cirup.Tool
cirup --helpRun one-shot without permanent install:
dotnet tool exec Devolutions.Cirup.Tool -- --help
dnx Devolutions.Cirup.Tool --helpCreate local dotnet tool packages from prebuilt release artifacts:
pwsh ./nuget/pack-cirup-dotnet-tool.ps1 -Version 1.2.3 -ArtifactsRoot ./dist -OutputDir ./dist/nugetcargo test --workspace
cargo fmt --all --check
cargo clippy --workspace --all-targets