From 59dd18d2a6ba070ac415953a027ce4c25d6a8787 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 23 Apr 2024 16:06:19 -0400 Subject: [PATCH 1/4] Read user configuration from ~/.config/ruff/ruff.toml on macOS --- Cargo.lock | 12 +++++++ Cargo.toml | 1 + crates/ruff_workspace/Cargo.toml | 1 + crates/ruff_workspace/src/pyproject.rs | 45 ++++++++++++++------------ docs/faq.md | 16 +++++---- 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb156f378154e..f880c6054c761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -754,6 +754,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "eyre" version = "0.6.12" @@ -2494,6 +2505,7 @@ dependencies = [ "anyhow", "colored", "dirs 5.0.1", + "etcetera", "glob", "globset", "ignore", diff --git a/Cargo.toml b/Cargo.toml index c617d5d69e57f..ad7269694c20a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,6 +61,7 @@ dashmap = { version = "5.5.3" } dirs = { version = "5.0.0" } drop_bomb = { version = "0.1.5" } env_logger = { version = "0.11.0" } +etcetera = { version = "0.8.0" } fern = { version = "0.6.1" } filetime = { version = "0.2.23" } glob = { version = "0.3.1" } diff --git a/crates/ruff_workspace/Cargo.toml b/crates/ruff_workspace/Cargo.toml index 25c5fbaa84857..c2e4734cf0884 100644 --- a/crates/ruff_workspace/Cargo.toml +++ b/crates/ruff_workspace/Cargo.toml @@ -24,6 +24,7 @@ ruff_macros = { workspace = true } anyhow = { workspace = true } colored = { workspace = true } dirs = { workspace = true } +etcetera = { workspace = true } ignore = { workspace = true } is-macro = { workspace = true } itertools = { workspace = true } diff --git a/crates/ruff_workspace/src/pyproject.rs b/crates/ruff_workspace/src/pyproject.rs index 75a6d13243f51..814d90822b23c 100644 --- a/crates/ruff_workspace/src/pyproject.rs +++ b/crates/ruff_workspace/src/pyproject.rs @@ -3,11 +3,13 @@ use std::path::{Path, PathBuf}; use anyhow::{Context, Result}; +use etcetera::BaseStrategy; use log::debug; use pep440_rs::VersionSpecifiers; use serde::{Deserialize, Serialize}; use ruff_linter::settings::types::PythonVersion; +use ruff_linter::warn_user_once; use crate::options::Options; @@ -99,28 +101,31 @@ pub fn find_settings_toml>(path: P) -> Result> { /// Find the path to the user-specific `pyproject.toml` or `ruff.toml`, if it /// exists. pub fn find_user_settings_toml() -> Option { - // Search for a user-specific `.ruff.toml`. - let mut path = dirs::config_dir()?; - path.push("ruff"); - path.push(".ruff.toml"); - if path.is_file() { - return Some(path); - } - - // Search for a user-specific `ruff.toml`. - let mut path = dirs::config_dir()?; - path.push("ruff"); - path.push("ruff.toml"); - if path.is_file() { - return Some(path); + let strategy = etcetera::base_strategy::choose_base_strategy().ok()?; + let config_dir = strategy.config_dir().join("ruff"); + + // Search for a user-specific `.ruff.toml`, then a `ruff.toml`, then a `pyproject.toml`. + for filename in [".ruff.toml", "ruff.toml", "pyproject.toml"] { + let path = config_dir.join(filename); + if path.is_file() { + return Some(path); + } } - // Search for a user-specific `pyproject.toml`. - let mut path = dirs::config_dir()?; - path.push("ruff"); - path.push("pyproject.toml"); - if path.is_file() { - return Some(path); + // On macOS, we used to support reading from `/Users/Alice/Library/Application Support`. + if cfg!(target_os = "macos") { + let deprecated_config_dir = dirs::config_dir()?.join("ruff"); + + for file in [".ruff.toml", "ruff.toml", "pyproject.toml"] { + let path = deprecated_config_dir.join(file); + if path.is_file() { + warn_user_once!( + "Reading configuration from `~/Library/Application Support` is deprecated. Please move your configuration to `{}/{file}`.", + config_dir.display(), + ); + return Some(path); + } + } } None diff --git a/docs/faq.md b/docs/faq.md index ed8475f2f55ae..b287b21c21cdf 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -612,16 +612,20 @@ Ruff doesn't currently support INI files, like `setup.cfg` or `tox.ini`. ## How can I change Ruff's default configuration? -When no configuration file is found, Ruff will look for a user-specific `pyproject.toml` or -`ruff.toml` file as a last resort. This behavior is similar to Flake8's `~/.config/flake8`. +When no configuration file is found, Ruff will look for a user-specific `ruff.toml` file as a +last resort. This behavior is similar to Flake8's `~/.config/flake8`. -On macOS, Ruff expects that file to be located at `/Users/Alice/Library/Application Support/ruff/ruff.toml`. +On macOS and Linux, Ruff expects that file to be located at `~/.config/ruff/ruff.toml`, +and respects the `XDG_CONFIG_HOME` specification. -On Linux, Ruff expects that file to be located at `/home/alice/.config/ruff/ruff.toml`. +On Windows, Ruff expects that file to be located at `~\AppData\Roaming\ruff\ruff.toml`. -On Windows, Ruff expects that file to be located at `C:\Users\Alice\AppData\Roaming\ruff\ruff.toml`. +!!! note + Prior to `v0.5.0`, Ruff would read user-specific configuration from + `~/Library/Application Support/ruff/ruff.toml` on macOS. While Ruff will still respect + such configuration files, the use of `~/Library/ Application Support` is considered deprecated. -For more, see the [`dirs`](https://docs.rs/dirs/4.0.0/dirs/fn.config_dir.html) crate. +For more, see the [`etcetera`](https://crates.io/crates/etcetera) crate. ## Ruff tried to fix something — but it broke my code. What's going on? From 38199c3a99ec86acb68159fd5e32f545f0532b82 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Mon, 24 Jun 2024 14:44:43 +0200 Subject: [PATCH 2/4] Remove dirs dependency --- Cargo.lock | 1 - Cargo.toml | 1 - crates/ruff_workspace/Cargo.toml | 1 - crates/ruff_workspace/src/pyproject.rs | 5 +++-- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f880c6054c761..9321f1d015bf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2504,7 +2504,6 @@ version = "0.0.0" dependencies = [ "anyhow", "colored", - "dirs 5.0.1", "etcetera", "glob", "globset", diff --git a/Cargo.toml b/Cargo.toml index ad7269694c20a..645ee958a4639 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,6 @@ countme = { version = "3.0.1" } criterion = { version = "0.5.1", default-features = false } crossbeam = { version = "0.8.4" } dashmap = { version = "5.5.3" } -dirs = { version = "5.0.0" } drop_bomb = { version = "0.1.5" } env_logger = { version = "0.11.0" } etcetera = { version = "0.8.0" } diff --git a/crates/ruff_workspace/Cargo.toml b/crates/ruff_workspace/Cargo.toml index c2e4734cf0884..5b34cfbfcaefd 100644 --- a/crates/ruff_workspace/Cargo.toml +++ b/crates/ruff_workspace/Cargo.toml @@ -23,7 +23,6 @@ ruff_macros = { workspace = true } anyhow = { workspace = true } colored = { workspace = true } -dirs = { workspace = true } etcetera = { workspace = true } ignore = { workspace = true } is-macro = { workspace = true } diff --git a/crates/ruff_workspace/src/pyproject.rs b/crates/ruff_workspace/src/pyproject.rs index 814d90822b23c..85725b740a06d 100644 --- a/crates/ruff_workspace/src/pyproject.rs +++ b/crates/ruff_workspace/src/pyproject.rs @@ -114,10 +114,11 @@ pub fn find_user_settings_toml() -> Option { // On macOS, we used to support reading from `/Users/Alice/Library/Application Support`. if cfg!(target_os = "macos") { - let deprecated_config_dir = dirs::config_dir()?.join("ruff"); + let strategy = etcetera::base_strategy::Apple::new().ok()?; + let config_dir = strategy.data_dir().join("ruff"); for file in [".ruff.toml", "ruff.toml", "pyproject.toml"] { - let path = deprecated_config_dir.join(file); + let path = config_dir.join(file); if path.is_file() { warn_user_once!( "Reading configuration from `~/Library/Application Support` is deprecated. Please move your configuration to `{}/{file}`.", From d681e492947f3445a6f6b3549cd3f34016a00318 Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Mon, 24 Jun 2024 14:58:35 +0200 Subject: [PATCH 3/4] Fix WASM build --- crates/ruff_workspace/src/pyproject.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/ruff_workspace/src/pyproject.rs b/crates/ruff_workspace/src/pyproject.rs index 85725b740a06d..8984c3b2309ce 100644 --- a/crates/ruff_workspace/src/pyproject.rs +++ b/crates/ruff_workspace/src/pyproject.rs @@ -3,7 +3,6 @@ use std::path::{Path, PathBuf}; use anyhow::{Context, Result}; -use etcetera::BaseStrategy; use log::debug; use pep440_rs::VersionSpecifiers; use serde::{Deserialize, Serialize}; @@ -100,7 +99,10 @@ pub fn find_settings_toml>(path: P) -> Result> { /// Find the path to the user-specific `pyproject.toml` or `ruff.toml`, if it /// exists. +#[cfg(not(target_arch = "wasm32"))] pub fn find_user_settings_toml() -> Option { + use etcetera::BaseStrategy; + let strategy = etcetera::base_strategy::choose_base_strategy().ok()?; let config_dir = strategy.config_dir().join("ruff"); @@ -132,6 +134,11 @@ pub fn find_user_settings_toml() -> Option { None } +#[cfg(target_arch = "wasm32")] +pub fn find_user_settings_toml() -> Option { + None +} + /// Load `Options` from a `pyproject.toml` or `ruff.toml` file. pub fn load_options>(path: P) -> Result { if path.as_ref().ends_with("pyproject.toml") { From c4d143a927e8cfce193e6d7dae22945d606af24d Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Mon, 24 Jun 2024 15:01:05 +0200 Subject: [PATCH 4/4] Fix deprecation message --- crates/ruff_workspace/Cargo.toml | 4 +++- crates/ruff_workspace/src/pyproject.rs | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/ruff_workspace/Cargo.toml b/crates/ruff_workspace/Cargo.toml index 5b34cfbfcaefd..20a81205c55dd 100644 --- a/crates/ruff_workspace/Cargo.toml +++ b/crates/ruff_workspace/Cargo.toml @@ -23,7 +23,6 @@ ruff_macros = { workspace = true } anyhow = { workspace = true } colored = { workspace = true } -etcetera = { workspace = true } ignore = { workspace = true } is-macro = { workspace = true } itertools = { workspace = true } @@ -42,6 +41,9 @@ shellexpand = { workspace = true } strum = { workspace = true } toml = { workspace = true } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +etcetera = { workspace = true } + [dev-dependencies] # Enable test rules during development ruff_linter = { workspace = true, features = ["clap", "test-rules"] } diff --git a/crates/ruff_workspace/src/pyproject.rs b/crates/ruff_workspace/src/pyproject.rs index 8984c3b2309ce..6230672814743 100644 --- a/crates/ruff_workspace/src/pyproject.rs +++ b/crates/ruff_workspace/src/pyproject.rs @@ -8,7 +8,6 @@ use pep440_rs::VersionSpecifiers; use serde::{Deserialize, Serialize}; use ruff_linter::settings::types::PythonVersion; -use ruff_linter::warn_user_once; use crate::options::Options; @@ -102,6 +101,7 @@ pub fn find_settings_toml>(path: P) -> Result> { #[cfg(not(target_arch = "wasm32"))] pub fn find_user_settings_toml() -> Option { use etcetera::BaseStrategy; + use ruff_linter::warn_user_once; let strategy = etcetera::base_strategy::choose_base_strategy().ok()?; let config_dir = strategy.config_dir().join("ruff"); @@ -117,10 +117,10 @@ pub fn find_user_settings_toml() -> Option { // On macOS, we used to support reading from `/Users/Alice/Library/Application Support`. if cfg!(target_os = "macos") { let strategy = etcetera::base_strategy::Apple::new().ok()?; - let config_dir = strategy.data_dir().join("ruff"); + let deprecated_config_dir = strategy.data_dir().join("ruff"); for file in [".ruff.toml", "ruff.toml", "pyproject.toml"] { - let path = config_dir.join(file); + let path = deprecated_config_dir.join(file); if path.is_file() { warn_user_once!( "Reading configuration from `~/Library/Application Support` is deprecated. Please move your configuration to `{}/{file}`.",