Skip to content

fix(cli): preserve program names from anchor.toml when scaffold runbook#680

Merged
MicaiahReid merged 3 commits into
mainfrom
fix/convert-case
Jun 1, 2026
Merged

fix(cli): preserve program names from anchor.toml when scaffold runbook#680
MicaiahReid merged 3 commits into
mainfrom
fix/convert-case

Conversation

@MicaiahReid
Copy link
Copy Markdown
Collaborator

@MicaiahReid MicaiahReid commented May 29, 2026

Fixes #679

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 29, 2026

Greptile Summary

This PR fixes a bug where program names from Anchor.toml and Cargo.toml were being mangled by convert_case::Case::Snake, which splits at digit–letter transitions (e.g. v2v_2). The fix replaces the snake_case conversion with name-preserving logic in both the Anchor manifest path and the Cargo manifest fallback path.

  • In anchor.rs, program name keys from [programs.localnet] are now cloned verbatim instead of run through to_case(Case::Snake).
  • In utils.rs, the name resolution prefers [lib] name from Cargo.toml (already underscore-safe) and falls back to package.name.replace('-', \"_\") — a simple substitution that does not split digits. Both paths are covered by new regression tests using tempfile.

Confidence Score: 5/5

Safe to merge — the change is a targeted fix to a name-mangling bug with full test coverage and no regressions introduced.

Both affected code paths (Anchor manifest and Cargo manifest) are corrected with minimal, focused changes. The old convert_case calls are removed entirely, and the replacement logic (clone() / replace('-', "_")) is straightforwardly correct. Three new unit tests and one integration test assert the expected behavior, including the digit-splitting regression case. No existing behavior is broken for names that did not contain digits.

No files require special attention.

Important Files Changed

Filename Overview
crates/cli/src/scaffold/anchor.rs Removes to_case(Case::Snake) from program name deserialization; adds a regression test for name preservation.
crates/cli/src/scaffold/utils.rs Adds Lib struct with optional name, switches fallback to replace('-', "_"), and adds three new unit tests covering all name-resolution branches.
crates/cli/Cargo.toml Adds tempfile as a dev-dependency to support filesystem-based unit tests in utils.rs.
crates/sdk-node/package-lock.json Replaces empty optional stubs for platform-specific surfpool packages with full v1.3.0 entries from the npm registry.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Scaffold runbook] --> B{Anchor.toml present?}
    B -- yes --> C[Parse AnchorManifest]
    C --> D["deser_programs()"]
    D --> E["name.clone() ✅\n(was: to_case(Case::Snake) ❌)"]
    E --> F[program_name preserved verbatim]

    B -- no --> G[Walk workspace Cargo.toml members]
    G --> H{lib.name present?}
    H -- yes --> I[use lib.name directly]
    H -- no --> J["package.name.replace('-', '_') ✅\n(was: to_case(Case::Snake) ❌)"]
    I --> K[program_name preserved]
    J --> K

    F --> L[Construct .so path & check existence]
    K --> L
    L --> M[ProgramMetadata]
Loading

Reviews (5): Last reviewed commit: "chore: update package-lock" | Re-trigger Greptile

Comment on lines +90 to +93
#[derive(Debug, Clone, Deserialize)]
pub struct Lib {
pub name: String,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 The name field on Lib is non-optional, which means CargoManifestFile::from_manifest_str will fail with a deserialization error for any Cargo.toml that has a [lib] section without an explicit name key. This is extremely common — both in this very repository (crates/core, crates/types, crates/sdk all have [lib] path = "src/lib.rs" with no name) and in standard Anchor/Solana projects where [lib] crate-type = ["cdylib", "lib"] is typical. When the workspace scanner hits any such member, scaffolding fails entirely rather than falling back to the package name.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed: 3daf01e

Comment on lines +25 to +29
let program_name = manifest
.lib
.as_ref()
.map(|lib| lib.name.clone())
.unwrap_or_else(|| package.name.replace('-', "_"));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Once Lib.name becomes Option<String>, the fallback chain here needs to use and_then instead of map so a Lib present but with no name still falls through to the package-name logic.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed: 3daf01e

Comment thread .mcp.json Outdated
@MicaiahReid
Copy link
Copy Markdown
Collaborator Author

@greptileai I've addressed your comments - ready for rereview

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 29, 2026

Want your agent to iterate on Greptile's feedback? Try greploops.

@MicaiahReid MicaiahReid requested a review from lgalabru June 1, 2026 12:37
@MicaiahReid MicaiahReid merged commit 1133a48 into main Jun 1, 2026
9 of 10 checks passed
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 deploy fails for packages with a digit in the name (e.g. v2) — program name mis-derived via convert_case, leaving a non-executable stub

2 participants