Skip to content

Commit 7eab3f7

Browse files
committed
v0.3.0-pre.1
1 parent 8ec06a6 commit 7eab3f7

File tree

9 files changed

+59
-48
lines changed

9 files changed

+59
-48
lines changed

CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
# Changelog
22

3-
## Unreleased
3+
## 0.3.0-pre.1
4+
5+
A major release with significant changes to the API:
6+
7+
- Interior mutability and references are removed. Both `Cmd` and `Shell` are now values.
8+
- `pushd`-style API are removed in favor of `Shell`-returning functional builders like
9+
`with_current_dir`.
10+
- Split `copy_file` into `copy_file` and `copy_file_to_dir`, removing auto-magical directory
11+
detection.
12+
- Remove fine-grained control of stdin streams from `Cmd`. Instead:
13+
- There's a menu of `run`, `run_echo`, `run_interactive`, `read` that generally try to do the
14+
right thing.
15+
- The error messages now carry last 128KiB of stdout/stderr and print them on error.
16+
- There's `to_command` method for converting to `std::process::Command` which does allow for fine
17+
grained control.
18+
- Support for timeouts.
19+
- MSRV is raised to 1.73.0.
420

521
## 0.2.7
622

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
name = "xshell"
33
description = "Utilities for quick shell scripting in Rust"
44
categories = ["development-tools::build-utils", "filesystem"]
5-
version = "0.2.7" # also update xshell-macros/Cargo.toml and CHANGELOG.md
5+
version = "0.3.0-pre.1" # also update xshell-macros/Cargo.toml and CHANGELOG.md
66
license = "MIT OR Apache-2.0"
77
repository = "https://github.com/matklad/xshell"
88
authors = ["Alex Kladov <[email protected]>"]
99
edition = "2021"
10-
rust-version = "1.63"
10+
rust-version = "1.73"
1111

1212
exclude = [".github/", "bors.toml", "rustfmt.toml", "cbench", "mock_bin/"]
1313

1414
[workspace]
1515

1616
[dependencies]
17-
xshell-macros = { version = "=0.2.7", path = "./xshell-macros" }
17+
xshell-macros = { version = "=0.3.0-pre.1", path = "./xshell-macros" }
1818

1919
[dev-dependencies]
2020
anyhow = "1.0.56"

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ fn main() -> anyhow::Result<()> {
1414

1515
let user = "matklad";
1616
let repo = "xshell";
17-
cmd!(sh, "git clone https://github.com/{user}/{repo}.git").run()?;
17+
cmd!(sh, "git clone https://github.com/{user}/{repo}.git").run_echo()?;
1818
sh.set_current_dir(repo);
1919

2020
let test_args = ["-Zunstable-options", "--report-time"];
21-
cmd!(sh, "cargo test -- {test_args...}").run()?;
21+
cmd!(sh, "cargo test -- {test_args...}").run_echo()?;
2222

2323
let manifest = sh.read_file("Cargo.toml")?;
2424
let version = manifest
@@ -27,10 +27,10 @@ fn main() -> anyhow::Result<()> {
2727
.map(|it| it.0)
2828
.ok_or_else(|| anyhow::format_err!("can't find version field in the manifest"))?;
2929

30-
cmd!(sh, "git tag {version}").run()?;
30+
cmd!(sh, "git tag {version}").run_echo()?;
3131

32-
let dry_run = if sh.env_var("CI").is_ok() { None } else { Some("--dry-run") };
33-
cmd!(sh, "cargo publish {dry_run...}").run()?;
32+
let dry_run = if sh.var("CI").is_ok() { None } else { Some("--dry-run") };
33+
cmd!(sh, "cargo publish {dry_run...}").run_echo()?;
3434

3535
Ok(())
3636
}

examples/ci.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn publish(sh: &Shell) -> Result<()> {
5757

5858
if current_branch == "master" && !tag_exists {
5959
// Could also just use `CARGO_REGISTRY_TOKEN` environmental variable.
60-
let token = sh.env_var("CRATES_IO_TOKEN").unwrap_or("DUMMY_TOKEN".to_string());
60+
let token = sh.var("CRATES_IO_TOKEN").unwrap_or("DUMMY_TOKEN".to_string());
6161
cmd!(sh, "git tag v{version}").run_echo()?;
6262
cmd!(sh, "cargo publish --token {token} --package xshell-macros").run_echo()?;
6363
cmd!(sh, "cargo publish --token {token} --package xshell").run_echo()?;

examples/clone_and_publish.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn main() -> anyhow::Result<()> {
2121

2222
cmd!(sh, "git tag {version}").run()?;
2323

24-
let dry_run = if sh.env_var("CI").is_ok() { None } else { Some("--dry-run") };
24+
let dry_run = if sh.var("CI").is_ok() { None } else { Some("--dry-run") };
2525
cmd!(sh, "cargo publish {dry_run...}").run()?;
2626

2727
Ok(())

src/lib.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173
//!
174174
//! ```no_run
175175
//! # use xshell::{Shell, cmd}; let sh = Shell::new().unwrap();
176-
//! let dry_run = if sh.env_var("CI").is_ok() { None } else { Some("--dry-run") };
176+
//! let dry_run = if sh.var("CI").is_ok() { None } else { Some("--dry-run") };
177177
//! cmd!(sh, "cargo publish {dry_run...}").run_echo()?;
178178
//! # Ok::<(), xshell::Error>(())
179179
//! ```
@@ -203,7 +203,7 @@
203203
//!
204204
//! cmd!(sh, "git tag {version}").run_echo()?;
205205
//!
206-
//! let dry_run = if sh.env_var("CI").is_ok() { None } else { Some("--dry-run") };
206+
//! let dry_run = if sh.var("CI").is_ok() { None } else { Some("--dry-run") };
207207
//! cmd!(sh, "cargo publish {dry_run...}").run()?;
208208
//!
209209
//! Ok(())
@@ -217,8 +217,7 @@
217217
//!
218218
//! ## Maintenance
219219
//!
220-
//! Minimum Supported Rust Version: 1.63.0. MSRV bump is not considered semver breaking. MSRV is
221-
//! updated conservatively.
220+
//! MSRV bump is not considered semver breaking. MSRV is updated conservatively.
222221
//!
223222
//! The crate isn't comprehensive yet, but this is a goal. You are hereby encouraged to submit PRs
224223
//! with missing functionality!
@@ -426,10 +425,10 @@ impl Shell {
426425
///
427426
/// Environment of the [`Shell`] affects all commands spawned via this
428427
/// shell.
429-
pub fn env_var(&self, key: impl AsRef<OsStr>) -> Result<String> {
428+
pub fn var(&self, key: impl AsRef<OsStr>) -> Result<String> {
430429
fn inner(sh: &Shell, key: &OsStr) -> Result<String> {
431430
let env_os = sh
432-
.env_var_os(key)
431+
.var_os(key)
433432
.ok_or(VarError::NotPresent)
434433
.map_err(|err| Error::new_var(err, key.to_os_string()))?;
435434
env_os
@@ -444,7 +443,7 @@ impl Shell {
444443
///
445444
/// Environment of the [`Shell`] affects all commands spawned via this
446445
/// shell.
447-
pub fn env_var_os(&self, key: impl AsRef<OsStr>) -> Option<OsString> {
446+
pub fn var_os(&self, key: impl AsRef<OsStr>) -> Option<OsString> {
448447
fn inner(sh: &Shell, key: &OsStr) -> Option<OsString> {
449448
sh.env.get(key).map(OsString::from).or_else(|| env::var_os(key))
450449
}
@@ -457,7 +456,7 @@ impl Shell {
457456
///
458457
/// Environment of the [`Shell`] affects all commands spawned via this
459458
/// shell.
460-
pub fn env_vars_os(&self) -> HashMap<OsString, OsString> {
459+
pub fn vars_os(&self) -> HashMap<OsString, OsString> {
461460
let mut result: HashMap<OsString, OsString> = Default::default();
462461
result.extend(env::vars_os());
463462
result.extend(self.env.iter().map(|(k, v)| (OsString::from(k), OsString::from(v))));
@@ -467,7 +466,7 @@ impl Shell {
467466
/// Sets the value of `key` environment variable for this [`Shell`] to `value`.
468467
///
469468
/// Note that this doesn't affect [`std::env::var`].
470-
pub fn set_env_var(&mut self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) {
469+
pub fn set_var(&mut self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) {
471470
fn inner(sh: &mut Shell, key: &OsStr, value: &OsStr) {
472471
Arc::make_mut(&mut sh.env).insert(key.into(), value.into());
473472
}
@@ -477,7 +476,7 @@ impl Shell {
477476
/// Returns a new [`Shell`] with environmental variable `key` set to `value`.
478477
///
479478
/// Note that this doesn't affect [`std::env::var`].
480-
pub fn with_env_var(&self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> Shell {
479+
pub fn with_var(&self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> Shell {
481480
fn inner(sh: &Shell, key: &OsStr, value: &OsStr) -> Shell {
482481
let mut env = Arc::clone(&sh.env);
483482
Arc::make_mut(&mut env).insert(key.into(), value.into());
@@ -523,11 +522,7 @@ impl Shell {
523522

524523
/// Creates a `dst` file with the same contents as `src`
525524
#[doc(alias = "cp")]
526-
pub fn copy_file_to_path(
527-
&self,
528-
src_file: impl AsRef<Path>,
529-
dst_file: impl AsRef<Path>,
530-
) -> Result<()> {
525+
pub fn copy_file(&self, src_file: impl AsRef<Path>, dst_file: impl AsRef<Path>) -> Result<()> {
531526
fn inner(sh: &Shell, src: &Path, dst: &Path) -> Result<()> {
532527
let src = sh.path(src);
533528
let dst = sh.path(dst);
@@ -554,7 +549,7 @@ impl Shell {
554549
let Some(file_name) = src.file_name() else {
555550
return Err(Error::new_copy_file(io::ErrorKind::InvalidData.into(), src, dst));
556551
};
557-
sh.copy_file_to_path(&src, &dst.join(file_name))
552+
sh.copy_file(&src, &dst.join(file_name))
558553
}
559554
inner(self, src_file.as_ref(), dst_dir.as_ref())
560555
}

tests/it/env.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ fn test_env() {
3434
);
3535
}
3636

37-
let _g1 = sh.set_env_var(v1, "foobar");
38-
let _g2 = sh.set_env_var(v2, "quark");
37+
let _g1 = sh.set_var(v1, "foobar");
38+
let _g2 = sh.set_var(v2, "quark");
3939

4040
assert_env(cmd!(sh, "xecho -$ {v1} {v2}"), &[(v1, Some("foobar")), (v2, Some("quark"))]);
4141
assert_env(cmd!(cloned_sh, "xecho -$ {v1} {v2}"), &[(v1, None), (v2, None)]);
@@ -79,8 +79,8 @@ fn test_env_clear() {
7979
&[(v1, Some("789")), (v2, None)],
8080
);
8181

82-
let _g1 = sh.set_env_var(v1, "foobar");
83-
let _g2 = sh.set_env_var(v2, "quark");
82+
let _g1 = sh.set_var(v1, "foobar");
83+
let _g2 = sh.set_var(v2, "quark");
8484

8585
assert_env(cmd!(sh, "{xecho} -$ {v1} {v2}").env_clear(), &[(v1, None), (v2, None)]);
8686
assert_env(

tests/it/main.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn setup() -> Shell {
2424
.unwrap_or_else(|err| panic!("failed to install binaries from mock_bin: {}", err));
2525
});
2626

27-
sh.set_env_var("PATH", target_dir);
27+
sh.set_var("PATH", target_dir);
2828
sh
2929
}
3030

@@ -318,40 +318,40 @@ const VAR: &str = "SPICA";
318318
fn test_subshells_env() {
319319
let sh = setup();
320320

321-
let e1 = sh.env_var_os(VAR);
321+
let e1 = sh.var_os(VAR);
322322
{
323323
let mut sh = sh.clone();
324-
sh.set_env_var(VAR, "1");
325-
let e2 = sh.env_var_os(VAR);
324+
sh.set_var(VAR, "1");
325+
let e2 = sh.var_os(VAR);
326326
assert_eq!(e2.as_deref(), Some("1".as_ref()));
327327
{
328328
let mut sh = sh.clone();
329-
let _e = sh.set_env_var(VAR, "2");
330-
let e3 = sh.env_var_os(VAR);
329+
let _e = sh.set_var(VAR, "2");
330+
let e3 = sh.var_os(VAR);
331331
assert_eq!(e3.as_deref(), Some("2".as_ref()));
332332
}
333-
let e4 = sh.env_var_os(VAR);
333+
let e4 = sh.var_os(VAR);
334334
assert_eq!(e4, e2);
335335
}
336-
let e5 = sh.env_var_os(VAR);
336+
let e5 = sh.var_os(VAR);
337337
assert_eq!(e5, e1);
338338
}
339339

340340
#[test]
341341
fn test_push_env_and_set_env_var() {
342342
let sh = setup();
343343

344-
let e1 = sh.env_var_os(VAR);
344+
let e1 = sh.var_os(VAR);
345345
{
346346
let mut sh = sh.clone();
347-
sh.set_env_var(VAR, "1");
348-
let e2 = sh.env_var_os(VAR);
347+
sh.set_var(VAR, "1");
348+
let e2 = sh.var_os(VAR);
349349
assert_eq!(e2.as_deref(), Some("1".as_ref()));
350-
sh.set_env_var(VAR, "2");
351-
let e3 = sh.env_var_os(VAR);
350+
sh.set_var(VAR, "2");
351+
let e3 = sh.var_os(VAR);
352352
assert_eq!(e3.as_deref(), Some("2".as_ref()));
353353
}
354-
let e5 = sh.env_var_os(VAR);
354+
let e5 = sh.var_os(VAR);
355355
assert_eq!(e5, e1);
356356
}
357357

@@ -369,7 +369,7 @@ fn test_copy_file() {
369369
sh.write_file(&foo, "hello world").unwrap();
370370
sh.create_dir(&dir).unwrap();
371371

372-
sh.copy_file_to_path(&foo, &bar).unwrap();
372+
sh.copy_file(&foo, &bar).unwrap();
373373
assert_eq!(sh.read_file(&bar).unwrap(), "hello world");
374374

375375
sh.copy_file_to_dir(&foo, &dir).unwrap();

xshell-macros/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[package]
22
name = "xshell-macros"
33
description = "Private implementation detail of xshell crate"
4-
version = "0.2.7"
4+
version = "0.3.0-pre.1"
55
license = "MIT OR Apache-2.0"
66
repository = "https://github.com/matklad/xshell"
77
authors = ["Aleksey Kladov <[email protected]>"]
88
edition = "2021"
9-
rust-version = "1.59"
9+
rust-version = "1.73"
1010

1111
[lib]
1212
proc-macro = true

0 commit comments

Comments
 (0)