├── VERSION_TEMPLATE ├── .gitattributes ├── .gitignore ├── script └── build │ ├── update_version │ ├── git_revision │ ├── branch_revision │ ├── trunk_revision │ └── revision ├── README.md ├── pom.xml ├── src └── main │ └── java │ └── clojure │ └── tools │ └── Install.java └── epl.html /VERSION_TEMPLATE: -------------------------------------------------------------------------------- 1 | 0.1.GENERATED_VERSION 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | epl.html linguist-vendored=true 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | target/ 4 | dependency-reduced-pom.xml 5 | deps.edn 6 | .cpcache 7 | -------------------------------------------------------------------------------- /script/build/update_version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | mvn versions:set -DgenerateBackupPoms=false -DnewVersion=`script/build/revision`-SNAPSHOT 6 | -------------------------------------------------------------------------------- /script/build/git_revision: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Return the portion of the version number generated from git 4 | # 5 | 6 | set -e 7 | 8 | trunk_basis=`script/build/trunk_revision` 9 | sha=`git rev-parse HEAD` 10 | 11 | sha=${sha:0:${#sha}-34} # drop the last 34 characters, keep 6 12 | 13 | echo $trunk_basis 14 | -------------------------------------------------------------------------------- /script/build/branch_revision: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # If on a branch other than master, returns the number of commits made off of master 4 | # If on master, returns 0 5 | 6 | set -e 7 | 8 | master_tag=`git rev-parse --abbrev-ref HEAD` 9 | 10 | if [ "$master_tag" == "master" ]; then 11 | echo "0" 12 | else 13 | last_commit=`git rev-parse HEAD` 14 | revision=`git rev-list master..$last_commit | wc -l` 15 | echo $revision 16 | fi 17 | -------------------------------------------------------------------------------- /script/build/trunk_revision: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Returns the number of commits made since the v0.0 tag 4 | 5 | set -e 6 | 7 | REVISION=`git --no-replace-objects describe --match v0.0` 8 | 9 | # Extract the version number from the string. Do this in two steps so 10 | # it is a little easier to understand. 11 | REVISION=${REVISION:5} # drop the first 5 characters 12 | REVISION=${REVISION:0:${#REVISION}-9} # drop the last 9 characters 13 | 14 | echo $REVISION 15 | -------------------------------------------------------------------------------- /script/build/revision: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Return the complete revision number 4 | # ...-[-qualifier] 5 | 6 | set -e 7 | 8 | version_template=`cat VERSION_TEMPLATE` 9 | 10 | if [[ "$version_template" =~ ^[0-9]+\.[0-9]+\.GENERATED_VERSION(-[a-zA-Z0-9]+)?$ ]]; then 11 | 12 | git_revision=`script/build/git_revision` 13 | echo ${version_template/GENERATED_VERSION/$git_revision} 14 | 15 | else 16 | echo "Invalid version template string: $version_template" >&2 17 | exit -1 18 | fi 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | clojure-install 2 | ===================================== 3 | 4 | # DEPRECATED - this project is no longer active. See https://github.com/clojure/brew-install. 5 | 6 | ---- 7 | 8 | The Clojure install project is used to bootstrap a system to include Clojure, 9 | tools.deps.alpha, and the scripts necessary to use them to obtain more 10 | dependencies and run a Clojure repl or programs. 11 | 12 | The installer assumes only that Java is available. The install tool is written 13 | in Java and uses the necessary Maven Aether libraries to traverse and 14 | download the initial dependency set. 15 | 16 | In general, this project will be obtained and used within system installers rather 17 | than used directly. 18 | 19 | ## Release Information 20 | 21 | Latest release: 0.1.21 22 | 23 | * [All released versions](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.clojure%22%20AND%20a%3A%22clojure-install%22) 24 | 25 | [Leiningen](http://github.com/technomancy/leiningen/) dependency information: 26 | 27 | ``` 28 | [org.clojure/clojure-install "0.1.21"] 29 | ``` 30 | 31 | [Maven](http://maven.apache.org) dependency information: 32 | 33 | ``` 34 | 35 | org.clojure 36 | clojure-install 37 | 0.1.21 38 | 39 | ``` 40 | 41 | 42 | ## Usage 43 | 44 | ### `clojure.tools.Install` 45 | 46 | The `Install` program performs the following steps: 47 | 48 | * Given a Clojure config directory 49 | * Read `CONFIG/clj.props` 50 | * Use those props to form a dependency set 51 | * Download those dependencies and all transitive dependencies to the local Maven repository 52 | * If `CONFIG/clj.cp` or `CONFIG/deps.edn` exist, copy them to backup files 53 | * Create `CONFIG/clj.cp` - used when invoking tools.deps.alpha 54 | * Create `CONFIG/deps.edn` - user-level deps map, for declaring default deps and artifact providers 55 | 56 | This can be re-run to pick up manual changes in `clj.props`. 57 | 58 | ### `clj.props` file 59 | 60 | Example props file: 61 | 62 | ``` 63 | org.clojure/clojure=1.9.0-alpha17 64 | org.clojure/tools.deps.alpha=0.1.14 65 | org.clojure/spec.alpha=0.1.123 66 | ``` 67 | 68 | ## Developer Information 69 | 70 | * [GitHub project](https://github.com/clojure/clojure-install) 71 | * [How to contribute](https://dev.clojure.org/display/community/Contributing) 72 | * [Bug Tracker](https://dev.clojure.org/jira/browse/INST) 73 | * [Continuous Integration](https://build.clojure.org/job/clojure-install/) 74 | * [Compatibility Test Matrix](https://build.clojure.org/job/clojure-install-test-matrix/) 75 | 76 | ## License 77 | 78 | Copyright © 2017 Rich Hickey and contributors 79 | 80 | Distributed under the Eclipse Public License, the same as Clojure. 81 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.clojure 5 | clojure-install 6 | 0.1.22-SNAPSHOT 7 | jar 8 | clojure-install 9 | Clojure dependency installer 10 | https://github.com/clojure/clojure-install 11 | 12 | 13 | scm:git:git@github.com:clojure/clojure-install.git 14 | scm:git:git@github.com:clojure/clojure-install.git 15 | git@github.com:clojure/clojure-install.git 16 | HEAD 17 | 18 | 19 | 20 | 21 | Eclipse Public License 1.0 22 | http://opensource.org/licenses/eclipse-1.0.php 23 | repo 24 | 25 | 26 | 27 | 28 | 29 | puredanger 30 | Alex Miller 31 | 32 | 33 | 34 | 35 | 1.0.3 36 | 3.3.9 37 | 38 | 39 | 40 | 41 | org.apache.maven.resolver 42 | maven-resolver-api 43 | ${resolverVersion} 44 | 45 | 46 | org.apache.maven.resolver 47 | maven-resolver-spi 48 | ${resolverVersion} 49 | 50 | 51 | org.apache.maven.resolver 52 | maven-resolver-impl 53 | ${resolverVersion} 54 | 55 | 56 | org.apache.maven.resolver 57 | maven-resolver-connector-basic 58 | ${resolverVersion} 59 | 60 | 61 | org.apache.maven.resolver 62 | maven-resolver-transport-file 63 | ${resolverVersion} 64 | 65 | 66 | org.apache.maven.resolver 67 | maven-resolver-transport-http 68 | ${resolverVersion} 69 | 70 | 71 | org.apache.maven 72 | maven-aether-provider 73 | ${mavenVersion} 74 | 75 | 76 | org.eclipse.aether 77 | aether-api 78 | 79 | 80 | org.eclipse.aether 81 | aether-spi 82 | 83 | 84 | org.eclipse.aether 85 | aether-util 86 | 87 | 88 | org.eclipse.aether 89 | aether-impl 90 | 91 | 92 | 93 | 94 | org.slf4j 95 | slf4j-nop 96 | 1.6.2 97 | 98 | 99 | 100 | 101 | 102 | 103 | sonatype-nexus-staging 104 | https://oss.sonatype.org/content/repositories/snapshots 105 | 106 | 107 | 108 | 109 | 110 | 111 | org.apache.maven.plugins 112 | maven-compiler-plugin 113 | 3.6.0 114 | 115 | 1.7 116 | 1.7 117 | UTF-8 118 | 119 | 120 | 121 | 125 | org.apache.maven.plugins 126 | maven-release-plugin 127 | 2.5.3 128 | 129 | false 130 | true 131 | 132 | 133 | 134 | 135 | org.sonatype.plugins 136 | nexus-staging-maven-plugin 137 | 1.6.7 138 | true 139 | 140 | 141 | sonatype-nexus-staging 142 | https://oss.sonatype.org/ 143 | true 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | sign 152 | 153 | 154 | 155 | 156 | org.apache.maven.plugins 157 | maven-gpg-plugin 158 | 1.5 159 | 160 | 161 | sign-artifacts 162 | verify 163 | 164 | sign 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /src/main/java/clojure/tools/Install.java: -------------------------------------------------------------------------------- 1 | package clojure.tools; 2 | 3 | import org.apache.maven.repository.internal.MavenRepositorySystemUtils; 4 | import org.eclipse.aether.DefaultRepositorySystemSession; 5 | import org.eclipse.aether.RepositorySystem; 6 | import org.eclipse.aether.RepositorySystemSession; 7 | import org.eclipse.aether.artifact.Artifact; 8 | import org.eclipse.aether.artifact.DefaultArtifact; 9 | import org.eclipse.aether.collection.CollectRequest; 10 | import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; 11 | import org.eclipse.aether.graph.Dependency; 12 | import org.eclipse.aether.impl.DefaultServiceLocator; 13 | import org.eclipse.aether.repository.LocalRepository; 14 | import org.eclipse.aether.repository.RemoteRepository; 15 | import org.eclipse.aether.resolution.*; 16 | import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; 17 | import org.eclipse.aether.spi.connector.transport.TransporterFactory; 18 | import org.eclipse.aether.transfer.TransferEvent; 19 | import org.eclipse.aether.transfer.TransferListener; 20 | import org.eclipse.aether.transport.file.FileTransporterFactory; 21 | import org.eclipse.aether.transport.http.HttpTransporterFactory; 22 | 23 | import java.io.*; 24 | import java.nio.file.Files; 25 | import java.nio.file.StandardCopyOption; 26 | import java.util.ArrayList; 27 | import java.util.Iterator; 28 | import java.util.List; 29 | import java.util.Properties; 30 | import java.util.Map; 31 | 32 | public class Install { 33 | 34 | private static String HOME = System.getProperty("user.home"); 35 | 36 | private static File backup(File f, boolean verbose) throws IOException { 37 | if(f.exists()) { 38 | File backup = new File(f.getParentFile(), f.getName() + ".backup"); 39 | if(verbose) System.out.println("Backing up " + f.getAbsolutePath() + " to .backup file"); 40 | Files.copy(f.toPath(), backup.toPath(), StandardCopyOption.REPLACE_EXISTING); 41 | } 42 | return f; 43 | } 44 | 45 | public static class ConsoleTransferListener implements TransferListener { 46 | public void transferInitiated(TransferEvent transferEvent) {} 47 | public void transferProgressed(TransferEvent transferEvent) {} 48 | public void transferSucceeded(TransferEvent transferEvent) {} 49 | public void transferCorrupted(TransferEvent transferEvent) {} 50 | public void transferFailed(TransferEvent transferEvent) {} 51 | 52 | public void transferStarted(TransferEvent transferEvent) { 53 | String resource = transferEvent.getResource().getResourceName(); 54 | if(resource.endsWith(".jar")) { 55 | String message = "Downloading: " + resource; 56 | System.out.println(message); 57 | } 58 | } 59 | } 60 | 61 | private static RepositorySystem repositorySystem() { 62 | DefaultServiceLocator loc = MavenRepositorySystemUtils.newServiceLocator(); 63 | loc.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); 64 | loc.addService(TransporterFactory.class, FileTransporterFactory.class); 65 | loc.addService(TransporterFactory.class, HttpTransporterFactory.class); 66 | return loc.getService(RepositorySystem.class); 67 | } 68 | 69 | private static RepositorySystemSession repositorySession(RepositorySystem system, boolean offline) { 70 | DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); 71 | String localRepo = new File(new File(HOME, ".m2"), "repository").getAbsolutePath(); 72 | session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, new LocalRepository(localRepo))); 73 | session.setOffline(offline); 74 | session.setTransferListener(new ConsoleTransferListener()); 75 | return session; 76 | } 77 | 78 | private static Artifact makeArtifact(String groupId, String artifactId, String version) { 79 | return new DefaultArtifact(groupId, artifactId, "jar", version); 80 | } 81 | 82 | private static Dependency makeDependency(String groupId, String artifactId, String version) { 83 | return new Dependency(makeArtifact(groupId, artifactId, version), null); 84 | } 85 | 86 | private static VersionRangeRequest makeVersionRangeRequest(String groupId, String artifactId) { 87 | VersionRangeRequest req = new VersionRangeRequest(); 88 | req.setArtifact(makeArtifact(groupId, artifactId, "[0,)")); 89 | return req; 90 | } 91 | 92 | private static List resolveDeps(RepositorySystem system, RepositorySystemSession session, RemoteRepository repo, List deps) 93 | throws DependencyResolutionException { 94 | List repos = new ArrayList(); 95 | repos.add(repo); 96 | 97 | CollectRequest collectRequest = new CollectRequest(deps, null, repos); 98 | collectRequest.setRequestContext("runtime"); 99 | 100 | DependencyResult result = system.resolveDependencies(session, new DependencyRequest(collectRequest, null)); 101 | List results = result.getArtifactResults(); 102 | return results; 103 | } 104 | 105 | private static void install(String configDir, boolean verbose) throws Exception { 106 | // Ensure config directory exists 107 | File clojure = new File(configDir); 108 | if(! clojure.exists()) { 109 | throw new IOException("Directory does not exist: " + clojure.getAbsolutePath()); 110 | } 111 | 112 | // Read properties file 113 | File cljPropsFile = new File(clojure, "clj.props"); 114 | if(! cljPropsFile.exists()) { 115 | throw new IOException("Missing props file at: " + cljPropsFile.getAbsolutePath()); 116 | 117 | } 118 | Properties props = new Properties(); 119 | props.load(new FileReader(cljPropsFile)); 120 | 121 | // Ready for mavening 122 | boolean offline = false; 123 | RepositorySystem system = repositorySystem(); 124 | RepositorySystemSession session = repositorySession(system, offline); 125 | RemoteRepository repo = new RemoteRepository.Builder("central", "default", "https://repo1.maven.org/maven2").build(); 126 | 127 | // Load and install deps 128 | if(verbose) System.out.println("Installing deps"); 129 | List deps = new ArrayList(); 130 | for (Map.Entry entry: props.entrySet()) { 131 | String lib = (String) entry.getKey(); 132 | String[] parts = lib.split("/"); 133 | String version = (String) entry.getValue(); 134 | if(parts.length == 1) { 135 | deps.add(makeDependency(parts[0], parts[0], version)); 136 | } else if(parts.length == 2) { 137 | deps.add(makeDependency(parts[0], parts[1], version)); 138 | } else { 139 | throw new IOException("Invalid lib in props file: " + lib + ", expected something like org.clojure/clojure"); 140 | } 141 | } 142 | List results = resolveDeps(system, session, repo, deps); 143 | 144 | // Find files and make backups 145 | File cp = backup(new File(clojure, "clj.cp"), verbose); 146 | File systemdeps = backup(new File(clojure, "deps.edn"), verbose); 147 | 148 | // Write clj.cp 149 | if(verbose) System.out.println("Writing: " + cp.getAbsolutePath()); 150 | BufferedWriter cpWriter = new BufferedWriter(new FileWriter(cp)); 151 | Iterator resultsIter = results.iterator(); 152 | cpWriter.write(resultsIter.next().getArtifact().getFile().getAbsolutePath()); 153 | while(resultsIter.hasNext()) { 154 | cpWriter.write(File.pathSeparatorChar); 155 | cpWriter.write(resultsIter.next().getArtifact().getFile().getAbsolutePath()); 156 | } 157 | cpWriter.close(); 158 | 159 | // Write system deps.edn 160 | if(verbose) System.out.println("Writing: " + systemdeps.getAbsolutePath()); 161 | BufferedWriter systemdepsWriter = new BufferedWriter(new FileWriter(systemdeps)); 162 | systemdepsWriter.write(String.format( 163 | "{:deps {%1$s/%2$s {:type :mvn :version \"%3$s\"}}\n" + 164 | " :providers {:mvn {:repos {\"central\" {:url \"https://repo1.maven.org/maven2/\"}\n" + 165 | " \"clojars\" {:url \"https://clojars.org/repo/\"}}}}}", 166 | "org.clojure", "clojure", props.get("org.clojure/clojure"))); 167 | systemdepsWriter.close(); 168 | 169 | if(verbose) System.out.println("Done."); 170 | } 171 | 172 | /** 173 | * Usage: java clojure.tools.Install config_dir [opts] 174 | * 175 | * config_dir - the Clojure config directory to use 176 | * 177 | * opts: 178 | * 179 | * -v - verbose mode 180 | * 181 | * Expects to be called in the context of install-clj script, which ensures: 182 | * 183 | * ~/.clojure exists 184 | * ~/.clojure/clj.props exists 185 | */ 186 | public static void main(String[] args) { 187 | try { 188 | if(args.length == 0) { 189 | throw new IOException("No config directory specified"); 190 | } 191 | String configDir = args[0]; 192 | boolean verbose = args.length > 1 && args[1].equals("-v"); 193 | install(configDir, verbose); 194 | } catch(Throwable e) { 195 | System.err.println(e.getMessage()); 196 | System.exit(1); 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /epl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Eclipse Public License - Version 1.0 8 | 25 | 26 | 27 | 28 | 29 | 30 |

Eclipse Public License - v 1.0

31 | 32 |

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 33 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR 34 | DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS 35 | AGREEMENT.

36 | 37 |

1. DEFINITIONS

38 | 39 |

"Contribution" means:

40 | 41 |

a) in the case of the initial Contributor, the initial 42 | code and documentation distributed under this Agreement, and

43 |

b) in the case of each subsequent Contributor:

44 |

i) changes to the Program, and

45 |

ii) additions to the Program;

46 |

where such changes and/or additions to the Program 47 | originate from and are distributed by that particular Contributor. A 48 | Contribution 'originates' from a Contributor if it was added to the 49 | Program by such Contributor itself or anyone acting on such 50 | Contributor's behalf. Contributions do not include additions to the 51 | Program which: (i) are separate modules of software distributed in 52 | conjunction with the Program under their own license agreement, and (ii) 53 | are not derivative works of the Program.

54 | 55 |

"Contributor" means any person or entity that distributes 56 | the Program.

57 | 58 |

"Licensed Patents" mean patent claims licensable by a 59 | Contributor which are necessarily infringed by the use or sale of its 60 | Contribution alone or when combined with the Program.

61 | 62 |

"Program" means the Contributions distributed in accordance 63 | with this Agreement.

64 | 65 |

"Recipient" means anyone who receives the Program under 66 | this Agreement, including all Contributors.

67 | 68 |

2. GRANT OF RIGHTS

69 | 70 |

a) Subject to the terms of this Agreement, each 71 | Contributor hereby grants Recipient a non-exclusive, worldwide, 72 | royalty-free copyright license to reproduce, prepare derivative works 73 | of, publicly display, publicly perform, distribute and sublicense the 74 | Contribution of such Contributor, if any, and such derivative works, in 75 | source code and object code form.

76 | 77 |

b) Subject to the terms of this Agreement, each 78 | Contributor hereby grants Recipient a non-exclusive, worldwide, 79 | royalty-free patent license under Licensed Patents to make, use, sell, 80 | offer to sell, import and otherwise transfer the Contribution of such 81 | Contributor, if any, in source code and object code form. This patent 82 | license shall apply to the combination of the Contribution and the 83 | Program if, at the time the Contribution is added by the Contributor, 84 | such addition of the Contribution causes such combination to be covered 85 | by the Licensed Patents. The patent license shall not apply to any other 86 | combinations which include the Contribution. No hardware per se is 87 | licensed hereunder.

88 | 89 |

c) Recipient understands that although each Contributor 90 | grants the licenses to its Contributions set forth herein, no assurances 91 | are provided by any Contributor that the Program does not infringe the 92 | patent or other intellectual property rights of any other entity. Each 93 | Contributor disclaims any liability to Recipient for claims brought by 94 | any other entity based on infringement of intellectual property rights 95 | or otherwise. As a condition to exercising the rights and licenses 96 | granted hereunder, each Recipient hereby assumes sole responsibility to 97 | secure any other intellectual property rights needed, if any. For 98 | example, if a third party patent license is required to allow Recipient 99 | to distribute the Program, it is Recipient's responsibility to acquire 100 | that license before distributing the Program.

101 | 102 |

d) Each Contributor represents that to its knowledge it 103 | has sufficient copyright rights in its Contribution, if any, to grant 104 | the copyright license set forth in this Agreement.

105 | 106 |

3. REQUIREMENTS

107 | 108 |

A Contributor may choose to distribute the Program in object code 109 | form under its own license agreement, provided that:

110 | 111 |

a) it complies with the terms and conditions of this 112 | Agreement; and

113 | 114 |

b) its license agreement:

115 | 116 |

i) effectively disclaims on behalf of all Contributors 117 | all warranties and conditions, express and implied, including warranties 118 | or conditions of title and non-infringement, and implied warranties or 119 | conditions of merchantability and fitness for a particular purpose;

120 | 121 |

ii) effectively excludes on behalf of all Contributors 122 | all liability for damages, including direct, indirect, special, 123 | incidental and consequential damages, such as lost profits;

124 | 125 |

iii) states that any provisions which differ from this 126 | Agreement are offered by that Contributor alone and not by any other 127 | party; and

128 | 129 |

iv) states that source code for the Program is available 130 | from such Contributor, and informs licensees how to obtain it in a 131 | reasonable manner on or through a medium customarily used for software 132 | exchange.

133 | 134 |

When the Program is made available in source code form:

135 | 136 |

a) it must be made available under this Agreement; and

137 | 138 |

b) a copy of this Agreement must be included with each 139 | copy of the Program.

140 | 141 |

Contributors may not remove or alter any copyright notices contained 142 | within the Program.

143 | 144 |

Each Contributor must identify itself as the originator of its 145 | Contribution, if any, in a manner that reasonably allows subsequent 146 | Recipients to identify the originator of the Contribution.

147 | 148 |

4. COMMERCIAL DISTRIBUTION

149 | 150 |

Commercial distributors of software may accept certain 151 | responsibilities with respect to end users, business partners and the 152 | like. While this license is intended to facilitate the commercial use of 153 | the Program, the Contributor who includes the Program in a commercial 154 | product offering should do so in a manner which does not create 155 | potential liability for other Contributors. Therefore, if a Contributor 156 | includes the Program in a commercial product offering, such Contributor 157 | ("Commercial Contributor") hereby agrees to defend and 158 | indemnify every other Contributor ("Indemnified Contributor") 159 | against any losses, damages and costs (collectively "Losses") 160 | arising from claims, lawsuits and other legal actions brought by a third 161 | party against the Indemnified Contributor to the extent caused by the 162 | acts or omissions of such Commercial Contributor in connection with its 163 | distribution of the Program in a commercial product offering. The 164 | obligations in this section do not apply to any claims or Losses 165 | relating to any actual or alleged intellectual property infringement. In 166 | order to qualify, an Indemnified Contributor must: a) promptly notify 167 | the Commercial Contributor in writing of such claim, and b) allow the 168 | Commercial Contributor to control, and cooperate with the Commercial 169 | Contributor in, the defense and any related settlement negotiations. The 170 | Indemnified Contributor may participate in any such claim at its own 171 | expense.

172 | 173 |

For example, a Contributor might include the Program in a commercial 174 | product offering, Product X. That Contributor is then a Commercial 175 | Contributor. If that Commercial Contributor then makes performance 176 | claims, or offers warranties related to Product X, those performance 177 | claims and warranties are such Commercial Contributor's responsibility 178 | alone. Under this section, the Commercial Contributor would have to 179 | defend claims against the other Contributors related to those 180 | performance claims and warranties, and if a court requires any other 181 | Contributor to pay any damages as a result, the Commercial Contributor 182 | must pay those damages.

183 | 184 |

5. NO WARRANTY

185 | 186 |

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS 187 | PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 188 | OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, 189 | ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY 190 | OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely 191 | responsible for determining the appropriateness of using and 192 | distributing the Program and assumes all risks associated with its 193 | exercise of rights under this Agreement , including but not limited to 194 | the risks and costs of program errors, compliance with applicable laws, 195 | damage to or loss of data, programs or equipment, and unavailability or 196 | interruption of operations.

197 | 198 |

6. DISCLAIMER OF LIABILITY

199 | 200 |

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT 201 | NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, 202 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING 203 | WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF 204 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 205 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR 206 | DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 207 | HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

208 | 209 |

7. GENERAL

210 | 211 |

If any provision of this Agreement is invalid or unenforceable under 212 | applicable law, it shall not affect the validity or enforceability of 213 | the remainder of the terms of this Agreement, and without further action 214 | by the parties hereto, such provision shall be reformed to the minimum 215 | extent necessary to make such provision valid and enforceable.

216 | 217 |

If Recipient institutes patent litigation against any entity 218 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 219 | Program itself (excluding combinations of the Program with other 220 | software or hardware) infringes such Recipient's patent(s), then such 221 | Recipient's rights granted under Section 2(b) shall terminate as of the 222 | date such litigation is filed.

223 | 224 |

All Recipient's rights under this Agreement shall terminate if it 225 | fails to comply with any of the material terms or conditions of this 226 | Agreement and does not cure such failure in a reasonable period of time 227 | after becoming aware of such noncompliance. If all Recipient's rights 228 | under this Agreement terminate, Recipient agrees to cease use and 229 | distribution of the Program as soon as reasonably practicable. However, 230 | Recipient's obligations under this Agreement and any licenses granted by 231 | Recipient relating to the Program shall continue and survive.

232 | 233 |

Everyone is permitted to copy and distribute copies of this 234 | Agreement, but in order to avoid inconsistency the Agreement is 235 | copyrighted and may only be modified in the following manner. The 236 | Agreement Steward reserves the right to publish new versions (including 237 | revisions) of this Agreement from time to time. No one other than the 238 | Agreement Steward has the right to modify this Agreement. The Eclipse 239 | Foundation is the initial Agreement Steward. The Eclipse Foundation may 240 | assign the responsibility to serve as the Agreement Steward to a 241 | suitable separate entity. Each new version of the Agreement will be 242 | given a distinguishing version number. The Program (including 243 | Contributions) may always be distributed subject to the version of the 244 | Agreement under which it was received. In addition, after a new version 245 | of the Agreement is published, Contributor may elect to distribute the 246 | Program (including its Contributions) under the new version. Except as 247 | expressly stated in Sections 2(a) and 2(b) above, Recipient receives no 248 | rights or licenses to the intellectual property of any Contributor under 249 | this Agreement, whether expressly, by implication, estoppel or 250 | otherwise. All rights in the Program not expressly granted under this 251 | Agreement are reserved.

252 | 253 |

This Agreement is governed by the laws of the State of New York and 254 | the intellectual property laws of the United States of America. No party 255 | to this Agreement will bring a legal action under this Agreement more 256 | than one year after the cause of action arose. Each party waives its 257 | rights to a jury trial in any resulting litigation.

258 | 259 | 260 | 261 | 262 | --------------------------------------------------------------------------------