Skip to content

fix(cli): preserve digits when deriving lib_name from package name#4544

Open
DanielChernov7 wants to merge 1 commit into
otter-sec:masterfrom
DanielChernov7:fix/3715-lib-name-digit-boundaries
Open

fix(cli): preserve digits when deriving lib_name from package name#4544
DanielChernov7 wants to merge 1 commit into
otter-sec:masterfrom
DanielChernov7:fix/3715-lib-name-digit-boundaries

Conversation

@DanielChernov7

Copy link
Copy Markdown

Summary

Manifest::lib_name() and get_or_create_program_id() used heck::to_snake_case, which inserts underscores at digit boundaries (e.g. groth16_verify -> groth_16_verify). Cargo's default lib-target name derivation only replaces - with _, so anchor was looking for IDL / SO / keypair artifacts
under a name Cargo never produces, breaking anchor test / anchor build for any project whose package name contains digits adjacent to letters.

This PR switches both call sites to .replace('-', "_") to match Cargo, and adds unit tests covering the digit-boundary regression, the dash → underscore case, plain snake_case pass-through, and the explicit [lib].name override.

Closes #3715.

Branch Target

master — this change is not breaking. The new behavior matches Cargo's default lib-target naming rule, which is what anchor's build pipeline already produces on disk.

Test plan

  • cargo test -p anchor-cli --lib — 25 tests pass (4 new + 21 existing)
  • cargo clippy -p anchor-cli --all-targets -- -D warnings — clean
  • cargo +nightly fmt -p anchor-cli — applied

@DanielChernov7

Copy link
Copy Markdown
Author

Taking this - draft PR at #4544.

Root cause: Manifest::lib_name() and get_or_create_program_id() use heck::to_snake_case, which inserts underscores at digit boundaries (groth16_verify -> groth_16_verify). Cargo's default lib-target name derivation only does - -> _, so anchor ends up looking for artifacts under a name Cargo
never produces.

PR switches both call sites to .replace('-', "_") and adds regression tests.

@DanielChernov7 DanielChernov7 marked this pull request as ready for review May 18, 2026 14:26
Comment thread cli/src/config.rs Outdated
// produce `groth_16_verify` here, sending anchor to look for IDL/SO
// artifacts under a name Cargo never produces.
#[test]
fn lib_name_preserves_digits_in_snake_case_package_name() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

these regression tests passed again master aswell? can you try different words with upper and lowercases

@DanielChernov7 DanielChernov7 force-pushed the fix/3715-lib-name-digit-boundaries branch from 052cea4 to 36c8d53 Compare May 20, 2026 17:33
@DanielChernov7

Copy link
Copy Markdown
Author

Good catch, you were right. I checked: heck 0.4 (as pinned in cli/Cargo.toml) doesn't actually split on letter↔digit boundaries, so my original test (groth16_verify → groth16_verify) passed on master too. The real divergence between heck and Cargo's default lib-target derivation is case-related - heck
lowercases and splits camelCase, while Cargo preserves the package name and only swaps - for _.

Force-pushed an update with four tests that actually fail on master - Groth16Verify, groth16Verify, HTTPServer, MyProgram (verified by running them against unmodified master; all four fail with e.g. left: "groth16_verify", right: "Groth16Verify"). Kept four sanity tests for the cases that already worked
(dash replacement, plain snake_case, snake_case with digits, explicit [lib].name override). Commit message and code comment updated to describe the actual divergence

@0x4ka5h 0x4ka5h left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

i dont think we could add commit message with --trailers of ai

Comment thread cli/src/rust_template.rs Outdated
pub fn get_or_create_program_id(name: &str, target_path: impl AsRef<Path>) -> Pubkey {
// Match Cargo's default lib-target naming (`-` -> `_`). Using a full
// snake_case conversion would split digit boundaries (e.g.
// `groth16_verify` -> `groth_16_verify`) and diverge from the actual

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can you replace the groth16_verify -> groth_16_verify example with the actual case (Groth16Verify -> groth16_verify is what heck does).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can you address this aswell? seems like you missed this one.

`Manifest::lib_name()` used `heck::to_snake_case`, which lowercases
and splits on camel-case boundaries (e.g. `Groth16Verify` ->
`groth16_verify`, `HTTPServer` -> `http_server`). Cargo's default
lib-target name derivation only replaces `-` with `_` and preserves
case, so anchor was looking for IDL / SO / keypair artifacts under a
name Cargo never produces for any package whose name contains
uppercase letters, breaking `anchor test` / `anchor build`.

Switch to `.replace('-', "_")` to match Cargo, and add regression
tests covering the four divergent cases (PascalCase with digits,
camelCase with digits, consecutive uppercase, plain PascalCase),
plus sanity tests for the cases that already worked (dash
replacement, plain snake_case pass-through, snake_case with digits,
explicit `[lib].name` override).

Closes otter-sec#3715.
@DanielChernov7 DanielChernov7 force-pushed the fix/3715-lib-name-digit-boundaries branch from 36c8d53 to f7945d0 Compare May 21, 2026 07:52
@DanielChernov7

Copy link
Copy Markdown
Author

Fixed the stale example in the rust_template.rs comment to use the actual heck divergence.
Dropped the AI co-author trailer from the commit message.

@0x4ka5h 0x4ka5h left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

the changes lgtm, but i'm not sure about commit meessages @jamie-osec

@DanielChernov7

Copy link
Copy Markdown
Author

Hi, do we have any updates so far?

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.

anchor test is trying to find groth_16_verify.json when the generated file is called groth16_verify.json

2 participants