Skip to content

Commit 32b1ed1

Browse files
committed
Auto merge of #9767 - nipunn1313:refactor, r=alexcrichton
Refactor fake_file() away from cargo_command tests There are already similar preexisting test helpers which also work on windows. Port over the executable-creation helper into the file() helper and things appear to pass. Was inspired to do this when trying to add tests to solve a separate issue.
2 parents 9815087 + dde290e commit 32b1ed1

File tree

2 files changed

+54
-79
lines changed

2 files changed

+54
-79
lines changed

crates/cargo-test-support/src/lib.rs

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,36 @@ pub mod tools;
7070
struct FileBuilder {
7171
path: PathBuf,
7272
body: String,
73+
executable: bool,
7374
}
7475

7576
impl FileBuilder {
76-
pub fn new(path: PathBuf, body: &str) -> FileBuilder {
77+
pub fn new(path: PathBuf, body: &str, executable: bool) -> FileBuilder {
7778
FileBuilder {
7879
path,
7980
body: body.to_string(),
81+
executable: executable,
8082
}
8183
}
8284

83-
fn mk(&self) {
85+
fn mk(&mut self) {
86+
if self.executable {
87+
self.path.set_extension(env::consts::EXE_EXTENSION);
88+
}
89+
8490
self.dirname().mkdir_p();
8591
fs::write(&self.path, &self.body)
8692
.unwrap_or_else(|e| panic!("could not create file {}: {}", self.path.display(), e));
93+
94+
#[cfg(unix)]
95+
if self.executable {
96+
use std::os::unix::fs::PermissionsExt;
97+
98+
let mut perms = fs::metadata(&self.path).unwrap().permissions();
99+
let mode = perms.mode();
100+
perms.set_mode(mode | 0o111);
101+
fs::set_permissions(&self.path, perms).unwrap();
102+
}
87103
}
88104

89105
fn dirname(&self) -> &Path {
@@ -122,11 +138,16 @@ impl SymlinkBuilder {
122138
}
123139

124140
#[cfg(windows)]
125-
fn mk(&self) {
141+
fn mk(&mut self) {
126142
self.dirname().mkdir_p();
127143
if self.src_is_dir {
128144
t!(os::windows::fs::symlink_dir(&self.dst, &self.src));
129145
} else {
146+
if let Some(ext) = self.dst.extension() {
147+
if ext == env::consts::EXE_EXTENSION {
148+
self.src.set_extension(ext);
149+
}
150+
}
130151
t!(os::windows::fs::symlink_file(&self.dst, &self.src));
131152
}
132153
}
@@ -177,13 +198,22 @@ impl ProjectBuilder {
177198

178199
/// Adds a file to the project.
179200
pub fn file<B: AsRef<Path>>(mut self, path: B, body: &str) -> Self {
180-
self._file(path.as_ref(), body);
201+
self._file(path.as_ref(), body, false);
181202
self
182203
}
183204

184-
fn _file(&mut self, path: &Path, body: &str) {
185-
self.files
186-
.push(FileBuilder::new(self.root.root().join(path), body));
205+
/// Adds an executable file to the project.
206+
pub fn executable<B: AsRef<Path>>(mut self, path: B, body: &str) -> Self {
207+
self._file(path.as_ref(), body, true);
208+
self
209+
}
210+
211+
fn _file(&mut self, path: &Path, body: &str, executable: bool) {
212+
self.files.push(FileBuilder::new(
213+
self.root.root().join(path),
214+
body,
215+
executable,
216+
));
187217
}
188218

189219
/// Adds a symlink to a file to the project.
@@ -219,13 +249,17 @@ impl ProjectBuilder {
219249

220250
let manifest_path = self.root.root().join("Cargo.toml");
221251
if !self.no_manifest && self.files.iter().all(|fb| fb.path != manifest_path) {
222-
self._file(Path::new("Cargo.toml"), &basic_manifest("foo", "0.0.1"))
252+
self._file(
253+
Path::new("Cargo.toml"),
254+
&basic_manifest("foo", "0.0.1"),
255+
false,
256+
)
223257
}
224258

225259
let past = time::SystemTime::now() - Duration::new(1, 0);
226260
let ftime = filetime::FileTime::from_system_time(past);
227261

228-
for file in self.files.iter() {
262+
for file in self.files.iter_mut() {
229263
file.mk();
230264
if is_coarse_mtime() {
231265
// Place the entire project 1 second in the past to ensure
@@ -237,7 +271,7 @@ impl ProjectBuilder {
237271
}
238272
}
239273

240-
for symlink in self.symlinks.iter() {
274+
for symlink in self.symlinks.iter_mut() {
241275
symlink.mk();
242276
}
243277

@@ -316,7 +350,7 @@ impl Project {
316350

317351
/// Changes the contents of an existing file.
318352
pub fn change_file(&self, path: &str, body: &str) {
319-
FileBuilder::new(self.root().join(path), body).mk()
353+
FileBuilder::new(self.root().join(path), body, false).mk()
320354
}
321355

322356
/// Creates a `ProcessBuilder` to run a program in the project

tests/testsuite/cargo_command.rs

Lines changed: 9 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,16 @@
11
//! Tests for custom cargo commands and other global command features.
22
33
use std::env;
4-
use std::fs::{self, File};
4+
use std::fs;
55
use std::io::Read;
66
use std::path::{Path, PathBuf};
77
use std::process::Stdio;
88
use std::str;
99

1010
use cargo_test_support::cargo_process;
11-
use cargo_test_support::paths::{self, CargoPathExt};
11+
use cargo_test_support::paths;
1212
use cargo_test_support::registry::Package;
13-
use cargo_test_support::{basic_bin_manifest, basic_manifest, cargo_exe, project, Project};
14-
15-
#[cfg_attr(windows, allow(dead_code))]
16-
enum FakeKind<'a> {
17-
Executable,
18-
Symlink { target: &'a Path },
19-
}
20-
21-
/// Adds an empty file with executable flags (and platform-dependent suffix).
22-
//
23-
// TODO: move this to `Project` if other cases using this emerge.
24-
fn fake_file(proj: Project, dir: &Path, name: &str, kind: &FakeKind<'_>) -> Project {
25-
let path = proj
26-
.root()
27-
.join(dir)
28-
.join(&format!("{}{}", name, env::consts::EXE_SUFFIX));
29-
path.parent().unwrap().mkdir_p();
30-
match *kind {
31-
FakeKind::Executable => {
32-
File::create(&path).unwrap();
33-
make_executable(&path);
34-
}
35-
FakeKind::Symlink { target } => {
36-
make_symlink(&path, target);
37-
}
38-
}
39-
return proj;
40-
41-
#[cfg(unix)]
42-
fn make_executable(p: &Path) {
43-
use std::os::unix::prelude::*;
44-
45-
let mut perms = fs::metadata(p).unwrap().permissions();
46-
let mode = perms.mode();
47-
perms.set_mode(mode | 0o111);
48-
fs::set_permissions(p, perms).unwrap();
49-
}
50-
#[cfg(windows)]
51-
fn make_executable(_: &Path) {}
52-
#[cfg(unix)]
53-
fn make_symlink(p: &Path, t: &Path) {
54-
::std::os::unix::fs::symlink(t, p).expect("Failed to create symlink");
55-
}
56-
#[cfg(windows)]
57-
fn make_symlink(_: &Path, _: &Path) {
58-
panic!("Not supported")
59-
}
60-
}
13+
use cargo_test_support::{basic_bin_manifest, basic_manifest, cargo_exe, project};
6114

6215
fn path() -> Vec<PathBuf> {
6316
env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect()
@@ -91,13 +44,9 @@ fn list_aliases_with_descriptions() {
9144

9245
#[cargo_test]
9346
fn list_command_looks_at_path() {
94-
let proj = project().build();
95-
let proj = fake_file(
96-
proj,
97-
Path::new("path-test"),
98-
"cargo-1",
99-
&FakeKind::Executable,
100-
);
47+
let proj = project()
48+
.executable(Path::new("path-test").join("cargo-1"), "")
49+
.build();
10150

10251
let mut path = path();
10352
path.push(proj.root().join("path-test"));
@@ -114,19 +63,11 @@ fn list_command_looks_at_path() {
11463
);
11564
}
11665

117-
// Windows and symlinks don't currently mix well.
118-
#[cfg(unix)]
11966
#[cargo_test]
12067
fn list_command_resolves_symlinks() {
121-
let proj = project().build();
122-
let proj = fake_file(
123-
proj,
124-
Path::new("path-test"),
125-
"cargo-2",
126-
&FakeKind::Symlink {
127-
target: &cargo_exe(),
128-
},
129-
);
68+
let proj = project()
69+
.symlink(cargo_exe(), Path::new("path-test").join("cargo-2"))
70+
.build();
13071

13172
let mut path = path();
13273
path.push(proj.root().join("path-test"));

0 commit comments

Comments
 (0)