From bf7fe03219f0db8c983adb81b5ae4bc9cc0236f9 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Thu, 23 Jul 2026 01:15:45 +0000 Subject: [PATCH 12/25] minicargo: set the CARGO_PKG_* metadata environment variables cargo defines CARGO_PKG_AUTHORS/DESCRIPTION/HOMEPAGE/REPOSITORY/ LICENSE/LICENSE_FILE/README/RUST_VERSION for every crate (empty string when the manifest omits them), and env!("CARGO_PKG_...") is a hard error when the variable is undefined - hex 0.7.0 uses env!("CARGO_PKG_DESCRIPTION") in its clap setup and failed to build. The values were already parsed-and-ignored in the manifest loader; they are now recorded (authors ':'-joined as cargo does; `readme = false` and `.workspace = true` inheritance left as empty strings) and exported in push_env_common. Also accepts the `license-file` key, which previously would have been rejected as unknown. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_013wCVW89GjmNyYviEcANPHM --- tools/minicargo/build.cpp | 10 ++++++++ tools/minicargo/manifest.cpp | 50 ++++++++++++++++++++++++++++++++---- tools/minicargo/manifest.h | 20 +++++++++++++++ 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp index 0a71f339..6180db0b 100644 --- a/tools/minicargo/build.cpp +++ b/tools/minicargo/build.cpp @@ -747,6 +747,16 @@ namespace { env.push_back("CARGO_PKG_VERSION_MAJOR", ::format(manifest.version().major)); env.push_back("CARGO_PKG_VERSION_MINOR", ::format(manifest.version().minor)); env.push_back("CARGO_PKG_VERSION_PATCH", ::format(manifest.version().patch)); + // Metadata variables: cargo always defines these (empty when absent), and + // `env!("CARGO_PKG_...")` hard-errors if they are undefined + env.push_back("CARGO_PKG_AUTHORS", manifest.pkg_authors()); + env.push_back("CARGO_PKG_DESCRIPTION", manifest.pkg_description()); + env.push_back("CARGO_PKG_HOMEPAGE", manifest.pkg_homepage()); + env.push_back("CARGO_PKG_REPOSITORY", manifest.pkg_repository()); + env.push_back("CARGO_PKG_LICENSE", manifest.pkg_license()); + env.push_back("CARGO_PKG_LICENSE_FILE", manifest.pkg_license_file()); + env.push_back("CARGO_PKG_README", manifest.pkg_readme()); + env.push_back("CARGO_PKG_RUST_VERSION", manifest.pkg_rust_version()); // - Downstream environment variables manifest.iter_main_dependencies([&](const PackageRef& dep) { if( ! dep.is_disabled() ) diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp index e4187903..54453e0c 100644 --- a/tools/minicargo/manifest.cpp +++ b/tools/minicargo/manifest.cpp @@ -513,15 +513,51 @@ void PackageManifest::fill_from_kv(ErrorHandler& eh, const WorkspaceManifest* wm eh.error("Build script path cannot be empty"); } } - else if( key == "authors" - || key == "description" + else if( key == "authors" ) + { + // Exported as CARGO_PKG_AUTHORS (':'-joined, as cargo does) + if( key_val.path.size() == 2 && key_val.value.m_type == TomlValue::Type::List ) + { + for(const auto& sv : key_val.value.m_sub_values) + { + if( sv.m_type != TomlValue::Type::String ) + continue; + if( !rv.m_pkg_authors.empty() ) + rv.m_pkg_authors += ":"; + rv.m_pkg_authors += sv.as_string(); + } + } + } + else if( key == "description" || key == "homepage" || key == "documentation" || key == "repository" || key == "readme" - || key == "categories" - || key == "keywords" || key == "license" + || key == "license-file" + ) + { + // Recorded for the `CARGO_PKG_*` environment variables + // (`.workspace = true` inheritance is not handled - left empty, + // and e.g. `readme = false` is a boolean - also left empty) + if( key_val.path.size() == 2 && key_val.value.m_type == TomlValue::Type::String ) + { + ::std::string* slot + = key == "description" ? &rv.m_pkg_description + : key == "homepage" ? &rv.m_pkg_homepage + : key == "repository" ? &rv.m_pkg_repository + : key == "readme" ? &rv.m_pkg_readme + : key == "license" ? &rv.m_pkg_license + : key == "license-file" ? &rv.m_pkg_license_file + : nullptr /*documentation: no matching env var*/; + if( slot ) + { + *slot = key_val.value.as_string(); + } + } + } + else if( key == "categories" + || key == "keywords" ) { // Informational only, ignore @@ -544,7 +580,11 @@ void PackageManifest::fill_from_kv(ErrorHandler& eh, const WorkspaceManifest* wm } else if( key == "rust-version" ) { - // Minimum supported rust version, don't care? + // Minimum supported rust version - exported as CARGO_PKG_RUST_VERSION + if( key_val.path.size() == 2 && key_val.value.m_type == TomlValue::Type::String ) + { + rv.m_pkg_rust_version = key_val.value.as_string(); + } } else if( key == "links" ) { diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h index 545ae38a..0a18cce7 100644 --- a/tools/minicargo/manifest.h +++ b/tools/minicargo/manifest.h @@ -350,6 +350,18 @@ class PackageManifest PackageVersion m_version; ::std::string m_links; + // Package metadata, exported as `CARGO_PKG_*` environment variables + // (cargo sets these to empty strings when absent, and `env!` hard-errors on + // undefined variables) + ::std::string m_pkg_authors; // ':'-joined, as cargo does + ::std::string m_pkg_description; + ::std::string m_pkg_homepage; + ::std::string m_pkg_repository; + ::std::string m_pkg_license; + ::std::string m_pkg_license_file; + ::std::string m_pkg_readme; + ::std::string m_pkg_rust_version; + Edition m_edition = Edition::Unspec; ::std::string m_build_script; @@ -385,6 +397,14 @@ private: public: const PackageVersion& version() const { return m_version; } + const ::std::string& pkg_authors() const { return m_pkg_authors; } + const ::std::string& pkg_description() const { return m_pkg_description; } + const ::std::string& pkg_homepage() const { return m_pkg_homepage; } + const ::std::string& pkg_repository() const { return m_pkg_repository; } + const ::std::string& pkg_license() const { return m_pkg_license; } + const ::std::string& pkg_license_file() const { return m_pkg_license_file; } + const ::std::string& pkg_readme() const { return m_pkg_readme; } + const ::std::string& pkg_rust_version() const { return m_pkg_rust_version; } bool is_std_magic() const { return m_manifest_dir == ::helpers::path(); } -- 2.43.0