4

feat: Add a basic linting system by Muscraft · Pull Request #13621 · rust-lang/c...

 4 weeks ago
source link: https://github.com/rust-lang/cargo/pull/13621
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

feat: Add a basic linting system #13621

Conversation

Contributor

This PR adds a basic linting system, the first step towards User control over cargo warnings. To demonstrate the system, a lint for #12826 is added. It supports controlling cargo lints via the [lints.cargo] table. Lints can be controlled either by a group or individually.

This is meant to lay down some fundamental infrastructure for the whole linting system and is not meant to be fully featured. Over time, features will be added that will help us reach a much more solid state.

weihanglo and jeffparsons reacted with hooray emojiweihanglo and jeffparsons reacted with heart emoji

Collaborator

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

rustbot

added A-manifest Area: Cargo.toml issues A-workspaces Area: workspaces S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

labels

Mar 22, 2024

}

impl Lint {

pub fn level(&self, lints: &TomlToolLints, edition: Edition) -> LintLevel {

One thing worth thinking hard is that how to avoid future build failure if people set something like -D cargo::all and we introduce new cargo lints.

A possible way is having every new lint capped max to warning in the current edition, and relax in the next.

Contributor

Author

One way to potentially do this is to have each lint have a version field similar to Feature, that is the version they are stabilized in. From there, we add a "dynamic" group cargo:new-lints that all lints stabilized in that version are apart of. We then add documentation saying if a user doesn't want to break CI with -D cargo::all, they should have the command be:

cargo <cmd> -- -W cargo:new-lints -D cargo:all

I don't think this is perfect but it would work

weihanglo reacted with thumbs up emoji

Contributor

I don't think rustc or clippy maintain compatibility with all

Collaborator

☔ The latest upstream changes (presumably #13627) made this pull request unmergeable. Please resolve the merge conflicts.

});

// Add implicit features for optional dependencies if they weren't

// explicitly listed anywhere.

let explicitly_listed = user_defined_features.map_or(HashSet::new(), |f| {

We might want some more test cases to exercising implicit features lint.

  • has dep:foo
  • has foo = [] feature
  • build.dependencies
  • target platform dependencies

Since this PR aims for the linting system. Let's leave it later.

src/cargo/util/lints.rs

Show resolved

Member

As this is for linting system, the only blocker is an unstable flag for [lints.cargo]. Let me know if you are willing to work on it in this PR or later.

Member

@weihanglo weihanglo

left a comment

Thanks! Now looks pretty great and we're ready to merge this 👍🏾

Member

This public interface of the linting system ([lints.cargo] table) is behind a new unstable flag -Z cargo-lints, with only a warning if not on nightly (non-blocking flag). Since the Cargo team is aware of the linting system Scott has been working on, I think we could merge it as-is without an FCP. Let me know if something goes wrong then.

@bors r+

Collaborator

📌 Commit 307c7f8 has been approved by weihanglo

It is now in the queue for this repository.

bors

added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

labels

Mar 23, 2024

Collaborator

⌛ Testing commit 307c7f8 with merge 61855e7...

Collaborator

☀️ Test successful - checks-actions
Approved by: weihanglo
Pushing 61855e7 to master...

use std::path::Path;

use toml_edit::ImDocument;

fn get_span(document: &ImDocument<String>, path: &[&str], get_value: bool) -> Option<Range<usize>> {

Contributor

nit: please put the focus of the file (what comes first) on the API and not the implementation details

edition_lint_opts: Some((Edition::Edition2024, LintLevel::Deny)),

};

pub fn check_implicit_features(

Contributor

imo its a bit messy to shove lint implementations in here just because they are lints. This body should live where its called.

use std::path::Path;

use toml_edit::ImDocument;

fn get_span(document: &ImDocument<String>, path: &[&str], get_value: bool) -> Option<Range<usize>> {

Contributor

These needs documentation, especially around how arrays are handled

/// Gets the relative path to a manifest from the current working directory, or

/// the absolute path of the manifest if a relative path cannot be constructed

fn rel_cwd_manifest_path(path: &Path, gctx: &GlobalContext) -> String {

Contributor

ditto, this belongs at the end of the file

/// Gets the relative path to a manifest from the current working directory, or

/// the absolute path of the manifest if a relative path cannot be constructed

fn rel_cwd_manifest_path(path: &Path, gctx: &GlobalContext) -> String {

Contributor

String in this is suspect. Should this have display in the name?

Or should we try to switch to camino?

Comment on lines

+87 to +106

let level = self

.groups

.iter()

.map(|g| g.name)

.chain(std::iter::once(self.name))

.filter_map(|n| lints.get(n).map(|l| (n, l)))

.max_by_key(|(n, l)| (l.priority(), std::cmp::Reverse(*n)));

match level {

Some((_, toml_lint)) => toml_lint.level().into(),

None => {

if let Some((lint_edition, lint_level)) = self.edition_lint_opts {

if edition >= lint_edition {

return lint_level;

}

}

self.default_level

}

}

}

Contributor

Do we document anywhere the status of the warnings group?

Contributor

Note: even if we don't support the group in [lints], we'd need to be able to support it in the future with #8424.

impl LintLevel {

pub fn to_diagnostic_level(self) -> Level {

match self {

LintLevel::Allow => Level::Note,

Contributor

Why is Allow translating to Note. We shouldn't be showing Allow

{

continue;

}

if lint_level == LintLevel::Forbid || lint_level == LintLevel::Deny {

Contributor

Should we have an is_error function?

}

let level = lint_level.to_diagnostic_level();

let manifest_path = rel_cwd_manifest_path(path, gctx);

let message = level.title("unused optional dependency").snippet(

Contributor

This message doesn't make sense pre-2024

@@ -0,0 +1,34 @@

use cargo_test_support::prelude::*;

Contributor

None of our other UI tests nest this deeply

name: "rust-2024-compatibility",

default_level: LintLevel::Allow,

desc: "warn about compatibility with Rust 2024",

edition_lint_opts: Some((Edition::Edition2024, LintLevel::Deny)),

Contributor

We're only making this Deny for 2024? That means people can override this to allow it. If they do, we should make sure that the dependency truly is unused and doesn't create a feature.

}

impl Lint {

pub fn level(&self, lints: &TomlToolLints, edition: Edition) -> LintLevel {

Contributor

We should verify this handles Forbid correctly.

}

let level = lint_level.to_diagnostic_level();

let manifest_path = rel_cwd_manifest_path(path, gctx);

let message = level.title("unused optional dependency").snippet(

Contributor

Should we have a transitional note that implicit features are no longer supported?

}

let level = lint_level.to_diagnostic_level();

let manifest_path = rel_cwd_manifest_path(path, gctx);

let message = level.title("unused optional dependency").snippet(

Contributor

rustc/clippy lints display the lint name (and where the level was set) on first instance of it being reported

Comment on lines

+1100 to +1103

let path = path.join("Cargo.toml");

if let MaybePackage::Package(pkg) = maybe_pkg {

self.emit_lints(pkg, &path)?

}

Contributor

We need a test to ensure this is subject to cap-lints

Comment on lines

+1466 to +1468

if tool == "cargo" && !gctx.cli_unstable().cargo_lints {

warn_for_cargo_lint_feature(gctx, warnings);

}

Contributor

Do we need to strip lints.cargo before we publish?

Contributor

Would it be possible to update unstable.md with documentation about this feature?

Also, is #12235 the main tracking issue for what needs to be done next? Is there an outline of what steps need to be taken?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

epage

epage left review comments

weihanglo

weihanglo approved these changes
Labels
A-manifest Area: Cargo.toml issues A-unstable Area: nightly unstable support A-workspaces Area: workspaces S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects

None yet

Milestone

1.79.0

Development

Successfully merging this pull request may close these issues.

None yet

6 participants

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK