Skip to content

Commit

Permalink
Merge pull request #5 from IsWladi/release/v1.0.0
Browse files Browse the repository at this point in the history
Release/v1.0.0
  • Loading branch information
IsWladi authored Nov 10, 2024
2 parents aec1df3 + 3594ede commit 86d8159
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 61 deletions.
65 changes: 65 additions & 0 deletions Cargo.lock

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

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "watchcrab"
version = "0.6.0"
version = "1.0.0"
edition = "2021"
description = """
WatchCrab is a Rust-based command-line tool for monitoring directories, triggering custom actions on file system events like creation, modification, or deletion—ideal for automating tasks or logging changes, with seamless integration for advanced workflows.
WatchCrab is a fast, secure, and easy-to-use Rust-based tool to monitor filesystem events across platforms. Effortlessly automate tasks and log changes.
"""
license = "MIT"
homepage = "https://github.com/IsWladi/WatchCrab"
Expand All @@ -20,3 +20,6 @@ crossbeam-channel = "0.5.13"
signal-hook = "0.3.17"
libc = "0.2"

[target.'cfg(windows)'.dependencies]
windows = {version = "0.58.0", features = ["Win32_System_Console", "Win32_System_Threading"]}

20 changes: 9 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@
![» Crate](https://flat.badgen.net/crates/v/watchcrab)
![» Downloads](https://flat.badgen.net/crates/d/watchcrab)

`watchcrab` is a Rust-based command-line tool that monitors directories for filesystem events such as file creation, modification, and deletion. It allows you to execute shell commands when these events occur, making it ideal for automating file processing tasks or generating logs.
`watchcrab` is a Rust-based command-line tool that monitors directories for filesystem events like file creation, modification, and deletion. It triggers shell commands in response to these events, making it ideal for automating file-processing workflows, generating logs, or integrating with larger automation systems.

## Project Status

WatchCrab is currently with the main features implemented but is not stable yet. The project is under active development, and new features and improvements are being added regularly. If you encounter any issues or have suggestions for improvements, please open an issue.
WatchCrab is now fully featured, and the project will be maintained to address any issues or bugs. New features may be added if deemed necessary. If you encounter any problems or have suggestions, please open an issue.

## Features

- **Directory Monitoring**: Observe directories for a wide range of filesystem events, including file creation, modification, deletion, and more.
- **Automated Command Execution**: Optionally Trigger customizable shell commands automatically in response to detected events.
- **Asynchronous Event Handling**: Optionally handle events asynchronously to improve performance and responsiveness.
- **Optimized for Automation Workflows**: Designed to integrate smoothly into automation pipelines with minimal configuration.
- **JSON Output**: Provides structured JSON output for straightforward parsing and seamless integration with other tools.
- **Graceful Shutdown (Unix-like systems)**: Ensures safe program termination by waiting for all in-progress commands to finish executing before shutting down. This prevents abrupt termination, reducing the risk of data loss or unexpected errors.
- **Cross-Platform Compatibility**: Runs on both Unix-like systems (Linux, macOS) and Windows.
- **Logging of Command Output**: Optionally Saves the `stdout` and `stderr` of executed commands to a file for easy debugging and record-keeping.
- **Directory Monitoring**: Monitors directories for events, such as file creation, modification, and deletion.
- **Automated Command Execution**: Executes customizable shell commands in response to events.
- **Asynchronous Event Handling**: Optionally handle events asynchronously for higher performance.
- **JSON Output**: Outputs events in JSON for easier parsing and integration with other tools.
- **Graceful Shutdown**: Waits for ongoing tasks to complete before termination, preventing data loss.
- **Cross-Platform**: Compatible with Unix-like systems (Linux, macOS) and Windows.
- **Command Logging**: Optionally logs stdout and stderr of commands for debugging.

## Installation

Expand Down
37 changes: 30 additions & 7 deletions docs/usage_examples.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Usage Examples

WatchCrab provides flexible options for monitoring filesystem events and automating actions based on those events. Here are some example commands to help you get started.

## 1. Monitor filesystem events in a specific directory

To start watching a directory for all filesystem events:
Expand Down Expand Up @@ -37,28 +39,49 @@ The `--args` flag allows you to run a custom shell command when an event is dete
- `{kind}`: The type of event (e.g., create, modify, delete).
- `{path}`: The path to the file that triggered the event.

For example, to log each event:
**Unix**

By default, WatchCrab uses `sh -c` to execute commands on Unix-like systems (Linux, macOS). For example, to log each event:

```bash
watchcrab --path /path/to/directory --args "echo 'Event: {kind} -> Path: {path}'"
```

The `--args` string is passed directly to the shell, so you can use any valid shell command, by default it uses `sh -c` or `cmd /C` depending on the OS.

You can choose the shell to use with the `--sh-cmd` flag:
You can specify a different shell with the `--sh-cmd` flag, like `bash`:

```bash
watchcrab --path /path/to/directory --sh-cmd "bash -c" --args "echo 'Event: {kind} -> Path: {path}'"
watchcrab --path /path/to/directory --sh-cmd "bash -c" --args "echo 'Event: {kind} -> Path: {path}'"
```

**Windows**

On Windows, WatchCrab uses `cmd /C` by default to execute commands. To log each event in Windows:

```powershell
watchcrab --path C:\path\to\directory --args "echo Event: {kind} -> Path: {path}"
```

You can also specify a different shell, such as PowerShell, using `--sh-cmd`:

```powershell
watchcrab --path C:\path\to\directory --sh-cmd "powershell -Command" --args "Write-Output 'Event: {kind} -> Path: {path}'"
```

## 5. Complex command execution
## 5. Flexible and Complex Command Execution

With WatchCrab, you can execute any shell command in response to filesystem events, allowing for high flexibility to adapt to your specific needs and creativity. The `--args` flag supports chaining multiple commands together, so you can build custom workflows that suit your tasks.

You can chain multiple commands together. For instance, to log an event, copy the file, and update a log file:
For example, you can log an event, copy the file to a backup folder, and update a log file in one command:

```bash
watchcrab --path /path/to/directory --events create --args "echo 'Event: {kind} -> Path: {path}' && cp -r {path} ./backup && echo 'log {kind} -> {path}' >> ./log.log"
```

The possibilities are endless. Here are a few ideas:
- **Compress files on creation**: Automatically compress files when they are created.
- **Trigger notifications**: Send desktop notifications or emails based on specific file events.
- **Run custom scripts**: Launch scripts for data processing, backups, or even API requests.

## 6. Asynchronous execution

If you want to run the shell command asynchronously, you can use --threads to specify the number of threads to use. For example, to run the command in four threads:
Expand Down
10 changes: 2 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,22 +165,16 @@ fn main() {
}
}) as Box<dyn Fn(Event) + Send + Sync + 'static>);

if cfg!(target_os = "windows") {
println!("Warning: In Windows, the graceful shutdown is not supported, so the commands can be abruptly terminated");
if args.threads > 1 {
println!("Warning: Be cautious when using multiple threads in Windows, as the commands can be abruptly terminated");
}
}

let watchcrab_watch = Watch::new(&path, args.recursive, &args.events, f, args.threads);
let result = watchcrab_watch.start();

match result {
Ok(_) => {
println!("WatchCrab stopped successfully. All tasks have completed.");
std::process::exit(0);
}
Err(e) => {
eprintln!("Error: {}", e);
eprintln!("WatchCrab Error: {}", e);
std::process::exit(1);
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ use std::process::{Child, Command, Stdio};
use std::sync::Mutex;
use std::{fs::OpenOptions, path::PathBuf};

#[cfg(target_family = "windows")]
use std::os::windows::process::CommandExt;

//https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/Threading/constant.CREATE_NO_WINDOW.html
#[cfg(target_family = "windows")]
use windows::Win32::System::Threading::CREATE_NO_WINDOW;

lazy_static::lazy_static! {
static ref LOG_FILE_MUTEX: Mutex<()> = Mutex::new(());
}
Expand Down Expand Up @@ -89,21 +96,20 @@ pub fn command_exec_unix(sh_cmd_split: &Vec<String>, args_str: String) -> Child
return Err(std::io::Error::last_os_error());
}

libc::signal(libc::SIGINT, libc::SIG_IGN);

Ok(())
})
.spawn()
.expect("failed to execute command")
}
}

///Execute a command on Windows
///Execute a command on Windows disabling the termination signal for the child process
#[cfg(target_family = "windows")]
pub fn command_exec_windows(sh_cmd_split: &Vec<String>, args_str: String) -> Child {
Command::new(&sh_cmd_split[0])
.arg(&sh_cmd_split[1])
.arg(args_str)
.creation_flags(CREATE_NO_WINDOW.0)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
Expand Down
Loading

0 comments on commit 86d8159

Please sign in to comment.