Skip to content

Commit 93a08f4

Browse files
committed
auto merge of #9802 : ben0x539/rust/mkdtemp-raii, r=alexcrichton
this incidentally stops `make check` from leaving directories in `/tmp` (Closes #9764)
2 parents 5bddcc1 + 63e9e49 commit 93a08f4

File tree

10 files changed

+616
-468
lines changed

10 files changed

+616
-468
lines changed

src/libextra/tempfile.rs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,63 @@ use std::os;
1515
use std::rand::Rng;
1616
use std::rand;
1717

18-
/// Attempts to make a temporary directory inside of `tmpdir` whose name will
19-
/// have the suffix `suffix`. If no directory can be created, None is returned.
20-
pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
21-
let mut r = rand::rng();
22-
for _ in range(0u, 1000) {
23-
let p = tmpdir.push(r.gen_ascii_str(16) + suffix);
24-
if os::make_dir(&p, 0x1c0) { // 700
25-
return Some(p);
18+
/// A wrapper for a path to temporary directory implementing automatic
19+
/// scope-pased deletion.
20+
pub struct TempDir {
21+
priv path: Option<Path>
22+
}
23+
24+
impl TempDir {
25+
/// Attempts to make a temporary directory inside of `tmpdir` whose name
26+
/// will have the suffix `suffix`. The directory will be automatically
27+
/// deleted once the returned wrapper is destroyed.
28+
///
29+
/// If no directory can be created, None is returned.
30+
pub fn new_in(tmpdir: &Path, suffix: &str) -> Option<TempDir> {
31+
if !tmpdir.is_absolute() {
32+
let abs_tmpdir = os::make_absolute(tmpdir);
33+
return TempDir::new_in(&abs_tmpdir, suffix);
34+
}
35+
36+
let mut r = rand::rng();
37+
for _ in range(0u, 1000) {
38+
let p = tmpdir.push(r.gen_ascii_str(16) + suffix);
39+
if os::make_dir(&p, 0x1c0) { // 700
40+
return Some(TempDir { path: Some(p) });
41+
}
42+
}
43+
None
44+
}
45+
46+
/// Attempts to make a temporary directory inside of `os::tmpdir()` whose
47+
/// name will have the suffix `suffix`. The directory will be automatically
48+
/// deleted once the returned wrapper is destroyed.
49+
///
50+
/// If no directory can be created, None is returned.
51+
pub fn new(suffix: &str) -> Option<TempDir> {
52+
TempDir::new_in(&os::tmpdir(), suffix)
53+
}
54+
55+
/// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
56+
/// This discards the wrapper so that the automatic deletion of the
57+
/// temporary directory is prevented.
58+
pub fn unwrap(self) -> Path {
59+
let mut tmpdir = self;
60+
tmpdir.path.take_unwrap()
61+
}
62+
63+
/// Access the wrapped `std::path::Path` to the temporary directory.
64+
pub fn path<'a>(&'a self) -> &'a Path {
65+
self.path.get_ref()
66+
}
67+
}
68+
69+
impl Drop for TempDir {
70+
fn drop(&mut self) {
71+
for path in self.path.iter() {
72+
os::remove_dir_recursive(path);
2673
}
2774
}
28-
None
2975
}
3076

3177
// the tests for this module need to change the path using change_dir,

src/libextra/test.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,8 +1148,7 @@ mod tests {
11481148
use test::{TestOpts, run_test};
11491149

11501150
use std::comm::{stream, SharedChan};
1151-
use tempfile;
1152-
use std::os;
1151+
use tempfile::TempDir;
11531152

11541153
#[test]
11551154
pub fn do_not_run_ignored_tests() {
@@ -1392,9 +1391,8 @@ mod tests {
13921391
13931392
pub fn ratchet_test() {
13941393
1395-
let dpth = tempfile::mkdtemp(&os::tmpdir(),
1396-
"test-ratchet").expect("missing test for ratchet");
1397-
let pth = dpth.push("ratchet.json");
1394+
let dpth = TempDir::new("test-ratchet").expect("missing test for ratchet");
1395+
let pth = dpth.path().push("ratchet.json");
13981396
13991397
let mut m1 = MetricMap::new();
14001398
m1.insert_metric("runtime", 1000.0, 2.0);
@@ -1432,7 +1430,5 @@ mod tests {
14321430
assert_eq!(m4.len(), 2);
14331431
assert_eq!(*(m4.find(&~"runtime").unwrap()), Metric { value: 1100.0, noise: 2.0 });
14341432
assert_eq!(*(m4.find(&~"throughput").unwrap()), Metric { value: 50.0, noise: 2.0 });
1435-
1436-
os::remove_dir_recursive(&dpth);
14371433
}
14381434
}

src/librustpkg/package_source.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,6 @@ impl PkgSrc {
239239
pub fn fetch_git(local: &Path, pkgid: &PkgId) -> Option<Path> {
240240
use conditions::git_checkout_failed::cond;
241241

242-
// We use a temporary directory because if the git clone fails,
243-
// it creates the target directory anyway and doesn't delete it
244-
245242
debug2!("Checking whether {} (path = {}) exists locally. Cwd = {}, does it? {:?}",
246243
pkgid.to_str(), pkgid.path.to_str(),
247244
os::getcwd().to_str(),

src/librustpkg/source_control.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
use std::{io, os, run, str};
1414
use std::run::{ProcessOutput, ProcessOptions, Process};
15-
use extra::tempfile;
15+
use extra::tempfile::TempDir;
1616
use version::*;
1717
use path_util::chmod_read_only;
1818

@@ -22,14 +22,6 @@ use path_util::chmod_read_only;
2222
/// directory (that the callee may use, for example, to check out remote sources into).
2323
/// Returns `CheckedOutSources` if the clone succeeded.
2424
pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult {
25-
use conditions::failed_to_create_temp_dir::cond;
26-
27-
let scratch_dir = tempfile::mkdtemp(&os::tmpdir(), "rustpkg");
28-
let clone_target = match scratch_dir {
29-
Some(d) => d.push("rustpkg_temp"),
30-
None => cond.raise(~"Failed to create temporary directory for fetching git sources")
31-
};
32-
3325
if os::path_exists(source) {
3426
debug2!("{} exists locally! Cloning it into {}",
3527
source.to_str(), target.to_str());
@@ -77,6 +69,14 @@ pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult
7769
}
7870
CheckedOutSources
7971
} else {
72+
use conditions::failed_to_create_temp_dir::cond;
73+
74+
let scratch_dir = TempDir::new("rustpkg");
75+
let clone_target = match scratch_dir {
76+
Some(d) => d.unwrap().push("rustpkg_temp"),
77+
None => cond.raise(~"Failed to create temporary directory for fetching git sources")
78+
};
79+
8080
DirToUse(clone_target)
8181
}
8282
}

0 commit comments

Comments
 (0)