Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f2b448f
fix: RS03 recognize tries all known medium sizes as candidates
Apr 8, 2026
fd2ac4e
fix: suppress verbose noise from RS03 candidate loop, fix deb build
Apr 8, 2026
3b25232
fix: update regtest golden files for multi-candidate RS03 recognize
Apr 8, 2026
6654a10
test: add pytest framework and RS03 recognition robustness tests
Apr 8, 2026
b80f9d5
enh: add golden-test framework for declarative regression tests
Apr 10, 2026
dd3f86a
enh: migrate all 28 RS01 verify tests from bash to Python
Apr 10, 2026
7b67c44
enh: migrate all 144 RS01 tests from bash to Python, disable bash tests
Apr 10, 2026
ec1d8f8
enh: migrate all 148 RS02 tests from bash to Python, disable bash tests
Apr 11, 2026
2073324
fix: wire CreateECC output/ecc_size fields, fix path stripping fidelity
Apr 10, 2026
62004ee
enh: migrate RS03f verify tests (34 tests) from bash to Python
Apr 14, 2026
c061ada
enh: migrate RS03f creation tests (14) from bash to Python
Apr 14, 2026
4889ef1
enh: migrate RS03f repair tests from bash to Python
Apr 15, 2026
31f8994
enh: migrate RS03f scanning tests (18) from bash to Python
Apr 15, 2026
9306ca9
enh: migrate RS03f reading tests (18) from bash to Python
Apr 15, 2026
a194816
fix: address code quality review for RS03f reading tests
Apr 15, 2026
b269367
enh: migrate RS03i strip + verify tests (50) from bash to Python
Apr 15, 2026
1c29845
fix: correct verify test count in RS03i docstring (48, not 50)
Apr 15, 2026
7e6c109
enh: migrate RS03i creation tests (20) from bash to Python
Apr 15, 2026
a8fa6ac
enh: migrate RS03i fixing tests (27) from bash to Python
Apr 15, 2026
47f0689
enh: migrate RS03i scanning tests (33) from bash to Python
Apr 16, 2026
2504286
enh: migrate RS03i reading tests (29) from bash to Python
Apr 16, 2026
c6d5a38
enh: disable all 274 bash RS03 tests, migrated to Python pytest
Apr 16, 2026
7d4af73
docs: add test suite README with framework docs and bash/python compa…
Apr 11, 2026
ca98828
docs: update test suite README and CLAUDE.md for completed migration
Apr 16, 2026
ab6ca23
fix: pytest test sizes and deb packaging for CI
Apr 8, 2026
05da4cf
fix: resolve remaining 17 Windows pytest failures
Apr 20, 2026
d8945dd
fix: normalize CRLF in pytest golden comparison for Windows
Apr 20, 2026
4f185b9
fix: drop empty-parametrize placeholders from test_golden collection
Apr 21, 2026
e81032d
i18n: add 5 machine-translated languages and CI coverage gate
Apr 23, 2026
ecbfba5
test(i18n): add returncode check and regex word-boundary anchors
Apr 23, 2026
b1c3f08
scripts: add fill-translations.py machine-translation helper
Apr 23, 2026
d66259c
scripts(fill-translations): add error handling for unreadable PO files
Apr 23, 2026
5a115e9
i18n(de): machine-translate 146 missing strings, marked fuzzy for review
Apr 23, 2026
87a834a
i18n(cs,ru): machine-translate missing strings, marked fuzzy for review
Apr 23, 2026
2ceddfb
i18n(pt_BR): machine-translate 341 missing strings, marked fuzzy for …
Apr 23, 2026
3f92cef
i18n(sv,it): machine-translate 1340 missing strings, marked fuzzy for…
Apr 23, 2026
389fe83
test(i18n): count translated+fuzzy as usable for CI gate (≥90%)
Apr 24, 2026
d262a59
i18n: fix fuzzy formatting and compile machine translations into .mo
Apr 24, 2026
1f3721a
docs: add i18n translator and maintainer guide
Apr 24, 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
5 changes: 5 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,8 @@ jobs:
mkdir -p /var/tmp/regtest
echo "Number of available processors: $(nproc || echo U)"
./regtest/runtests.sh
- name: pytest integration tests
if: matrix.printf == 'normal'
run: |
pip install pytest
python3 -m pytest tests/ -v
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ bugs and added a few tiny features.

See the [INSTALL](INSTALL) file. The [workflow file](.github/workflows/release.yml) that is used to automatically build binaries for each release can also help.

# :test_tube: Testing

The test suite uses Python/pytest with a declarative DSL for golden-file comparison tests. See the [test suite documentation](tests/README.md) for details on the framework, test coverage, and how to add new tests.

```bash
pip install pytest
python3 -m pytest tests/ -v
```

# :camera: Screenshots

### Reading a damaged CD under Windows:
Expand Down
2 changes: 1 addition & 1 deletion debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ICON_SIZES := $(patsubst contrib/dvdisaster%.png,%,$(ICONS))
override_dh_update_autotools_config:
dh_update_autotools_config
test -f $(BACKUP_TAR_FILE) || \
tar cpf $(BACKUP_TAR_FILE) $(MUTABLE_FILES)
tar cpf $(BACKUP_TAR_FILE) $(MUTABLE_FILES) 2>/dev/null || true

override_dh_clean:
dh_clean
Expand Down
183 changes: 183 additions & 0 deletions docs/i18n.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# dvdisaster i18n — Translator & Maintainer Guide

## Overview

dvdisaster uses GNU gettext for localization. The translation pipeline is:

```
src/*.c ──xgettext──> locale/messages.pot ──msgmerge──> locale/<lang>.po ──msgfmt──> locale/<lang>/LC_MESSAGES/dvdisaster.mo
```

| File | Purpose |
|------|---------|
| `locale/messages.pot` | Master template — all translatable strings extracted from C source |
| `locale/<lang>.po` | Per-language translation file — human and machine translations |
| `locale/<lang>/LC_MESSAGES/dvdisaster.mo` | Compiled binary — loaded at runtime (gitignored, built by `make`) |
| `locale/create-makefile` | Generator script called by `./configure` to produce `locale/Makefile` |

**Active languages (11 total):**

| Code | Language | Human-translated | Machine-translated (fuzzy) |
|------|----------|-----------------|---------------------------|
| `be` | Belarusian | 1096 | 0 |
| `cs` | Czech | 880 | ~216 |
| `de` | German | 950 | ~146 |
| `it` | Italian | 395 | ~700 |
| `ka` | Georgian | 1096 | 0 |
| `pl` | Polish | 1096 | 0 |
| `pt_BR` | Brazilian Portuguese | 755 | ~341 |
| `ru` | Russian | 766 | ~330 |
| `sv` | Swedish | 455 | ~640 |
| `tr` | Turkish | 1096 | 0 |
| `uk` | Ukrainian | 1096 | 0 |

Machine-translated entries are marked `#, fuzzy` for human review and compiled into `.mo` via `msgfmt --use-fuzzy`.

---

## Building .mo files

After running `./configure`:

```bash
make -C locale/
```

This runs `msgmerge` (syncs each `.po` with the current `.pot`) then `msgfmt --use-fuzzy -c` (compiles to `.mo`).

---

## Human translation workflow

### Reviewing machine-translated (fuzzy) entries

Find strings awaiting human review in any language:

```bash
msgattrib --fuzzy locale/de.po | grep -A2 "^msgid " | head -40
```

After editing, remove the `#, fuzzy` flag from the entry header to mark it as reviewed. Then rebuild:

```bash
make -C locale/
```

### Adding a new language

1. Create the `.po` scaffold using the existing template:

```bash
cd locale/
msginit --input=messages.pot --locale=<lang> --output=<lang>.po
```

2. (Optional) Machine-translate as a starting point:

```bash
pip install deep-translator polib
python3 scripts/fill-translations.py locale/<lang>.po <lang>
```

3. Fix any formatting issues introduced by machine translation:

```bash
python3 scripts/fix-fuzzy-formatting.py locale/<lang>.po
```

4. Verify it compiles cleanly:

```bash
msgfmt --use-fuzzy -c locale/<lang>.po -o /dev/null
```

5. Rebuild to generate the `.mo`:

```bash
make -C locale/
```

The `create-makefile` script auto-discovers all `*.po` files, so no manual Makefile edits are needed.

### Updating after new source strings are added

When C source files gain new translatable strings, regenerate `messages.pot` and sync all `.po` files:

```bash
make -C locale/ messages.pot # regenerate template
for lang in locale/*.po; do
msgmerge -q -U --no-wrap --no-fuzzy-matching "$lang" locale/messages.pot
done
```

Then use `fill-translations.py` to machine-translate the new gaps, and `fix-fuzzy-formatting.py` to fix any formatting issues before committing.

---

## Maintenance scripts

### `scripts/fill-translations.py`

Fills untranslated PO entries using Google Translate and marks them `#, fuzzy`.

```bash
# Dry run (preview only, no file changes)
python3 scripts/fill-translations.py locale/de.po de --dry-run

# Fill for real
python3 scripts/fill-translations.py locale/it.po it
```

Requires: `pip install deep-translator polib`

### `scripts/fix-fuzzy-formatting.py`

Fixes formatting errors in machine-translated fuzzy entries:
- Aligns leading/trailing `\n` between `msgid` and `msgstr`
- Corrects `%S` → `%s` and `%%` → `%` format-specifier corruptions
- Clears any entries that still fail `msgfmt --check-format` (English fallback)

```bash
python3 scripts/fix-fuzzy-formatting.py locale/de.po
python3 scripts/fix-fuzzy-formatting.py locale/*.po
```

Always run this after `fill-translations.py` and before committing.

---

## CI gates

`tests/test_i18n_coverage.py` runs two checks per language:

| Test | What it checks |
|------|---------------|
| `test_po_format_clean` | `msgfmt --use-fuzzy -c` exits 0 (no format errors) |
| `test_translation_coverage` | `(translated + fuzzy) / total ≥ 90%` |

Run locally:

```bash
python3 -m pytest tests/test_i18n_coverage.py -v
```

The `translated + fuzzy` metric reflects actual binary content: with `--use-fuzzy`, both buckets compile into the `.mo`.

---

## Fuzzy entry policy

Entries marked `#, fuzzy` are:
- **Compiled into `.mo`** (via `msgfmt --use-fuzzy`) — users see the machine translation, not English
- **Flagged for review** — translators should refine them over time
- **Excluded from `msgfmt --statistics` "translated" count** — the CI test accounts for this

To see how many strings still need human review per language:

```bash
for po in locale/*.po; do
lang=$(basename "$po" .po)
n=$(msgattrib --fuzzy "$po" 2>/dev/null | grep -c "^msgid " || echo 0)
echo "$lang: $n fuzzy"
done
```
Loading