Skip to content

Commit

Permalink
make dynamic loading conditional on 1.12
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Corfield <[email protected]>
  • Loading branch information
seancorfield committed Jan 14, 2024
1 parent 047c965 commit 58f2c19
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 11 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changes

* v0.7.0 in progress
* v0.7.0 -- 2024-01-13
* Address [#55](https://github.com/seancorfield/deps-new/issues/55) by adding support for compound template names that can be resolved to git repositories and template paths within them.

* v0.6.0 64e79d1 -- 2023-12-25
Expand Down
44 changes: 41 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ generate the documentation, e.g.,
<name>com.acme/cool-lib</name>
<description>FIXME: my new org.corfield.new/pom project.</description>
<url>https://github.com/com.acme/cool-lib</url>
<licenses>
<license>
<name>Eclipse Public License</name>
<url>http://www.eclipse.org/legal/epl-v10.html</url>
</license>
</licenses>
...
<scm>
<url>https://github.com/acme/cool-lib</url>
Expand All @@ -207,16 +213,48 @@ if present, uses that template to create a project, in `mynewproject`. Instead o
could use `-Sdeps` to specify the dependencies needed to make the template available:

```bash
clojure -Sdeps '{:deps {com.acme.project/cool-lib COORDINATES}}' -Tnew create :template com.acme.project/cool-lib :name myusername/mynewproject
clojure -Sdeps '{:deps {io.github.acme/templates COORDINATES}}' -Tnew create :template com.acme.project/cool-lib :name myusername/mynewproject
```

The `COORDINATES` could be something like `{:local/root "/path/to/cool-lib"}`
for a template that exists on the local filesystem, or it could be based on `:git/url`/`:git/sha` etc
for a template that exists in a `git` repository.

As of v0.7.0, if you are using Clojure 1.12 -- either as the default `:deps` in
your `deps.edn` file or via an alias, such as `-A:1.12` -- you can use a
shorter syntax for the template dependency:

```bash
clojure -A:1.12 -Tnew create :template io.github.acme/templates%com.acme.project/cool-lib :name myusername/mynewproject
```

`deps-new` will infer a `git` dependency, as `https://github.com/acme/templates`,
figure out the latest version on the default branch, check that out, and add it
to the classpath, and then proceed to use `com.acme.project/cool-lib` as above.
If you want to use a specific tag, you can use `#` to append that to the
template specification, e.g., `io.github.acme/templates%com.acme.project/cool-lib#v1.2.3`.
If the repo is structured such that the Clojure root is not the root of the
repo itself, i.e., you would normally use `:deps/root` in the coordinates, you
can specify that with an extra `%` in the template specification, after the
repo and before the actual template name, e.g., `io.github.acme/templates%lib%com.acme.project/cool-lib#v1.2.3`.
This would be equivalent to `{:deps {io.github.acme/templates {:git/tag "v1.2.3" :deps/root "lib"}}}`
(which would not be legal without `:git/sha` as well for `-Sdeps` but
`deps-new` will resolve the tag to a SHA for you).

If your template name matches the `git` "lib" name, you can omit the template
from the specification, e.g., `io.github.acme/cool-lib` would be treated as
both the implied `git` repo and also the template name, as if you had specified:
`io.github.acme/cool-lib%io.github.acme/cool-lib`.

The examples above using `-A:1.12` assume an alias like this in your `deps.edn` file:

```clojure
:1.12 {:override-deps {org.clojure/clojure {:mvn/version "1.12.0-alpha5"}}}
```

> Note: if you are on Windows, read [**Quoting keys and values**](https://clojure.org/reference/deps_and_cli#quoting) in the official **Deps and CLI Reference** documentation to understand how the above command needs to look on Powershell. Or take a look at the [Babashka CLI](#babashka-cli) library support.
> Note: because `deps-new` is based on `tools.build` and uses its file copying functions, the template must ultimately live on the filesystem, so `:local/root` and `git`-based coordinates are supported, but Maven/Clojars coordinates are not.
> Note: because `deps-new` is based on `tools.build` and uses its file copying functions, the template must ultimately live on the filesystem, so `:local/root` and `git`-based coordinates are supported, **but Maven/Clojars coordinates are not**.
As of v0.6.0, `:src-dirs` can be used to specify a list of
directories to search for templates, in addition to the classpath.
Expand Down Expand Up @@ -305,6 +343,6 @@ $ clj -M:new app --name foo/bar --overwrite delete

# License

Copyright © 2021-2023 Sean Corfield
Copyright © 2021-2024 Sean Corfield

Distributed under the Eclipse Public License version 1.0.
2 changes: 2 additions & 0 deletions src/org/corfield/new.clj
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
for `:delete`, to delete it first; if `:overwrite` is `nil`
or `false`, an existing directory will not be overwritten."
[opts]
;; try to establish a DynamicClassLoader so that we can load
;; templates onto the classpath (if we're running Clojure 1.12):
(try
(let [cl (.getContextClassLoader (Thread/currentThread))]
(.setContextClassLoader (Thread/currentThread) (clojure.lang.DynamicClassLoader. cl)))
Expand Down
29 changes: 22 additions & 7 deletions src/org/corfield/new/impl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
(ns ^:no-doc org.corfield.new.impl
"The implementation helpers for `org.corfield.new/create`."
(:require [clojure.java.io :as io]
[clojure.repl.deps :as deps]
[clojure.string :as str]
[clojure.tools.deps.extensions.git :as git]
[clojure.tools.build.api :as b]
Expand All @@ -16,6 +15,23 @@

(set! *warn-on-reflection* true)

;; Clojure 1.11 compatibility until TDEPS-258 is fixed:
(declare add-lib say-resolving) ; to quiet the linter!
(defmacro patch-add-lib []
(if (resolve 'clojure.core/*repl*)
`(do
(def ~'add-lib (requiring-resolve 'clojure.repl.deps/add-lib))
(defn ~'say-resolving [repo# tag#]
(println "Resolving" repo# "as a git dependency"
(str (when tag# (str "at " tag#))))))
`(do ; define these locally as stubs on Clojure 1.11:
(def ~(with-meta '*repl* {:dynamic true}) false)
(defn ~'add-lib [lib# _coords#]
(println "Dynamically adding" lib# "to the classpath requires Clojure 1.12!"))
(defn ~'say-resolving [repo# tag#]
(println repo# "matches a git dependency but will not be used!")))))
(patch-add-lib)

(defn- ->ns
"Given a string or symbol, presumably representing a
file path, return a string that represents the
Expand Down Expand Up @@ -216,13 +232,12 @@
[git-sha git-dir]
(get-git-sha (symbol repo) tag)
_ (when git-sha
(println "Resolving" repo "as a git dependency"
(str (when tag (str "at " tag))))
(say-resolving repo tag)
(binding [*repl* true]
(deps/add-lib (symbol repo)
(cond-> {:git/sha git-sha}
deps-root
(assoc :deps/root deps-root)))))
(add-lib (symbol repo)
(cond-> {:git/sha git-sha}
deps-root
(assoc :deps/root deps-root)))))
{:keys [main] :as name-data}
(deconstruct-project-name (symbol project-name)) ; allow for string or symbol
target-dir (str (or target-dir main))
Expand Down

0 comments on commit 58f2c19

Please sign in to comment.