-
Notifications
You must be signed in to change notification settings - Fork 958
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
Enable configuration files to "extend" other configuration files #1219
Conversation
@smackesey - This, combined with the changes on diff --git a/examples/docs_snippets/pyproject.toml b/examples/docs_snippets/pyproject.toml
index 13f6920c45..70bc2806fe 100644
--- a/examples/docs_snippets/pyproject.toml
+++ b/examples/docs_snippets/pyproject.toml
@@ -9,3 +9,14 @@ line-length = 88
preview = true
required-version = "22.10.0"
target-version = ['py37', 'py38', 'py39', 'py310', 'py311']
+
+[tool.ruff]
+extend = "../../pyproject.toml"
+
+extend-ignore = [
+
+ # (local variable assigned but never used): This happens a lot in the docs snippets for didactic
+ # purposes.
+ "F841",
+
+]
diff --git a/pyproject.toml b/pyproject.toml
index 4012d47c3e..2c62a258d5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -117,11 +117,6 @@ ignore = [
"T201", # (no print call)
"T203", # (no pprint call)
- # (local variable assigned but never used): This happens a lot in the docs snippets for didactic
- # purposes. We are putting it in the global rather than file-specific ignore pending resolution of
- # a bug with file-specific ignores.
- "F841",
-
]
# Match black. Note that this also checks comment line length, but black does not format comments. |
@andersk - Since you brought up overrides in #552, wondering what your stance is on how the "extends" semantics should work here. (If you're busy, all good, no worries.) Right now, if you I think ESLint merges the fields between parent and child. So, like, if one field is a list of plugins, I believe ESLint will just concatenate the lists when merging a parent into a child. I think I'd prefer something more explicit? I've considered using the |
e6fc307
to
96f73b4
Compare
One question with that strategy is what should happen if the parent sets |
96f73b4
to
30ba5bb
Compare
@andersk - Yeah, my instinct is that the child should always preside over the parent. So the algorithm would be, roughly:
On that last point: as an example, this today doesn't enable
|
30ba5bb
to
d588263
Compare
(Ok, all |
ff3b4ef
to
6ae9aae
Compare
6ae9aae
to
89e2c82
Compare
This PR implements an
extends
keyword in thepyproject.toml
schema. When provided, we resolve apyproject.toml
file by first loading the file pointed to byextends
, then overriding it with any properties defined in the current file.Configuration files are resolved recursively, such that the file you
extends
can also have anextends
(and we error if you introduce a cycle).In implementing this feature, I had to shift around some of the responsibilities that are split between
Options
,Configuration
, andSettings
(which are all bad names). As of this PR, they are as follows:Options
is the simplest: it's the exact schema implemented in TOML. It's the thing we read from apyproject.toml
file. Every field isOption
.Settings
is the fully resolved, internal settings for the linter. It doesn't have to look like the user-facing representation in the TOML file. For example, it includes a singleFxHashSet
of enabled check codes, rather than anignore
andselect
list. None of the fields areOption
, andSettings
is responsible for translating each field fromNone
to defaults.Configuration
is the intermediate representation that results from takingOptions
and resolving them relative to a given file system path. For example,Options
can includeexcludes
, which are relative paths. When we transformOptions
toConfiguration
, we have to provide a "project root" relative to which it's resolved. From there, we transform any paths into absolute paths based on that project root. All of the fields onConfiguration
are alsoOption
. (This changed in this PR.)When creating a
Settings
, we load the finalpyproject.toml
file from disk intoOptions
, then intoConfiguration
. We then look at theextends
keyword and iteratively collect all of theConfiguration
structs. When we're done, we go through and merge them into a singleConfiguration
. (This is why I had to make all fields onConfiguration
optional -- so that we can tell what's defined, and what's not.) Finally, we take theConfiguration
and transform it intoSettings
.Closes #1055. Closes #1215. #552 is also relevant.