about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_dev/src/main.rs20
-rw-r--r--clippy_dev/src/setup/toolchain.rs27
2 files changed, 39 insertions, 8 deletions
diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
index 93a74ba8387..1c36de0ac61 100644
--- a/clippy_dev/src/main.rs
+++ b/clippy_dev/src/main.rs
@@ -53,7 +53,12 @@ fn main() {
                     setup::git_hook::install_hook(force_override);
                 }
             },
-            SetupSubcommand::Toolchain { force, release, name } => setup::toolchain::create(force, release, &name),
+            SetupSubcommand::Toolchain {
+                standalone,
+                force,
+                release,
+                name,
+            } => setup::toolchain::create(standalone, force, release, &name),
             SetupSubcommand::VscodeTasks { remove, force_override } => {
                 if remove {
                     setup::vscode::remove_tasks();
@@ -267,14 +272,25 @@ enum SetupSubcommand {
         force_override: bool,
     },
     /// Install a rustup toolchain pointing to the local clippy build
+    ///
+    /// This creates a toolchain with symlinks pointing at
+    /// `target/.../{clippy-driver,cargo-clippy}`, rebuilds of the project will be reflected in the
+    /// created toolchain unless `--standalone` is passed
     Toolchain {
         #[arg(long, short)]
+        /// Create a standalone toolchain by copying the clippy binaries instead
+        /// of symlinking them
+        ///
+        /// Use this for example to create a toolchain, make a small change and then make another
+        /// toolchain with a different name in order to easily compare the two
+        standalone: bool,
+        #[arg(long, short)]
         /// Override an existing toolchain
         force: bool,
         #[arg(long, short)]
         /// Point to --release clippy binary
         release: bool,
-        #[arg(long, default_value = "clippy")]
+        #[arg(long, short, default_value = "clippy")]
         /// Name of the toolchain
         name: String,
     },
diff --git a/clippy_dev/src/setup/toolchain.rs b/clippy_dev/src/setup/toolchain.rs
index 8d98c6c92d9..2966629cf70 100644
--- a/clippy_dev/src/setup/toolchain.rs
+++ b/clippy_dev/src/setup/toolchain.rs
@@ -3,11 +3,14 @@ use std::env::current_dir;
 use std::ffi::OsStr;
 use std::fs;
 use std::path::{Path, PathBuf};
+use std::process::Command;
 use walkdir::WalkDir;
 
+use crate::utils::exit_if_err;
+
 use super::verify_inside_clippy_dir;
 
-pub fn create(force: bool, release: bool, name: &str) {
+pub fn create(standalone: bool, force: bool, release: bool, name: &str) {
     if !verify_inside_clippy_dir() {
         return;
     }
@@ -48,14 +51,22 @@ pub fn create(force: bool, release: bool, name: &str) {
         }
     }
 
-    symlink_bin("cargo-clippy", &dest, release);
-    symlink_bin("clippy-driver", &dest, release);
+    let status = Command::new("cargo")
+        .arg("build")
+        .args(release.then_some("--release"))
+        .status();
+    exit_if_err(status);
+
+    install_bin("cargo-clippy", &dest, standalone, release);
+    install_bin("clippy-driver", &dest, standalone, release);
 
     println!("Created toolchain {name}, use it in other projects with e.g. `cargo +{name} clippy`");
-    println!("Note: This will need to be re-run whenever the Clippy `rust-toolchain` changes");
+    if !standalone {
+        println!("Note: This will need to be re-run whenever the Clippy `rust-toolchain` changes");
+    }
 }
 
-fn symlink_bin(bin: &str, dest: &Path, release: bool) {
+fn install_bin(bin: &str, dest: &Path, standalone: bool, release: bool) {
     #[cfg(windows)]
     use std::os::windows::fs::symlink_file as symlink;
 
@@ -71,5 +82,9 @@ fn symlink_bin(bin: &str, dest: &Path, release: bool) {
     let mut dest = dest.to_path_buf();
     dest.extend(["bin", &file_name]);
 
-    symlink(src, dest).unwrap();
+    if standalone {
+        fs::copy(src, dest).unwrap();
+    } else {
+        symlink(src, dest).unwrap();
+    }
 }