Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ability to run a script once network is initialized #180

Merged
merged 13 commits into from
May 23, 2024
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ pop up parachain -f ./tests/zombienet.toml -p https://github.com/r0gue-io/pop-no
> :information_source: Pop CLI will automatically source the necessary polkadot binaries. Currently, these will be built
> if on a non-linux system.

### Run a command after the network has been spun up

The following will spin up the network locally according the the zombienet file and once the network is up, it will run the command specified in `--cmd`:

```shell
pop up parachain -f ./tests/zombienet.toml -p https://github.com/r0gue-io/pop-node --cmd ./path/to/my/script
```

### Contracts

Use `pop` to create a new Smart Contract project:
Expand Down
46 changes: 46 additions & 0 deletions crates/pop-cli/src/commands/up/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use cliclack::{
clear_screen, confirm, intro, log, multi_progress, outro, outro_cancel, set_theme, ProgressBar,
};
use console::{Emoji, Style};
use duct::cmd;
use pop_parachains::{NetworkNode, Status, Zombienet};
use std::time::Duration;
use tokio::time::sleep;
Expand All @@ -26,6 +27,9 @@ pub(crate) struct ZombienetCommand {
/// The url of the git repository of a parachain to be used, with branch/release tag specified as #fragment (e.g. 'https://github.com/org/repository#tag'). A specific binary name can also be optionally specified via query string parameter (e.g. 'https://github.com/org/repository?binaryname#tag'), defaulting to the name of the repository when not specified.
#[arg(short, long)]
parachain: Option<Vec<String>>,
/// The command to run after the network has been launched.
#[clap(name = "cmd", short = 'c', long)]
command: Option<String>,
/// Whether the output should be verbose.
#[arg(short, long, action)]
verbose: bool,
Expand Down Expand Up @@ -138,6 +142,10 @@ impl ZombienetCommand {
}
}

if let Some(command) = &self.command {
run_custom_command(&spinner, command).await?;
}

spinner.stop(result);
tokio::signal::ctrl_c().await?;
outro("Done")?;
Expand All @@ -151,6 +159,25 @@ impl ZombienetCommand {
}
}

pub(crate) async fn run_custom_command(
spinner: &ProgressBar,
command: &str,
) -> Result<(), anyhow::Error> {
spinner.set_message(format!("Spinning up network & running command: {}", command.to_string()));
sleep(Duration::from_secs(15)).await;

// Split the command into the base command and arguments
let mut parts = command.split_whitespace();
AlexD10S marked this conversation as resolved.
Show resolved Hide resolved
let base_command = parts.next().expect("Command cannot be empty");
let args: Vec<&str> = parts.collect();

cmd(base_command, &args)
.run()
.map_err(|e| anyhow::Error::new(e).context("Error running the command."))?;

Ok(())
}

/// Reports any observed status updates to a progress bar.
#[derive(Copy, Clone)]
struct ProgressReporter<'a>(&'a ProgressBar);
Expand All @@ -160,3 +187,22 @@ impl Status for ProgressReporter<'_> {
self.0.start(status.replace(" Compiling", "Compiling"))
}
}

// Write a test for run_custom_command
#[cfg(test)]
mod tests {
use super::*;

#[tokio::test]
async fn test_run_custom_command() -> Result<(), anyhow::Error> {
let spinner = ProgressBar::new(1);

// Define the command to be executed
let command = "echo 2 + 2";

// Call the run_custom_command function
run_custom_command(&spinner, command).await?;

Ok(())
}
}
Loading