Repository navigation
Describe each format in Rust and remove plugin.toml - #458
Merged
Merged
Conversation
Each format now describes itself with a 'static Descriptor that its
FormatPlugin::descriptor returns: id, name, version (the crate's,
env!("CARGO_PKG_VERSION")), description, mount, repository kinds,
storage and asset names. Descriptor, Storage, Assets (with
Assets::DEFAULT) and DEFAULT_MOUNT live in forge-plugin-api next to
RepositoryKind. NuGet and raw define theirs (DESCRIPTOR) next to their
implementations, so a typo in a key or a kind fails to compile.
Plugin::builtin takes only the format, Plugin::descriptor replaces
Plugin::manifest, and Plugin::id returns the descriptor's id without
leaking a copy. What the startup parser checked (the id's spelling and
the reserved ids, the mount, the kinds, the asset names) is now
forge_plugin::descriptor::check, which a test over plugins::builtin()
runs, together with the check that no two formats share an id: a bad
descriptor fails cargo test instead of startup.
Gone: plugin.toml from both crates, plugin_toml! and PLUGIN_TOML,
Manifest::parse, PluginError, SUPPORTED_APIS, forge_plugin_api::API and
the api key, the plugin_toml_names_this_crate tests, the "keep it equal"
comments, and forge-plugin's toml dependency (and its unused serde and
thiserror). The crates' README and docs/format-plugins.md show the
descriptor instead of plugin.toml.
GET /admin/formats answers as before.
Fixes #444
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CxwRK8xYPsMDBiMkySxcHf
schmitch
pushed a commit
that referenced
this pull request
Oct 24, 2026
Resolve the conflicts with #458 (formats describe themselves in Rust, plugin.toml is gone) and #460 (access levels): - npm describes itself with a DESCRIPTOR like NuGet and raw; plugin.toml's upstream_token key becomes the Descriptor field `upstream_token` (UpstreamToken::Bearer for npm, None for NuGet and raw). - The dispatcher's per-action authorization uses authz::Level. - The package_tag / cli_login migration becomes 0047: main's access levels took 0046. - The cli-login web page's path is a reserved mount. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BaGpNGgkQV54XvgL5D9ay2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #444
Part of #442. This PR is stacked on #456 (#443), which moves the format crates to
crates/formats/. Merge that one first; GitHub then retargets this one tomain.Changes
The descriptor. Each format describes itself with a
'staticvalue thatFormatPlugin::descriptor()returns. The new types live inforge-plugin-api, next toRepositoryKind:Descriptor:id,name,version,description,mount,kinds,storage,assets;Storage;Assets, with&'static strfields andAssets::DEFAULTin place of the serde default;DEFAULT_MOUNT.NuGet and raw each define
pub const DESCRIPTORnext to theirimpl FormatPlugin, withversion: env!("CARGO_PKG_VERSION"). A typo in a key or a kind now fails the build.The host side.
Plugin::builtin(implementation)takes only the format.Plugin::descriptor()replacesPlugin::manifest().Plugin::id()returnsdescriptor().idwithout leaking a copy.RepositoryKind::as_str()saves the format registry its own mapping.Checks. The startup parser's checks are now
forge_plugin::descriptor::check:RESERVED_IDS;RESERVED_MOUNTS, together with the existing test that every web UI page is reserved;checkalso refuses two formats with the same id. A new test inforge-server,plugins::tests::the_builtin_formats_describe_themselves_well, runs it overplugins::builtin(). It also shows thatcheckrefuses a malformed or reserved id, a second format with a built-in's id, and invalid asset names. The probe plugin inplugin_contract.rschecks its own descriptor the same way.Removed:
plugin.tomlfrom both crates;plugin_toml!,PLUGIN_TOML,Manifest::parseandmanifest.rs;PluginErrorandSUPPORTED_APIS;forge_plugin_api::APIand theapikey;plugin_toml_names_this_cratetest;versionin plugin.toml" comments;forge-plugin'stomldependency, plus its now unusedserdeandthiserror.Docs.
crates/formats/README.mdand Layout and Writing a plugin indocs/format-plugins.mdnow show the descriptor. The status note no longer mentions a declared contract version.The new doc example on
Descriptorisno_run.test-parallel.shrecords every test binary cargo would run, and that includes a doctest's temporary binary, which no longer exists when the script runs it. That's why the other doc examples in the repo don't run either.No changelog fragment, since nothing changes for anyone running Forge.
Checks
cargo fmt --checkandcargo clippy --workspace --all-targets -- -D warningspass.test-parallel.sh --workspace: 105 of 106 test binaries passed, including the existing admin tests ofGET /admin/formats, unchanged. The 106th was the doctest's temporary binary described above. With the exampleno_run,test-parallel.shover the plugin crates passes, the doctest included.cargo tree -p forge-pluginshows notoml.git grep -n 'plugin\.toml\|plugin_toml\|PLUGIN_TOML'finds nothing outsideCHANGELOG.mdanddocs/changes/.Generated by Claude Code