This repository was archived by the owner on Dec 29, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 254
Support simple external builds #988
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
//! Performs a build using a provided black-box build command, which ought to | ||
//! return a list of save-analysis JSON files to be reloaded by the RLS. | ||
//! Please note that since the command is ran externally (at a file/OS level) | ||
//! this doesn't work with files that are not saved. | ||
|
||
use std::io::BufRead; | ||
use std::io::Read; | ||
use std::fs::File; | ||
use std::path::{Path, PathBuf}; | ||
use std::process::{Command, Stdio}; | ||
|
||
use super::BuildResult; | ||
|
||
use rls_data::Analysis; | ||
use log::{log, trace}; | ||
|
||
/// Performs a build using an external command and interprets the results. | ||
/// The command should output on stdout a list of save-analysis .json files | ||
/// 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>>(cmd_line: S, build_dir: PathBuf) -> BuildResult { | ||
let cmd_line = cmd_line.as_ref(); | ||
let (cmd, args) = { | ||
let mut words = cmd_line.split_whitespace(); | ||
let cmd = match words.next() { | ||
Some(cmd) => cmd, | ||
None => { | ||
return BuildResult::Err("Specified build_command is empty".into(), None); | ||
} | ||
}; | ||
(cmd, words) | ||
}; | ||
let spawned = Command::new(&cmd) | ||
.args(args) | ||
.current_dir(&build_dir) | ||
.stdout(Stdio::piped()) | ||
.stderr(Stdio::null()) | ||
.spawn(); | ||
|
||
let child = match spawned { | ||
Ok(child) => child, | ||
Err(io) => { | ||
let err_msg = format!("Couldn't execute: {} ({:?})", cmd_line, io.kind()); | ||
trace!("{}", err_msg); | ||
return BuildResult::Err(err_msg, Some(cmd_line.to_owned())); | ||
}, | ||
}; | ||
|
||
let reader = std::io::BufReader::new(child.stdout.unwrap()); | ||
|
||
let files = reader.lines().filter_map(|res| res.ok()) | ||
.map(PathBuf::from) | ||
// Relative paths are relative to build command, not RLS itself (cwd may be different) | ||
.map(|path| if !path.is_absolute() { build_dir.join(path) } else { path }); | ||
|
||
let analyses = match read_analysis_files(files) { | ||
Ok(analyses) => analyses, | ||
Err(cause) => { | ||
let err_msg = format!("Couldn't read analysis data: {}", cause); | ||
return BuildResult::Err(err_msg, Some(cmd_line.to_owned())); | ||
} | ||
}; | ||
|
||
BuildResult::Success(build_dir.clone(), vec![], analyses, false) | ||
} | ||
|
||
/// 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> | ||
where | ||
I: Iterator, | ||
I::Item: AsRef<Path> | ||
{ | ||
let mut analyses = Vec::new(); | ||
|
||
for path in files { | ||
trace!("external::read_analysis_files: Attempt to read `{}`", path.as_ref().display()); | ||
|
||
let mut file = File::open(path).map_err(|e| e.to_string())?; | ||
let mut contents = String::new(); | ||
file.read_to_string(&mut contents).map_err(|e| e.to_string())?; | ||
|
||
let data = rustc_serialize::json::decode(&contents).map_err(|e| e.to_string())?; | ||
analyses.push(data); | ||
} | ||
|
||
Ok(analyses) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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.There was a problem hiding this comment.
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 theAnalysisHost
with a new one, retaining current index, but with a different genericAnalysisLoader
?There was a problem hiding this comment.
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?