├── resources
└── VERSION
├── samples
├── test.edn
└── test.json
├── tests.edn
├── .gitignore
├── src
├── app
│ ├── json.clj
│ ├── edn.clj
│ ├── json
│ │ └── bb.clj
│ └── main.clj
└── tabl
│ └── format
│ ├── k8s.clj
│ └── markdown.clj
├── dev
└── fiddle
│ ├── main.clj
│ └── formats.clj
├── CHANGES.md
├── scripts
└── compile
├── pod_test.clj
├── deps.edn
├── test
└── app
│ └── main_test.clj
├── README.md
└── LICENSE
/resources/VERSION:
--------------------------------------------------------------------------------
1 | 0.4.0-SNAPSHOT
2 |
--------------------------------------------------------------------------------
/samples/test.edn:
--------------------------------------------------------------------------------
1 | {:foo "bar", :baz 4}
2 | {:foo "oof", :baz 4}
3 |
--------------------------------------------------------------------------------
/samples/test.json:
--------------------------------------------------------------------------------
1 | {"foo":"bar","baz":4}
2 | {"foo":"oof","baz":4}
3 |
--------------------------------------------------------------------------------
/tests.edn:
--------------------------------------------------------------------------------
1 | #kaocha/v1
2 | {:reporter [kaocha.report/documentation]}
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .cpcache/
2 | .rebel_readline_history
3 | .socket-port
4 | .nrepl-port
5 | classes/
6 | .clj-kondo/.cache/
7 |
8 | tabl
9 | tabl.build_artifacts.txt
10 |
--------------------------------------------------------------------------------
/src/app/json.clj:
--------------------------------------------------------------------------------
1 | (ns app.json
2 | (:require [app.json.bb :as json.bb])
3 | (:import
4 | [com.fasterxml.jackson.core JsonParser]))
5 |
6 | (defn json-seq
7 | [reader]
8 | (lazy-seq
9 | (if-let [obj (json.bb/parse-json reader true)]
10 | (cons obj (json-seq reader))
11 | (.close ^JsonParser reader))))
12 |
13 | (defn reader->seq
14 | [reader]
15 | (-> (json.bb/json-parser reader)
16 | (json-seq)))
17 |
--------------------------------------------------------------------------------
/dev/fiddle/main.clj:
--------------------------------------------------------------------------------
1 | (ns fiddle.main
2 | (:require
3 | [clojure.tools.cli :refer [parse-opts]]
4 |
5 | [app.main :as main]))
6 |
7 | (defn h
8 | [& args]
9 | (let [parsed (parse-opts args main/cli-options)]
10 | (some->> (main/find-errors parsed)
11 | (main/print-errors parsed))))
12 |
13 |
14 | #_(h)
15 | #_(h "-h")
16 | #_(h "-x" "-h")
17 | #_(h "-f" "not-found.edn" "-e")
18 | #_(h "-f" "not-found.json" "-j")
19 |
--------------------------------------------------------------------------------
/src/tabl/format/k8s.clj:
--------------------------------------------------------------------------------
1 | (ns tabl.format.k8s
2 | (:require [clojure.string :as string]
3 | [doric.core :refer [aligned-td aligned-th]]))
4 |
5 | (defn th
6 | [col]
7 | (aligned-th (assoc col :title-align :left)))
8 |
9 | (def td aligned-td)
10 |
11 | (defn render [table]
12 | (concat [(str (string/join " " (map string/upper-case (first table))))]
13 | (for [tr (rest table)]
14 | (str (string/join " " tr)))))
15 |
--------------------------------------------------------------------------------
/src/app/edn.clj:
--------------------------------------------------------------------------------
1 | (ns app.edn
2 | (:require [clojure.edn :as edn]
3 | [clojure.java.io :as io])
4 | (:import
5 | [java.io PushbackReader]))
6 |
7 | (defn edn-seq
8 | [reader]
9 | (lazy-seq
10 | (if-let [obj (edn/read {:eof nil} reader)]
11 | (cons obj (edn-seq reader))
12 | (.close ^PushbackReader reader))))
13 |
14 | (defn reader->seq
15 | [reader]
16 | (-> (io/reader reader)
17 | (PushbackReader.)
18 | (edn-seq)))
19 |
--------------------------------------------------------------------------------
/src/app/json/bb.clj:
--------------------------------------------------------------------------------
1 | (ns app.json.bb
2 | (:require [cheshire.factory :as factory]
3 | [cheshire.parse :as cheshire-parse])
4 | (:import [com.fasterxml.jackson.core JsonFactory]
5 | [java.io Reader]))
6 |
7 | (defn json-parser [reader]
8 | (.createParser ^JsonFactory factory/json-factory
9 | ^Reader reader))
10 |
11 | (defn parse-json [json-reader keywordize]
12 | (cheshire-parse/parse-strict json-reader keywordize nil nil))
13 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | # v0.3.0
2 |
3 | Features:
4 |
5 | * Add md (markdown) and k8s style table formatting modes
6 |
7 | Fixes:
8 |
9 | * Compatibility with latest Babashka pod protocol
10 |
11 | # v0.2.0
12 |
13 | Features:
14 |
15 | * Add more table rendering modes, ability to choose
16 | * Add pod support for fancy and doric functions
17 |
18 | # v0.0.0-pre2
19 |
20 | Fixes:
21 |
22 | * When no file is specified, assume stdin even if not yet ready.
23 |
24 | # v0.0.0-pre1
25 |
26 | Initial version.
27 |
28 | * Handlers JSON and EDN input
29 |
--------------------------------------------------------------------------------
/scripts/compile:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | app_name=tabl
4 |
5 | rm -rf classes
6 | mkdir classes
7 | clojure -e "(compile 'app.main)"
8 |
9 | if [ -z "$NATIVE_IMAGE" ]; then
10 | echo 'Please set $NATIVE_IMAGE'
11 | exit 1
12 | fi
13 |
14 | $NATIVE_IMAGE \
15 | -cp $(clojure -Spath):classes \
16 | -H:Name=$app_name \
17 | -H:+ReportExceptionStackTraces \
18 | -H:IncludeResources=VERSION \
19 | --initialize-at-build-time \
20 | --report-unsupported-elements-at-runtime \
21 | --verbose \
22 | --no-fallback \
23 | --no-server \
24 | "-J-Xmx3g" \
25 | app.main
26 |
--------------------------------------------------------------------------------
/pod_test.clj:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bb
2 |
3 | (require '[babashka.pods :as pods])
4 | (pods/load-pod "./tabl")
5 | ; (pods/load-pod ["clojure" "-M" "-m" "app.main"])
6 |
7 | (require '[pod.tabl.fancy :as fancy])
8 | (require '[pod.tabl.doric :as doric])
9 |
10 | (def data
11 | [{:foo 1 :bar 2}
12 | {:foo 2 :bar 3}])
13 |
14 | (println "fancy")
15 | (fancy/print-table data)
16 | (println)
17 |
18 | (def doric-styles
19 | ['doric.csv
20 | 'doric.html
21 | 'doric.org
22 | 'doric.raw
23 | 'tabl.format.k8s
24 | 'tabl.format.markdown])
25 |
26 | (doseq [t doric-styles]
27 | (println t)
28 | (doric/print-table {:format t} data)
29 | (println))
30 |
--------------------------------------------------------------------------------
/src/tabl/format/markdown.clj:
--------------------------------------------------------------------------------
1 | (ns tabl.format.markdown
2 | (:require [clojure.string :as string]
3 | [doric.core :refer [aligned-td aligned-th]]))
4 |
5 | (def th aligned-th)
6 |
7 | (def td aligned-td)
8 |
9 | (defn render [table]
10 | (let [spacer (str "-"
11 | (string/join "-|-"
12 | (map #(apply str (repeat (.length ^java.lang.String %) "-"))
13 | (first table)))
14 | "-")]
15 | (concat [(str " " (string/join " | " (first table)) " ")
16 | spacer]
17 | (for [tr (rest table)]
18 | (str " " (string/join " | " tr) " ")))))
19 |
--------------------------------------------------------------------------------
/deps.edn:
--------------------------------------------------------------------------------
1 | {:aliases
2 | {:repl
3 | {:extra-paths ["dev"]
4 | :extra-deps {io.github.justone/cljdev {:git/sha "dc9171f9f091e476a734714d128704876c7fa679"}}
5 | :exec-fn cljdev.repl/start}
6 | :test
7 | {:extra-paths ["dev" "test"]
8 | :extra-deps {lambdaisland/kaocha {:mvn/version "1.70.1086"}}
9 | :main-opts ["-m" "kaocha.runner"]}}
10 |
11 | :deps
12 | {org.clojure/clojure {:mvn/version "1.11.1"}
13 | org.endot/bb-pod-racer {:mvn/version "0.1.9"}
14 | cheshire/cheshire {:mvn/version "5.11.0"}
15 | doric/doric {:git/url "https://github.com/justone/doric.git"
16 | :sha "43e9b7027902c2239fc7084ee7325262cf362ba0"}
17 | fancy/fancy {:mvn/version "0.2.3"}
18 | org.clojure/tools.cli {:mvn/version "1.0.214"}}
19 |
20 | :paths ["src" "resources"]}
21 |
--------------------------------------------------------------------------------
/dev/fiddle/formats.clj:
--------------------------------------------------------------------------------
1 | (ns fiddle.formats
2 | {:clj-kondo/config '{:linters {:unused-namespace {:level :off}}}}
3 | (:require
4 | [clojure.java.io :as io]
5 |
6 | [app.edn :as edn]
7 | [app.json :as json]
8 |
9 | [fancy.table :as table]
10 | [doric.core :as doric]
11 | ))
12 |
13 | #_(->> (io/reader "test.json")
14 | json/reader->seq
15 | (table/render-table)
16 | (run! println))
17 |
18 | #_(->> (io/reader "test.edn")
19 | edn/reader->seq
20 | (table/render-table)
21 | (run! println))
22 |
23 | (def data
24 | [{"foo" 1, "really long field name" 2}
25 | {"foo" "really long field value", "really long field name" 1}
26 | {"foo" 3, "really long field name" 0}])
27 |
28 | #_(println (doric/table {:format 'app.format.markdown} data))
29 | #_(println (doric/table {:format 'app.format.k8s} data))
30 |
--------------------------------------------------------------------------------
/test/app/main_test.clj:
--------------------------------------------------------------------------------
1 | (ns app.main-test
2 | (:require [app.main :as main]
3 | [clojure.java.io :as io]
4 | [clojure.string :as string]
5 | [clojure.test :refer [deftest is]]
6 | [clojure.tools.cli :refer [parse-opts]]))
7 |
8 | (defn errors-in
9 | [& args]
10 | (main/find-errors (parse-opts args main/cli-options)))
11 |
12 | (deftest errors
13 | (is (= {:exit 0}
14 | (errors-in "-h")))
15 | (is (= {:exit 0
16 | :plain true
17 | :message (string/trim (slurp (io/resource "VERSION")))}
18 | (errors-in "--version")))
19 | (is (= {:exit 1
20 | :message "please specify which format"}
21 | (errors-in)))
22 | (is (= {:exit 1
23 | :message "Unknown option: \"-x\""}
24 | (errors-in "-x")))
25 | (is (= {:exit 1
26 | :message "file not found: samples/not-found-test.edn"}
27 | (errors-in "-e" "-f" "samples/not-found-test.edn")))
28 | )
29 |
30 | (deftest run
31 | (is (= (str " :baz | :foo \n"
32 | "------|------\n"
33 | " 4 | bar \n"
34 | " 4 | oof \n")
35 | (with-out-str (main/-main "-e" "-f" "samples/test.edn"))))
36 | (is (= (str "|-----+-----|\n"
37 | "| Foo | Baz |\n"
38 | "|-----+-----|\n"
39 | "| bar | 4 |\n"
40 | "| oof | 4 |\n"
41 | "|-----+-----|\n")
42 | (with-out-str (main/-main "-e" "-m" "org" "-f" "samples/test.edn"))))
43 | (is (= (str "Foo Baz\n"
44 | "bar 4 \n"
45 | "oof 4 \n")
46 | (with-out-str (main/-main "-e" "-m" "raw" "-f" "samples/test.edn"))))
47 | (is (= (str "Foo,Baz\n"
48 | "bar,4\n"
49 | "oof,4\n")
50 | (with-out-str (main/-main "-e" "-m" "csv" "-f" "samples/test.edn"))))
51 | (is (= (str "
\n"
52 | "| Foo | Baz |
\n"
53 | "| bar | 4 |
\n"
54 | "| oof | 4 |
\n"
55 | "
\n")
56 | (with-out-str (main/-main "-e" "-m" "html" "-f" "samples/test.edn"))))
57 | (is (= (str "FOO BAZ\n"
58 | "bar 4 \n"
59 | "oof 4 \n")
60 | (with-out-str (main/-main "-e" "-m" "k8s" "-f" "samples/test.edn"))))
61 | (is (= (str " Foo | Baz \n"
62 | "-----|-----\n"
63 | " bar | 4 \n"
64 | " oof | 4 \n")
65 | (with-out-str (main/-main "-e" "-m" "md" "-f" "samples/test.edn"))))
66 | )
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tabl
2 |
3 | Make tables from data in your terminal.
4 |
5 | # Install
6 |
7 | Download the latest from the [releases page](https://github.com/justone/tabl/releases).
8 |
9 | # Usage
10 |
11 | This small utility takes JSON or EDN files with multiple maps and creates a
12 | table for ease of viewing. For example:
13 |
14 | ```
15 | $ cat test.json
16 | {"foo":"bar","baz":4}
17 | {"foo":"oof","baz":4}
18 | $ cat test.json | tabl -j
19 | :baz | :foo
20 | ------|------
21 | 4 | bar
22 | 4 | oof
23 | ```
24 |
25 | There are several table rendering modes available:
26 |
27 | | library | modes |
28 | |----------------------------------------------------|---------------------|
29 | | [fancy](https://github.com/chbrown/fancy-clojure/) | fancy |
30 | | [doric](https://github.com/joegallo/doric) | org, csv, html, raw |
31 | | built-in | md, k8s |
32 |
33 |
34 | ```
35 | $ cat test.json | tabl -j -m org
36 | |-----+-----|
37 | | Foo | Baz |
38 | |-----+-----|
39 | | bar | 4 |
40 | | oof | 4 |
41 | |-----+-----|
42 | ```
43 |
44 | # [Babashka pod](https://github.com/babashka/babashka.pods) support
45 |
46 | The following namespaces and functions are exposed via the pod interface:
47 |
48 | * `pod.tabl.fancy` (see [here](https://cljdoc.org/d/fancy/fancy/0.2.3/api/fancy.table) for more information)
49 | * `render-table` - returns table as a list of strings
50 | * `print-table` - prints a table based on data
51 | * `pod.tabl.doric`
52 | * `table` - returns table as a list of strings (see [here](https://github.com/joegallo/doric) for more information)
53 | * `print-table` - prints a table based on data
54 |
55 | Example:
56 |
57 | ```
58 | #!/usr/bin/env bb
59 |
60 | (require '[babashka.pods :as pods])
61 | (pods/load-pod "tabl")
62 |
63 | (require '[pod.tabl.fancy :as fancy])
64 | (require '[pod.tabl.doric :as doric])
65 |
66 | ;;
67 | (fancy/print-table [{:foo 1 :bar 2} {:foo 2 :bar 3}])
68 | (doric/print-table [{:foo 1 :bar 2} {:foo 2 :bar 3}])
69 | (doric/print-table {:format 'doric.org} [{:foo 1 :bar 2} {:foo 2 :bar 3}])
70 | ```
71 |
72 | See [pod_test.clj](./pod_test.clj) for more examples.
73 |
74 | # Development
75 |
76 | Not quite ready yet. This depends on a soon-to-be-released library.
77 |
78 | Thank you to [Michiel Borkent](https://github.com/borkdude) and
79 | [Lee Read](https://github.com/lread) for spearheading the GraalVM efforts,
80 | documented [here](https://github.com/lread/clj-graal-docs).
81 |
82 | # License
83 |
84 | Copyright © 2019-2022 Nate Jones
85 |
86 | Distributed under the EPL License. See LICENSE.
87 |
88 | This project contains code from:
89 |
90 | [babashka](https://github.com/borkdude/babashka), which is licensed under the same EPL License.
91 |
--------------------------------------------------------------------------------
/src/app/main.clj:
--------------------------------------------------------------------------------
1 | (ns app.main
2 | (:require [app.edn :as edn]
3 | [app.json :as json]
4 | [clojure.java.io :as io]
5 | [clojure.string :as string]
6 | [clojure.tools.cli :refer [parse-opts]]
7 | [doric.core :as doric]
8 | [doric.csv]
9 | [doric.html]
10 | [doric.org]
11 | [doric.raw]
12 | [fancy.table]
13 | [pod-racer.core :as pod]
14 | [tabl.format.k8s]
15 | [tabl.format.markdown])
16 | (:import
17 | [java.io File])
18 | (:gen-class))
19 |
20 | (def formatters
21 | {"fancy" fancy.table/print-table
22 | "org" #(->> % (doric/table {:format 'doric.org}) println)
23 | "csv" #(->> % (doric/table {:format 'doric.csv}) println)
24 | "raw" #(->> % (doric/table {:format 'doric.raw}) println)
25 | "html" #(->> % (doric/table {:format 'doric.html}) println)
26 | "md" #(->> % (doric/table {:format 'tabl.format.markdown}) println)
27 | "k8s" #(->> % (doric/table {:format 'tabl.format.k8s}) println)})
28 |
29 | (def cli-options
30 | [["-e" "--edn" "Input is JSON"]
31 | ["-f" "--file FILE" "File to process instead of stdin"]
32 | ["-j" "--json" "Input is EDN"]
33 | ; ["-c" "--csv" "Input is CSV"]
34 | ["-m" "--mode MODE" (str "Formatting mode, available options: " (string/join ", " (keys formatters)))
35 | :default "fancy"
36 | :validate [#(contains? formatters %) (str "Must be one of " (string/join ", " (keys formatters)))]]
37 | ["-h" "--help"]
38 | ["-v" "--version" "Print version"]])
39 |
40 | (defn print-usage
41 | [summary]
42 | (println "usage: tabl [opts]")
43 | (println " ")
44 | (println "options:")
45 | (println summary))
46 |
47 | (defn find-errors
48 | [parsed]
49 | (let [{:keys [errors options]} parsed
50 | {:keys [file help edn json version]} options]
51 | (cond
52 | help
53 | {:exit 0}
54 |
55 | version
56 | {:message (string/trim (slurp (io/resource "VERSION")))
57 | :plain true
58 | :exit 0}
59 |
60 | errors
61 | {:message (string/join "\n" errors)
62 | :exit 1}
63 |
64 | (not (or edn json))
65 | {:message "please specify which format"
66 | :exit 1}
67 |
68 | (and file (not (.exists ^File (io/file file))))
69 | {:message (str "file not found: " file)
70 | :exit 1}
71 | )))
72 |
73 | (defn print-errors
74 | [parsed errors]
75 | (let [{:keys [summary]} parsed
76 | {:keys [message exit plain]} errors]
77 | (if plain
78 | (println message)
79 | (do
80 | (when message
81 | (println message)
82 | (println " "))
83 | (print-usage summary)))
84 | exit))
85 |
86 | (defn select-input
87 | [options]
88 | (let [{:keys [file]} options]
89 | (if file
90 | (io/reader file)
91 | *in*)))
92 |
93 | (defn input->seq
94 | [options reader]
95 | (cond
96 | (:edn options)
97 | (edn/reader->seq reader)
98 |
99 | (:json options)
100 | (json/reader->seq reader)))
101 |
102 | (def pod-config
103 | {:pod/namespaces
104 | [{:pod/ns "pod.tabl.fancy"
105 | :pod/vars [{:var/name "render-table"
106 | :var/fn fancy.table/render-table}
107 | {:var/name "print-table"
108 | :var/fn fancy.table/print-table}]}
109 | {:pod/ns "pod.tabl.doric"
110 | :pod/vars [{:var/name "table"
111 | :var/fn doric/table}
112 | {:var/name "print-table"
113 | :var/fn (fn [& args]
114 | (println (apply doric/table args)))}]}]})
115 |
116 | (defn -main [& args]
117 | (let [parsed (parse-opts args cli-options)
118 | {:keys [options]} parsed]
119 | (if (System/getenv "BABASHKA_POD")
120 | (pod/launch pod-config)
121 | (or (some->> (find-errors parsed)
122 | (print-errors parsed)
123 | (System/exit))
124 | (let [data (->> (select-input options)
125 | (input->seq options))
126 | formatter (get formatters (:mode options))]
127 | (formatter data))))))
128 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------