Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cargo-dylint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dylint_internal = { version = "=6.3.2", path = "../internal" }
assert_cmd = { workspace = true }
cargo_metadata = { workspace = true }
ctor = { workspace = true }
dunce = { workspace = true }
glob = { workspace = true }
ignore = { workspace = true }
log = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions cargo-dylint/tests/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ fn markdown_does_not_use_inline_links() {
assert!(
!re.is_match(&markdown),
"`{}` uses inline links",
path.canonicalize().unwrap().to_string_lossy()
dunce::canonicalize(path).unwrap().to_string_lossy()
);
}
}
Expand All @@ -451,7 +451,7 @@ fn markdown_reference_links_are_sorted() {
assert!(
links_sorted == links,
"contents of `{}` are not what was expected:\n{}\n",
path.canonicalize().unwrap().to_string_lossy(),
dunce::canonicalize(path).unwrap().to_string_lossy(),
links_sorted.join("\n")
);
}
Expand Down
105 changes: 101 additions & 4 deletions cargo-dylint/tests/integration/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use assert_cmd::cargo::cargo_bin_cmd;
use dylint_internal::{
CommandExt,
clippy_utils::{set_clippy_utils_dependency_revision, set_toolchain_channel},
env,
env, library_filename_with_toolchain,
link::{debug_path_with_active_toolchain, debug_path_with_toolchain},
msrv,
rustup::{SanitizeEnvironment, active_toolchain},
Expand All @@ -16,10 +16,60 @@ use dylint_internal::{
use predicates::prelude::*;
use std::{
env::join_paths,
fmt::Write as _,
fs::OpenOptions,
io::Write,
path::{Path, PathBuf},
};
use tempfile::tempdir;

#[test]
fn metadata_and_lib_path_are_deduplicated() {
let library_dir = tempdir().unwrap();
let manifest_dir = tempdir().unwrap();
#[cfg(unix)]
let target_dir = tempdir().unwrap();

new_template(library_dir.path()).unwrap();
let toolchain = active_toolchain(library_dir.path()).unwrap();

dylint_internal::cargo::init("package `metadata_and_lib_path_test`")
.build()
.current_dir(&manifest_dir)
.args(["--name", "metadata_and_lib_path_test"])
.success()
.unwrap();

let library_dir_path = dunce::canonicalize(&library_dir).unwrap();
append_workspace_metadata(manifest_dir.path(), [library_dir_path.as_path()]).unwrap();

// On Unix, the symlink makes canonicalization change the library path. Windows symlinks or
// junctions can cause the same mismatch. This test does not create an alias on Windows,
// where symlink creation can require additional privileges. The Windows case checks
// deduplication without exercising alias resolution.
#[cfg(unix)]
std::os::unix::fs::symlink(&target_dir, manifest_dir.path().join("target")).unwrap();

cargo_bin_cmd!("cargo-dylint")
.current_dir(&manifest_dir)
.args(["dylint", "list", "--all"])
.assert()
.success();

let library_path = target_libraries_directory(manifest_dir.path(), &toolchain)
.unwrap()
.join(library_filename_with_toolchain("fill_me_in", &toolchain));

cargo_bin_cmd!("cargo-dylint")
.current_dir(&manifest_dir)
.args(["dylint", "list", "--all", "--no-build", "--lib-path"])
.arg(&library_path)
.assert()
.success()
// One occurrence in the library heading and one in its lint listing.
.stdout(predicate::str::contains("fill_me_in").count(2));
}

#[test]
fn one_name_multiple_toolchains() {
let tempdir = tempdir().unwrap();
Expand Down Expand Up @@ -227,6 +277,40 @@ fn relative_path() {
}
}

fn append_workspace_metadata<'a>(
manifest_dir: &Path,
lib_dirs: impl IntoIterator<Item = &'a Path>,
) -> Result<()> {
let manifest = manifest_dir.join("Cargo.toml");
let mut file = OpenOptions::new()
.append(true)
.open(&manifest)
.with_context(|| format!("Could not open `{}`", manifest.to_string_lossy()))?;

writeln!(file, "{}", workspace_metadata(lib_dirs))
.with_context(|| format!("Could not write to `{}`", manifest.to_string_lossy()))?;

Ok(())
}

fn workspace_metadata<'a>(lib_dirs: impl IntoIterator<Item = &'a Path>) -> String {
let mut metadata = String::from(
r"
[workspace.metadata.dylint]
libraries = [
",
);
for lib_dir in lib_dirs {
let path = toml::Value::String(lib_dir.to_string_lossy().into_owned());
writeln!(&mut metadata, " {{ path = {path} }},").unwrap();
}
metadata.push_str(
r"]
",
);
metadata
}

// smoelius: This test checks that if a library path is passed to `--path`, a "No library packages
// found in ..." message is emitted.
#[test]
Expand Down Expand Up @@ -258,7 +342,20 @@ fn list_by_path() {
fn target_debug(dir: &Path) -> Result<PathBuf> {
let metadata = dylint_internal::cargo::metadata(dir)?;
let debug_dir = metadata.target_directory.join("debug");
debug_dir
.canonicalize()
.with_context(|| format!("Could not canonicalize {debug_dir:?}"))
dunce::canonicalize(&debug_dir).with_context(|| format!("Could not canonicalize `{debug_dir}`"))
}

// smoelius: Hack. This function duplicates logic from, e.g.,
// `dylint::library_packages::Package::library_path_with_toolchain`.
fn target_libraries_directory(dir: &Path, toolchain: &str) -> Result<PathBuf> {
let target_directory = target_directory(dir)?;
Ok(target_directory
.join("dylint/libraries")
.join(toolchain)
.join("release"))
}

fn target_directory(dir: &Path) -> Result<PathBuf> {
let metadata = dylint_internal::cargo::metadata(dir)?;
Ok(metadata.target_directory.into_std_path_buf())
}
3 changes: 1 addition & 2 deletions dylint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cargo-util = { workspace = true, optional = true }
cargo-util-schemas = { workspace = true, optional = true }
cargo_metadata = { workspace = true }
chrono = { workspace = true, optional = true }
dunce = { workspace = true, optional = true }
dunce = { workspace = true }
fs_extra = { workspace = true, optional = true }
glob = { workspace = true, optional = true }
heck = { workspace = true, optional = true }
Expand Down Expand Up @@ -83,7 +83,6 @@ package_options = [
__cargo_cli = [
"cargo-util",
"cargo-util-schemas",
"dunce",
"dylint_internal/home",
"fs_extra",
"glob",
Expand Down
14 changes: 8 additions & 6 deletions dylint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ where
}

fn name_as_path(name: &str, as_path_only: bool) -> Result<Option<(String, PathBuf)>> {
if let Ok(path) = PathBuf::from(name).canonicalize() {
if let Ok(path) = dunce::canonicalize(name) {
if let Some((_, toolchain)) = parse_path_with_toolchain(&path) {
return Ok(Some((toolchain, path)));
}
Expand Down Expand Up @@ -482,17 +482,19 @@ fn list_lints(opts: &opts::Dylint, resolved: &ToolchainMap) -> Result<()> {

fn display_location(path: &Path) -> Result<String> {
let current_dir = current_dir().with_context(|| "Could not get current directory")?;
let current_dir_canonicalized = current_dir
.canonicalize()
.with_context(|| format!("Could not canonicalize `{}`", current_dir.display()))?;
let Ok(path_buf) = path.canonicalize() else {
return Ok("<unbuilt>".to_owned());
};
let parent = path_buf
.parent()
.ok_or_else(|| anyhow!("Could not get parent directory"))?;
Ok(parent
.strip_prefix(&current_dir)
.unwrap_or(parent)
.to_string_lossy()
.to_string())
let location = parent
.strip_prefix(&current_dir_canonicalized)
.unwrap_or(parent);
Ok(dunce::simplified(location).to_string_lossy().to_string())
}

fn clippy_disable_docs_links() -> Result<String> {
Expand Down
3 changes: 2 additions & 1 deletion dylint/src/library_packages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,8 @@ pub fn build_library(opts: &opts::Dylint, package: &Package) -> Result<PathBuf>
);
}

Ok(path)
dunce::canonicalize(&path)
.with_context(|| format!("Could not canonicalize `{}`", path.display()))
}

// smoelius: `pkg_dir` and `target_short_hash` are based on functions with the same names in
Expand Down
7 changes: 7 additions & 0 deletions examples/experimental/derive_opportunity/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/experimental/missing_doc_comment_llm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions examples/general/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions examples/restriction/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions examples/supplementary/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions examples/testing/clippy/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions examples/testing/straggler/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading