Skip to content
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
86f7f85
Introduce an authoritative locale catalogue registry
Aug 1, 2026
c0a4269
Add German, British English, French and Italian catalogues
Aug 1, 2026
c44acd2
Add Latin American Spanish and both Portuguese catalogues
Aug 1, 2026
7abdac7
Add Danish, Finnish, Norwegian Bokmål and Swedish catalogues
Aug 1, 2026
79966fe
Add Czech, Dutch and Polish catalogues
Aug 1, 2026
1764047
Add Greek, Hungarian, Romanian, Russian and Ukrainian catalogues
Aug 1, 2026
5d22ab5
Add Indonesian, Turkish and Vietnamese catalogues
Aug 1, 2026
62c98ac
Add Japanese, Korean, Thai and both Chinese catalogues
Aug 1, 2026
15852d5
Add Arabic, Hebrew and Persian catalogues
Aug 1, 2026
c98fa6f
Add Hindi, Welsh and Scottish Gaelic catalogues
Aug 1, 2026
dec0506
Cover locale selection, plurals and bidi in tests
Aug 1, 2026
9986fbe
Document the locale registry and fallback policy
Aug 1, 2026
731bda4
State the release-help locale policy at its decision points
Aug 1, 2026
d9a62a5
Make the locale test helpers fallible
Aug 1, 2026
692b5f4
Give the define_keys! scanner a parser type
Aug 1, 2026
ea0a495
Address review findings on bidi, plurals and translations
Aug 2, 2026
b1ca802
Correct the localization documentation
Aug 2, 2026
7790035
Settle the CodeScene findings on the build audit
Aug 2, 2026
db7e92f
Address the pre-merge check findings
Aug 2, 2026
1559a7b
Fix brace scanning, TOML header matching, and translation errors
Aug 2, 2026
4af2350
Drop out-of-scope reflow and tidy the rebase seams
Aug 3, 2026
2c85516
Break the localization cycle and prove the audit end to end
Aug 3, 2026
f425efc
Build each bundle for its catalogue's locale, and scan for the macro
Aug 3, 2026
33c86ae
Simplify plural_categories into a two-pass scan
Aug 3, 2026
038b9e2
Harden the audit's scanners and prove plural selection
Aug 3, 2026
417d903
Warn on locale fallback, and fix agreement in six catalogues
Aug 4, 2026
d9ccb9e
Read the audit's inputs at its boundary, not in its parsers
Aug 4, 2026
d8130ad
Keep startup diagnostics off stderr until the mode is known
Aug 4, 2026
f1e448b
Buffer startup diagnostics, and fix the guard drop order
Aug 4, 2026
4783e04
Settle startup diagnostics before clap exits the process
Aug 4, 2026
f6148fa
Drive the real startup orchestration from the unit tests
Aug 4, 2026
6e3715c
Bound the startup buffer, snapshot the audit failure, document both
Aug 4, 2026
fc6f8be
Parameterize the buffer settlement tests
Aug 4, 2026
1a2786d
Isolate the startup-diagnostics tests from the ambient environment
Aug 4, 2026
6d08743
Fix agreement and terminology, and lock the startup test's globals
Aug 4, 2026
a7c349e
Read indented continuations as pattern text, not comments
Aug 4, 2026
aa1f371
Agree grammar across locales, and pin the starred plural default
Aug 4, 2026
8d1f3b1
Tighten the restore probe, and speak of locale tags
Aug 5, 2026
4d6737e
Split declarations once, and end the table where a header truly begins
Aug 5, 2026
4b21dc0
Assert the rendered error, guard the restore, and correct eight catal…
Aug 5, 2026
98f5d30
Recast the Ukrainian command frames around a nominative subject
Aug 5, 2026
3473702
Assert the indented-hash continuation does not swallow the next entry
Aug 5, 2026
b08a98d
Require a header to read as one, and document the startup buffer
Aug 5, 2026
5a25d23
Bring the tracing and locale-precedence prose up to the buffered design
Aug 5, 2026
8de9b62
Say what zero means: en-GB writes, Hindi files, Persian colons
Aug 5, 2026
e1e8fad
Read quoted keys as headers, and tell values from headers by depth
Aug 5, 2026
acea9b5
Honour escapes inside quoted header keys
Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .codescene/code-health-rules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"usage": "Repo-scoped CodeScene overrides. Keep each rule_set narrowly scoped and justify it in matching_content_path_doc, so a reader can tell a deliberate exemption from an unexamined one.",
"rule_sets": [
{
"matching_content_path": "build_l10n_audit/**",
"matching_content_path_doc": "Hand-rolled scanners over borrowed source text. These modules parse the define_keys! macro, the Fluent catalogues, and the Cargo metadata without taking a parser dependency into the build script, so their helpers necessarily take &str views into a buffer the caller owns: a line and its trimmed form, a message body, a table. Grouping those borrows into a context type would add a value that is constructed once and immediately unpacked at each call site, and taking String instead would allocate per line across 35 catalogues while breaking the borrowed returns. Each helper is private, called only from its own module, and reachable from a single entry point (parse_catalogue, extract_key_constants, parse_metadata_locales), so the parameter grouping is visible at a glance rather than spread across an API. Reassess if these parsers grow beyond one screen each or gain external callers.",
"rules": [
{
"name": "String Heavy Function Arguments",
"weight": 0.0
}
]
}
]
}
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,30 @@

## Unreleased

### Added

- Ship 33 further locale catalogues, so `--locale` now selects any of `ar`,
`cs`, `cy`, `da`, `de`, `el`, `en-GB`, `en-US`, `es-419`, `es-ES`, `fa`, `fi`,
`fr`, `gd`, `he`, `hi`, `hu`, `id`, `it`, `ja`, `ko`, `nb`, `nl`, `pl`,
`pt-BR`, `pt-PT`, `ro`, `ru`, `sv`, `th`, `tr`, `uk`, `vi`, `zh-Hans` or
`zh-Hant`, with `en-US` remaining the source and fallback locale
([#466](https://github.com/leynos/netsuke/issues/466))

### Changed

- Select catalogues by exact locale tag with deliberate per-language fallback
rules, so `es-419` and `es-ES`, `pt-BR` and `pt-PT`, and `zh-Hans` and
`zh-Hant` stay distinct instead of collapsing onto one catalogue per language
([#466](https://github.com/leynos/netsuke/issues/466))
- Make `src/locale_catalogues.rs` the authoritative locale registry, read by
the embedded catalogues, the build-time audit, the `rerun-if-changed`
directives, packaging, and the tests; the build now fails if `Cargo.toml`'s
`ortho_config` locale metadata drifts from it
([#466](https://github.com/leynos/netsuke/issues/466))
- Extend the build-time localization audit to every declared locale and to
interpolation variables, so a message that drops or invents a `{ $variable }`
fails the build ([#466](https://github.com/leynos/netsuke/issues/466))

- Route graph-view node registration through a borrow-returning
`NodePathRegistry` accessor that looks paths up once on hits and clones a
path only on insertion ([#465](https://github.com/leynos/netsuke/issues/465))
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 43 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ include = [
"README.md",
"LICENSE",
"build.rs",
"build_l10n_audit.rs",
"build_l10n_audit/**",
]
license = "ISC"
readme = "README.md"
Expand All @@ -22,7 +22,43 @@ categories = ["command-line-utilities", "development-tools::build-utils"]

[package.metadata.ortho_config]
root_type = "netsuke::cli::CliConfig"
locales = ["en-US", "es-ES"]
locales = [
"ar",
"cs",
"cy",
"da",
"de",
"el",
"en-GB",
"en-US",
"es-419",
"es-ES",
"fa",
"fi",
"fr",
"gd",
"he",
"hi",
"hu",
"id",
"it",
"ja",
"ko",
"nb",
"nl",
"pl",
"pt-BR",
"pt-PT",
"ro",
"ru",
"sv",
"th",
"tr",
"uk",
"vi",
"zh-Hans",
"zh-Hant",
]

[package.metadata.kani.flags]
default-unwind = "6"
Expand Down Expand Up @@ -172,6 +208,11 @@ strip-ansi-escapes = "0.2"
toml = "0.8"
serde_yaml = "0.9"
proptest = "1.11.0"
# Plural-selection tests must pass numeric arguments to Fluent. `ortho_config`
# exposes `LocalizationArgs` as a map of `FluentValue`, but does not re-export
# the value type, so the tests need `fluent-bundle` directly. Constrained to
# the version `ortho_config` resolves, or the `FluentValue` types would differ.
fluent-bundle = "0.16.0"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Target-specific dev-deps
[target.'cfg(unix)'.dev-dependencies]
Expand Down
31 changes: 28 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,25 @@ mod cli_l10n;
#[path = "src/host_pattern.rs"]
mod host_pattern;

/// The locale registry, shared with the library crate.
///
/// Both `localization` and the audit reach the registry through
/// `crate::locale_catalogues`, so it is declared at this crate's root under
/// that name. It is public because `localization` re-exports it, and a private
/// module cannot be re-exported from a public path. The build script itself
/// reads `SUPPORTED_LOCALES` to emit one `rerun-if-changed` directive per
/// catalogue.
#[path = "src/locale_catalogues.rs"]
pub mod locale_catalogues;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/// Message rendering, shared with the library crate.
///
/// Exposed as `crate::localization`, which `cli`, `cli_l10n`, and
/// `host_pattern` reach for `localization::keys` when building the clap
/// command for man-page generation. Public so its `locales` re-export stays
/// reachable at `crate::localization::locales`.
#[path = "src/localization/mod.rs"]
mod localization;
pub mod localization;

#[expect(
dead_code,
Expand Down Expand Up @@ -136,8 +153,16 @@ fn emit_rerun_directives() {
println!("cargo:rerun-if-env-changed=TARGET");
println!("cargo:rerun-if-env-changed=PROFILE");
println!("cargo:rerun-if-changed=src/localization/keys.rs");
println!("cargo:rerun-if-changed=locales/en-US/messages.ftl");
println!("cargo:rerun-if-changed=locales/es-ES/messages.ftl");
println!("cargo:rerun-if-changed=src/locale_catalogues.rs");
println!("cargo:rerun-if-changed=Cargo.toml");
// The locale registry owns the catalogue list, so the rerun directives are
// derived from it rather than repeated by hand.
for entry in locale_catalogues::SUPPORTED_LOCALES {
println!(
"cargo:rerun-if-changed={}",
build_l10n_audit::catalogue_path(entry.tag()).display()
);
}
}

#[expect(
Expand Down
Loading
Loading