├── .clj-kondo ├── babashka │ └── fs │ │ └── config.edn ├── http-kit │ └── http-kit │ │ ├── config.edn │ │ └── httpkit │ │ └── with_channel.clj └── rewrite-clj │ └── rewrite-clj │ └── config.edn ├── test ├── test-jar │ ├── testjar.jar │ ├── java │ │ └── TestJar.java │ └── bb.edn └── deps_bin │ └── impl │ └── bin_test.clj ├── .dir-locals.el ├── .gitignore ├── src └── deps_bin │ ├── deps_bin.clj │ └── impl │ └── bin.clj ├── .github └── workflows │ └── ci.yml ├── bb.edn ├── deps.edn ├── README.md ├── pom.xml └── LICENSE /.clj-kondo/babashka/fs/config.edn: -------------------------------------------------------------------------------- 1 | {:lint-as {babashka.fs/with-temp-dir clojure.core/let}} 2 | -------------------------------------------------------------------------------- /test/test-jar/testjar.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericdallo/deps-bin/HEAD/test/test-jar/testjar.jar -------------------------------------------------------------------------------- /.clj-kondo/http-kit/http-kit/config.edn: -------------------------------------------------------------------------------- 1 | 2 | {:hooks 3 | {:analyze-call {org.httpkit.server/with-channel httpkit.with-channel/with-channel}}} 4 | -------------------------------------------------------------------------------- /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ;;; Directory Local Variables 2 | ;;; For more information see (info "(emacs) Directory Variables") 3 | 4 | ((clojure-mode . ((cider-clojure-cli-aliases . ":test")))) 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /.lsp/*.db 3 | /target 4 | /.DS_Store 5 | /.cpcache 6 | /.clj-kondo/.cache 7 | /.calva/output-window 8 | /deps-bin 9 | /deps-bin.jar 10 | /.nrepl-port 11 | 12 | *.class 13 | 14 | # Emacs 15 | *~ 16 | #* -------------------------------------------------------------------------------- /.clj-kondo/rewrite-clj/rewrite-clj/config.edn: -------------------------------------------------------------------------------- 1 | {:lint-as 2 | {rewrite-clj.zip/subedit-> clojure.core/-> 3 | rewrite-clj.zip/subedit->> clojure.core/->> 4 | rewrite-clj.zip/edit-> clojure.core/-> 5 | rewrite-clj.zip/edit->> clojure.core/->>}} 6 | -------------------------------------------------------------------------------- /.clj-kondo/http-kit/http-kit/httpkit/with_channel.clj: -------------------------------------------------------------------------------- 1 | (ns httpkit.with-channel 2 | (:require [clj-kondo.hooks-api :as api])) 3 | 4 | (defn with-channel [{node :node}] 5 | (let [[request channel & body] (rest (:children node))] 6 | (when-not (and request channel) (throw (ex-info "No request or channel provided" {}))) 7 | (when-not (api/token-node? channel) (throw (ex-info "Missing channel argument" {}))) 8 | (let [new-node 9 | (api/list-node 10 | (list* 11 | (api/token-node 'let) 12 | (api/vector-node [channel (api/vector-node [])]) 13 | request 14 | body))] 15 | 16 | {:node new-node}))) 17 | -------------------------------------------------------------------------------- /src/deps_bin/deps_bin.clj: -------------------------------------------------------------------------------- 1 | (ns deps-bin.deps-bin 2 | "Entry point for clojure -X options." 3 | (:require [deps-bin.impl.bin :as bin])) 4 | 5 | (defn bin 6 | "Generic entry point for bin invocations. 7 | Can be used with `clojure -X`: 8 | In `:aliases`: 9 | ```clojure 10 | :bin {:replace-deps {ericdallo/deps-bin {:mvn/version ...}} 11 | :exec-fn deps-bin.deps-bin/bin 12 | :exec-args {:name \"myBin\"}} 13 | ``` 14 | Then run: 15 | ``` 16 | clojure -X:bin :jar MyProject.jar 17 | ``` 18 | If the source JAR file is fixed, it could be added to `:exec-args` in 19 | `deps.edn`: 20 | ```clojure 21 | :jar {:replace-deps {ericdallo/deps-bin {:mvn/version ...}} 22 | :exec-fn deps-bin.deps-bin/bin 23 | :exec-args {:jar MyProject.jar}} 24 | ``` 25 | `:jar` can be specified as a symbol or a string. 26 | `:name` can be specified as a symbol or a string." 27 | [options] 28 | (bin/build-bin-as-main options)) 29 | -------------------------------------------------------------------------------- /test/test-jar/java/TestJar.java: -------------------------------------------------------------------------------- 1 | /** 2 | * A test jar implementation useful for testing jvm options and 3 | * parameter passing of the jar wrapper script. 4 | */ 5 | public class TestJar 6 | { 7 | /** 8 | * Prints out the system property values of each arg in ARGS on a 9 | * separate line. 10 | * 11 | * Line format is as follows. If there is no value for ARG, then 12 | * PROPERTY-VALUE is printed as NULL. 13 | * 14 | * :prop ARG :v PROPERTY-VALUE 15 | * 16 | * The program terminates with exit code 0, unless there is an arg 17 | * in ARGS of `testjar.return', in which case it exists with that 18 | * property's integer value. 19 | * 20 | */ 21 | public static void main (String[] args) 22 | { 23 | int ret = 0; 24 | for (int i = 0; i < args.length; i++) 25 | { 26 | String prop = args[i]; 27 | String v = System.getProperty(args[i]); 28 | if (prop.equals("testjar.return")) 29 | ret = Integer.parseInt(v); 30 | System.out.println(":prop " + prop + " :v " + v); 31 | } 32 | System.exit(ret); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/test-jar/bb.edn: -------------------------------------------------------------------------------- 1 | {:tasks 2 | {:requires [[babashka.fs :as fs] 3 | [babashka.process :as p] 4 | [clojure.string :as str]] 5 | :init (do (def class-name "TestJar") 6 | (def java-path (str "java/" class-name ".java")) 7 | (def classes-dir "classes") 8 | (def jar-path "testjar.jar")) 9 | clean (do (fs/delete-tree classes-dir) 10 | (fs/delete-if-exists jar-path)) 11 | 12 | compile (do (when-not (fs/exists? classes-dir) (fs/create-dir classes-dir)) 13 | (p/shell "javac" "--source" 8 "--target" 8 "-d" classes-dir java-path)) 14 | 15 | jar-make (let [bb (str \" (.get (.command (.info (java.lang.ProcessHandle/current)))) \")] 16 | (p/shell bb "-cp" classes-dir "uberjar" jar-path "-m" class-name)) 17 | 18 | jar-clean-make {:doc "Clean up and make jar file from source code." 19 | :task 20 | (doseq [task '[clean compile jar-make]] 21 | (println :task task) 22 | (run task))} 23 | 24 | jar-test (p/shell "java" "-Dxyz=9" "-jar" jar-path "xyz") 25 | 26 | jar-clean-test 27 | (doseq [task '[jar-clean-make jar-test]] 28 | (println :task task) 29 | (run task))}} 30 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | lint: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2.2.0 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Install Clojure 17 | uses: DeLaGuardo/setup-clojure@master 18 | with: 19 | bb: latest 20 | clj-kondo: latest 21 | 22 | - name: Lint codebase 23 | run: bb lint 24 | 25 | unit-test: 26 | runs-on: ${{matrix.os}} 27 | strategy: 28 | fail-fast: false 29 | matrix: 30 | os: [ubuntu-latest] 31 | jdk: [8, 11, 15, 17] 32 | include: 33 | - os: windows-latest 34 | jdk: 8 35 | - os: macos-latest 36 | jdk: 8 37 | steps: 38 | - uses: actions/checkout@v2.2.0 39 | with: 40 | fetch-depth: 0 41 | 42 | - name: Set up JDK ${{ matrix.jdk }} 43 | uses: actions/setup-java@v1 44 | with: 45 | java-version: ${{ matrix.jdk }} 46 | 47 | - name: Install Clojure 48 | uses: DeLaGuardo/setup-clojure@master 49 | with: 50 | cli: '1.10.3.1013' 51 | bb: latest 52 | 53 | - name: Run tests 54 | run: bb test 55 | 56 | -------------------------------------------------------------------------------- /bb.edn: -------------------------------------------------------------------------------- 1 | {:paths ["src"] 2 | :tasks 3 | {:requires [[babashka.deps :as deps] 4 | [babashka.fs :as fs] 5 | [babashka.process :as p] 6 | [clojure.string :as str]] 7 | 8 | lint {:doc "Run linter." 9 | :task (do (when-not (fs/exists? ".clj-kondo") 10 | ;; Prep linter. The `:test` alias has main as dep. 11 | (let [cp (with-out-str (deps/clojure ["-A:test" "-Spath"]))] 12 | (fs/create-dir ".clj-kondo") 13 | (p/shell "clj-kondo" "--lint" cp "--dependencies" "--copy-configs"))) 14 | (doseq [dir ["src" "test"]] 15 | (println :linting dir "...") 16 | (p/shell "clj-kondo" "--lint" dir) 17 | (println)))} 18 | 19 | lint-clean {:doc "Clean linter cache." 20 | :task (fs/delete-tree ".clj-kondo")} 21 | 22 | test {:doc "Run all tests." 23 | :task 24 | (-> (deps/clojure ["-M:test:runner"] {:inherit true}) 25 | p/check)}}} 26 | 27 | tj {:doc "Exec bb in test/test-jar." 28 | :task (let [dir "test/test-jar" 29 | bb (str \" (.get (.command (.info (java.lang.ProcessHandle/current)))) \") 30 | args (or *command-line-args* ["tasks"])] 31 | (println (str "in " dir "...\n")) 32 | (p/shell {:dir dir} (str/join " " (into [bb] args))))} 33 | 34 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:deps {org.clojure/clojure {:mvn/version "1.11.0-rc1"} 2 | org.clojure/tools.logging {:mvn/version "1.2.4"} 3 | org.apache.logging.log4j/log4j-core {:mvn/version "2.17.2"} 4 | org.slf4j/slf4j-simple {:mvn/version "1.7.36"} 5 | clj-zip-meta/clj-zip-meta {:mvn/version "0.1.3" 6 | :exclusions [org.clojure/clojure]} 7 | me.raynes/fs {:mvn/version "1.4.6"} 8 | de.ubercode.clostache/clostache {:mvn/version "1.4.0"}} 9 | :paths ["src"] 10 | :aliases {:test {:extra-paths ["test"] 11 | :extra-deps {babashka/fs {:mvn/version "0.1.11"} 12 | babashka/process {:mvn/version "0.2.10"}}} 13 | :runner {:extra-deps {com.cognitect/test-runner 14 | {:git/url "https://github.com/cognitect-labs/test-runner" 15 | :sha "b6b3193fcc42659d7e46ecd1884a228993441182"}} 16 | :main-opts ["-m" "cognitect.test-runner" 17 | "-d" "test"]} 18 | :jar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.1.303"}} 19 | :exec-fn hf.depstar/jar 20 | :exec-args {:jar "deps-bin.jar" 21 | :sync-pom true 22 | :version "1.0.0"}} 23 | :bin {:exec-fn deps-bin.deps-bin/bin 24 | :exec-args {:jar "deps-bin.jar" 25 | :name "deps-bin"}} 26 | :deploy {:replace-deps {slipset/deps-deploy {:mvn/version "0.2.0"}} 27 | :exec-fn deps-deploy.deps-deploy/deploy 28 | :exec-args {:installer :remote 29 | :artifact "deps-bin.jar"}}}} 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Clojars Project](https://img.shields.io/clojars/v/com.github.ericdallo/deps-bin.svg)](https://clojars.org/com.github.ericdallo/deps-bin) 2 | 3 | # deps-bin 4 | 5 | A Clojure library that builds an executable containing a embedded jar inside. 6 | This library is a `deps.edn` only alternative for [lein-binplus](https://github.com/BrunoBonacci/lein-binplus). It will create a executable file that exec `java -jar` with the provided jvm options, so you still need `java` on your `$PATH`. 7 | 8 | On MS-Windows, the executable has a `.bat` extension, since technically it is a script calling java with an embedded jar file. 9 | 10 | ## Usage 11 | 12 | To generate a executable, simply merge: 13 | 14 | ```clojure 15 | {:bin {:extra-deps {com.github.ericdallo/deps-bin {:mvn/version "RELEASE"}} 16 | :exec-fn deps-bin.deps-bin/bin 17 | :exec-args {:jar "my-jar.jar" 18 | :name "my-bin"}}} 19 | ``` 20 | 21 | into your deps.edn, and build with: 22 | 23 | ``` bash 24 | $ clojure -X:bin 25 | ``` 26 | 27 | and it should generate a executable that you can run with: 28 | 29 | ``` bash 30 | ./my-bin 31 | ``` 32 | 33 | In this example, it expects that you have a jar `my-jar.jar`, you can generate it with [depstar](https://github.com/seancorfield/depstar), for example: 34 | 35 | ``` bash 36 | $ clojure -X:jar && clojure -X:bin 37 | ``` 38 | 39 | ## Other options 40 | 41 | - `:help` true -- show this help (and exit) 42 | - `:jar` sym-or-str -- specify the source name of the JAR file 43 | - `:name` sym-or-str -- specify the name of the generated BIN file 44 | - `:skip-realign` true -- if should skip byte alignment repair. 45 | - `:jvm-opts` [strs] -- optional list of JVM options to use during bin executing 46 | - `:platforms` [kws] -- optional list of platforms for which to emit bins, valid kws: :unix, :windows, defaults to system platform 47 | 48 | ## Contribution 49 | 50 | Contributions are very welcome, please open an issue or a pull request if inspired :) 51 | 52 | # Support 53 | 54 | Consider support the work of this project [here](https://github.com/sponsors/ericdallo) ❤️ 55 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | jar 5 | com.github.ericdallo 6 | deps-bin 7 | 1.0.0 8 | deps-bin 9 | 10 | 11 | Eclipse Public License 2.0 12 | https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt 13 | 14 | 15 | 16 | 17 | org.clojure 18 | clojure 19 | 1.11.0-rc1 20 | 21 | 22 | org.clojure 23 | tools.logging 24 | 1.2.4 25 | 26 | 27 | de.ubercode.clostache 28 | clostache 29 | 1.4.0 30 | 31 | 32 | org.apache.logging.log4j 33 | log4j-core 34 | 2.17.2 35 | 36 | 37 | org.slf4j 38 | slf4j-simple 39 | 1.7.36 40 | 41 | 42 | clj-zip-meta 43 | clj-zip-meta 44 | 0.1.3 45 | 46 | 47 | org.clojure 48 | clojure 49 | 50 | 51 | 52 | 53 | me.raynes 54 | fs 55 | 1.4.6 56 | 57 | 58 | 59 | src 60 | 61 | 62 | 63 | clojars 64 | https://repo.clojars.org/ 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /test/deps_bin/impl/bin_test.clj: -------------------------------------------------------------------------------- 1 | (ns deps-bin.impl.bin-test 2 | (:require 3 | [babashka.fs :as fs] 4 | [babashka.process :as p] 5 | [clojure.string :as str] 6 | [clojure.test :refer [deftest testing is]] 7 | [deps-bin.impl.bin :as bin] 8 | [clj-zip-meta.core :as clj-zip-meta])) 9 | 10 | (deftest build-bin-as-main 11 | (testing "printing help" 12 | (is (= {:success false 13 | :reason :help} 14 | (bin/build-bin {:help true})))) 15 | (testing "when :jar is not provided" 16 | (is (= {:success false 17 | :reason :no-jar} 18 | (bin/build-bin {})))) 19 | (testing "when :name is not provided" 20 | (is (= {:success false 21 | :reason :no-name} 22 | (bin/build-bin {:jar "some-jar.jar"})))) 23 | (testing "when :name and :jar is provided" 24 | (with-redefs [bin/write-bin (constantly nil) 25 | clj-zip-meta/repair-zip-with-preamble-bytes (constantly nil)] 26 | (is (= {:success true 27 | :bin-path (str (fs/canonicalize (cond-> "some-bin" (fs/windows?) (str ".bat"))))} 28 | (bin/build-bin {:jar "some-jar.jar" 29 | :name "some-bin"}))))) 30 | (testing "with :platforms provided" 31 | (with-redefs [bin/write-bin (constantly nil) 32 | clj-zip-meta/repair-zip-with-preamble-bytes (constantly nil)] 33 | (is (= {:success true 34 | :bin-paths [(str (fs/canonicalize "some-bin.bat")) 35 | (str (fs/canonicalize "some-bin"))]} 36 | (bin/build-bin {:jar "some-jar.jar" 37 | :name "some-bin" 38 | :platforms ["foo" :windows :unix :unix]}))))) 39 | (testing "with invalid :platforms, default to system platform" 40 | (with-redefs [bin/write-bin (constantly nil) 41 | clj-zip-meta/repair-zip-with-preamble-bytes (constantly nil)] 42 | (is (= {:success true 43 | :bin-path (str (fs/canonicalize (cond-> "some-bin" (fs/windows?) (str ".bat"))))} 44 | (bin/build-bin {:jar "some-jar.jar" 45 | :name "some-bin" 46 | :platforms [:bad-platform]})))))) 47 | 48 | (deftest binary 49 | (let [test-jar "test/test-jar/testjar.jar"] 50 | 51 | (testing "jvm opts passing" 52 | (fs/with-temp-dir 53 | [temp-dir {}] 54 | (let [bin-path (str (fs/path temp-dir "testbin")) 55 | 56 | {:keys [success bin-path] :as build} 57 | (bin/build-bin {:jar test-jar 58 | :name bin-path 59 | :jvm-opts ["-Dxyz=5" "-Dzyx=0"] 60 | :skip-realign true})] 61 | (is success build) 62 | (let [{:keys [out]} (-> (p/process [bin-path "xyz" "zyx"] {:out :string :err :inherit}) 63 | p/check)] 64 | (is (= [":prop xyz :v 5" ":prop zyx :v 0"] 65 | (str/split-lines out))))))) 66 | 67 | (testing "return error value in case of error" 68 | (fs/with-temp-dir 69 | [temp-dir {}] 70 | (let [bin-path (str (fs/path temp-dir "testbin")) 71 | {:keys [success bin-path] :as build} (bin/build-bin {:jar test-jar 72 | :name bin-path 73 | :jvm-opts ["-Dtestjar.return=7"] 74 | :skip-realign true})] 75 | (is success build) 76 | (let [{:keys [exit out]} @(p/process [bin-path "testjar.return"] {:out :string :err :ihnerit})] 77 | (is (= [":prop testjar.return :v 7"] 78 | (str/split-lines out))) 79 | (is (= 7 exit)))))))) 80 | -------------------------------------------------------------------------------- /src/deps_bin/impl/bin.clj: -------------------------------------------------------------------------------- 1 | (ns deps-bin.impl.bin 2 | (:require 3 | [clj-zip-meta.core :refer [repair-zip-with-preamble-bytes]] 4 | [clojure.java.io :as io] 5 | [clojure.string :as str] 6 | [clostache.parser :refer [render]] 7 | [me.raynes.fs :as fs])) 8 | 9 | (def ^:private allowed-platforms 10 | #{:unix :windows}) 11 | 12 | (defn ^:private system-platform [] 13 | (if (str/starts-with? (System/getProperty "os.name") "Windows") 14 | :windows 15 | :unix)) 16 | 17 | (defn ^:private platform-filename [platform name] 18 | (case platform 19 | :windows (str name ".bat") 20 | :unix name)) 21 | 22 | (defn ^:private preamble-template [platform] 23 | (case platform 24 | :unix "#!/usr/bin/env bash\nexec java {{{jvm-opts}}} -jar $0 \"$@\"\ngoto :eof\n" 25 | :windows "@echo off\r\njava {{{jvm-opts}}} -jar \"%~f0\" %*\r\nexit /b %errorlevel%\r\n")) 26 | 27 | (defn ^:private print-help [] 28 | (println "library usage:") 29 | (println " clojure -X:bin :jar MyProject.jar :name myBin") 30 | (println "options:") 31 | (println " :help true -- show this help (and exit)") 32 | (println " :jar sym-or-str -- specify the source name of the JAR file") 33 | (println " :name sym-or-str -- specify the name of the generated BIN file") 34 | (println " :skip-realign true -- whether should skip byte alignment repair") 35 | (println " :jvm-opts [strs] -- optional list of JVM options to use during bin executing") 36 | (println " :platforms [kws] -- optional list of platforms for which to emit bins,") 37 | (println " valid kws: :unix, :windows, defaults to system platform")) 38 | 39 | (defn ^:private preamble [platform {:keys [jvm-opts] :as options}] 40 | (-> (preamble-template platform) 41 | (render (merge options {:jvm-opts (str/join " " jvm-opts)})) 42 | (str/replace #"\\\$" "\\$"))) 43 | 44 | (defn ^:private write-bin [bin-file jar preamble] 45 | (io/make-parents bin-file) 46 | (with-open [bin (io/output-stream bin-file)] 47 | (.write bin (.getBytes preamble)) 48 | (io/copy (fs/file jar) bin)) 49 | (fs/chmod "+x" bin-file)) 50 | 51 | (defn ^:private coerce-platforms [coll] 52 | (if-some [platforms (->> coll (keep allowed-platforms) distinct not-empty)] 53 | platforms 54 | [(system-platform)])) 55 | 56 | (defn emit-bin! 57 | "Writes bin, optionally re-aligns it and returns its canonical path." 58 | [platform {:keys [jar name skip-realign] :as options}] 59 | (let [name (platform-filename platform name) 60 | bin-file (io/file name) 61 | preamble (preamble platform options)] 62 | (println "Creating" (clojure.core/name platform) "standalone executable:" name) 63 | (write-bin name jar preamble) 64 | (when-not skip-realign 65 | (println "Re-aligning zip offsets...") 66 | (repair-zip-with-preamble-bytes bin-file)) 67 | (.getCanonicalPath bin-file))) 68 | 69 | (defn build-bin 70 | "Core functionality for deps-bin. Can be called from a REPL or as a library. 71 | Returns a hash map containing: 72 | * `:success` -- `true` or `false` 73 | * `:bin-path` -- On `:success`, it is the abs path to the binary. 74 | * `:bin-paths` -- Same as above, but when building for multiple platforms. 75 | * `:reason` -- if `:success` is `false`, this explains what failed: 76 | * `:help` -- help was requested 77 | * `:no-jar` -- the `:jar` option was missing 78 | * `:no-name` -- the `:name` option was missing 79 | Additional detail about success and failure is also logged." 80 | [{:keys [help jar name platforms] :as options}] 81 | (cond 82 | 83 | help 84 | {:success false :reason :help} 85 | 86 | (not jar) 87 | {:success false :reason :no-jar} 88 | 89 | (not name) 90 | {:success false :reason :no-name} 91 | 92 | :else 93 | (let [platforms (coerce-platforms platforms) 94 | emitted-paths (mapv #(emit-bin! % options) platforms)] 95 | (if (= (count emitted-paths) 1) 96 | {:success true :bin-path (first emitted-paths)} 97 | {:success true :bin-paths emitted-paths})))) 98 | 99 | (defn build-bin-as-main 100 | "Command-line entry point for `-X` (and legacy `-M`) that performs 101 | checking on arguments, offers help, and calls `(System/exit 1)` if 102 | the BIN-building process encounters errors." 103 | [options] 104 | (let [result (build-bin options)] 105 | (if (:success result) 106 | (shutdown-agents) 107 | (do 108 | (case (:reason result) 109 | :help (print-help) 110 | :no-jar (print-help) 111 | :no-name (print-help)) 112 | (System/exit 1))))) 113 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 2.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 4 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION 5 | OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial content 12 | Distributed under this Agreement, and 13 | 14 | b) in the case of each subsequent Contributor: 15 | i) changes to the Program, and 16 | ii) additions to the Program; 17 | where such changes and/or additions to the Program originate from 18 | and are Distributed by that particular Contributor. A Contribution 19 | "originates" from a Contributor if it was added to the Program by 20 | such Contributor itself or anyone acting on such Contributor's behalf. 21 | Contributions do not include changes or additions to the Program that 22 | are not Modified Works. 23 | 24 | "Contributor" means any person or entity that Distributes the Program. 25 | 26 | "Licensed Patents" mean patent claims licensable by a Contributor which 27 | are necessarily infringed by the use or sale of its Contribution alone 28 | or when combined with the Program. 29 | 30 | "Program" means the Contributions Distributed in accordance with this 31 | Agreement. 32 | 33 | "Recipient" means anyone who receives the Program under this Agreement 34 | or any Secondary License (as applicable), including Contributors. 35 | 36 | "Derivative Works" shall mean any work, whether in Source Code or other 37 | form, that is based on (or derived from) the Program and for which the 38 | editorial revisions, annotations, elaborations, or other modifications 39 | represent, as a whole, an original work of authorship. 40 | 41 | "Modified Works" shall mean any work in Source Code or other form that 42 | results from an addition to, deletion from, or modification of the 43 | contents of the Program, including, for purposes of clarity any new file 44 | in Source Code form that contains any contents of the Program. Modified 45 | Works shall not include works that contain only declarations, 46 | interfaces, types, classes, structures, or files of the Program solely 47 | in each case in order to link to, bind by name, or subclass the Program 48 | or Modified Works thereof. 49 | 50 | "Distribute" means the acts of a) distributing or b) making available 51 | in any manner that enables the transfer of a copy. 52 | 53 | "Source Code" means the form of a Program preferred for making 54 | modifications, including but not limited to software source code, 55 | documentation source, and configuration files. 56 | 57 | "Secondary License" means either the GNU General Public License, 58 | Version 2.0, or any later versions of that license, including any 59 | exceptions or additional permissions as identified by the initial 60 | Contributor. 61 | 62 | 2. GRANT OF RIGHTS 63 | 64 | a) Subject to the terms of this Agreement, each Contributor hereby 65 | grants Recipient a non-exclusive, worldwide, royalty-free copyright 66 | license to reproduce, prepare Derivative Works of, publicly display, 67 | publicly perform, Distribute and sublicense the Contribution of such 68 | Contributor, if any, and such Derivative Works. 69 | 70 | b) Subject to the terms of this Agreement, each Contributor hereby 71 | grants Recipient a non-exclusive, worldwide, royalty-free patent 72 | license under Licensed Patents to make, use, sell, offer to sell, 73 | import and otherwise transfer the Contribution of such Contributor, 74 | if any, in Source Code or other form. This patent license shall 75 | apply to the combination of the Contribution and the Program if, at 76 | the time the Contribution is added by the Contributor, such addition 77 | of the Contribution causes such combination to be covered by the 78 | Licensed Patents. The patent license shall not apply to any other 79 | combinations which include the Contribution. No hardware per se is 80 | licensed hereunder. 81 | 82 | c) Recipient understands that although each Contributor grants the 83 | licenses to its Contributions set forth herein, no assurances are 84 | provided by any Contributor that the Program does not infringe the 85 | patent or other intellectual property rights of any other entity. 86 | Each Contributor disclaims any liability to Recipient for claims 87 | brought by any other entity based on infringement of intellectual 88 | property rights or otherwise. As a condition to exercising the 89 | rights and licenses granted hereunder, each Recipient hereby 90 | assumes sole responsibility to secure any other intellectual 91 | property rights needed, if any. For example, if a third party 92 | patent license is required to allow Recipient to Distribute the 93 | Program, it is Recipient's responsibility to acquire that license 94 | before distributing the Program. 95 | 96 | d) Each Contributor represents that to its knowledge it has 97 | sufficient copyright rights in its Contribution, if any, to grant 98 | the copyright license set forth in this Agreement. 99 | 100 | e) Notwithstanding the terms of any Secondary License, no 101 | Contributor makes additional grants to any Recipient (other than 102 | those set forth in this Agreement) as a result of such Recipient's 103 | receipt of the Program under the terms of a Secondary License 104 | (if permitted under the terms of Section 3). 105 | 106 | 3. REQUIREMENTS 107 | 108 | 3.1 If a Contributor Distributes the Program in any form, then: 109 | 110 | a) the Program must also be made available as Source Code, in 111 | accordance with section 3.2, and the Contributor must accompany 112 | the Program with a statement that the Source Code for the Program 113 | is available under this Agreement, and informs Recipients how to 114 | obtain it in a reasonable manner on or through a medium customarily 115 | used for software exchange; and 116 | 117 | b) the Contributor may Distribute the Program under a license 118 | different than this Agreement, provided that such license: 119 | i) effectively disclaims on behalf of all other Contributors all 120 | warranties and conditions, express and implied, including 121 | warranties or conditions of title and non-infringement, and 122 | implied warranties or conditions of merchantability and fitness 123 | for a particular purpose; 124 | 125 | ii) effectively excludes on behalf of all other Contributors all 126 | liability for damages, including direct, indirect, special, 127 | incidental and consequential damages, such as lost profits; 128 | 129 | iii) does not attempt to limit or alter the recipients' rights 130 | in the Source Code under section 3.2; and 131 | 132 | iv) requires any subsequent distribution of the Program by any 133 | party to be under a license that satisfies the requirements 134 | of this section 3. 135 | 136 | 3.2 When the Program is Distributed as Source Code: 137 | 138 | a) it must be made available under this Agreement, or if the 139 | Program (i) is combined with other material in a separate file or 140 | files made available under a Secondary License, and (ii) the initial 141 | Contributor attached to the Source Code the notice described in 142 | Exhibit A of this Agreement, then the Program may be made available 143 | under the terms of such Secondary Licenses, and 144 | 145 | b) a copy of this Agreement must be included with each copy of 146 | the Program. 147 | 148 | 3.3 Contributors may not remove or alter any copyright, patent, 149 | trademark, attribution notices, disclaimers of warranty, or limitations 150 | of liability ("notices") contained within the Program from any copy of 151 | the Program which they Distribute, provided that Contributors may add 152 | their own appropriate notices. 153 | 154 | 4. COMMERCIAL DISTRIBUTION 155 | 156 | Commercial distributors of software may accept certain responsibilities 157 | with respect to end users, business partners and the like. While this 158 | license is intended to facilitate the commercial use of the Program, 159 | the Contributor who includes the Program in a commercial product 160 | offering should do so in a manner which does not create potential 161 | liability for other Contributors. Therefore, if a Contributor includes 162 | the Program in a commercial product offering, such Contributor 163 | ("Commercial Contributor") hereby agrees to defend and indemnify every 164 | other Contributor ("Indemnified Contributor") against any losses, 165 | damages and costs (collectively "Losses") arising from claims, lawsuits 166 | and other legal actions brought by a third party against the Indemnified 167 | Contributor to the extent caused by the acts or omissions of such 168 | Commercial Contributor in connection with its distribution of the Program 169 | in a commercial product offering. The obligations in this section do not 170 | apply to any claims or Losses relating to any actual or alleged 171 | intellectual property infringement. In order to qualify, an Indemnified 172 | Contributor must: a) promptly notify the Commercial Contributor in 173 | writing of such claim, and b) allow the Commercial Contributor to control, 174 | and cooperate with the Commercial Contributor in, the defense and any 175 | related settlement negotiations. The Indemnified Contributor may 176 | participate in any such claim at its own expense. 177 | 178 | For example, a Contributor might include the Program in a commercial 179 | product offering, Product X. That Contributor is then a Commercial 180 | Contributor. If that Commercial Contributor then makes performance 181 | claims, or offers warranties related to Product X, those performance 182 | claims and warranties are such Commercial Contributor's responsibility 183 | alone. Under this section, the Commercial Contributor would have to 184 | defend claims against the other Contributors related to those performance 185 | claims and warranties, and if a court requires any other Contributor to 186 | pay any damages as a result, the Commercial Contributor must pay 187 | those damages. 188 | 189 | 5. NO WARRANTY 190 | 191 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 192 | PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" 193 | BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 194 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF 195 | TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 196 | PURPOSE. Each Recipient is solely responsible for determining the 197 | appropriateness of using and distributing the Program and assumes all 198 | risks associated with its exercise of rights under this Agreement, 199 | including but not limited to the risks and costs of program errors, 200 | compliance with applicable laws, damage to or loss of data, programs 201 | or equipment, and unavailability or interruption of operations. 202 | 203 | 6. DISCLAIMER OF LIABILITY 204 | 205 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 206 | PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS 207 | SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST 209 | PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 210 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 211 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 212 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE 213 | POSSIBILITY OF SUCH DAMAGES. 214 | 215 | 7. GENERAL 216 | 217 | If any provision of this Agreement is invalid or unenforceable under 218 | applicable law, it shall not affect the validity or enforceability of 219 | the remainder of the terms of this Agreement, and without further 220 | action by the parties hereto, such provision shall be reformed to the 221 | minimum extent necessary to make such provision valid and enforceable. 222 | 223 | If Recipient institutes patent litigation against any entity 224 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 225 | Program itself (excluding combinations of the Program with other software 226 | or hardware) infringes such Recipient's patent(s), then such Recipient's 227 | rights granted under Section 2(b) shall terminate as of the date such 228 | litigation is filed. 229 | 230 | All Recipient's rights under this Agreement shall terminate if it 231 | fails to comply with any of the material terms or conditions of this 232 | Agreement and does not cure such failure in a reasonable period of 233 | time after becoming aware of such noncompliance. If all Recipient's 234 | rights under this Agreement terminate, Recipient agrees to cease use 235 | and distribution of the Program as soon as reasonably practicable. 236 | However, Recipient's obligations under this Agreement and any licenses 237 | granted by Recipient relating to the Program shall continue and survive. 238 | 239 | Everyone is permitted to copy and distribute copies of this Agreement, 240 | but in order to avoid inconsistency the Agreement is copyrighted and 241 | may only be modified in the following manner. The Agreement Steward 242 | reserves the right to publish new versions (including revisions) of 243 | this Agreement from time to time. No one other than the Agreement 244 | Steward has the right to modify this Agreement. The Eclipse Foundation 245 | is the initial Agreement Steward. The Eclipse Foundation may assign the 246 | responsibility to serve as the Agreement Steward to a suitable separate 247 | entity. Each new version of the Agreement will be given a distinguishing 248 | version number. The Program (including Contributions) may always be 249 | Distributed subject to the version of the Agreement under which it was 250 | received. In addition, after a new version of the Agreement is published, 251 | Contributor may elect to Distribute the Program (including its 252 | Contributions) under the new version. 253 | 254 | Except as expressly stated in Sections 2(a) and 2(b) above, Recipient 255 | receives no rights or licenses to the intellectual property of any 256 | Contributor under this Agreement, whether expressly, by implication, 257 | estoppel or otherwise. All rights in the Program not expressly granted 258 | under this Agreement are reserved. Nothing in this Agreement is intended 259 | to be enforceable by any entity that is not a Contributor or Recipient. 260 | No third-party beneficiary rights are created under this Agreement. 261 | 262 | Exhibit A - Form of Secondary Licenses Notice 263 | 264 | "This Source Code may also be made available under the following 265 | Secondary Licenses when the conditions for such availability set forth 266 | in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), 267 | version(s), and exceptions or additional permissions here}." 268 | 269 | Simply including a copy of this Agreement, including this Exhibit A 270 | is not sufficient to license the Source Code under Secondary Licenses. 271 | 272 | If it is not possible or desirable to put the notice in a particular 273 | file, then You may include the notice in a location (such as a LICENSE 274 | file in a relevant directory) where a recipient would be likely to 275 | look for such a notice. 276 | 277 | You may add additional accurate notices of copyright ownership. 278 | --------------------------------------------------------------------------------