about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2024-01-02 21:59:39 -0600
committerCase Duckworth2024-01-02 21:59:39 -0600
commita233e84067051cf9bdcb8dc66c2383490ca5ff03 (patch)
tree1c36a3e502657feedefb739a45f1aa5cb7a6b372
downloadok-a233e84067051cf9bdcb8dc66c2383490ca5ff03.tar.gz
ok-a233e84067051cf9bdcb8dc66c2383490ca5ff03.zip
initial commit
-rwxr-xr-xok109
-rwxr-xr-xok199
2 files changed, 208 insertions, 0 deletions
diff --git a/ok b/ok new file mode 100755 index 0000000..058c98d --- /dev/null +++ b/ok
@@ -0,0 +1,109 @@
1#!/bin/sh
2
3QUIET=false
4NORUN=false
5FNEW=false
6_ARGS=true
7
8OKFILE=./ok
9FRFILE=.fr
10
11usage(){
12 exec >&2
13 cat<<EOH
14Usage: ok [OPTIONS] [TARGET...]
15Options:
16 -h Show this help and exit
17 -q Run quietly
18 -x Run with 'set -x'
19 -B Run all targets as if they were "new"
20 -f FILE Use FILE as \$OKFILE (default: 'ok')
21 -C DIRECTORY Change to DIRECTORY before doing anything
22Targets defined in $OKFILE:
23$(sed -n \
24 -e 's/^alias *\(.*\)/*\1/p' \
25 -e 's/^\([a-z][a-z]*\)().*##* *\(.*\)/ \1 # \2/p' \
26 -e 's/^\([a-z][a-z]*\)().*/ \1/p' \
27 "$OKFILE")
28EOH
29}
30
31procargs(){
32 $_ARGS || return 1
33 while getopts hqnxBf:C: OPT
34 do
35 case "$OPT" in
36 (h) usage; exit ;;
37 (q) QUIET=true ;;
38 (x) set -x ;;
39 (n) NORUN=true ;;
40 (B) FNEW=true ;;
41 (f) test -f "$OPTARG" && OKFILE="$OPTARG" || exit 2 ;;
42 (C) cd "$OPTARG" || exit 2 ;;
43 (*) usage; exit 1 ;;
44 esac
45 done
46}
47
48go(){
49 procargs "$@" && shift $((OPTIND - 1))
50 DEFAULT="$(sed -n 's/^\([a-z][a-z]*\)().*/\1/p' "$OKFILE"|sed q)"
51 . "$OKFILE" || exit 3
52 test -z "$1" && "$DEFAULT"
53 for target
54 do
55 if grep -q "$target" "$FRFILE"
56 then if buildp "$target" \
57 "$(grep "$target" "$FRFILE" | cut -f3-)"
58 then eval "$(grep "$target" "$FRFILE" | cut -f2-)"
59 fi
60 else "$target"
61 fi
62 done
63}
64
65dep(){
66 _ARGS=false go "$@"
67}
68
69buildp(){ # buildp TARGET DEPENDENCIES...
70 $FNEW && return 0
71 target="$1"; shift
72 test -e "$target" || return 0
73 for f
74 do
75 test x-- = "x$f" && continue
76 test "$f" -nt "$target" && return 0
77 done
78 return 1
79}
80
81ok(){ # ok COMMAND ARGS..
82 $QUIET || printf >&2 '* %s\n' "$*"
83 $NORUN || "$@" || exit $((100 + $?))
84}
85
86quietly(){ "$@" >/dev/null 2>&1; }
87
88allfiles(){
89 cut -f2- <"$FRFILE" |
90 while read -r line
91 do eval "$line"
92 done
93}
94
95fr(){ # fr < TARGET JOB DEPS...
96 # recommended: use a heredoc
97 :>"$FRFILE"
98 while read -r target job deps
99 do
100 eval set -- "$deps"
101 printf '%s\tok %s\t%s\n' \
102 "$target" \
103 "$job" \
104 "$(printf '%s\n' "$deps"|sed 's/--.*//')" \
105 >>"$FRFILE"
106 done
107}
108
109go "$@"
diff --git a/ok1 b/ok1 new file mode 100755 index 0000000..9d7971c --- /dev/null +++ b/ok1
@@ -0,0 +1,99 @@
1#!/bin/sh
2## ok: a minimal command runner and build tool
3# by Case Duckworth <acdw@acdw.net> -- released to the public domain
4
5QUIET=false
6NORUN=false
7FBUILD=false
8OKFILE=./ok
9FRFILE=.fr
10
11_usage() {
12 exec >&2
13 cat<<EOF
14Usage: ok [OPTIONS] [TARGET...]
15Options:
16 -h Show this help and exit
17 -q Don't output diagnostic messages
18 -x Run with set -x
19 -B Treat all targets as 'new' (force running)
20 -n Don't run commands
21 -f FILE Use FILE as \$OKFILE (default: 'ok')
22 -C DIRECTORY Change to DIRECTORY before doing anything
23Targets defined in $OKFILE:
24$(sed -n \
25 -e 's/^alias *\(.*\)/*\1/p' \
26 -e 's/^\([a-z][a-z]*\)().*##* *\(.*\)/ \1 # \2/p' \
27 -e 's/^\([a-z][a-z]*\)().*/ \1/p' \
28 "$OKFILE")
29EOF
30 exit $1
31}
32
33buildp() { # buildp target dependency...
34 $FBUILD && return
35 target="$1"; shift
36 test -e "$target" || return
37 for f
38 do
39 test x-- = "x$f" && continue
40 test "$f" -nt "$target" && return
41 done
42 return 1
43}
44
45ok() { # ok command...
46 $QUIET || printf >&2 '* %s\n' "$*"
47 $NORUN || "$@" || exit $((100 + $?))
48}
49
50quietly() { "$@" >/dev/null 2>&1; }
51
52frun() {
53 cut -f2- <"$FRFILE" |
54 while read -r line
55 do eval "$line"
56 done
57}
58
59fr() { # fr < GOAL JOB DEPS...
60 # recommended: use a heredoc
61 :>"$FRFILE"
62 while read -r goal job deps
63 do
64 eval set -- "$deps"
65 if buildp "$goal" "$@"
66 then
67 printf '%s\t%s %s\n' \
68 "$goal" \
69 "$job" "$(echo "$deps"|sed 's/--.*//')" \
70 >>"$FRFILE"
71 fi
72 done
73}
74
75while getopts hqnxBf:C: OPT
76do
77 case "$OPT" in
78 (h) _usage ;;
79 (q) QUIET=true ;;
80 (x) set -x ;;
81 (n) NORUN=true ;;
82 (B) FBUILD=true ;;
83 (f) OKFILE="$OPTARG" ;;
84 (C) cd "$OPTARG" || exit 2 ;;
85 (*) _usage 1 ;;
86 esac
87done
88shift $((OPTIND - 1))
89
90. "$OKFILE" || exit 3
91
92test -z "$1" && default
93for target
94do
95 if grep -q "$target" "$FRFILE"
96 then eval "$(grep "$target" "$FRFILE" | cut -f2-)"
97 else "$target"
98 fi
99done