Skip to content

Commit a6e9899

Browse files
committed
docs(cli): document view status filtering workflow
1 parent c565ed9 commit a6e9899

5 files changed

Lines changed: 41 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on Keep a Changelog and this project follows Semantic Versioning while APIs remain in 0.x evolution.
66

7+
## [Unreleased]
8+
9+
### Added
10+
- CLI `view` status-based filtering with `--status`, `--keys-only`, and `--json` output modes for listing untranslated/review-needed entries.
11+
12+
### Changed
13+
- `view --status` now supports strict metadata gating: `langcodec --strict view ... --status ...` requires explicit status metadata (v1 support: `.xcstrings`).
14+
715
## [0.7.0] - 2026-02-17
816

917
### Added

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ This is a `0.7.0` release available on [crates.io](https://crates.io/crates/lang
6262
- Normalize and detect drift: `langcodec normalize -i 'locales/**/*.{strings,xml,csv,tsv,xcstrings}' --check`
6363
- Sync existing keys only: `langcodec sync --source A.xcstrings --target B.xcstrings --match-lang en`
6464
- View: `langcodec view -i strings.xml --full`
65+
- View filtered untranslated/review-needed keys: `langcodec view -i Localizable.xcstrings --status new,needs_review --keys-only`
66+
- View filtered results as JSON: `langcodec view -i Localizable.xcstrings --status new --lang fr --json`
6567
- Stats (JSON): `langcodec stats -i Localizable.xcstrings --json`
6668
- See full options: langcodec-cli/README.md#stats
6769
- Example output:
@@ -99,6 +101,7 @@ This is a `0.7.0` release available on [crates.io](https://crates.io/crates/lang
99101
- Normalize `--continue-on-error` processes all inputs and returns non-zero if any file fails.
100102
- Android path inference: `values/strings.xml` (no qualifier) defaults to English (`en`).
101103
- When converting to `.xcstrings`, if `source_language` or `version` metadata is missing, the CLI defaults them to `en` and `1.0` respectively (overridable via flags).
104+
- Strict status filtering note: `langcodec --strict view --status ...` requires explicit status metadata (supported in v1: `.xcstrings`).
102105

103106
#### Plurals
104107

langcodec-cli/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,21 @@ CI-oriented options:
6363

6464
```sh
6565
langcodec view -i values/strings.xml --full
66+
langcodec view -i Localizable.xcstrings --status new,needs_review
67+
langcodec view -i Localizable.xcstrings --status new --lang fr --json
68+
langcodec view -i Localizable.xcstrings --status new,needs_review --keys-only
6669
```
6770

6871
Prints entries. Plurals are labeled with `Type: Plural` and show categories.
6972

73+
View options:
74+
75+
- `--status`: Filter by one or more statuses (`translated|needs_review|new|do_not_translate|stale`), comma-separated.
76+
- `--keys-only`: Print only keys in text mode (`lang<TAB>key` when `--lang` is not set).
77+
- `--json`: Output machine-readable JSON (`summary` + `entries` or `keys` payload).
78+
- `--lang`: Restrict results to a specific language before status filtering.
79+
- `--strict`: With `--status`, requires explicit status metadata (supported in v1: `.xcstrings`).
80+
7081
### stats
7182

7283
```sh

langcodec-cli/src/view.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ fn parse_status_filter(status: &Option<String>) -> Result<Option<Vec<EntryStatus
2626
};
2727

2828
let mut parsed = Vec::new();
29-
for token in raw_status.split(',').map(str::trim).filter(|s| !s.is_empty()) {
29+
for token in raw_status
30+
.split(',')
31+
.map(str::trim)
32+
.filter(|s| !s.is_empty())
33+
{
3034
let normalized = token.replace(['-', ' '], "_");
3135
let entry_status = normalized.parse::<EntryStatus>().map_err(|_| {
3236
format!(

langcodec-cli/tests/view_status_cli_tests.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,20 @@ fn test_view_status_json_outputs_entries_payload() {
488488
assert_eq!(payload["summary"]["total_matches"], 2);
489489
assert_eq!(payload["summary"]["statuses"]["needs_review"], 2);
490490
let languages = payload["summary"]["languages"].as_array().unwrap();
491-
assert_eq!(languages.len(), 2, "Expected 2 languages. payload: {payload}");
491+
assert_eq!(
492+
languages.len(),
493+
2,
494+
"Expected 2 languages. payload: {payload}"
495+
);
492496
assert!(languages.iter().any(|lang| lang == "en"));
493497
assert!(languages.iter().any(|lang| lang == "fr"));
494498

495499
let entries = payload["entries"].as_array().unwrap();
496-
assert_eq!(entries.len(), 2, "Expected only filtered entries. payload: {payload}");
500+
assert_eq!(
501+
entries.len(),
502+
2,
503+
"Expected only filtered entries. payload: {payload}"
504+
);
497505

498506
let en_entry = entries
499507
.iter()
@@ -536,7 +544,10 @@ fn test_view_status_json_keys_only_outputs_keys_payload() {
536544

537545
assert_eq!(payload["summary"]["total_matches"], 2);
538546
assert_eq!(payload["summary"]["statuses"]["needs_review"], 2);
539-
assert!(payload.get("entries").is_none(), "Expected keys-only payload");
547+
assert!(
548+
payload.get("entries").is_none(),
549+
"Expected keys-only payload"
550+
);
540551

541552
let keys = payload["keys"].as_array().unwrap();
542553
assert_eq!(keys.len(), 2);

0 commit comments

Comments
 (0)