Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ project:

With such a project definition you can run `dust get-deps` to fetch the
dependencies of the project and dust will set up the `load-paths` var in
Pixie so that the namespaces are availlable in the repl or when running
programs:
Pixie so that the namespaces are available in the repl or when running programs:

```
$ dust get-deps
Expand Down Expand Up @@ -76,5 +75,4 @@ Some ideas:

* `dust doc`, probably using something like [this](https://github.com/pixie-lang/pixie/blob/master/examples/gen-docs.pxi)
* dependency improvements:
- recursive dependencies (e.g. fetch dependencies of dependencies)
- fetch dependencies from paths inside repositories, maybe via a `:path "sub/dir"` option
16 changes: 7 additions & 9 deletions dust
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,28 @@ if [ -z "$pixie_path" ]; then
fi
run_dust="$pixie_path -l $base_path/src $base_path/run.pxi"

function load_path() {
function set_load_path() {
load_path=""
if [ -f "project.pxi" ]; then
load_path="`$run_dust load-path option`"
if [ -f "project.pxi" ] && [ -f ".load-path" ]; then
load_path="`cat .load-path`"
fi
echo $load_path
}

case $1 in
"get-deps")
$run_dust $@ | sh
;;
""|"repl")
rlwrap_cmd=""
if [ -n "`which rlwrap`" ]; then
rlwrap_cmd="rlwrap -aignored -n"
fi
$rlwrap_cmd $pixie_path `load_path`
set_load_path
$rlwrap_cmd $pixie_path $load_path
;;
"run")
shift
file=$1
shift
$pixie_path `load_path` $file $@
set_load_path
$pixie_path $load_path $file $@
;;
-h|--help)
$run_dust help
Expand Down
1 change: 1 addition & 0 deletions examples/html/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
deps
.load-path
91 changes: 36 additions & 55 deletions run.pxi
Original file line number Diff line number Diff line change
@@ -1,79 +1,59 @@
(require dust.project :as p)
(refer 'dust.project :only '(defproject))

(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 {}))

(defmacro defcmd [name description params & body]
(let [f (cons `fn (cons params body))
(defmacro defcmd
[name description params & body]
(let [body (if (:no-project (meta name))
body
(cons `(load-file "project.pxi") body))
cmd {:name (str name)
:description description
:params `(quote ~params)
:cmd f}]
`(do (swap! *all-commands*
assoc '~name ~cmd)
:cmd (cons `fn (cons params body))}]
`(do (swap! *all-commands* assoc '~name ~cmd)
'~name)))

(defcmd describe "Describe the current project."
(defcmd describe
"Describe the current project."
[]
(load-file "project.pxi")
(p/describe @p/*project*))

(defcmd deps "List the dependencies and their versions of the current project."
(defcmd deps
"List the dependencies and their versions of the current project."
[]
(load-file "project.pxi")
(doseq [dep (:dependencies @p/*project*)]
(println (:name dep) (:version dep))))
(doseq [[name version] (:dependencies @p/*project*)]
(println name version)))

(defn echo [& args]
(apply println "echo" args))

(defn mkdir [dir]
(println "mkdir" "-p" dir))

(defn rm [file]
(println "rm" file))

(defn download [url file]
(println "curl" "--silent" "--location" "--output" file url))

(defn extract-to [archive dir]
(mkdir dir)
(println "tar" "--strip-components" 1 "--extract" "--directory" dir "--file" archive))

(defcmd get-deps "Download the dependencies of the current project."
(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."
[]
(load-file "project.pxi")

(mkdir "deps")
(doseq [{:keys [name version ref]} (get @p/*project* :dependencies)]
(echo "Downloading" name)
(let [download-url (str "https://github.com/" name "/archive/" version ".tar.gz")
file-name (str "deps/" (str/replace (str name) "/" "-") ".tar.gz")
dep-dir (str "deps/" name)]
(download download-url file-name)
(extract-to file-name dep-dir)
(rm file-name))))

(defcmd load-path "Print the load path of the current project."
[& [format]]
(load-file "project.pxi")
(let [print-fn (if (= format "option")
#(print "--load-path" % "")
println)
project @p/*project*]
(doseq [path (get project :source-paths)]
(print-fn path))
(doseq [{:keys [name]} (get project :dependencies)]
(print-fn (str "deps/" name "/src")))))

(defcmd repl "Start a REPL in 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 run "Run the code in the given file."
(defcmd ^:no-project run
"Run the code in the given file."
[file]
(throw (str "This should be invoked by the wrapper.")))

Expand Down Expand Up @@ -102,7 +82,8 @@
(doseq [{:keys [name description]} (vals @*all-commands*)]
(println (str " " name (apply str (repeat (- 10 (count name)) " ")) description))))

(defcmd help "Display the help"
(defcmd ^:no-project help
"Display the help"
[& [cmd]]
(if cmd
(help-cmd cmd)
Expand Down
67 changes: 67 additions & 0 deletions src/dust/deps.pxi
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
(ns dust.deps
(require pixie.string :as str)
(require pixie.io :as io)
(require pixie.fs :as fs)
(require dust.project :as p))

(defn cmd
[& args]
(sh (str/join " " args)))

(defn rm [file]
(cmd "rm" file))

(defn mkdir [file]
(cmd "mkdir" "-p" file))

(defn download [url file]
(cmd "curl" "--silent" "--location" "--output" file url))

(defn extract-to [archive dir]
(mkdir dir)
(cmd "tar" "--strip-components" 1 "--extract" "--directory" dir "--file" archive))

(defn write-load-path
"Write .load-path for project"
[project]
(let [paths (mapcat (fn [{:keys [path source-paths]}]
(if path
(map #(str path "/" %) source-paths)
source-paths))
(:dependencies project))]
(io/spit ".load-path"
(str "--load-path " (str/join " --load-path " paths)))))

(defn load-project
"Load project.pxi in dir - return project map"
[dir]
(-> (io/slurp (str dir "/project.pxi"))
(read-string)
(rest)
(p/project->map)
(eval)
(assoc :path dir)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is :path used anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, right here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah sorry, i missed that. :)


(defn resolve-dependency
"Download and extract dependency - return dependency project map."
[[name version]]
(let [url (str "https://github.com/" name "/archive/" version ".tar.gz")
file-name (str "deps/" (str/replace (str name) "/" "-") ".tar.gz")
dep-dir (str "deps/" name)]
(when (not (fs/exists? (fs/->Dir dep-dir)))
(println "Downloading" name)
(download url file-name)
(extract-to file-name dep-dir)
(rm file-name))
(load-project dep-dir)))

(defn get-deps
"Recursively download and extract all project dependencies."
[project]
(let [child-fn #(map resolve-dependency (:dependencies %))
dep-dir "deps"]
(when (fs/exists? (fs/->Dir dep-dir))
(cmd "rm" "-r" dep-dir))
(mkdir dep-dir)
(assoc project :dependencies
(vec (tree-seq :dependencies child-fn project)))))
48 changes: 23 additions & 25 deletions src/dust/project.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,31 @@

(def *project* (atom nil))

(defn expand-dependencies [project]
(let [deps (get project :dependencies)]
(if deps
(assoc project
:dependencies
(vec (map (fn [[name version & options]]
(merge {:name name, :version version}
(apply hashmap options)))
deps)))
project)))

(defn merge-defaults [project]
(merge {:source-paths ["src"]}
project))
(merge {:source-paths ["src"]} project))

(defn quote-dependency-names
[project]
(if-let [deps (:dependencies project)]
(assoc project
:dependencies
(vec (map (fn [[nm & rest]]
(vec (cons `(quote ~nm) rest)))
deps)))
project))

(defn project->map
[[nm version & description]]
(let [description (apply hashmap description)]
(-> description
(assoc :name `(quote ~nm) :version version)
quote-dependency-names
merge-defaults)))

(defmacro defproject
[nm version & description]
(let [description (apply hashmap description)
description (if (contains? description :dependencies)
(update-in description [:dependencies] (fn [deps] `(quote ~deps)))
description)]
`(reset! *project*
(-> (assoc ~description
:name (quote ~nm)
:version ~version)
expand-dependencies
merge-defaults))))
[& args]
(let [project (project->map args)]
`(reset! *project* ~project)))

(defn describe [project]
(let [{:keys [name version]} project]
Expand All @@ -39,5 +37,5 @@
(println (str " " (str/capitalize k) ": " v))))
(when-let [deps (get project :dependencies)]
(println " Dependencies:")
(doseq [{:keys [name version]} deps]
(doseq [[name version] deps]
(println (str " - " name "@" version))))))