diff --git a/leiningen-core/src/leiningen/core/project.clj b/leiningen-core/src/leiningen/core/project.clj index 44772d98..49063e84 100644 --- a/leiningen-core/src/leiningen/core/project.clj +++ b/leiningen-core/src/leiningen/core/project.clj @@ -466,11 +466,38 @@ (.toString (BigInteger. 1 (-> (java.security.MessageDigest/getInstance "SHA1") (.digest (.getBytes content)))) 16)) +(defn- keyword-composite-profile? [profile] + (and (composite-profile? profile) (every? keyword? profile))) + +(defn- ordered-keyword-composite-profiles [project] + (->> project meta :profiles + (filter (comp keyword-composite-profile? val)) + (remove (comp empty? val)) + (sort-by count) + (reverse))) + +(defn- first-matching-composite [profiles composites] + (->> composites + (filter (fn [[_ v]] (= v (take (count v) profiles)))) + (first))) + +(defn- normalize-profile-names [project profiles] + (let [composites (ordered-keyword-composite-profiles project)] + (loop [profiles' profiles + normalized ()] + (if (seq profiles') + (if-let [[k v] (first-matching-composite profiles' composites)] + (recur (drop (count v) profiles') (cons k normalized)) + (recur (rest profiles') (cons (first profiles') normalized))) + (if (= (count profiles) (count normalized)) + profiles + (normalize-profile-names project (reverse normalized))))))) + (defn profile-scope-target-path [project profiles] (let [n #(if (map? %) (subs (sha1 (pr-str %)) 0 8) (name %))] (if (:target-path project) (update-in project [:target-path] format - (str/join "+" (map n (remove #{:default :provided} profiles)))) + (str/join "+" (map n (normalize-profile-names project profiles)))) project))) (defn target-path-subdirs [{:keys [target-path] :as project} key] diff --git a/leiningen-core/test/leiningen/core/test/project.clj b/leiningen-core/test/leiningen/core/test/project.clj index 3c49a78f..27d21319 100755 --- a/leiningen-core/test/leiningen/core/test/project.clj +++ b/leiningen-core/test/leiningen/core/test/project.clj @@ -590,3 +590,26 @@ [["central" {:url "https://repo1.maven.org/maven2/" :snapshots false}] ["clojars" {:url "https://clojars.org/repo/"}]]}}))))))) + +(deftest test-profile-scope-target-path + (let [project (with-meta + {:target-path "target/%s"} + {:profiles {:ab [:a :b] + :abc [:ab :c] + :bcd [:b :c :d] + :a {} + :b {} + :c {} + :d {} + :e {}}})] + (are [ps tp] (= (profile-scope-target-path project ps) {:target-path tp}) + [:a :b] "target/ab" + [:a :b :c] "target/abc" + [:b :c] "target/b+c" + [:b :a] "target/b+a" + [:c :b :a] "target/c+b+a" + [:c :a :b] "target/c+ab" + [:a :b :c :d] "target/abc+d" + [:e :b :c :d] "target/e+bcd" + [:c :a :b :d] "target/c+ab+d" + [:a] "target/a")))