Skip to content

Commit

Permalink
Fix lein run first argument bugs.
Browse files Browse the repository at this point in the history
There were three related problems:

1) The first argument was always parsed with read-string, even
   when defaulting to the :main namespace.  This caused
   non-numeric first arguments to throw:

   Exception in thread "main" java.lang.Exception: Unable to
   resolve symbol: foo in this context

   Avoid read-string entirely and update the unit tests to use an
   unreadable string instead of a number to make the problem obvious.

   This problem was reported by Marek Kubica on the Clojure
   mailing list.

2) When using an alias the alias keyword was passed to -main as the
   first argument.  This is inconsistent with how the -m and :main
   simply pass the program arguments, not the namespace or -m flag.

3) There was no way to pass "-m" or a string beginning with ":"
   as a first argument to the run program.  Added "--" as an option
   to escape these.
  • Loading branch information
ato committed Dec 24, 2010
1 parent b61da8c commit 3f299cc
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 16 deletions.
19 changes: 10 additions & 9 deletions src/leiningen/run.clj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
(defn ^{:help-arglists '([])} run
"Run a -main function with optional command-line arguments.
USAGE: lein run [ARGS...]
USAGE: lein run [--] [ARGS...]
Calls the -main function in the namespace specified as :main in project.clj.
You may use -- to escape the first argument in case it begins with `-' or `:'.
USAGE: lein run -m NAMESPACE [ARGS...]
Calls the -main function in the specified namespace.
Expand All @@ -23,13 +24,13 @@ USAGE: lein run :alias [ARGS...]
Aliases can be defined in project.clj as
:run-aliases {:alias a.namespace
:alias2 another.namespace}"
[project & [flag & args]]
(let [flag (and flag (read-string flag))
alias (and (keyword? flag) (flag (:run-aliases project)))
args (if (and flag (not= '-m flag))
(conj args flag)
args)]
[project & [flag & args :as all-args]]
(let [kw (when (= (first flag) \:) (keyword (subs flag 1)))
alias (get (:run-aliases project) kw)
all-args (if (= flag "--") args all-args)]
(cond alias (apply run project "-m" (cons alias args))
(= flag '-m) (apply run-main project args)
(:main project) (apply run-main project (:main project) args)
(= flag "-m") (if (first args)
(apply run-main project args)
(abort "Option -m requires a namespace argument."))
(:main project) (apply run-main project (:main project) all-args)
:else (abort "No :main namespace specified in project.clj."))))
20 changes: 13 additions & 7 deletions test/test_run.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,22 @@
(delete-file out-file :silently)))

(deftest test-basic
(is (zero? (run project "1")))
(is (= "nom:1" (slurp out-file))))
(is (zero? (run project "/unreadable")))
(is (= "nom:/unreadable" (slurp out-file))))

(deftest test-alt-main
(is (zero? (run project "-m" "org.domain.tricky-name.munch" "1")))
(is (= ":munched (\"1\")" (slurp out-file))))
(is (zero? (run project "-m" "org.domain.tricky-name.munch" "/unreadable")))
(is (= ":munched (\"/unreadable\")" (slurp out-file))))

(deftest test-aliases
(is (zero? (run project ":bbb" "1")))
(is (zero? (run project ":bbb" "/unreadable")))
(is (= "BRUNCH" (slurp out-file)))
(delete-file out-file :silently)
(is (zero? (run project ":mmm" "1")))
(is (= ":munched (:mmm \"1\")" (slurp out-file))))
(is (zero? (run project ":mmm" "/unreadable")))
(is (= ":munched (\"/unreadable\")" (slurp out-file))))

(deftest test-escape-args
(is (zero? (run project "--" ":bbb")))
(is (= "nom::bbb" (slurp out-file)))
(is (zero? (run project "--" "-m")))
(is (= "nom:-m" (slurp out-file))))

0 comments on commit 3f299cc

Please sign in to comment.