From d528564443044598c6c1828a1787cb6417ca47b5 Mon Sep 17 00:00:00 2001 From: Daniel Cardenas Date: Tue, 20 Aug 2024 16:23:04 -0700 Subject: [PATCH 1/5] Update subproject clean targets with absolute paths --- example/libs/lib-b/project.clj | 4 +++- example/project.clj | 2 +- project.clj | 2 +- src/lein_monolith/config.clj | 16 +++++++++++++++- test/lein_monolith/config_test.clj | 20 ++++++++++++++++++++ 5 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 test/lein_monolith/config_test.clj diff --git a/example/libs/lib-b/project.clj b/example/libs/lib-b/project.clj index b223dc3..17cdbd0 100644 --- a/example/libs/lib-b/project.clj +++ b/example/libs/lib-b/project.clj @@ -4,4 +4,6 @@ :dependencies [[org.clojure/clojure "1.10.1"] - [lein-monolith.example/lib-a "MONOLITH-SNAPSHOT"]]) + [lein-monolith.example/lib-a "MONOLITH-SNAPSHOT"]] + + :clean-targets ^{:protect false} ["target" "resources"]) diff --git a/example/project.clj b/example/project.clj index bfe7864..1d66791 100644 --- a/example/project.clj +++ b/example/project.clj @@ -6,7 +6,7 @@ "version++" ["version+"]} :plugins - [[lein-monolith "1.10.0"] + [[lein-monolith "1.10.1-SNAPSHOT"] [lein-pprint "1.2.0"]] :dependencies diff --git a/project.clj b/project.clj index 582f7b1..cafb3e4 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject lein-monolith "1.10.0" +(defproject lein-monolith "1.10.1-SNAPSHOT" :description "Leiningen plugin for managing subrojects within a monorepo." :url "https://github.com/amperity/lein-monolith" :license {:name "Apache License 2.0" diff --git a/src/lein_monolith/config.clj b/src/lein_monolith/config.clj index 29e07ff..9979afe 100644 --- a/src/lein_monolith/config.clj +++ b/src/lein_monolith/config.clj @@ -121,6 +121,19 @@ :else nil)) +(defn- with-absolute-clean-targets + "Returns the given project map with its clean targets updated to use absolute paths + to work around https://github.com/technomancy/leiningen/issues/2707" + [{:keys [root clean-targets] :as project}] + (let [abs-target-fn (fn [target] + (if (and (string? target) + (not (.isAbsolute (io/file target)))) + (str (io/file root target)) + target)) + abs-clean-targets (with-meta (mapv abs-target-fn clean-targets) (meta clean-targets))] + (assoc project :clean-targets abs-clean-targets))) + + (defn- read-subproject "Reads a leiningen project definition from the given directory and returns the loaded project map, or nil if the directory does not contain a valid @@ -129,7 +142,8 @@ (let [project-file (io/file dir "project.clj")] (when (.exists project-file) (lein/debug "Reading subproject definition from" (str project-file)) - (project/read-raw (str project-file))))) + (-> (project/read-raw (str project-file)) + (with-absolute-clean-targets))))) (defn read-subprojects! diff --git a/test/lein_monolith/config_test.clj b/test/lein_monolith/config_test.clj new file mode 100644 index 0000000..c1b7c00 --- /dev/null +++ b/test/lein_monolith/config_test.clj @@ -0,0 +1,20 @@ +(ns lein-monolith.config-test + (:require + [clojure.java.io :as io] + [clojure.test :refer [deftest is testing]] + [lein-monolith.config :as config] + [lein-monolith.test-utils :refer [read-example-project]])) + + +(deftest read-subprojects + (testing "subproject clean targets use absolute paths" + (let [monolith (read-example-project) + subprojects (config/read-subprojects! monolith) + test-project (get subprojects 'lein-monolith.example/lib-b) + clean-targets (:clean-targets test-project)] + (is (map? test-project) + "lib-b subproject was loaded") + (is (= {:protect false} (meta clean-targets)) + "metadata is preserved") + (is (= (set clean-targets) (set (filter #(.isAbsolute (io/file %)) clean-targets))) + "All clean target paths are absolute")))) From bbbd978e588cb35d27a30bd88fb38faa31f797b2 Mon Sep 17 00:00:00 2001 From: Daniel Cardenas Date: Tue, 20 Aug 2024 16:33:12 -0700 Subject: [PATCH 2/5] Have CI tests install the snapshot version of lein monolith --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e944b2..87902ca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,6 +50,7 @@ jobs: - v1-test- - run: lein deps - run: lein check + - run: lein install - run: lein with-profile +ci test2junit - run: rm -r ~/.m2/repository/lein-monolith - store_test_results: From 30eae3399f2ddc3e7cd22c5da3fc71bc89e634a8 Mon Sep 17 00:00:00 2001 From: Daniel Cardenas Date: Tue, 20 Aug 2024 16:46:40 -0700 Subject: [PATCH 3/5] oops also update the changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index beabfac..ccf8be9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] -... +### Changed +- Subproject `:clean-targets` will automatically be updated with absolute paths to support running + the `clean` task as part of `lein monolith each`. + [#99](https://github.com/amperity/lein-monolith/pull/99) ## [1.10.0] - 2024-06-03 From 37b26fd5253931d667be841d658560225f2ba2c8 Mon Sep 17 00:00:00 2001 From: Daniel Cardenas Date: Mon, 26 Aug 2024 13:54:09 -0700 Subject: [PATCH 4/5] Add unit test to verify that subproject clean targets are actually cleaned up --- test/lein_monolith/task/each_test.clj | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 test/lein_monolith/task/each_test.clj diff --git a/test/lein_monolith/task/each_test.clj b/test/lein_monolith/task/each_test.clj new file mode 100644 index 0000000..c23b5f3 --- /dev/null +++ b/test/lein_monolith/task/each_test.clj @@ -0,0 +1,38 @@ +(ns lein-monolith.task.each-test + (:require + [clojure.java.io :as io] + [clojure.string :as str] + [clojure.test :refer [deftest is testing]] + [lein-monolith.config :as config] + [lein-monolith.task.each :as each] + [lein-monolith.test-utils :refer [read-example-project]])) + + +(defn- test-path + "Returns the path where the test file should exist for the given target path." + [subproject target] + (if (= :target-path target) + (str (:root subproject) "/target/test.txt") + (str target "/test.txt"))) + + +(deftest clean-subprojects + (testing "Verify that the clean targets for each subproject are cleaned up by `lein monolith each clean`." + (let [monolith (read-example-project) + subprojects (config/read-subprojects! monolith)] + (doseq [[_subproject-name subproject] subprojects] + (doseq [target (:clean-targets subproject)] + (let [path (test-path subproject target)] + (is (str/starts-with? path (:root subproject)) + "The test file path should be created within the subproject directory.") + (io/make-parents path) + (spit path "test") + (is (.exists (io/file path)) "The test file should have been created.")))) + (each/run-tasks monolith {} ["clean"]) ; lein monolith each clean + (doseq [[_subproject-name subproject] subprojects] + (doseq [target (:clean-targets subproject)] + (let [path (test-path subproject target) + test-file (io/file path) + parent-dir (io/file (.getParent test-file))] + (is (not (.exists test-file)) "The test file should not exist after a lein clean") + (is (not (.exists parent-dir)) "The target directory should not exist after a lein clean"))))))) From 3c2ed2d3c14afbfe8b46bf9bfadf3aee85457552 Mon Sep 17 00:00:00 2001 From: Daniel Cardenas Date: Tue, 15 Oct 2024 13:08:34 -0500 Subject: [PATCH 5/5] PR feedback --- test/lein_monolith/task/each_test.clj | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/lein_monolith/task/each_test.clj b/test/lein_monolith/task/each_test.clj index c23b5f3..b206fac 100644 --- a/test/lein_monolith/task/each_test.clj +++ b/test/lein_monolith/task/each_test.clj @@ -20,19 +20,19 @@ (testing "Verify that the clean targets for each subproject are cleaned up by `lein monolith each clean`." (let [monolith (read-example-project) subprojects (config/read-subprojects! monolith)] - (doseq [[_subproject-name subproject] subprojects] - (doseq [target (:clean-targets subproject)] - (let [path (test-path subproject target)] - (is (str/starts-with? path (:root subproject)) - "The test file path should be created within the subproject directory.") - (io/make-parents path) - (spit path "test") - (is (.exists (io/file path)) "The test file should have been created.")))) + (doseq [[_subproject-name subproject] subprojects + target (:clean-targets subproject)] + (let [path (test-path subproject target)] + (is (str/starts-with? path (:root subproject)) + "The test file path should be created within the subproject directory.") + (io/make-parents path) + (spit path "test") + (is (.exists (io/file path)) "The test file should have been created."))) (each/run-tasks monolith {} ["clean"]) ; lein monolith each clean - (doseq [[_subproject-name subproject] subprojects] - (doseq [target (:clean-targets subproject)] - (let [path (test-path subproject target) - test-file (io/file path) - parent-dir (io/file (.getParent test-file))] - (is (not (.exists test-file)) "The test file should not exist after a lein clean") - (is (not (.exists parent-dir)) "The target directory should not exist after a lein clean"))))))) + (doseq [[_subproject-name subproject] subprojects + target (:clean-targets subproject)] + (let [path (test-path subproject target) + test-file (io/file path) + parent-dir (io/file (.getParent test-file))] + (is (not (.exists test-file)) "The test file should not exist after a lein clean") + (is (not (.exists parent-dir)) "The target directory should not exist after a lein clean"))))))