Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transitive dependency support #11

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ You can pass subproject directory locations via command line (overrides `:sub`):
$ lein sub -s "module/foo-common:module/dep-vendor-xyz" jar
```

You can force dependency discovery between sub-projects (overrides build order specified in the `:sub` vector):

```bash
$ lein sub clean -d
```


## Getting in touch

Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject lein-sub "0.3.0"
(defproject lein-sub "0.3.1"
:description "Leiningen Subprojects plugin"
:url "https://github.com/kumarshantanu/lein-sub"
:license {:name "Eclipse Public License"
Expand Down
58 changes: 50 additions & 8 deletions src/leiningen/sub.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,52 @@
[leiningen.core.main :as main]
[leiningen.core.project :as project]))

(defn proj-version [proj]
[(symbol (:group proj) (:name proj)) (:version proj)])

(defn apply-task-to-subproject
[sub-proj-dir task-name args]
(println "Reading project from" sub-proj-dir)
(let [sub-project (project/init-project
(project/read (str sub-proj-dir "/project.clj")))
new-task-name (main/lookup-alias task-name sub-project)]
[sub-project task-name args]
(println "Building project " (proj-version sub-project))
(let [new-task-name (main/lookup-alias task-name sub-project)]
(main/apply-task new-task-name sub-project args)))

(defn apply-task-to-subproject-dir
[sub-project-dir task-name args]
(let [ sub-project (project/init-project (project/read (str sub-project-dir "/project.clj")))]
(apply-task-to-subproject sub-project task-name args)))

(defn read-all-subprojects
[sub-proj-dirs]
(map #(project/init-project (project/read (str % "/project.clj"))) sub-proj-dirs))

(defn perform-in-order [enriched-projects task-name args]
"Applies tasks to all projects in a recursion, unless finished or a cycle was encountered"
(let [ build-this-round (filter #(empty? (:internal-deps %)) enriched-projects)
built-this-round (into #{} (map #(proj-version %) build-this-round))
build-next-round (filter #(not (empty? (:internal-deps %))) enriched-projects)
build-next-round (map #(assoc %
:internal-deps
(filter
(fn [dep](not (contains? built-this-round dep)))
(:internal-deps %))) build-next-round)]
(if (and (empty? build-this-round) (not (empty? build-next-round)))
(main/abort (str "Cycle dependecy, cannot resolve proper build order for projects: "
(into #{} (map #(proj-version %) build-next-round))))
(if (not (empty? build-this-round))
(do
(doseq [each build-this-round]
(apply-task-to-subproject each task-name args))
(perform-in-order build-next-round task-name args))))))


(defn enriched-projects [subprojects]
"Adds :internal-deps vector with all dependencies that are within this build-tree"
(let [all-subprojects (into #{} (map #(proj-version %) subprojects))
enriched-projects
(map (fn [project](assoc project
:internal-deps
(into [] (filterv #(contains? all-subprojects %) (:dependencies project))))) subprojects)]
enriched-projects))

(defn resolve-subprojects
"Parse `args` and return [sub-projects task-name args]"
Expand Down Expand Up @@ -42,10 +79,15 @@ or specify subproject dirs via command line:

Note: Each sub-project directory should have its own project.clj file")))


(defn sub
"Run task for all subprojects"
[project task-name & args]
(let [[subprojects task-name args] (resolve-subprojects project task-name args)]
(doseq [each subprojects]
(apply-task-to-subproject each task-name args))))
(cond
;; -d would trigger "discovery mode" build order
(= "-d" (first args))
(perform-in-order (enriched-projects (read-all-subprojects subprojects)) task-name (rest args))
;; the normal way will follow artifacts order in the build script
:else
(doseq [each subprojects]
(apply-task-to-subproject-dir each task-name args)))))
7 changes: 5 additions & 2 deletions subtest/child/project.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
(defproject child "0.1.0-SNAPSHOT"
(def version (clojure.string/trim (:out (clojure.java.shell/sh "git" "describe" "--always"))))

(defproject subtest/child version
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]])
:dependencies [[org.clojure/clojure "1.4.0"]
[subtest/common-child ~version]])
7 changes: 5 additions & 2 deletions subtest/child2/project.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
(defproject child2 "0.1.0-SNAPSHOT"
(def version (clojure.string/trim (:out (clojure.java.shell/sh "git" "describe" "--always"))))

(defproject subtest/child2 version
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]])
:dependencies [[org.clojure/clojure "1.4.0"]
[subtest/common-child ~version]])
10 changes: 10 additions & 0 deletions subtest/child3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/target
/lib
/classes
/checkouts
pom.xml
*.jar
*.class
.lein-deps-sum
.lein-failures
.lein-plugins
13 changes: 13 additions & 0 deletions subtest/child3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# child2

A Clojure library designed to ... well, that part is up to you.

## Usage

FIXME

## License

Copyright © 2012 FIXME

Distributed under the Eclipse Public License, the same as Clojure.
9 changes: 9 additions & 0 deletions subtest/child3/project.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(def version (clojure.string/trim (:out (clojure.java.shell/sh "git" "describe" "--always"))))

(defproject subtest/child3 version
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]
[subtest/child2 ~version]])
6 changes: 6 additions & 0 deletions subtest/child3/src/child2/core.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(ns child2.core)

(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!"))
7 changes: 7 additions & 0 deletions subtest/child3/test/child2/core_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(ns child2.core-test
(:use clojure.test
child2.core))

(deftest a-test
(testing "FIXME, I fail."
(is (= 0 1))))
10 changes: 10 additions & 0 deletions subtest/common-child/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/target
/lib
/classes
/checkouts
pom.xml
*.jar
*.class
.lein-deps-sum
.lein-failures
.lein-plugins
13 changes: 13 additions & 0 deletions subtest/common-child/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# child2

A Clojure library designed to ... well, that part is up to you.

## Usage

FIXME

## License

Copyright © 2012 FIXME

Distributed under the Eclipse Public License, the same as Clojure.
8 changes: 8 additions & 0 deletions subtest/common-child/project.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(def version (clojure.string/trim (:out (clojure.java.shell/sh "git" "describe" "--always"))))

(defproject subtest/common-child version
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]])
6 changes: 6 additions & 0 deletions subtest/common-child/src/child2/core.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(ns child2.core)

(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!"))
7 changes: 7 additions & 0 deletions subtest/common-child/test/child2/core_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(ns child2.core-test
(:use clojure.test
child2.core))

(deftest a-test
(testing "FIXME, I fail."
(is (= 0 1))))
4 changes: 2 additions & 2 deletions subtest/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]]
:plugins [[lein-sub "0.3.0"]]
:sub ["child" "child2"])
:plugins [[lein-sub "0.3.1"]]
:sub ["common-child" "child" "child2" "child3"])