diff --git a/README.adoc b/README.adoc index c73aef4..af850f5 100644 --- a/README.adoc +++ b/README.adoc @@ -48,6 +48,9 @@ definitions. | `provides` | A relative or absolute path to a file that the task provides. If the file exists, then the task will be skipped. +| `unless` +| A script snippet which can determine whether the task should execute. A non-zero exit status causes the task to execute. + |=== .echo.ztask diff --git a/cli/src/transport/ssh.rs b/cli/src/transport/ssh.rs index d7bff30..9641019 100644 --- a/cli/src/transport/ssh.rs +++ b/cli/src/transport/ssh.rs @@ -113,13 +113,26 @@ impl Transport for Ssh { } } - if let Some(unless) = &command.parameters.get("unless") { - debug!("An `unless` parameter was given, running {}", unless); - } - let remote_script = "._zap_command"; let args_file = "._zap_args.json"; + if let Some(unless) = &command.parameters.get("unless") { + debug!("An `unless` parameter was given, running {}", unless); + if self.send_bytes(Path::new(remote_script), &unless.as_bytes().to_vec(), 0o700) { + let mut channel = self.session.channel_session().unwrap(); + channel.exec(&format!("./{}", remote_script)); + let mut s = String::new(); + channel.read_to_string(&mut s).unwrap(); + print!("{}", s); + channel.wait_close().expect("Failed to close the channel"); + let exit = channel.exit_status().unwrap(); + if exit == 0 { + debug!("Unless script returned success, so bailing out early"); + return 0; + } + } + } + if let Some(script) = command.task.script.as_bytes(Some(&command.parameters)) { if dry_run { println!("{}", "Dry-run\n----".yellow());