Skip to content

Commit

Permalink
feat(actions): add spinner for run action, improve styling a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
norskeld committed Mar 4, 2024
1 parent 0a2ce0f commit c16cb22
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 4 deletions.
45 changes: 45 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dirs = "5.0.1"
flate2 = { version = "1.0.28" }
git2 = { version = "0.18.1", features = ["vendored-libgit2"] }
glob-match = { version = "0.2.1" }
indicatif = "0.17.8"
inquire = { version = "0.7.0", features = ["editor"] }
kdl = { version = "4.6.0" }
reqwest = { version = "0.11.22", features = ["json"] }
Expand Down
39 changes: 37 additions & 2 deletions src/actions/actions.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::path::{Path, PathBuf};
use std::process;

use crossterm::style::Stylize;
use run_script::ScriptOptions;
use unindent::Unindent;

use crate::actions::{State, Value};
use crate::manifest::actions::*;
use crate::spinner::Spinner;

impl Copy {
pub async fn execute(&self) -> anyhow::Result<()> {
Expand Down Expand Up @@ -52,6 +55,7 @@ impl Run {
P: Into<PathBuf> + AsRef<Path>,
{
let mut command = self.command.clone();
let spinner = Spinner::new();

if let Some(injects) = &self.injects {
for inject in injects {
Expand All @@ -62,13 +66,44 @@ impl Run {
}
}

let name = self
.name
.clone()
.or_else(|| {
let lines = command.trim().lines().count();

if lines > 1 {
Some(command.trim().lines().next().unwrap().to_string() + "...")
} else {
Some(command.clone())
}
})
.unwrap();

let options = ScriptOptions {
working_directory: Some(root.into()),
..ScriptOptions::new()
};

// NOTE: This will exit the main process in case of error.
let (output, _) = run_script::run_script_or_exit!(command, options);
spinner.set_message(format!("{}", name.clone().grey()));

// Actually run the script.
let (code, output, err) = run_script::run_script!(command, options)?;
let has_failed = code > 0;

// Re-format depending on the exit code.
let name = if has_failed { name.red() } else { name.green() };

// Stopping before printing output/errors, otherwise the spinner message won't be cleared.
spinner.stop_with_message(format!("{name}\n",));

if has_failed {
if !err.is_empty() {
eprintln!("{err}");
}

process::exit(1);
}

Ok(println!("{}", output.trim()))
}
Expand Down
4 changes: 2 additions & 2 deletions src/actions/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ impl Executor {
let mut state = State::new();

for ActionSuite { name, actions, .. } in suites {
let symbol = "⦿".blue().bold();
let title = "Running suite".blue();
let symbol = "+".blue().bold();
let title = "Suite".blue();
let name = name.clone().green();

println!("{symbol} {title}: {name}\n");
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ pub mod fs;
pub mod manifest;
pub mod path;
pub mod repository;
pub mod spinner;
pub mod unpacker;
53 changes: 53 additions & 0 deletions src/spinner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::time::Duration;

use indicatif::{ProgressBar, ProgressStyle};

/// Small wrapper around the `indicatif` spinner.
pub struct Spinner {
spinner: ProgressBar,
}

impl Spinner {
/// Creates a new spinner.
pub fn new() -> Self {
let style = ProgressStyle::default_spinner().tick_chars("⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋·");
let spinner = ProgressBar::new_spinner();

spinner.set_style(style);
spinner.enable_steady_tick(Duration::from_millis(80));

Self { spinner }
}

/// Sets the message of the spinner.
pub fn set_message<S>(&self, message: S)
where
S: Into<String> + AsRef<str>,
{
self.spinner.set_message(message.into());
}

/// Stops the spinner.
pub fn stop(&self) {
self.spinner.finish();
}

/// Stops the spinner with the message.
pub fn stop_with_message<S>(&self, message: S)
where
S: Into<String> + AsRef<str>,
{
self.spinner.finish_with_message(message.into());
}

/// Stops the spinner and clears the message.
pub fn stop_with_clear(&self) {
self.spinner.finish_and_clear();
}
}

impl Default for Spinner {
fn default() -> Self {
Self::new()
}
}

0 comments on commit c16cb22

Please sign in to comment.