Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Support simple external builds #988

Merged
merged 3 commits into from
Aug 30, 2018
Merged

Conversation

Xanewok
Copy link
Member

@Xanewok Xanewok commented Aug 14, 2018

@nrc this is the implementation of external build we talked about.
What's left is resolving the timeout issue (otherwise RLS will be stuck waiting 'building' if the build command loops) and resolving the pathbuf (de)serialize in rls-data (rustc serializes it with rustc-serialize, added a Deserialize impl for Serde backend deserializing with rustc-serialize format).

Since I worked on integrating this with Buck, here's a simple script that I used:

#!/bin/bash

# $1 - input file
# Output - directories of rebuilt json files
BUCK=~/repos/buck/bin/buck

RULE=$("$BUCK" query "owner($1)")
DEPS=$("$BUCK" query "kind('^rust_.*$', deps($RULE))")
for dep in $DEPS; do
	# Outputs save-analysis file for each dependency lib/bin
	$BUCK build "$dep#save-analysis" --show-output | awk '{print $2}'
done

which for "rust.build_command": "/home/xanewok/.../script.sh server/src/main.rs, for example, outputs:

buck-out/gen/server/server#default,save-analysis/save-analysis/server-e9d875ca101d0939.json
buck-out/gen/project1/project1#default,save-analysis/save-analysis/libproject1-f0ccf02843c7368b.json
buck-out/gen/project2/project2#default,save-analysis/save-analysis/libproject2-a1b98c5ddb92a465.json

As of now, build command does not support diagnostics, but I imagine we could tweak it further and support diagnostics/save-analysis via different message JSON payloads.

@nrc do you think this is good for now as-is?

@jsgf
Copy link

jsgf commented Aug 14, 2018

This looks reasonable to me.

BTW, you can combine some of those buck operations to amortize its startup cost:

DEPS=$("$BUCK" query "kind('^rust_.*$', deps(owner($1)))")

and

$BUCK build --show-output $(for dep in $DEPS; do echo "$dep#save-analysis"; done) | awk '{print $2}'

@Xanewok
Copy link
Member Author

Xanewok commented Aug 16, 2018

r? @nrc

This is somewhat simplistic for now but do you think we could land this?

In addition to supporting diagnostics, at some point in the future it might be a good idea to also pass rustc invocations used in the build itself.

Copy link
Member

@nrc nrc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments inline, I think the only major one is about implementing AnalysisLoader.

src/config.rs Outdated
@@ -221,6 +229,10 @@ impl Config {
self.build_bin = Inferrable::Inferred(None);
self.build_lib = Inferrable::Inferred(false);
self.cfg_test = false;
self.build_command = None;
} else if !self.build_on_save {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of requiring build_on_save, you could set build_on_save to true if there is a build command

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

src/config.rs Outdated
@@ -157,6 +157,13 @@ pub struct Config {
/// local variable declaration. When set to false, the content is only availabe when
/// holding the `ctrl` key in some editors.
pub show_hover_context: bool,
/// EXPERIMENTAL (needs unstable features)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like you're enforcing the 'unstable features' requirement

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am resetting the option here if the unstable features are not enabled; am I missing something else?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are sorry, missed that. Looks fine.

/// to be reloaded by the RLS.
/// Note: This is *very* experimental and preliminary - this can viewed as
/// an experimentation until a more complete solution emerges.
pub(super) fn build_with_external_cmd<S: AsRef<str>>(path: S, build_dir: PathBuf) -> BuildResult {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path is the command line, rather than an actual path, correct? In which case it should have a more accurate name

},
};

// TODO: Timeout?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to timeout (given how long builds can take, I don't see how we can).


// TODO: Timeout?
let reader = std::io::BufReader::new(child.stdout.unwrap());
use std::io::BufRead;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: lift this to module scope.

/// Reads and deserializes given save-analysis JSON files into corresponding
/// `rls_data::Analysis` for each file. If an error is encountered, a `String`
/// with the error message is returned.
fn read_analysis_files<I>(files: I) -> Result<Vec<Analysis>, String>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better approach is to add another AnalysisLoader (see https://github.com/nrc/rls-analysis/blob/master/src/loader.rs) implementation to do the loading, that would keep the reading and deserialising of save-analysis encapsulated in rls-analysis rather than both there and the rls.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally didn't go with that, since it seems you can't incrementally load analysis with a different AnalysisLoader - we can only create a fresh one with a different loader.

I imagine we'd have to create new rls-analysis API that would allow us to incrementally load-once with a &dyn AnalysisLoader or allow us to replace the AnalysisHost with a new one, retaining current index, but with a different generic AnalysisLoader?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that sounds like a problem with the AnalysisLoader API, could you file an issue with details to the rls-analysis crate please?

This is currently enabled via `build_command` config option.
The specified command runs as a build procedure; it should output a
list of save-analysis .json files to be reloaded by the RLS so that the
usual features, e.g. type info on hover, work.

The `build_command` requires `build_on_save` (otherwise RLS needs a lot
of dummy rebuilds to sync the files and treat them as fresh)
@nrc
Copy link
Member

nrc commented Aug 30, 2018

Thanks for the changes!

@nrc nrc merged commit 783bfd0 into rust-lang:master Aug 30, 2018
bors added a commit to rust-lang/rust that referenced this pull request Sep 4, 2018
Update RLS and Rustfmt

RLS
* Allow project model to download crates ([#1020](rust-lang/rls#1020))
* Support simple external builds ([#988](rust-lang/rls#988))
* Support using external Rustfmt ([#990](rust-lang/rls#990))

Rustfmt (0.99.4)
* Format chains with comment ([#2899](https://github.com/rust-lang-nursery/rls/pull/2899))
* Do not show wildcard pattern in slice pattern ([#2912](https://github.com/rust-lang-nursery/rls/pull/2912))
* Impl only use ([#2951](https://github.com/rust-lang-nursery/rls/pull/2951))
* ... and [more](rust-lang/rustfmt@5c9a2b6...1c40881)

Bumped in tandem to pull a single version of `rustc-ap-*` libs.

r? @nrc
@Xanewok Xanewok deleted the external-build branch September 5, 2018 09:21
Xanewok added a commit to Xanewok/rls-vscode that referenced this pull request Sep 5, 2018
@damienmg
Copy link

damienmg commented Dec 1, 2018

@Xanewok: I took a deep look at this change this week to try to integrate with Bazel but I was wondering why go with list of Analysis vs cargo build --build-plan format, especially since the latter seems to be the format of RawInvocation, that is the format read by RLS.

I ask this specifically because the Analysis format does not support env variables nor declaring non-rust file dependencies (e.g. BUILD files or proto files) and it also seems to drop dependencies on crates that are not compiled in this project (i.e. external dependencies).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants