diff --git a/Cargo.lock b/Cargo.lock index ae8694825..9aa4387a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,17 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "cargo_toml" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "067a0b9ae9282dd1f63b6c1e76a065d741fc1733e566dc50b5b5d8a84d7e3c4a" +dependencies = [ + "serde", + "serde_derive", + "toml", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -69,6 +80,7 @@ name = "flowistry" version = "0.3.8" dependencies = [ "anyhow", + "cargo_toml", "clap", "env_logger", "intervaltree", @@ -240,6 +252,23 @@ dependencies = [ "winapi", ] +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "smallvec" version = "1.6.1" @@ -306,6 +335,15 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + [[package]] name = "unicode-width" version = "0.1.8" diff --git a/Cargo.toml b/Cargo.toml index 989c75909..2fe655c97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ intervaltree = "0.2" # For binaries clap = {version = "2.33", default-features = false} +cargo_toml = "0.10" [dev-dependencies] lazy_static = "1.4" diff --git a/ide/build.cjs b/ide/build.cjs index 261148718..a21c4cb1e 100644 --- a/ide/build.cjs +++ b/ide/build.cjs @@ -8,9 +8,11 @@ const pkg = require("./package.json"); const options = cli(); const rust_toolchain = toml.parse(fs.readFileSync("../rust-toolchain.toml")); +const install_script = fs.readFileSync('../scripts/install-binaries.sh').toString(); const define = { TOOLCHAIN: JSON.stringify(rust_toolchain.toolchain), - VERSION: JSON.stringify(pkg.version) + VERSION: JSON.stringify(pkg.version), + INSTALL_SCRIPT: JSON.stringify(install_script) }; let common = { diff --git a/ide/src/effects.ts b/ide/src/effects.ts index cc0b154e5..6953d7843 100644 --- a/ide/src/effects.ts +++ b/ide/src/effects.ts @@ -29,7 +29,6 @@ export let effects = async ( try { let cmd = `effects ${doc.fileName} ${doc.offsetAt(selection.anchor)}`; let stdout = await call_flowistry(cmd); - log(stdout); let lines = stdout.split("\n"); let last_line = lines[lines.length - 1]; let effects: Effects = JSON.parse(last_line); diff --git a/ide/src/setup.ts b/ide/src/setup.ts index 415649f09..0c5c1ee44 100644 --- a/ide/src/setup.ts +++ b/ide/src/setup.ts @@ -9,6 +9,7 @@ declare const TOOLCHAIN: { channel: string; components: string[]; }; +declare const INSTALL_SCRIPT: string; const SHOW_LOADER_THRESHOLD = 1000; @@ -99,11 +100,19 @@ export async function setup(): Promise { if (version != VERSION) { let components = TOOLCHAIN.components.join(","); let rustup_cmd = `rustup toolchain install ${TOOLCHAIN.channel} -c ${components}`; - let cargo_cmd = `${cargo} install flowistry --version ${VERSION} --force`; - await exec( - `${rustup_cmd} && ${cargo_cmd}`, - "Installing Flowistry crate... (this may take a minute)" - ); + await exec(rustup_cmd, "Installing nightly Rust..."); + + try { + await exec(INSTALL_SCRIPT, "Downloading Flowistry binaries..."); + } catch (e) { + log("Install script failed with error:", e.toString()); + + let cargo_cmd = `${cargo} install flowistry --version ${VERSION} --force`; + await exec( + cargo_cmd, + "Flowistry binaries not available, instead installing Flowistry crate from source... (this may take a minute)" + ); + } if (version == "") { vscode.window.showInformationMessage( diff --git a/ide/src/slicing.ts b/ide/src/slicing.ts index b1b8ca3e1..30ed8196a 100644 --- a/ide/src/slicing.ts +++ b/ide/src/slicing.ts @@ -119,7 +119,6 @@ export async function slice( let stdout = await call_flowistry(cmd); let lines = stdout.split("\n"); - log(lines); let last_line = lines[lines.length - 1]; let slice_output: SliceOutput = JSON.parse(last_line); diff --git a/scripts/install-binaries.sh b/scripts/install-binaries.sh new file mode 100755 index 000000000..6293a0a59 --- /dev/null +++ b/scripts/install-binaries.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e +cd $(mktemp -d) + +REPO="willcrichton/flowistry" +TARGET=$(rustc -Vv | grep host | cut -d' ' -f2) +LATEST=$(curl -s https://api.github.com/repos/${REPO}/releases/latest | jq -r '.name') +RELEASE_URL="https://github.com/${REPO}/releases/download/${LATEST}" + +BINARY_PATH="${TARGET}.tar.gz" +BINARY_URL="${RELEASE_URL}/${BINARY_PATH}" +LOCAL_BIN_DIR="${CARGO_HOME:-$HOME/.cargo}/bin" + +if wget -q --spider ${BINARY_URL}; then + wget -q ${BINARY_URL} + tar -xf ${BINARY_PATH} + rm ${BINARY_PATH} + mkdir -p ${LOCAL_BIN_DIR} + mv ./* ${LOCAL_BIN_DIR} +else + exit 1 +fi \ No newline at end of file diff --git a/src/bin/cargo-flowistry.rs b/src/bin/cargo-flowistry.rs index db82dd882..76d453b57 100644 --- a/src/bin/cargo-flowistry.rs +++ b/src/bin/cargo-flowistry.rs @@ -5,6 +5,7 @@ extern crate rustc_interface; use clap::clap_app; use std::{ env, + path::PathBuf, process::{exit, Command}, }; @@ -40,21 +41,27 @@ fn main() { ) .get_matches_from(env::args().skip(1)); - let mut args = match matches.subcommand() { + let (mut args, file_name) = match matches.subcommand() { ("rustc_version", _) => { let commit_hash = rustc_interface::util::commit_hash_str().unwrap_or("unknown"); println!("{}", commit_hash); exit(0); } - ("backward_slice" | "forward_slice", Some(sub_m)) => vec![ - ("FILE", sub_m.value_of("file").unwrap()), - ("START", sub_m.value_of("start").unwrap()), - ("END", sub_m.value_of("end").unwrap()), - ], - ("effects", Some(sub_m)) => vec![ - ("FILE", sub_m.value_of("file").unwrap()), - ("POS", sub_m.value_of("pos").unwrap()), - ], + ("backward_slice" | "forward_slice", Some(sub_m)) => ( + vec![ + ("FILE", sub_m.value_of("file").unwrap()), + ("START", sub_m.value_of("start").unwrap()), + ("END", sub_m.value_of("end").unwrap()), + ], + sub_m.value_of("file").unwrap(), + ), + ("effects", Some(sub_m)) => ( + vec![ + ("FILE", sub_m.value_of("file").unwrap()), + ("POS", sub_m.value_of("pos").unwrap()), + ], + sub_m.value_of("file").unwrap(), + ), _ => { unimplemented!() } @@ -66,14 +73,33 @@ fn main() { }; args.push(("COMMAND", cmd)); + let mut file_path = PathBuf::from(file_name); + let mut package = None; + while let Some(parent) = file_path.parent() { + file_path = parent.to_path_buf(); + + let manifest_path = file_path.join("Cargo.toml"); + if manifest_path.exists() { + let manifest = cargo_toml::Manifest::from_path(manifest_path).unwrap(); + package = Some(manifest.package.unwrap().name); + break; + } + } + let mut cmd = Command::new(cargo_path); cmd .arg("check") .arg("-q") - .arg("--all") .args(flags) .env("RUSTC_WORKSPACE_WRAPPER", flowistry_rustc_path); + match package { + Some(package) => { + cmd.arg("-p").arg(package); + } + None => panic!("Could not find package for file: {}", file_path.display()), + }; + for (k, v) in args { cmd.env(format!("FLOWISTRY_{}", k), v); }