Merge branch 'dev' into next

This commit is contained in:
Lucas Nogueira
2022-08-21 17:48:56 -03:00
12 changed files with 270 additions and 178 deletions

View File

@@ -0,0 +1,6 @@
---
"cli.rs": patch
"cli.js": patch
---
Check if the default build target is set in the Cargo configuration.

View File

@@ -0,0 +1,6 @@
---
"cli.rs": "patch"
"cli.js": "patch"
---
Use `cargo metadata` to detect the workspace root and target directory.

View File

@@ -2628,12 +2628,12 @@ fn handle_event_loop<T: UserEvent>(
for handler in handlers {
handler(&event);
}
}
let global_listeners = system_tray_manager.global_listeners.lock().unwrap();
let global_listeners_iter = global_listeners.iter();
for global_listener in global_listeners_iter {
global_listener(tray_id, &event);
}
let global_listeners = system_tray_manager.global_listeners.lock().unwrap();
let global_listeners_iter = global_listeners.iter();
for global_listener in global_listeners_iter {
global_listener(tray_id, &event);
}
}
#[cfg(all(desktop, feature = "system-tray"))]
@@ -2662,6 +2662,12 @@ fn handle_event_loop<T: UserEvent>(
handler(&event);
}
}
let global_listeners = system_tray_manager.global_listeners.lock().unwrap();
let global_listeners_iter = global_listeners.iter();
for global_listener in global_listeners_iter {
global_listener(id.0, &event);
}
}
Event::WindowEvent {
event, window_id, ..

View File

@@ -20,7 +20,7 @@ fn has_feature(feature: &str) -> bool {
.unwrap()
.push(feature.to_string());
// when a feature is enabled, Cargo sets the `CARGO_FEATURE_<name` env var to 1
// when a feature is enabled, Cargo sets the `CARGO_FEATURE_<name>` env var to 1
// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
std::env::var(format!("CARGO_FEATURE_{}", AsShoutySnakeCase(feature)))
.map(|x| x == "1")

View File

@@ -960,9 +960,9 @@ unconfig@^0.3.4:
jiti "^1.13.0"
undici@^5.2.0:
version "5.8.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.8.0.tgz#dec9a8ccd90e5a1d81d43c0eab6503146d649a4f"
integrity sha512-1F7Vtcez5w/LwH2G2tGnFIihuWUlc58YidwLiCv+jR2Z50x0tNXpRRw7eOIJ+GvqCqIkg9SB7NWAJ/T9TLfv8Q==
version "5.9.1"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.9.1.tgz#fc9fd85dd488f965f153314a63d9426a11f3360b"
integrity sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==
unocss@^0.39.3:
version "0.39.3"

View File

@@ -49,9 +49,9 @@
"@rollup/plugin-node-resolve": "13.3.0",
"@rollup/plugin-sucrase": "4.0.4",
"@rollup/plugin-typescript": "8.3.4",
"@typescript-eslint/eslint-plugin": "5.33.0",
"@typescript-eslint/parser": "5.33.0",
"eslint": "8.21.0",
"@typescript-eslint/eslint-plugin": "5.33.1",
"@typescript-eslint/parser": "5.33.1",
"eslint": "8.22.0",
"eslint-config-prettier": "8.5.0",
"eslint-config-standard-with-typescript": "21.0.1",
"eslint-plugin-import": "2.26.0",
@@ -61,7 +61,7 @@
"prettier": "2.7.1",
"regenerator-runtime": "0.13.9",
"rimraf": "3.0.2",
"rollup": "2.77.2",
"rollup": "2.78.0",
"rollup-plugin-terser": "7.0.2",
"tslib": "2.4.0",
"typedoc": "0.23.10",

View File

@@ -1359,14 +1359,14 @@
dependencies:
"@types/node" "*"
"@typescript-eslint/eslint-plugin@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.0.tgz#059798888720ec52ffa96c5f868e31a8f70fa3ec"
integrity sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==
"@typescript-eslint/eslint-plugin@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz#c0a480d05211660221eda963cc844732fe9b1714"
integrity sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==
dependencies:
"@typescript-eslint/scope-manager" "5.33.0"
"@typescript-eslint/type-utils" "5.33.0"
"@typescript-eslint/utils" "5.33.0"
"@typescript-eslint/scope-manager" "5.33.1"
"@typescript-eslint/type-utils" "5.33.1"
"@typescript-eslint/utils" "5.33.1"
debug "^4.3.4"
functional-red-black-tree "^1.0.1"
ignore "^5.2.0"
@@ -1374,14 +1374,14 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/parser@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.33.0.tgz#26ec3235b74f0667414613727cb98f9b69dc5383"
integrity sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==
"@typescript-eslint/parser@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.33.1.tgz#e4b253105b4d2a4362cfaa4e184e2d226c440ff3"
integrity sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==
dependencies:
"@typescript-eslint/scope-manager" "5.33.0"
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/typescript-estree" "5.33.0"
"@typescript-eslint/scope-manager" "5.33.1"
"@typescript-eslint/types" "5.33.1"
"@typescript-eslint/typescript-estree" "5.33.1"
debug "^4.3.4"
"@typescript-eslint/parser@^4.0.0":
@@ -1402,20 +1402,20 @@
"@typescript-eslint/types" "4.25.0"
"@typescript-eslint/visitor-keys" "4.25.0"
"@typescript-eslint/scope-manager@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.33.0.tgz#509d7fa540a2c58f66bdcfcf278a3fa79002e18d"
integrity sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw==
"@typescript-eslint/scope-manager@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz#8d31553e1b874210018ca069b3d192c6d23bc493"
integrity sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==
dependencies:
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/visitor-keys" "5.33.0"
"@typescript-eslint/types" "5.33.1"
"@typescript-eslint/visitor-keys" "5.33.1"
"@typescript-eslint/type-utils@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.33.0.tgz#92ad1fba973c078d23767ce2d8d5a601baaa9338"
integrity sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==
"@typescript-eslint/type-utils@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz#1a14e94650a0ae39f6e3b77478baff002cec4367"
integrity sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==
dependencies:
"@typescript-eslint/utils" "5.33.0"
"@typescript-eslint/utils" "5.33.1"
debug "^4.3.4"
tsutils "^3.21.0"
@@ -1424,10 +1424,10 @@
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.25.0.tgz#0e444a5c5e3c22d7ffa5e16e0e60510b3de5af87"
integrity sha512-+CNINNvl00OkW6wEsi32wU5MhHti2J25TJsJJqgQmJu3B3dYDBcmOxcE5w9cgoM13TrdE/5ND2HoEnBohasxRQ==
"@typescript-eslint/types@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.33.0.tgz#d41c584831805554b063791338b0220b613a275b"
integrity sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw==
"@typescript-eslint/types@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.33.1.tgz#3faef41793d527a519e19ab2747c12d6f3741ff7"
integrity sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==
"@typescript-eslint/typescript-estree@4.25.0":
version "4.25.0"
@@ -1442,28 +1442,28 @@
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/typescript-estree@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.0.tgz#02d9c9ade6f4897c09e3508c27de53ad6bfa54cf"
integrity sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ==
"@typescript-eslint/typescript-estree@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz#a573bd360790afdcba80844e962d8b2031984f34"
integrity sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==
dependencies:
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/visitor-keys" "5.33.0"
"@typescript-eslint/types" "5.33.1"
"@typescript-eslint/visitor-keys" "5.33.1"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.33.0.tgz#46797461ce3146e21c095d79518cc0f8ec574038"
integrity sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==
"@typescript-eslint/utils@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.33.1.tgz#171725f924fe1fe82bb776522bb85bc034e88575"
integrity sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==
dependencies:
"@types/json-schema" "^7.0.9"
"@typescript-eslint/scope-manager" "5.33.0"
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/typescript-estree" "5.33.0"
"@typescript-eslint/scope-manager" "5.33.1"
"@typescript-eslint/types" "5.33.1"
"@typescript-eslint/typescript-estree" "5.33.1"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
@@ -1475,12 +1475,12 @@
"@typescript-eslint/types" "4.25.0"
eslint-visitor-keys "^2.0.0"
"@typescript-eslint/visitor-keys@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.0.tgz#fbcbb074e460c11046e067bc3384b5d66b555484"
integrity sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw==
"@typescript-eslint/visitor-keys@5.33.1":
version "5.33.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz#0155c7571c8cd08956580b880aea327d5c34a18b"
integrity sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==
dependencies:
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/types" "5.33.1"
eslint-visitor-keys "^3.3.0"
acorn-jsx@^5.3.2:
@@ -2030,10 +2030,10 @@ eslint-visitor-keys@^3.3.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
eslint@8.21.0:
version "8.21.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.21.0.tgz#1940a68d7e0573cef6f50037addee295ff9be9ef"
integrity sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==
eslint@8.22.0:
version "8.22.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48"
integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==
dependencies:
"@eslint/eslintrc" "^1.3.0"
"@humanwhocodes/config-array" "^0.10.4"
@@ -3105,10 +3105,10 @@ rollup-plugin-terser@7.0.2:
serialize-javascript "^4.0.0"
terser "^5.0.0"
rollup@2.77.2:
version "2.77.2"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.2.tgz#6b6075c55f9cc2040a5912e6e062151e42e2c4e3"
integrity sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==
rollup@2.78.0:
version "2.78.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.78.0.tgz#00995deae70c0f712ea79ad904d5f6b033209d9e"
integrity sha512-4+YfbQC9QEVvKTanHhIAFVUFSRsezvQF8vFOJwtGfb9Bb+r014S+qryr9PSmw8x6sMnPkmFBGAvIFVQxvJxjtg==
optionalDependencies:
fsevents "~2.3.2"

View File

@@ -37,7 +37,7 @@
}
},
"devDependencies": {
"@napi-rs/cli": "2.11.1",
"@napi-rs/cli": "2.11.4",
"cross-env": "7.0.3",
"cross-spawn": "7.0.3",
"fs-extra": "10.1.0",

View File

@@ -669,10 +669,10 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@napi-rs/cli@2.11.1":
version "2.11.1"
resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-2.11.1.tgz#1fe30c3b12baa240dbaf8fcdeed53588d8340a15"
integrity sha512-JRfUgQTrogU/YrOoOgrZdnSopZemmT9ohet8SMxZXQZFtSIjOTSBQOC+vMrqKIfZmSKTtxE8cNIIlscHSP7PCA==
"@napi-rs/cli@2.11.4":
version "2.11.4"
resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-2.11.4.tgz#28bea72dd6758ce7fc94d515493c5bd1ef00b6ec"
integrity sha512-rjU651owB4GJetO3pnu3B8TyVM3Fis3AYb+U16bKxYyykp81S+dJlIgWc8Lc0t55PYbHlBM3hxdgy4pultxMAw==
"@sinclair/typebox@^0.24.1":
version "0.24.19"

View File

@@ -794,13 +794,10 @@ pub fn command(_options: Options) -> Result<()> {
} else {
None
};
let lock: Option<CargoLock> = if let Ok(lock_contents) =
read_to_string(get_workspace_dir(&tauri_dir).join("Cargo.lock"))
{
toml::from_str(&lock_contents).ok()
} else {
None
};
let lock: Option<CargoLock> = get_workspace_dir()
.ok()
.and_then(|p| read_to_string(p.join("Cargo.lock")).ok())
.and_then(|s| toml::from_str(&s).ok());
for (dep, label) in [
("tauri", format!("{} {}", "tauri", "[RUST]".dimmed())),

View File

@@ -8,7 +8,7 @@ use std::{
fs::{File, FileType},
io::{Read, Write},
path::{Path, PathBuf},
process::ExitStatus,
process::{Command, ExitStatus},
str::FromStr,
sync::{
mpsc::{channel, sync_channel},
@@ -20,7 +20,6 @@ use std::{
use anyhow::Context;
#[cfg(target_os = "linux")]
use heck::ToKebabCase;
use log::warn;
use log::{debug, info};
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
use serde::Deserialize;
@@ -35,8 +34,10 @@ use crate::helpers::{
config::{reload as reload_config, wix_settings, Config},
};
mod cargo_config;
mod desktop;
mod manifest;
use cargo_config::Config as CargoConfig;
use manifest::{rewrite_manifest, Manifest};
#[derive(Debug, Default, Clone)]
@@ -305,7 +306,7 @@ impl Rust {
let process = Arc::new(Mutex::new(child));
let (tx, rx) = channel();
let tauri_path = tauri_dir();
let workspace_path = get_workspace_dir(&tauri_path);
let workspace_path = get_workspace_dir()?;
let watch_folders = if tauri_path == workspace_path {
vec![tauri_path]
@@ -439,22 +440,12 @@ impl CargoSettings {
}
}
#[derive(Deserialize)]
struct CargoBuildConfig {
#[serde(rename = "target-dir")]
target_dir: Option<String>,
}
#[derive(Deserialize)]
struct CargoConfig {
build: Option<CargoBuildConfig>,
}
pub struct RustAppSettings {
manifest: Manifest,
cargo_settings: CargoSettings,
cargo_package_settings: CargoPackageSettings,
package_settings: PackageSettings,
cargo_config: CargoConfig,
}
impl AppSettings for RustAppSettings {
@@ -642,11 +633,14 @@ impl RustAppSettings {
default_run: cargo_package_settings.default_run.clone(),
};
let cargo_config = CargoConfig::load(&tauri_dir())?;
Ok(Self {
manifest,
cargo_settings,
cargo_package_settings,
package_settings,
cargo_config,
})
}
@@ -655,100 +649,60 @@ impl RustAppSettings {
}
pub fn out_dir(&self, target: Option<String>, debug: bool) -> crate::Result<PathBuf> {
let tauri_dir = tauri_dir();
let workspace_dir = get_workspace_dir(&tauri_dir);
get_target_dir(&workspace_dir, target, !debug)
get_target_dir(
target
.as_deref()
.or_else(|| self.cargo_config.build().target()),
!debug,
)
}
}
/// This function determines where 'target' dir is and suffixes it with 'release' or 'debug'
/// to determine where the compiled binary will be located.
fn get_target_dir(
project_root_dir: &Path,
target: Option<String>,
is_release: bool,
) -> crate::Result<PathBuf> {
let mut path: PathBuf = match std::env::var_os("CARGO_TARGET_DIR") {
Some(target_dir) => target_dir.into(),
None => {
let mut root_dir = project_root_dir.to_path_buf();
let target_path: Option<PathBuf> = loop {
// cargo reads configs under .cargo/config.toml or .cargo/config
let mut cargo_config_path = root_dir.join(".cargo/config");
if !cargo_config_path.exists() {
cargo_config_path = root_dir.join(".cargo/config.toml");
}
// if the path exists, parse it
if cargo_config_path.exists() {
let mut config_str = String::new();
let mut config_file = File::open(&cargo_config_path)
.with_context(|| format!("failed to open {:?}", cargo_config_path))?;
config_file
.read_to_string(&mut config_str)
.with_context(|| "failed to read cargo config file")?;
let config: CargoConfig =
toml::from_str(&config_str).with_context(|| "failed to parse cargo config file")?;
if let Some(build) = config.build {
if let Some(target_dir) = build.target_dir {
break Some(target_dir.into());
}
}
}
if !root_dir.pop() {
break None;
}
};
target_path.unwrap_or_else(|| project_root_dir.join("target"))
}
};
#[derive(Deserialize)]
struct CargoMetadata {
target_directory: PathBuf,
workspace_root: PathBuf,
}
if let Some(ref triple) = target {
fn get_cargo_metadata() -> crate::Result<CargoMetadata> {
let output = Command::new("cargo")
.args(["metadata", "--no-deps", "--format-version", "1"])
.current_dir(tauri_dir())
.output()?;
if !output.status.success() {
return Err(anyhow::anyhow!(
"cargo metadata command exited with a non zero exit code: {}",
String::from_utf8(output.stderr)?
));
}
Ok(serde_json::from_slice(&output.stdout)?)
}
/// This function determines the 'target' directory and suffixes it with 'release' or 'debug'
/// to determine where the compiled binary will be located.
fn get_target_dir(target: Option<&str>, is_release: bool) -> crate::Result<PathBuf> {
let mut path = get_cargo_metadata()
.with_context(|| "failed to get cargo metadata")?
.target_directory;
if let Some(triple) = target {
path.push(triple);
}
path.push(if is_release { "release" } else { "debug" });
Ok(path)
}
/// Walks up the file system, looking for a Cargo.toml file
/// If one is found before reaching the root, then the current_dir's package belongs to that parent workspace if it's listed on [workspace.members].
///
/// If this package is part of a workspace, returns the path to the workspace directory
/// Otherwise returns the current directory.
pub fn get_workspace_dir(current_dir: &Path) -> PathBuf {
let mut dir = current_dir.to_path_buf();
let project_path = dir.clone();
while dir.pop() {
if dir.join("Cargo.toml").exists() {
match CargoSettings::load(&dir) {
Ok(cargo_settings) => {
if let Some(workspace_settings) = cargo_settings.workspace {
if let Some(members) = workspace_settings.members {
if members.iter().any(|member| {
glob::glob(&dir.join(member).to_string_lossy())
.unwrap()
.any(|p| p.unwrap() == project_path)
}) {
return dir;
}
}
}
}
Err(e) => {
warn!(
"Found `{}`, which may define a parent workspace, but \
failed to parse it. If this is indeed a parent workspace, undefined behavior may occur: \
\n {:#}",
dir.display(),
e
);
}
}
}
}
// Nothing found walking up the file system, return the starting directory
current_dir.to_path_buf()
/// Executes `cargo metadata` to get the workspace directory.
pub fn get_workspace_dir() -> crate::Result<PathBuf> {
Ok(
get_cargo_metadata()
.with_context(|| "failed to get cargo metadata")?
.workspace_root,
)
}
#[allow(unused_variables)]

View File

@@ -0,0 +1,123 @@
use anyhow::{Context, Result};
use serde::Deserialize;
use std::{
fs,
path::{Path, PathBuf},
};
struct PathAncestors<'a> {
current: Option<&'a Path>,
}
impl<'a> PathAncestors<'a> {
fn new(path: &'a Path) -> PathAncestors<'a> {
PathAncestors {
current: Some(path),
}
}
}
impl<'a> Iterator for PathAncestors<'a> {
type Item = &'a Path;
fn next(&mut self) -> Option<&'a Path> {
if let Some(path) = self.current {
self.current = path.parent();
Some(path)
} else {
None
}
}
}
#[derive(Default, Deserialize)]
pub struct BuildConfig {
target: Option<String>,
}
#[derive(Deserialize)]
pub struct ConfigSchema {
build: Option<BuildConfig>,
}
#[derive(Default)]
pub struct Config {
build: BuildConfig,
}
impl Config {
pub fn load(path: &Path) -> Result<Self> {
let mut config = Self::default();
for current in PathAncestors::new(path) {
if let Some(path) = get_file_path(&current.join(".cargo"), "config", true)? {
let contents = fs::read_to_string(&path)
.with_context(|| format!("failed to read configuration file `{}`", path.display()))?;
let toml: ConfigSchema = toml::from_str(&contents)
.with_context(|| format!("could not parse TOML configuration in `{}`", path.display()))?;
if let Some(target) = toml.build.and_then(|b| b.target) {
config.build.target = Some(target);
break;
}
}
}
Ok(config)
}
pub fn build(&self) -> &BuildConfig {
&self.build
}
}
impl BuildConfig {
pub fn target(&self) -> Option<&str> {
self.target.as_deref()
}
}
/// The purpose of this function is to aid in the transition to using
/// .toml extensions on Cargo's config files, which were historically not used.
/// Both 'config.toml' and 'credentials.toml' should be valid with or without extension.
/// When both exist, we want to prefer the one without an extension for
/// backwards compatibility, but warn the user appropriately.
fn get_file_path(
dir: &Path,
filename_without_extension: &str,
warn: bool,
) -> Result<Option<PathBuf>> {
let possible = dir.join(filename_without_extension);
let possible_with_extension = dir.join(format!("{}.toml", filename_without_extension));
if possible.exists() {
if warn && possible_with_extension.exists() {
// We don't want to print a warning if the version
// without the extension is just a symlink to the version
// WITH an extension, which people may want to do to
// support multiple Cargo versions at once and not
// get a warning.
let skip_warning = if let Ok(target_path) = fs::read_link(&possible) {
target_path == possible_with_extension
} else {
false
};
if !skip_warning {
log::warn!(
"Both `{}` and `{}` exist. Using `{}`",
possible.display(),
possible_with_extension.display(),
possible.display()
);
}
}
Ok(Some(possible))
} else if possible_with_extension.exists() {
Ok(Some(possible_with_extension))
} else {
Ok(None)
}
}