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 --- .cargo/config | 1 + crates/ra_editor/src/typing.rs | 2 +- crates/tools/src/lib.rs | 29 ++++++++++++++++++++++++++++- crates/tools/src/main.rs | 17 +++++++++++------ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/.cargo/config b/.cargo/config index c0be661fd..79f1dc389 100644 --- a/.cargo/config +++ b/.cargo/config @@ -4,6 +4,7 @@ gen-syntax = "run --package tools -- gen-syntax" gen-tests = "run --package tools -- gen-tests" install-code = "run --package tools -- install-code" format = "run --package tools -- format" +format-hook = "run --package tools -- format-hook" render-test = "run --package ra_cli -- render-test" parse = "run --package ra_cli -- parse" 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(-) 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 1e554d551f1510780377158fda8d86ff8c8266fe Mon Sep 17 00:00:00 2001 From: DJMcNab <36049421+DJMcNab@users.noreply.github.com> Date: Sun, 9 Dec 2018 10:41:42 +0000 Subject: Fix alignment of `.cargo/config` --- .cargo/config | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.cargo/config b/.cargo/config index 79f1dc389..afb569b75 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,10 +1,10 @@ [alias] # Automatically generates the ast and syntax kinds files -gen-syntax = "run --package tools -- gen-syntax" +gen-syntax = "run --package tools -- gen-syntax" gen-tests = "run --package tools -- gen-tests" install-code = "run --package tools -- install-code" -format = "run --package tools -- format" -format-hook = "run --package tools -- format-hook" +format = "run --package tools -- format" +format-hook = "run --package tools -- format-hook" -render-test = "run --package ra_cli -- render-test" -parse = "run --package ra_cli -- parse" +render-test = "run --package ra_cli -- render-test" +parse = "run --package ra_cli -- parse" -- 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 --- .cargo/config | 10 +++++----- crates/tools/src/bin/pre-commit.rs | 37 +++++++++++++++++++++++++++++++++++++ crates/tools/src/lib.rs | 32 ++++++++++---------------------- 3 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 crates/tools/src/bin/pre-commit.rs diff --git a/.cargo/config b/.cargo/config index afb569b75..c319d33f2 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,10 +1,10 @@ [alias] # Automatically generates the ast and syntax kinds files -gen-syntax = "run --package tools -- gen-syntax" -gen-tests = "run --package tools -- gen-tests" -install-code = "run --package tools -- install-code" -format = "run --package tools -- format" -format-hook = "run --package tools -- format-hook" +gen-syntax = "run --package tools --bin tools -- gen-syntax" +gen-tests = "run --package tools --bin tools -- gen-tests" +install-code = "run --package tools --bin tools -- install-code" +format = "run --package tools --bin tools -- format" +format-hook = "run --package tools --bin tools -- format-hook" render-test = "run --package ra_cli -- render-test" parse = "run --package ra_cli -- parse" 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