about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-06 14:51:51 +0000
committerbors <bors@rust-lang.org>2020-10-06 14:51:51 +0000
commit9fdaeb393a16951f6fdef087193fef576e36aba6 (patch)
tree64d4bc18709a56c9aa4127bbf52a9a9e2c8017fc /src
parent08e2d4616613716362b4b49980ff303f2b9ae654 (diff)
parent0845627f73faa2322bc24421cf3dd1f5dd3005df (diff)
Auto merge of #76356 - caass:hooks, r=jyn514
Add a command to install a git hook to automatically run `x.py test tidy --bless`

Some folks (such as myself) would probably find a lot of convenience in a pre-commit hook that automatically runs tidy before committing, to avoid burning CI time learning that your commit wasn't tidy.

I'm absolutely positive I have missed some stuff. I basically just got this to where you can run `./x.py run install-git-hook` and then clicked the commit button. Please let me know what else you'd like me to add before this can be merged!

[rustc-dev-guide companion PR](https://github.com/rust-lang/rustc-dev-guide/pull/848)
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/setup.rs47
-rwxr-xr-xsrc/etc/pre-commit.sh21
3 files changed, 69 insertions, 1 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index c87476d8f58..4bc162abee6 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -477,7 +477,7 @@ impl<'a> Builder<'a> {
                 install::Src,
                 install::Rustc
             ),
-            Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest,),
+            Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest),
         }
     }
 
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index 8a77641fbfe..24ec43373cc 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -46,6 +46,12 @@ pub fn setup(src_path: &Path, include_name: &str) {
         _ => return,
     };
 
+    println!();
+
+    t!(install_git_hook_maybe(src_path));
+
+    println!();
+
     println!("To get started, try one of the following commands:");
     for cmd in suggestions {
         println!("- `x.py {}`", cmd);
@@ -86,3 +92,44 @@ d) Install Rust from source"
     };
     Ok(template.to_owned())
 }
+
+// install a git hook to automatically run tidy --bless, if they want
+fn install_git_hook_maybe(src_path: &Path) -> io::Result<()> {
+    let mut input = String::new();
+    println!(
+        "Rust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
+If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` on each commit
+to ensure your code is up to par. If you decide later that this behavior is undesirable,
+simply delete the `pre-commit` file from .git/hooks."
+    );
+
+    let should_install = loop {
+        print!("Would you like to install the git hook?: [y/N] ");
+        io::stdout().flush()?;
+        input.clear();
+        io::stdin().read_line(&mut input)?;
+        break match input.trim().to_lowercase().as_str() {
+            "y" | "yes" => true,
+            "n" | "no" | "" => false,
+            _ => {
+                println!("error: unrecognized option '{}'", input.trim());
+                println!("note: press Ctrl+C to exit");
+                continue;
+            }
+        };
+    };
+
+    Ok(if should_install {
+        let src = src_path.join("src").join("etc").join("pre-commit.sh");
+        let dst = src_path.join(".git").join("hooks").join("pre-commit");
+        match fs::hard_link(src, dst) {
+            Err(e) => println!(
+                "x.py encountered an error -- do you already have the git hook installed?\n{}",
+                e
+            ),
+            Ok(_) => println!("Linked `src/etc/pre-commit.sh` to `.git/hooks/pre-commit`"),
+        };
+    } else {
+        println!("Ok, skipping installation!");
+    })
+}
diff --git a/src/etc/pre-commit.sh b/src/etc/pre-commit.sh
new file mode 100755
index 00000000000..5c5922a7e63
--- /dev/null
+++ b/src/etc/pre-commit.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+#
+# Call `tidy --bless` before each commit
+# Copy this scripts to .git/hooks to activate,
+# and remove it from .git/hooks to deactivate.
+#
+
+set -Eeuo pipefail
+
+ROOT_DIR="$(git rev-parse --show-toplevel)";
+COMMAND="$ROOT_DIR/x.py test tidy --bless";
+
+if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
+  COMMAND="python $COMMAND"
+fi
+
+echo "Running pre-commit script '$COMMAND'";
+
+cd "$ROOT_DIR"
+
+$COMMAND;