Skip to content
This repository was archived by the owner on Nov 24, 2023. It is now read-only.

Commit ccbe3db

Browse files
authored
Merge pull request #91 from alexcrichton/do-not-lie-if-not-fixing
Don't print "Fixing" if fixes are reverted
2 parents 5d20194 + b2ddfeb commit ccbe3db

File tree

4 files changed

+69
-16
lines changed

4 files changed

+69
-16
lines changed

cargo-fix/src/diagnostics.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
//! cross-platform way.
33
44
use std::env;
5-
use std::io::BufReader;
6-
use std::net::{SocketAddr, TcpListener, TcpStream};
5+
use std::io::{BufReader, Write, Read};
6+
use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream};
77
use std::thread::{self, JoinHandle};
88

99
use failure::{Error, ResultExt};
@@ -29,8 +29,16 @@ impl Message {
2929
let mut client =
3030
TcpStream::connect(&addr).context("failed to connect to parent diagnostics target")?;
3131

32-
serde_json::to_writer(&mut client, &self)
32+
let s = serde_json::to_string(self)
33+
.context("failed to serialize message")?;
34+
client.write_all(s.as_bytes())
3335
.context("failed to write message to diagnostics target")?;
36+
client.shutdown(Shutdown::Write)
37+
.context("failed to shutdown")?;
38+
39+
let mut tmp = Vec::new();
40+
client.read_to_end(&mut tmp)
41+
.context("failed to receive a disconnect")?;
3442

3543
Ok(())
3644
}

cargo-fix/src/main.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use std::path::Path;
2222
use rustfix::diagnostics::Diagnostic;
2323
use failure::{Error, ResultExt};
2424

25+
use diagnostics::Message;
26+
2527
mod cli;
2628
mod lock;
2729
mod diagnostics;
@@ -65,11 +67,11 @@ fn cargo_fix_rustc() -> Result<(), Error> {
6567
// To that end we only actually try to fix things if it looks like we're
6668
// compiling a Rust file and it *doesn't* have an absolute filename. That's
6769
// not the best heuristic but matches what Cargo does today at least.
68-
let mut files_to_restore = HashMap::new();
70+
let mut fixes = FixedCrate::default();
6971
if let Some(path) = filename {
7072
if !Path::new(&path).is_absolute() {
7173
trace!("start rustfixing {:?}", path);
72-
files_to_restore = rustfix_crate(rustc.as_ref(), &path)?;
74+
fixes = rustfix_crate(rustc.as_ref(), &path)?;
7375
}
7476
}
7577

@@ -84,9 +86,15 @@ fn cargo_fix_rustc() -> Result<(), Error> {
8486
let mut cmd = Command::new(&rustc);
8587
cmd.args(env::args().skip(1));
8688
cmd.arg("--cap-lints=warn");
87-
if files_to_restore.len() > 0 {
89+
if fixes.original_files.len() > 0 {
8890
let output = cmd.output().context("failed to spawn rustc")?;
8991

92+
if output.status.success() {
93+
for message in fixes.messages.drain(..) {
94+
message.post()?;
95+
}
96+
}
97+
9098
// If we succeeded then we'll want to commit to the changes we made, if
9199
// any. If stderr is empty then there's no need for the final exec at
92100
// the end, we just bail out here.
@@ -98,7 +106,7 @@ fn cargo_fix_rustc() -> Result<(), Error> {
98106
// user's code with our changes. Back out everything and fall through
99107
// below to recompile again.
100108
if !output.status.success() {
101-
for (k, v) in files_to_restore {
109+
for (k, v) in fixes.original_files {
102110
File::create(&k)
103111
.and_then(|mut f| f.write_all(v.as_bytes()))
104112
.with_context(|_| format!("failed to write file `{}`", k))?;
@@ -109,7 +117,13 @@ fn cargo_fix_rustc() -> Result<(), Error> {
109117
exit_with(cmd.status().context("failed to spawn rustc")?);
110118
}
111119

112-
fn rustfix_crate(rustc: &Path, filename: &str) -> Result<HashMap<String, String>, Error> {
120+
#[derive(Default)]
121+
struct FixedCrate {
122+
messages: Vec<Message>,
123+
original_files: HashMap<String, String>,
124+
}
125+
126+
fn rustfix_crate(rustc: &Path, filename: &str) -> Result<FixedCrate, Error> {
113127
// If not empty, filter by these lints
114128
//
115129
// TODO: Implement a way to specify this
@@ -143,7 +157,7 @@ fn rustfix_crate(rustc: &Path, filename: &str) -> Result<HashMap<String, String>
143157
filename,
144158
output.status.code()
145159
);
146-
return Ok(HashMap::new());
160+
return Ok(Default::default())
147161
}
148162

149163
// Sift through the output of the compiler to look for JSON messages
@@ -194,7 +208,8 @@ fn rustfix_crate(rustc: &Path, filename: &str) -> Result<HashMap<String, String>
194208
num_suggestion, filename
195209
);
196210

197-
let mut old_files = HashMap::with_capacity(file_map.len());
211+
let mut original_files = HashMap::with_capacity(file_map.len());
212+
let mut messages = Vec::new();
198213
for (file, suggestions) in file_map {
199214
// Attempt to read the source code for this file. If this fails then
200215
// that'd be pretty surprising, so log a message and otherwise keep
@@ -207,16 +222,19 @@ fn rustfix_crate(rustc: &Path, filename: &str) -> Result<HashMap<String, String>
207222
let num_suggestions = suggestions.len();
208223
debug!("applying {} fixes to {}", num_suggestions, file);
209224

210-
diagnostics::Message::fixing(&file, num_suggestion).post()?;
225+
messages.push(Message::fixing(&file, num_suggestions));
211226

212227
let new_code = rustfix::apply_suggestions(&code, &suggestions)?;
213228
File::create(&file)
214229
.and_then(|mut f| f.write_all(new_code.as_bytes()))
215230
.with_context(|_| format!("failed to write file `{}`", file))?;
216-
old_files.insert(file, code);
231+
original_files.insert(file, code);
217232
}
218233

219-
Ok(old_files)
234+
Ok(FixedCrate {
235+
messages,
236+
original_files,
237+
})
220238
}
221239

222240
fn exit_with(status: ExitStatus) -> ! {

cargo-fix/tests/all/broken_build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ fn broken_fixes_backed_out() {
110110
.cwd("bar")
111111
.env("RUSTC", p.root.join("foo/target/debug/foo"))
112112
.stderr_contains("oh no")
113+
.stderr_not_contains("[FIXING]")
113114
.status(101)
114115
.run();
115116

cargo-fix/tests/all/main.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ impl Project {
8383
stdout_contains: Vec::new(),
8484
stderr: None,
8585
stderr_contains: Vec::new(),
86+
stderr_not_contains: Vec::new(),
8687
status: 0,
8788
ran: false,
8889
cwd: None,
@@ -108,6 +109,7 @@ struct ExpectCmd<'a> {
108109
stdout_contains: Vec<String>,
109110
stderr: Option<String>,
110111
stderr_contains: Vec<String>,
112+
stderr_not_contains: Vec<String>,
111113
status: i32,
112114
cwd: Option<PathBuf>,
113115
}
@@ -144,6 +146,11 @@ impl<'a> ExpectCmd<'a> {
144146
self
145147
}
146148

149+
fn stderr_not_contains(&mut self, s: &str) -> &mut Self {
150+
self.stderr_not_contains.push(s.to_string());
151+
self
152+
}
153+
147154
fn run(&mut self) {
148155
self.ran = true;
149156
let mut parts = self.cmd.split_whitespace();
@@ -199,11 +206,22 @@ impl<'a> ExpectCmd<'a> {
199206
if code != self.status {
200207
panic!("expected exit code `{}` got `{}`", self.status, code);
201208
}
202-
self.match_std(&output.stdout, &self.stdout, &self.stdout_contains);
203-
self.match_std(&output.stderr, &self.stderr, &self.stderr_contains);
209+
self.match_std(&output.stdout, &self.stdout, &self.stdout_contains, &[]);
210+
self.match_std(
211+
&output.stderr,
212+
&self.stderr,
213+
&self.stderr_contains,
214+
&self.stderr_not_contains,
215+
);
204216
}
205217

206-
fn match_std(&self, actual: &[u8], expected: &Option<String>, contains: &[String]) {
218+
fn match_std(
219+
&self,
220+
actual: &[u8],
221+
expected: &Option<String>,
222+
contains: &[String],
223+
not_contains: &[String],
224+
) {
207225
let actual = match str::from_utf8(actual) {
208226
Ok(s) => s,
209227
Err(_) => panic!("std wasn't utf8"),
@@ -224,6 +242,14 @@ impl<'a> ExpectCmd<'a> {
224242
);
225243
panic!("test failed");
226244
}
245+
for s in not_contains {
246+
let s = self.clean(s);
247+
if !actual.contains(&s) {
248+
continue;
249+
}
250+
println!("expected to not find `{}`", s);
251+
panic!("test failed");
252+
}
227253
}
228254

229255
fn clean(&self, s: &str) -> String {

0 commit comments

Comments
 (0)