Skip to content

Commit

Permalink
Remove Dynapath, accomodate enrich-classpath
Browse files Browse the repository at this point in the history
Fixes #122
Fixes #120
Fixes #105
Fixes #103
Fixes #50
  • Loading branch information
vemv authored and bbatsov committed Dec 14, 2021
1 parent 32459cc commit 98c7263
Show file tree
Hide file tree
Showing 19 changed files with 299 additions and 439 deletions.
24 changes: 7 additions & 17 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ jobs:
- run:
name: Running tests
command: make test
# Eastwood is run for every item in the CI matrix, because its results are sensitive to the code in the runtime,
# so we make the most out of this linter by exercising all profiles, JDK versions, etc.
- run:
name: Running Eastwood
command: make eastwood

######################################################################
#
Expand All @@ -172,10 +177,9 @@ jobs:
# The ci-test-matrix does the following:
#
# - run tests against the target matrix
# - Java 8 and 11
# - Java 8, 11, 16 and 17
# - Clojure 1.8, 1.9, 1.10, master
# - linter, eastwood and cljfmt
# - runs code coverage report

workflows:
version: 2.1
Expand All @@ -186,17 +190,7 @@ workflows:
parameters:
jdk_version: [openjdk8, openjdk11, openjdk16, openjdk17]
clojure_version: ["1.8", "1.9", "1.10", "master"]
test_profiles: ["+test", "+test,+no-dynapath"]
- util_job:
# This step exercises JDK8 specifically. Eastwood, given its runtime-based approach can detect problems specific to JDK8
# (specifically, it will analyze the `java.legacy-parser` ns):
name: Code Linting, JDK8 (Eastwood only)
jdk_version: openjdk8
steps:
- run:
name: Running Eastwood
command: |
make eastwood
test_profiles: ["+test", "+test,+enrich-classpath"]
- util_job:
name: Code Linting, (latest LTS JDK)
jdk_version: openjdk17
Expand All @@ -209,7 +203,3 @@ workflows:
name: Running clj-kondo
command: |
make kondo
- run:
name: Running Eastwood
command: |
make eastwood
5 changes: 4 additions & 1 deletion .clj-kondo/config.edn
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{:output {:progress true
:exclude-files ["analysis.cljc" "meta.cljc" "inspect_test.clj"]}
:linters {:unused-private-var {:level :warning
:exclude [orchard.query-test/a-private orchard.query-test/docd-fn]}}}
:exclude [orchard.query-test/a-private orchard.query-test/docd-fn]}
;; Enable this opt-in linter:
:unsorted-required-namespaces
{:level :warning}}}
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## master (unreleased)

### Changes

* Remove `dynapath` dependency
* With it, defns related with mutable classloader are now deprecated and are no-ops
* `-Dorchard.use-dynapath=false` has no effect now either.
* Accomodate [`enrich-classpath`](https://github.com/clojure-emacs/enrich-classpath)
* Now, if you intend to use Orchard for its Java functionality, it is expected that you use enrich-classpath also.
* If not present, Java-related features won't work (but at least won't throw a compile-time error).

### Bugs Fixed

* [#135](https://github.com/clojure-emacs/orchard/issues/135): Fix problematic double var lookup in `orchard.xref/fn-refs`.
Expand Down
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: test test-watch docs eastwood cljfmt release deploy clean
.PHONY: test test-watch docs eastwood cljfmt release deploy clean .EXPORT_ALL_VARIABLES

VERSION ?= 1.10

Expand All @@ -7,10 +7,11 @@ TEST_PROFILES ?= +test
resources/clojuredocs/export.edn:
curl -o $@ https://github.com/clojure-emacs/clojuredocs-export-edn/raw/master/exports/export.compact.edn

test:
# .EXPORT_ALL_VARIABLES passes TEST_PROFILES to Lein so that it can inspect the active profiles, which is needed for a complete Eastwood setup:
test: clean .EXPORT_ALL_VARIABLES
lein with-profile -user,-dev,+$(VERSION),$(TEST_PROFILES) test

test-watch: test-resources/clojuredocs/export.edn
test-watch: test-resources/clojuredocs/export.edn clean
lein with-profile +$(VERSION),$(TEST_PROFILES) test-refresh

eastwood:
Expand Down
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ Orchard is meant to run alongside your application and we can't have a
dev tools library interfere with your app right? Dependency collisions are nasty problems which are best solved
by making sure there can't be any shared libraries to cause the conflict.

Currently Orchard has one runtime dependency (`dynapath`), but we hope to eliminate it at some point.

### API Optimized for Editors

Code editors can't know what symbols resolve to without consulting a REPL that's why they would typically
Expand Down Expand Up @@ -86,18 +84,19 @@ Just add `orchard` as a dependency and start hacking.
Consult the [API documentation](https://cljdoc.org/d/cider/orchard/CURRENT) to get a better idea about the
functionality that's provided.

#### Using `enrich-classpath` for best results

There are features that Orchard intends to provide (especially, those related to Java interaction) which need to assume a pre-existing initial classpath that already has various desirable items, such as the JDK sources, third-party sources, special jars such as `tools` (for JDK8), a given project's own Java sources... all that is a domain in itself, which is why our [enrich-classpath](https://github.com/clojure-emacs/enrich-classpath) project does it.

For getting the most out of Orchard, it is therefore recommended/necessary to use `enrich-classpath`. Please refer to its installation/usage instructions.

## Configuration options

So far, Orchard follows these options, which can be specified as Java system properties
(which means that end users can choose to set them globally without fiddling with tooling internals):

* `"-Dorchard.use-dynapath=false"` (default: true)
* if `false`, all features that currently depend on dynapath (and therefore alter the classpath) will be disabled.
* This is a way to avoid a number of known issues: [#103](https://github.com/clojure-emacs/orchard/issues/103), [#105](https://github.com/clojure-emacs/orchard/issues/105), [#112](https://github.com/clojure-emacs/orchard/pull/112).
* Note that if this option is `false`, Orchard clients will have to figure out themselves a way to e.g. fetch Java sources.
* It is foreseen that soon enough this will be reliably offered as a Lein plugin.
* `"-Dorchard.initialize-cache.silent=true"` (default: `true`)
* if `false`, the _class info cache_ initialization may print warnings (possibly spurious ones).xx
* if `false`, the _class info cache_ initialization may print warnings (possibly spurious ones).

## History

Expand Down
2 changes: 1 addition & 1 deletion dev/user.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[clojure.set :as set]
[clojure.string :as string]
[clojure.test :as test]
[clojure.tools.namespace.repl :refer [refresh refresh-all clear refresh-dirs set-refresh-dirs]]))
[clojure.tools.namespace.repl :refer [clear refresh refresh-all refresh-dirs set-refresh-dirs]]))

(def jdk8?
(->> "java.version" System/getProperty (re-find #"^1.8.")))
Expand Down
95 changes: 21 additions & 74 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,72 +1,13 @@
;;;; The following code allows to add the JDK sources without `dynapath` being present.

(require '[clojure.java.io :as io])

(import '[java.util.zip ZipInputStream]
'[java.io FileOutputStream])

(defmacro while-let [[sym expr] & body]
`(loop [~sym ~expr]
(when ~sym
~@body
(recur ~expr))))

(defn jdk-find [f]
(let [home (io/file (System/getProperty "java.home"))
parent (.getParentFile home)
paths [(io/file home f)
(io/file home "lib" f)
(io/file parent f)
(io/file parent "lib" f)]]
(->> paths (filter #(.canRead ^java.io.File %)) first str)))

(def jdk-sources
(let [java-path->zip-path (fn [path]
(some-> (io/resource path)
^java.net.JarURLConnection (. openConnection)
(. getJarFileURL)
io/as-file
str))]
(or (java-path->zip-path "java.base/java/lang/Object.java") ; JDK9+
(java-path->zip-path "java/lang/Object.java") ; JDK8-
(jdk-find "src.zip"))))

(defn uncompress [path target]
(let [zis (-> target io/input-stream ZipInputStream.)]
(while-let [entry (-> zis .getNextEntry)]
(let [size (-> entry .getSize)
bytes (byte-array 1024)
dest (->> entry .getName (io/file path))
dir (-> entry .getName (clojure.string/split #"/") butlast)
_ (->> (clojure.string/join "/" dir) (java.io.File. path) .mkdirs)
output (FileOutputStream. dest)]
(loop [len (-> zis (.read bytes))]
(when (pos? len)
(-> output (.write bytes 0 len))
(recur (-> zis (.read bytes)))))
(-> output .close)))))

(defn unzipped-jdk-source []
(when-not (-> "unzipped-jdk-source" io/file .exists)
(let [choice jdk-sources]
(-> "unzipped-jdk-source" io/file .mkdirs)
;; For some reason simply adding a .zip to the classpath doesn't work, so one has to uncompress the contents:
(uncompress "./unzipped-jdk-source/" choice)))
"unzipped-jdk-source")

(def jdk8? (->> "java.version" System/getProperty (re-find #"^1.8.")))

;;;; Project definition

(defproject cider/orchard "0.7.3"
:description "A fertile ground for Clojure tooling"
:url "https://github.com/clojure-emacs/orchard"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:scm {:name "git" :url "https://github.com/clojure-emacs/orchard"}

:dependencies [[org.tcrawley/dynapath "1.1.0"]
[org.clojure/clojurescript "1.10.520"]]
:dependencies [[org.clojure/clojurescript "1.10.520"]]
:exclusions [org.clojure/clojure] ; see versions matrix below

:aliases {"bump-version" ["change" "version" "leiningen.release/bump-version"]}
Expand All @@ -83,8 +24,7 @@
:password :env/clojars_password
:sign-releases false}]]

:jvm-opts ["-Dorchard.use-dynapath=true"
"-Dclojure.main.report=stderr"]
:jvm-opts ["-Dclojure.main.report=stderr"]

:source-paths ["src" "src-jdk8" "src-newer-jdks"]
:test-paths ~(cond-> ["test"]
Expand All @@ -110,15 +50,15 @@
:resource-paths ["test-resources"
"not-a.jar"
"does-not-exist.jar"]
:java-source-paths ["test-java"]
;; Initialize the cache verbosely, as usual, so that possible issues can be more easily diagnosed:
:jvm-opts ["-Dorchard.initialize-cache.silent=false"
"-Dorchard.internal.test-suite-running=true"]}
"-Dorchard.internal.test-suite-running=true"
"-Dorchard.internal.has-enriched-classpath=false"]}

:no-dynapath {:jvm-opts ["-Dorchard.use-dynapath=false"]
:resource-paths [~(unzipped-jdk-source)]
:plugins ~(if jdk8?
'[[lein-jdk-tools "0.1.1"]]
[])}
:enrich-classpath {:plugins [[mx.cider/enrich-classpath "1.5.0"]]
:middleware [cider.enrich-classpath/middleware]
:jvm-opts ["-Dorchard.internal.has-enriched-classpath=true"]}

;; Development tools
:dev {:dependencies [[org.clojure/tools.namespace "1.1.0"]]
Expand All @@ -132,9 +72,16 @@
letfn [[:block 1] [:inner 2]]}}}

:clj-kondo [:test
{:dependencies [[clj-kondo "2021.10.19"]]}]

:eastwood {:plugins [[jonase/eastwood "0.9.9"]]
:eastwood {:exclude-namespaces [~(if jdk8?
'orchard.java.parser
'orchard.java.legacy-parser)]}}})
{:dependencies [[clj-kondo "2021.12.01"]]}]

:eastwood {:plugins [[jonase/eastwood "1.0.0"]]
:eastwood {:exclude-namespaces ~(cond-> []
jdk8?
(conj 'orchard.java.parser)

(or (not jdk8?)
(not (-> "TEST_PROFILES"
System/getenv
(doto assert)
(.contains "enrich-classpath"))))
(conj 'orchard.java.legacy-parser))}}})
15 changes: 10 additions & 5 deletions src-newer-jdks/orchard/java/parser.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
[clojure.string :as str])
(:import
(java.io StringReader StringWriter)
(javax.lang.model.element Element ElementKind ExecutableElement
TypeElement VariableElement)
(javax.lang.model.element Element ElementKind ExecutableElement TypeElement VariableElement)
(javax.swing.text.html HTML$Tag HTMLEditorKit$ParserCallback)
(javax.swing.text.html.parser ParserDelegator)
(javax.tools ToolProvider)
Expand Down Expand Up @@ -69,9 +68,15 @@
sources (-> (.getStandardFileManager compiler nil nil nil)
(.getJavaFileObjectsFromFiles [tmpfile]))
doclet (class (reify Doclet
(init [this _ _] (reset! result nil))
(run [this root] (reset! result root) true)
(getSupportedOptions [this] #{})))
(init [_this _ _]
(reset! result nil))

(run [_this root]
(reset! result root)
true)

(getSupportedOptions [_this]
#{})))
out (StringWriter.) ; discard compiler messages
opts (apply conj ["--show-members" "private"
"--show-types" "private"
Expand Down
4 changes: 2 additions & 2 deletions src/orchard/apropos.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
{:author "Jeff Valk"}
(:require
[orchard.meta :refer [var-name var-doc] :as m]
[orchard.query :as query]
[orchard.misc :as misc])
[orchard.misc :as misc]
[orchard.query :as query])
(:import
[clojure.lang MultiFn]))

Expand Down
Loading

0 comments on commit 98c7263

Please sign in to comment.