Skip to content
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

[Feature Request / Proposal] Upstream / preset / profile to preconfigure options #809

Open
pwoolvett opened this issue Nov 18, 2022 · 13 comments
Labels
configuration Related to settings and configuration

Comments

@pwoolvett
Copy link
Contributor

pwoolvett commented Nov 18, 2022

Would something like preset or a profile be a feature you'd like to see?

for example:

[tool.ruff]
preset = "charliemarsh"

alternatively

[tool.ruff]
upstream = "https://.../ruff-profile.toml"

The idea would be to (1) add a new parameter in the cli and in the config , and (2) override defaults eg after this with the loaded contents of the profile / upstream file.

would a PR with mentioned implementation be accepted? Or would more discussion be required (eg as part of the eventual plugin system)? Or maybe it's just a non-goal?

@charliermarsh
Copy link
Member

Yeah I like this idea, I think this could be quite useful. The main question that comes to mind is where / how the presets should be defined.

isort supports presets (called "profiles"), but they're all defined in isort itself, which is probably not what we want here.

eslint supports shareable configs, but they have to be released on npm (or defined and loaded from the local filesystem), which we also probably don't want.

A URL seems reasonable, but we'd definitely want to cache it.

Can we think of other examples to model on here? Maybe something pre-commit like, where you specify a URL and explicitly run install to fetch (or update) the config locally?

@charliermarsh charliermarsh added enhancement configuration Related to settings and configuration labels Nov 18, 2022
@pwoolvett
Copy link
Contributor Author

Presets seem to involve more logic.

I think the most straightforward would be the "upstream" variant, which would just be a local or cached remote .toml with configuration to use as defaults, overriden by local ruff config+cli. Then most common "presets" could just be tomls hosted together with the documentation :).

In that case, the pre-commit hook could be used to invalidate cached url (stage 1), before actually running ruff (stage 2). Or actually just provide two ruff hooks here: one to invalidate remote (people not using upstream wont care about this), and the current one.
(you were talking about pre-commit, not pre-commit, right?)

@charliermarsh
Copy link
Member

Yeah. We could also just cache it in .ruff_cache and then users can always rm -rf .ruff_cache to clear it out. (I want to make regular purging of the .ruff_cache slightly more automatic anyway, right now it just gets bigger with every release.)

@charliermarsh
Copy link
Member

@pwoolvett - Are you interested in working on it? :)

@pwoolvett
Copy link
Contributor Author

sure! ill have a go at it and send a pr

@charliermarsh
Copy link
Member

We now have extend = "/path/to/pyproject.toml" which is relevant here.

@michaeloliverx
Copy link

Maybe relevant, Something akin to tsconfig.json extends?

https://www.typescriptlang.org/tsconfig#extends

@charliermarsh
Copy link
Member

Created a Discussion around this: #3363

@Avasam
Copy link

Avasam commented Apr 12, 2023

We now have extend = "/path/to/pyproject.toml" which is relevant here.

The more projects I move over to Ruff, the more I really wish I could extend some base configs cross-projects. Something like being able to use a URL in extend or a path relative to site-packages, like:

Maybe relevant, Something akin to tsconfig.json extends?

typescriptlang.org/tsconfig#extends

It's also the last major feature missing before I feel confident showing off (and integrating) Ruff at my workplace, where we love being able to reference a global base configuration for our tooling, massively simplifying other dev's work when it comes to following company-wide standards, staying up to date, and integrating/configuring the tools in all projects as easily as possible.

(tl;dr: adoption is easier when I can say "add these 3 lines to your configs" instead of "copy these config files that will soon be out of date")

@gaborbernat
Copy link
Contributor

gaborbernat commented Apr 26, 2023

@charliermarsh we spoke about this at PyCon how for Python would generalize better if one could pull configuration via a plugin system of an additionaly installed Python package. Ideally, we'd not even need any configuration such as:

[tool.ruff]
preset = "tox_ruff_config"

When installed into a Python interpreter, we could just use https://docs.python.org/3/library/importlib.metadata.html#entry-points via the ruff key, and if a such library is detected load that configuration file as a base (still overwrite-able via pyproject.toml). How one woud use this is via pre-commit:

- repo: https://github.com/charliermarsh/ruff-pre-commit
  rev: "v0.0.263"
  hooks:
    - id: ruff
       additional_dependencies: [tox_ruff_config==1.0.1]

This solution would cache natively, would be versioned by design, and would work behind enterprise firewalls too. This feature would only work if ruff is installed via Python, and would be no-op should you run ruff as a dedicated binary.

@yoann9344
Copy link

yoann9344 commented Feb 19, 2024

It would be nice to be able to extend the config from a main project on another git.

[tool.ruff]
extend = "../ruff/pyproject.toml"
# instead we could write something like this :
extend = { git = "https://github.com/astral-sh/ruff.git", tag="0.2.1" }
extend = { git = "https://github.com/astral-sh/ruff.git", branch="some_branch" }
# maybe with the possibility to configure the path to the `pyproject.toml`
extend = { git = "https://github.com/astral-sh/ruff.git", tag="0.2.1", path = "my_dir_configs/pyproject.toml" }

Could even imagine to retrieve a config from a dependency manager like pep compliant or poetry :

[project]
dependencies = [
    "my-repo @ git+https://github.com/my-repo/ruff.git@0.2.1"
]
[tool.poetry.dependencies]
my-repo = { git = "https://github.com/my-repo/ruff.git", tag="0.2.1" }

[tool.ruff]
extend = { pep = "my-repo", path = "my_dir_configs/pyproject.toml" }
extend = { poetry = "my-repo", path = "my_dir_configs/pyproject.toml" }

The logic behind will basically do something like this :

# With default values :
# extend_tag=""
# extend_branch=""
# extend_path="pyproject.toml"
position=`pwd`
git clone --no-checkout --depth=1 --no-tags $extend_git $somewhere_in_ruff_cache
cd $somewhere_in_ruff_cache
if [ "$extend_tag" != "" ]; then
    git fetch origin "+refs/tags/${extend_tag}:refs/tags/${extend_tag}" --no-tags
    git checkout $extend_tag -- $extend_path
else
    git checkout $extend_branch -- $extend_path  # empty branch is HEAD
fi
cd $position
# config ruff to point on the retrieved toml
config_extend "${somewhere_in_ruff_cache}/${extend_path}"

Then we could imagine that extend can include presets :

extend = { preset = "strict_without_doc" }
# Would be be an alias for :
extend = { git = "https://github.com/astral-sh/ruff.git", tag = "<running_ruff_version>", path = "presets_config/strict_without_doc.toml" }
# We could even imagine to block the config to an older version
extend = { preset = "strict_without_doc", tag = "0.2.0" }

I think it is better to keep the same key for adding other configs. So everything that involves joining a toml would be under extend, doc, config and code would be clearer this way. Then to have multiple configs, we could image a list, where order matters :

extend = [
    { preset = "Doc_permissive" },
    { preset = "Flake8_without_warnings" },
    { preset = "Import" },
    { preset = "Security_strict" },
]

@hinricht
Copy link

Also very interested in the feature to extend from a remote URL.
Use-case is to settle on a sane base config for ruff which can get included in all projects, but individual rules could easly tuned without code duplication.

@Avasam
Copy link

Avasam commented Apr 18, 2024

Do keep in mind though that online shared configs will break pre-commit.ci as it doesn't allow internet acces whilst running, only on install.

This could be worked around if the pre-commit action can "dry-run" and cache the extended config file.

dprint currently has this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
configuration Related to settings and configuration
Projects
None yet
Development

No branches or pull requests

7 participants