Skip to content

Commit

Permalink
Broken Build:
Browse files Browse the repository at this point in the history
	lib: rustfmt output to stdout
	Simplify the rustfmt and write mechanism.
  • Loading branch information
manaskarekar committed Oct 22, 2017
1 parent 8582a90 commit ad4fe98
Showing 1 changed file with 91 additions and 13 deletions.
104 changes: 91 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1580,18 +1580,15 @@ impl Bindings {

/// Write these bindings as source text to a file.
pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
{
let file = try!(
OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(path.as_ref())
);
self.write(Box::new(file))?;
}

self.rustfmt_generated_file(path.as_ref())
let file = try!(
OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(path.as_ref())
);
self.write(Box::new(file))?;
Ok(())
}

/// Write these bindings as source text to the given `Write`able.
Expand All @@ -1604,11 +1601,19 @@ impl Bindings {
writer.write(line.as_bytes())?;
writer.write("\n".as_bytes())?;
}

if !self.options.raw_lines.is_empty() {
writer.write("\n".as_bytes())?;
}

writer.write(self.module.as_str().as_bytes())?;
let bindings = self.module.as_str().to_string();

match self.rustfmt_generated_string(bindings) {
Ok(rustfmt_bindings) => {
writer.write(rustfmt_bindings.as_str().as_bytes())?;
},
Err(err) => eprintln!("{:?}", err),
}
Ok(())
}

Expand Down Expand Up @@ -1668,6 +1673,79 @@ impl Bindings {
))
}
}

/// Checks if rustfmt_bindings is set and runs rustfmt on the string
//fn rustfmt_generated_string(&self, source: String) -> io::Result<Option<(String, String)>> {
fn rustfmt_generated_string(&self, source: String) -> io::Result<String> {
let _t = self.context.timer("rustfmt_generated_string");

if !self.context.options().rustfmt_bindings {
return Ok(source);
}

let rustfmt = if let Ok(rustfmt) = which::which("rustfmt") {
rustfmt
} else {
eprintln!("warning: could not find usable rustfmt to pretty print bindings");
return Ok(source);
};

let mut cmd = if let Ok(rustup) = which::which("rustup") {
let mut cmd = Command::new(rustup);
cmd.args(&["run", "nightly", "rustfmt", "--"]);
cmd
} else {
Command::new(rustfmt)
};

cmd
.args(&["--write-mode=display"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped());

if let Some(path) = self.context
.options()
.rustfmt_configuration_file
.as_ref()
.and_then(|f| f.to_str())
{
cmd.args(&["--config-path", path]);
}

let mut child = cmd.spawn().expect("Failed to spawn rustfmt.");
let mut child_stdin = child.stdin.take().unwrap();
let mut child_stdout = child.stdout.take().unwrap();
let mut child_stderr = child.stderr.take().unwrap();

// Write to stdin in a new thread, so that we can read from stdout on this
// thread. This keeps the child from blocking on writing to its stdout which
// might block us from writing to its stdin.
let stdin_handle = ::std::thread::spawn(move || {
child_stdin.write_all(source.as_bytes())
});

// Read stderr on a new thread for similar reasons.
let stderr_handle = ::std::thread::spawn(move || {
let mut output = vec![];
io::copy(&mut child_stderr, &mut output)
.map(|_| String::from_utf8_lossy(&output).to_string())
});

let mut output = vec![];
io::copy(&mut child_stdout, &mut output)
.expect("Should copy stdout into vec OK");

// Ignore actual rustfmt status because it is often non-zero for trivial
// things.
let _ = child.wait().expect("should wait on rustfmt child OK");

stdin_handle.join();
let bindings = String::from_utf8(output).unwrap();
let child_stderr = stderr_handle.join();

Ok(bindings)
}
}

/// Determines whether the given cursor is in any of the files matched by the
Expand Down

0 comments on commit ad4fe98

Please sign in to comment.