From bf7fe03219f0db8c983adb81b5ae4bc9cc0236f9 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
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 `<key>.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 <noreply@anthropic.com>
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
+                // (`<key>.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

