mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Update jpm tool.
The jpm tool can now use git to download dependencies, install packages from urls, and use a manifest file for better uninstalls.
This commit is contained in:
		| @@ -1,6 +1,9 @@ | ||||
| # Changelog | ||||
| All notable changes to this project will be documented in this file. | ||||
|  | ||||
| ## Unreleased | ||||
| - Change semantics of `-l` flag to be import rather than dofile. | ||||
|  | ||||
| ## 1.0.0 - 2019-07-01 | ||||
| - Add `with` macro for resource handling. | ||||
| - Add `propagate` function so we can "rethrow" signals after they are | ||||
|   | ||||
							
								
								
									
										85
									
								
								auxbin/jpm
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								auxbin/jpm
									
									
									
									
									
								
							| @@ -8,13 +8,27 @@ | ||||
|   (peg/compile | ||||
|     '(* "--" '(some (if-not "=" 1)) "=" '(any 1)))) | ||||
|  | ||||
| (defn- local-rule | ||||
|   [rule] | ||||
|   (cook/import-rules "./project.janet") | ||||
|   (cook/do-rule rule)) | ||||
|  | ||||
| (defn- help | ||||
|   [] | ||||
|   (print "usage: jpm [targets]... --key=value ...") | ||||
|   (print "Available targets are:") | ||||
|   (each k (sort (keys (dyn :rules @{}))) | ||||
|     (print "  " k)) | ||||
|   (print ` | ||||
| usage: jpm --key=value ... [subcommand] [args]... | ||||
|  | ||||
| Subcommands are: | ||||
|   build : build all artifacts | ||||
|   install (repo) : install artifacts. If a repo is given, install the contents of that | ||||
|                    git repository, assuming that the repository is a jpm project. If not, build | ||||
|                    and install the current project. | ||||
|   uninstall (module) : uninstall a module. If no module is given, uninstall the module | ||||
|                        defined by the current directory. | ||||
|   clean : remove any generated files or artifacts | ||||
|   test : run tests | ||||
|   deps : install dependencies. | ||||
|   clear-cache : clear the git cache. Useful for updating dependencies. | ||||
|  | ||||
| Keys are: | ||||
|   --modpath : The directory to install modules to. Defaults to $JANET_MODPATH or (dyn :syspath) | ||||
| @@ -27,17 +41,64 @@ Keys are: | ||||
|   --lflags : Extra linker flags for native modules. Defaults to $LFLAGS if set. | ||||
|     `)) | ||||
|  | ||||
| (defn build | ||||
|   [] | ||||
|   (local-rule "build")) | ||||
|  | ||||
| (defn clean | ||||
|   [] | ||||
|   (local-rule "clean")) | ||||
|  | ||||
| (defn install | ||||
|   [&opt repo] | ||||
|   (if repo | ||||
|     (cook/install-git repo) | ||||
|     (local-rule "install"))) | ||||
|  | ||||
| (defn test | ||||
|   [] | ||||
|   (local-rule "test")) | ||||
|  | ||||
| (defn uninstall | ||||
|   [&opt what] | ||||
|   (if what | ||||
|     (cook/uninstall what) | ||||
|     (local-rule "uninstall"))) | ||||
|  | ||||
| (defn deps | ||||
|   [] | ||||
|   (local-rule "install-deps")) | ||||
|  | ||||
| (def subcommands | ||||
|   {"build" build | ||||
|    "clean" clean | ||||
|    "install" install | ||||
|    "test" test | ||||
|    "help" help | ||||
|    "deps" deps | ||||
|    "clear-cache" cook/clear-cache | ||||
|    "uninstall" uninstall}) | ||||
|  | ||||
| (def args (tuple/slice process/args 2)) | ||||
| (def todo @[]) | ||||
| (each arg args | ||||
|   (if (string/has-prefix? "--" arg) | ||||
| (def len (length args)) | ||||
| (var i 0) | ||||
|  | ||||
| # Get flags | ||||
| (while (< i len) | ||||
|   (def arg (args i)) | ||||
|   (unless (string/has-prefix? "--" arg) (break)) | ||||
|   (if-let [m (peg/match argpeg arg)] | ||||
|     (let [[key value] m] | ||||
|       (setdyn (keyword key) value)) | ||||
|     (print "invalid argument " arg)) | ||||
|     (array/push todo arg))) | ||||
|   (++ i)) | ||||
|  | ||||
| (cook/import-rules "./project.janet") | ||||
|  | ||||
| (if (empty? todo) (help)) | ||||
| (each rule todo (cook/do-rule rule)) | ||||
| # Run subcommand | ||||
| (if (= i len) | ||||
|   (help) | ||||
|   (do | ||||
|     (if-let [com (subcommands (args i))] | ||||
|       (com ;(tuple/slice args (+ i 1))) | ||||
|       (do | ||||
|         (print "invalid command " (args i)) | ||||
|         (help))))) | ||||
|   | ||||
| @@ -15,14 +15,14 @@ | ||||
| (def- sep (if is-win "\\" "/")) | ||||
| (def- objext (if is-win ".obj" ".o")) | ||||
| (def- modext (if is-win ".dll" ".so")) | ||||
| (def- absprefix (if is-win "C:\\" "/")) | ||||
|  | ||||
| # | ||||
| # Rule Engine | ||||
| # | ||||
|  | ||||
| (defn- getrules [] | ||||
|   (def rules (dyn :rules)) | ||||
|   (if rules rules (setdyn :rules @{}))) | ||||
|   (if-let [rules (dyn :rules)] rules (setdyn :rules @{}))) | ||||
|  | ||||
| (defn- gettarget [target] | ||||
|   (def item ((getrules) target)) | ||||
| @@ -284,25 +284,98 @@ | ||||
|         (file/close out) | ||||
|         (file/close f))) | ||||
|  | ||||
| (defn- abspath | ||||
|   "Create an absolute path. Does not resolve . and .. (useful for | ||||
|   generating entries in install manifest file)." | ||||
|   [path] | ||||
|   (if (string/has-prefix? absprefix) | ||||
|     path | ||||
|     (string (os/cwd) sep path))) | ||||
|  | ||||
| # | ||||
| # Declaring Artifacts - used in project.janet, targets specifically | ||||
| # tailored for janet. | ||||
| # Public utilities | ||||
| # | ||||
|  | ||||
| (defn- install-rule | ||||
| (defn repo-id | ||||
|   "Convert a repo url into a path component that serves as its id." | ||||
|   [repo] | ||||
|   (string/replace-all "\\" "_" (string/replace-all "/" "_" repo))) | ||||
|  | ||||
| (defn find-manifest-dir | ||||
|   "Get the path to the directory containing manifests for installed | ||||
|   packages." | ||||
|   [&opt opts] | ||||
|   (string (opt (or opts @{}) :modpath JANET_MODPATH) sep ".manifests")) | ||||
|  | ||||
| (defn find-manifest | ||||
|   "Get the full path of a manifest file given a package name." | ||||
|   [name &opt opts] | ||||
|   (string (find-manifest-dir opts) sep name ".txt")) | ||||
|  | ||||
| (defn find-cache | ||||
|   "Return the path to the global cache." | ||||
|   [&opt opts] | ||||
|   (def path (opt (or opts @{}) :modpath JANET_MODPATH)) | ||||
|   (string path sep ".cache")) | ||||
|  | ||||
| (defn uninstall | ||||
|   "Uninstall bundle named name" | ||||
|   [name &opt opts] | ||||
|   (def manifest (find-manifest name opts)) | ||||
|   (def f (file/open manifest :r)) | ||||
|   (unless f (print manifest " does not exist") (break)) | ||||
|   (loop [line :iterate (:read f :line)] | ||||
|     (def path ((string/split "\n" line) 0)) | ||||
|     (print "removing " path) | ||||
|     (try (rm path) ([err] | ||||
|                     (unless (= err "No such file or directory") | ||||
|                       (error err))))) | ||||
|   (print "removing " manifest) | ||||
|   (rm manifest) | ||||
|   (:close f) | ||||
|   (print "Uninstalled.")) | ||||
|  | ||||
| (defn clear-cache | ||||
|   "Clear the global git cache." | ||||
|   [&opt opts] | ||||
|   (rm (find-cache opts))) | ||||
|  | ||||
| (defn install-git | ||||
|   "Install a bundle from git. If the bundle is already installed, the bundle | ||||
|   is reinistalled (but not rebuilt if artifacts are cached)." | ||||
|   [repo &opt opts] | ||||
|   (def cache (find-cache opts)) | ||||
|   (os/mkdir cache) | ||||
|   (def id (repo-id repo)) | ||||
|   (def module-dir (string cache sep id)) | ||||
|   (when (os/mkdir module-dir) | ||||
|     (os/execute ["git" "clone" repo module-dir] :p)) | ||||
|   (def olddir (os/cwd)) | ||||
|   (os/cd module-dir) | ||||
|   (try | ||||
|     (with-dyns [:rules @{}] | ||||
|       (import-rules "./project.janet") | ||||
|       (do-rule "install-deps") | ||||
|       (do-rule "build") | ||||
|       (do-rule "install")) | ||||
|     ([err] nil)) | ||||
|   (os/cd olddir)) | ||||
|  | ||||
| (defn install-rule | ||||
|   "Add install and uninstall rule for moving file from src into destdir." | ||||
|   [src destdir] | ||||
|   (def parts (string/split sep src)) | ||||
|   (def name (last parts)) | ||||
|   (def path (string destdir sep name)) | ||||
|   (array/push (dyn :installed-files) path) | ||||
|   (add-body "install" | ||||
|             (try (os/mkdir destdir) ([err] nil)) | ||||
|             (copy src destdir)) | ||||
|   (add-body "uninstall" | ||||
|             (def path (string destdir sep name)) | ||||
|             (print "removing " path) | ||||
|             (try (rm path) ([err] | ||||
|                             (unless (= err "No such file or directory") | ||||
|                               (error err)))))) | ||||
|             (copy src destdir))) | ||||
|  | ||||
| # | ||||
| # Declaring Artifacts - used in project.janet, targets specifically | ||||
| # tailored for janet. | ||||
| # | ||||
|  | ||||
| (defn declare-native | ||||
|   "Declare a native binary. This is a shared library that can be loaded | ||||
| @@ -378,11 +451,37 @@ | ||||
|   Also sets up basic phony targets like clean, build, test, etc." | ||||
|   [&keys meta] | ||||
|   (setdyn :project meta) | ||||
|   (try (os/mkdir "build") ([err] nil)) | ||||
|   (phony "build" []) | ||||
|   (phony "install" ["build"] (print "Installed.")) | ||||
|   (phony "uninstall" [] (print "Uninstalled.")) | ||||
|   (phony "clean" [] (rm "build") (print "Deleted build directory.")) | ||||
|  | ||||
|   (def installed-files @[]) | ||||
|   (def manifests (find-manifest-dir)) | ||||
|   (def manifest (find-manifest (meta :name))) | ||||
|   (setdyn :manifest manifest) | ||||
|   (setdyn :manifest-dir manifests) | ||||
|   (setdyn :installed-files installed-files) | ||||
|  | ||||
|   (rule "./build" [] (os/mkdir "build")) | ||||
|   (phony "build" ["./build"]) | ||||
|  | ||||
|   (phony "manifest" [] | ||||
|          (print "generating " manifest "...") | ||||
|          (os/mkdir manifests) | ||||
|          (spit manifest (string (string/join installed-files "\n") "\n"))) | ||||
|   (phony "install" ["uninstall" "build" "manifest"] | ||||
|          (print "Installed as '" (meta :name) "'.")) | ||||
|  | ||||
|   (phony "install-deps" [] | ||||
|          (if-let [deps (meta :dependencies)] | ||||
|            (each dep deps | ||||
|              (install-git dep)) | ||||
|            (print "no dependencies found"))) | ||||
|  | ||||
|   (phony "uninstall" [] | ||||
|          (uninstall (meta :name))) | ||||
|  | ||||
|   (phony "clean" [] | ||||
|          (rm "build") | ||||
|          (print "Deleted build directory.")) | ||||
|  | ||||
|   (phony "test" ["build"] | ||||
|          (defn dodir | ||||
|            [dir] | ||||
|   | ||||
| @@ -29,8 +29,8 @@ | ||||
| #define JANET_VERSION_MAJOR 1 | ||||
| #define JANET_VERSION_MINOR 0 | ||||
| #define JANET_VERSION_PATCH 0 | ||||
| #define JANET_VERSION_EXTRA "" | ||||
| #define JANET_VERSION "1.0.0" | ||||
| #define JANET_VERSION_EXTRA "-dev" | ||||
| #define JANET_VERSION "1.0.0-dev" | ||||
|  | ||||
| /* #define JANET_BUILD "local" */ | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose