From 9f8420bf50089717f80dcad6e5fef54cf0356f21 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Fri, 3 Apr 2020 19:32:50 -0500 Subject: [PATCH] Add jpm repl subcommand and post-deps macro for jpm. This will allow more flexibility in writing jpm project files. --- CHANGELOG.md | 2 ++ auxbin/jpm | 73 ++++++++++++++++++++++++++++++++++++++-------------- jpm.1 | 9 +++++++ 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a83b1eab..b1ae5089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. - Add os/umask - Add os/perm-int - Add os/perm-string +- Add :octal-permissions option for os/stat. +- Add `jpm repl` subcommand, as well as `post-deps` macro in project.janet files. ## 1.8.1 - 2020-03-31 - Fix bugs for big endian systems diff --git a/auxbin/jpm b/auxbin/jpm index 072bc37e..80578d5c 100755 --- a/auxbin/jpm +++ b/auxbin/jpm @@ -181,11 +181,12 @@ (put into k (x k)))) into) -(defn import-rules - "Import another file that defines more rules. This ruleset - is merged into the current ruleset." - [path] +(defn require-jpm + "Require a jpm file project file. This is different from a normal require + in that code is loaded in the jpm environment." + [path &opt no-deps] (def env (make-env)) + (put env :jpm-no-deps no-deps) (unless (os/stat path :mode) (error (string "cannot open " path))) (loop [k :keys _env :when (symbol? k)] @@ -194,9 +195,24 @@ (loop [k :keys currenv :when (keyword? k)] (put env k (currenv k))) (dofile path :env env :exit true) + env) + +(defn import-rules + "Import another file that defines more rules. This ruleset + is merged into the current ruleset." + [path &opt no-deps] + (def env (require-jpm path no-deps)) (when-let [rules (env :rules)] (merge-into (getrules) rules)) env) +(defmacro post-deps + "Run code at the top level if jpm dependencies are installed. Build + code that imports dependencies should be wrapped with this macro, as project.janet + needs to be able to run successfully even without dependencies installed." + [& body] + (unless (dyn :jpm-no-deps) + ~',(reduce |(eval $1) nil body))) + # # OS and shell helpers # @@ -914,8 +930,8 @@ int main(int argc, const char **argv) { '(* "--" '(some (if-not "=" 1)) (+ (* "=" '(any 1)) -1)))) (defn- local-rule - [rule] - (import-rules "./project.janet") + [rule &opt no-deps] + (import-rules "./project.janet" no-deps) (do-rule rule)) (defn- help @@ -950,6 +966,8 @@ Subcommands are: name is lockfile.janet. load-lockfile (lockfile) : Install modules from a lockfile in a reproducible way. The default lockfile name is lockfile.janet. + repl : Run a repl in the context of the current project.janet file. This lets you run rules and + otherwise debug the current project.janet file. Keys are: --modpath : The directory to install modules to. Defaults to $JANET_MODPATH, $JANET_PATH, or (dyn :syspath) @@ -963,15 +981,16 @@ Keys are: --pkglist : URL of git repository for package listing. Defaults to $JANET_PKGLIST or https://github.com/janet-lang/pkgs.git Flags are: + --nocolor : Disable color in the jpm repl. --verbose : Print shell commands as they are executed. --test : If passed to jpm install, runs tests before installing. Will run tests recursively on dependencies. `)) -(defn- show-help +(defn show-help [] (print help)) -(defn- show-paths +(defn show-paths [] (print "binpath: " (dyn :binpath JANET_BINPATH)) (print "modpath: " (dyn :modpath JANET_MODPATH)) @@ -979,21 +998,21 @@ Flags are: (print "headerpath: " (dyn :headerpath JANET_HEADERPATH)) (print "syspath: " (dyn :syspath))) -(defn- build +(defn build [] (local-rule "build")) -(defn- clean +(defn clean [] (local-rule "clean")) -(defn- install +(defn install [&opt repo] (if repo (install-git repo) (local-rule "install"))) -(defn- test +(defn test [] (local-rule "test")) @@ -1003,25 +1022,40 @@ Flags are: (uninstall what) (local-rule "uninstall"))) -(defn- deps +(defn deps [] - (local-rule "install-deps")) + (local-rule "install-deps" true)) -(defn- list-rules - [] - (import-rules "./project.janet") +(defn list-rules + [&opt ctx] + (import-rules "./project.janet" true) (def ks (sort (seq [k :keys (dyn :rules)] k))) (each k ks (print k))) -(defn- update-pkgs +(defn update-pkgs [] (install-git (dyn :pkglist default-pkglist))) -(defn- quickbin +(defn quickbin [input output] (create-executable @{} input output) (do-rule output)) +(defn jpm-repl + [] + (def env (require-jpm "./project.janet")) + (def p (env :project)) + (def name (p :name)) + (setdyn :pretty-format (if-not (dyn :nocolor) "%.20Q" "%.20q")) + (setdyn :err-color (if-not (dyn :nocolor) true)) + (print "Project: " name) + (print "Repository: " (p :repo)) + (print "Author: " (p :author)) + (defn getchunk [buf p] + (def [line] (parser/where p)) + (getline (string "jpm[" name "]:" line ":" (parser/state p :delimiters) "> ") buf env)) + (repl getchunk nil env)) + (def- subcommands {"build" build "clean" clean @@ -1030,6 +1064,7 @@ Flags are: "test" test "help" help "deps" deps + "repl" jpm-repl "show-paths" show-paths "clear-cache" clear-cache "run" local-rule diff --git a/jpm.1 b/jpm.1 index 2e749d77..0a0c72e3 100644 --- a/jpm.1 +++ b/jpm.1 @@ -24,6 +24,10 @@ More interesting are the local commands. For more information on jpm usage, see .SH FLAGS +.TP +.BR \-\-nocolor +Disable color in the jpm repl. + .TP .BR \-\-verbose Print detailed messages of what jpm is doing, including compilation commands and other shell commands. @@ -154,6 +158,11 @@ The main function is the entry point of the program and will receive command lin as function arguments. The entry file can import other modules, including native C modules, and jpm will attempt to include the dependencies into the generated executable. +.TP +.BR repl +Load the current project.janet file and start a repl in it's environment. This lets a user better +debug the project file, as well as run rules manually. + .SH ENVIRONMENT .B JANET_PATH