Skip to content

internal: ⬆️ xshell #11700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/ide_db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ limit = { path = "../limit", version = "0.0.0" }
[dev-dependencies]
test_utils = { path = "../test_utils" }
sourcegen = { path = "../sourcegen" }
xshell = "0.1"
xshell = "0.2.0"
expect-test = "1.2.0-pre.1"
23 changes: 15 additions & 8 deletions crates/ide_db/src/tests/sourcegen_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ use std::{borrow::Cow, fs, path::Path};
use itertools::Itertools;
use stdx::format_to;
use test_utils::project_root;
use xshell::cmd;
use xshell::{cmd, Shell};

/// This clones rustc repo, and so is not worth to keep up-to-date. We update
/// manually by un-ignoring the test from time to time.
#[test]
#[ignore]
fn sourcegen_lint_completions() {
let sh = &Shell::new().unwrap();

let rust_repo = project_root().join("./target/rust");
if !rust_repo.exists() {
cmd!("git clone --depth=1 https://github.com/rust-lang/rust {rust_repo}").run().unwrap();
cmd!(sh, "git clone --depth=1 https://github.com/rust-lang/rust {rust_repo}")
.run()
.unwrap();
}

let mut contents = String::from(
Expand All @@ -30,16 +34,19 @@ pub struct LintGroup {
",
);

generate_lint_descriptor(&mut contents);
generate_lint_descriptor(sh, &mut contents);
contents.push('\n');

generate_feature_descriptor(&mut contents, &rust_repo.join("src/doc/unstable-book/src"));
contents.push('\n');

let lints_json = project_root().join("./target/clippy_lints.json");
cmd!("curl https://rust-lang.github.io/rust-clippy/master/lints.json --output {lints_json}")
.run()
.unwrap();
cmd!(
sh,
"curl https://rust-lang.github.io/rust-clippy/master/lints.json --output {lints_json}"
)
.run()
.unwrap();
generate_descriptor_clippy(&mut contents, &lints_json);

let contents = sourcegen::add_preamble("sourcegen_lints", sourcegen::reformat(contents));
Expand All @@ -48,10 +55,10 @@ pub struct LintGroup {
sourcegen::ensure_file_contents(destination.as_path(), &contents);
}

fn generate_lint_descriptor(buf: &mut String) {
fn generate_lint_descriptor(sh: &Shell, buf: &mut String) {
// FIXME: rustdoc currently requires an input file for -Whelp cc https://github.com/rust-lang/rust/pull/88831
let file = project_root().join(file!());
let stdout = cmd!("rustdoc -W help {file}").read().unwrap();
let stdout = cmd!(sh, "rustdoc -W help {file}").read().unwrap();
let start_lints = stdout.find("---- ------- -------").unwrap();
let start_lint_groups = stdout.find("---- ---------").unwrap();
let start_lints_rustdoc =
Expand Down
2 changes: 1 addition & 1 deletion crates/rust-analyzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jemallocator = { version = "0.4.1", package = "tikv-jemallocator", optional = tr
[dev-dependencies]
expect-test = "1.2.0-pre.1"
jod-thread = "0.1.0"
xshell = "0.1"
xshell = "0.2.0"

test_utils = { path = "../test_utils" }
sourcegen = { path = "../sourcegen" }
Expand Down
39 changes: 24 additions & 15 deletions crates/rust-analyzer/tests/slow-tests/tidy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,43 @@ use std::{
path::{Path, PathBuf},
};

use xshell::{cmd, pushd, pushenv, read_file};
use xshell::{cmd, Shell};

#[test]
fn check_code_formatting() {
let _dir = pushd(sourcegen::project_root()).unwrap();
let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
let sh = &Shell::new().unwrap();
sh.change_dir(sourcegen::project_root());
sh.set_var("RUSTUP_TOOLCHAIN", "stable");

let out = cmd!("rustfmt --version").read().unwrap();
let out = cmd!(sh, "rustfmt --version").read().unwrap();
if !out.contains("stable") {
panic!(
"Failed to run rustfmt from toolchain 'stable'. \
Please run `rustup component add rustfmt --toolchain stable` to install it.",
)
}

let res = cmd!("cargo fmt -- --check").run();
let res = cmd!(sh, "cargo fmt -- --check").run();
if res.is_err() {
let _ = cmd!("cargo fmt").run();
let _ = cmd!(sh, "cargo fmt").run();
}
res.unwrap()
}

#[test]
fn check_lsp_extensions_docs() {
let sh = &Shell::new().unwrap();

let expected_hash = {
let lsp_ext_rs =
read_file(sourcegen::project_root().join("crates/rust-analyzer/src/lsp_ext.rs"))
.unwrap();
let lsp_ext_rs = sh
.read_file(sourcegen::project_root().join("crates/rust-analyzer/src/lsp_ext.rs"))
.unwrap();
stable_hash(lsp_ext_rs.as_str())
};

let actual_hash = {
let lsp_extensions_md =
read_file(sourcegen::project_root().join("docs/dev/lsp-extensions.md")).unwrap();
sh.read_file(sourcegen::project_root().join("docs/dev/lsp-extensions.md")).unwrap();
let text = lsp_extensions_md
.lines()
.find_map(|line| line.strip_prefix("lsp_ext.rs hash:"))
Expand All @@ -62,6 +65,8 @@ Please adjust docs/dev/lsp-extensions.md.

#[test]
fn files_are_tidy() {
let sh = &Shell::new().unwrap();

let files = sourcegen::list_files(&sourcegen::project_root().join("crates"));

let mut tidy_docs = TidyDocs::default();
Expand All @@ -70,7 +75,7 @@ fn files_are_tidy() {
let extension = path.extension().unwrap_or_default().to_str().unwrap_or_default();
match extension {
"rs" => {
let text = read_file(&path).unwrap();
let text = sh.read_file(&path).unwrap();
check_todo(&path, &text);
check_dbg(&path, &text);
check_test_attrs(&path, &text);
Expand All @@ -80,7 +85,7 @@ fn files_are_tidy() {
tidy_marks.visit(&path, &text);
}
"toml" => {
let text = read_file(&path).unwrap();
let text = sh.read_file(&path).unwrap();
check_cargo_toml(&path, text);
}
_ => (),
Expand Down Expand Up @@ -139,8 +144,10 @@ fn check_cargo_toml(path: &Path, text: String) {

#[test]
fn check_merge_commits() {
let bors = cmd!("git rev-list --merges --author 'bors\\[bot\\]' HEAD~19..").read().unwrap();
let all = cmd!("git rev-list --merges HEAD~19..").read().unwrap();
let sh = &Shell::new().unwrap();

let bors = cmd!(sh, "git rev-list --merges --author 'bors\\[bot\\]' HEAD~19..").read().unwrap();
let all = cmd!(sh, "git rev-list --merges HEAD~19..").read().unwrap();
if bors != all {
panic!(
"
Expand Down Expand Up @@ -213,6 +220,8 @@ See https://github.com/rust-lang/rust-clippy/issues/5537 for discussion.

#[test]
fn check_licenses() {
let sh = &Shell::new().unwrap();

let expected = "
0BSD OR MIT OR Apache-2.0
Apache-2.0
Expand All @@ -235,7 +244,7 @@ Zlib OR Apache-2.0 OR MIT
.filter(|it| !it.is_empty())
.collect::<Vec<_>>();

let meta = cmd!("cargo metadata --format-version 1").read().unwrap();
let meta = cmd!(sh, "cargo metadata --format-version 1").read().unwrap();
let mut licenses = meta
.split(|c| c == ',' || c == '{' || c == '}')
.filter(|it| it.contains(r#""license""#))
Expand Down
2 changes: 1 addition & 1 deletion crates/sourcegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ rust-version = "1.57"
doctest = false

[dependencies]
xshell = "0.1"
xshell = "0.2.0"
13 changes: 7 additions & 6 deletions crates/sourcegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{
path::{Path, PathBuf},
};

use xshell::{cmd, pushenv};
use xshell::{cmd, Shell};

pub fn list_rust_files(dir: &Path) -> Vec<PathBuf> {
let mut res = list_files(dir);
Expand Down Expand Up @@ -133,8 +133,8 @@ impl fmt::Display for Location {
}
}

fn ensure_rustfmt() {
let version = cmd!("rustfmt --version").read().unwrap_or_default();
fn ensure_rustfmt(sh: &Shell) {
let version = cmd!(sh, "rustfmt --version").read().unwrap_or_default();
if !version.contains("stable") {
panic!(
"Failed to run rustfmt from toolchain 'stable'. \
Expand All @@ -144,10 +144,11 @@ fn ensure_rustfmt() {
}

pub fn reformat(text: String) -> String {
let _e = pushenv("RUSTUP_TOOLCHAIN", "stable");
ensure_rustfmt();
let sh = Shell::new().unwrap();
sh.set_var("RUSTUP_TOOLCHAIN", "stable");
ensure_rustfmt(&sh);
let rustfmt_toml = project_root().join("rustfmt.toml");
let mut stdout = cmd!("rustfmt --config-path {rustfmt_toml} --config fn_single_line=true")
let mut stdout = cmd!(sh, "rustfmt --config-path {rustfmt_toml} --config fn_single_line=true")
.stdin(text)
.read()
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ rust-version = "1.57"
anyhow = "1.0.26"
flate2 = "1.0"
write-json = "0.1.0"
xshell = "0.1"
xshell = "0.2.0"
xflags = "0.2.1"
# Avoid adding more dependencies to this crate
57 changes: 30 additions & 27 deletions xtask/src/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,23 @@ use std::{
path::{Path, PathBuf},
};

use anyhow::Result;
use flate2::{write::GzEncoder, Compression};
use xshell::{cmd, cp, mkdir_p, pushd, pushenv, read_file, rm_rf, write_file};
use xshell::{cmd, Shell};

use crate::{date_iso, flags, project_root};

impl flags::Dist {
pub(crate) fn run(self) -> Result<()> {
let stable =
std::env::var("GITHUB_REF").unwrap_or_default().as_str() == "refs/heads/release";
pub(crate) fn run(self, sh: &Shell) -> anyhow::Result<()> {
let stable = sh.var("GITHUB_REF").unwrap_or_default().as_str() == "refs/heads/release";

let project_root = project_root();
let target = Target::get(&project_root);
let dist = project_root.join("dist");
rm_rf(&dist)?;
mkdir_p(&dist)?;
sh.remove_path(&dist)?;
sh.create_dir(&dist)?;

let release_channel = if stable { "stable" } else { "nightly" };
dist_server(release_channel, &target)?;
dist_server(sh, release_channel, &target)?;

if let Some(patch_version) = self.client_patch_version {
let version = if stable {
Expand All @@ -32,58 +30,63 @@ impl flags::Dist {
// A hack to make VS Code prefer nightly over stable.
format!("0.3.{}", patch_version)
};
let release_tag = if stable { date_iso()? } else { "nightly".to_string() };
dist_client(&version, &release_tag, &target)?;
let release_tag = if stable { date_iso(sh)? } else { "nightly".to_string() };
dist_client(sh, &version, &release_tag, &target)?;
}
Ok(())
}
}

fn dist_client(version: &str, release_tag: &str, target: &Target) -> Result<()> {
fn dist_client(
sh: &Shell,
version: &str,
release_tag: &str,
target: &Target,
) -> anyhow::Result<()> {
let bundle_path = Path::new("editors").join("code").join("server");
mkdir_p(&bundle_path)?;
cp(&target.server_path, &bundle_path)?;
sh.create_dir(&bundle_path)?;
sh.copy_file(&target.server_path, &bundle_path)?;
if let Some(symbols_path) = &target.symbols_path {
cp(symbols_path, &bundle_path)?;
sh.copy_file(symbols_path, &bundle_path)?;
}

let _d = pushd("./editors/code")?;
let _d = sh.push_dir("./editors/code");

let mut patch = Patch::new("./package.json")?;
let mut patch = Patch::new(sh, "./package.json")?;
patch
.replace(r#""version": "0.4.0-dev""#, &format!(r#""version": "{}""#, version))
.replace(r#""releaseTag": null"#, &format!(r#""releaseTag": "{}""#, release_tag))
.replace(r#""$generated-start": {},"#, "")
.replace(",\n \"$generated-end\": {}", "")
.replace(r#""enabledApiProposals": [],"#, r#""#);
patch.commit()?;
patch.commit(sh)?;

Ok(())
}

fn dist_server(release_channel: &str, target: &Target) -> Result<()> {
let _e = pushenv("RUST_ANALYZER_CHANNEL", release_channel);
let _e = pushenv("CARGO_PROFILE_RELEASE_LTO", "thin");
fn dist_server(sh: &Shell, release_channel: &str, target: &Target) -> anyhow::Result<()> {
let _e = sh.push_env("RUST_ANALYZER_CHANNEL", release_channel);
let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin");

// Uncomment to enable debug info for releases. Note that:
// * debug info is split on windows and macs, so it does nothing for those platforms,
// * on Linux, this blows up the binary size from 8MB to 43MB, which is unreasonable.
// let _e = pushenv("CARGO_PROFILE_RELEASE_DEBUG", "1");
// let _e = sh.push_env("CARGO_PROFILE_RELEASE_DEBUG", "1");

if target.name.contains("-linux-") {
env::set_var("CC", "clang");
}

let target_name = &target.name;
cmd!("cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} --release").run()?;
cmd!(sh, "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} --release").run()?;

let dst = Path::new("dist").join(&target.artifact_name);
gzip(&target.server_path, &dst.with_extension("gz"))?;

Ok(())
}

fn gzip(src_path: &Path, dest_path: &Path) -> Result<()> {
fn gzip(src_path: &Path, dest_path: &Path) -> anyhow::Result<()> {
let mut encoder = GzEncoder::new(File::create(dest_path)?, Compression::best());
let mut input = io::BufReader::new(File::open(src_path)?);
io::copy(&mut input, &mut encoder)?;
Expand Down Expand Up @@ -133,9 +136,9 @@ struct Patch {
}

impl Patch {
fn new(path: impl Into<PathBuf>) -> Result<Patch> {
fn new(sh: &Shell, path: impl Into<PathBuf>) -> anyhow::Result<Patch> {
let path = path.into();
let contents = read_file(&path)?;
let contents = sh.read_file(&path)?;
Ok(Patch { path, original_contents: contents.clone(), contents })
}

Expand All @@ -145,8 +148,8 @@ impl Patch {
self
}

fn commit(&self) -> Result<()> {
write_file(&self.path, &self.contents)?;
fn commit(&self, sh: &Shell) -> anyhow::Result<()> {
sh.write_file(&self.path, &self.contents)?;
Ok(())
}
}
Expand Down
Loading