Skip to content

Commit 4805a7b

Browse files
committed
Add Windows implementation of rename
1 parent de9f3cc commit 4805a7b

File tree

2 files changed

+57
-13
lines changed

2 files changed

+57
-13
lines changed

collector/src/execute.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::{BuildKind, Compiler, RunKind};
44
use anyhow::{anyhow, bail, Context};
5-
use collector::command_output;
5+
use collector::{command_output, robocopy};
66
use database::{PatchName, QueryLabel};
77
use futures::stream::FuturesUnordered;
88
use futures::stream::StreamExt;
@@ -23,6 +23,20 @@ use tokio::runtime::Runtime;
2323

2424
mod rustc;
2525

26+
#[cfg(windows)]
27+
fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> anyhow::Result<()> {
28+
let (from, to) = (from.as_ref(), to.as_ref());
29+
30+
let ctx = format!("renaming file {:?} to {:?}", from, to);
31+
32+
if fs::metadata(from)?.is_file() {
33+
return Ok(fs::rename(from, to).with_context(|| ctx.clone())?);
34+
}
35+
36+
robocopy(from, to, &[&"/move"]).with_context(|| ctx.clone())
37+
}
38+
39+
#[cfg(unix)]
2640
fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> anyhow::Result<()> {
2741
let (from, to) = (from.as_ref(), to.as_ref());
2842
if fs::rename(from, to).is_err() {

collector/src/lib.rs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use chrono::NaiveDate;
22
pub use database::{Commit, PatchName, QueryLabel};
33
use serde::Deserialize;
4-
use std::cmp::PartialOrd;
4+
use std::{cmp::PartialOrd, ffi::OsStr, path::Path};
55
use std::fmt;
66
use std::process::{self, Command};
77

@@ -144,7 +144,31 @@ pub fn run_command(cmd: &mut Command) -> anyhow::Result<()> {
144144
Ok(())
145145
}
146146

147-
pub fn command_output(cmd: &mut Command) -> anyhow::Result<process::Output> {
147+
#[cfg(windows)]
148+
pub fn robocopy(from: &Path, to: &Path, extra_args: &[&dyn AsRef<OsStr>]) -> anyhow::Result<()> {
149+
let mut cmd = Command::new("robocopy");
150+
cmd.arg(from).arg(to).arg("/s").arg("/e");
151+
152+
for arg in extra_args {
153+
cmd.arg(arg.as_ref());
154+
}
155+
156+
let output = run_command_with_output(&mut cmd)?;
157+
158+
if output.status.code() >= Some(8) {
159+
// robocopy returns 0-7 on success
160+
return Err(anyhow::anyhow!(
161+
"expected success, got {}\n\nstderr={}\n\n stdout={}",
162+
output.status,
163+
String::from_utf8_lossy(&output.stderr),
164+
String::from_utf8_lossy(&output.stdout)
165+
));
166+
}
167+
168+
Ok(())
169+
}
170+
171+
fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output> {
148172
log::trace!("running: {:?}", cmd);
149173
let mut child = cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).spawn()?;
150174

@@ -174,19 +198,25 @@ pub fn command_output(cmd: &mut Command) -> anyhow::Result<process::Output> {
174198
)?;
175199

176200
let status = child.wait()?;
177-
if !status.success() {
178-
return Err(anyhow::anyhow!(
179-
"expected success, got {}\n\nstderr={}\n\n stdout={}",
180-
status,
181-
String::from_utf8_lossy(&stderr),
182-
String::from_utf8_lossy(&stdout)
183-
));
184-
}
185201

186-
let output = process::Output {
202+
Ok(process::Output {
187203
status,
188204
stdout: stdout,
189205
stderr: stderr,
190-
};
206+
})
207+
}
208+
209+
pub fn command_output(cmd: &mut Command) -> anyhow::Result<process::Output> {
210+
let output = run_command_with_output(cmd)?;
211+
212+
if !output.status.success() {
213+
return Err(anyhow::anyhow!(
214+
"expected success, got {}\n\nstderr={}\n\n stdout={}",
215+
output.status,
216+
String::from_utf8_lossy(&output.stderr),
217+
String::from_utf8_lossy(&output.stdout)
218+
));
219+
}
220+
191221
Ok(output)
192222
}

0 commit comments

Comments
 (0)