├── dev-resources └── t_parent │ └── samples │ ├── parents │ ├── with_foo_property │ │ ├── .gitignore │ │ └── project.clj │ ├── with_profiles │ │ └── project.clj │ ├── with_managed_deps │ │ └── project.clj │ └── with_profile_plugin │ │ └── project.clj │ └── children │ ├── with_no_parent_coords_or_path │ └── project.clj │ ├── with_parent_path │ └── project.clj │ ├── with_parent_coords │ └── project.clj │ ├── with_invalid_parent_coords │ └── project.clj │ ├── with_invalid_parent_path │ └── project.clj │ ├── with_parent_with_profile │ └── project.clj │ ├── with_parent_with_managed_deps │ └── project.clj │ └── with_parent_profile_plugin │ └── project.clj ├── .gitignore ├── src ├── lein_parent │ └── plugin.clj └── leiningen │ └── parent.clj ├── project.clj ├── README.md ├── test └── leiningen │ └── t_parent.clj └── LICENSE /dev-resources/t_parent/samples/parents/with_foo_property/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | pom.xml -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | *.swp 11 | -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/parents/with_foo_property/project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-parent/parent-with-foo-property "0.0.1" 2 | :description "Parent project that provides a property 'foo'" 3 | :foo "foo") -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/parents/with_profiles/project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-parent/parent-with-profile "0.0.1" 2 | :description "Parent project that provides a profile to be inherited" 3 | :profiles {:foo {:bar "bar"}}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_no_parent_coords_or_path/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-no-parent-coords-or-path "0.0.1" 2 | :description "Child project that doesn't specifies path or coords for parent" 3 | :parent-project {:inherit [:foo]}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_parent_path/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-parent-path "0.0.1" 2 | :description "Child project that references parent project via path" 3 | :parent-project {:path "../../parents/with_foo_property/project.clj" 4 | :inherit [:foo]}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/parents/with_managed_deps/project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-parent/parent-with-managed-deps "0.0.1" 2 | :description "Parent project that provides managed dependencies" 3 | :managed-dependencies [[clj-time "0.5.1"] 4 | [ring/ring-codec "1.0.1"]]) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_parent_coords/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-parent-path "0.0.1" 2 | :description "Child project that references parent project via coords" 3 | :parent-project {:coords [lein-parent/parent-with-foo-property "0.0.1"] 4 | :inherit [:foo]}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_invalid_parent_coords/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-invalid-parent-coords "0.0.1" 2 | :description "Child project that specifies invalid coords for a parent project" 3 | :parent-project {:coords [lein-parent/does-not-exist "0.0.1"] 4 | :inherit [:foo]}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_invalid_parent_path/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-invalid-parent-path "0.0.1" 2 | :description "Child project that specifies an invalid path for a parent project" 3 | :parent-project {:path "../../parents/does_not_exist/project.clj" 4 | :inherit [:foo]}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_parent_with_profile/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-parent-with-profiles "0.0.1" 2 | :description "Child project that references parent project with a profile" 3 | :parent-project {:path "../../parents/with_profiles/project.clj" 4 | :inherit [[:profiles :foo]]}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_parent_with_managed_deps/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-parent-with-managed-deps "0.0.1" 2 | :description "Child project that references parent project with managed dependencies" 3 | :parent-project {:path "../../parents/with_managed_deps/project.clj" 4 | :inherit [:managed-dependencies]}) -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/parents/with_profile_plugin/project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-parent/parent-with-profile-plugin "0.0.1" 2 | :description "Parent project that provides profile plugins" 3 | :dependencies [[org.clojure/clojure "1.9.0"]] 4 | :exclusions [org.clojure/clojure 5 | org.clojure/clojurescript] 6 | :profiles {:dev {:plugins [[venantius/ultra "0.5.2"]]}}) 7 | -------------------------------------------------------------------------------- /dev-resources/t_parent/samples/children/with_parent_profile_plugin/project.clj: -------------------------------------------------------------------------------- 1 | (defproject child-with-parent-profile-plugin "0.0.1" 2 | :description "Child project that references parent project with profile plugins" 3 | :dependencies [[medley "1.0.0"]] 4 | :parent-project {:coords [lein-parent/parent-with-profile-plugin "0.0.1"] 5 | :inherit [:dependencies [:profiles :dev]]}) 6 | -------------------------------------------------------------------------------- /src/lein_parent/plugin.clj: -------------------------------------------------------------------------------- 1 | (ns lein-parent.plugin 2 | (:require [leiningen.parent :as parent] 3 | [leiningen.core.project :as project])) 4 | 5 | (def meta-merge #'project/meta-merge) 6 | 7 | (defn middleware [project] 8 | (if-let [inherited (parent/inherited-properties project)] 9 | (with-meta (meta-merge project inherited) 10 | (update (meta project) :profiles merge (:profiles inherited))) 11 | project)) 12 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-parent "0.3.10-SNAPSHOT" 2 | :description "Leiningen plugin for inheriting properties from a parent project" 3 | :url "https://github.com/achin/lein-parent" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :eval-in-leiningen true 7 | :plugins [[lein-midje "3.2.1"]] 8 | :profiles {:dev {:dependencies [[midje "1.9.8"] 9 | [com.cemerick/pomegranate "1.1.0"]]}}) 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lein-parent 2 | 3 | A Leiningen plugin for inheriting properties from a parent project. 4 | 5 | This plugin is useful when you have a series of related projects that all share 6 | some set of properties and want to avoid duplicating the values across 7 | projects. e.g. you have several projects that all share the same Maven private 8 | repository information. 9 | 10 | lein-parent is the conceptual reverse of 11 | [lein-sub](https://github.com/kumarshantanu/lein-sub). 12 | 13 | ## Usage 14 | 15 | Put `[lein-parent "0.3.9"]` into the `:plugins` vector of your project.clj. 16 | 17 | Specify a parent in your project.clj and which properties to inherit from it as 18 | follows. 19 | 20 | ```clj 21 | :parent-project {:path "../project.clj" 22 | :inherit [:dependencies :repositories [:profiles :dev]] 23 | :only-deps [org.clojure/clojure com.stuartsierra/component]} 24 | ``` 25 | 26 | As of lein-parent 0.3.0 and leiningen 2.7.0, you can also reference a parent 27 | project by its lein/maven coords, like this: 28 | 29 | ```clj 30 | :parent-project {:coords [org.foo/clojure-parent-project "1.0.0"] 31 | :inherit [:managed-dependencies]} 32 | ``` 33 | 34 | Inherited properties may be either keywords or sequences of 35 | keywords. These values are used to select which properties from your 36 | parent to merge into your project. To select only specific 37 | dependencies, specify the first part of the dependency atoms in a 38 | sequence with :only-deps. To see the actual values of these 39 | properties, run: 40 | 41 | $ lein parent 42 | 43 | ## Managed Dependencies 44 | 45 | Leiningen 2.7.0 introduced support for a `:managed-dependencies` property in 46 | your leiningen project file. Using this property, you can define version numbers 47 | in the `:managed-dependencies` section without causing the dependencies to be 48 | realized / enforced. Then, you can omit the version number from the `:dependencies` 49 | section and just specify the dependency group id / artifact id. This will cause 50 | the dependency to be realized, and the version will be inherited from the 51 | `:managed-dependencies` section. 52 | 53 | When combined with `lein-parent`, this allows you to `:inherit` the 54 | `:managed-dependencies` section from a parent project and share the version 55 | numbers for common dependencies across many child projects. This can be very 56 | powerful in reducing the burden of dealing with transitive dependency version 57 | conflicts across multiple projects. 58 | 59 | For example: 60 | 61 | ```clj 62 | (defproject superfun/myparent "1.0.0" 63 | :managed-dependencies [[clj-time "0.12.0"] 64 | [me.raynes/fs "1.4.6"] 65 | [ring/ring-codec "1.0.1"]]) 66 | 67 | (defproject superfun/kid-a "1.0.0-SNAPSHOT" 68 | :parent-project {:coords [superfun/myparent "1.0.0"] 69 | :inherit [:managed-dependencies]} 70 | :dependencies [[clj-time] 71 | [me.raynes/fs]]) 72 | 73 | (defproject superfun/kid-b "1.0.0-SNAPSHOT" 74 | :parent-project {:coords [superfun/myparent "1.0.0"] 75 | :inherit [:managed-dependencies]} 76 | :dependencies [[clj-time] 77 | [ring/ring-codec]]) 78 | ``` 79 | 80 | For more information, see [leiningen's docs on Managed Dependencies](https://github.com/technomancy/leiningen/blob/master/doc/MANAGED_DEPS.md) 81 | 82 | ## License 83 | 84 | Copyright © 2014 Alex Chin 85 | 86 | Distributed under the Eclipse Public License either version 1.0 or (at 87 | your option) any later version. 88 | -------------------------------------------------------------------------------- /test/leiningen/t_parent.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.t-parent 2 | (:use [midje.sweet]) 3 | (:require [leiningen.parent :as p] 4 | [lein-parent.plugin :as plugin] 5 | [clojure.test :refer :all] 6 | [leiningen.core.project :as project] 7 | [leiningen.install :as install]) 8 | (:import (java.io FileNotFoundException))) 9 | 10 | (def m {:a 1 11 | :b 2 12 | :c 3 13 | :d {4 :red 14 | 5 :green 15 | 6 :blue} 16 | :e {7 {:white :apple 17 | :black :orange}}}) 18 | 19 | (fact "about select-keys-in" 20 | (p/select-keys-in m [:a]) => (just {:a 1}) 21 | (p/select-keys-in m [:a :b :c]) => (just {:a 1 22 | :b 2 23 | :c 3}) 24 | (p/select-keys-in m [:d]) => (just {:d {4 :red 25 | 5 :green 26 | 6 :blue}}) 27 | (p/select-keys-in m [[:d 4]]) => (just {:d {4 :red}}) 28 | (p/select-keys-in m [[:d 4] [:e]]) => (just {:d {4 :red} 29 | :e {7 {:white :apple 30 | :black :orange}}}) 31 | (p/select-keys-in m [:a [:d 4]]) => (just {:a 1 32 | :d {4 :red}})) 33 | 34 | 35 | (defn test-proj-path 36 | [kind proj-name] 37 | (str "./dev-resources/t_parent/samples/" kind "/" proj-name "/project.clj")) 38 | 39 | (defn child-path 40 | [proj-name] 41 | (test-proj-path "children" proj-name)) 42 | 43 | (defn parent-path 44 | [proj-name] 45 | (test-proj-path "parents" proj-name)) 46 | 47 | (defn read-child-project 48 | [proj-name] 49 | (-> proj-name 50 | child-path 51 | project/read 52 | plugin/middleware)) 53 | 54 | (deftest parent-project-specification-test 55 | (testing "parent projects can be loaded by path" 56 | (let [project (read-child-project "with_parent_path")] 57 | (is (= "foo" (:foo project))))) 58 | (testing "Error thrown if non-existent path provided" 59 | (try 60 | (read-child-project "with_invalid_parent_path") 61 | ;; should not get here! 62 | (is (true? false) "Exception should have been thrown by call to 'read-project'!") 63 | (catch Exception e 64 | (is (instance? FileNotFoundException (.getCause e)))))) 65 | (testing "parent projects can be loaded by coordinates" 66 | (install/install (project/read (parent-path "with_foo_property"))) 67 | (let [project (read-child-project "with_parent_coords")] 68 | (is (= "foo" (:foo project))))) 69 | (testing "Error thrown if non-existent coords provided" 70 | (is (thrown-with-msg? Exception #"Could not find artifact lein-parent:does-not-exist" 71 | (read-child-project "with_invalid_parent_coords")))) 72 | (testing "parent projects can be loaded by coordinates and contain dev plugins" 73 | (install/install (project/read (parent-path "with_profile_plugin"))) 74 | (let [project (read-child-project "with_parent_profile_plugin")] 75 | (is (= [['venantius/ultra "0.5.2"]] (get-in project [:profiles :dev :plugins])))))) 76 | 77 | (deftest inherited-values-test 78 | (testing "managed_dependencies can be inherited from parent" 79 | (let [project (read-child-project "with_parent_with_managed_deps")] 80 | (is (= [['clj-time "0.5.1"] ['ring/ring-codec "1.0.1"]] 81 | (:managed-dependencies project))))) 82 | 83 | (testing "profiles can be inherited from parent" 84 | (testing "when the profile is activated" 85 | ;; with-profiles calls the set-profiles function to 'activate' selected profiles 86 | (let [project (project/set-profiles (read-child-project "with_parent_with_profile") [:foo])] 87 | (is (= "bar" (:bar project))))) 88 | (testing "when the profile is not activated, the profile is still available in the project" 89 | ;; with-profiles calls the set-profiles function to 'activate' selected profiles 90 | (let [project (read-child-project "with_parent_with_profile")] 91 | (is (nil? (:bar project))) 92 | (is (= "bar" (get-in project [:profiles :foo :bar]))))))) 93 | -------------------------------------------------------------------------------- /src/leiningen/parent.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.parent 2 | (:require [clojure.pprint :as pp] 3 | [leiningen.core.project :as project] 4 | [leiningen.core.main :as main] 5 | [leiningen.core.classpath :as classpath] 6 | [cemerick.pomegranate.aether :as aether]) 7 | (:import (java.util.zip ZipFile) 8 | (java.io InputStreamReader))) 9 | 10 | (defn ensure-sequence 11 | [x] 12 | (if (sequential? x) x (vector x))) 13 | 14 | (defn select-keys-in 15 | "Returns a map containing only those entries or sub-entries in m whose key 16 | path is in ksseq. Similar to select-keys except each value in ksseq is either 17 | a single key or sequence of keys." 18 | [m ksseq] 19 | (->> ksseq 20 | (map ensure-sequence) 21 | (map (juxt identity (partial get-in m))) 22 | (reduce (partial apply assoc-in) {}))) 23 | 24 | (defn filter-deps 25 | "props is a map of project properties, deps is a sequence of desired 26 | dependency names. Returns props with only the depednencies from deps 27 | included." 28 | [props deps] 29 | (if (and deps (:dependencies props)) 30 | (let [deps (-> deps ensure-sequence set) 31 | filter-fn (fn [d] (contains? deps (first d)))] 32 | (update-in props [:dependencies] (partial filter filter-fn))) 33 | props)) 34 | 35 | (defn is-absolute? 36 | [path] 37 | (.isAbsolute (java.io.File. path))) 38 | 39 | (defn make-absolute 40 | [root path] 41 | (.getAbsolutePath (java.io.File. root path))) 42 | 43 | (defn resolve-path 44 | [root path] 45 | (if (is-absolute? path) 46 | path 47 | (make-absolute root path))) 48 | 49 | ; Copied from leiningen.core.classpath 50 | (defn update-policies [update checksum [repo-name opts]] 51 | [repo-name (merge {:update (or update :daily) 52 | :checksum (or checksum :fail)} opts)]) 53 | 54 | (defn- read-project 55 | [file] 56 | ;; Leiningen 2.5 introduced read-raw and changed read to call init-project 57 | ;; automatically. By detecting the existance of read-raw we can avoid a 58 | ;; redundant call to init-project. 59 | (if (resolve 'leiningen.core.project/read-raw) 60 | (project/read file) 61 | (project/init-project (project/read file)))) 62 | 63 | (defn resolve-project-from-coords 64 | [coords {:keys [repositories offline? update checksum local-repo]}] 65 | (let [resolved-parent-artifact (first (aether/resolve-artifacts 66 | :coordinates [coords] 67 | :repositories (map (comp (partial update-policies update checksum) classpath/add-repo-auth) 68 | repositories) 69 | :offline? offline? 70 | :local-repo local-repo)) 71 | artifact-jar (:file (meta resolved-parent-artifact)) 72 | artifact-zip (ZipFile. artifact-jar) 73 | project-clj-path (format "META-INF/leiningen/%s/project.clj" (first coords))] 74 | (read-project (InputStreamReader. (.getInputStream 75 | artifact-zip 76 | (.getEntry artifact-zip project-clj-path)))))) 77 | 78 | (defn get-parent-project 79 | [project {:keys [path coords]}] 80 | (cond 81 | coords 82 | (resolve-project-from-coords 83 | coords 84 | project) 85 | 86 | path 87 | (let [path (resolve-path (:root project) path)] 88 | (read-project path)) 89 | 90 | :else 91 | (main/warn "WARNING: :parent-project does not specify :coords or :path, so no parent project will be loaded."))) 92 | 93 | (defn parent-properties 94 | [proj ks] 95 | (select-keys-in proj ks)) 96 | 97 | (defn inherited-properties 98 | [project] 99 | (when-let [parent-project (:parent-project project)] 100 | (let [{:keys [inherit only-deps]} parent-project] 101 | (-> (get-parent-project project parent-project) 102 | (parent-properties inherit) 103 | (filter-deps only-deps))))) 104 | 105 | (defn parent 106 | "Show project properties inherited from parent project 107 | 108 | Your project may have a parent project. Specify a parent in your project.clj as 109 | follows. 110 | 111 | :parent-project {:path \"../project.clj\" 112 | :inherit [:dependencies :repositories [:profiles :dev]] 113 | :only-deps [org.clojure/tools-logging com.example/whatever}" 114 | [project & args] 115 | (if-let [inherited (inherited-properties project)] 116 | (do (printf "Inheriting properties %s from %s\n\n" 117 | (get-in project [:parent-project :inherit]) 118 | (get-in project [:parent-project :coords] 119 | (get-in project [:parent-project :path]))) 120 | (pp/pprint inherited)) 121 | (println "No parent project specified"))) 122 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 4 | 5 | 1. DEFINITIONS 6 | 7 | "Contribution" means: 8 | 9 | a) in the case of the initial Contributor, the initial code and 10 | documentation distributed under this Agreement, and 11 | 12 | b) in the case of each subsequent Contributor: 13 | 14 | i) changes to the Program, and 15 | 16 | ii) additions to the Program; 17 | 18 | where such changes and/or additions to the Program originate from and are 19 | distributed by that particular Contributor. A Contribution 'originates' from 20 | a Contributor if it was added to the Program by such Contributor itself or 21 | anyone acting on such Contributor's behalf. Contributions do not include 22 | additions to the Program which: (i) are separate modules of software 23 | distributed in conjunction with the Program under their own license 24 | agreement, and (ii) are not derivative works of the Program. 25 | 26 | "Contributor" means any person or entity that distributes the Program. 27 | 28 | "Licensed Patents" mean patent claims licensable by a Contributor which are 29 | necessarily infringed by the use or sale of its Contribution alone or when 30 | combined with the Program. 31 | 32 | "Program" means the Contributions distributed in accordance with this 33 | Agreement. 34 | 35 | "Recipient" means anyone who receives the Program under this Agreement, 36 | including all Contributors. 37 | 38 | 2. GRANT OF RIGHTS 39 | 40 | a) Subject to the terms of this Agreement, each Contributor hereby grants 41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 42 | reproduce, prepare derivative works of, publicly display, publicly perform, 43 | distribute and sublicense the Contribution of such Contributor, if any, and 44 | such derivative works, in source code and object code form. 45 | 46 | b) Subject to the terms of this Agreement, each Contributor hereby grants 47 | Recipient a non-exclusive, worldwide, royalty-free patent license under 48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 49 | transfer the Contribution of such Contributor, if any, in source code and 50 | object code form. This patent license shall apply to the combination of the 51 | Contribution and the Program if, at the time the Contribution is added by the 52 | Contributor, such addition of the Contribution causes such combination to be 53 | covered by the Licensed Patents. The patent license shall not apply to any 54 | other combinations which include the Contribution. No hardware per se is 55 | licensed hereunder. 56 | 57 | c) Recipient understands that although each Contributor grants the licenses 58 | to its Contributions set forth herein, no assurances are provided by any 59 | Contributor that the Program does not infringe the patent or other 60 | intellectual property rights of any other entity. Each Contributor disclaims 61 | any liability to Recipient for claims brought by any other entity based on 62 | infringement of intellectual property rights or otherwise. As a condition to 63 | exercising the rights and licenses granted hereunder, each Recipient hereby 64 | assumes sole responsibility to secure any other intellectual property rights 65 | needed, if any. For example, if a third party patent license is required to 66 | allow Recipient to distribute the Program, it is Recipient's responsibility 67 | to acquire that license before distributing the Program. 68 | 69 | d) Each Contributor represents that to its knowledge it has sufficient 70 | copyright rights in its Contribution, if any, to grant the copyright license 71 | set forth in this Agreement. 72 | 73 | 3. REQUIREMENTS 74 | 75 | A Contributor may choose to distribute the Program in object code form under 76 | its own license agreement, provided that: 77 | 78 | a) it complies with the terms and conditions of this Agreement; and 79 | 80 | b) its license agreement: 81 | 82 | i) effectively disclaims on behalf of all Contributors all warranties and 83 | conditions, express and implied, including warranties or conditions of title 84 | and non-infringement, and implied warranties or conditions of merchantability 85 | and fitness for a particular purpose; 86 | 87 | ii) effectively excludes on behalf of all Contributors all liability for 88 | damages, including direct, indirect, special, incidental and consequential 89 | damages, such as lost profits; 90 | 91 | iii) states that any provisions which differ from this Agreement are offered 92 | by that Contributor alone and not by any other party; and 93 | 94 | iv) states that source code for the Program is available from such 95 | Contributor, and informs licensees how to obtain it in a reasonable manner on 96 | or through a medium customarily used for software exchange. 97 | 98 | When the Program is made available in source code form: 99 | 100 | a) it must be made available under this Agreement; and 101 | 102 | b) a copy of this Agreement must be included with each copy of the Program. 103 | 104 | Contributors may not remove or alter any copyright notices contained within 105 | the Program. 106 | 107 | Each Contributor must identify itself as the originator of its Contribution, 108 | if any, in a manner that reasonably allows subsequent Recipients to identify 109 | the originator of the Contribution. 110 | 111 | 4. COMMERCIAL DISTRIBUTION 112 | 113 | Commercial distributors of software may accept certain responsibilities with 114 | respect to end users, business partners and the like. While this license is 115 | intended to facilitate the commercial use of the Program, the Contributor who 116 | includes the Program in a commercial product offering should do so in a 117 | manner which does not create potential liability for other Contributors. 118 | Therefore, if a Contributor includes the Program in a commercial product 119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend 120 | and indemnify every other Contributor ("Indemnified Contributor") against any 121 | losses, damages and costs (collectively "Losses") arising from claims, 122 | lawsuits and other legal actions brought by a third party against the 123 | Indemnified Contributor to the extent caused by the acts or omissions of such 124 | Commercial Contributor in connection with its distribution of the Program in 125 | a commercial product offering. The obligations in this section do not apply 126 | to any claims or Losses relating to any actual or alleged intellectual 127 | property infringement. In order to qualify, an Indemnified Contributor must: 128 | a) promptly notify the Commercial Contributor in writing of such claim, and 129 | b) allow the Commercial Contributor tocontrol, and cooperate with the 130 | Commercial Contributor in, the defense and any related settlement 131 | negotiations. The Indemnified Contributor may participate in any such claim 132 | at its own expense. 133 | 134 | For example, a Contributor might include the Program in a commercial product 135 | offering, Product X. That Contributor is then a Commercial Contributor. If 136 | that Commercial Contributor then makes performance claims, or offers 137 | warranties related to Product X, those performance claims and warranties are 138 | such Commercial Contributor's responsibility alone. Under this section, the 139 | Commercial Contributor would have to defend claims against the other 140 | Contributors related to those performance claims and warranties, and if a 141 | court requires any other Contributor to pay any damages as a result, the 142 | Commercial Contributor must pay those damages. 143 | 144 | 5. NO WARRANTY 145 | 146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON 147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER 148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR 149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A 150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the 151 | appropriateness of using and distributing the Program and assumes all risks 152 | associated with its exercise of rights under this Agreement , including but 153 | not limited to the risks and costs of program errors, compliance with 154 | applicable laws, damage to or loss of data, programs or equipment, and 155 | unavailability or interruption of operations. 156 | 157 | 6. DISCLAIMER OF LIABILITY 158 | 159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 166 | OF SUCH DAMAGES. 167 | 168 | 7. GENERAL 169 | 170 | If any provision of this Agreement is invalid or unenforceable under 171 | applicable law, it shall not affect the validity or enforceability of the 172 | remainder of the terms of this Agreement, and without further action by the 173 | parties hereto, such provision shall be reformed to the minimum extent 174 | necessary to make such provision valid and enforceable. 175 | 176 | If Recipient institutes patent litigation against any entity (including a 177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 178 | (excluding combinations of the Program with other software or hardware) 179 | infringes such Recipient's patent(s), then such Recipient's rights granted 180 | under Section 2(b) shall terminate as of the date such litigation is filed. 181 | 182 | All Recipient's rights under this Agreement shall terminate if it fails to 183 | comply with any of the material terms or conditions of this Agreement and 184 | does not cure such failure in a reasonable period of time after becoming 185 | aware of such noncompliance. If all Recipient's rights under this Agreement 186 | terminate, Recipient agrees to cease use and distribution of the Program as 187 | soon as reasonably practicable. However, Recipient's obligations under this 188 | Agreement and any licenses granted by Recipient relating to the Program shall 189 | continue and survive. 190 | 191 | Everyone is permitted to copy and distribute copies of this Agreement, but in 192 | order to avoid inconsistency the Agreement is copyrighted and may only be 193 | modified in the following manner. The Agreement Steward reserves the right to 194 | publish new versions (including revisions) of this Agreement from time to 195 | time. No one other than the Agreement Steward has the right to modify this 196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 197 | Eclipse Foundation may assign the responsibility to serve as the Agreement 198 | Steward to a suitable separate entity. Each new version of the Agreement will 199 | be given a distinguishing version number. The Program (including 200 | Contributions) may always be distributed subject to the version of the 201 | Agreement under which it was received. In addition, after a new version of 202 | the Agreement is published, Contributor may elect to distribute the Program 203 | (including its Contributions) under the new version. Except as expressly 204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 205 | licenses to the intellectual property of any Contributor under this 206 | Agreement, whether expressly, by implication, estoppel or otherwise. All 207 | rights in the Program not expressly granted under this Agreement are 208 | reserved. 209 | 210 | This Agreement is governed by the laws of the State of Washington and the 211 | intellectual property laws of the United States of America. No party to this 212 | Agreement will bring a legal action under this Agreement more than one year 213 | after the cause of action arose. Each party waives its rights to a jury trial 214 | in any resulting litigation. 215 | --------------------------------------------------------------------------------