-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add rn watch entity for file change monitoring #48
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -80,6 +80,49 @@ _u7_run() { | |||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| watch) | ||||||||||||||||||||||||||||||||||||||||||||||
| local file="$1" | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$file" || "$2" != "run" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: u7 rn watch <file> run <command>" | ||||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ ! -e "$file" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "File not found: $file" | ||||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| shift 2 | ||||||||||||||||||||||||||||||||||||||||||||||
| local cmd="$*" | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$cmd" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: u7 rn watch <file> run <command>" | ||||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$_U7_DRY_RUN" == "1" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "[dry-run] watch $file and run $cmd on change" | ||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "Watching $file for changes... (Ctrl+C to stop)" | ||||||||||||||||||||||||||||||||||||||||||||||
| if command -v inotifywait &>/dev/null; then | ||||||||||||||||||||||||||||||||||||||||||||||
| while inotifywait -qq -e modify "$file"; do | ||||||||||||||||||||||||||||||||||||||||||||||
| eval "$cmd" | ||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||
| local last_mod cur_mod | ||||||||||||||||||||||||||||||||||||||||||||||
| last_mod=$(stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null) | ||||||||||||||||||||||||||||||||||||||||||||||
| while true; do | ||||||||||||||||||||||||||||||||||||||||||||||
| sleep 1 | ||||||||||||||||||||||||||||||||||||||||||||||
| cur_mod=$(stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null) | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -z "$cur_mod" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "File no longer exists, stopping watch." >&2 | ||||||||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$cur_mod" != "$last_mod" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| last_mod="$cur_mod" | ||||||||||||||||||||||||||||||||||||||||||||||
| eval "$cmd" | ||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+111
to
+122
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The polling loop does not handle file deletion gracefully. If the file is deleted, The loop should detect when
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| ;; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| --help|-h) | ||||||||||||||||||||||||||||||||||||||||||||||
| cat << 'EOF' | ||||||||||||||||||||||||||||||||||||||||||||||
| u7 rn (run) - Execute/Control | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -89,6 +132,7 @@ Usage: u7 rn <entity> [arguments] | |||||||||||||||||||||||||||||||||||||||||||||
| Entities: | ||||||||||||||||||||||||||||||||||||||||||||||
| job <cmd> in <time> Schedule command (5s, 10m, 1h) | ||||||||||||||||||||||||||||||||||||||||||||||
| script <path> Execute shell script | ||||||||||||||||||||||||||||||||||||||||||||||
| watch <file> run <command> Watch file and run command on change | ||||||||||||||||||||||||||||||||||||||||||||||
| <command> in background Run command in background | ||||||||||||||||||||||||||||||||||||||||||||||
| <command> with priority <nice> Run with CPU priority | ||||||||||||||||||||||||||||||||||||||||||||||
| check syntax in file <path> Check single file syntax | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -988,6 +988,30 @@ else | |
| ((PASSED++)) | ||
| fi | ||
|
|
||
| # ===== rn watch tests ===== | ||
|
|
||
| # Test: rn watch usage (missing args) | ||
| result=$(u7 rn watch 2>&1) | ||
| assert_contains "rn watch shows usage on missing args" "Usage" "$result" | ||
|
|
||
| # Test: rn watch usage (missing run keyword) | ||
| touch watch_target.txt | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
| result=$(u7 rn watch watch_target.txt 2>&1) | ||
| assert_contains "rn watch shows usage when run keyword missing" "Usage" "$result" | ||
|
|
||
| # Test: rn watch file not found | ||
| result=$(u7 rn watch nonexistent_file.txt run echo hi 2>&1) | ||
| assert_contains "rn watch reports missing file" "not found" "$result" | ||
|
|
||
| # Test: rn watch dry-run | ||
| touch watch_target.txt | ||
| result=$(u7 -n rn watch watch_target.txt run echo hello 2>&1) | ||
| assert_equals "rn watch dry-run output" "[dry-run] watch watch_target.txt and run echo hello on change" "$result" | ||
|
|
||
| # Test: rn watch help text includes watch | ||
| result=$(u7 rn --help 2>&1) | ||
| assert_contains "rn help mentions watch" "watch" "$result" | ||
|
|
||
| # ===== sh log tests ===== | ||
|
|
||
| # Setup: create a temp log file | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
evalon command strings can be risky and lead to unexpected behavior due to double evaluation of shell metacharacters. It's generally safer to execute commands in a more controlled environment.While
evalallows executing shell functions from the parent environment, consider if this is a required feature. If not, a safer alternative likebash -c "$cmd"could be used, which runs the command in an isolated subshell. This advice also applies to line 118.