From 8a4f477fc2142a1537b046cf745e59009ba03f6c Mon Sep 17 00:00:00 2001 From: PuQing Date: Mon, 3 Aug 2026 00:49:17 +0800 Subject: [PATCH 1/2] build: prepare v0.2.0 for crates.io + PyPI distribution The pivot to a pure toolchain manager (removing build/init/run) changed the CLI surface significantly, so bump the workspace 0.1.5 -> 0.2.0 and make the whole workspace publishable for the first time since the pivot. Rename for available registry names (verified 2026-08-03): - crates.io `lemma` is taken by an unrelated active project, so the binary crate `lemma` -> `lemma-rs`, resuming our own previously published crate (0.1.5, 2025-11). The executable stays `lemma` via [[bin]] name. - `lemma-cli` -> `lemma-args` (also taken); directory renamed to match and all `lemma_cli` imports updated to `lemma_args`. - PyPI `lemma` is taken, so the Python package is renamed `lemma` -> `lemma-lean` in pyproject.toml (maturin bin binding unchanged). Make `cargo publish` work: - Add `version = "0.2.0"` to every internal workspace dependency (they were path-only, which cargo rejects when packaging). - Align `lemma-static` on the workspace version (was pinned 0.1.0). - Move the integration test suite from the workspace-root `tests/` into `crates/lemma-rs/tests/` so the published crate no longer references a `../../tests` path outside its package root. cd.yml: rewrite to publish all 9 crates in topological dependency order (static/platform/output -> toolchain -> config -> args -> download -> install -> lemma-rs), skipping anything already published so a re-run after a partial failure is safe, with a short pause for sparse-index propagation. User-facing install guidance (README, README_CN, `lemma self update`, `lemma self uninstall`, help text) now points at `pipx install lemma-lean` and `cargo install lemma-rs` instead of the squatted `lemma` names. --- .github/workflows/cd.yml | 52 ++++++++++++- Cargo.lock | 78 +++++++++---------- Cargo.toml | 18 ++--- README.md | 34 +++++--- README_CN.md | 28 +++++-- crates/{lemma-cli => lemma-args}/Cargo.toml | 2 +- crates/{lemma-cli => lemma-args}/src/cli.rs | 0 crates/{lemma-cli => lemma-args}/src/help.rs | 21 +++-- crates/{lemma-cli => lemma-args}/src/lib.rs | 0 crates/lemma-config/src/lib.rs | 2 +- crates/lemma-rs/Cargo.toml | 6 +- crates/lemma-rs/src/commands.rs | 2 +- crates/lemma-rs/src/commands/cache.rs | 2 +- crates/lemma-rs/src/commands/completions.rs | 2 +- crates/lemma-rs/src/commands/override.rs | 2 +- crates/lemma-rs/src/commands/self_update.rs | 14 ++-- crates/lemma-rs/src/main.rs | 2 +- .../lemma-rs/tests}/integration_tests.rs | 0 .../lemma-rs/tests}/suite/cli_config.rs | 0 .../lemma-rs/tests}/suite/cli_edge_cases.rs | 0 .../lemma-rs/tests}/suite/cli_init.rs | 0 .../lemma-rs/tests}/suite/cli_link.rs | 0 .../lemma-rs/tests}/suite/cli_override.rs | 0 .../lemma-rs/tests}/suite/cli_project.rs | 0 .../lemma-rs/tests}/suite/cli_proxy.rs | 0 .../lemma-rs/tests}/suite/cli_toolchain.rs | 4 +- .../lemma-rs/tests}/suite/cli_uninstall.rs | 0 {tests => crates/lemma-rs/tests}/suite/mod.rs | 0 .../lemma-rs/tests}/suite/test_helpers.rs | 0 crates/lemma-static/Cargo.toml | 2 +- pyproject.toml | 4 +- 31 files changed, 175 insertions(+), 100 deletions(-) rename crates/{lemma-cli => lemma-args}/Cargo.toml (94%) rename crates/{lemma-cli => lemma-args}/src/cli.rs (100%) rename crates/{lemma-cli => lemma-args}/src/help.rs (95%) rename crates/{lemma-cli => lemma-args}/src/lib.rs (100%) rename {tests => crates/lemma-rs/tests}/integration_tests.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_config.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_edge_cases.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_init.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_link.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_override.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_project.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_proxy.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/cli_toolchain.rs (98%) rename {tests => crates/lemma-rs/tests}/suite/cli_uninstall.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/mod.rs (100%) rename {tests => crates/lemma-rs/tests}/suite/test_helpers.rs (100%) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index ced501f..892995b 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -14,8 +14,54 @@ jobs: - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - - name: Publish lemma crate - working-directory: crates/lemma-rs - run: cargo publish + - name: Publish all crates in dependency order env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: | + set -euo pipefail + + # Topological order of the internal dependency graph: + # lemma-static, lemma-platform, lemma-output (no internal deps) + # lemma-toolchain -> static, platform + # lemma-config -> static, toolchain + # lemma-args -> config, static + # lemma-download -> static, platform, config, toolchain + # lemma-install -> static, config, toolchain, download + # lemma-rs -> all of the above + crates=( + lemma-static + lemma-platform + lemma-output + lemma-toolchain + lemma-config + lemma-args + lemma-download + lemma-install + lemma-rs + ) + + # Return 0 if name@version is already present on crates.io, so a + # re-run after a partial failure skips what is already published. + is_published() { + local name="$1" version="$2" status + status=$(curl -s -o /dev/null -w '%{http_code}' \ + -H 'User-Agent: lemma-ci (https://github.com/LeanOxide/lemma)' \ + "https://crates.io/api/v1/crates/${name}/${version}") + [ "$status" = "200" ] + } + + for crate in "${crates[@]}"; do + pkgid="$(cargo pkgid -p "$crate")" + version="${pkgid##*#}" + version="${version##*@}" + if is_published "$crate" "$version"; then + echo "::notice::${crate} ${version} already published, skipping" + continue + fi + echo "::group::Publishing ${crate} ${version}" + cargo publish -p "$crate" + echo "::endgroup::" + # Give the sparse index a moment to propagate before publishing the + # next crate, which may depend on the one just published. + sleep 20 + done diff --git a/Cargo.lock b/Cargo.lock index 217ead5..2e170bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -902,38 +902,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] -name = "lemma" -version = "0.1.5" -dependencies = [ - "anyhow", - "clap", - "clap_complete", - "colored", - "dirs", - "fs-err", - "lemma-cli", - "lemma-config", - "lemma-download", - "lemma-install", - "lemma-output", - "lemma-static", - "lemma-toolchain", - "proptest", - "rayon", - "regex", - "serde", - "serde_json", - "tempfile", - "thiserror 1.0.69", - "toml 0.8.23", - "tracing", - "tracing-subscriber", - "url", -] - -[[package]] -name = "lemma-cli" -version = "0.1.5" +name = "lemma-args" +version = "0.2.0" dependencies = [ "clap", "clap_complete", @@ -943,7 +913,7 @@ dependencies = [ [[package]] name = "lemma-config" -version = "0.1.5" +version = "0.2.0" dependencies = [ "anyhow", "clap", @@ -961,7 +931,7 @@ dependencies = [ [[package]] name = "lemma-download" -version = "0.1.5" +version = "0.2.0" dependencies = [ "anyhow", "colored", @@ -983,7 +953,7 @@ dependencies = [ [[package]] name = "lemma-install" -version = "0.1.5" +version = "0.2.0" dependencies = [ "anyhow", "bzip2", @@ -1006,7 +976,7 @@ dependencies = [ [[package]] name = "lemma-output" -version = "0.1.5" +version = "0.2.0" dependencies = [ "colored", "indicatif", @@ -1014,19 +984,49 @@ dependencies = [ [[package]] name = "lemma-platform" -version = "0.1.5" +version = "0.2.0" dependencies = [ "target-lexicon", "thiserror 1.0.69", ] +[[package]] +name = "lemma-rs" +version = "0.2.0" +dependencies = [ + "anyhow", + "clap", + "clap_complete", + "colored", + "dirs", + "fs-err", + "lemma-args", + "lemma-config", + "lemma-download", + "lemma-install", + "lemma-output", + "lemma-static", + "lemma-toolchain", + "proptest", + "rayon", + "regex", + "serde", + "serde_json", + "tempfile", + "thiserror 1.0.69", + "toml 0.8.23", + "tracing", + "tracing-subscriber", + "url", +] + [[package]] name = "lemma-static" -version = "0.1.0" +version = "0.2.0" [[package]] name = "lemma-toolchain" -version = "0.1.5" +version = "0.2.0" dependencies = [ "anyhow", "dirs", diff --git a/Cargo.toml b/Cargo.toml index cea4aa9..e5dadd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ resolver = "2" [workspace.package] -version = "0.1.5" +version = "0.2.0" edition = "2021" rust-version = "1.75" license = "MIT OR Apache-2.0" @@ -12,14 +12,14 @@ authors = ["PuQing "] repository = "https://github.com/LeanOxide/lemma.git" [workspace.dependencies] -lemma-cli = { path = "crates/lemma-cli" } -lemma-config = { path = "crates/lemma-config" } -lemma-toolchain = { path = "crates/lemma-toolchain" } -lemma-static = { path = "crates/lemma-static" } -lemma-platform = { path = "crates/lemma-platform" } -lemma-download = { path = "crates/lemma-download" } -lemma-install = { path = "crates/lemma-install" } -lemma-output = { path = "crates/lemma-output" } +lemma-args = { path = "crates/lemma-args", version = "0.2.0" } +lemma-config = { path = "crates/lemma-config", version = "0.2.0" } +lemma-toolchain = { path = "crates/lemma-toolchain", version = "0.2.0" } +lemma-static = { path = "crates/lemma-static", version = "0.2.0" } +lemma-platform = { path = "crates/lemma-platform", version = "0.2.0" } +lemma-download = { path = "crates/lemma-download", version = "0.2.0" } +lemma-install = { path = "crates/lemma-install", version = "0.2.0" } +lemma-output = { path = "crates/lemma-output", version = "0.2.0" } serde = { version = "1.0", features = ["derive"] } toml = "0.8" diff --git a/README.md b/README.md index 6903d63..da95a15 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Lemma - A Modern Lean4 Toolchain Manager ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/LeanOxide/lemma/ci.yml?style=flat-square&logo=github) -![PyPI Version](https://img.shields.io/pypi/v/lemma?style=flat-square&logo=pypi) -![PyPI Downloads](https://img.shields.io/pypi/dm/lemma?style=flat-square&logo=pypi) +![PyPI Version](https://img.shields.io/pypi/v/lemma-lean?style=flat-square&logo=pypi) +![PyPI Downloads](https://img.shields.io/pypi/dm/lemma-lean?style=flat-square&logo=pypi) [![dependency status](https://deps.rs/repo/github/LeanOxide/lemma/status.svg?style=flat-square)](https://deps.rs/repo/github/LeanOxide/lemma) -![PyPI License](https://img.shields.io/pypi/l/lemma?style=flat-square) +![PyPI License](https://img.shields.io/pypi/l/lemma-lean?style=flat-square) [![codecov](https://codecov.io/github/LeanOxide/lemma/graph/badge.svg)](https://codecov.io/github/LeanOxide/lemma) [English](README.md) | [简体中文](README_CN.md) @@ -47,24 +47,34 @@ GitHub release assets. ## Installation -### Quick Install (Recommended) +The command-line executable is always named `lemma`, regardless of how you install it. -Install Lemma as a Python package. The package name and command are both `lemma`. +### From PyPI (Recommended) + +Install Lemma as a Python package named `lemma-lean`: ```bash -pipx install lemma +pipx install lemma-lean ``` If you do not use `pipx`, install with Python's user site instead: ```bash -python -m pip install --user lemma +python -m pip install --user lemma-lean ``` On Windows, use the Python launcher if needed: ```powershell -py -m pip install --user lemma +py -m pip install --user lemma-lean +``` + +### From crates.io + +If you have a Rust toolchain installed, you can also install the `lemma-rs` crate, which provides the same `lemma` executable: + +```bash +cargo install lemma-rs ``` After installation, run a setup command such as `lemma toolchain install stable`. Lemma will create proxy commands such as `lean`, `lake`, and `leanc` under `~/.lemma/bin`. Add that directory to your `PATH` if you want to call those proxies directly. @@ -73,7 +83,7 @@ After installation, run a setup command such as `lemma toolchain install stable` ```bash # Build from source -cargo build --release -p lemma +cargo build --release -p lemma-rs # Install the CLI from this checkout cargo install --path crates/lemma-rs @@ -84,9 +94,11 @@ cargo install --path crates/lemma-rs Use the same package manager that installed Lemma: ```bash -pipx upgrade lemma +pipx upgrade lemma-lean # or -python -m pip install --user --upgrade lemma +python -m pip install --user --upgrade lemma-lean +# or, for a crates.io install +cargo install lemma-rs ``` `lemma self update` prints these safe package-manager commands instead of replacing the running binary directly. diff --git a/README_CN.md b/README_CN.md index ccc6668..f970ffd 100644 --- a/README_CN.md +++ b/README_CN.md @@ -35,24 +35,34 @@ release_asset_url_prefix = "https://mirror.example.com" ## 安装 -### 快速安装(推荐) +无论通过哪种方式安装,可执行文件名始终为 `lemma`。 -Lemma 现在通过 Python 包发布,包名和命令名都是 `lemma`。 +### 从 PyPI 安装(推荐) + +Lemma 以名为 `lemma-lean` 的 Python 包发布: ```bash -pipx install lemma +pipx install lemma-lean ``` 如果不使用 `pipx`,可以使用 Python user site 安装: ```bash -python -m pip install --user lemma +python -m pip install --user lemma-lean ``` Windows 可以使用 Python launcher: ```powershell -py -m pip install --user lemma +py -m pip install --user lemma-lean +``` + +### 从 crates.io 安装 + +如果已经安装了 Rust 工具链,也可以安装 `lemma-rs` crate,它提供相同的 `lemma` 可执行文件: + +```bash +cargo install lemma-rs ``` 安装后,运行 `lemma toolchain install stable` 等初始化命令。Lemma 会在 `~/.lemma/bin` 下创建 `lean`、`lake`、`leanc` 等代理命令;如果希望直接运行这些代理命令,请把该目录加入 `PATH`。 @@ -61,7 +71,7 @@ py -m pip install --user lemma ```bash # 构建发布版本 -cargo build --release -p lemma +cargo build --release -p lemma-rs # 从当前源码安装 CLI cargo install --path crates/lemma-rs @@ -72,9 +82,11 @@ cargo install --path crates/lemma-rs 使用安装 Lemma 时的同一个包管理器更新: ```bash -pipx upgrade lemma +pipx upgrade lemma-lean # 或 -python -m pip install --user --upgrade lemma +python -m pip install --user --upgrade lemma-lean +# 或(crates.io 安装方式) +cargo install lemma-rs ``` `lemma self update` 会显示这些安全的包管理器更新命令,不会直接覆盖当前正在运行的二进制文件。 diff --git a/crates/lemma-cli/Cargo.toml b/crates/lemma-args/Cargo.toml similarity index 94% rename from crates/lemma-cli/Cargo.toml rename to crates/lemma-args/Cargo.toml index ea9b194..287c3cd 100644 --- a/crates/lemma-cli/Cargo.toml +++ b/crates/lemma-args/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "lemma-cli" +name = "lemma-args" version.workspace = true edition.workspace = true rust-version.workspace = true diff --git a/crates/lemma-cli/src/cli.rs b/crates/lemma-args/src/cli.rs similarity index 100% rename from crates/lemma-cli/src/cli.rs rename to crates/lemma-args/src/cli.rs diff --git a/crates/lemma-cli/src/help.rs b/crates/lemma-args/src/help.rs similarity index 95% rename from crates/lemma-cli/src/help.rs rename to crates/lemma-args/src/help.rs index 9fdc508..e170951 100644 --- a/crates/lemma-cli/src/help.rs +++ b/crates/lemma-args/src/help.rs @@ -293,21 +293,26 @@ pub static SELF_HELP: &str = r"DISCUSSION: pub static SELF_UPDATE_HELP: &str = r"DISCUSSION: Shows safe package-manager commands for upgrading lemma. - Lemma is distributed as the `lemma` Python package. This command does not - download archives or replace the running executable directly, because pipx, - pip, and other package managers own those installed files. + Lemma is distributed as the `lemma-lean` Python package (and also as the + `lemma-rs` crate on crates.io). This command does not download archives or + replace the running executable directly, because pipx, pip, cargo, and other + package managers own those installed files. Recommended: - $ pipx upgrade lemma + $ pipx upgrade lemma-lean Fallback: - $ python -m pip install --user --upgrade lemma + $ python -m pip install --user --upgrade lemma-lean Windows fallback: - PS C:\> py -m pip install --user --upgrade lemma"; + PS C:\> py -m pip install --user --upgrade lemma-lean + + crates.io install: + + $ cargo install lemma-rs --force"; pub static SELF_UNINSTALL_HELP: &str = r"DISCUSSION: Removes lemma-managed data. This will remove: @@ -316,8 +321,8 @@ pub static SELF_UNINSTALL_HELP: &str = r"DISCUSSION: - The entire ~/.lemma directory It does not uninstall the Python package or remove package-manager owned - executables. Use `pipx uninstall lemma` or `python -m pip uninstall lemma` - for that. + executables. Use `pipx uninstall lemma-lean` or + `python -m pip uninstall lemma-lean` for that. Example: diff --git a/crates/lemma-cli/src/lib.rs b/crates/lemma-args/src/lib.rs similarity index 100% rename from crates/lemma-cli/src/lib.rs rename to crates/lemma-args/src/lib.rs diff --git a/crates/lemma-config/src/lib.rs b/crates/lemma-config/src/lib.rs index 1e80d0a..70f6fb0 100644 --- a/crates/lemma-config/src/lib.rs +++ b/crates/lemma-config/src/lib.rs @@ -20,7 +20,7 @@ //! //! - Contains `Option` for all values (may be unspecified) //! - Maps 1:1 with CLI flags from `lemma-cli` -//! - Created by converting from `lemma_cli::GlobalArgs` +//! - Created by converting from `lemma_args::GlobalArgs` //! - Used only as input to settings resolution //! //! ### 2. [`Config`] diff --git a/crates/lemma-rs/Cargo.toml b/crates/lemma-rs/Cargo.toml index eff97d9..dcdf542 100644 --- a/crates/lemma-rs/Cargo.toml +++ b/crates/lemma-rs/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "lemma" +name = "lemma-rs" version.workspace = true edition.workspace = true license.workspace = true @@ -13,11 +13,11 @@ path = "src/main.rs" [[test]] name = "integration_tests" -path = "../../tests/integration_tests.rs" +path = "tests/integration_tests.rs" [dependencies] # Internal crates -lemma-cli.workspace = true +lemma-args.workspace = true lemma-static.workspace = true lemma-config.workspace = true lemma-toolchain.workspace = true diff --git a/crates/lemma-rs/src/commands.rs b/crates/lemma-rs/src/commands.rs index 0bd6a8f..28c8189 100644 --- a/crates/lemma-rs/src/commands.rs +++ b/crates/lemma-rs/src/commands.rs @@ -20,7 +20,7 @@ pub mod upgrade; pub mod which; use anyhow::Result; -use lemma_cli::{Commands, SelfCommands, ToolchainCommands}; +use lemma_args::{Commands, SelfCommands, ToolchainCommands}; use lemma_config::{Config, GlobalSettings}; use lemma_output::Printer; diff --git a/crates/lemma-rs/src/commands/cache.rs b/crates/lemma-rs/src/commands/cache.rs index b5838ef..31141cb 100644 --- a/crates/lemma-rs/src/commands/cache.rs +++ b/crates/lemma-rs/src/commands/cache.rs @@ -5,7 +5,7 @@ use std::fs; use std::io::{self, Write}; use std::path::Path; -use lemma_cli::cli::CacheCommands; +use lemma_args::cli::CacheCommands; use lemma_config::{Config, GlobalSettings}; use lemma_output::Printer; diff --git a/crates/lemma-rs/src/commands/completions.rs b/crates/lemma-rs/src/commands/completions.rs index 414cd19..bdc7dae 100644 --- a/crates/lemma-rs/src/commands/completions.rs +++ b/crates/lemma-rs/src/commands/completions.rs @@ -4,7 +4,7 @@ use anyhow::Result; use clap::CommandFactory; use clap_complete::{generate, Shell}; -use lemma_cli::Cli; +use lemma_args::Cli; use lemma_config::GlobalSettings; use lemma_output::Printer; diff --git a/crates/lemma-rs/src/commands/override.rs b/crates/lemma-rs/src/commands/override.rs index 36d8b52..62f8813 100644 --- a/crates/lemma-rs/src/commands/override.rs +++ b/crates/lemma-rs/src/commands/override.rs @@ -4,7 +4,7 @@ use anyhow::{Context, Result}; use std::env; use std::path::PathBuf; -use lemma_cli::OverrideCommands; +use lemma_args::OverrideCommands; use lemma_config::Config; use lemma_config::GlobalSettings; use lemma_output::Printer; diff --git a/crates/lemma-rs/src/commands/self_update.rs b/crates/lemma-rs/src/commands/self_update.rs index 239db8b..44be73b 100644 --- a/crates/lemma-rs/src/commands/self_update.rs +++ b/crates/lemma-rs/src/commands/self_update.rs @@ -6,7 +6,7 @@ use lemma_output::Printer; use std::env; use std::fs; -const PACKAGE_NAME: &str = "lemma"; +const PACKAGE_NAME: &str = "lemma-lean"; pub fn update(settings: &GlobalSettings, printer: &Printer) -> Result<()> { printer.header("Update lemma")?; @@ -21,10 +21,10 @@ pub fn update(settings: &GlobalSettings, printer: &Printer) -> Result<()> { } } - printer.list_item("Recommended: pipx upgrade lemma")?; - printer.list_item("Fallback: python -m pip install --user --upgrade lemma")?; - printer.list_item("Windows fallback: py -m pip install --user --upgrade lemma")?; - printer.list_item("Source install: cargo install lemma --force")?; + printer.list_item("Recommended: pipx upgrade lemma-lean")?; + printer.list_item("Fallback: python -m pip install --user --upgrade lemma-lean")?; + printer.list_item("Windows fallback: py -m pip install --user --upgrade lemma-lean")?; + printer.list_item("crates.io install: cargo install lemma-rs --force")?; printer.success("Run the command that matches how you installed lemma.")?; printer.warning( @@ -90,8 +90,8 @@ pub fn uninstall(skip_confirm: bool, settings: &GlobalSettings, printer: &Printe } printer.success("Removed lemma-managed data")?; - printer.list_item("To remove the Python package: pipx uninstall lemma")?; - printer.list_item("Or, if installed with pip: python -m pip uninstall lemma")?; + printer.list_item("To remove the Python package: pipx uninstall lemma-lean")?; + printer.list_item("Or, if installed with pip: python -m pip uninstall lemma-lean")?; Ok(()) } diff --git a/crates/lemma-rs/src/main.rs b/crates/lemma-rs/src/main.rs index 91c98ed..9722a9e 100644 --- a/crates/lemma-rs/src/main.rs +++ b/crates/lemma-rs/src/main.rs @@ -31,7 +31,7 @@ mod commands; use anyhow::Result; use clap::Parser; use colored::Colorize; -use lemma_cli::Cli; +use lemma_args::Cli; use lemma_config::GlobalSettings; use std::path::PathBuf; diff --git a/tests/integration_tests.rs b/crates/lemma-rs/tests/integration_tests.rs similarity index 100% rename from tests/integration_tests.rs rename to crates/lemma-rs/tests/integration_tests.rs diff --git a/tests/suite/cli_config.rs b/crates/lemma-rs/tests/suite/cli_config.rs similarity index 100% rename from tests/suite/cli_config.rs rename to crates/lemma-rs/tests/suite/cli_config.rs diff --git a/tests/suite/cli_edge_cases.rs b/crates/lemma-rs/tests/suite/cli_edge_cases.rs similarity index 100% rename from tests/suite/cli_edge_cases.rs rename to crates/lemma-rs/tests/suite/cli_edge_cases.rs diff --git a/tests/suite/cli_init.rs b/crates/lemma-rs/tests/suite/cli_init.rs similarity index 100% rename from tests/suite/cli_init.rs rename to crates/lemma-rs/tests/suite/cli_init.rs diff --git a/tests/suite/cli_link.rs b/crates/lemma-rs/tests/suite/cli_link.rs similarity index 100% rename from tests/suite/cli_link.rs rename to crates/lemma-rs/tests/suite/cli_link.rs diff --git a/tests/suite/cli_override.rs b/crates/lemma-rs/tests/suite/cli_override.rs similarity index 100% rename from tests/suite/cli_override.rs rename to crates/lemma-rs/tests/suite/cli_override.rs diff --git a/tests/suite/cli_project.rs b/crates/lemma-rs/tests/suite/cli_project.rs similarity index 100% rename from tests/suite/cli_project.rs rename to crates/lemma-rs/tests/suite/cli_project.rs diff --git a/tests/suite/cli_proxy.rs b/crates/lemma-rs/tests/suite/cli_proxy.rs similarity index 100% rename from tests/suite/cli_proxy.rs rename to crates/lemma-rs/tests/suite/cli_proxy.rs diff --git a/tests/suite/cli_toolchain.rs b/crates/lemma-rs/tests/suite/cli_toolchain.rs similarity index 98% rename from tests/suite/cli_toolchain.rs rename to crates/lemma-rs/tests/suite/cli_toolchain.rs index 8655e97..85853fd 100644 --- a/tests/suite/cli_toolchain.rs +++ b/crates/lemma-rs/tests/suite/cli_toolchain.rs @@ -188,8 +188,8 @@ fn test_self_update_shows_package_manager_guidance() { let result = ctx.run(&["self", "update"]); result.assert_success(); - result.assert_stdout_contains("pipx upgrade lemma"); - result.assert_stdout_contains("python -m pip install --user --upgrade lemma"); + result.assert_stdout_contains("pipx upgrade lemma-lean"); + result.assert_stdout_contains("python -m pip install --user --upgrade lemma-lean"); result.assert_stdout_not_contains(&format!("{}{}", "lemma.", "puqing.work")); result.assert_stdout_not_contains(&format!("{}{}", "manifests/", "stable.toml")); } diff --git a/tests/suite/cli_uninstall.rs b/crates/lemma-rs/tests/suite/cli_uninstall.rs similarity index 100% rename from tests/suite/cli_uninstall.rs rename to crates/lemma-rs/tests/suite/cli_uninstall.rs diff --git a/tests/suite/mod.rs b/crates/lemma-rs/tests/suite/mod.rs similarity index 100% rename from tests/suite/mod.rs rename to crates/lemma-rs/tests/suite/mod.rs diff --git a/tests/suite/test_helpers.rs b/crates/lemma-rs/tests/suite/test_helpers.rs similarity index 100% rename from tests/suite/test_helpers.rs rename to crates/lemma-rs/tests/suite/test_helpers.rs diff --git a/crates/lemma-static/Cargo.toml b/crates/lemma-static/Cargo.toml index dfdc80f..637da16 100644 --- a/crates/lemma-static/Cargo.toml +++ b/crates/lemma-static/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lemma-static" -version = "0.1.0" +version.workspace = true edition = { workspace = true } repository = { workspace = true } authors = { workspace = true } diff --git a/pyproject.toml b/pyproject.toml index 54e9323..34ee657 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,8 +3,8 @@ requires = ["maturin>=1.7,<2"] build-backend = "maturin" [project] -name = "lemma" -version = "0.1.5" +name = "lemma-lean" +version = "0.2.0" description = "A modern Lean4 toolchain manager" readme = "README.md" requires-python = ">=3.8" From 17eb4f2c8c39ac726d1453533b30153e4e053348 Mon Sep 17 00:00:00 2001 From: PuQing Date: Mon, 3 Aug 2026 01:21:20 +0800 Subject: [PATCH 2/2] test: fix integration tests on nightly via CARGO_BIN_EXE_lemma The integration suite located the `lemma` binary by walking up from `env::current_exe()` and guessing `target/debug/lemma`. That broke on the nightly toolchain used by CI: nightly places the integration test binary under `target/debug/build/lemma-rs//out/` instead of `target/debug/deps/`, so `current_exe().parent().parent()` no longer lands in `target/debug` and every integration test failed with `Os { code: 2, kind: NotFound }` (Test Suite + Code Coverage jobs). Use `env!("CARGO_BIN_EXE_lemma")` instead. Cargo sets it to the absolute path of the binary it builds for the integration test and guarantees that binary is built before the test runs, so it is correct regardless of toolchain, profile, or `--target-dir` (the coverage job uses a custom one). Verified on nightly from a clean build: cargo +nightly test --locked --all-features --workspace -> 129 passed, 0 failed cargo +nightly fmt --check / clippy -D warnings -> clean --- crates/lemma-rs/tests/suite/test_helpers.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/lemma-rs/tests/suite/test_helpers.rs b/crates/lemma-rs/tests/suite/test_helpers.rs index 454e94b..5b2d021 100644 --- a/crates/lemma-rs/tests/suite/test_helpers.rs +++ b/crates/lemma-rs/tests/suite/test_helpers.rs @@ -23,14 +23,14 @@ impl LemmaTestContext { let bin_dir = lemma_home.join("bin"); let toolchains_dir = lemma_home.join("toolchains"); - // Get the path to the lemma executable - let lemma_exe = env::current_exe() - .expect("Failed to get current exe") - .parent() - .expect("Failed to get parent dir") - .parent() - .expect("Failed to get grandparent dir") - .join("lemma"); + // Cargo sets CARGO_BIN_EXE_ to the absolute path of the `lemma` + // binary it builds for this integration test, and guarantees that binary + // is built before the test runs. This is robust across toolchains and + // platforms. The previous approach of walking up from `current_exe()` + // broke on nightly, which places the test binary under + // `target/debug/build/.../out/` instead of `target/debug/deps/`, so the + // guessed `target/debug/lemma` path did not exist. + let lemma_exe = PathBuf::from(env!("CARGO_BIN_EXE_lemma")); Self { temp_dir,