Skip to content

Commit ac98efc

Browse files
committed
ys: Fixes for CLI getopts with more tests
1 parent bd53d1e commit ac98efc

File tree

6 files changed

+211
-118
lines changed

6 files changed

+211
-118
lines changed

ys/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ test: test-unit
6262
test-all: test-unit test-run
6363

6464
test-unit: $(LEIN) $(YAMLSCRIPT_CORE_INSTALLED)
65-
$< test
65+
$< test $(lein-test)
6666

6767
test-run: $(BPAN_LOCAL) build
6868
prove $${TEST_VERBOSE:+'-v'} $(test)

ys/src/yamlscript/cli.clj

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,24 @@
7272
;; See https://clojure.github.io/tools.cli/#clojure.tools.cli/parse-opts
7373
(def cli-options
7474
[;
75-
[nil "--run"
76-
"Run a YAMLScript program file (default)"]
77-
["-l" "--load"
78-
"Output (compact) JSON of YAMLScript evaluation"]
7975
["-e" "--eval YSEXPR"
8076
"Evaluate a YAMLScript expression
8177
multiple -e values joined by newline"
8278
:default []
8379
:update-fn conj
8480
:multi true]
81+
["-l" "--load"
82+
"Output (compact) JSON of YAMLScript evaluation"]
83+
["-f" "--file FILE"
84+
"Explicitly indicate input file"]
8585

8686
["-c" "--compile"
8787
"Compile YAMLScript to Clojure"]
8888
["-b" "--binary"
8989
"Compile to a native binary executable"]
9090

9191
["-p" "--print"
92-
"Print the result of --run in code mode"]
92+
"Print the final evaluation result value"]
9393
["-o" "--output FILE"
9494
"Output file for --load, --compile or --binary"]
9595
["-s" "--stream"
@@ -500,6 +500,15 @@ Options:
500500
(mutex1 opts :print (set/difference action-opts #{:run}))
501501
(mutex1 opts :to (set/difference action-opts #{:load :compile})))))
502502

503+
(defn looks-like-expr [file]
504+
(when (and
505+
(string? file)
506+
(re-find #"(?:^(?:\ |(?:_?[.:]\w))|\ $|\()" file))
507+
(if (fs/exists? file)
508+
(err (str "'" file "' looks like an expression,\n"
509+
"but is also the name of a file. Use --eval or -e."))
510+
true)))
511+
503512
(defn do-main [opts args help error errs]
504513
(if error
505514
(do-error [(str "Error: " error)])
@@ -520,20 +529,20 @@ Options:
520529
:nrepl (do-nrepl opts args)
521530
(do-run opts args)))))
522531

523-
(defn -main [& argv]
524-
(global/reset-env nil)
525-
532+
(defn get-opts [argv]
526533
(let [orig argv
527-
arg1 (first argv)
528-
[args argv] (if (and arg1 (not (re-find #"^-" arg1)))
529-
[[arg1] (cons "--" (rest argv))]
530-
(split-with #(not= "--" %1) argv))
534+
[args argv] (split-with #(not= "--" %1) argv)
535+
[argv is--] (if (= "--" (first argv))
536+
[(rest argv) true]
537+
[argv false])
538+
;_ (WWW "args argv" args argv)
531539
options (cli/parse-opts args cli-options)
532540
{opts :options
533541
args :arguments
534542
help :summary
535543
errs :errors} options
536-
args (concat args (rest argv))
544+
;_ (WWW "args argv" args argv)
545+
args (concat args argv)
537546
opts (if-not (seq orig) (assoc opts :help true) opts)
538547
error (validate-opts opts)
539548
opts (if (env "YS_FORMAT") (assoc opts :to (env "YS_FORMAT")) opts)
@@ -564,44 +573,61 @@ Options:
564573
opts (if (env "YS_STACK_TRACE") (assoc opts :stack-trace true) opts)
565574
opts (if (env "YS_UNORDERED") (assoc opts :unordered true) opts)
566575
opts (if (env "YS_XTRACE") (assoc opts :xtrace true) opts)
567-
[file & args] args
568-
arg1 (first args)
569-
looks-like-expr
570-
(fn []
571-
(when (and
572-
(string? file)
573-
(re-find #"(?:^(?:\ |(?:_?[.:]\w))|\ $|\()" file))
574-
(if (fs/exists? file)
575-
(err (str "'" file "' looks like an expression,\n"
576-
"but is also the name of a file. Use --eval or -e."))
577-
true)))
576+
577+
; _ (WWW "opts" opts "args "args)
578+
is-e (seq (:eval opts))
579+
[arg1 arg2] args
578580
[opts args] (if (and
579581
(not (seq (:eval opts)))
580-
(looks-like-expr)
581-
(or (nil? arg1)
582-
(= arg1 "-")
583-
(fs/exists? arg1)))
584-
[(assoc opts
585-
:file (or arg1 "-")
586-
:eval [file]
587-
:mode "code"
588-
:load true
589-
:to (or (:to opts) "yaml"))
590-
(drop 1 args)]
582+
(looks-like-expr arg1))
583+
(let [opts (assoc opts
584+
:eval [arg1]
585+
:mode (or (:mode opts) "code")
586+
:load true
587+
:to (or (:to opts) "yaml"))
588+
args (rest args)
589+
[opts args] (if (and arg2
590+
(not is--)
591+
(not (re-find #"^-" arg2)))
592+
[(assoc opts :file arg2) (rest args)]
593+
[opts args])
594+
file (or (:file opts)
595+
(when is-- "-"))
596+
opts (if file
597+
(assoc opts :file file)
598+
opts)]
599+
[opts args])
591600
[opts args])
592-
opts (assoc opts :file (or
593-
(:file opts)
594-
file
595-
(and
596-
(:load opts)
597-
(not (seq (:eval opts)))
598-
"-")))]
599-
600-
(reset! global/opts opts)
601-
601+
; _ (WWW "opts" opts "args" args)
602+
file (:file opts)
603+
file (or file
604+
(and (seq (:eval opts)) (not is-e) (not is--) "-"))
605+
; _ (WWW file)
606+
[file args] (if file
607+
[file args]
608+
(if (and (not is--)
609+
(seq args)
610+
(not (re-find #"^-." (first args))))
611+
[(first args) (rest args)]
612+
[nil args]))
613+
file (or file
614+
(and (not (seq (:eval opts))) (:load opts) "-"))
615+
opts (if file (assoc opts :file file) opts)
616+
args (vec args)]
602617
(when (env "YS_SHOW_OPTS")
603618
(println (yaml/generate-string{:opts opts :args args})))
619+
[opts args error errs help]))
620+
621+
(comment
622+
(take 2 (get-opts [".foo" "bar" "baz"]))
623+
(take 2 (get-opts [".foo"]))
624+
#__)
604625

626+
(defn -main [& argv]
627+
(global/reset-env nil)
628+
(let [[opts args error errs help] (get-opts argv)
629+
out (:output opts)]
630+
(reset! global/opts opts)
605631
(if out
606632
(with-open [out (io/writer out)]
607633
(binding [*out* out]

ys/test/cli-usage.t

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,41 @@ HELP =: |
1414

1515
Options:
1616

17-
--run Run a YAMLScript program file (default)
18-
-l, --load Output (compact) JSON of YAMLScript evaluation
1917
-e, --eval YSEXPR Evaluate a YAMLScript expression
2018
multiple -e values joined by newline
19+
-l, --load Output (compact) JSON of YAMLScript evaluation
20+
-f, --file FILE Explicitly indicate input file
21+
22+
# -c, --compile Compile YAMLScript to Clojure
23+
# -b, --binary Compile to a native binary executable
24+
25+
# -p, --print Print the final evaluation result value
26+
# -o, --output FILE Output file for --load, --compile or --binary
27+
# -s, --stream Output all results from a multi-document stream
28+
29+
# -T, --to FORMAT Output format for --load:
30+
# json, yaml, edn
31+
# -J, --json Output (pretty) JSON for --load
32+
# -Y, --yaml Output YAML for --load
33+
# -E, --edn Output EDN for --load
34+
# -U, --unordered Mappings don't preserve key order (faster)
2135

22-
-c, --compile Compile YAMLScript to Clojure
23-
-b, --binary Compile to a native binary executable
24-
25-
# -p, --print Print the result of --run in code mode
26-
# -o, --output FILE Output file for --load, --compile or --binary
27-
# -s, --stream Output all results from a multi-document stream
28-
#
29-
# -T, --to FORMAT Output format for --load:
30-
# json, yaml, edn
31-
# -J, --json Output (pretty) JSON for --load
32-
# -Y, --yaml Output YAML for --load
33-
# -E, --edn Output EDN for --load
34-
# -U, --unordered Mappings don't preserve key order (faster)
35-
#
36-
# -m, --mode MODE Add a mode tag: code, data, or bare (for -e)
37-
# -C, --clojure Treat input as Clojure code
38-
#
39-
# -d Debug all compilation stages
40-
# -D, --debug-stage STAGE Debug a specific compilation stage:
41-
# parse, compose, resolve, build,
42-
# transform, construct, print
43-
# can be used multiple times
44-
# -S, --stack-trace Print full stack trace for errors
45-
# -x, --xtrace Print each expression before evaluation
46-
#
47-
# --install Install the libyamlscript shared library
48-
# --upgrade Upgrade both ys and libyamlscript
49-
#
50-
# --version Print version and exit
51-
# -h, --help Print this help and exit
36+
# -m, --mode MODE Add a mode tag: code, data, or bare (for -e)
37+
# -C, --clojure Treat input as Clojure code
38+
39+
# -d Debug all compilation stages
40+
# -D, --debug-stage STAGE Debug a specific compilation stage:
41+
# parse, compose, resolve, build,
42+
# transform, construct, print
43+
# can be used multiple times
44+
# -S, --stack-trace Print full stack trace for errors
45+
# -x, --xtrace Print each expression before evaluation
46+
47+
# --install Install the libyamlscript shared library
48+
# --upgrade Upgrade both ys and libyamlscript
49+
50+
# --version Print version and exit
51+
# -h, --help Print this help and exit
5252

5353
#'
5454

@@ -226,24 +226,4 @@ test::
226226
- ham
227227
- zucchini
228228

229-
- note: Test args
230-
- cmnd:: "ys $DIR/show-args"
231-
want: nil nil
232-
- cmnd:: "$DIR/show-args"
233-
want: nil nil
234-
- cmnd:: "ys $DIR/show-args --"
235-
want: ("--") ("--")
236-
- cmnd:: "$DIR/show-args --"
237-
want: ("--") ("--")
238-
- cmnd:: "ys $DIR/show-args :foo -42 bar 3.14"
239-
want: (":foo" "-42" "bar" "3.14") (:foo -42 "bar" 3.14)
240-
- cmnd:: "$DIR/show-args :foo -42 bar 3.14"
241-
want: (":foo" "-42" "bar" "3.14") (:foo -42 "bar" 3.14)
242-
- cmnd:: "$DIR/show-args -a -- -b"
243-
want: ("-a" "--" "-b") ("-a" "--" "-b")
244-
- cmnd:: "$DIR/show-args -- -b"
245-
want: ("--" "-b") ("--" "-b")
246-
- cmnd:: "$DIR/show-args -a --"
247-
want: ("-a" "--") ("-a" "--")
248-
249229
done:

ys/test/yamlscript/cli_test.clj

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"'say' evaluates to a symbol")
6565

6666
;; Figure out why this stopped working
67-
#_(has (ys "-ce" "std/say: 123")
67+
#_(is (ys "-ce" "std/say: 123")
6868
"(std/say 123)"
6969
"-c prints Clojure code of compilation")
7070

@@ -80,10 +80,6 @@
8080
"must be one of: json, yaml, edn"
8181
"Validate --to=...")
8282

83-
(has (ys "--run" "--load" "...")
84-
"Error: Options --load and --run are mutually exclusive"
85-
"Can't use multiple action options together")
86-
8783
(has (ys "-J" "-Y" "...")
8884
"Error: Options --yaml and --json are mutually exclusive"
8985
"Can't use multiple data format options together")
@@ -96,22 +92,10 @@
9692
"Error: Options --version and --stack-trace are mutually exclusive"
9793
"Can't use other options with --version")
9894

99-
#_(has (ys "--mode=code" "--run" "...")
100-
"Error: Options --mode and --run are mutually exclusive"
101-
"Can't use --mode with certain actions")
102-
103-
#_(has (ys "--kill" "-e" "...")
104-
"Error: Options --eval and --kill are mutually exclusive"
105-
"Can't --eval with certain actions")
106-
10795
(has (ys "-ple" "...")
10896
"Error: Options --print and --load are mutually exclusive"
10997
"Can't use --print with --load")
11098

111-
(has (ys "--run" "--to=json" "-e" "...")
112-
"Error: Options --to and --run are mutually exclusive"
113-
"Can't use --to with --run")
114-
11599
(is (ys "-Y" "test/loader.ys")
116100
"foo: This is a string
117101
bar:

0 commit comments

Comments
 (0)