Skip to content

Commit cca6c29

Browse files
committed
Introduce alternative to EnvCommand
The `EnvCommand` was designed when there was no built in way to stream stdout & stderr to the user and also when I was not as experienced with Rust. The `commons::cmd` takes a few things that were nice about EnvCommand and modularizes them so they can be used piece-meal. Core goals: - Talk to the user, includes display functions to render commands to the user - Consistent errors, Errors need to include maximum information including command and stdout/stderr. Good display by default. - Consistent experience mapping user versus OS errors.
1 parent 6925f53 commit cca6c29

File tree

6 files changed

+350
-10
lines changed

6 files changed

+350
-10
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

buildpacks/ruby/src/layers/bundle_install_layer.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::{BundleWithout, RubyBuildpack, RubyBuildpackError};
22
use commons::{
3-
display::SentenceList,
4-
env_command::{CommandError, EnvCommand},
5-
gemfile_lock::ResolvedRubyVersion,
3+
cmd, cmd::CmdError, display::SentenceList, gemfile_lock::ResolvedRubyVersion,
64
metadata_digest::MetadataDigest,
75
};
86
use libcnb::{
@@ -12,6 +10,7 @@ use libcnb::{
1210
layer_env::{LayerEnv, ModificationBehavior, Scope},
1311
Env,
1412
};
13+
use libherokubuildpack::command::CommandExt;
1514
use libherokubuildpack::log as user;
1615
use serde::{Deserialize, Serialize};
1716
use std::path::Path;
@@ -337,11 +336,12 @@ fn layer_env(layer_path: &Path, app_dir: &Path, without_default: &BundleWithout)
337336
/// # Errors
338337
///
339338
/// When the 'bundle install' command fails this function returns an error.
340-
fn bundle_install(env: &Env) -> Result<(), CommandError> {
339+
///
340+
fn bundle_install(env: &Env) -> Result<(), CmdError> {
341341
// ## Run `$ bundle install`
342-
let command = EnvCommand::new_show_keys(
343-
"bundle",
344-
&["install"],
342+
let mut command = cmd::create("bundle", &["install"], env);
343+
let command_string = cmd::display_with_keys(
344+
&command,
345345
env,
346346
[
347347
"BUNDLE_BIN",
@@ -353,9 +353,13 @@ fn bundle_install(env: &Env) -> Result<(), CommandError> {
353353
],
354354
);
355355

356-
user::log_info(format!("\nRunning command:\n$ {command}"));
356+
user::log_info(format!("\nRunning command:\n$ {command_string}"));
357357

358-
command.stream()?;
358+
command
359+
.output_and_write_streams(std::io::stdout(), std::io::stderr())
360+
.map_err(cmd::os_command_error)
361+
.and_then(|output| cmd::check_non_zero(output, cmd::OutputState::AlreadyStreamed))
362+
.map_err(|error| CmdError::new(command_string, error))?;
359363

360364
Ok(())
361365
}

buildpacks/ruby/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![allow(clippy::module_name_repetitions)]
44
use crate::layers::{RubyInstallError, RubyInstallLayer};
55
use commons::cache::CacheError;
6+
use commons::cmd::CmdError;
67
use commons::env_command::CommandError;
78
use commons::gem_list::GemList;
89
use commons::gemfile_lock::GemfileLock;
@@ -169,7 +170,7 @@ pub(crate) enum RubyBuildpackError {
169170
MissingGemfileLock(std::io::Error),
170171
InAppDirCacheError(CacheError),
171172
BundleInstallDigestError(commons::metadata_digest::DigestError),
172-
BundleInstallCommandError(CommandError),
173+
BundleInstallCommandError(CmdError),
173174
RakeAssetsPrecompileFailed(CommandError),
174175
GemInstallBundlerCommandError(CommandError),
175176
}

commons/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ sha2 = "0.10"
1818
tempfile = "3"
1919
thiserror = "1"
2020
walkdir = "2"
21+
lazy_static = "1.4.0"
2122

2223
[dev-dependencies]
2324
filetime = "0.2"

0 commit comments

Comments
 (0)