From e823db06985d6782ff3803d3a4dea67a3c18426c Mon Sep 17 00:00:00 2001 From: DJMcNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 9 Dec 2018 10:29:13 +0000 Subject: Implement and test format hook --- crates/ra_editor/src/typing.rs | 2 +- crates/tools/src/lib.rs | 29 ++++++++++++++++++++++++++++- crates/tools/src/main.rs | 17 +++++++++++------ 3 files changed, 40 insertions(+), 8 deletions(-) (limited to 'crates') diff --git a/crates/ra_editor/src/typing.rs b/crates/ra_editor/src/typing.rs index 9703e0371..01acdda7c 100644 --- a/crates/ra_editor/src/typing.rs +++ b/crates/ra_editor/src/typing.rs @@ -20,7 +20,7 @@ pub fn join_lines(file: &SourceFileNode, range: TextRange) -> LocalEdit { return LocalEdit { edit: EditBuilder::new().finish(), cursor_position: None, - } + }; } Some(pos) => pos, }; diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index 674b9d11f..d6c448f3b 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs @@ -1,7 +1,11 @@ use std::{ path::{Path, PathBuf}, process::{Command, Stdio}, + fs::OpenOptions, + io::{Write, Error, ErrorKind} }; +#[cfg(unix)] +use std::os::unix::fs::OpenOptionsExt; use failure::bail; use itertools::Itertools; @@ -39,7 +43,7 @@ pub fn collect_tests(s: &str) -> Vec<(usize, Test)> { let (start_line, name) = loop { match block.next() { Some((idx, line)) if line.starts_with("test ") => { - break (idx, line["test ".len()..].to_string()) + break (idx, line["test ".len()..].to_string()); } Some(_) => (), None => continue 'outer, @@ -116,3 +120,26 @@ fn install_rustfmt() -> Result<()> { ".", ) } + +pub fn install_format_hook() -> Result<()> { + let path = Path::new("./.git/hooks/pre-commit"); + if !path.exists() { + let mut open_options = OpenOptions::new(); + #[cfg(unix)] + { + // Set as executable + open_options.mode(0o770); + } + let mut file = open_options.write(true).create(true).open(path)?; + write!( + file, + r#"#!/bin/sh + +cargo format +git update-index --add ."# + )?; + } else { + return Err(Error::new(ErrorKind::AlreadyExists, "Git hook already created").into()); + } + Ok(()) +} diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs index 36a7c83e2..9e90ac5c2 100644 --- a/crates/tools/src/main.rs +++ b/crates/tools/src/main.rs @@ -7,7 +7,7 @@ use std::{ use clap::{App, Arg, SubCommand}; use failure::bail; -use tools::{collect_tests, generate, run, run_rustfmt, Mode, Overwrite, Result, Test, Verify}; +use tools::{collect_tests, generate, install_format_hook, run, run_rustfmt, Mode, Overwrite, Result, Test, Verify}; const GRAMMAR_DIR: &str = "./crates/ra_syntax/src/grammar"; const INLINE_TESTS_DIR: &str = "./crates/ra_syntax/tests/data/parser/inline"; @@ -25,17 +25,22 @@ fn main() -> Result<()> { .subcommand(SubCommand::with_name("gen-tests")) .subcommand(SubCommand::with_name("install-code")) .subcommand(SubCommand::with_name("format")) + .subcommand(SubCommand::with_name("format-hook")) .get_matches(); let mode = if matches.is_present("verify") { Verify } else { Overwrite }; - match matches.subcommand() { - ("install-code", _) => install_code_extension()?, - ("gen-tests", _) => gen_tests(mode)?, - ("gen-syntax", _) => generate(Overwrite)?, - ("format", _) => run_rustfmt(Overwrite)?, + match matches + .subcommand_name() + .expect("Subcommand must be specified") + { + "install-code" => install_code_extension()?, + "gen-tests" => gen_tests(mode)?, + "gen-syntax" => generate(Overwrite)?, + "format" => run_rustfmt(mode)?, + "format-hook" => install_format_hook()?, _ => unreachable!(), } Ok(()) -- cgit v1.2.3 From 279ff4927ade19c51553ea36147605c6ff4347ae Mon Sep 17 00:00:00 2001 From: DJMcNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 9 Dec 2018 10:37:04 +0000 Subject: Update hook to not add unstaged files --- crates/tools/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index d6c448f3b..bc550c597 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs @@ -136,7 +136,9 @@ pub fn install_format_hook() -> Result<()> { r#"#!/bin/sh cargo format -git update-index --add ."# +for path in $( git diff --name-only --cached ); do + git update-index --add $path +done"# )?; } else { return Err(Error::new(ErrorKind::AlreadyExists, "Git hook already created").into()); -- cgit v1.2.3 From cbce28a348ebb5db646cfc5cd3305c6bce80e915 Mon Sep 17 00:00:00 2001 From: DJMcNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 9 Dec 2018 12:27:13 +0000 Subject: Reimplement format-hook using a rust binary --- crates/tools/src/bin/pre-commit.rs | 37 +++++++++++++++++++++++++++++++++++++ crates/tools/src/lib.rs | 32 ++++++++++---------------------- 2 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 crates/tools/src/bin/pre-commit.rs (limited to 'crates') diff --git a/crates/tools/src/bin/pre-commit.rs b/crates/tools/src/bin/pre-commit.rs new file mode 100644 index 000000000..ca1909479 --- /dev/null +++ b/crates/tools/src/bin/pre-commit.rs @@ -0,0 +1,37 @@ +use std::{ + process::{Command}, +}; + +use tools::{Result, run_rustfmt, run, project_root}; +use failure::bail; + +fn main() -> tools::Result<()> { + run_rustfmt(tools::Overwrite)?; + update_staged() +} + +fn update_staged() -> Result<()> { + let root = project_root(); + let output = Command::new("git") + .arg("diff") + .arg("--name-only") + .arg("--cached") + .current_dir(&root) + .output()?; + if !output.status.success() { + bail!( + "`git diff --name-only --cached` exited with {}", + output.status + ); + } + for line in String::from_utf8(output.stdout)?.lines() { + run( + &format!( + "git update-index --add {}", + root.join(line).to_string_lossy() + ), + ".", + )?; + } + Ok(()) +} diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index bc550c597..95d6e08f0 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs @@ -1,11 +1,9 @@ use std::{ path::{Path, PathBuf}, process::{Command, Stdio}, - fs::OpenOptions, - io::{Write, Error, ErrorKind} + fs::copy, + io::{Error, ErrorKind} }; -#[cfg(unix)] -use std::os::unix::fs::OpenOptionsExt; use failure::bail; use itertools::Itertools; @@ -69,7 +67,7 @@ pub fn generate(mode: Mode) -> Result<()> { } pub fn project_root() -> PathBuf { - Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap()) + Path::new(&env!("CARGO_MANIFEST_DIR")) .ancestors() .nth(2) .unwrap() @@ -122,24 +120,14 @@ fn install_rustfmt() -> Result<()> { } pub fn install_format_hook() -> Result<()> { - let path = Path::new("./.git/hooks/pre-commit"); - if !path.exists() { - let mut open_options = OpenOptions::new(); - #[cfg(unix)] - { - // Set as executable - open_options.mode(0o770); + let result_path = Path::new("./.git/hooks/pre-commit"); + if !result_path.exists() { + run("cargo build --package tools --bin pre-commit", ".")?; + if cfg!(windows) { + copy("./target/debug/pre-commit.exe", result_path)?; + } else { + copy("./target/debug/pre-commit", result_path)?; } - let mut file = open_options.write(true).create(true).open(path)?; - write!( - file, - r#"#!/bin/sh - -cargo format -for path in $( git diff --name-only --cached ); do - git update-index --add $path -done"# - )?; } else { return Err(Error::new(ErrorKind::AlreadyExists, "Git hook already created").into()); } -- cgit v1.2.3