Skip to content

feat(core): import Guitar Pro 7/8 (.gp) - #133

Merged
PhysShell merged 4 commits into
mainfrom
claude/gp7-import
Jul 18, 2026
Merged

feat(core): import Guitar Pro 7/8 (.gp)#133
PhysShell merged 4 commits into
mainfrom
claude/gp7-import

Conversation

@PhysShell

Copy link
Copy Markdown
Owner

Guitar Pro 7/8 (.gp) import

Recovers the one format the importer refused. In the target tab collection 79 of 410 files (19%) are .gp and all returned UnsupportedFormat; this makes them import.

Base 18ec861 (main)
HEAD da8fdbe
Commits 2 (RED → GREEN)

Why it's small

A .gp file is a plain ZIP (PK\x03\x04) carrying Content/score.gpif. The guitarpro 0.4.2 crate griff already depends on ships Song::read_gp, which unzips it and runs the same GPIF conversion the GP6 .gpx path already uses. The Song's version.number.0 becomes 7, so gp_song_to_score needs no change: it tags source_meta.format = "GP7" and takes the existing >= 6 branch (zero-indexed strings, raw repeat counts). No new dependency — guitarpro was already resolved and compiles read_gp unconditionally (the crate declares no features).

A subagent spike established feasibility (found read_gp, proved the GPIF path, swept all 79 files); every claim here was then re-verified on this actual change, not taken from the spike.

RED → GREEN

commit
a225a85 RED three failing tests fix the contract
da8fdbe GREEN detect_gp_version + import_gp_score + CLI mapping + docs

Tests:

  • detect_version_gp7 — ZIP magic → Some(7) (was None; detect_version_unknown drops its stale PK line).
  • import_gp7_dispatches_to_the_reader — ZIP magic + garbage must reach read_gp and fail there with a typed Parse error, not UnsupportedFormat. This proves the branch is wired without a real .gp fixture — see below.
  • source_format_follows_the_importer_tag — the "GP7" importer tag maps to SourceFormat::Gp, not the MIDI fallback.

No committed .gp test asset, by policy. The corpus is copyrighted community tabs (redistributable: false), so no .gp can be committed, and the repo has no committed GP binary fixtures at all (the GP files under corpus/ are local and git-ignored). The dispatch test covers the wiring with a synthetic ZIP-magic input instead.

Change

  • core/src/gp.rs: detect_gp_version recognises PK\x03\x04 → 7; import_gp_score adds Some(7) => song.read_gp(data)?. Support-matrix and function docs updated.
  • core/src/corpus.rs: SourceFormat::Gp variant ("gp" under the existing rename_all). Additive — no exhaustive match on SourceFormat exists, so nothing breaks.
  • cli/src/main.rs: source_format maps "GP7" => SourceFormat::Gp; five help strings now list .gp.

Local acceptance (files not committed)

Re-ran the ingest inventory over the real collection on this build:

whole collection:  328/410 (80%)  ->  407/410 (99%)
.gp:                 0/79         ->   79/79      (0 panics; F-003 did not fire)
notes read:        1.32M          ->  1.65M

The 3 that still fail are truncated .gp5 files (genuine EOF corruption, unrelated to this change).

Validation

cargo fmt --all --check 0 · cargo clippy --workspace --all-targets -- -D warnings 0 · cargo test --workspace --exclude griff-cli 0 (core 210) · cargo doc --no-deps --workspace 15 warnings, identical to base 18ec861 · cargo +1.92 check (MSRV) 0 · fuzz nightly check 0.

cargo test -p griff-cli fails only missing_file_golden — the pre-existing Russian-locale golden (os error 2 renders localised on this machine); identical at base, unaffected by this change, green on CI's English runner.

Blast radius

Three files, all additive. import_score_auto is content-sniffed, so .gp routes automatically once the branch lands — no extension-dispatch change. Nothing outside the GP import path is touched.

Not self-accepted, not merged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM

PhysShell and others added 2 commits July 18, 2026 16:50
GP7/8 `.gp` was the one format the importer refused: 79 of 410 tabs in the
target collection (19%) returned UnsupportedFormat. A `.gp` file is a ZIP
(`PK\x03\x04`) carrying `Content/score.gpif`, and the `guitarpro` 0.4.2 crate
griff already depends on ships `Song::read_gp`, which unzips it and runs the
same GPIF conversion the GP6 `.gpx` path uses.

Three failing tests fix the contract:

- `detect_version_gp7`: the ZIP magic maps to Some(7) (was None).
- `import_gp7_dispatches_to_the_reader`: ZIP magic + garbage must reach
  `read_gp` and fail *there* with a typed Parse error, not UnsupportedFormat.
  This proves the branch is wired without a real `.gp` fixture — the corpus is
  copyrighted community tabs (redistributable:false), so no `.gp` can be
  committed as a test asset, and the repo has no committed GP binary fixtures.
- `source_format_follows_the_importer_tag`: the "GP7" importer tag maps to the
  new `SourceFormat::Gp`, not the MIDI fallback.

`detect_version_unknown` drops its PK line, since `PK\x03\x04` is no longer
unknown. `SourceFormat::Gp` is added as an inert data-only variant so the CLI
test compiles; the mapping that would satisfy it is deliberately not wired yet.
No exhaustive match on SourceFormat exists, so the variant breaks nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
`detect_gp_version` maps the ZIP magic `PK\x03\x04` to major version 7, and
`import_gp_score` dispatches it to `guitarpro::Song::read_gp`, which unzips
`Content/score.gpif` and runs the same GPIF conversion `read_gpx` (GP6) already
uses. `gp_song_to_score` needs no change: the Song's `version.number.0` is 7, so
it tags `source_meta.format = "GP7"` and takes the existing `>= 6` branch
(zero-indexed strings, raw repeat counts). The CLI maps that tag to
`SourceFormat::Gp`.

Local acceptance over the target collection (the 79 real `.gp` files this
machine has, not committed): all 79 import, 0 panics — the F-003 guitarpro
out-of-bounds did not fire on any. Whole-collection import went 328/410 (80%)
to 407/410 (99%); the remaining 3 are truncated `.gp5` files (genuine EOF
corruption, not a format gap). Notes read rose 1.32M to 1.65M.

No new dependency: `guitarpro` 0.4.2 was already resolved and already compiles
`read_gp` (the crate declares no features). Docs updated: the support matrix,
the `import_gp_score` doc, and the five CLI help strings that list formats.

Validation: fmt, clippy -D warnings, workspace tests (core 210), cargo doc
(15 warnings, identical to base) — all clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@PhysShell, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 72c4b36f-2690-4a39-837e-45a3eead43d2

📥 Commits

Reviewing files that changed from the base of the PR and between 6cc24c9 and 73911d4.

📒 Files selected for processing (4)
  • cli/src/main.rs
  • core/src/corpus.rs
  • core/src/gp.rs
  • ui-core/src/capture.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/gp7-import

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da8fdbeb6f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cli/src/main.rs
PhysShell and others added 2 commits July 18, 2026 18:18
…t midi

Review finding on this PR (Codex): the CLI's `source_format` gained a `"GP7" =>
SourceFormat::Gp` arm, but the cockpit/capture path has its own copy of the same
mapper in `ui-core/src/capture.rs`, and it was left with only GP3..GP6. A `.gp`
score curated through the UI therefore records `source.format = "midi"` — the
exact silent-mislabel the CLI change was meant to prevent, on the other path.

The test maps a GP7-tagged score through the capture mapper and expects
`SourceFormat::Gp`; it fails today with `midi`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
The cockpit/capture `source_format` mapper gains the `"GP7" =>
SourceFormat::Gp` arm, matching the CLI. A `.gp` score curated through the UI
now records its true format instead of falling back to `midi`. The RED test
passes.

Both copies of this mapping now carry GP7; they stay parallel by convention
(the cockpit path is wasm and cannot share the CLI's binary-only helpers).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
@PhysShell
PhysShell merged commit ed85313 into main Jul 18, 2026
15 checks passed
PhysShell added a commit that referenced this pull request Jul 18, 2026
Brings PR #133's Guitar Pro 7/8 support and the cockpit capture provenance
fix onto this branch, so griff ingest reads the 79 .gp files in the target
collection instead of skipping them as unrecognised. No conflicts: #133 touched
core/src/gp.rs, core/src/corpus.rs (the SourceFormat::Gp variant), cli/src/main.rs
(the source_format arm) and ui-core/src/capture.rs; this branch's ingest work is
in core/src/ingest.rs and separate cli functions.

This branch's 12 commits and their hashes are unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant