Skip to content

Commit

Permalink
chore: move from structopt to clap v4 with derive
Browse files Browse the repository at this point in the history
  • Loading branch information
Joxit committed Oct 10, 2023
1 parent 9b01335 commit e068c3e
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 111 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ keywords = ["cli", "shell", "command", "task"]
categories = ["command-line-utilities"]

[dependencies]
structopt = "^0.3"
clap = { version = "^4.4", features = ["derive"] }
yaml-rust = "^0.4"
linked-hash-map = "^0.5"
libc = "^0.2"
Expand All @@ -24,3 +24,4 @@ hostname = "^0.3"
regex = "^1.3"
chrono = "^0.4"
cron = "0.12"
clap_complete = "^4.4"
140 changes: 72 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,122 +4,126 @@
[![Crates.io version shield](https://img.shields.io/crates/v/runtasktic.svg)](https://crates.io/crates/runtasktic)
[![Crates.io license shield](https://img.shields.io/crates/l/runtasktic.svg)](https://crates.io/crates/runtasktic)

Runtasktic is a *fantastic* command-line task management tool for execution of regular long sequential or parallel tasks.
Runtasktic is a _fantastic_ command-line task management tool for execution of regular long sequential or parallel tasks.

There are often tasks that we repeat several times in predefined orders. Some of these tasks can take time and we would like to be notified when it ends. This is why this project exists.

Describe your tasks in a YAML file, execute all of them with runtasktic in foreground or background. Configure the notification system, and be notified at the end of each task or when they are all finished.
Describe your tasks in a YAML file, execute all of them with runtasktic in foreground or background. Configure the notification system, and be notified at the end of each task or when they are all finished. Onlyt Slack is supported right now, need more ? Submit a Feature Request or Pull Request.

## When should I need runtasktic ?

- when you have a redundant long running task list
- when you need a notification after a long task completion
- when you need an alternative to nohup
- when you need an alternative to crontab

## CLI

```
runtasktic 0.4.0
Jones Magloire @Joxit
Command-line task management tool for execution of regular long sequential or parallel tasks.
USAGE:
runtasktic <SUBCOMMAND>
Usage: runtasktic <COMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
Commands:
run Run tasks
dot Export the configuration to a graph (needs graphviz/dot)
exec Execute a single command with notification
completion Generate completion script for your shell
help Print this message or the help of the given subcommand(s)
SUBCOMMANDS:
completion Generate completion script for your shell
dot Export the configuration to a graph (needs graphviz/dot)
exec Execute a single command with notification
help Prints this message or the help of the given subcommand(s)
run Run tasks
Options:
-h, --help Print help
-V, --version Print version
```

### Run: all tasks of a configuration file

```
runtasktic-run 0.4.0
Run tasks
Run all tasks from your configuration in background or foreground.
USAGE:
runtasktic run [FLAGS] [OPTIONS] [--] [config]...
Set the notification, messages, output files, concurency, working directory and many more options in your configuration.
FLAGS:
-b, --background Run the task in background
-h, --help Prints help information
-V, --version Prints version information
Usage: runtasktic run [OPTIONS] [CONFIG]...
OPTIONS:
-s, --start <starts>... Override the starting task if the job had already been started before. When using many
configuration files, start states must be in the first configuration file. Can be many
task ids with comma separated values
Arguments:
[CONFIG]...
Configurations path (YAML)
ARGS:
<config>... Configurations path (YAML)
Options:
-s, --start <STARTS>
Override the starting task if the job had already been started before. When using many configuration files, start states must be in the first configuration file. Can be many task ids with comma separated values
-b, --background
Run the task in background
--cron <CRON>
Schedule your tasks using cron expression
-h, --help
Print help (see a summary with '-h')
```

### Exec: Simple command, just like nohup with notification

```
runtasktic-exec 0.4.0
Execute a single command with notification
Execute a single command with notification in background or foreground.
Inherit the notification from a configuration file and set your default one in your home: `~/.runtasktic.yml` or `~/.runtasktic.yaml`.
Usage: runtasktic exec [OPTIONS] [COMMAND]...
Arguments:
[COMMAND]...
Command to execute
Options:
-c, --config <CONFIG>
Configuration path (YAML). Will use config file located `~/.runtasktic.yml` or `~/.runtasktic.yaml` by default. If you want no config file execusion, use `--config -`
USAGE:
runtasktic exec [FLAGS] [OPTIONS] [command]...
-t, --task <TASK>
Run a single task from the configuration file
FLAGS:
-b, --background Exec the command in background
-h, --help Prints help information
-V, --version Prints version information
-b, --background
Exec the command in background
OPTIONS:
-c, --config <config> Configuration path (YAML)
-t, --task <task> Run a single task from the configuration file
--cron <CRON>
Schedule your tasks using cron expression
ARGS:
<command>... Command to execute
-h, --help
Print help (see a summary with '-h')
```

### Dot: Create a graph using graphviz of your configuration file

```
runtasktic-dot 0.4.0
Export the configuration to a graph (needs graphviz/dot)
USAGE:
runtasktic dot <config> <image>
Usage: runtasktic dot <CONFIG> <IMAGE>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
Arguments:
<CONFIG> Path of the configuration file to visualize
<IMAGE> Path for the image. `dot` command is required
ARGS:
<config> Path of the configuration file to visualize
<image> Path for the image. `dot` command is required
Options:
-h, --help Print help
```

### Completion: Generate completion script for your shell

```
runtasktic-completion 0.4.0
Generate completion script for your shell
USAGE:
runtasktic completion <SUBCOMMAND>
Usage: runtasktic completion <COMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
Commands:
bash Generates a .bash completion file for the Bourne Again SHell (BASH). Save the output in `/etc/bash_completion.d/runtasktic` or `~/.local/share/bash-completion/completions/runtasktic`
fish Generates a .fish completion file for the Friendly Interactive SHell (fish)
zsh Generates a completion file for the Z SHell (ZSH)
elvish Generates a completion file for Elvish
help Print this message or the help of the given subcommand(s)
SUBCOMMANDS:
bash Generates a .bash completion file for the Bourne Again SHell (BASH). Save the output in
`/etc/bash_completion.d/runtasktic` or `~/.local/share/bash-completion/completions/runtasktic`
elvish Generates a completion file for Elvish
fish Generates a .fish completion file for the Friendly Interactive SHell (fish)
help Prints this message or the help of the given subcommand(s)
zsh Generates a completion file for the Z SHell (ZSH)
Options:
-h, --help Print help
```

## Configuration
Expand All @@ -128,7 +132,7 @@ SUBCOMMANDS:
tasks:
a: # The id of the task
commands: # Commands to execute, they must exist with a 0 exit code
- echo Begin a
- echo Begin a
- sleep 0.5
- echo End a
on_failure: exit # `continue` or `exit` when the tasks ends with a non 0 exit code
Expand All @@ -137,7 +141,7 @@ tasks:
- echo Begin b
- sleep 0.25
- echo End b
depends_on: [ a ] # This task will be executed after a.
depends_on: [a] # This task will be executed after a.
notification:
slack: # send notification to slack
url: https://hooks.slack.com/services/XXXXX/XXXXX/XXXXX # The slack server url
Expand All @@ -148,7 +152,7 @@ notification:
output: stderr # print notification on `stdout`, `stedrr`, `none` or `/custom/path`
when: always # `always`, `task-end`, `end` or `never` when should I send notification
messages:
task_end: Task {task.id} ended with status code {task.status_code} # Availables templates are {task.id}, {task.short_cmd}, {task.full_cmd}, {task.status_code}, {hostname}, {env.*} for environment variables
task_end: Task {task.id} ended with status code {task.status_code} # Availables templates are {task.id}, {task.short_cmd}, {task.full_cmd}, {task.status_code}, {hostname}, {env.*} for environment variables
all_task_end: All tasks ended. Got {resume.success} success and {resume.failures} failure. # Availables templates are {resulme.success}, {resume.failures}, {hostname}, {env.*} for environment variables
task_failed: Tasks ended prematurely. Got {resume.success} success and {resume.failures} failure. Contains one critical failure. # Availables templates are {resulme.success}, {resume.failures}, {hostname}, {env.*} for environment variables. Triggered when `on_failure: exit` is used.

Expand All @@ -165,4 +169,4 @@ on_failure: continue # `continue` or `exit` default behaviour when a task fail,

[Play with concurrency](https://github.com/Joxit/task-scheduler/blob/master/tests/resources/concurrency.yml)

[Play with notification](https://github.com/Joxit/task-scheduler/blob/master/tests/resources/notification.yml)
[Play with notification](https://github.com/Joxit/task-scheduler/blob/master/tests/resources/notification.yml)
18 changes: 10 additions & 8 deletions src/commands/completion.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use crate::Runtasktic;
use structopt::clap::Shell;
use structopt::StructOpt;
use clap::{CommandFactory, Parser};
use clap_complete::{generate, Shell};

#[derive(Debug, StructOpt)]
#[derive(Parser, Debug)]
pub enum Completion {
/// Generates a .bash completion file for the Bourne Again SHell (BASH).
/// Save the output in `/etc/bash_completion.d/runtasktic` or `~/.local/share/bash-completion/completions/runtasktic`
#[structopt(name = "bash")]
#[command(name = "bash")]
Bash,
/// Generates a .fish completion file for the Friendly Interactive SHell (fish)
#[structopt(name = "fish")]
#[command(name = "fish")]
Fish,
/// Generates a completion file for the Z SHell (ZSH)
#[structopt(name = "zsh")]
#[command(name = "zsh")]
Zsh,
/// Generates a completion file for Elvish
#[structopt(name = "elvish")]
#[command(name = "elvish")]
Elvish,
}

Expand All @@ -27,6 +27,8 @@ impl Completion {
Completion::Zsh => Shell::Zsh,
Completion::Elvish => Shell::Elvish,
};
Runtasktic::clap().gen_completions_to("runtasktic", shell, &mut std::io::stdout());
let mut cli = Runtasktic::command();
let bin_name = cli.get_name().to_string();
generate(shell, &mut cli, &bin_name, &mut std::io::stdout());
}
}
4 changes: 2 additions & 2 deletions src/commands/dot.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::config::Config;
use crate::fst::dot::*;
use crate::fst::*;
use clap::Parser;
use std::fs;
use std::io::Cursor;
use std::path::PathBuf;
use std::process::exit;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[derive(Parser, Debug)]
pub struct Dot {
/// Path of the configuration file to visualize.
#[structopt()]
Expand Down
18 changes: 8 additions & 10 deletions src/commands/exec.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
use crate::config::Config;
use crate::utils::traits::{CommandConfig, WaitSchedule};
use chrono::Local;
use clap::Parser;
use cron::Schedule;
use libc::{fork, signal};
use libc::{SIGHUP, SIG_IGN};
use std::fs;
use std::path::PathBuf;
use std::process::{exit, Command, Stdio};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[derive(Parser, Debug)]
pub struct Exec {
/// Configuration path (YAML).
/// Will use config file located `~/.runtasktic.yml` or `~/.runtasktic.yaml` by default.
/// If you want no config file execusion, use `--config -`
#[structopt(long = "config", short = "c")]
#[arg(long = "config", short = 'c')]
config: Option<PathBuf>,
/// Run a single task from the configuration file.
#[structopt(long = "task", short = "t", requires = "config")]
#[arg(long = "task", short = 't', requires = "config")]
task: Option<String>,
/// Exec the command in background
#[structopt(long = "background", short = "b")]
#[arg(long = "background", short = 'b')]
background: bool,
/// Schedule your tasks using cron expression.
#[structopt(long = "cron")]
#[arg(long = "cron")]
cron: Option<Schedule>,
/// Command to execute
#[structopt()]
#[arg()]
command: Vec<String>,
}

Expand All @@ -41,9 +41,7 @@ impl Exec {
let timezone = Local::now().timezone();

if self.command.is_empty() && self.task.is_none() {
let clap = crate::Runtasktic::clap();
let args = format!("{} exec --help", clap.get_name());
clap.get_matches_from(args.split(" "));
crate::Runtasktic::display_help("exec");
}

if self.background && unsafe { fork() } != 0 {
Expand Down
20 changes: 12 additions & 8 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@ use crate::commands::completion::Completion;
use crate::commands::dot::Dot;
use crate::commands::exec::Exec;
use crate::commands::run::Run;
use structopt::StructOpt;
use clap::Parser;

mod completion;
mod dot;
mod exec;
mod run;

#[derive(Debug, StructOpt)]
#[derive(Parser, Debug)]
pub enum Command {
/// Run tasks.
#[structopt(name = "run")]
/// Run all tasks from your configuration in background or foreground.
///
/// Set the notification, messages, output files, concurency, working directory and many more options in your configuration.
#[command(name = "run")]
Run(Run),
/// Export the configuration to a graph (needs graphviz/dot).
#[structopt(name = "dot")]
#[command(name = "dot")]
Dot(Dot),
/// Execute a single command with notification.
#[structopt(name = "exec")]
/// Execute a single command with notification in background or foreground.
///
/// Inherit the notification from a configuration file and set your default one in your home: `~/.runtasktic.yml` or `~/.runtasktic.yaml`.
#[command(name = "exec")]
Exec(Exec),
/// Generate completion script for your shell.
#[structopt(name = "completion")]
#[command(name = "completion", subcommand)]
Completion(Completion),
}

Expand Down
Loading

0 comments on commit e068c3e

Please sign in to comment.