Honor whitelist settings when javac called via jar - fixes #2089

This commit refactors a few things from the `jar` and
`javac` tasks in order to ensure that the "whitelisted"
settings from the user profile (`:local-repo`, `:mirrors`,
etc.) are honored when the `jar` task launches `javac`.

It also adds a test to validate the new behavior.
This commit is contained in:
Chris Price 2016-02-15 09:14:23 -08:00
parent 2ca63f0084
commit f981ddd247
6 changed files with 51 additions and 22 deletions

View file

@ -837,6 +837,16 @@
:excluded-profiles exclude-profiles
:profile-inherited-meta include-profiles-meta}))))
(def whitelist-keys
"Project keys which don't affect the production of the jar (sans its name)
should be propagated to the compilation phase and not stripped out."
[:offline? :local-repo :certificates :warn-on-reflection :mirrors :uberjar-name :jar-name])
(defn retain-whitelisted-keys
"Retains the whitelisted keys from the original map in the new one."
[new original]
(merge new (select-keys original whitelist-keys)))
;; # High-level profile operations
(defn set-profiles

View file

@ -3,7 +3,6 @@
(:require [leiningen.pom :as pom]
[leiningen.clean :as clean]
[leiningen.compile :as compile]
[leiningen.core.classpath :as classpath]
[leiningen.core.project :as project]
[leiningen.core.eval :as eval]
[leiningen.core.main :as main]
@ -13,8 +12,6 @@
[clojure.string :as string]
[clojure.java.io :as io])
(:import (java.util.jar Manifest JarEntry JarOutputStream)
(java.util.regex Pattern)
(java.util.jar JarFile)
(java.io BufferedOutputStream FileOutputStream
ByteArrayInputStream)))
@ -220,16 +217,6 @@
jar-name (format jar-name (:version project))]
(str (io/file target jar-name))))
(def whitelist-keys
"Project keys which don't affect the production of the jar (sans its name)
should be propagated to the compilation phase and not stripped out."
[:offline? :local-repo :certificates :warn-on-reflection :mirrors :uberjar-name :jar-name])
(defn- retain-whitelisted-keys
"Retains the whitelisted keys from the original map in the new one."
[new original]
(merge new (select-keys original whitelist-keys)))
(defn- compile-main? [{:keys [main source-paths] :as project}]
(and main (not (:skip-aot (meta main)))
(some #(or (.exists (io/file % (b/path-for main "clj")))
@ -271,7 +258,7 @@
inserted if provided."
[project main f & args]
(-> (apply f project args)
(retain-whitelisted-keys project)
(project/retain-whitelisted-keys project)
(add-main main)))
(defn- preprocess-project [project & [main]]

View file

@ -98,6 +98,14 @@
(abort# "Java compiler not found; Be sure to use java from a JDK\n"
"rather than a JRE by modifying PATH or setting JAVA_CMD."))))
(defn javac-project-for-subprocess
"Merge profiles to create project appropriate for javac subprocess. This
function is mostly extracted to simplify testing, to validate that settings
like `:local-repo` and `:mirrors` are respected."
[project subprocess-profile]
(-> (project/merge-profiles project [subprocess-profile])
(project/retain-whitelisted-keys project)))
;; We can't really control what is printed here. We're just going to
;; allow `.run` to attach in, out, and err to the standard streams. This
;; should have the effect of compile errors being printed. javac doesn't
@ -117,7 +125,7 @@
(try
(binding [eval/*pump-in* false]
(eval/eval-in
(project/merge-profiles project [subprocess-profile])
(javac-project-for-subprocess project subprocess-profile)
form))
(catch Exception e
(if-let [exit-code (:exit-code (ex-data e))]

View file

@ -168,7 +168,7 @@ be deactivated."
(with-open [out (-> standalone-filename
(FileOutputStream.)
(ZipOutputStream.))]
(let [whitelisted (select-keys project jar/whitelist-keys)
(let [whitelisted (select-keys project project/whitelist-keys)
project (-> (project/unmerge-profiles project [:default])
(merge whitelisted))
deps (->> (classpath/resolve-dependencies :dependencies project)

View file

@ -15,12 +15,15 @@
(io/file local-repo
(if (string? n) n (or (namespace n) (name n))) (name n) v))
(defn- read-test-project [name]
(with-redefs [user/profiles (constantly {})]
(defn read-test-project-with-user-profiles [name user-profiles]
(with-redefs [user/profiles (constantly user-profiles)]
(let [project (project/read (format "test_projects/%s/project.clj" name))]
(project/init-project
(project/project-with-profiles-meta
project (merge @project/default-profiles (:profiles project)))))))
project (merge @project/default-profiles (:profiles project)))))))
(defn read-test-project [name]
(read-test-project-with-user-profiles name {}))
(def with-resources-project (read-test-project "with-resources"))

View file

@ -3,10 +3,11 @@
[leiningen.core.main :as main]
[leiningen.core.project :as project]
[leiningen.core.utils :refer [platform-nullsink]]
[leiningen.test.helper :as helper])
[leiningen.test.helper :as helper]
[robert.hooke :as hooke]
[leiningen.javac :as javac])
(:use [clojure.test]
[leiningen.jar])
(:import (java.util.jar JarFile)))
[leiningen.jar]))
(def long-line
(apply str (repeat 10000 "a")))
@ -134,3 +135,23 @@
:bytes ""}]))]
(is (not (.contains out-str
"Warning: The Main-Class specified does not exist"))))))
(deftest javac-launched-with-whitelisted-settings
(let [user-profile {:local-repo "foo/bar"
:mirrors {"central" {:name "central"
:url "http://uk.maven.org/maven2"}}}
orig-project (-> (helper/read-test-project-with-user-profiles
"java-main"
{:user user-profile}))
javac-project (atom {})
javac-project-hook (fn [f proj profile]
(let [new-project (f proj profile)]
(reset! javac-project new-project)
new-project))]
(hooke/with-scope
(hooke/add-hook #'javac/javac-project-for-subprocess javac-project-hook)
(jar orig-project)
(is (= (:local-repo orig-project)
(:local-repo @javac-project)))
(is (= (:mirrors orig-project)
(:mirrors @javac-project))))))