diff options
-rwxr-xr-x | ok | 109 | ||||
-rwxr-xr-x | ok1 | 99 |
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 | |||
3 | QUIET=false | ||
4 | NORUN=false | ||
5 | FNEW=false | ||
6 | _ARGS=true | ||
7 | |||
8 | OKFILE=./ok | ||
9 | FRFILE=.fr | ||
10 | |||
11 | usage(){ | ||
12 | exec >&2 | ||
13 | cat<<EOH | ||
14 | Usage: ok [OPTIONS] [TARGET...] | ||
15 | Options: | ||
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 | ||
22 | Targets 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") | ||
28 | EOH | ||
29 | } | ||
30 | |||
31 | procargs(){ | ||
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 | |||
48 | go(){ | ||
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 | |||
65 | dep(){ | ||
66 | _ARGS=false go "$@" | ||
67 | } | ||
68 | |||
69 | buildp(){ # 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 | |||
81 | ok(){ # ok COMMAND ARGS.. | ||
82 | $QUIET || printf >&2 '* %s\n' "$*" | ||
83 | $NORUN || "$@" || exit $((100 + $?)) | ||
84 | } | ||
85 | |||
86 | quietly(){ "$@" >/dev/null 2>&1; } | ||
87 | |||
88 | allfiles(){ | ||
89 | cut -f2- <"$FRFILE" | | ||
90 | while read -r line | ||
91 | do eval "$line" | ||
92 | done | ||
93 | } | ||
94 | |||
95 | fr(){ # 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 | |||
109 | go "$@" | ||
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 | |||
5 | QUIET=false | ||
6 | NORUN=false | ||
7 | FBUILD=false | ||
8 | OKFILE=./ok | ||
9 | FRFILE=.fr | ||
10 | |||
11 | _usage() { | ||
12 | exec >&2 | ||
13 | cat<<EOF | ||
14 | Usage: ok [OPTIONS] [TARGET...] | ||
15 | Options: | ||
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 | ||
23 | Targets 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") | ||
29 | EOF | ||
30 | exit $1 | ||
31 | } | ||
32 | |||
33 | buildp() { # 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 | |||
45 | ok() { # ok command... | ||
46 | $QUIET || printf >&2 '* %s\n' "$*" | ||
47 | $NORUN || "$@" || exit $((100 + $?)) | ||
48 | } | ||
49 | |||
50 | quietly() { "$@" >/dev/null 2>&1; } | ||
51 | |||
52 | frun() { | ||
53 | cut -f2- <"$FRFILE" | | ||
54 | while read -r line | ||
55 | do eval "$line" | ||
56 | done | ||
57 | } | ||
58 | |||
59 | fr() { # 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 | |||
75 | while getopts hqnxBf:C: OPT | ||
76 | do | ||
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 | ||
87 | done | ||
88 | shift $((OPTIND - 1)) | ||
89 | |||
90 | . "$OKFILE" || exit 3 | ||
91 | |||
92 | test -z "$1" && default | ||
93 | for target | ||
94 | do | ||
95 | if grep -q "$target" "$FRFILE" | ||
96 | then eval "$(grep "$target" "$FRFILE" | cut -f2-)" | ||
97 | else "$target" | ||
98 | fi | ||
99 | done | ||