diff options
Diffstat (limited to 'xtask/src/lib.rs')
-rw-r--r-- | xtask/src/lib.rs | 126 |
1 files changed, 42 insertions, 84 deletions
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index 40a6682be..e46c21db7 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs | |||
@@ -1,17 +1,22 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | mod cmd; | ||
4 | pub mod install; | ||
5 | pub mod pre_commit; | ||
6 | |||
3 | pub mod codegen; | 7 | pub mod codegen; |
8 | mod ast_src; | ||
4 | 9 | ||
5 | use anyhow::Context; | 10 | use anyhow::Context; |
6 | pub use anyhow::Result; | ||
7 | use std::{ | 11 | use std::{ |
8 | env, fs, | 12 | env, fs, |
9 | io::{Error as IoError, ErrorKind}, | ||
10 | path::{Path, PathBuf}, | 13 | path::{Path, PathBuf}, |
11 | process::{Command, Output, Stdio}, | 14 | process::{Command, Stdio}, |
12 | }; | 15 | }; |
13 | 16 | ||
14 | use crate::codegen::Mode; | 17 | use crate::{cmd::run, codegen::Mode}; |
18 | |||
19 | pub use anyhow::Result; | ||
15 | 20 | ||
16 | const TOOLCHAIN: &str = "stable"; | 21 | const TOOLCHAIN: &str = "stable"; |
17 | 22 | ||
@@ -25,40 +30,6 @@ pub fn project_root() -> PathBuf { | |||
25 | .to_path_buf() | 30 | .to_path_buf() |
26 | } | 31 | } |
27 | 32 | ||
28 | pub struct Cmd<'a> { | ||
29 | pub unix: &'a str, | ||
30 | pub windows: &'a str, | ||
31 | pub work_dir: &'a str, | ||
32 | } | ||
33 | |||
34 | impl Cmd<'_> { | ||
35 | pub fn run(self) -> Result<()> { | ||
36 | if cfg!(windows) { | ||
37 | run(self.windows, self.work_dir) | ||
38 | } else { | ||
39 | run(self.unix, self.work_dir) | ||
40 | } | ||
41 | } | ||
42 | pub fn run_with_output(self) -> Result<Output> { | ||
43 | if cfg!(windows) { | ||
44 | run_with_output(self.windows, self.work_dir) | ||
45 | } else { | ||
46 | run_with_output(self.unix, self.work_dir) | ||
47 | } | ||
48 | } | ||
49 | } | ||
50 | |||
51 | pub fn run(cmdline: &str, dir: &str) -> Result<()> { | ||
52 | do_run(cmdline, dir, |c| { | ||
53 | c.stdout(Stdio::inherit()); | ||
54 | }) | ||
55 | .map(|_| ()) | ||
56 | } | ||
57 | |||
58 | pub fn run_with_output(cmdline: &str, dir: &str) -> Result<Output> { | ||
59 | do_run(cmdline, dir, |_| {}) | ||
60 | } | ||
61 | |||
62 | pub fn run_rustfmt(mode: Mode) -> Result<()> { | 33 | pub fn run_rustfmt(mode: Mode) -> Result<()> { |
63 | match Command::new("rustup") | 34 | match Command::new("rustup") |
64 | .args(&["run", TOOLCHAIN, "--", "cargo", "fmt", "--version"]) | 35 | .args(&["run", TOOLCHAIN, "--", "cargo", "fmt", "--version"]) |
@@ -78,23 +49,11 @@ pub fn run_rustfmt(mode: Mode) -> Result<()> { | |||
78 | Ok(()) | 49 | Ok(()) |
79 | } | 50 | } |
80 | 51 | ||
81 | pub fn install_rustfmt() -> Result<()> { | 52 | fn install_rustfmt() -> Result<()> { |
82 | run(&format!("rustup toolchain install {}", TOOLCHAIN), ".")?; | 53 | run(&format!("rustup toolchain install {}", TOOLCHAIN), ".")?; |
83 | run(&format!("rustup component add rustfmt --toolchain {}", TOOLCHAIN), ".") | 54 | run(&format!("rustup component add rustfmt --toolchain {}", TOOLCHAIN), ".") |
84 | } | 55 | } |
85 | 56 | ||
86 | pub fn install_pre_commit_hook() -> Result<()> { | ||
87 | let result_path = | ||
88 | PathBuf::from(format!("./.git/hooks/pre-commit{}", std::env::consts::EXE_SUFFIX)); | ||
89 | if !result_path.exists() { | ||
90 | let me = std::env::current_exe()?; | ||
91 | fs::copy(me, result_path)?; | ||
92 | } else { | ||
93 | Err(IoError::new(ErrorKind::AlreadyExists, "Git hook already created"))?; | ||
94 | } | ||
95 | Ok(()) | ||
96 | } | ||
97 | |||
98 | pub fn run_clippy() -> Result<()> { | 57 | pub fn run_clippy() -> Result<()> { |
99 | match Command::new("rustup") | 58 | match Command::new("rustup") |
100 | .args(&["run", TOOLCHAIN, "--", "cargo", "clippy", "--version"]) | 59 | .args(&["run", TOOLCHAIN, "--", "cargo", "clippy", "--version"]) |
@@ -124,7 +83,7 @@ pub fn run_clippy() -> Result<()> { | |||
124 | Ok(()) | 83 | Ok(()) |
125 | } | 84 | } |
126 | 85 | ||
127 | pub fn install_clippy() -> Result<()> { | 86 | fn install_clippy() -> Result<()> { |
128 | run(&format!("rustup toolchain install {}", TOOLCHAIN), ".")?; | 87 | run(&format!("rustup toolchain install {}", TOOLCHAIN), ".")?; |
129 | run(&format!("rustup component add clippy --toolchain {}", TOOLCHAIN), ".") | 88 | run(&format!("rustup component add clippy --toolchain {}", TOOLCHAIN), ".") |
130 | } | 89 | } |
@@ -143,41 +102,40 @@ pub fn run_fuzzer() -> Result<()> { | |||
143 | run("rustup run nightly -- cargo fuzz run parser", "./crates/ra_syntax") | 102 | run("rustup run nightly -- cargo fuzz run parser", "./crates/ra_syntax") |
144 | } | 103 | } |
145 | 104 | ||
146 | pub fn reformat_staged_files() -> Result<()> { | 105 | /// Cleans the `./target` dir after the build such that only |
147 | run_rustfmt(Mode::Overwrite)?; | 106 | /// dependencies are cached on CI. |
148 | let root = project_root(); | 107 | pub fn run_pre_cache() -> Result<()> { |
149 | let output = Command::new("git") | 108 | let slow_tests_cookie = Path::new("./target/.slow_tests_cookie"); |
150 | .arg("diff") | 109 | if !slow_tests_cookie.exists() { |
151 | .arg("--diff-filter=MAR") | 110 | panic!("slow tests were skipped on CI!") |
152 | .arg("--name-only") | ||
153 | .arg("--cached") | ||
154 | .current_dir(&root) | ||
155 | .output()?; | ||
156 | if !output.status.success() { | ||
157 | anyhow::bail!( | ||
158 | "`git diff --diff-filter=MAR --name-only --cached` exited with {}", | ||
159 | output.status | ||
160 | ); | ||
161 | } | 111 | } |
162 | for line in String::from_utf8(output.stdout)?.lines() { | 112 | rm_rf(slow_tests_cookie)?; |
163 | run(&format!("git update-index --add {}", root.join(line).to_string_lossy()), ".")?; | 113 | |
114 | for entry in Path::new("./target/debug").read_dir()? { | ||
115 | let entry = entry?; | ||
116 | if entry.file_type().map(|it| it.is_file()).ok() == Some(true) { | ||
117 | // Can't delete yourself on windows :-( | ||
118 | if !entry.path().ends_with("xtask.exe") { | ||
119 | rm_rf(&entry.path())? | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | fs::remove_file("./target/.rustc_info.json")?; | ||
125 | let to_delete = ["ra_", "heavy_test"]; | ||
126 | for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() { | ||
127 | for entry in Path::new(dir).read_dir()? { | ||
128 | let entry = entry?; | ||
129 | if to_delete.iter().any(|&it| entry.path().display().to_string().contains(it)) { | ||
130 | rm_rf(&entry.path())? | ||
131 | } | ||
132 | } | ||
164 | } | 133 | } |
134 | |||
165 | Ok(()) | 135 | Ok(()) |
166 | } | 136 | } |
167 | 137 | ||
168 | fn do_run<F>(cmdline: &str, dir: &str, mut f: F) -> Result<Output> | 138 | fn rm_rf(path: &Path) -> Result<()> { |
169 | where | 139 | if path.is_file() { fs::remove_file(path) } else { fs::remove_dir_all(path) } |
170 | F: FnMut(&mut Command), | 140 | .with_context(|| format!("failed to remove {:?}", path)) |
171 | { | ||
172 | eprintln!("\nwill run: {}", cmdline); | ||
173 | let proj_dir = project_root().join(dir); | ||
174 | let mut args = cmdline.split_whitespace(); | ||
175 | let exec = args.next().unwrap(); | ||
176 | let mut cmd = Command::new(exec); | ||
177 | f(cmd.args(args).current_dir(proj_dir).stderr(Stdio::inherit())); | ||
178 | let output = cmd.output().with_context(|| format!("running `{}`", cmdline))?; | ||
179 | if !output.status.success() { | ||
180 | anyhow::bail!("`{}` exited with {}", cmdline, output.status); | ||
181 | } | ||
182 | Ok(output) | ||
183 | } | 141 | } |