-
-
Notifications
You must be signed in to change notification settings - Fork 942
improve cargo/install_package #7614
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,6 +47,90 @@ function _translate_local_path_in_deps(cargotoml, rootdir) | |
| io.writefile(cargotoml, content) | ||
| end | ||
|
|
||
| -- is it a cargo workspace manifest? (it contains a [workspace] or [workspace.xxx] table) | ||
| function _is_workspace_manifest(content) | ||
| for _, line in ipairs(content:split("\n", {plain = true, strict = true})) do | ||
| if line:match("^%s*%[workspace[%].]") then | ||
| return true | ||
| end | ||
| end | ||
| return false | ||
| end | ||
|
|
||
| -- get the workspace inheritance tables from the workspace root manifest | ||
| -- | ||
| -- if the given Cargo.toml is a member of a cargo workspace and uses workspace inheritance, | ||
| -- e.g. `anyhow.workspace = true`, `version.workspace = true`, `[lints] workspace = true`, | ||
| -- we need to inject the `[workspace.package]`/`[workspace.dependencies]`/`[workspace.lints]` | ||
| -- tables from the workspace root manifest, otherwise cargo will fail to resolve them, e.g. | ||
| -- | ||
| -- error inheriting `anyhow` from workspace root manifest's `workspace.dependencies.anyhow` | ||
| -- `workspace.dependencies` was not defined | ||
| -- | ||
| -- @see https://github.com/xmake-io/xmake/issues/7619 | ||
| -- https://doc.rust-lang.org/cargo/reference/workspaces.html#the-workspacedependencies-table | ||
| function _get_workspace_inherited_tables(cargo_toml) | ||
|
|
||
| -- find the workspace root manifest by walking up | ||
| local rootmanifest | ||
| local dir = path.directory(path.absolute(cargo_toml)) | ||
| while dir and #dir > 0 do | ||
| local manifest = path.join(dir, "Cargo.toml") | ||
| if os.isfile(manifest) then | ||
| local content = io.readfile(manifest) | ||
| if content and _is_workspace_manifest(content) then | ||
| rootmanifest = manifest | ||
| break | ||
| end | ||
| end | ||
| local parentdir = path.directory(dir) | ||
| if parentdir == dir then | ||
| break | ||
| end | ||
| dir = parentdir | ||
| end | ||
|
|
||
| -- not a workspace member, or the manifest itself is the workspace root (self-contained) | ||
| if not rootmanifest or path.absolute(rootmanifest) == path.absolute(cargo_toml) then | ||
| return | ||
| end | ||
|
|
||
| -- extract all the [workspace.xxx] sub-tables, e.g. [workspace.package]/[workspace.dependencies]/[workspace.lints] | ||
| -- we do not copy the bare [workspace] table (members/exclude), otherwise cargo will search for the member crates. | ||
| local content = io.readfile(rootmanifest) | ||
| if not content then | ||
| return | ||
| end | ||
| local result = {} | ||
| local in_subtable = false | ||
| for _, line in ipairs(content:split("\n", {plain = true, strict = true})) do | ||
| local header = line:match("^%s*%[(.-)%]%s*$") | ||
| if header then | ||
| in_subtable = header:trim():startswith("workspace.") | ||
| if in_subtable then | ||
| table.insert(result, line) | ||
| end | ||
| elseif in_subtable then | ||
| table.insert(result, line) | ||
| end | ||
| end | ||
| if #result == 0 then | ||
| return | ||
| end | ||
|
|
||
| -- translate the local paths in the workspace dependencies, they are relative to the workspace root directory | ||
| local rootdir = path.directory(rootmanifest) | ||
| local workspace_toml = table.concat(result, "\n") | ||
| workspace_toml = workspace_toml:gsub("path%s+=%s+\"(.-)\"", function (localpath) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using |
||
| if not path.is_absolute(localpath) then | ||
| localpath = path.absolute(localpath, rootdir) | ||
| end | ||
| localpath = localpath:gsub("\\", "/") | ||
| return "path = \"" .. localpath .. "\"" | ||
| end) | ||
| return workspace_toml | ||
| end | ||
|
|
||
| -- install package | ||
| -- | ||
| -- e.g. | ||
|
|
@@ -101,6 +185,13 @@ function main(name, opt) | |
| tomlfile:print("") | ||
| tomlfile:print("[workspace]") | ||
| tomlfile:print("") | ||
| -- inject the workspace inheritance tables if the given Cargo.toml is a workspace member, | ||
| -- e.g. `anyhow.workspace = true`. @see https://github.com/xmake-io/xmake/issues/7619 | ||
| local workspace_toml = _get_workspace_inherited_tables(configs.cargo_toml) | ||
| if workspace_toml then | ||
| tomlfile:write(workspace_toml) | ||
| tomlfile:print("") | ||
| end | ||
|
Comment on lines
+191
to
+194
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| tomlfile:close() | ||
| else | ||
| local tomlfile = io.open(cargotoml, "w") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Splitting the entire file content into lines just to check if it contains a workspace pattern is inefficient and can consume unnecessary memory for larger files. We can use Lua's pattern matching directly on the file content to check for the pattern at the start of the string or after a newline.