Skip to content

Commit 3ef1747

Browse files
bors[bot]matklad
andauthored
Merge #7
7: cpt r=matklad a=matklad - mktemp_d and tests for cp - Publish 0.1.7 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents c4d641c + 7be8d33 commit 3ef1747

6 files changed

Lines changed: 75 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 0.1.7
4+
5+
- `mktemp_d` creates an (insecure, world readable) temporary directory.
6+
- `cp(foo, bar)` copies `foo` _into_ `bar`, if `bar` is an existing directory.
7+
38
## 0.1.6
49

510
- `.read()` chomps `\r\n` on Windows.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "xshell"
33
description = "Utilities for quick shell scripting in Rust"
44
categories = ["development-tools::build-utils", "filesystem"]
5-
version = "0.1.6"
5+
version = "0.1.7"
66
license = "MIT OR Apache-2.0"
77
repository = "https://github.com/matklad/xshell"
88
authors = ["Aleksey Kladov <[email protected]>"]
@@ -13,4 +13,4 @@ exclude = [".github/", "bors.toml", "rustfmt.toml", "cbench", "mock_bin/"]
1313
[workspace]
1414

1515
[dependencies]
16-
xshell-macros = { version = "0.1.6", path = "./xshell-macros"}
16+
xshell-macros = { version = "0.1.7", path = "./xshell-macros"}

src/fs.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::path::{Path, PathBuf};
1+
use std::{
2+
path::{Path, PathBuf},
3+
sync::atomic::{AtomicUsize, Ordering},
4+
};
25

36
use crate::{error::fs_err, gsl, Result};
47

@@ -66,6 +69,29 @@ pub fn cwd() -> Result<PathBuf> {
6669
with_path(&Path::new("."), std::env::current_dir())
6770
}
6871

72+
pub fn mktemp_d() -> Result<TempDir> {
73+
let _guard = gsl::read();
74+
let base = std::env::temp_dir();
75+
let pid = std::process::id();
76+
mkdir_p(&base)?;
77+
78+
static CNT: AtomicUsize = AtomicUsize::new(0);
79+
80+
let mut n_try = 0u32;
81+
loop {
82+
n_try += 1;
83+
let cnt = CNT.fetch_add(1, Ordering::Relaxed);
84+
let path = base.join(format!("{}_{}", pid, cnt));
85+
if let Err(io_err) = std::fs::create_dir(&path) {
86+
if n_try == 1024 {
87+
return Err(fs_err(path, io_err));
88+
}
89+
continue;
90+
}
91+
return Ok(TempDir { path });
92+
}
93+
}
94+
6995
fn with_path<T>(path: &Path, res: Result<T, std::io::Error>) -> Result<T> {
7096
res.map_err(|io_err| fs_err(path.to_path_buf(), io_err))
7197
}
@@ -95,3 +121,19 @@ fn read_dir_aux(path: &Path) -> std::io::Result<Vec<PathBuf>> {
95121
res.sort();
96122
Ok(res)
97123
}
124+
125+
pub struct TempDir {
126+
path: PathBuf,
127+
}
128+
129+
impl TempDir {
130+
pub fn path(&self) -> &Path {
131+
&self.path
132+
}
133+
}
134+
135+
impl Drop for TempDir {
136+
fn drop(&mut self) {
137+
rm_rf(&self.path).unwrap()
138+
}
139+
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ pub use xshell_macros::__cmd;
257257
pub use crate::{
258258
env::{pushd, pushenv, Pushd, Pushenv},
259259
error::{Error, Result},
260-
fs::{cp, cwd, mkdir_p, read_dir, read_file, rm_rf, write_file},
260+
fs::{cp, cwd, mkdir_p, mktemp_d, read_dir, read_file, rm_rf, write_file, TempDir},
261261
};
262262

263263
#[macro_export]

tests/it.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{ffi::OsStr, thread, time::Duration, time::Instant};
22

3-
use xshell::{cmd, cwd, mkdir_p, pushd, pushenv, read_file, rm_rf, write_file};
3+
use xshell::{cmd, cp, cwd, mkdir_p, mktemp_d, pushd, pushenv, read_file, rm_rf, write_file};
44

55
#[test]
66
fn smoke() {
@@ -208,6 +208,28 @@ fn test_pushenv_lock() {
208208
t2.join().unwrap();
209209
}
210210

211+
#[test]
212+
fn test_cp() {
213+
let path;
214+
{
215+
let tempdir = mktemp_d().unwrap();
216+
path = tempdir.path().to_path_buf();
217+
let foo = tempdir.path().join("foo.txt");
218+
let bar = tempdir.path().join("bar.txt");
219+
let dir = tempdir.path().join("dir");
220+
write_file(&foo, "hello world").unwrap();
221+
mkdir_p(&dir).unwrap();
222+
223+
cp(&foo, &bar).unwrap();
224+
assert_eq!(read_file(&bar).unwrap(), "hello world");
225+
226+
cp(&foo, &dir).unwrap();
227+
assert_eq!(read_file(&dir.join("foo.txt")).unwrap(), "hello world");
228+
assert!(path.exists());
229+
}
230+
assert!(!path.exists());
231+
}
232+
211233
fn check_failure(code: &str, err_msg: &str) {
212234
mkdir_p("./target/cf").unwrap();
213235
let _p = pushd("./target/cf").unwrap();

xshell-macros/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "xshell-macros"
33
description = "Private implementation detail of xshell crate"
4-
version = "0.1.6"
4+
version = "0.1.7"
55
authors = ["Aleksey Kladov <[email protected]>"]
66
edition = "2018"
77
license = "MIT OR Apache-2.0"

0 commit comments

Comments
 (0)