Skip to content

Commit 91f9bc2

Browse files
committed
Refactor xtasks
1 parent b02576d commit 91f9bc2

File tree

5 files changed

+290
-281
lines changed

5 files changed

+290
-281
lines changed

xtask/src/help.rs

Lines changed: 0 additions & 33 deletions
This file was deleted.

xtask/src/install.rs

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
//! Installs rust-analyzer langauge server and/or editor plugin.
2+
3+
use std::{env, path::PathBuf, str};
4+
5+
use anyhow::{Context, Result};
6+
7+
use crate::{run, run_with_output, Cmd};
8+
9+
// Latest stable, feel free to send a PR if this lags behind.
10+
const REQUIRED_RUST_VERSION: u32 = 40;
11+
12+
pub struct InstallCmd {
13+
pub client: Option<ClientOpt>,
14+
pub server: Option<ServerOpt>,
15+
}
16+
17+
pub enum ClientOpt {
18+
VsCode,
19+
}
20+
21+
pub struct ServerOpt {
22+
pub jemalloc: bool,
23+
}
24+
25+
impl InstallCmd {
26+
pub fn run(self) -> Result<()> {
27+
if cfg!(target_os = "macos") {
28+
fix_path_for_mac().context("Fix path for mac")?
29+
}
30+
if let Some(server) = self.server {
31+
install_server(server).context("install server")?;
32+
}
33+
if let Some(client) = self.client {
34+
install_client(client).context("install client")?;
35+
}
36+
Ok(())
37+
}
38+
}
39+
40+
fn fix_path_for_mac() -> Result<()> {
41+
let mut vscode_path: Vec<PathBuf> = {
42+
const COMMON_APP_PATH: &str =
43+
r"/Applications/Visual Studio Code.app/Contents/Resources/app/bin";
44+
const ROOT_DIR: &str = "";
45+
let home_dir = match env::var("HOME") {
46+
Ok(home) => home,
47+
Err(e) => anyhow::bail!("Failed getting HOME from environment with error: {}.", e),
48+
};
49+
50+
[ROOT_DIR, &home_dir]
51+
.iter()
52+
.map(|dir| String::from(*dir) + COMMON_APP_PATH)
53+
.map(PathBuf::from)
54+
.filter(|path| path.exists())
55+
.collect()
56+
};
57+
58+
if !vscode_path.is_empty() {
59+
let vars = match env::var_os("PATH") {
60+
Some(path) => path,
61+
None => anyhow::bail!("Could not get PATH variable from env."),
62+
};
63+
64+
let mut paths = env::split_paths(&vars).collect::<Vec<_>>();
65+
paths.append(&mut vscode_path);
66+
let new_paths = env::join_paths(paths).context("build env PATH")?;
67+
env::set_var("PATH", &new_paths);
68+
}
69+
70+
Ok(())
71+
}
72+
73+
fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
74+
let npm_version = Cmd {
75+
unix: r"npm --version",
76+
windows: r"cmd.exe /c npm --version",
77+
work_dir: "./editors/code",
78+
}
79+
.run();
80+
81+
if npm_version.is_err() {
82+
eprintln!("\nERROR: `npm --version` failed, `npm` is required to build the VS Code plugin")
83+
}
84+
85+
Cmd { unix: r"npm install", windows: r"cmd.exe /c npm install", work_dir: "./editors/code" }
86+
.run()?;
87+
Cmd {
88+
unix: r"npm run package --scripts-prepend-node-path",
89+
windows: r"cmd.exe /c npm run package",
90+
work_dir: "./editors/code",
91+
}
92+
.run()?;
93+
94+
let code_binary = ["code", "code-insiders", "codium"].iter().find(|bin| {
95+
Cmd {
96+
unix: &format!("{} --version", bin),
97+
windows: &format!("cmd.exe /c {}.cmd --version", bin),
98+
work_dir: "./editors/code",
99+
}
100+
.run()
101+
.is_ok()
102+
});
103+
104+
let code_binary = match code_binary {
105+
Some(it) => it,
106+
None => anyhow::bail!("Can't execute `code --version`. Perhaps it is not in $PATH?"),
107+
};
108+
109+
Cmd {
110+
unix: &format!(r"{} --install-extension ./ra-lsp-0.0.1.vsix --force", code_binary),
111+
windows: &format!(
112+
r"cmd.exe /c {}.cmd --install-extension ./ra-lsp-0.0.1.vsix --force",
113+
code_binary
114+
),
115+
work_dir: "./editors/code",
116+
}
117+
.run()?;
118+
119+
let output = Cmd {
120+
unix: &format!(r"{} --list-extensions", code_binary),
121+
windows: &format!(r"cmd.exe /c {}.cmd --list-extensions", code_binary),
122+
work_dir: ".",
123+
}
124+
.run_with_output()?;
125+
126+
if !str::from_utf8(&output.stdout)?.contains("ra-lsp") {
127+
anyhow::bail!(
128+
"Could not install the Visual Studio Code extension. \
129+
Please make sure you have at least NodeJS 10.x together with the latest version of VS Code installed and try again."
130+
);
131+
}
132+
133+
Ok(())
134+
}
135+
136+
fn install_server(opts: ServerOpt) -> Result<()> {
137+
let mut old_rust = false;
138+
if let Ok(output) = run_with_output("cargo --version", ".") {
139+
if let Ok(stdout) = String::from_utf8(output.stdout) {
140+
println!("{}", stdout);
141+
if !check_version(&stdout, REQUIRED_RUST_VERSION) {
142+
old_rust = true;
143+
}
144+
}
145+
}
146+
147+
if old_rust {
148+
eprintln!(
149+
"\nWARNING: at least rust 1.{}.0 is required to compile rust-analyzer\n",
150+
REQUIRED_RUST_VERSION,
151+
)
152+
}
153+
154+
let res = if opts.jemalloc {
155+
run("cargo install --path crates/ra_lsp_server --locked --force --features jemalloc", ".")
156+
} else {
157+
run("cargo install --path crates/ra_lsp_server --locked --force", ".")
158+
};
159+
160+
if res.is_err() && old_rust {
161+
eprintln!(
162+
"\nWARNING: at least rust 1.{}.0 is required to compile rust-analyzer\n",
163+
REQUIRED_RUST_VERSION,
164+
)
165+
}
166+
167+
res
168+
}
169+
170+
fn check_version(version_output: &str, min_minor_version: u32) -> bool {
171+
// Parse second the number out of
172+
// cargo 1.39.0-beta (1c6ec66d5 2019-09-30)
173+
let minor: Option<u32> = version_output.split('.').nth(1).and_then(|it| it.parse().ok());
174+
match minor {
175+
None => true,
176+
Some(minor) => minor >= min_minor_version,
177+
}
178+
}

xtask/src/lib.rs

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
//! FIXME: write short doc here
22
33
pub mod codegen;
4+
pub mod install;
5+
pub mod pre_commit;
46
mod ast_src;
57

68
use anyhow::Context;
79
pub use anyhow::Result;
810
use std::{
9-
env, fs,
10-
io::{Error as IoError, ErrorKind},
11+
env,
1112
path::{Path, PathBuf},
1213
process::{Command, Output, Stdio},
1314
};
@@ -79,23 +80,11 @@ pub fn run_rustfmt(mode: Mode) -> Result<()> {
7980
Ok(())
8081
}
8182

82-
pub fn install_rustfmt() -> Result<()> {
83+
fn install_rustfmt() -> Result<()> {
8384
run(&format!("rustup toolchain install {}", TOOLCHAIN), ".")?;
8485
run(&format!("rustup component add rustfmt --toolchain {}", TOOLCHAIN), ".")
8586
}
8687

87-
pub fn install_pre_commit_hook() -> Result<()> {
88-
let result_path =
89-
PathBuf::from(format!("./.git/hooks/pre-commit{}", std::env::consts::EXE_SUFFIX));
90-
if !result_path.exists() {
91-
let me = std::env::current_exe()?;
92-
fs::copy(me, result_path)?;
93-
} else {
94-
Err(IoError::new(ErrorKind::AlreadyExists, "Git hook already created"))?;
95-
}
96-
Ok(())
97-
}
98-
9988
pub fn run_clippy() -> Result<()> {
10089
match Command::new("rustup")
10190
.args(&["run", TOOLCHAIN, "--", "cargo", "clippy", "--version"])
@@ -144,28 +133,6 @@ pub fn run_fuzzer() -> Result<()> {
144133
run("rustup run nightly -- cargo fuzz run parser", "./crates/ra_syntax")
145134
}
146135

147-
pub fn reformat_staged_files() -> Result<()> {
148-
run_rustfmt(Mode::Overwrite)?;
149-
let root = project_root();
150-
let output = Command::new("git")
151-
.arg("diff")
152-
.arg("--diff-filter=MAR")
153-
.arg("--name-only")
154-
.arg("--cached")
155-
.current_dir(&root)
156-
.output()?;
157-
if !output.status.success() {
158-
anyhow::bail!(
159-
"`git diff --diff-filter=MAR --name-only --cached` exited with {}",
160-
output.status
161-
);
162-
}
163-
for line in String::from_utf8(output.stdout)?.lines() {
164-
run(&format!("git update-index --add {}", root.join(line).to_string_lossy()), ".")?;
165-
}
166-
Ok(())
167-
}
168-
169136
fn do_run<F>(cmdline: &str, dir: &str, mut f: F) -> Result<Output>
170137
where
171138
F: FnMut(&mut Command),

0 commit comments

Comments
 (0)