-
Notifications
You must be signed in to change notification settings - Fork 14
/
run.pxi
165 lines (137 loc) · 5.53 KB
/
run.pxi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
(require dust.project :as p)
(refer 'dust.project :only '(defproject load-project!))
(require dust.deps :as d)
(require pixie.string :as str)
(require pixie.io :as io)
(require pixie.fs :as fs)
(require pixie.test :as t)
(def *all-commands* (atom {}))
(def unknown-command (atom true))
(def show-all (atom false))
(def namespaces (atom '("pixie.stdlib" "pixie.async" "pixie.math" "pixie.stacklets" "pixie.system" "pixie.buffers" "pixie.test" "pixie.channels" "pixie.parser" "pixie.time" "pixie.csp" "pixie.uv" "pixie.repl" "pixie.streams" "pixie.ffi-infer" "pixie.io.common" "pixie.io.tty" "pixie.io.tcp" "pixie.io.uv-common" "pixie.io" "pixie.io-blocking" "pixie.fs" "pixie.set" "pixie.string" "pixie.walk")))
(defmacro defcmd
[name description params & body]
(let [body (if (:no-project (meta name))
body
(cons `(load-project!) body))
cmd {:name (str name)
:description description
:params `(quote ~params)
:cmd (cons `fn (cons params body))}]
`(do (swap! *all-commands* assoc '~name ~cmd)
'~name)))
(defcmd describe
"Describe the current project."
[]
(p/describe @p/*project*))
(defn showdoc [ns function]
(let [name (str (if (not= ns "pixie.stdlib") (str ns "/") (str ns "/")))]
;loads other possible namespaces in case function is in other namespace
(if (= @show-all true) (eval (read-string (str "(require " ns ")"))))
(let [data (meta (eval (read-string (str name function))))]
(print (str "\n " name function "\n\n\t"))
(let [func-name (if (not= (str/index-of function "/") nil) (str function) (str name function))]
(loop [sigs (lazy-seq (:signatures data))]
(when (not= sigs '())
(print (str/replace (str (lazy-seq (first sigs)) " ") "(" (str "(" func-name " ")))
(recur (rest sigs)))))
(if (nil? data)
(do
(println "\n\n\t No documentation available.\n")
(reset! unknown-command false)
(if (= (first @namespaces) "") (reset! namespaces '())))
(do
(print (str "\n\n\t"))
(print
(if (not= (str (:doc data)) "nil")
(str (:doc data) " ")
(str "No further documentation available.\n")))
(reset! unknown-command false)
(print
(if (not= (str (:added data)) "nil")
(str " [added: v" (:added data) "]\n\n")
(str "\n\n")))
(if (= (first @namespaces) "pixie.stdlib")
(reset! namespaces '())))))))
(defcmd doc
"Show function documentation. Broaden search using -all"
[function-name & search-all]
(if (= (str (first search-all)) "-all") (reset! show-all true))
(loop [_ 0]
(when (not= @namespaces '())
(try (showdoc (str (first @namespaces)) (str function-name))
(catch e
nil))
(recur (reset! namespaces (rest @namespaces)))))
(if (= @unknown-command true) (println (str "\n " function-name "\n\n\t Function not found. " (if (not= (str (first search-all)) "-all") (str "Broaden search using -all flag.\n") (str "\n"))))))
(defcmd deps
"List the dependencies and their versions of the current project."
[]
(doseq [[name version] (:dependencies @p/*project*)]
(println name version)))
(defcmd load-path
"Print the load path of the current project."
[]
(when (not (fs/exists? (fs/file ".load-path")))
(println "Please run `dust get-deps`")
(exit 1))
(doseq [path (str/split (io/slurp ".load-path") "--load-path")]
(when (not (str/empty? path))
(println (str/trim path)))))
(defcmd get-deps
"Download the dependencies of the current project."
[]
(-> @p/*project* d/get-deps d/write-load-path))
(defcmd ^:no-project repl
"Start a REPL in the current project."
[]
(throw (str "This should be invoked by the wrapper.")))
(defcmd ^:no-project run
"Run the code in the given file."
[file]
(throw (str "This should be invoked by the wrapper.")))
(defn load-tests [dirs]
(println "Looking for tests...")
(let [dirs (distinct (map fs/dir dirs))
pxi-files (->> dirs
(mapcat fs/walk-files)
(filter #(fs/extension? % "pxi"))
(filter #(str/starts-with? (fs/basename %) "test-"))
(distinct))]
(foreach [file pxi-files]
(println "Loading " file)
(load-file (fs/abs file)))))
(defcmd test "Run the tests of the current project."
[& args]
(println @load-paths)
(load-tests (:test-paths @p/*project*))
(let [result (apply t/run-tests args)]
(exit (get result :fail))))
(defn help-cmd [cmd]
(let [{:keys [name description params] :as info} (get @*all-commands* (symbol cmd))]
(if info
(do
(println (str "Usage: dust " name " " params))
(println)
(println description))
(println "Unknown command:" cmd))))
(defn help-all []
(println "Usage: dust <cmd> <options>")
(println)
(println "Available commands:")
(doseq [{:keys [name description]} (vals @*all-commands*)]
(println (str " " name (apply str (repeat (- 10 (count name)) " ")) description))))
(defcmd ^:no-project help
"Display the help"
[& [cmd]]
(if cmd
(help-cmd cmd)
(help-all)))
(def *command* (first program-arguments))
(let [cmd (get @*all-commands* (symbol *command*))]
(try
(if cmd
(apply (get cmd :cmd) (next program-arguments))
(println "Unknown command:" *command*))
(catch :dust/Exception e
(println (str "Dust encountered an error: " (pr-str (ex-msg e)))))))