mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-26 11:55:04 +00:00
Switch from not_bash to xshell
This commit is contained in:
parent
f0412da4a2
commit
49a90d4c31
14 changed files with 181 additions and 325 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -421,12 +421,6 @@ dependencies = [
|
||||||
"toolchain",
|
"toolchain",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fs-err"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bcd1163ae48bda72a20ae26d66a04d3094135cadab911cff418ae5e33f253431"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fsevent"
|
name = "fsevent"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
|
@ -1920,17 +1914,32 @@ dependencies = [
|
||||||
"winapi-build",
|
"winapi-build",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xshell"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f7f756f2faab73adb00db44db716598ab2c9e4bce4a875c053022291bd3cab4"
|
||||||
|
dependencies = [
|
||||||
|
"xshell-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xshell-macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51b020c2f3132b34067e2f6ebc58f0f210624898713a8186b8cdb75d3b8c3001"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xtask"
|
name = "xtask"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"flate2",
|
"flate2",
|
||||||
"fs-err",
|
|
||||||
"pico-args",
|
"pico-args",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"ungrammar",
|
"ungrammar",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"write-json",
|
"write-json",
|
||||||
|
"xshell",
|
||||||
]
|
]
|
||||||
|
|
|
@ -18,5 +18,5 @@ quote = "1.0.2"
|
||||||
ungrammar = "1.1.3"
|
ungrammar = "1.1.3"
|
||||||
walkdir = "2.3.1"
|
walkdir = "2.3.1"
|
||||||
write-json = "0.1.0"
|
write-json = "0.1.0"
|
||||||
fs-err = "2.3"
|
xshell = "0.1"
|
||||||
# Avoid adding more dependencies to this crate
|
# Avoid adding more dependencies to this crate
|
||||||
|
|
|
@ -15,12 +15,9 @@ use std::{
|
||||||
fmt, mem,
|
fmt, mem,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
use xshell::{cmd, pushenv, read_file, write_file};
|
||||||
|
|
||||||
use crate::{
|
use crate::{ensure_rustfmt, project_root, Result};
|
||||||
ensure_rustfmt,
|
|
||||||
not_bash::{fs2, pushenv, run},
|
|
||||||
project_root, Result,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
gen_assists_docs::{generate_assists_docs, generate_assists_tests},
|
gen_assists_docs::{generate_assists_docs, generate_assists_tests},
|
||||||
|
@ -57,7 +54,7 @@ impl CodegenCmd {
|
||||||
/// A helper to update file on disk if it has changed.
|
/// A helper to update file on disk if it has changed.
|
||||||
/// With verify = false,
|
/// With verify = false,
|
||||||
fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> {
|
fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> {
|
||||||
match fs2::read_to_string(path) {
|
match read_file(path) {
|
||||||
Ok(old_contents) if normalize(&old_contents) == normalize(contents) => {
|
Ok(old_contents) if normalize(&old_contents) == normalize(contents) => {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -67,7 +64,7 @@ fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> {
|
||||||
anyhow::bail!("`{}` is not up-to-date", path.display());
|
anyhow::bail!("`{}` is not up-to-date", path.display());
|
||||||
}
|
}
|
||||||
eprintln!("updating {}", path.display());
|
eprintln!("updating {}", path.display());
|
||||||
fs2::write(path, contents)?;
|
write_file(path, contents)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
||||||
fn normalize(s: &str) -> String {
|
fn normalize(s: &str) -> String {
|
||||||
|
@ -80,10 +77,10 @@ const PREAMBLE: &str = "Generated file, do not edit by hand, see `xtask/src/code
|
||||||
fn reformat(text: &str) -> Result<String> {
|
fn reformat(text: &str) -> Result<String> {
|
||||||
let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
|
let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
|
||||||
ensure_rustfmt()?;
|
ensure_rustfmt()?;
|
||||||
let stdout = run!(
|
let rustfmt_toml = project_root().join("rustfmt.toml");
|
||||||
"rustfmt --config-path {} --config fn_single_line=true", project_root().join("rustfmt.toml").display();
|
let stdout = cmd!("rustfmt --config-path {rustfmt_toml} --config fn_single_line=true")
|
||||||
<text.as_bytes()
|
.stdin(text)
|
||||||
)?;
|
.read()?;
|
||||||
Ok(format!("//! {}\n\n{}\n", PREAMBLE, stdout))
|
Ok(format!("//! {}\n\n{}\n", PREAMBLE, stdout))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,13 @@ use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
use xshell::{cmd, read_file};
|
||||||
|
|
||||||
use crate::{
|
use crate::codegen::{project_root, reformat, update, Mode, Result};
|
||||||
codegen::{project_root, reformat, update, Mode, Result},
|
|
||||||
not_bash::{fs2, run},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn generate_features(mode: Mode) -> Result<()> {
|
pub fn generate_features(mode: Mode) -> Result<()> {
|
||||||
if !Path::new("./target/rust").exists() {
|
if !Path::new("./target/rust").exists() {
|
||||||
run!("git clone https://github.com/rust-lang/rust ./target/rust")?;
|
cmd!("git clone https://github.com/rust-lang/rust ./target/rust").run()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let contents = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?;
|
let contents = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?;
|
||||||
|
@ -34,7 +32,7 @@ fn generate_descriptor(src_dir: PathBuf) -> Result<String> {
|
||||||
.map(|entry| {
|
.map(|entry| {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_");
|
let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_");
|
||||||
let doc = fs2::read_to_string(path).unwrap();
|
let doc = read_file(path).unwrap();
|
||||||
|
|
||||||
quote! { LintCompletion { label: #feature_ident, description: #doc } }
|
quote! { LintCompletion { label: #feature_ident, description: #doc } }
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use flate2::{write::GzEncoder, Compression};
|
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
fs::File,
|
fs::File,
|
||||||
|
@ -7,11 +6,10 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use flate2::{write::GzEncoder, Compression};
|
||||||
|
use xshell::{cmd, cp, mkdir_p, pushd, read_file, rm_rf, write_file};
|
||||||
|
|
||||||
use crate::{
|
use crate::{date_iso, project_root};
|
||||||
not_bash::{date_iso, fs2, pushd, rm_rf, run},
|
|
||||||
project_root,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct DistCmd {
|
pub struct DistCmd {
|
||||||
pub nightly: bool,
|
pub nightly: bool,
|
||||||
|
@ -22,7 +20,7 @@ impl DistCmd {
|
||||||
pub fn run(self) -> Result<()> {
|
pub fn run(self) -> Result<()> {
|
||||||
let dist = project_root().join("dist");
|
let dist = project_root().join("dist");
|
||||||
rm_rf(&dist)?;
|
rm_rf(&dist)?;
|
||||||
fs2::create_dir_all(&dist)?;
|
mkdir_p(&dist)?;
|
||||||
|
|
||||||
if let Some(version) = self.client_version {
|
if let Some(version) = self.client_version {
|
||||||
let release_tag = if self.nightly { "nightly".to_string() } else { date_iso()? };
|
let release_tag = if self.nightly { "nightly".to_string() } else { date_iso()? };
|
||||||
|
@ -34,7 +32,7 @@ impl DistCmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dist_client(version: &str, release_tag: &str) -> Result<()> {
|
fn dist_client(version: &str, release_tag: &str) -> Result<()> {
|
||||||
let _d = pushd("./editors/code");
|
let _d = pushd("./editors/code")?;
|
||||||
let nightly = release_tag == "nightly";
|
let nightly = release_tag == "nightly";
|
||||||
|
|
||||||
let mut patch = Patch::new("./package.json")?;
|
let mut patch = Patch::new("./package.json")?;
|
||||||
|
@ -54,20 +52,16 @@ fn dist_client(version: &str, release_tag: &str) -> Result<()> {
|
||||||
}
|
}
|
||||||
patch.commit()?;
|
patch.commit()?;
|
||||||
|
|
||||||
run!("npm ci")?;
|
cmd!("npm ci").run()?;
|
||||||
run!("npx vsce package -o ../../dist/rust-analyzer.vsix")?;
|
cmd!("npx vsce package -o ../../dist/rust-analyzer.vsix").run()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dist_server() -> Result<()> {
|
fn dist_server() -> Result<()> {
|
||||||
if cfg!(target_os = "linux") {
|
if cfg!(target_os = "linux") {
|
||||||
env::set_var("CC", "clang");
|
env::set_var("CC", "clang");
|
||||||
run!(
|
|
||||||
"cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --release"
|
|
||||||
)?;
|
|
||||||
} else {
|
|
||||||
run!("cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --release")?;
|
|
||||||
}
|
}
|
||||||
|
cmd!("cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --release").run()?;
|
||||||
|
|
||||||
let (src, dst) = if cfg!(target_os = "linux") {
|
let (src, dst) = if cfg!(target_os = "linux") {
|
||||||
("./target/release/rust-analyzer", "./dist/rust-analyzer-linux")
|
("./target/release/rust-analyzer", "./dist/rust-analyzer-linux")
|
||||||
|
@ -82,7 +76,7 @@ fn dist_server() -> Result<()> {
|
||||||
let src = Path::new(src);
|
let src = Path::new(src);
|
||||||
let dst = Path::new(dst);
|
let dst = Path::new(dst);
|
||||||
|
|
||||||
fs2::copy(&src, &dst)?;
|
cp(&src, &dst)?;
|
||||||
gzip(&src, &dst.with_extension("gz"))?;
|
gzip(&src, &dst.with_extension("gz"))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -105,7 +99,7 @@ struct Patch {
|
||||||
impl Patch {
|
impl Patch {
|
||||||
fn new(path: impl Into<PathBuf>) -> Result<Patch> {
|
fn new(path: impl Into<PathBuf>) -> Result<Patch> {
|
||||||
let path = path.into();
|
let path = path.into();
|
||||||
let contents = fs2::read_to_string(&path)?;
|
let contents = read_file(&path)?;
|
||||||
Ok(Patch { path, original_contents: contents.clone(), contents })
|
Ok(Patch { path, original_contents: contents.clone(), contents })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,13 +109,14 @@ impl Patch {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit(&self) -> io::Result<()> {
|
fn commit(&self) -> Result<()> {
|
||||||
fs2::write(&self.path, &self.contents)
|
write_file(&self.path, &self.contents)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Patch {
|
impl Drop for Patch {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
fs2::write(&self.path, &self.original_contents).unwrap();
|
write_file(&self.path, &self.original_contents).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
use std::{env, path::PathBuf, str};
|
use std::{env, path::PathBuf, str};
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Context, Result};
|
use anyhow::{bail, format_err, Context, Result};
|
||||||
|
use xshell::{cmd, pushd};
|
||||||
use crate::not_bash::{pushd, run};
|
|
||||||
|
|
||||||
// Latest stable, feel free to send a PR if this lags behind.
|
// Latest stable, feel free to send a PR if this lags behind.
|
||||||
const REQUIRED_RUST_VERSION: u32 = 47;
|
const REQUIRED_RUST_VERSION: u32 = 47;
|
||||||
|
@ -76,7 +75,7 @@ fn fix_path_for_mac() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
|
fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
|
||||||
let _dir = pushd("./editors/code");
|
let _dir = pushd("./editors/code")?;
|
||||||
|
|
||||||
let find_code = |f: fn(&str) -> bool| -> Result<&'static str> {
|
let find_code = |f: fn(&str) -> bool| -> Result<&'static str> {
|
||||||
["code", "code-insiders", "codium", "code-oss"]
|
["code", "code-insiders", "codium", "code-oss"]
|
||||||
|
@ -89,24 +88,25 @@ fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let installed_extensions = if cfg!(unix) {
|
let installed_extensions = if cfg!(unix) {
|
||||||
run!("npm --version").context("`npm` is required to build the VS Code plugin")?;
|
cmd!("npm --version").run().context("`npm` is required to build the VS Code plugin")?;
|
||||||
run!("npm install")?;
|
cmd!("npm install").run()?;
|
||||||
|
|
||||||
run!("npm run package --scripts-prepend-node-path")?;
|
cmd!("npm run package --scripts-prepend-node-path").run()?;
|
||||||
|
|
||||||
let code = find_code(|bin| run!("{} --version", bin).is_ok())?;
|
let code = find_code(|bin| cmd!("{bin} --version").read().is_ok())?;
|
||||||
run!("{} --install-extension rust-analyzer.vsix --force", code)?;
|
cmd!("{code} --install-extension rust-analyzer.vsix --force").run()?;
|
||||||
run!("{} --list-extensions", code; echo = false)?
|
cmd!("{code} --list-extensions").read()?
|
||||||
} else {
|
} else {
|
||||||
run!("cmd.exe /c npm --version")
|
cmd!("cmd.exe /c npm --version")
|
||||||
|
.run()
|
||||||
.context("`npm` is required to build the VS Code plugin")?;
|
.context("`npm` is required to build the VS Code plugin")?;
|
||||||
run!("cmd.exe /c npm install")?;
|
cmd!("cmd.exe /c npm install").run()?;
|
||||||
|
|
||||||
run!("cmd.exe /c npm run package")?;
|
cmd!("cmd.exe /c npm run package").run()?;
|
||||||
|
|
||||||
let code = find_code(|bin| run!("cmd.exe /c {}.cmd --version", bin).is_ok())?;
|
let code = find_code(|bin| cmd!("cmd.exe /c {bin}.cmd --version").read().is_ok())?;
|
||||||
run!(r"cmd.exe /c {}.cmd --install-extension rust-analyzer.vsix --force", code)?;
|
cmd!("cmd.exe /c {code}.cmd --install-extension rust-analyzer.vsix --force").run()?;
|
||||||
run!("cmd.exe /c {}.cmd --list-extensions", code; echo = false)?
|
cmd!("cmd.exe /c {code}.cmd --list-extensions").read()?
|
||||||
};
|
};
|
||||||
|
|
||||||
if !installed_extensions.contains("rust-analyzer") {
|
if !installed_extensions.contains("rust-analyzer") {
|
||||||
|
@ -122,7 +122,7 @@ fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
|
||||||
|
|
||||||
fn install_server(opts: ServerOpt) -> Result<()> {
|
fn install_server(opts: ServerOpt) -> Result<()> {
|
||||||
let mut old_rust = false;
|
let mut old_rust = false;
|
||||||
if let Ok(stdout) = run!("cargo --version") {
|
if let Ok(stdout) = cmd!("cargo --version").read() {
|
||||||
if !check_version(&stdout, REQUIRED_RUST_VERSION) {
|
if !check_version(&stdout, REQUIRED_RUST_VERSION) {
|
||||||
old_rust = true;
|
old_rust = true;
|
||||||
}
|
}
|
||||||
|
@ -134,12 +134,13 @@ fn install_server(opts: ServerOpt) -> Result<()> {
|
||||||
REQUIRED_RUST_VERSION,
|
REQUIRED_RUST_VERSION,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
let features = match opts.malloc {
|
||||||
let malloc_feature = match opts.malloc {
|
Malloc::System => &[][..],
|
||||||
Malloc::System => "",
|
Malloc::Mimalloc => &["--features", "mimalloc"],
|
||||||
Malloc::Mimalloc => "--features mimalloc",
|
|
||||||
};
|
};
|
||||||
let res = run!("cargo install --path crates/rust-analyzer --locked --force {}", malloc_feature);
|
|
||||||
|
let cmd = cmd!("cargo install --path crates/rust-analyzer --locked --force {features...}");
|
||||||
|
let res = cmd.run();
|
||||||
|
|
||||||
if res.is_err() && old_rust {
|
if res.is_err() && old_rust {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
@ -148,7 +149,8 @@ fn install_server(opts: ServerOpt) -> Result<()> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.map(drop)
|
res?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_version(version_output: &str, min_minor_version: u32) -> bool {
|
fn check_version(version_output: &str, min_minor_version: u32) -> bool {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
//!
|
//!
|
||||||
//! See https://github.com/matklad/cargo-xtask/
|
//! See https://github.com/matklad/cargo-xtask/
|
||||||
|
|
||||||
pub mod not_bash;
|
|
||||||
pub mod codegen;
|
pub mod codegen;
|
||||||
mod ast_src;
|
mod ast_src;
|
||||||
|
|
||||||
|
@ -19,11 +18,9 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use walkdir::{DirEntry, WalkDir};
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
use xshell::{cmd, pushd, pushenv};
|
||||||
|
|
||||||
use crate::{
|
use crate::codegen::Mode;
|
||||||
codegen::Mode,
|
|
||||||
not_bash::{pushd, pushenv},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use anyhow::{bail, Context as _, Result};
|
pub use anyhow::{bail, Context as _, Result};
|
||||||
|
|
||||||
|
@ -53,18 +50,19 @@ pub fn rust_files(path: &Path) -> impl Iterator<Item = PathBuf> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_rustfmt(mode: Mode) -> Result<()> {
|
pub fn run_rustfmt(mode: Mode) -> Result<()> {
|
||||||
let _dir = pushd(project_root());
|
let _dir = pushd(project_root())?;
|
||||||
let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
|
let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
|
||||||
ensure_rustfmt()?;
|
ensure_rustfmt()?;
|
||||||
match mode {
|
let check = match mode {
|
||||||
Mode::Overwrite => run!("cargo fmt"),
|
Mode::Overwrite => &[][..],
|
||||||
Mode::Verify => run!("cargo fmt -- --check"),
|
Mode::Verify => &["--", "--check"],
|
||||||
}?;
|
};
|
||||||
|
cmd!("cargo fmt {check...}").run()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_rustfmt() -> Result<()> {
|
fn ensure_rustfmt() -> Result<()> {
|
||||||
let out = run!("rustfmt --version")?;
|
let out = cmd!("rustfmt --version").read()?;
|
||||||
if !out.contains("stable") {
|
if !out.contains("stable") {
|
||||||
bail!(
|
bail!(
|
||||||
"Failed to run rustfmt from toolchain 'stable'. \
|
"Failed to run rustfmt from toolchain 'stable'. \
|
||||||
|
@ -75,40 +73,46 @@ fn ensure_rustfmt() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_clippy() -> Result<()> {
|
pub fn run_clippy() -> Result<()> {
|
||||||
if run!("cargo clippy --version").is_err() {
|
if cmd!("cargo clippy --version").read().is_err() {
|
||||||
bail!(
|
bail!(
|
||||||
"Failed run cargo clippy. \
|
"Failed run cargo clippy. \
|
||||||
Please run `rustup component add clippy` to install it.",
|
Please run `rustup component add clippy` to install it.",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let allowed_lints = [
|
let allowed_lints = "
|
||||||
"clippy::collapsible_if",
|
-A clippy::collapsible_if
|
||||||
"clippy::needless_pass_by_value",
|
-A clippy::needless_pass_by_value
|
||||||
"clippy::nonminimal_bool",
|
-A clippy::nonminimal_bool
|
||||||
"clippy::redundant_pattern_matching",
|
-A clippy::redundant_pattern_matching
|
||||||
];
|
"
|
||||||
run!("cargo clippy --all-features --all-targets -- -A {}", allowed_lints.join(" -A "))?;
|
.split_ascii_whitespace();
|
||||||
|
cmd!("cargo clippy --all-features --all-targets -- {allowed_lints...}").run()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_fuzzer() -> Result<()> {
|
pub fn run_fuzzer() -> Result<()> {
|
||||||
let _d = pushd("./crates/syntax");
|
let _d = pushd("./crates/syntax")?;
|
||||||
let _e = pushenv("RUSTUP_TOOLCHAIN", "nightly");
|
let _e = pushenv("RUSTUP_TOOLCHAIN", "nightly");
|
||||||
if run!("cargo fuzz --help").is_err() {
|
if cmd!("cargo fuzz --help").read().is_err() {
|
||||||
run!("cargo install cargo-fuzz")?;
|
cmd!("cargo install cargo-fuzz").run()?;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Expecting nightly rustc
|
// Expecting nightly rustc
|
||||||
let out = run!("rustc --version")?;
|
let out = cmd!("rustc --version").read()?;
|
||||||
if !out.contains("nightly") {
|
if !out.contains("nightly") {
|
||||||
bail!("fuzz tests require nightly rustc")
|
bail!("fuzz tests require nightly rustc")
|
||||||
}
|
}
|
||||||
|
|
||||||
run!("cargo fuzz run parser")?;
|
cmd!("cargo fuzz run parser").run()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn date_iso() -> Result<String> {
|
||||||
|
let res = cmd!("date --iso --utc").read()?;
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
fn is_release_tag(tag: &str) -> bool {
|
fn is_release_tag(tag: &str) -> bool {
|
||||||
tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit())
|
tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit())
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,12 @@ use std::env;
|
||||||
|
|
||||||
use codegen::CodegenCmd;
|
use codegen::CodegenCmd;
|
||||||
use pico_args::Arguments;
|
use pico_args::Arguments;
|
||||||
|
use xshell::pushd;
|
||||||
use xtask::{
|
use xtask::{
|
||||||
codegen::{self, Mode},
|
codegen::{self, Mode},
|
||||||
dist::DistCmd,
|
dist::DistCmd,
|
||||||
install::{ClientOpt, InstallCmd, Malloc, ServerOpt},
|
install::{ClientOpt, InstallCmd, Malloc, ServerOpt},
|
||||||
metrics::MetricsCmd,
|
metrics::MetricsCmd,
|
||||||
not_bash::pushd,
|
|
||||||
pre_cache::PreCacheCmd,
|
pre_cache::PreCacheCmd,
|
||||||
pre_commit, project_root,
|
pre_commit, project_root,
|
||||||
release::{PromoteCmd, ReleaseCmd},
|
release::{PromoteCmd, ReleaseCmd},
|
||||||
|
@ -29,7 +29,7 @@ fn main() -> Result<()> {
|
||||||
return pre_commit::run_hook();
|
return pre_commit::run_hook();
|
||||||
}
|
}
|
||||||
|
|
||||||
let _d = pushd(project_root());
|
let _d = pushd(project_root())?;
|
||||||
|
|
||||||
let mut args = Arguments::from_env();
|
let mut args = Arguments::from_env();
|
||||||
let subcommand = args.subcommand()?.unwrap_or_default();
|
let subcommand = args.subcommand()?.unwrap_or_default();
|
||||||
|
|
|
@ -7,8 +7,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Result};
|
use anyhow::{bail, format_err, Result};
|
||||||
|
use xshell::{cmd, mkdir_p, pushd, pushenv, read_file, rm_rf};
|
||||||
use crate::not_bash::{fs2, pushd, pushenv, rm_rf, run};
|
|
||||||
|
|
||||||
type Unit = String;
|
type Unit = String;
|
||||||
|
|
||||||
|
@ -23,12 +22,13 @@ impl MetricsCmd {
|
||||||
rm_rf("./target/release")?;
|
rm_rf("./target/release")?;
|
||||||
}
|
}
|
||||||
if !Path::new("./target/rustc-perf").exists() {
|
if !Path::new("./target/rustc-perf").exists() {
|
||||||
fs2::create_dir_all("./target/rustc-perf")?;
|
mkdir_p("./target/rustc-perf")?;
|
||||||
run!("git clone https://github.com/rust-lang/rustc-perf.git ./target/rustc-perf")?;
|
cmd!("git clone https://github.com/rust-lang/rustc-perf.git ./target/rustc-perf")
|
||||||
|
.run()?;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let _d = pushd("./target/rustc-perf");
|
let _d = pushd("./target/rustc-perf")?;
|
||||||
run!("git reset --hard 1d9288b0da7febf2599917da1b57dc241a1af033")?;
|
cmd!("git reset --hard 1d9288b0da7febf2599917da1b57dc241a1af033").run()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _env = pushenv("RA_METRICS", "1");
|
let _env = pushenv("RA_METRICS", "1");
|
||||||
|
@ -39,17 +39,20 @@ impl MetricsCmd {
|
||||||
metrics.measure_analysis_stats("webrender")?;
|
metrics.measure_analysis_stats("webrender")?;
|
||||||
|
|
||||||
if !self.dry_run {
|
if !self.dry_run {
|
||||||
let _d = pushd("target");
|
let _d = pushd("target")?;
|
||||||
let metrics_token = env::var("METRICS_TOKEN").unwrap();
|
let metrics_token = env::var("METRICS_TOKEN").unwrap();
|
||||||
let repo = format!("https://{}@github.com/rust-analyzer/metrics.git", metrics_token);
|
cmd!(
|
||||||
run!("git clone --depth 1 {}", repo)?;
|
"git clone --depth 1 https://{metrics_token}@github.com/rust-analyzer/metrics.git"
|
||||||
let _d = pushd("metrics");
|
)
|
||||||
|
.run()?;
|
||||||
|
let _d = pushd("metrics")?;
|
||||||
|
|
||||||
let mut file = std::fs::OpenOptions::new().append(true).open("metrics.json")?;
|
let mut file = std::fs::OpenOptions::new().append(true).open("metrics.json")?;
|
||||||
writeln!(file, "{}", metrics.json())?;
|
writeln!(file, "{}", metrics.json())?;
|
||||||
run!("git add .")?;
|
cmd!("git add .").run()?;
|
||||||
run!("git -c user.name=Bot -c user.email=dummy@example.com commit --message 📈")?;
|
cmd!("git -c user.name=Bot -c user.email=dummy@example.com commit --message 📈")
|
||||||
run!("git push origin master")?;
|
.run()?;
|
||||||
|
cmd!("git push origin master").run()?;
|
||||||
}
|
}
|
||||||
eprintln!("{:#?}", metrics);
|
eprintln!("{:#?}", metrics);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -59,10 +62,10 @@ impl MetricsCmd {
|
||||||
impl Metrics {
|
impl Metrics {
|
||||||
fn measure_build(&mut self) -> Result<()> {
|
fn measure_build(&mut self) -> Result<()> {
|
||||||
eprintln!("\nMeasuring build");
|
eprintln!("\nMeasuring build");
|
||||||
run!("cargo fetch")?;
|
cmd!("cargo fetch").run()?;
|
||||||
|
|
||||||
let time = Instant::now();
|
let time = Instant::now();
|
||||||
run!("cargo build --release --package rust-analyzer --bin rust-analyzer")?;
|
cmd!("cargo build --release --package rust-analyzer --bin rust-analyzer").run()?;
|
||||||
let time = time.elapsed();
|
let time = time.elapsed();
|
||||||
self.report("build", time.as_millis() as u64, "ms".into());
|
self.report("build", time.as_millis() as u64, "ms".into());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -78,7 +81,7 @@ impl Metrics {
|
||||||
}
|
}
|
||||||
fn measure_analysis_stats_path(&mut self, name: &str, path: &str) -> Result<()> {
|
fn measure_analysis_stats_path(&mut self, name: &str, path: &str) -> Result<()> {
|
||||||
eprintln!("\nMeasuring analysis-stats/{}", name);
|
eprintln!("\nMeasuring analysis-stats/{}", name);
|
||||||
let output = run!("./target/release/rust-analyzer analysis-stats --quiet {}", path)?;
|
let output = cmd!("./target/release/rust-analyzer analysis-stats --quiet {path}").read()?;
|
||||||
for (metric, value, unit) in parse_metrics(&output) {
|
for (metric, value, unit) in parse_metrics(&output) {
|
||||||
self.report(&format!("analysis-stats/{}/{}", name, metric), value, unit.into());
|
self.report(&format!("analysis-stats/{}/{}", name, metric), value, unit.into());
|
||||||
}
|
}
|
||||||
|
@ -118,7 +121,7 @@ impl Metrics {
|
||||||
fn new() -> Result<Metrics> {
|
fn new() -> Result<Metrics> {
|
||||||
let host = Host::new()?;
|
let host = Host::new()?;
|
||||||
let timestamp = SystemTime::now();
|
let timestamp = SystemTime::now();
|
||||||
let revision = run!("git rev-parse HEAD")?;
|
let revision = cmd!("git rev-parse HEAD").read()?;
|
||||||
Ok(Metrics { host, timestamp, revision, metrics: BTreeMap::new() })
|
Ok(Metrics { host, timestamp, revision, metrics: BTreeMap::new() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +163,7 @@ impl Host {
|
||||||
return Ok(Host { os, cpu, mem });
|
return Ok(Host { os, cpu, mem });
|
||||||
|
|
||||||
fn read_field<'a>(path: &str, field: &str) -> Result<String> {
|
fn read_field<'a>(path: &str, field: &str) -> Result<String> {
|
||||||
let text = fs2::read_to_string(path)?;
|
let text = read_file(path)?;
|
||||||
|
|
||||||
let line = text
|
let line = text
|
||||||
.lines()
|
.lines()
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
//! A bad shell -- small cross platform module for writing glue code
|
|
||||||
|
|
||||||
use std::{
|
|
||||||
cell::RefCell,
|
|
||||||
env,
|
|
||||||
ffi::OsString,
|
|
||||||
io::{self, Write},
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
process::{Command, Stdio},
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::{bail, Context, Result};
|
|
||||||
|
|
||||||
pub use fs_err as fs2;
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! run {
|
|
||||||
($($expr:expr),*) => {
|
|
||||||
run!($($expr),*; echo = true)
|
|
||||||
};
|
|
||||||
($($expr:expr),* ; echo = $echo:expr) => {
|
|
||||||
$crate::not_bash::run_process(format!($($expr),*), $echo, None)
|
|
||||||
};
|
|
||||||
($($expr:expr),* ; <$stdin:expr) => {
|
|
||||||
$crate::not_bash::run_process(format!($($expr),*), false, Some($stdin))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub use crate::run;
|
|
||||||
|
|
||||||
pub struct Pushd {
|
|
||||||
_p: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pushd(path: impl Into<PathBuf>) -> Pushd {
|
|
||||||
Env::with(|env| env.pushd(path.into()));
|
|
||||||
Pushd { _p: () }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Pushd {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
Env::with(|env| env.popd())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Pushenv {
|
|
||||||
_p: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pushenv(var: &str, value: &str) -> Pushenv {
|
|
||||||
Env::with(|env| env.pushenv(var.into(), value.into()));
|
|
||||||
Pushenv { _p: () }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Pushenv {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
Env::with(|env| env.popenv())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rm_rf(path: impl AsRef<Path>) -> io::Result<()> {
|
|
||||||
let path = path.as_ref();
|
|
||||||
if !path.exists() {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
if path.is_file() {
|
|
||||||
fs2::remove_file(path)
|
|
||||||
} else {
|
|
||||||
fs2::remove_dir_all(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn run_process(cmd: String, echo: bool, stdin: Option<&[u8]>) -> Result<String> {
|
|
||||||
run_process_inner(&cmd, echo, stdin).with_context(|| format!("process `{}` failed", cmd))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn date_iso() -> Result<String> {
|
|
||||||
run!("date --iso --utc")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_process_inner(cmd: &str, echo: bool, stdin: Option<&[u8]>) -> Result<String> {
|
|
||||||
let mut args = shelx(cmd);
|
|
||||||
let binary = args.remove(0);
|
|
||||||
let current_dir = Env::with(|it| it.cwd().to_path_buf());
|
|
||||||
|
|
||||||
if echo {
|
|
||||||
println!("> {}", cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut command = Command::new(binary);
|
|
||||||
command.args(args).current_dir(current_dir).stderr(Stdio::inherit());
|
|
||||||
let output = match stdin {
|
|
||||||
None => command.stdin(Stdio::null()).output(),
|
|
||||||
Some(stdin) => {
|
|
||||||
command.stdin(Stdio::piped()).stdout(Stdio::piped());
|
|
||||||
let mut process = command.spawn()?;
|
|
||||||
process.stdin.take().unwrap().write_all(stdin)?;
|
|
||||||
process.wait_with_output()
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
let stdout = String::from_utf8(output.stdout)?;
|
|
||||||
|
|
||||||
if echo {
|
|
||||||
print!("{}", stdout)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
bail!("{}", output.status)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(stdout.trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: some real shell lexing here
|
|
||||||
fn shelx(cmd: &str) -> Vec<String> {
|
|
||||||
let mut res = Vec::new();
|
|
||||||
for (string_piece, in_quotes) in cmd.split('\'').zip([false, true].iter().copied().cycle()) {
|
|
||||||
if in_quotes {
|
|
||||||
res.push(string_piece.to_string())
|
|
||||||
} else {
|
|
||||||
if !string_piece.is_empty() {
|
|
||||||
res.extend(string_piece.split_ascii_whitespace().map(|it| it.to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Env {
|
|
||||||
pushd_stack: Vec<PathBuf>,
|
|
||||||
pushenv_stack: Vec<(OsString, Option<OsString>)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Env {
|
|
||||||
fn with<F: FnOnce(&mut Env) -> T, T>(f: F) -> T {
|
|
||||||
thread_local! {
|
|
||||||
static ENV: RefCell<Env> = RefCell::new(Env {
|
|
||||||
pushd_stack: vec![env::current_dir().unwrap()],
|
|
||||||
pushenv_stack: vec![],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ENV.with(|it| f(&mut *it.borrow_mut()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pushd(&mut self, dir: PathBuf) {
|
|
||||||
let dir = self.cwd().join(dir);
|
|
||||||
self.pushd_stack.push(dir);
|
|
||||||
env::set_current_dir(self.cwd())
|
|
||||||
.unwrap_or_else(|err| panic!("Failed to set cwd to {}: {}", self.cwd().display(), err));
|
|
||||||
}
|
|
||||||
fn popd(&mut self) {
|
|
||||||
self.pushd_stack.pop().unwrap();
|
|
||||||
env::set_current_dir(self.cwd()).unwrap();
|
|
||||||
}
|
|
||||||
fn pushenv(&mut self, var: OsString, value: OsString) {
|
|
||||||
self.pushenv_stack.push((var.clone(), env::var_os(&var)));
|
|
||||||
env::set_var(var, value)
|
|
||||||
}
|
|
||||||
fn popenv(&mut self) {
|
|
||||||
let (var, value) = self.pushenv_stack.pop().unwrap();
|
|
||||||
match value {
|
|
||||||
None => env::remove_var(var),
|
|
||||||
Some(value) => env::set_var(var, value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn cwd(&self) -> &Path {
|
|
||||||
self.pushd_stack.last().unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,8 +4,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use xshell::rm_rf;
|
||||||
use crate::not_bash::{fs2, rm_rf};
|
|
||||||
|
|
||||||
pub struct PreCacheCmd;
|
pub struct PreCacheCmd;
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ impl PreCacheCmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fs2::remove_file("./target/.rustc_info.json")?;
|
rm_rf("./target/.rustc_info.json")?;
|
||||||
|
|
||||||
let to_delete = read_dir("./crates", FileType::is_dir)?
|
let to_delete = read_dir("./crates", FileType::is_dir)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -3,19 +3,21 @@
|
||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
|
use xshell::cmd;
|
||||||
|
|
||||||
use crate::{not_bash::run, project_root, run_rustfmt, Mode};
|
use crate::{project_root, run_rustfmt, Mode};
|
||||||
|
|
||||||
// FIXME: if there are changed `.ts` files, also reformat TypeScript (by
|
// FIXME: if there are changed `.ts` files, also reformat TypeScript (by
|
||||||
// shelling out to `npm fmt`).
|
// shelling out to `npm fmt`).
|
||||||
pub fn run_hook() -> Result<()> {
|
pub fn run_hook() -> Result<()> {
|
||||||
run_rustfmt(Mode::Overwrite)?;
|
run_rustfmt(Mode::Overwrite)?;
|
||||||
|
|
||||||
let diff = run!("git diff --diff-filter=MAR --name-only --cached")?;
|
let diff = cmd!("git diff --diff-filter=MAR --name-only --cached").read()?;
|
||||||
|
|
||||||
let root = project_root();
|
let root = project_root();
|
||||||
for line in diff.lines() {
|
for line in diff.lines() {
|
||||||
run!("git update-index --add {}", root.join(line).display())?;
|
let file = root.join(line);
|
||||||
|
cmd!("git update-index --add {file}").run()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::{
|
use xshell::{cmd, cp, pushd, read_dir, write_file};
|
||||||
codegen, is_release_tag,
|
|
||||||
not_bash::{date_iso, fs2, pushd, run},
|
use crate::{codegen, date_iso, is_release_tag, project_root, Mode, Result};
|
||||||
project_root, Mode, Result,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct ReleaseCmd {
|
pub struct ReleaseCmd {
|
||||||
pub dry_run: bool,
|
pub dry_run: bool,
|
||||||
|
@ -11,10 +9,10 @@ pub struct ReleaseCmd {
|
||||||
impl ReleaseCmd {
|
impl ReleaseCmd {
|
||||||
pub fn run(self) -> Result<()> {
|
pub fn run(self) -> Result<()> {
|
||||||
if !self.dry_run {
|
if !self.dry_run {
|
||||||
run!("git switch release")?;
|
cmd!("git switch release").run()?;
|
||||||
run!("git fetch upstream --tags --force")?;
|
cmd!("git fetch upstream --tags --force").run()?;
|
||||||
run!("git reset --hard tags/nightly")?;
|
cmd!("git reset --hard tags/nightly").run()?;
|
||||||
run!("git push")?;
|
cmd!("git push").run()?;
|
||||||
}
|
}
|
||||||
codegen::generate_assists_docs(Mode::Overwrite)?;
|
codegen::generate_assists_docs(Mode::Overwrite)?;
|
||||||
codegen::generate_feature_docs(Mode::Overwrite)?;
|
codegen::generate_feature_docs(Mode::Overwrite)?;
|
||||||
|
@ -23,8 +21,8 @@ impl ReleaseCmd {
|
||||||
let changelog_dir = website_root.join("./thisweek/_posts");
|
let changelog_dir = website_root.join("./thisweek/_posts");
|
||||||
|
|
||||||
let today = date_iso()?;
|
let today = date_iso()?;
|
||||||
let commit = run!("git rev-parse HEAD")?;
|
let commit = cmd!("git rev-parse HEAD").read()?;
|
||||||
let changelog_n = fs2::read_dir(changelog_dir.as_path())?.count();
|
let changelog_n = read_dir(changelog_dir.as_path())?.len();
|
||||||
|
|
||||||
let contents = format!(
|
let contents = format!(
|
||||||
"\
|
"\
|
||||||
|
@ -52,20 +50,20 @@ https://github.com/sponsors/rust-analyzer[GitHub Sponsors].
|
||||||
);
|
);
|
||||||
|
|
||||||
let path = changelog_dir.join(format!("{}-changelog-{}.adoc", today, changelog_n));
|
let path = changelog_dir.join(format!("{}-changelog-{}.adoc", today, changelog_n));
|
||||||
fs2::write(&path, &contents)?;
|
write_file(&path, &contents)?;
|
||||||
|
|
||||||
for &adoc in ["manual.adoc", "generated_features.adoc", "generated_assists.adoc"].iter() {
|
for &adoc in ["manual.adoc", "generated_features.adoc", "generated_assists.adoc"].iter() {
|
||||||
let src = project_root().join("./docs/user/").join(adoc);
|
let src = project_root().join("./docs/user/").join(adoc);
|
||||||
let dst = website_root.join(adoc);
|
let dst = website_root.join(adoc);
|
||||||
fs2::copy(src, dst)?;
|
cp(src, dst)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tags = run!("git tag --list"; echo = false)?;
|
let tags = cmd!("git tag --list").read()?;
|
||||||
let prev_tag = tags.lines().filter(|line| is_release_tag(line)).last().unwrap();
|
let prev_tag = tags.lines().filter(|line| is_release_tag(line)).last().unwrap();
|
||||||
|
|
||||||
let git_log = run!("git log {}..HEAD --merges --reverse", prev_tag; echo = false)?;
|
let git_log = cmd!("git log {prev_tag}..HEAD --merges --reverse").read()?;
|
||||||
let git_log_dst = website_root.join("git.log");
|
let git_log_dst = website_root.join("git.log");
|
||||||
fs2::write(git_log_dst, &git_log)?;
|
write_file(git_log_dst, &git_log)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -77,27 +75,25 @@ pub struct PromoteCmd {
|
||||||
|
|
||||||
impl PromoteCmd {
|
impl PromoteCmd {
|
||||||
pub fn run(self) -> Result<()> {
|
pub fn run(self) -> Result<()> {
|
||||||
let _dir = pushd("../rust-rust-analyzer");
|
let _dir = pushd("../rust-rust-analyzer")?;
|
||||||
run!("git switch master")?;
|
cmd!("git switch master").run()?;
|
||||||
run!("git fetch upstream")?;
|
cmd!("git fetch upstream").run()?;
|
||||||
run!("git reset --hard upstream/master")?;
|
cmd!("git reset --hard upstream/master").run()?;
|
||||||
run!("git submodule update --recursive")?;
|
cmd!("git submodule update --recursive").run()?;
|
||||||
|
|
||||||
let branch = format!("rust-analyzer-{}", date_iso()?);
|
let branch = format!("rust-analyzer-{}", date_iso()?);
|
||||||
run!("git switch -c {}", branch)?;
|
cmd!("git switch -c {branch}").run()?;
|
||||||
{
|
{
|
||||||
let _dir = pushd("src/tools/rust-analyzer");
|
let _dir = pushd("src/tools/rust-analyzer")?;
|
||||||
run!("git fetch origin")?;
|
cmd!("git fetch origin").run()?;
|
||||||
run!("git reset --hard origin/release")?;
|
cmd!("git reset --hard origin/release").run()?;
|
||||||
}
|
}
|
||||||
run!("git add src/tools/rust-analyzer")?;
|
cmd!("git add src/tools/rust-analyzer").run()?;
|
||||||
run!("git commit -m':arrow_up: rust-analyzer'")?;
|
cmd!("git commit -m':arrow_up: rust-analyzer'").run()?;
|
||||||
if !self.dry_run {
|
if !self.dry_run {
|
||||||
run!("git push")?;
|
cmd!("git push").run()?;
|
||||||
run!(
|
cmd!("xdg-open https://github.com/matklad/rust/pull/new/{branch}?body=r%3F%20%40ghost")
|
||||||
"xdg-open https://github.com/matklad/rust/pull/new/{}?body=r%3F%20%40ghost",
|
.run()?;
|
||||||
branch
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use xshell::{cmd, read_file};
|
||||||
use xtask::{
|
use xtask::{
|
||||||
codegen::{self, Mode},
|
codegen::{self, Mode},
|
||||||
not_bash::{fs2, run},
|
|
||||||
project_root, run_rustfmt, rust_files,
|
project_root, run_rustfmt, rust_files,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,14 +48,13 @@ fn smoke_test_docs_generation() {
|
||||||
fn check_lsp_extensions_docs() {
|
fn check_lsp_extensions_docs() {
|
||||||
let expected_hash = {
|
let expected_hash = {
|
||||||
let lsp_ext_rs =
|
let lsp_ext_rs =
|
||||||
fs2::read_to_string(project_root().join("crates/rust-analyzer/src/lsp_ext.rs"))
|
read_file(project_root().join("crates/rust-analyzer/src/lsp_ext.rs")).unwrap();
|
||||||
.unwrap();
|
|
||||||
stable_hash(lsp_ext_rs.as_str())
|
stable_hash(lsp_ext_rs.as_str())
|
||||||
};
|
};
|
||||||
|
|
||||||
let actual_hash = {
|
let actual_hash = {
|
||||||
let lsp_extensions_md =
|
let lsp_extensions_md =
|
||||||
fs2::read_to_string(project_root().join("docs/dev/lsp-extensions.md")).unwrap();
|
read_file(project_root().join("docs/dev/lsp-extensions.md")).unwrap();
|
||||||
let text = lsp_extensions_md
|
let text = lsp_extensions_md
|
||||||
.lines()
|
.lines()
|
||||||
.find_map(|line| line.strip_prefix("lsp_ext.rs hash:"))
|
.find_map(|line| line.strip_prefix("lsp_ext.rs hash:"))
|
||||||
|
@ -83,7 +82,7 @@ Please adjust docs/dev/lsp-extensions.md.
|
||||||
fn rust_files_are_tidy() {
|
fn rust_files_are_tidy() {
|
||||||
let mut tidy_docs = TidyDocs::default();
|
let mut tidy_docs = TidyDocs::default();
|
||||||
for path in rust_files(&project_root().join("crates")) {
|
for path in rust_files(&project_root().join("crates")) {
|
||||||
let text = fs2::read_to_string(&path).unwrap();
|
let text = read_file(&path).unwrap();
|
||||||
check_todo(&path, &text);
|
check_todo(&path, &text);
|
||||||
check_trailing_ws(&path, &text);
|
check_trailing_ws(&path, &text);
|
||||||
deny_clippy(&path, &text);
|
deny_clippy(&path, &text);
|
||||||
|
@ -94,7 +93,9 @@ fn rust_files_are_tidy() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_merge_commits() {
|
fn check_merge_commits() {
|
||||||
let stdout = run!("git rev-list --merges --invert-grep --author 'bors\\[bot\\]' HEAD~19.."; echo = false)
|
let stdout =
|
||||||
|
dbg!(cmd!("git rev-list --merges --invert-grep --author 'bors\\[bot\\]' HEAD~19.."))
|
||||||
|
.read()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if !stdout.is_empty() {
|
if !stdout.is_empty() {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -168,7 +169,7 @@ Zlib OR Apache-2.0 OR MIT
|
||||||
.filter(|it| !it.is_empty())
|
.filter(|it| !it.is_empty())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let meta = run!("cargo metadata --format-version 1"; echo = false).unwrap();
|
let meta = cmd!("cargo metadata --format-version 1").read().unwrap();
|
||||||
let mut licenses = meta
|
let mut licenses = meta
|
||||||
.split(|c| c == ',' || c == '{' || c == '}')
|
.split(|c| c == ',' || c == '{' || c == '}')
|
||||||
.filter(|it| it.contains(r#""license""#))
|
.filter(|it| it.contains(r#""license""#))
|
||||||
|
@ -177,6 +178,25 @@ Zlib OR Apache-2.0 OR MIT
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
licenses.sort();
|
licenses.sort();
|
||||||
licenses.dedup();
|
licenses.dedup();
|
||||||
|
if licenses != expected {
|
||||||
|
let mut diff = String::new();
|
||||||
|
|
||||||
|
diff += &format!("New Licenses:\n");
|
||||||
|
for &l in licenses.iter() {
|
||||||
|
if !expected.contains(&l) {
|
||||||
|
diff += &format!(" {}\n", l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff += &format!("\nMissing Licenses:\n");
|
||||||
|
for &l in expected.iter() {
|
||||||
|
if !licenses.contains(&l) {
|
||||||
|
diff += &format!(" {}\n", l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("different set of licenses!\n{}", diff);
|
||||||
|
}
|
||||||
assert_eq!(licenses, expected);
|
assert_eq!(licenses, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue