├── test_projects ├── sample │ ├── .nrepl-port │ ├── checkouts │ │ └── sample2 │ │ │ ├── src │ │ │ └── sample2 │ │ │ │ ├── alt.clj │ │ │ │ └── core.clj │ │ │ ├── .gitignore │ │ │ ├── test │ │ │ └── sample2 │ │ │ │ └── core_test.clj │ │ │ ├── project.clj │ │ │ └── README │ ├── src │ │ └── nom │ │ │ └── nom │ │ │ ├── check.clj │ │ │ └── nom.clj │ ├── test │ │ └── test_nom_nom_nom.clj │ └── project.clj ├── overlapped-sourcepaths │ ├── src │ │ └── foo │ └── project.clj ├── sample-reader-cond │ ├── src │ │ └── nom │ │ │ └── nom │ │ │ ├── clj.clj │ │ │ └── cljc.cljc │ ├── test │ │ ├── clj_test.clj │ │ ├── cljc_test.cljc │ │ └── selectors.clj │ └── project.clj ├── tricky-name │ ├── .gitignore │ ├── src │ │ └── org │ │ │ └── domain │ │ │ └── tricky_name │ │ │ ├── brunch.clj │ │ │ ├── munch.clj │ │ │ └── core.clj │ └── project.clj ├── sample-deploy │ ├── deploy-me-0.1.0-SNAPSHOT-fat.jarr │ └── project.clj ├── with-resources │ ├── resources │ │ └── nested │ │ │ └── dir │ │ │ └── sample.txt │ └── project.clj ├── sample-failing │ ├── test │ │ └── sample │ │ │ └── unreadable.clj │ ├── project.clj │ └── src │ │ └── nom │ │ └── nom │ │ └── nom.clj ├── more-gen-classes │ ├── src │ │ └── more_gen_classes │ │ │ ├── bar.clj │ │ │ ├── baz.clj │ │ │ └── foo.clj │ ├── doc │ │ └── intro.md │ ├── .gitignore │ ├── README.md │ └── project.clj ├── sample-no-aot │ ├── src │ │ └── nom │ │ │ └── nom │ │ │ └── nom.clj │ ├── test │ │ ├── namespace.clj │ │ └── selectors.clj │ └── project.clj ├── native │ ├── .gitignore │ └── project.clj ├── with-aliases2 │ ├── project.clj │ └── profiles.clj ├── uberjar-merging │ ├── resources │ │ └── data_readers.clj │ └── project.clj ├── bad-require │ ├── src │ │ └── bad_require │ │ │ └── core.clj │ ├── .gitignore │ └── project.clj ├── sample-fixture-error │ ├── project.clj │ └── test │ │ ├── test_c.clj │ │ ├── test_b.clj │ │ └── test_a.clj ├── lein-test-reload-bug │ ├── project.clj │ └── test │ │ └── lein_test_reload_bug │ │ ├── b_protocol.clj │ │ ├── a_deftype.clj │ │ └── core_test.clj ├── lein-test-exit-code │ ├── project.clj │ └── test │ │ └── lein_test_exit_code │ │ └── core_test.clj ├── data-readers-backwards-compatibility │ └── project.clj ├── sample-ordered-aot │ ├── src │ │ └── sample_ordered_aot │ │ │ ├── baz.clj │ │ │ └── foo.clj │ └── project.clj ├── java-main │ ├── .gitignore │ ├── src │ │ └── java │ │ │ └── my │ │ │ └── java │ │ │ └── Main.java │ └── project.clj ├── file-not-found-thrower │ ├── .gitignore │ ├── src │ │ └── file_not_found_thrower │ │ │ └── core.clj │ └── project.clj ├── with-classifiers │ └── project.clj ├── README.txt ├── jvm-opts │ └── project.clj ├── provided │ ├── project.clj │ └── src │ │ └── provided │ │ └── core │ │ └── Example.java ├── with-pom-plugins │ └── project.clj ├── sample-profile-meta │ └── project.clj ├── with-aliases │ └── project.clj ├── managed-deps-snapshot │ └── project.clj ├── managed-deps │ └── project.clj └── uberjar-components-merging │ └── components1.xml ├── test ├── sample-connect-string ├── .gnupg │ ├── gpg.conf │ ├── gpg.sh │ ├── pubring.kbx │ └── trustdb.gpg ├── sample-connect-string-http ├── sample-index.zip └── leiningen │ ├── echo.clj │ ├── project.clj │ └── test │ ├── install.clj │ ├── vcs.clj │ ├── jvm_opts.clj │ ├── update_in.clj │ ├── do.clj │ ├── javac.clj │ ├── help.clj │ ├── new │ └── templates.clj │ ├── run.clj │ ├── deploy.clj │ ├── test.clj │ └── uberjar.clj ├── leiningen-core ├── test │ ├── resources │ │ ├── profiles-empty.clj │ │ └── profiles.clj │ └── leiningen │ │ ├── sirius.clj │ │ ├── zero.clj │ │ ├── var_args.clj │ │ ├── bluuugh.clj │ │ ├── one_or_two.clj │ │ ├── fixed_and_var_args.clj │ │ └── core │ │ └── test │ │ ├── helper.clj │ │ ├── mirrors.clj │ │ ├── utils.clj │ │ ├── user.clj │ │ └── eval.clj ├── dev-resources │ ├── checkouts │ │ ├── lib1 │ │ │ └── project.clj │ │ └── lib2 │ │ │ └── project.clj │ ├── p2.clj │ ├── p4.clj │ ├── p3.clj │ ├── p5.clj │ ├── replace-repositories.clj │ ├── p1.clj │ ├── profile-metadata.clj │ └── leiningen │ │ └── downloads.clj ├── project.clj ├── README.md ├── pom.xml └── src │ └── leiningen │ └── core │ └── ssl.clj ├── resources ├── leiningen │ ├── help │ │ ├── copying │ │ ├── faq │ │ ├── gpg │ │ ├── news │ │ ├── readme │ │ ├── deploying │ │ ├── profiles │ │ ├── sample │ │ ├── tutorial │ │ ├── project.clj │ │ ├── templates │ │ └── mixed-source │ ├── new │ │ ├── template │ │ │ ├── foo.clj │ │ │ ├── gitignore │ │ │ ├── hgignore │ │ │ ├── project.clj │ │ │ ├── temp.clj │ │ │ ├── README.md │ │ │ └── CHANGELOG.md │ │ ├── app │ │ │ ├── intro.md │ │ │ ├── core.clj │ │ │ ├── gitignore │ │ │ ├── test.clj │ │ │ ├── hgignore │ │ │ ├── project.clj │ │ │ ├── CHANGELOG.md │ │ │ └── README.md │ │ ├── default │ │ │ ├── intro.md │ │ │ ├── core.clj │ │ │ ├── gitignore │ │ │ ├── test.clj │ │ │ ├── hgignore │ │ │ ├── project.clj │ │ │ ├── README.md │ │ │ └── CHANGELOG.md │ │ └── plugin │ │ │ ├── name.clj │ │ │ ├── gitignore │ │ │ ├── hgignore │ │ │ ├── project.clj │ │ │ ├── CHANGELOG.md │ │ │ └── README.md │ └── bootclasspath-deps.clj ├── leiningen.png └── repl-welcome ├── web ├── img │ ├── leiningen.jpg │ └── favicon │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-256x256.png │ │ ├── browserconfig.xml │ │ ├── manifest.json │ │ └── safari-pinned-tab.svg ├── robots.txt ├── .htaccess ├── stylesheets │ ├── htmlize.css │ ├── lein.css │ └── layout.css └── 404.html ├── .github └── ISSUE_TEMPLATE │ ├── issue.md │ ├── feature_request.md │ └── bug_report.md ├── TUTORIAL.md ├── .gitattributes ├── bin ├── lein.cmd ├── issues.clj ├── release └── lein-pkg ├── lein-pprint ├── project.clj ├── test │ └── leiningen │ │ └── test │ │ └── pprint.clj ├── src │ └── leiningen │ │ └── pprint.clj └── README.md ├── src └── leiningen │ ├── version.clj │ ├── plugin.clj │ ├── upgrade.clj │ ├── retest.clj │ ├── show_profiles.clj │ ├── classpath.clj │ ├── new │ ├── plugin.clj │ ├── app.clj │ ├── default.clj │ └── template.clj │ ├── install.clj │ ├── do.clj │ ├── check.clj │ ├── update_in.clj │ ├── search.clj │ ├── trampoline.clj │ ├── with_profile.clj │ ├── clean.clj │ └── vcs.clj ├── .gitignore ├── .circleci └── config.yml ├── bash_completion.bash ├── project.clj ├── zsh_completion.zsh ├── pcmpl-lein.el ├── doc ├── ja │ └── lein_ja.1 └── lein.1 └── CONTRIBUTING.md /test_projects/sample/.nrepl-port: -------------------------------------------------------------------------------- 1 | 4242 -------------------------------------------------------------------------------- /test/sample-connect-string: -------------------------------------------------------------------------------- 1 | myhost:23 2 | -------------------------------------------------------------------------------- /leiningen-core/test/resources/profiles-empty.clj: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/leiningen/help/copying: -------------------------------------------------------------------------------- 1 | ../../../COPYING -------------------------------------------------------------------------------- /resources/leiningen/help/faq: -------------------------------------------------------------------------------- 1 | ../../../doc/FAQ.md -------------------------------------------------------------------------------- /resources/leiningen/help/gpg: -------------------------------------------------------------------------------- 1 | ../../../doc/GPG.md -------------------------------------------------------------------------------- /resources/leiningen/help/news: -------------------------------------------------------------------------------- 1 | ../../../NEWS.md -------------------------------------------------------------------------------- /test/.gnupg/gpg.conf: -------------------------------------------------------------------------------- 1 | keyserver keys.openpgp.org -------------------------------------------------------------------------------- /test_projects/overlapped-sourcepaths/src/foo: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/leiningen/help/readme: -------------------------------------------------------------------------------- 1 | ../../../README.md -------------------------------------------------------------------------------- /resources/leiningen/help/deploying: -------------------------------------------------------------------------------- 1 | ../../../doc/DEPLOY.md -------------------------------------------------------------------------------- /resources/leiningen/help/profiles: -------------------------------------------------------------------------------- 1 | ../../../doc/PROFILES.md -------------------------------------------------------------------------------- /resources/leiningen/help/sample: -------------------------------------------------------------------------------- 1 | ../../../sample.project.clj -------------------------------------------------------------------------------- /resources/leiningen/help/tutorial: -------------------------------------------------------------------------------- 1 | ../../../doc/TUTORIAL.md -------------------------------------------------------------------------------- /resources/leiningen/help/project.clj: -------------------------------------------------------------------------------- 1 | ../../../sample.project.clj -------------------------------------------------------------------------------- /resources/leiningen/help/templates: -------------------------------------------------------------------------------- 1 | ../../../doc/TEMPLATES.md -------------------------------------------------------------------------------- /test/sample-connect-string-http: -------------------------------------------------------------------------------- 1 | http://localhost:23/repl 2 | -------------------------------------------------------------------------------- /resources/leiningen/help/mixed-source: -------------------------------------------------------------------------------- 1 | ../../../doc/MIXED_PROJECTS.md -------------------------------------------------------------------------------- /resources/leiningen/new/template/foo.clj: -------------------------------------------------------------------------------- 1 | (def {{name}} :foo) 2 | -------------------------------------------------------------------------------- /test_projects/sample-reader-cond/src/nom/nom/clj.clj: -------------------------------------------------------------------------------- 1 | (ns nom.nom.clj) 2 | -------------------------------------------------------------------------------- /test/.gnupg/gpg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export GNUPGHOME=$(dirname $0) 3 | gpg $@ -------------------------------------------------------------------------------- /test_projects/sample-reader-cond/src/nom/nom/cljc.cljc: -------------------------------------------------------------------------------- 1 | (ns nom.nom.cljc) 2 | -------------------------------------------------------------------------------- /test_projects/tricky-name/.gitignore: -------------------------------------------------------------------------------- 1 | pom.xml 2 | *jar 3 | lib 4 | classes 5 | -------------------------------------------------------------------------------- /test_projects/sample-deploy/deploy-me-0.1.0-SNAPSHOT-fat.jarr: -------------------------------------------------------------------------------- 1 | I am a teapot! 2 | -------------------------------------------------------------------------------- /test_projects/sample/checkouts/sample2/src/sample2/alt.clj: -------------------------------------------------------------------------------- 1 | (ns sample2.alt) 2 | -------------------------------------------------------------------------------- /test_projects/with-resources/resources/nested/dir/sample.txt: -------------------------------------------------------------------------------- 1 | Do not remove me! 2 | -------------------------------------------------------------------------------- /test_projects/sample-failing/test/sample/unreadable.clj: -------------------------------------------------------------------------------- 1 | (ns sample.unreadable 2 | 3 | -------------------------------------------------------------------------------- /test_projects/sample/checkouts/sample2/.gitignore: -------------------------------------------------------------------------------- 1 | pom.xml 2 | *jar 3 | lib 4 | classes -------------------------------------------------------------------------------- /leiningen-core/test/resources/profiles.clj: -------------------------------------------------------------------------------- 1 | {:user {:plugins [[lein-pprint "1.1.1"]]}} 2 | -------------------------------------------------------------------------------- /test/sample-index.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/test/sample-index.zip -------------------------------------------------------------------------------- /web/img/leiningen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/leiningen.jpg -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Standard issue 3 | about: Anything else 4 | --- 5 | -------------------------------------------------------------------------------- /resources/leiningen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/resources/leiningen.png -------------------------------------------------------------------------------- /test/.gnupg/pubring.kbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/test/.gnupg/pubring.kbx -------------------------------------------------------------------------------- /test_projects/more-gen-classes/src/more_gen_classes/bar.clj: -------------------------------------------------------------------------------- 1 | (ns more-gen-classes.bar 2 | (:gen-class)) 3 | -------------------------------------------------------------------------------- /test_projects/more-gen-classes/src/more_gen_classes/baz.clj: -------------------------------------------------------------------------------- 1 | (ns more-gen-classes.baz 2 | (:gen-class)) 3 | -------------------------------------------------------------------------------- /test_projects/more-gen-classes/src/more_gen_classes/foo.clj: -------------------------------------------------------------------------------- 1 | (ns more-gen-classes.foo 2 | (:gen-class)) 3 | -------------------------------------------------------------------------------- /test_projects/sample-no-aot/src/nom/nom/nom.clj: -------------------------------------------------------------------------------- 1 | (ns nom.nom.nom) 2 | ;; This file is not AOT compiled! 3 | -------------------------------------------------------------------------------- /web/img/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/favicon/favicon.ico -------------------------------------------------------------------------------- /TUTORIAL.md: -------------------------------------------------------------------------------- 1 | The [tutorial has moved](https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md)! 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | #disable autocrlf for all .bat files since they already have CRLF in raw format 2 | *.bat -crlf 3 | -------------------------------------------------------------------------------- /web/img/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /web/img/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /web/img/favicon/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/favicon/mstile-150x150.png -------------------------------------------------------------------------------- /web/img/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | --- 5 | -------------------------------------------------------------------------------- /test_projects/native/.gitignore: -------------------------------------------------------------------------------- 1 | pom.xml 2 | *jar 3 | /lib 4 | /nnnative 5 | /classes 6 | .lein-failures 7 | .lein-deps-sum 8 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/sirius.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.sirius) 2 | 3 | (defn ^:pass-through-help sirius [project & args] args) 4 | -------------------------------------------------------------------------------- /test/leiningen/echo.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.echo) 2 | 3 | (defn ^:no-project-needed echo [project & args] 4 | (apply println args)) 5 | -------------------------------------------------------------------------------- /test_projects/sample/checkouts/sample2/src/sample2/core.clj: -------------------------------------------------------------------------------- 1 | (ns sample2.core 2 | (:require sample2.alt) 3 | (:gen-class)) 4 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/checkouts/lib1/project.clj: -------------------------------------------------------------------------------- 1 | (defproject checkout-lib1 "0.0.1" 2 | :description "Test some checkouts.") 3 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/checkouts/lib2/project.clj: -------------------------------------------------------------------------------- 1 | (defproject checkout-lib2 "0.0.1" 2 | :description "Test some checkouts.") 3 | -------------------------------------------------------------------------------- /test_projects/with-aliases2/project.clj: -------------------------------------------------------------------------------- 1 | (defproject project-with-aliases "0.1.0-SNAPSHOT" 2 | :a 1 3 | :profiles {:a2 {:a 2}}) 4 | -------------------------------------------------------------------------------- /web/img/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /web/img/favicon/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/leiningen/master/web/img/favicon/android-chrome-256x256.png -------------------------------------------------------------------------------- /test_projects/sample/src/nom/nom/check.clj: -------------------------------------------------------------------------------- 1 | (ns nom.nom.check 2 | (:require [sample2.core]) 3 | (:gen-class)) 4 | 5 | (defn -main []) 6 | -------------------------------------------------------------------------------- /test_projects/uberjar-merging/resources/data_readers.clj: -------------------------------------------------------------------------------- 1 | {nomnomnom/identity clojure.core/identity, 2 | mf/i nomnomnom/override, 3 | } 4 | -------------------------------------------------------------------------------- /web/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org/ 2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 3 | 4 | User-agent: * 5 | 6 | -------------------------------------------------------------------------------- /bin/lein.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set ps1=%~dpn0.ps1 4 | shift 5 | powershell -NoProfile -ExecutionPolicy Bypass -File "%ps1%" %* 6 | -------------------------------------------------------------------------------- /test_projects/bad-require/src/bad_require/core.clj: -------------------------------------------------------------------------------- 1 | (ns bad-require.core 2 | (:require [this.namespace.does.not.exist])) 3 | 4 | (defn -main []) 5 | -------------------------------------------------------------------------------- /test_projects/sample-fixture-error/project.clj: -------------------------------------------------------------------------------- 1 | (defproject sample-fixture-error "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.8.0"]]) 3 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/zero.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.zero "Dummy task for tests.") 2 | 3 | (defn zero [project] 4 | (println "a dummy task for tests")) 5 | -------------------------------------------------------------------------------- /resources/leiningen/new/app/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction to {{name}} 2 | 3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) 4 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction to {{name}} 2 | 3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) 4 | -------------------------------------------------------------------------------- /test_projects/lein-test-reload-bug/project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-test-reload-bug "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.10.1"]]) 3 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/core.clj: -------------------------------------------------------------------------------- 1 | (ns {{namespace}}) 2 | 3 | (defn foo 4 | "I don't do a whole lot." 5 | [x] 6 | (println x "Hello, World!")) 7 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/p2.clj: -------------------------------------------------------------------------------- 1 | (defproject middler "0.0.1" 2 | :description "Test some middleware." 3 | :middleware [leiningen.core.test.project/add-seven]) 4 | -------------------------------------------------------------------------------- /test_projects/more-gen-classes/doc/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction to more-gen-classes 2 | 3 | TODO: write [great documentation](http://jacobian.org/writing/what-to-write/) 4 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/var_args.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.var-args "Dummy task for tests.") 2 | 3 | (defn var-args [project & args] 4 | (println "a dummy task for tests.")) 5 | -------------------------------------------------------------------------------- /test_projects/lein-test-exit-code/project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-test-exit-code "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.10.1"]] 3 | :eval-in :leiningen) 4 | -------------------------------------------------------------------------------- /test_projects/sample-failing/project.clj: -------------------------------------------------------------------------------- 1 | (defproject nomnomnom "0.5.0-SNAPSHOT" 2 | :dependencies [[~(symbol "org.clojure" "clojure") ~"1.2.0"]] 3 | :aot [nom.nom.nom]) 4 | -------------------------------------------------------------------------------- /test_projects/overlapped-sourcepaths/project.clj: -------------------------------------------------------------------------------- 1 | (defproject overlapped-sourcepaths "0.1.0" 2 | :dependencies [[org.clojure/clojure "1.3.0"]] 3 | :java-source-paths ["src"]) 4 | -------------------------------------------------------------------------------- /resources/leiningen/new/app/core.clj: -------------------------------------------------------------------------------- 1 | (ns {{namespace}} 2 | (:gen-class)) 3 | 4 | (defn -main 5 | "I don't do a whole lot ... yet." 6 | [& args] 7 | (println "Hello, World!")) 8 | -------------------------------------------------------------------------------- /resources/leiningen/new/plugin/name.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.{{unprefixed-name}}) 2 | 3 | (defn {{unprefixed-name}} 4 | "I don't do a lot." 5 | [project & args] 6 | (println "Hi!")) 7 | -------------------------------------------------------------------------------- /test_projects/data-readers-backwards-compatibility/project.clj: -------------------------------------------------------------------------------- 1 | (defproject bug "bug" 2 | :dependencies [[org.clojure/clojure "1.8.0"] 3 | [org.flatland/ordered "1.5.6"]]) 4 | -------------------------------------------------------------------------------- /test_projects/sample-ordered-aot/src/sample_ordered_aot/baz.clj: -------------------------------------------------------------------------------- 1 | (ns sample-ordered-aot.baz) 2 | 3 | (defn baz 4 | "I don't do a whole lot." 5 | [x] 6 | (println x "Hello, World!")) 7 | -------------------------------------------------------------------------------- /test_projects/sample-ordered-aot/src/sample_ordered_aot/foo.clj: -------------------------------------------------------------------------------- 1 | (ns sample-ordered-aot.foo) 2 | 3 | (defn foo 4 | "I don't do a whole lot." 5 | [x] 6 | (println x "Hello, World!")) 7 | -------------------------------------------------------------------------------- /test/leiningen/project.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.project) 2 | 3 | (defn ^:no-project-needed project [project & args] 4 | (if (seq args) 5 | (get-in project (mapv keyword args)) 6 | project)) 7 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/bluuugh.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.bluuugh 2 | "Dummy task for tests.") 3 | 4 | (defn ^:no-project-needed bluuugh 5 | [project] 6 | (println "This is a dummy task for tests.")) -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/one_or_two.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.one-or-two "Dummy task for tests") 2 | 3 | (defn one-or-two 4 | "Dummy task for tests" 5 | ([project one]) 6 | ([project one two])) 7 | -------------------------------------------------------------------------------- /test_projects/java-main/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | profiles.clj 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | /.lein-* 10 | /.nrepl-port 11 | /.prepl-port 12 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/p4.clj: -------------------------------------------------------------------------------- 1 | (defproject middler-no-implicits "0.0.1" 2 | :description "Test some middleware." 3 | :middleware [leiningen.core.test.project/add-seven] 4 | :implicits false) 5 | -------------------------------------------------------------------------------- /test_projects/file-not-found-thrower/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | profiles.clj 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | /.lein-* 10 | /.nrepl-port 11 | /.prepl-port 12 | -------------------------------------------------------------------------------- /test_projects/with-classifiers/project.clj: -------------------------------------------------------------------------------- 1 | (defproject with-classifiers "0.1.0-SNAPSHOT" 2 | :classifiers {:tests {:source-paths ^:replace ["test"] 3 | :resource-paths ^:replace []}}) 4 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/fixed_and_var_args.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.fixed-and-var-args "Dummy task for tests.") 2 | 3 | (defn fixed-and-var-args [project one two & rest] 4 | (println "a dummy task for tests")) 5 | -------------------------------------------------------------------------------- /resources/leiningen/new/template/gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | /.prepl-port 11 | .hgignore 12 | .hg/ 13 | -------------------------------------------------------------------------------- /test_projects/file-not-found-thrower/src/file_not_found_thrower/core.clj: -------------------------------------------------------------------------------- 1 | (ns file-not-found-thrower.core) 2 | 3 | (defn -main 4 | "I don't do a whole lot." 5 | [] 6 | (slurp "haha this file does NOT EXIST")) 7 | -------------------------------------------------------------------------------- /test_projects/java-main/src/java/my/java/Main.java: -------------------------------------------------------------------------------- 1 | package my.java; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | System.out.println("Hello from Java!"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test_projects/lein-test-reload-bug/test/lein_test_reload_bug/b_protocol.clj: -------------------------------------------------------------------------------- 1 | (prn "loading" 'lein-test-reload-bug.b-protocol) 2 | 3 | (ns lein-test-reload-bug.b-protocol) 4 | 5 | (defprotocol B 6 | (b [this])) 7 | -------------------------------------------------------------------------------- /test_projects/sample-reader-cond/test/clj_test.clj: -------------------------------------------------------------------------------- 1 | (ns clj-test 2 | (:use [clojure.test] 3 | [selectors :only [record-ran]])) 4 | 5 | (deftest clojure-test 6 | (record-ran :clj-test) 7 | (is true)) 8 | -------------------------------------------------------------------------------- /test_projects/tricky-name/src/org/domain/tricky_name/brunch.clj: -------------------------------------------------------------------------------- 1 | (ns org.domain.tricky-name.brunch) 2 | 3 | (defn -main [& args] 4 | (spit (format "%s/lein-test" (System/getProperty "java.io.tmpdir")) "BRUNCH")) 5 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/p3.clj: -------------------------------------------------------------------------------- 1 | (defproject middlest "0.0.1" 2 | :description "Test explicit middleware inside a plugin." 3 | :plugins [[lein-maven "0.1.0"]] 4 | :middleware [leiningen.mvn/maven-checkouts]) 5 | -------------------------------------------------------------------------------- /test_projects/sample/checkouts/sample2/test/sample2/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns sample2.core-test 2 | (:use [sample2.core] :reload-all) 3 | (:use [clojure.test])) 4 | 5 | (deftest replace-me ;; FIXME: write 6 | (is false)) 7 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/p5.clj: -------------------------------------------------------------------------------- 1 | (defproject middler-no-implicit-middleware "0.0.1" 2 | :description "Test some middleware." 3 | :middleware [leiningen.core.test.project/add-seven] 4 | :implicit-middleware false) 5 | -------------------------------------------------------------------------------- /resources/leiningen/new/app/gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | profiles.clj 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | /.lein-* 10 | /.nrepl-port 11 | /.prepl-port 12 | .hgignore 13 | .hg/ 14 | -------------------------------------------------------------------------------- /test_projects/java-main/project.clj: -------------------------------------------------------------------------------- 1 | (defproject java-main "0.1.0-SNAPSHOT" 2 | :java-source-paths ["src/java"] 3 | :dependencies [[org.clojure/clojure "1.8.0"]] ;; lein run errors if not there. 4 | :main my.java.Main) 5 | -------------------------------------------------------------------------------- /test_projects/sample-fixture-error/test/test_c.clj: -------------------------------------------------------------------------------- 1 | (ns test-c 2 | (:require [clojure.test :refer :all] 3 | [test-a :refer (record-ran)])) 4 | 5 | (deftest test-c 6 | (record-ran :test-c) 7 | (is (= 1 1))) 8 | -------------------------------------------------------------------------------- /resources/leiningen/new/app/test.clj: -------------------------------------------------------------------------------- 1 | (ns {{namespace}}-test 2 | (:require [clojure.test :refer :all] 3 | [{{namespace}} :refer :all])) 4 | 5 | (deftest a-test 6 | (testing "FIXME, I fail." 7 | (is (= 0 1)))) 8 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | profiles.clj 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | /.lein-* 10 | /.nrepl-port 11 | /.prepl-port 12 | .hgignore 13 | .hg/ 14 | -------------------------------------------------------------------------------- /resources/leiningen/new/plugin/gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | profiles.clj 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | /.lein-* 10 | /.nrepl-port 11 | /.prepl-port 12 | .hgignore 13 | .hg/ 14 | -------------------------------------------------------------------------------- /test_projects/sample-reader-cond/project.clj: -------------------------------------------------------------------------------- 1 | (defproject nomnomnom "0.5.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.8.0"] 3 | [janino "2.5.15"]] 4 | :aot :all 5 | :uberjar-exclusions [#"DUMMY"]) 6 | -------------------------------------------------------------------------------- /test_projects/sample/checkouts/sample2/project.clj: -------------------------------------------------------------------------------- 1 | (defproject sample2 "1.0.0-SNAPSHOT" 2 | :description "FIXME: write" 3 | :dependencies [[org.clojure/clojure "1.1.0"] 4 | [org.clojure/clojure-contrib "1.1.0"]]) -------------------------------------------------------------------------------- /test_projects/with-resources/project.clj: -------------------------------------------------------------------------------- 1 | (defproject project-with-resources "0.5.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.3.0"] 3 | [janino "2.5.15"]] 4 | 5 | :resource-paths ["resources"]) 6 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/test.clj: -------------------------------------------------------------------------------- 1 | (ns {{namespace}}-test 2 | (:require [clojure.test :refer :all] 3 | [{{namespace}} :refer :all])) 4 | 5 | (deftest a-test 6 | (testing "FIXME, I fail." 7 | (is (= 0 1)))) 8 | -------------------------------------------------------------------------------- /test_projects/sample/checkouts/sample2/README: -------------------------------------------------------------------------------- 1 | # sample2 2 | 3 | FIXME: write description 4 | 5 | ## Usage 6 | 7 | FIXME: write 8 | 9 | ## Installation 10 | 11 | FIXME: write 12 | 13 | ## License 14 | 15 | FIXME: write 16 | -------------------------------------------------------------------------------- /test_projects/tricky-name/src/org/domain/tricky_name/munch.clj: -------------------------------------------------------------------------------- 1 | (ns org.domain.tricky-name.munch) 2 | 3 | (defn -main [& args] 4 | (spit (format "%s/lein-test" (System/getProperty "java.io.tmpdir")) 5 | (pr-str :munched args))) 6 | -------------------------------------------------------------------------------- /test_projects/README.txt: -------------------------------------------------------------------------------- 1 | These projects are used for leiningen's test suite, so don't change 2 | any of these values without updating the relevant tests. If you 3 | just want a basic project to work from, generate a new one with 4 | "lein new". 5 | -------------------------------------------------------------------------------- /test_projects/bad-require/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | profiles.clj 6 | pom.xml 7 | pom.xml.asc 8 | *.jar 9 | *.class 10 | .lein-deps-sum 11 | .lein-failures 12 | .lein-plugins 13 | .lein-repl-history 14 | -------------------------------------------------------------------------------- /test_projects/more-gen-classes/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | profiles.clj 6 | pom.xml 7 | pom.xml.asc 8 | *.jar 9 | *.class 10 | .lein-deps-sum 11 | .lein-failures 12 | .lein-plugins 13 | .lein-repl-history 14 | -------------------------------------------------------------------------------- /resources/leiningen/new/plugin/hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | target/** 3 | classes/** 4 | checkouts/** 5 | profiles.clj 6 | pom.xml 7 | pom.xml.asc 8 | *.jar 9 | *.class 10 | /.lein-* 11 | /.nrepl-port 12 | /.prepl-port 13 | .gitignore 14 | .git/** 15 | -------------------------------------------------------------------------------- /test_projects/jvm-opts/project.clj: -------------------------------------------------------------------------------- 1 | (defproject custom/args "0.0.1-SNAPSHOT" 2 | :description "A test project" 3 | :dependencies [[org.clojure/clojure "1.8.0"]] 4 | :profiles {:no-op {} 5 | :ascii {:jvm-opts ["-Dfile.encoding=ASCII"]}}) 6 | -------------------------------------------------------------------------------- /test_projects/tricky-name/project.clj: -------------------------------------------------------------------------------- 1 | (defproject org.domain/tricky-name "1.0" 2 | :description "One with a tricky group and project name" 3 | :dependencies [[org.clojure/clojure "1.3.0"]] 4 | :main ^{:skip-aot true} org.domain.tricky-name.core) 5 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | target/** 3 | classes/** 4 | checkouts/** 5 | profiles.clj 6 | pom.xml 7 | pom.xml.asc 8 | *.jar 9 | *.class 10 | /.lein-* 11 | /.nrepl-port 12 | /.prepl-port 13 | .gitignore 14 | .git/** 15 | -------------------------------------------------------------------------------- /resources/leiningen/new/template/hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | target/** 3 | classes/** 4 | checkouts/** 5 | profiles.clj 6 | pom.xml 7 | pom.xml.asc 8 | *.jar 9 | *.class 10 | /.lein-* 11 | /.nrepl-port 12 | /.prepl-port 13 | .gitignore 14 | .git/** 15 | -------------------------------------------------------------------------------- /test_projects/sample-reader-cond/test/cljc_test.cljc: -------------------------------------------------------------------------------- 1 | (ns cljc-test 2 | (:use #?(:clj [clojure.test] 3 | :cljs [cljs.test]) 4 | [selectors :only [record-ran]])) 5 | 6 | (deftest conditional-test 7 | (record-ran :cljc-test) 8 | (is true)) 9 | -------------------------------------------------------------------------------- /resources/leiningen/new/app/hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | pom.xml 3 | pom.xml.asc 4 | *.jar 5 | *.class 6 | .gitignore 7 | .git/** 8 | 9 | syntax: regexp 10 | ^.nrepl-port 11 | ^.prepl-port 12 | ^.lein-.* 13 | ^target/ 14 | ^classes/ 15 | ^checkouts/ 16 | profiles.clj 17 | -------------------------------------------------------------------------------- /resources/repl-welcome: -------------------------------------------------------------------------------- 1 | Docs: (doc function-name-here) 2 | (find-doc "part-of-name-here") 3 | Source: (source function-name-here) 4 | Javadoc: (javadoc java-object-or-class-here) 5 | Exit: Control+D or (exit) or (quit) 6 | Results: Stored in vars *1, *2, *3, an exception in *e 7 | -------------------------------------------------------------------------------- /test_projects/tricky-name/src/org/domain/tricky_name/core.clj: -------------------------------------------------------------------------------- 1 | (ns org.domain.tricky-name.core) 2 | 3 | (defn -main [& args] 4 | (when-not (empty? args) 5 | (spit (format "%s/lein-test" (System/getProperty "java.io.tmpdir")) 6 | (str "nom:" (first args))) 7 | (recur (rest args)))) 8 | -------------------------------------------------------------------------------- /test_projects/lein-test-reload-bug/test/lein_test_reload_bug/a_deftype.clj: -------------------------------------------------------------------------------- 1 | (prn "loading" 'lein-test-reload-bug.a-deftype) 2 | 3 | (ns lein-test-reload-bug.a-deftype 4 | (:require [lein-test-reload-bug.b-protocol 5 | :refer [B]])) 6 | 7 | (deftype A [] 8 | B 9 | (b [this] :ok)) 10 | -------------------------------------------------------------------------------- /test_projects/more-gen-classes/README.md: -------------------------------------------------------------------------------- 1 | # more-gen-classes 2 | 3 | A Clojure library designed to ... well, that part is up to you. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © 2013 FIXME 12 | 13 | Distributed under the Eclipse Public License, the same as Clojure. 14 | -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | Options +MultiViews -ExecCGI 2 | RewriteEngine on 3 | 4 | # HTTPS 5 | RewriteCond %{HTTPS} !=on 6 | RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L] 7 | 8 | Header set Strict-Transport-Security "max-age=31536000" env=HTTPS 9 | Header always set Permissions-Policy: interest-cohort=() 10 | -------------------------------------------------------------------------------- /lein-pprint/project.clj: -------------------------------------------------------------------------------- 1 | (defproject lein-pprint "1.3.2" 2 | :description "Pretty-print a representation of the project map." 3 | :url "https://github.com/technomancy/leiningen" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :eval-in-leiningen true) 7 | -------------------------------------------------------------------------------- /test_projects/sample-deploy/project.clj: -------------------------------------------------------------------------------- 1 | (defproject deploy-me "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.8.0"]]) 7 | -------------------------------------------------------------------------------- /web/img/favicon/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #ffffff 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/leiningen/new/plugin/project.clj: -------------------------------------------------------------------------------- 1 | (defproject {{name}} "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" 5 | :url "https://www.eclipse.org/legal/epl-2.0/"} 6 | :eval-in-leiningen true) 7 | -------------------------------------------------------------------------------- /test_projects/more-gen-classes/project.clj: -------------------------------------------------------------------------------- 1 | (defproject more-gen-classes "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.8.0"]]) 7 | -------------------------------------------------------------------------------- /test_projects/provided/project.clj: -------------------------------------------------------------------------------- 1 | (defproject provided "0" 2 | :license {:name "Eclipse Public License" 3 | :url "http://www.eclipse.org/legal/epl-v10.html"} 4 | :dependencies [] 5 | :java-source-paths ["src"] 6 | :main provided.core.Example 7 | :profiles {:provided {:dependencies [[org.clojure/clojure "1.4.0"]]}}) 8 | -------------------------------------------------------------------------------- /test_projects/provided/src/provided/core/Example.java: -------------------------------------------------------------------------------- 1 | package provided.core; 2 | 3 | import clojure.lang.RT; 4 | 5 | public class Example { 6 | 7 | public static void 8 | main(String... args) { 9 | System.exit( 10 | RT.intCast( 11 | RT.var("clojure.core", "read-string").invoke("0"))); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /test_projects/sample-no-aot/test/namespace.clj: -------------------------------------------------------------------------------- 1 | (ns ^:integration namespace 2 | (:use [clojure.test] 3 | [selectors :only [record-ran]])) 4 | 5 | (deftest integration-test 6 | (record-ran :integration-ns) 7 | (is true)) 8 | 9 | (deftest ^:int2 int2-integration-test 10 | (record-ran :integration-ns) 11 | (is true)) 12 | -------------------------------------------------------------------------------- /test_projects/sample/test/test_nom_nom_nom.clj: -------------------------------------------------------------------------------- 1 | (ns test-nom-nom-nom 2 | (:use [nom.nom.nom] 3 | [clojure.test])) 4 | 5 | (defn test-ns-hook 6 | [] 7 | (is false)) 8 | 9 | (defn f [x] 10 | (.list x)) 11 | 12 | (deftest should-use-1.1.0 13 | (is (= "1.1.0" (clojure-version))) 14 | (f (java.io.File. "/tmp"))) 15 | -------------------------------------------------------------------------------- /test_projects/file-not-found-thrower/project.clj: -------------------------------------------------------------------------------- 1 | (defproject file-not-found-thrower "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.8.0"]]) 7 | -------------------------------------------------------------------------------- /test_projects/bad-require/project.clj: -------------------------------------------------------------------------------- 1 | (defproject bad-require "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.8.0"]] 7 | :main bad-require.core) 8 | -------------------------------------------------------------------------------- /test_projects/sample-fixture-error/test/test_b.clj: -------------------------------------------------------------------------------- 1 | (ns test-b 2 | (:require [clojure.test :refer :all] 3 | [test-a :refer [record-ran]])) 4 | 5 | (use-fixtures :once 6 | (fn [& _] 7 | (throw (Exception. "Don't panic. This is an expected exception.")))) 8 | 9 | (deftest test-b 10 | (record-ran :test-b) 11 | (is (= 1 1))) 12 | -------------------------------------------------------------------------------- /test_projects/with-aliases2/profiles.clj: -------------------------------------------------------------------------------- 1 | {:user 2 | {:aliases {"echo" ["with-profile" "+a2" "echo"] 3 | "project" ["with-profile" "+a2" "project"] 4 | "projecta" ["with-profile" "+a2" "project" "a"] 5 | "project-set" ["with-profile" "a2" "project"] 6 | "projecta-set" ["with-profile" "a2" "project" "a"]}}} 7 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/replace-repositories.clj: -------------------------------------------------------------------------------- 1 | (defproject metadata-check "0.1.0" 2 | :description "Check that repositories can be replaced." 3 | :license {:name "Eclipse Public License"} 4 | :dependencies [[robert/hooke "1.1.2"] 5 | [stencil "0.2.0"]] 6 | :repositories ^:replace [["nexus" {:url "https://clojars.org/repo/"}]]) 7 | -------------------------------------------------------------------------------- /resources/leiningen/new/template/project.clj: -------------------------------------------------------------------------------- 1 | (defproject {{group-prefix}}lein-template.{{artifact-id}} "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" 5 | :url "https://www.eclipse.org/legal/epl-2.0/"} 6 | :eval-in-leiningen true) 7 | -------------------------------------------------------------------------------- /test_projects/sample-failing/src/nom/nom/nom.clj: -------------------------------------------------------------------------------- 1 | (ns nom.nom.nom 2 | (:gen-class)) 3 | 4 | failure-expected-here-dont-freak-out 5 | 6 | This noming squirrel will cause compilation of this file to fail. 7 | 8 | ,;;:;, 9 | ;;;;; 10 | ,:;;:; ,'=. 11 | ;:;:;' .=" ,'_\ 12 | ':;:;,/ ,__:=@ 13 | ';;:; =./)_ 14 | `"=\_ )_"` 15 | ``'" 16 | -------------------------------------------------------------------------------- /test_projects/sample-reader-cond/test/selectors.clj: -------------------------------------------------------------------------------- 1 | (ns selectors 2 | (:use [clojure.test] 3 | [clojure.java.io])) 4 | 5 | (defn record-ran [t] 6 | (let [file-name (format "%s/lein-test-ran" 7 | (System/getProperty "java.io.tmpdir"))] 8 | (with-open [w (writer file-name :append true)] 9 | (.write w (str t "\n"))))) 10 | 11 | -------------------------------------------------------------------------------- /test_projects/sample-ordered-aot/project.clj: -------------------------------------------------------------------------------- 1 | (defproject sample-ordered-aot "0.1.0-SNAPSHOT" 2 | :description "This project is to drive testing of ordered aot compilation." 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.8.0"]] 7 | :aot :all) 8 | -------------------------------------------------------------------------------- /test_projects/lein-test-exit-code/test/lein_test_exit_code/core_test.clj: -------------------------------------------------------------------------------- 1 | (ns lein-test-exit-code.core-test 2 | (:require [clojure.test :refer [deftest is]])) 3 | 4 | (defmacro gen-failing-deftests [n] 5 | `(do 6 | ~@(for [i (range n)] 7 | `(deftest ~(symbol (str "expected-failure-" i)) 8 | (is false "Expected failure."))))) 9 | 10 | (gen-failing-deftests 256) 11 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/project.clj: -------------------------------------------------------------------------------- 1 | (defproject {{raw-name}} "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" 5 | :url "https://www.eclipse.org/legal/epl-2.0/"} 6 | :dependencies [[org.clojure/clojure "1.10.1"]] 7 | :repl-options {:init-ns {{namespace}}}) 8 | -------------------------------------------------------------------------------- /test_projects/sample-no-aot/project.clj: -------------------------------------------------------------------------------- 1 | (defproject nomnomnom "0.5.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.3.0"] 3 | [janino "2.5.15"]] 4 | :uberjar-exclusions [#"DUMMY"] 5 | :test-selectors {:default (fn [m] (not (:integration m))) 6 | :integration :integration 7 | :int2 :int2 8 | :no-custom (fn [m] (not (false? (:custom m))))}) 9 | -------------------------------------------------------------------------------- /web/stylesheets/htmlize.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #000000; 3 | background-color: #ffffff; 4 | } 5 | .constant { 6 | /* font-lock-constant-face */ 7 | color: #008b8b; 8 | } 9 | .esk-paren { 10 | /* esk-paren-face */ 11 | color: #8c8c8c; 12 | } 13 | .hl-line { 14 | /* hl-line */ 15 | background-color: #b4eeb4; 16 | } 17 | .string { 18 | /* font-lock-string-face */ 19 | color: #8b2252; 20 | } 21 | -------------------------------------------------------------------------------- /src/leiningen/version.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.version 2 | "Print version for Leiningen and the current JVM." 3 | (:require [leiningen.core.main :as main])) 4 | 5 | (defn ^:no-project-needed version 6 | "Print version for Leiningen and the current JVM." 7 | [project] 8 | (println "Leiningen" (main/leiningen-version) 9 | "on Java" (System/getProperty "java.version") 10 | (System/getProperty "java.vm.name"))) 11 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/core/test/helper.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.core.test.helper) 2 | 3 | (defn abort-msg 4 | "Catches main/abort thrown by calling f on its args and returns its error 5 | message." 6 | [f & args] 7 | (with-out-str 8 | (binding [*err* *out*] 9 | (try 10 | (apply f args) 11 | (catch clojure.lang.ExceptionInfo e 12 | (when-not (:exit-code (ex-data e)) 13 | (throw e))))))) 14 | -------------------------------------------------------------------------------- /test_projects/sample-fixture-error/test/test_a.clj: -------------------------------------------------------------------------------- 1 | (ns test-a 2 | (:require [clojure.test :refer :all] 3 | [clojure.java.io :refer [writer]])) 4 | 5 | (defn record-ran [t] 6 | (let [file-name (format "%s/lein-test-ran" 7 | (System/getProperty "java.io.tmpdir"))] 8 | (with-open [w (writer file-name :append true)] 9 | (.write w (str t "\n"))))) 10 | 11 | (deftest test-a 12 | (record-ran :test-a) 13 | (is (= 1 1))) 14 | -------------------------------------------------------------------------------- /test_projects/sample/src/nom/nom/nom.clj: -------------------------------------------------------------------------------- 1 | (ns nom.nom.nom 2 | (:import [org.jdom.adapters CrimsonDOMAdapter]) 3 | (:gen-class)) 4 | 5 | (when-not (= "1.3.0" (clojure-version)) 6 | (throw (Exception. (str "Not running Clojure 1.3.0: " 7 | (clojure-version))))) 8 | 9 | (def unused-proxy (proxy [Object] [] (toString [] "unused"))) 10 | 11 | (defn -main [& args] 12 | (when-not (empty? args) 13 | (println "NOM! Munched" (first args)) 14 | (recur (rest args)))) 15 | -------------------------------------------------------------------------------- /web/img/favicon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Leiningen", 3 | "icons": [ 4 | { 5 | "src": "/img/favicon/android-chrome-192x192.png", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | }, 9 | { 10 | "src": "/img/favicon/android-chrome-256x256.png", 11 | "sizes": "256x256", 12 | "type": "image/png" 13 | } 14 | ], 15 | "theme_color": "#ffffff", 16 | "background_color": "#ffffff", 17 | "display": "standalone" 18 | } -------------------------------------------------------------------------------- /resources/leiningen/new/app/project.clj: -------------------------------------------------------------------------------- 1 | (defproject {{raw-name}} "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" 5 | :url "https://www.eclipse.org/legal/epl-2.0/"} 6 | :dependencies [[org.clojure/clojure "1.10.1"]] 7 | :main ^:skip-aot {{namespace}} 8 | :target-path "target/%s" 9 | :profiles {:uberjar {:aot :all 10 | :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}}) 11 | -------------------------------------------------------------------------------- /src/leiningen/plugin.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.plugin 2 | "DEPRECATED. Please use the :user profile instead." 3 | (:require [leiningen.core.main :as main])) 4 | 5 | (defn ^:no-project-needed plugin 6 | "DEPRECATED. Please use the :user profile instead." 7 | [& args] 8 | (main/abort "The plugin task has been removed.\n" 9 | "\nPlease see the upgrade guide for instructions on how to use" 10 | "the user profile to\nspecify plugins instead:" 11 | "https://github.com/technomancy/leiningen/wiki/Upgrading")) 12 | -------------------------------------------------------------------------------- /resources/leiningen/new/template/temp.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.new.{{artifact-id}} 2 | (:require [leiningen.new.templates :as tmpl] 3 | [leiningen.core.main :as main])) 4 | 5 | (def render (tmpl/renderer "{{sanitized}}")) 6 | 7 | (defn {{artifact-id}} 8 | "FIXME: write documentation" 9 | [name] 10 | (let [data {:name name 11 | :sanitized (tmpl/name-to-path name)}] 12 | (main/info "Generating fresh 'lein new' {{name}} project.") 13 | (tmpl/->files data 14 | ["src/{{placeholder}}/foo.clj" (render "foo.clj" data)]))) 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | *.bak 3 | *.swp 4 | *.class 5 | *asc 6 | *jar 7 | *~ 8 | .lein* 9 | /.classpath 10 | /.nrepl-port 11 | /.prepl-port 12 | /.project 13 | /.settings 14 | /hs_err_pid*.log 15 | /lein.man 16 | /lein_ja.man 17 | /leiningen-core/.lein-plugins/checksum 18 | /leiningen-core/.nrepl-port 19 | /leiningen-core/.prepl-port 20 | /leiningen-core/dev-resources/target 21 | /lein-pprint/.nrepl-port 22 | /lein-pprint/.prepl-port 23 | /logs 24 | /scratch.clj 25 | /target 26 | /wiki 27 | /web 28 | TAGS 29 | test_projects/*/target 30 | pom.xml 31 | deps.txt 32 | profiles.clj 33 | -------------------------------------------------------------------------------- /test_projects/uberjar-merging/project.clj: -------------------------------------------------------------------------------- 1 | (defproject nomnomnom "0.5.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.8.0"] 3 | [janino "2.5.15"] 4 | [org.platypope/method-fn "0.1.0"] 5 | [porcupine "0.0.4"]] 6 | :uberjar-exclusions [#"DUMMY"] 7 | :uberjar-merge-with {#"\.properties$" [slurp str spit]} 8 | :test-selectors {:default (fn [m] (not (:integration m))) 9 | :integration :integration 10 | :int2 :int2 11 | :no-custom (fn [m] (not (false? (:custom m))))}) 12 | -------------------------------------------------------------------------------- /test_projects/with-pom-plugins/project.clj: -------------------------------------------------------------------------------- 1 | (defproject project-with-pom-plugins "0.1.0-SNAPSHOT" 2 | :pom-plugins [[two.parameter/simple-plugin "1.0.0"] 3 | [three.parameter/with-vec "1.0.1" 4 | [:a 1 :a 2 :a 3]] 5 | [three.parameter/with-map "1.0.2" 6 | {:a 1 7 | :b 2 8 | :c 3}] 9 | [three.parameter/with-list "1.0.3" 10 | (:root 11 | [:a 1] 12 | [:b 13 | [:c 2] 14 | [:d 3]])]]) 15 | -------------------------------------------------------------------------------- /test_projects/native/project.clj: -------------------------------------------------------------------------------- 1 | (defproject project-name "1.0.0-SNAPSHOT" 2 | :description "Test support for transitive native dependencies" 3 | :native-path "nnnative" 4 | :dependencies [[org.clojure/clojure "1.4.0"] 5 | [serial-port "1.0.7"] 6 | [penumbra/lwjgl "2.4.2"] 7 | [com.badlogicgames.gdx/gdx-platform "0.9.9"] 8 | [com.badlogicgames.gdx/gdx-platform "0.9.9" :classifier "natives-desktop"] 9 | [org.clojars.samaaron/rxtx "2.2.0"] 10 | [jriengine "0.8.4"] 11 | [tokyocabinet "1.24.0"]]) 12 | -------------------------------------------------------------------------------- /test_projects/sample-profile-meta/project.clj: -------------------------------------------------------------------------------- 1 | (defproject nomnomnom "0.5.0-SNAPSHOT" 2 | :dependencies [] 3 | :profiles {:default [:leiningen/default :my-leaky :my-provided :my-test] 4 | :my-leaky ^:leaky {:dependencies 5 | [[org.clojure/tools.macro "0.1.2"]]} 6 | :my-test 7 | ^{:pom-scope :test} {:dependencies 8 | [[org.clojure/java.classpath "0.2.2"]]} 9 | :my-provided 10 | ^{:pom-scope :provided} {:dependencies 11 | [[org.clojure/tools.namespace "0.2.6"]]}}) 12 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/p1.clj: -------------------------------------------------------------------------------- 1 | (defproject leiningen "2.0.0-SNAPSHOT" 2 | :description "Automate Clojure projects without setting your hair on fire." 3 | :url "https://github.com/technomancy/leiningen" 4 | :license {:name "Eclipse Public License"} 5 | :dependencies [[leiningen-core "2.0.0-SNAPSHOT"] 6 | [clucy "0.2.2" :exclusions [org.clojure/clojure]] 7 | [lancet "1.0.1"] 8 | [robert/hooke "1.1.2"] 9 | [stencil "0.2.0"] 10 | ["net.3scale/3scale-api" "3.0.2"] 11 | ["clj-http" "3.4.1"]] 12 | :twelve ~(+ 6 2 4) 13 | :disable-implicit-clean true 14 | :eval-in-leiningen true) 15 | -------------------------------------------------------------------------------- /src/leiningen/upgrade.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.upgrade 2 | "Upgrade Leiningen to specified version or latest stable." 3 | (:require [leiningen.core.main :as main])) 4 | 5 | ;; This file is only a placeholder. The real upgrade 6 | ;; implementation can be found in the 'lein' script. 7 | 8 | (defn ^:no-project-needed upgrade 9 | "Upgrade Leiningen to specified version or latest stable." 10 | [project & args] 11 | (main/abort "Upgrade is either disabled, or you have tried to call it from a" 12 | "higher order\ntask. If you've installed lein through a package" 13 | "manager, upgrade lein through\nthe package manager's upgrade" 14 | "commands.")) 15 | -------------------------------------------------------------------------------- /src/leiningen/retest.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.retest 2 | "Run only the test namespaces which failed last time around." 3 | (:require [leiningen.test :as test] 4 | [leiningen.core.main :as main])) 5 | 6 | (defn retest 7 | "Run only the test namespaces which failed last time around." 8 | [project & selectors] 9 | (if (:monkeypatch-clojure-test project true) 10 | (apply test/test project 11 | (concat (if (.exists (java.io.File. ".lein-failures")) 12 | (->> (slurp ".lein-failures") 13 | read-string keys sort)) 14 | selectors)) 15 | (main/abort "Cannot retest when :monkeypatch-clojure-test is disabled."))) 16 | -------------------------------------------------------------------------------- /src/leiningen/show_profiles.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.show-profiles 2 | "List all available profiles or display one if given an argument." 3 | (:require [clojure.string] 4 | [clojure.pprint :as pprint] 5 | [leiningen.core.project :as project])) 6 | 7 | (defn ^:no-project-needed show-profiles 8 | "List all available profiles or display one if given an argument." 9 | ([project] 10 | (->> (project/read-profiles project) 11 | (keys) 12 | (map (comp #(subs % 1) str)) 13 | (sort) 14 | (clojure.string/join "\n") 15 | (println))) 16 | ([project profile] 17 | (-> (project/read-profiles project) 18 | (get (keyword profile)) 19 | (pprint/pprint)) 20 | (flush))) 21 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/profile-metadata.clj: -------------------------------------------------------------------------------- 1 | (defproject metadata-check "0.1.0" 2 | :description "Check that profile metadata is retained." 3 | :license {:name "Eclipse Public License"} 4 | :dependencies [[leiningen-core "2.0.0-SNAPSHOT"] 5 | [clucy "0.2.2" :exclusions [org.clojure/clojure]] 6 | [lancet "1.0.1"] 7 | [robert/hooke "1.1.2"] 8 | [stencil "0.2.0"]] 9 | :profiles {:bar {:dependencies ^:please-keep-me [[lancet "1.0.2"] 10 | [stencil "0.3.0"]] 11 | :repositories ^:replace []} 12 | :baz {:dependencies ^:hello [] 13 | :repositories ^:displace [] 14 | :java-opts ["my" "java" "opts"]}}) 15 | -------------------------------------------------------------------------------- /test_projects/sample-no-aot/test/selectors.clj: -------------------------------------------------------------------------------- 1 | (ns selectors 2 | (:use [clojure.test] 3 | [clojure.java.io])) 4 | 5 | (defn record-ran [t] 6 | (let [file-name (format "%s/lein-test-ran" 7 | (System/getProperty "java.io.tmpdir"))] 8 | (with-open [w (writer file-name :append true)] 9 | (.write w (str t "\n"))))) 10 | 11 | (use-fixtures :each (fn [t] (record-ran :fixture) (t))) 12 | 13 | (deftest ^{:integration true} integration-test 14 | (record-ran :integration) 15 | (is true)) 16 | 17 | (deftest regular 18 | (record-ran :regular) 19 | (is true)) 20 | 21 | (deftest ^{:custom false} not-custom 22 | (record-ran :not-custom) 23 | (is true)) 24 | 25 | (deftest ^{:int2 true} integration-2 26 | (record-ran :int2) 27 | (is true)) 28 | -------------------------------------------------------------------------------- /test_projects/with-aliases/project.clj: -------------------------------------------------------------------------------- 1 | (defproject project-with-aliases "0.1.0-SNAPSHOT" 2 | :aliases {"p" ["echo" "p"] 3 | "a2p" ["with-profile" "+a2" "p"] 4 | "pp" ["with-profile" "+a2" "echo" "pp"] 5 | "ppp" ["with-profile" "+a2" "echo" "ppp"] 6 | "echo" ["echo" "hello"] 7 | 8 | "project" ["project"] 9 | "projecta" ["project" "a"] 10 | 11 | "pa2project" ["with-profile" "+a2" "project"] 12 | "pa2projecta" ["with-profile" "+a2" "project" "a"] 13 | 14 | "a2project" ["with-profile" "a2" "project"] 15 | "a2projecta" ["with-profile" "a2" "project" "a"]} 16 | :a 1 17 | :profiles {:a2 {:aliases {"q" ["echo" "q"] 18 | "inp-projecta" ["project" "a"]} 19 | :a 2}}) 20 | -------------------------------------------------------------------------------- /test_projects/lein-test-reload-bug/test/lein_test_reload_bug/core_test.clj: -------------------------------------------------------------------------------- 1 | (prn "loading" 'lein-test-reload-bug.core-test) 2 | 3 | (ns lein-test-reload-bug.core-test 4 | (:require [clojure.test :refer [deftest is]] 5 | [lein-test-reload-bug.a-deftype :refer [->A]] 6 | [lein-test-reload-bug.b-protocol :refer [b]])) 7 | 8 | (deftest a-test 9 | (let [a (->A)] 10 | (prn "The current hash of interface lein_test_reload_bug.b_protocol.B is" (hash lein_test_reload_bug.b_protocol.B)) 11 | (prn "The current instance of A implements lein_test_reload_bug.b_protocol.B with [name hash]:" 12 | (-> (into {} 13 | (map (juxt #(.getName ^Class %) hash)) 14 | (-> a class supers)) 15 | (find "lein_test_reload_bug.b_protocol.B"))) 16 | (is (= :ok (b a))))) 17 | -------------------------------------------------------------------------------- /resources/leiningen/new/template/README.md: -------------------------------------------------------------------------------- 1 | # {{name}} 2 | 3 | A Leiningen template for FIXME. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © {{year}} FIXME 12 | 13 | This program and the accompanying materials are made available under the 14 | terms of the Eclipse Public License 2.0 which is available at 15 | http://www.eclipse.org/legal/epl-2.0. 16 | 17 | This Source Code may also be made available under the following Secondary 18 | Licenses when the conditions for such availability set forth in the Eclipse 19 | Public License, v. 2.0 are satisfied: GNU General Public License as published by 20 | the Free Software Foundation, either version 2 of the License, or (at your 21 | option) any later version, with the GNU Classpath Exception which is available 22 | at https://www.gnu.org/software/classpath/license.html. 23 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/README.md: -------------------------------------------------------------------------------- 1 | # {{name}} 2 | 3 | A Clojure library designed to ... well, that part is up to you. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © {{year}} FIXME 12 | 13 | This program and the accompanying materials are made available under the 14 | terms of the Eclipse Public License 2.0 which is available at 15 | http://www.eclipse.org/legal/epl-2.0. 16 | 17 | This Source Code may also be made available under the following Secondary 18 | Licenses when the conditions for such availability set forth in the Eclipse 19 | Public License, v. 2.0 are satisfied: GNU General Public License as published by 20 | the Free Software Foundation, either version 2 of the License, or (at your 21 | option) any later version, with the GNU Classpath Exception which is available 22 | at https://www.gnu.org/software/classpath/license.html. 23 | -------------------------------------------------------------------------------- /test/leiningen/test/install.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.install 2 | (:require [leiningen.core.user :as user]) 3 | (:use [clojure.test] 4 | [leiningen.install] 5 | [leiningen.test.helper] 6 | [clojure.java.io :only [file]])) 7 | 8 | (deftest ^:online test-install 9 | (unmemoize #'leiningen.core.classpath/get-dependencies-memoized 10 | #'leiningen.core.classpath/get-dependencies*) 11 | (delete-file-recursively (m2-dir "nomnomnom" "0.5.0-SNAPSHOT") true) 12 | (install sample-project) 13 | (is (not (empty? (.listFiles (m2-dir "nomnomnom" "0.5.0-SNAPSHOT")))))) 14 | 15 | (def tricky-m2-dir (file local-repo "org" "domain" "tricky-name" "1.0")) 16 | 17 | (deftest ^:online test-tricky-name-install 18 | (delete-file-recursively tricky-m2-dir true) 19 | (install tricky-name-project) 20 | (is (not (empty? (.listFiles tricky-m2-dir))))) 21 | -------------------------------------------------------------------------------- /resources/leiningen/new/app/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | - Add a new arity to `make-widget-async` to provide a different widget shape. 7 | 8 | ## [0.1.1] - {{date}} 9 | ### Changed 10 | - Documentation on how to make the widgets. 11 | 12 | ### Removed 13 | - `make-widget-sync` - we're all async, all the time. 14 | 15 | ### Fixed 16 | - Fixed widget maker to keep working when daylight savings switches over. 17 | 18 | ## 0.1.0 - {{date}} 19 | ### Added 20 | - Files from the new template. 21 | - Widget maker public API - `make-widget-sync`. 22 | 23 | [Unreleased]: https://sourcehost.site/your-name/{{name}}/compare/0.1.1...HEAD 24 | [0.1.1]: https://sourcehost.site/your-name/{{name}}/compare/0.1.0...0.1.1 25 | -------------------------------------------------------------------------------- /src/leiningen/classpath.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.classpath 2 | "Print the classpath of the current project." 3 | (:require [leiningen.core.classpath :as classpath] 4 | [leiningen.core.main :as main] 5 | [clojure.string :as str]) 6 | (:import (org.eclipse.aether.resolution DependencyResolutionException))) 7 | 8 | (defn get-classpath-string [project] 9 | (try 10 | (str/join java.io.File/pathSeparatorChar (classpath/get-classpath project)) 11 | (catch DependencyResolutionException e 12 | (main/abort (.getMessage e))))) 13 | 14 | (defn classpath 15 | "Write the classpath of the current project to output-file. 16 | 17 | With no arguments, print the classpath to stdout. 18 | 19 | Suitable for java's -cp option." 20 | ([project] 21 | (println (get-classpath-string project))) 22 | ([project output-file] 23 | (spit output-file (get-classpath-string project)))) 24 | -------------------------------------------------------------------------------- /resources/leiningen/new/default/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | - Add a new arity to `make-widget-async` to provide a different widget shape. 7 | 8 | ## [0.1.1] - {{date}} 9 | ### Changed 10 | - Documentation on how to make the widgets. 11 | 12 | ### Removed 13 | - `make-widget-sync` - we're all async, all the time. 14 | 15 | ### Fixed 16 | - Fixed widget maker to keep working when daylight savings switches over. 17 | 18 | ## 0.1.0 - {{date}} 19 | ### Added 20 | - Files from the new template. 21 | - Widget maker public API - `make-widget-sync`. 22 | 23 | [Unreleased]: https://sourcehost.site/your-name/{{name}}/compare/0.1.1...HEAD 24 | [0.1.1]: https://sourcehost.site/your-name/{{name}}/compare/0.1.0...0.1.1 25 | -------------------------------------------------------------------------------- /resources/leiningen/new/plugin/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | - Add a new arity to `make-widget-async` to provide a different widget shape. 7 | 8 | ## [0.1.1] - {{date}} 9 | ### Changed 10 | - Documentation on how to make the widgets. 11 | 12 | ### Removed 13 | - `make-widget-sync` - we're all async, all the time. 14 | 15 | ### Fixed 16 | - Fixed widget maker to keep working when daylight savings switches over. 17 | 18 | ## 0.1.0 - {{date}} 19 | ### Added 20 | - Files from the new template. 21 | - Widget maker public API - `make-widget-sync`. 22 | 23 | [Unreleased]: https://sourcehost.site/your-name/{{name}}/compare/0.1.1...HEAD 24 | [0.1.1]: https://sourcehost.site/your-name/{{name}}/compare/0.1.0...0.1.1 25 | -------------------------------------------------------------------------------- /resources/leiningen/new/template/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). 3 | 4 | ## [Unreleased] 5 | ### Changed 6 | - Add a new arity to `make-widget-async` to provide a different widget shape. 7 | 8 | ## [0.1.1] - {{date}} 9 | ### Changed 10 | - Documentation on how to make the widgets. 11 | 12 | ### Removed 13 | - `make-widget-sync` - we're all async, all the time. 14 | 15 | ### Fixed 16 | - Fixed widget maker to keep working when daylight savings switches over. 17 | 18 | ## 0.1.0 - {{date}} 19 | ### Added 20 | - Files from the new template. 21 | - Widget maker public API - `make-widget-sync`. 22 | 23 | [Unreleased]: https://source-host.site/your-name/{{name}}/compare/0.1.1...HEAD 24 | [0.1.1]: https://source-host.site/your-name/{{name}}/compare/0.1.0...0.1.1 25 | -------------------------------------------------------------------------------- /test/leiningen/test/vcs.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.vcs 2 | (:require [clojure.test :refer :all] 3 | [leiningen.vcs :as vcs])) 4 | 5 | (deftest parsed-args 6 | (testing "VCS tag argument parsing" 7 | (are [args parsed-args] (= (vcs/parse-tag-args args) parsed-args) 8 | [] {:sign? true :annotate? true} 9 | ["v"] {:prefix "v" :sign? true :annotate? true} 10 | ["v" "--sign"] {:prefix "v" :sign? true :annotate? true} 11 | ["--sign"] {:sign? true :annotate? true} 12 | ["--no-sign"] {:sign? false :annotate? true} 13 | ["--no-sign" "v"] {:prefix "v" :sign? false :annotate? true} 14 | ["--no-annotate"] {:sign? true :annotate? false} 15 | ["--annotate"] {:sign? true :annotate? true} 16 | ["--no-sign" "--no-annotate" "v"] {:sign? false :annotate? false :prefix "v"} 17 | ["-s"] {:sign? true :annotate? true} 18 | ["v" "r"] {:prefix "r" :sign? true :annotate? true}))) 19 | -------------------------------------------------------------------------------- /test/leiningen/test/jvm_opts.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.jvm-opts 2 | (:require [leiningen.with-profile :refer [with-profile]] 3 | [leiningen.test.helper :refer [jvm-opts-project 4 | with-system-out-str]]) 5 | (:use clojure.test)) 6 | 7 | ;; This is a regression test for technomancy/leiningen#1676 (make sure 8 | ;; that file.encoding can be overriden by profiles.) 9 | (deftest file-encoding-conveyed 10 | (let [exec '(println "system encoding" (System/getProperty "file.encoding")) 11 | run-with #(with-system-out-str 12 | (with-profile jvm-opts-project % "run" 13 | "-m" "clojure.main" 14 | "-e" (pr-str exec)))] 15 | (testing "baseline sane" 16 | (is (.contains (run-with "+no-op") "system encoding UTF-8"))) 17 | (testing "accepts alternative" 18 | (is (.contains (run-with "+ascii") "system encoding ASCII"))))) 19 | -------------------------------------------------------------------------------- /lein-pprint/test/leiningen/test/pprint.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.pprint 2 | (:require [clojure.test :refer :all] 3 | [leiningen.pprint :refer :all])) 4 | 5 | (def project {:foo {:bar "str"}}) 6 | 7 | (defn check [desc keys output] 8 | (is (= output (with-out-str (apply pprint project keys)))) desc) 9 | 10 | (defn check-no-pretty [desc keys output] 11 | (check desc (concat ["--no-pretty" "--"] keys) output)) 12 | 13 | (deftest test-pprint 14 | (check "pretty-print a key" [":foo"] "{:bar \"str\"}\n") 15 | 16 | (check-no-pretty "print a key" [":foo"] "{:bar str}\n") 17 | 18 | (check "pretty-print a sequence" ["[:foo :bar]"] "\"str\"\n") 19 | 20 | (check-no-pretty "print a sequence" ["[:foo :bar]"] "str\n") 21 | 22 | (check "pretty-print a project" [] "{:foo {:bar \"str\"}}\n") 23 | 24 | (check-no-pretty "print a project" [] "{:foo {:bar str}}\n") 25 | 26 | (check "pretty-print multiple" [":foo" "[:foo :bar]"] "{:bar \"str\"}\n\"str\"\n") 27 | 28 | (check-no-pretty "print multiple" [":foo" "[:foo :bar]"] "{:bar str}\nstr\n")) 29 | -------------------------------------------------------------------------------- /web/stylesheets/lein.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px 0 200px 0; 3 | } 4 | 5 | h1, h2, h3, h4, h5, h6 { 6 | font-family: "Bitter", serif; 7 | font-weight: 400; 8 | } 9 | 10 | nav#links { 11 | margin-top: 149px; 12 | } 13 | 14 | /* nav#links > a { float: left; } */ 15 | /* nav#links > a + a:before { display: block; float: left; content: ' | '; } */ 16 | 17 | .constant { 18 | color: #25536D; 19 | } 20 | 21 | a, a:visited { 22 | color: #25536D; 23 | text-decoration: none; 24 | border-bottom: 1px solid; 25 | } 26 | 27 | a:hover, a:focus { 28 | color: black; 29 | } 30 | 31 | 32 | p { 33 | text-align: justify; 34 | -webkit-hyphens: auto; 35 | -moz-hyphens: auto; 36 | } 37 | 38 | p#pitch { 39 | text-align: left; 40 | } 41 | 42 | pre, tt, kbd, code { 43 | font-family: 'Inconsolata', 'Consolas', mono; 44 | } 45 | 46 | #sample-project { 47 | font-size: 16px; 48 | } 49 | 50 | hr { 51 | margin: 35px 0; 52 | } 53 | 54 | h3 { 55 | margin: 21px 0; 56 | } 57 | 58 | #footer p { 59 | text-align: center; 60 | } 61 | -------------------------------------------------------------------------------- /lein-pprint/src/leiningen/pprint.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.pprint 2 | (:require [clojure.pprint :as pprint])) 3 | 4 | (defn- parse-flags [args] 5 | (let [[flag separator & rest] args] 6 | (if (= [flag separator] ["--no-pretty" "--"]) 7 | [println rest] 8 | [pprint/pprint args]))) 9 | 10 | (defn- get-values [project keys] 11 | (if (seq keys) 12 | (map #(let [key (read-string %) 13 | f (if (sequential? key) get-in get)] 14 | (f project key)) keys) 15 | [project])) 16 | 17 | (defn ^:no-project-needed pprint 18 | "Usage: pprint [--no-pretty] [--] [selector...] 19 | 20 | When no selectors are specified, pretty-prints a representation of 21 | the entire project map. Otherwise pretty-prints the item(s) 22 | retrieved by (get-in project selector) when reading a selector 23 | produces something sequential, or (get project selector) when it 24 | doesn't. If \"--no-pretty\" is specified, doesn't pretty-print, 25 | just prints." 26 | [project & args] 27 | (let [[show keys] (parse-flags args)] 28 | (run! show (get-values project keys))) 29 | (flush)) 30 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/core/test/mirrors.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.core.test.mirrors 2 | (:require [clojure.test :refer :all] 3 | [cemerick.pomegranate :as pom] 4 | [leiningen.core.project :refer [defproject init-project]])) 5 | 6 | 7 | ;; Regression test for Issue #1555 8 | (defproject mirrors-work-ok-with-plugins-project "0.0.0" 9 | ;; we need to use a sequence of pairs rather than a map to 10 | ;; reproduce the bug; IRL maps got converted to seqs somehow or 11 | ;; another anyhow, but apparently not by init-project. 12 | :mirrors [["central" {:name "foo" 13 | :url "https://repo1.maven.org/maven2/"}]] 14 | ;; Have to have a plugin to reproduce 15 | :plugins [[lein-pprint "1.1.1"]]) 16 | 17 | (deftest ^:online mirrors-work-ok-with-plugins 18 | ;; turn off add-classpath so we don't actually mutate the classpath; 19 | ;; we're still hitting the internet, and there's probably something 20 | ;; in pomegranate we could redef to prevent that, but I haven't 21 | ;; figured out what it is exactly. 22 | (with-redefs [pom/add-classpath (constantly nil)] 23 | (is (init-project project)))) 24 | -------------------------------------------------------------------------------- /src/leiningen/new/plugin.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.new.plugin 2 | (:require [leiningen.new.templates :refer [renderer sanitize year date ->files]] 3 | [leiningen.core.main :as main])) 4 | 5 | (defn plugin 6 | "A leiningen plugin project template." 7 | [^String name] 8 | (let [render (renderer "plugin") 9 | unprefixed (if (.startsWith name "lein-") 10 | (subs name 5) 11 | name) 12 | data {:name name 13 | :unprefixed-name unprefixed 14 | :sanitized (sanitize unprefixed) 15 | :year (year) 16 | :date (date)}] 17 | (main/info (str "Generating a fresh Leiningen plugin called " name ".")) 18 | (->files data 19 | ["project.clj" (render "project.clj" data)] 20 | ["README.md" (render "README.md" data)] 21 | [".gitignore" (render "gitignore" data)] 22 | [".hgignore" (render "hgignore" data)] 23 | ["src/leiningen/{{sanitized}}.clj" (render "name.clj" data)] 24 | ["LICENSE" (render "LICENSE" data)] 25 | ["CHANGELOG.md" (render "CHANGELOG.md" data)]))) 26 | -------------------------------------------------------------------------------- /leiningen-core/project.clj: -------------------------------------------------------------------------------- 1 | (defproject leiningen-core "2.9.7-SNAPSHOT" 2 | :url "https://github.com/technomancy/leiningen" 3 | :license {:name "Eclipse Public License" 4 | :url "http://www.eclipse.org/legal/epl-v10.html"} 5 | :description "Library for core functionality of Leiningen." 6 | ;; If you update these, update resources/leiningen/bootclasspath-deps.clj too 7 | :dependencies [[org.clojure/clojure "1.10.1"] 8 | [timofreiberg/bultitude "0.3.0" 9 | :exclusions [org.clojure/clojure]] 10 | [org.flatland/classlojure "0.7.1"] 11 | [robert/hooke "1.3.0"] 12 | [clj-commons/pomegranate "1.2.1" 13 | :exclusions [org.slf4j/jcl-over-slf4j]] 14 | [com.hypirion/io "0.3.1"] 15 | [org.slf4j/slf4j-nop "1.7.25"] ; wagon-http uses slf4j 16 | ;; we pull this in transitively but want a newer version 17 | [org.clojure/tools.macro "0.1.5"]] 18 | :scm {:dir ".."} 19 | :dev-resources-path "dev-resources" 20 | :aliases {"bootstrap" ["with-profile" "base" 21 | "do" "install," "classpath" ".lein-bootstrap"]}) 22 | -------------------------------------------------------------------------------- /resources/leiningen/new/app/README.md: -------------------------------------------------------------------------------- 1 | # {{name}} 2 | 3 | FIXME: description 4 | 5 | ## Installation 6 | 7 | Download from http://example.com/FIXME. 8 | 9 | ## Usage 10 | 11 | FIXME: explanation 12 | 13 | $ java -jar {{name}}-0.1.0-standalone.jar [args] 14 | 15 | ## Options 16 | 17 | FIXME: listing of options this app accepts. 18 | 19 | ## Examples 20 | 21 | ... 22 | 23 | ### Bugs 24 | 25 | ... 26 | 27 | ### Any Other Sections 28 | ### That You Think 29 | ### Might be Useful 30 | 31 | ## License 32 | 33 | Copyright © {{year}} FIXME 34 | 35 | This program and the accompanying materials are made available under the 36 | terms of the Eclipse Public License 2.0 which is available at 37 | http://www.eclipse.org/legal/epl-2.0. 38 | 39 | This Source Code may also be made available under the following Secondary 40 | Licenses when the conditions for such availability set forth in the Eclipse 41 | Public License, v. 2.0 are satisfied: GNU General Public License as published by 42 | the Free Software Foundation, either version 2 of the License, or (at your 43 | option) any later version, with the GNU Classpath Exception which is available 44 | at https://www.gnu.org/software/classpath/license.html. 45 | -------------------------------------------------------------------------------- /resources/leiningen/new/plugin/README.md: -------------------------------------------------------------------------------- 1 | # {{name}} 2 | 3 | A Leiningen plugin to do many wonderful things. 4 | 5 | ## Usage 6 | 7 | FIXME: Use this for user-level plugins: 8 | 9 | Put `[{{name}} "0.1.0-SNAPSHOT"]` into the `:plugins` vector of your `:user` 10 | profile. 11 | 12 | FIXME: Use this for project-level plugins: 13 | 14 | Put `[{{name}} "0.1.0-SNAPSHOT"]` into the `:plugins` vector of your project.clj. 15 | 16 | FIXME: and add an example usage that actually makes sense: 17 | 18 | $ lein {{unprefixed-name}} 19 | 20 | ## License 21 | 22 | Copyright © {{year}} FIXME 23 | 24 | This program and the accompanying materials are made available under the 25 | terms of the Eclipse Public License 2.0 which is available at 26 | http://www.eclipse.org/legal/epl-2.0. 27 | 28 | This Source Code may also be made available under the following Secondary 29 | Licenses when the conditions for such availability set forth in the Eclipse 30 | Public License, v. 2.0 are satisfied: GNU General Public License as published by 31 | the Free Software Foundation, either version 2 of the License, or (at your 32 | option) any later version, with the GNU Classpath Exception which is available 33 | at https://www.gnu.org/software/classpath/license.html. 34 | -------------------------------------------------------------------------------- /test_projects/sample/project.clj: -------------------------------------------------------------------------------- 1 | (def clj-version "1.3.0") 2 | 3 | (defproject nomnomnom "0.5.0-SNAPSHOT" 4 | :description "A test project" 5 | :url "http://leiningen.org" 6 | :license {:name "Eclipse Public License" 7 | :url "http://www.eclipse.org/legal/epl-v10.html"} 8 | :dependencies [[~(symbol "org.clojure" "clojure") ~clj-version] 9 | [rome ~(str "0." "9")] 10 | [ring "1.0.0"]] 11 | :plugins [[codox "0.6.4"]] 12 | :main nom.nom.nom 13 | :global-vars {*warn-on-reflection* true} 14 | :jar-exclusions [#"^META-INF"] 15 | :filespecs [{:type :fn :fn (fn [p] {:type :bytes :path "bytes.clj" 16 | :bytes (str "[:bytes \"are\" " 17 | (:name p) "]")})}] 18 | :test-selectors {:integration :integration 19 | :default (complement :integration) 20 | :random (fn [_] (> (rand) ~(float 1/2)))} 21 | :repositories [["other" {:url "http://example.com/repo" 22 | :update :always 23 | :releases {:checksum :warn}}]] 24 | :deploy-repositories {"snapshots" ~(format "file://%s/lein-repo" 25 | (System/getProperty "java.io.tmpdir"))}) 26 | -------------------------------------------------------------------------------- /bin/issues.clj: -------------------------------------------------------------------------------- 1 | ;; This is just a one-off tool to classify/summarize issues programmatically. 2 | 3 | (try (require 'tentacles.issues) 4 | (catch java.io.FileNotFoundException _ 5 | (cemerick.pomegranate/add-dependencies 6 | :repositories [["clojars" {:url "https://clojars.org/repo/"}]] 7 | :coordinates '[[tentacles "0.2.7"]]) 8 | (require 'tentacles.issues))) 9 | 10 | (defn labeled? [label issue] (some #(= (:name %) label) (:labels issue))) 11 | (def low-priority? #{1566 1544 1319 1363 1155}) 12 | (def order ["2.4.3" "other" "Enhancement" "docs" "low" "3.0.0"]) 13 | 14 | (defn categorize [i] 15 | (cond (labeled? "Windows" i) nil 16 | (:title (:milestone i)) (:title (:milestone i)) 17 | (labeled? "Enhancement" i) "Enhancement" 18 | (labeled? "docs" i) "docs" 19 | (low-priority? (:number i)) "low" 20 | :else "other")) 21 | 22 | (defn report [] 23 | (doseq [[category issues] (->> (tentacles.issues/issues 24 | "technomancy" "leiningen") 25 | (group-by categorize) 26 | (sort-by #(.indexOf order (key %)))) 27 | :when category] 28 | (println "\n#" category) 29 | (doseq [i issues] 30 | (println (:number i) "-" (:title i))))) 31 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/core/test/utils.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.core.test.utils 2 | (:require [leiningen.core.utils :as utils] 3 | [clojure.test :refer [deftest testing is]] 4 | [clojure.java.io :as io])) 5 | 6 | (def profiles "./leiningen-core/test/resources/") 7 | 8 | (def sample-profile {:user {:plugins '[[lein-pprint "1.1.1"]]}}) 9 | 10 | (deftest read-profiles 11 | (testing "Empty profile file" 12 | (is (nil? (utils/read-file (io/file (str profiles "profiles-empty.clj")))))) 13 | (testing "Non-empty profile file" 14 | (is (= (utils/read-file (io/file (str profiles "profiles.clj"))) sample-profile)))) 15 | 16 | (deftest properties-strip-comments 17 | (with-open [baos (java.io.ByteArrayOutputStream.)] 18 | (let [properties (doto (java.util.Properties.) 19 | (.setProperty "version" "0.1.0-SNAPSHOT") 20 | (.setProperty "groupId" "groupId") 21 | (.setProperty "artifactId" "(:name project)"))] 22 | (.store properties baos "Extra comment") 23 | (let [str (-> baos 24 | str 25 | utils/strip-properties-comments)] 26 | (with-open [input-stream (io/input-stream (.getBytes str))] 27 | (is (= properties (doto (java.util.Properties.) (.load input-stream))))))))) -------------------------------------------------------------------------------- /test/.gnupg/trustdb.gpg: -------------------------------------------------------------------------------- 1 | gpg^=i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test_projects/managed-deps-snapshot/project.clj: -------------------------------------------------------------------------------- 1 | (def clj-version "1.3.0") 2 | 3 | (defproject mgmt "0.99.0-SNAPSHOT" 4 | :description "A test project" 5 | 6 | :managed-dependencies [[~(symbol "org.clojure" "clojure") ~clj-version] 7 | [rome ~(str "0." "9")] 8 | [ring/ring "1.0.0"] 9 | [ring/ring-codec "1.0.1"] 10 | [ring/ring-headers "0.2.0"] 11 | [commons-math/commons-math "1.2" :classifier "sources"] 12 | [org.apache.commons/commons-csv "1.4" :classifier "sources"] 13 | [ring/ring-defaults "0.2.1"] 14 | [org.clojure/tools.reader "1.0.0-beta3"]] 15 | 16 | :dependencies [[org.clojure/clojure] 17 | [rome/rome nil] 18 | [ring] 19 | [ring/ring-codec nil :exclusions [commons-codec]] 20 | [ring/ring-headers :exclusions [ring/ring-core]] 21 | [commons-codec "1.6"] 22 | [commons-math nil :classifier "sources"] 23 | [org.apache.commons/commons-csv :classifier "sources"] 24 | [org.clojure/tools.emitter.jvm "0.1.0-beta5"] ; depends on tools.reader 0.8.5 25 | [org.clojure/tools.namespace "0.3.0-alpha3"] ; depends on tools.reader 0.10.0 26 | ]) 27 | -------------------------------------------------------------------------------- /test/leiningen/test/update_in.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.update-in 2 | (:refer-clojure :exclude [update-in]) 3 | (:use clojure.test leiningen.update-in)) 4 | 5 | (defn- prj-map [p] (with-meta p {:without-profiles p})) 6 | 7 | (deftest test-update-in 8 | (doseq 9 | [[in-args task-form] 10 | (->> [[(prj-map {:version "1.0.0"}) 11 | ":" "assoc" ":version" "\"2.0.0\"" "--" "jar"] 12 | ["jar" (prj-map {:version "2.0.0"})] 13 | 14 | [(prj-map {:repl-options {:port 1}}) 15 | ":repl-options:port" "inc" "--" "repl" ":headless"] 16 | ["repl" (prj-map {:repl-options {:port 2}}) ":headless"] 17 | 18 | [(prj-map {:dependencies [['clojure.core (clojure-version)]]}) 19 | ":dependencies" "conj" "[slamhound \"1.1.3\"]" "--" "repl"] 20 | ["repl" (prj-map {:dependencies [['clojure.core (clojure-version)] 21 | ['slamhound "1.1.3"]]})]] 22 | (partition 2))] 23 | (let [[in-prj key-path f & args] in-args 24 | [keys-vec f f-args [task-name & task-args]] 25 | (parse-args key-path f args) 26 | out-prj (update-project in-prj keys-vec f f-args)] 27 | (is (= task-form (concat [task-name out-prj] task-args))) 28 | (is (= (meta (second task-form)) (meta out-prj)))))) 29 | -------------------------------------------------------------------------------- /src/leiningen/install.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.install 2 | "Install the current project to the local repository." 3 | (:require [cemerick.pomegranate.aether :as aether] 4 | [leiningen.core.project :as project] 5 | [leiningen.core.main :as main] 6 | [leiningen.jar :as jar] 7 | [leiningen.pom :as pom] 8 | [clojure.java.io :as io]) 9 | (:import (java.util.jar JarFile) 10 | (java.util UUID))) 11 | 12 | (defn install 13 | "Install jar and pom to the local repository; typically ~/.m2. 14 | 15 | In order to install arbitrary files into a repository see the deploy task." 16 | [project] 17 | (when (not (or (:install-releases? project true) 18 | (pom/snapshot? project))) 19 | (main/abort "Can't install release artifacts when :install-releases?" 20 | "is set to false.")) 21 | (let [jarfiles (jar/jar project) 22 | pomfile (pom/pom project) 23 | local-repo (:local-repo project)] 24 | (aether/install 25 | :coordinates [(symbol (:group project) (:name project)) 26 | (:version project)] 27 | :artifact-map jarfiles 28 | :pom-file (io/file pomfile) 29 | :local-repo local-repo) 30 | (main/info (str "Installed jar and pom into " (if local-repo 31 | local-repo "local repo") ".")))) 32 | -------------------------------------------------------------------------------- /test/leiningen/test/do.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.do 2 | (:refer-clojure :exclude [do]) 3 | (:use [clojure.test] 4 | [leiningen.do])) 5 | 6 | (deftest test-group-args-empty-args 7 | (is (= [] (group-args [])))) 8 | 9 | (deftest test-group-args-single-task 10 | (is (= [["pom"]] (group-args ["pom"])))) 11 | 12 | (deftest test-group-args-without-args 13 | (is (= [["clean"] ["deps"] ["test"]] 14 | (group-args ["clean," "deps," "test"])))) 15 | 16 | (deftest test-group-args-with-args 17 | (is (= [["test" "test-core"] ["version"]] 18 | (group-args ["test" "test-core," "version"])))) 19 | 20 | (deftest test-group-args-with-long-chain 21 | (is (= [["help" "help"] ["help" "version"] ["version"] 22 | ["test" "test-compile"]] 23 | (group-args '("help" "help," "help" "version," "version," 24 | "test" "test-compile"))))) 25 | 26 | (deftest test-group-existing-collections 27 | (is (= [["clean"] ["test" ":integration"] '("deploy" "clojars")] 28 | (group-args ["clean" ["test" ":integration"] 29 | '("deploy" "clojars")]))) 30 | (is (= [["foo" "bar"] ["baz" "quux"]] 31 | (group-args [["foo" "bar"] ["baz" "quux"]]))) 32 | (is (= [["foo" "bar"] ["baz"]] 33 | (group-args [["foo" "bar"] "baz"]))) 34 | (is (= [["combinations"] ["work"] ["as" "well"]] 35 | (group-args ["combinations," "work" ["as" "well"]])))) 36 | -------------------------------------------------------------------------------- /src/leiningen/do.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.do 2 | "Higher-order task to perform other tasks in succession." 3 | (:refer-clojure :exclude [do]) 4 | (:require [leiningen.core.main :as main])) 5 | 6 | (defn- conj-to-last [coll x] 7 | (update-in coll [(dec (count coll))] conj x)) 8 | 9 | (defn- butlast-char 10 | "Removes the last character in the string." 11 | [s] 12 | (subs s 0 (dec (count s)))) 13 | 14 | (defn- pop-if-last 15 | "Pops the collection if (pred (peek coll)) is truthy." 16 | [coll pred] 17 | (if (pred (peek coll)) 18 | (pop coll) 19 | coll)) 20 | 21 | (defn ^:internal group-args 22 | ([args] (-> (reduce group-args [[]] args) 23 | (pop-if-last empty?))) 24 | ([groups arg] 25 | (cond (coll? arg) (-> (pop-if-last groups empty?) 26 | (conj arg [])) 27 | (.endsWith arg ",") (-> groups 28 | (conj-to-last (butlast-char arg)) 29 | (conj [])) 30 | :else (conj-to-last groups arg)))) 31 | 32 | (defn ^:no-project-needed ^:higher-order do 33 | "Higher-order task to perform other tasks in succession. 34 | 35 | Each comma-separated group should be a task name followed by optional arguments. 36 | 37 | USAGE: lein do test, compile :all, deploy private-repo" 38 | [project & args] 39 | (doseq [arg-group (group-args args)] 40 | (main/resolve-and-apply project arg-group))) 41 | -------------------------------------------------------------------------------- /src/leiningen/new/app.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.new.app 2 | "Generate a basic application project." 3 | (:require [leiningen.new.templates :refer [renderer year date project-name 4 | ->files sanitize-ns name-to-path 5 | multi-segment]] 6 | [leiningen.core.main :as main])) 7 | 8 | (defn app 9 | "An application project template." 10 | [name] 11 | (let [render (renderer "app") 12 | main-ns (multi-segment (sanitize-ns name)) 13 | data {:raw-name name 14 | :name (project-name name) 15 | :namespace main-ns 16 | :nested-dirs (name-to-path main-ns) 17 | :year (year) 18 | :date (date)}] 19 | (main/info "Generating a project called" name "based on the 'app' template.") 20 | (->files data 21 | ["project.clj" (render "project.clj" data)] 22 | ["README.md" (render "README.md" data)] 23 | ["doc/intro.md" (render "intro.md" data)] 24 | [".gitignore" (render "gitignore" data)] 25 | [".hgignore" (render "hgignore" data)] 26 | ["src/{{nested-dirs}}.clj" (render "core.clj" data)] 27 | ["test/{{nested-dirs}}_test.clj" (render "test.clj" data)] 28 | ["LICENSE" (render "LICENSE" data)] 29 | ["CHANGELOG.md" (render "CHANGELOG.md" data)] 30 | "resources"))) 31 | -------------------------------------------------------------------------------- /test_projects/managed-deps/project.clj: -------------------------------------------------------------------------------- 1 | (def clj-version "1.3.0") 2 | 3 | (defproject mgmt "0.99.0" 4 | :description "A test project" 5 | 6 | :managed-dependencies [[~(symbol "org.clojure" "clojure") ~clj-version] 7 | [rome ~(str "0." "9")] 8 | [ring/ring "1.0.0"] 9 | [ring/ring-codec "1.0.1"] 10 | [ring/ring-headers "0.2.0"] 11 | [commons-math/commons-math "1.2" :classifier "sources"] 12 | [org.apache.commons/commons-csv "1.4" :classifier "sources"] 13 | [ring/ring-defaults "0.2.1"] 14 | [org.clojure/tools.reader "1.0.0-beta3"]] 15 | 16 | :dependencies [[org.clojure/clojure] 17 | [rome/rome nil] 18 | [ring] 19 | [ring/ring-codec nil :exclusions [commons-codec]] 20 | [ring/ring-headers :exclusions [ring/ring-core]] 21 | [commons-codec "1.6"] 22 | [commons-math nil :classifier "sources"] 23 | [org.apache.commons/commons-csv :classifier "sources"] 24 | [org.clojure/tools.emitter.jvm "0.1.0-beta5"] ; depends on tools.reader 0.8.5 25 | [org.clojure/tools.namespace "0.3.0-alpha3"] ; depends on tools.reader 0.10.0 26 | ] 27 | 28 | :profiles {:add-deps {:dependencies [[org.clojure/clojure]]} 29 | :replace-deps {:dependencies ^:replace [[org.clojure/clojure]]}}) 30 | -------------------------------------------------------------------------------- /lein-pprint/README.md: -------------------------------------------------------------------------------- 1 | # lein-pprint 2 | 3 | Pretty-print a representation of the project map. 4 | 5 | This is a sample of how a simple plugin would work. 6 | 7 | ## Usage 8 | 9 | Add `[lein-pprint "1.3.2"]` to `:plugins`. 10 | 11 | ```bash 12 | $ lein pprint 13 | ``` 14 | 15 | ```clj 16 | {:compile-path "/home/phil/src/leiningen/lein-pprint/classes", 17 | :group "lein-pprint", 18 | :source-path ("/home/phil/src/leiningen/lein-pprint/src"), 19 | :dependencies nil, 20 | :target-path "/home/phil/src/leiningen/lein-pprint/target", 21 | :name "lein-pprint", 22 | :root "/home/phil/src/leiningen/lein-pprint", 23 | :version "1.0.0", 24 | :jar-exclusions [#"^\."], 25 | :test-path ("/home/phil/src/leiningen/lein-pprint/test"), 26 | :repositories 27 | (["central" {:url "https://repo1.maven.org/maven2"}] 28 | ["clojars" {:url "https://repo.clojars.org/"}]), 29 | :uberjar-exclusions [#"^META-INF/DUMMY.SF"], 30 | :eval-in :leiningen, 31 | :plugins [[lein-swank "1.4.0-SNAPSHOT"]], 32 | :resources-path 33 | ("/home/phil/src/leiningen/lein-pprint/dev-resources" 34 | "/home/phil/src/leiningen/lein-pprint/resources"), 35 | :native-path "/home/phil/src/leiningen/lein-pprint/native", 36 | :description "Pretty-print a representation of the project map."} 37 | ``` 38 | 39 | Use the `--no-pretty` flag to just print rather than pretty-print. 40 | 41 | ```bash 42 | $ lein pprint :version 43 | "1.0.0" 44 | $ lein pprint --no-pretty -- :version 45 | 1.0.0 46 | ``` 47 | 48 | ## License 49 | 50 | Copyright © 2012-2020 Phil Hagelberg and contributors. 51 | 52 | Distributed under the Eclipse Public License, the same as Clojure. 53 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | clojure: 5 | docker: 6 | - image: clojure:<< parameters.java_version >>-lein 7 | parameters: 8 | java_version: 9 | description: "Java version" 10 | default: "openjdk-11" 11 | type: string 12 | working_directory: ~/leiningen 13 | 14 | jobs: 15 | build: 16 | executor: clojure 17 | parameters: 18 | java_version: 19 | description: "Java version" 20 | default: << parameters.java_version >> 21 | type: string 22 | steps: 23 | - checkout 24 | - restore_cache: 25 | key: leiningen-{{ checksum "project.clj" }} 26 | - run: apt update -qq && apt install -y gnupg 27 | - run: 28 | name: Bootstrap leiningen-core 29 | working_directory: ~/leiningen/leiningen-core 30 | command: lein bootstrap 31 | - run: 32 | name: Test Leiningen 33 | environment: 34 | GNUPGHOME: test/.gnupg 35 | command: bin/lein test 36 | - run: 37 | name: Test lein-pprint 38 | working_directory: lein-pprint 39 | command: lein test 40 | - save_cache: 41 | paths: 42 | - $HOME/.m2 43 | - $HOME/.lein 44 | key: leiningen-{{ checksum "project.clj" }} 45 | 46 | workflows: 47 | test-with-matrix: 48 | jobs: 49 | - build: 50 | name: "openjdk8" 51 | java_version: "openjdk-8" 52 | - build: 53 | name: "openjdk11" 54 | java_version: "openjdk-11" 55 | - build: 56 | name: "openjdk16" 57 | java_version: "openjdk-16" 58 | -------------------------------------------------------------------------------- /src/leiningen/check.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.check 2 | "Check syntax and warn on reflection." 3 | (:require [leiningen.core.eval :as eval] 4 | [leiningen.core.main :as main] 5 | [bultitude.core :as b] 6 | [clojure.java.io :as io])) 7 | 8 | (defn check 9 | "Check syntax and warn on reflection." 10 | ([project] 11 | (let [source-files (map io/file (:source-paths project)) 12 | nses (sort (b/namespaces-on-classpath :classpath source-files 13 | :ignore-unreadable? false)) 14 | action `(let [failures# (atom 0)] 15 | (doseq [ns# '~nses] 16 | ;; load will add the .clj, so can't use ns/path-for. 17 | (let [ns-file# (-> (str ns#) 18 | (.replace \- \_) 19 | (.replace \. \/))] 20 | (binding [*out* *err*] 21 | (println "Compiling namespace" ns#)) 22 | (try 23 | (binding [*warn-on-reflection* true] 24 | (load ns-file#)) 25 | (catch ExceptionInInitializerError e# 26 | (swap! failures# inc) 27 | (.printStackTrace e#))))) 28 | (if-not (zero? @failures#) 29 | (System/exit @failures#)))] 30 | (try 31 | (binding [eval/*pump-in* false] 32 | (eval/eval-in-project project action)) 33 | (catch clojure.lang.ExceptionInfo e 34 | (main/abort "Failed.")))))) 35 | -------------------------------------------------------------------------------- /src/leiningen/new/default.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.new.default 2 | "Generate a library project." 3 | (:require [leiningen.new.templates :refer [renderer year date project-name 4 | ->files sanitize-ns name-to-path 5 | multi-segment]] 6 | [leiningen.core.main :as main])) 7 | 8 | (defn default 9 | "A general project template for libraries. 10 | 11 | Accepts a group id in the project name: `lein new foo.bar/baz`" 12 | [name] 13 | (let [render (renderer "default") 14 | main-ns (multi-segment (sanitize-ns name)) 15 | data {:raw-name name 16 | :name (project-name name) 17 | :namespace main-ns 18 | :nested-dirs (name-to-path main-ns) 19 | :year (year) 20 | :date (date)}] 21 | (main/info "Generating a project called" name "based on the 'default' template.") 22 | (main/info "The default template is intended for library projects, not applications.") 23 | (main/info "To see other templates (app, plugin, etc), try `lein help new`.") 24 | (->files data 25 | ["project.clj" (render "project.clj" data)] 26 | ["README.md" (render "README.md" data)] 27 | ["doc/intro.md" (render "intro.md" data)] 28 | [".gitignore" (render "gitignore" data)] 29 | [".hgignore" (render "hgignore" data)] 30 | ["src/{{nested-dirs}}.clj" (render "core.clj" data)] 31 | ["test/{{nested-dirs}}_test.clj" (render "test.clj" data)] 32 | ["LICENSE" (render "LICENSE" data)] 33 | ["CHANGELOG.md" (render "CHANGELOG.md" data)] 34 | "resources"))) 35 | -------------------------------------------------------------------------------- /bash_completion.bash: -------------------------------------------------------------------------------- 1 | _lein_completion() { 2 | local cur prev tasks 3 | COMPREPLY=() 4 | cur="${COMP_WORDS[COMP_CWORD]}" 5 | prev="${COMP_WORDS[COMP_CWORD-1]}" 6 | tasks="change check classpath clean compile deploy deps do help install jar javac new plugin pom release repl retest run search show-profiles test trampoline uberjar update-in upgrade vcs version with-profile" 7 | 8 | case "${prev}" in 9 | change | check | classpath | clean | deploy | deps | do | install | jar | javac | new | plugin | pom | release | repl | show-profiles | uberjar | update-in | vcs | version) 10 | COMPREPLY=() 11 | ;; 12 | help) 13 | # Show tasks again, but only once; don't infinitely recurse 14 | local prev2="${COMP_WORDS[COMP_CWORD-2]}" 15 | if [ "$prev2" == "help" ]; then 16 | COMPREPLY=() 17 | else 18 | COMPREPLY=( $(compgen -W "${tasks}" -- ${cur}) ) 19 | fi 20 | ;; 21 | test | retest ) 22 | # list project's test namespaces: 23 | local namespaces=$(find test/ -type f -name "*.clj" -exec sed -n 's/^(ns[ ]*//p' '{}' '+') 24 | COMPREPLY=( $(compgen -W "${namespaces}" -- ${cur}) ) 25 | ;; 26 | run | compile) 27 | # list project's src namespaces: 28 | local namespaces=$(find src/ -type f -name "*.clj" -exec sed -n 's/^(ns[ ]*//p' '{}' '+') 29 | COMPREPLY=( $(compgen -W "${namespaces}" -- ${cur}) ) 30 | ;; 31 | lein) 32 | COMPREPLY=( $(compgen -W "${tasks}" -- ${cur}) ) 33 | ;; 34 | esac 35 | 36 | return 0 37 | } 38 | complete -F _lein_completion lein 39 | -------------------------------------------------------------------------------- /test/leiningen/test/javac.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.javac 2 | (:use [clojure.test] 3 | [clojure.java.io :only [file]] 4 | [leiningen.javac :only [javac normalize-javac-options]] 5 | [leiningen.test.helper :only [delete-file-recursively 6 | #_dev-deps-project]])) 7 | 8 | (deftest test-javac-options-normalization 9 | (testing "that Leiningen 2 style options are returned unmodified" 10 | (are [arg] (= arg (normalize-javac-options arg)) 11 | ["-target" "1.6" "-source" "1.6"] 12 | ["-deprecation" "-g"])) 13 | (testing "conversion of Leiningen 1 style options that are supported" 14 | (are [old new] (= new (normalize-javac-options old)) 15 | {:debug false} ["-g:none"] 16 | {:debug "off"} ["-g:none"] 17 | ;; overriden by :compile-path 18 | {:destdir "clazzez"} [] 19 | {:encoding "utf8"} ["-encoding" "utf8"] 20 | {:debugLevel "source,lines"} ["-g:source,lines"])) 21 | (testing "conversion of multiple Leiningen 1 style options" 22 | ;; Cannot assume argument order from hash maps 23 | (are [old new] (= new 24 | (apply hash-map (normalize-javac-options old))) 25 | {:source "1.5" :target "1.5"} {"-target" "1.5" "-source" "1.5"} 26 | {:source 1.5 "target" 1.5} {"-target" "1.5" "-source" "1.5"}))) 27 | 28 | (deftest ^:disabled ; not really; need to fix this 29 | test-javac 30 | #_(delete-file-recursively (:compile-path dev-deps-project) true) 31 | #_(javac dev-deps-project) 32 | (is (.exists (file "test_projects/dev-deps-only/classes" 33 | "dev_deps_only" "Junk.class"))) 34 | (is (.exists (file "test_projects/dev-deps-only/classes" 35 | "dev_deps_only" "Junk2.class")))) 36 | -------------------------------------------------------------------------------- /src/leiningen/update_in.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.update-in 2 | "Perform arbitrary transformations on your project map." 3 | (:refer-clojure :exclude [update-in]) 4 | (:require [leiningen.core.main :as main] 5 | [leiningen.core.project :as project] 6 | [leiningen.core.utils :as utils] 7 | [clojure.core :as clj])) 8 | 9 | (defn ^:internal parse-args [key-path f args] 10 | (let [[f-args [_ & task+args]] (split-with #(not= "--" %) args)] 11 | [(mapv keyword (rest (.split key-path ":"))) 12 | (utils/require-resolve (read-string f)) 13 | (mapv read-string f-args) 14 | task+args])) 15 | 16 | (defn ^:internal update-project [project keys-vec f args] 17 | (let [f #(if (seq keys-vec) 18 | (apply clj/update-in % keys-vec f args) 19 | (apply f % args))] 20 | (-> (vary-meta (f project) clj/update-in [:without-profiles] f) 21 | (project/load-plugins) 22 | (project/activate-middleware)))) 23 | 24 | (defn ^:higher-order ^:no-project-needed update-in 25 | "Perform arbitrary transformations on your project map. 26 | 27 | Acts a lot like calling `clojure.core/update-in` on your project map 28 | and then invoking a task on it, but with a few differences. Instead of 29 | a vector of keys for reaching into nested maps, just mash keywords 30 | together like \":repl-options:port\". A single \":\" refers to the map 31 | root. Provide the arguments to f (which must be a resolvable var) 32 | followed by \"--\", and then the task name and arguments to the task: 33 | 34 | $ lein update-in :dependencies conj \"[slamhound \\\"1.1.3\\\"]\" -- repl" 35 | [project key-path f & args] 36 | (let [[keys-vec f f-args task+args] (parse-args key-path f args)] 37 | (main/resolve-and-apply (update-project project keys-vec f f-args) 38 | task+args))) 39 | -------------------------------------------------------------------------------- /src/leiningen/new/template.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.new.template 2 | (:require [clojure.string :as str] 3 | [leiningen.new.templates :as t] 4 | [leiningen.core.main :as main])) 5 | 6 | (defn template 7 | "A meta-template for 'lein new' templates." 8 | [template-name] 9 | (when-not (namespace (symbol template-name)) 10 | (main/warn (str "Template names must use a group-id to conform with new" 11 | " Clojars security policy:\n" 12 | "https://github.com/clojars/clojars-web/wiki/Verified-Group-Names" 13 | "\n\nYou may generate this template but you may not be" 14 | " able to publish it on Clojars."))) 15 | (let [render (t/renderer "template") 16 | sym (symbol template-name) 17 | data {:name template-name 18 | :artifact-id (name sym) 19 | ;; if there's no group-id we need to leave out the slash 20 | :group-prefix (if-let [group-id (namespace sym)] 21 | (str group-id "/")) 22 | :sanitized (t/name-to-path (name sym)) 23 | :placeholder "{{sanitized}}" 24 | :year (t/year) 25 | :date (t/date)}] 26 | (main/info "Generating fresh 'lein new' template project.") 27 | (t/->files data 28 | ["README.md" (render "README.md" data)] 29 | ["project.clj" (render "project.clj" data)] 30 | [".gitignore" (render "gitignore" data)] 31 | [".hgignore" (render "hgignore" data)] 32 | ["src/leiningen/new/{{sanitized}}.clj" (render "temp.clj" data)] 33 | ["resources/leiningen/new/{{sanitized}}/foo.clj" (render "foo.clj")] 34 | ["LICENSE" (render "LICENSE" data)] 35 | ["CHANGELOG.md" (render "CHANGELOG.md" data)]))) 36 | -------------------------------------------------------------------------------- /web/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | Your Page Title Here :) 12 | 13 | 14 | 17 | 18 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 40 |
41 |

Sorry. Couldn't Find That Page!

42 |
43 | 44 | 46 | 47 | -------------------------------------------------------------------------------- /web/stylesheets/layout.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V1.1 3 | * Copyright 2011, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8/17/2011 8 | */ 9 | 10 | /* Table of Content 11 | ================================================== 12 | #Site Styles 13 | #Page Styles 14 | #Media Queries 15 | #Font-Face */ 16 | 17 | /* #Site Styles 18 | ================================================== */ 19 | 20 | /* #Page Styles 21 | ================================================== */ 22 | 23 | /* #Media Queries 24 | ================================================== */ 25 | 26 | /* Smaller than standard 960 (devices and browsers) */ 27 | @media only screen and (max-width: 959px) {} 28 | 29 | /* Tablet Portrait size to standard 960 (devices and browsers) */ 30 | @media only screen and (min-width: 768px) and (max-width: 959px) {} 31 | 32 | /* All Mobile Sizes (devices and browser) */ 33 | @media only screen and (max-width: 767px) {} 34 | 35 | /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ 36 | @media only screen and (min-width: 480px) and (max-width: 767px) {} 37 | 38 | /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ 39 | @media only screen and (max-width: 479px) {} 40 | 41 | 42 | /* #Font-Face 43 | ================================================== */ 44 | /* This is the proper syntax for an @font-face file 45 | Just create a "fonts" folder at the root, 46 | copy your FontName into code below and remove 47 | comment brackets */ 48 | 49 | /* @font-face { 50 | font-family: 'FontName'; 51 | src: url('../fonts/FontName.eot'); 52 | src: url('../fonts/FontName.eot?iefix') format('eot'), 53 | url('../fonts/FontName.woff') format('woff'), 54 | url('../fonts/FontName.ttf') format('truetype'), 55 | url('../fonts/FontName.svg#webfontZam02nTh') format('svg'); 56 | font-weight: normal; 57 | font-style: normal; } 58 | */ -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a report to help us improve 4 | --- 5 | 6 | **Initial debugging steps** 7 | Before creating a report, _especially_ around exceptions being thrown when running Leiningen, please check if the error still occurs after: 8 | 9 | - [ ] Updating to using the latest released version of Leiningen (`lein upgrade`). 10 | - [ ] Moving your `~/.lein/profiles.clj` (if present) out of the way. This contains third-party dependencies and plugins that can cause problems inside Leiningen. 11 | - [ ] Updating any old versions of plugins in your `project.clj`, especially if the problem is with a plugin not working. Old versions of plugins like nREPL and CIDER (as well as others) can cause problems with newer versions of Leiningen. 12 | - [ ] (If you are using Java 9 or newer), updating your dependencies to their most recent versions. Recent JDK's have introduced changes which can break some Clojure libraries. 13 | 14 | **Describe the bug** 15 | A clear and concise description of what the bug is. 16 | 17 | **To Reproduce** 18 | Steps to reproduce the behavior: 19 | 1. Go to '...' 20 | 2. Run the command '...' 21 | 3. See error 22 | 23 | **Actual behavior** 24 | What actually happened? 25 | 26 | **Expected behavior** 27 | A clear and concise description of what you expected to happen. 28 | 29 | **Link to sample project** 30 | If relevant, please provide a link to a project or a `project.clj` that others can use to help debug the issue. 31 | 32 | **Logs** 33 | If applicable, add logs to help explain your problem, including the command that you ran. If the logs are very large, please put them in a [gist](https://gist.github.com/). 34 | 35 | **Environment** 36 | - Leiningen Version: [e.g. 2.9.0]. Get this by running `lein version`. 37 | - Leiningen installation method: [e.g. Homebrew, apt, manual]. 38 | - JDK Version: [e.g. openjdk version "11.0.1"]. Get this by running `java -version`. 39 | - OS: [e.g. Ubuntu 18.04, macOS 10.14]. 40 | - Anything else that might be relevant to your problem? 41 | 42 | **Additional context** 43 | Add any other context you have about the problem here. Did this work previously on older versions of Leiningen, or older JDK's? 44 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | ;; This is Leiningen's own project configuration. See doc/TUTORIAL.md 2 | ;; file as well as sample.project.clj for help writing your own. 3 | 4 | (defproject leiningen "2.9.7-SNAPSHOT" 5 | :description "Automate Clojure projects without setting your hair on fire." 6 | :url "https://github.com/technomancy/leiningen" 7 | :license {:name "Eclipse Public License" 8 | :url "http://www.eclipse.org/legal/epl-v10.html"} 9 | ;; If you update these, update resources/leiningen/bootclasspath-deps.clj too 10 | :dependencies [[leiningen-core "2.9.5"] 11 | ;; needed for pom 12 | [org.clojure/data.xml "0.2.0-alpha5"] 13 | ;; needed for test 14 | [timofreiberg/bultitude "0.3.0" 15 | :exclusions [org.clojure/clojure]] 16 | ;; needed for new 17 | [stencil "0.5.0" :exclusions [org.clojure/core.cache]] 18 | ;; needed for uberjar 19 | [commons-lang "2.6"] 20 | ;; needed for repl 21 | [nrepl "0.8.3"] 22 | ;; needed for change 23 | [org.clojars.trptcolin/sjacket "0.1.1.1" :exclusions [org.clojure/clojure]] 24 | ;; bump versions of various common transitive deps 25 | [net.cgrand/parsley "0.9.3" :exclusions [org.clojure/clojure]] 26 | [scout "0.1.1"] 27 | [commons-io "2.8.0"] 28 | [org.apache.httpcomponents/httpclient "4.5.13"] 29 | [org.apache.httpcomponents/httpcore "4.4.13"]] 30 | :pedantic? :abort 31 | ;; checkout-deps don't work with :eval-in :leiningen 32 | :profiles {:dev {:resource-paths ["leiningen-core/dev-resources"] 33 | :test-paths ["leiningen-core/test"]} 34 | :uberjar {:aot [#"leiningen" 35 | leiningen.core.ssl ; lazy-loaded 36 | cemerick.pomegranate 37 | classlojure.core 38 | nrepl.core]}} 39 | :test-selectors {:default (complement :disabled) 40 | :offline (comp (partial not-any? identity) 41 | (juxt :online :disabled))} 42 | :source-paths ["leiningen-core/src" "src"] 43 | :eval-in :leiningen) 44 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/core/test/user.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.core.test.user 2 | (:use clojure.test 3 | leiningen.core.user)) 4 | 5 | (deftest resolving-repo-creds 6 | (with-redefs [credentials (constantly {#"^https://clojars\.org/.*" 7 | {:username "u" :password "p" 8 | :passphrase "looooong" 9 | :private-key-file "./somewhere"}})] 10 | (testing "Literal creds unmolested" 11 | (is (= (resolve-credentials {:url "https://clojars.org/repo" 12 | :username "easily" :password "stolen"}) 13 | {:url "https://clojars.org/repo" 14 | :username "easily" :password "stolen"}))) 15 | (testing "Lookup in environment" 16 | (with-redefs [getenv {"LEIN_USERNAME" "flynn" 17 | "CUSTOMENV" "flotilla"}] 18 | (is (= (resolve-credentials {:url "https://clojars.org/repo" 19 | :username :env 20 | :password :env/customenv}) 21 | {:url "https://clojars.org/repo" 22 | :username "flynn" :password "flotilla"})))) 23 | (testing "Check multiple locations" 24 | (with-redefs [getenv {"LEIN_USERNAME" "flynn" 25 | "CUSTOMENV" "flotilla"}] 26 | (is (= (resolve-credentials {:url "https://clojars.org/repo" 27 | :username [:gpg :env] 28 | :password [:env/customenv :gpg]}) 29 | {:url "https://clojars.org/repo" 30 | :username "u" :password "flotilla"})))) 31 | (testing "Custom keys unmolested (and :creds expanded)" 32 | (is (= (resolve-credentials {:url "https://clojars.org/repo" 33 | :creds :gpg 34 | :foo [:gpg "0x00D85767"]}) 35 | {:url "https://clojars.org/repo" 36 | :username "u" :password "p" 37 | :passphrase "looooong" :private-key-file "./somewhere" 38 | :foo [:gpg "0x00D85767"]}))) 39 | (testing "Pulls string out when env/gpg are absent" 40 | (let [settings {:url "https://clojars.private" 41 | :username [:gpg :env/circle_jars_username "ACTUAL"]}] 42 | (is (= "ACTUAL" (:username (resolve-credentials settings)))))))) 43 | 44 | -------------------------------------------------------------------------------- /src/leiningen/search.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.search 2 | "Search Central and Clojars for published artifacts." 3 | (:require [clojure.string :as string] 4 | [clojure.xml :as xml] 5 | [leiningen.core.project :as project] 6 | [leiningen.core.main :as main]) 7 | (:import (java.net URLEncoder))) 8 | 9 | (defn- decruft-central-xml [content] 10 | (zipmap (map #(get-in % [:attrs :name]) content) 11 | (map #(get-in % [:content 0]) content))) 12 | 13 | (defn parse [url] 14 | (try (xml/parse url) 15 | (catch Exception e 16 | (main/warn "Could not retrieve search results from" url "because of" 17 | (class e)) 18 | (when main/*debug* 19 | (.printStackTrace e))))) 20 | 21 | (defn search-central [query] 22 | (let [url (str "https://search.maven.org/solrsearch/select?wt=xml&q=" query)] 23 | (doseq [doc (get-in (parse url) [:content 1 :content])] 24 | (let [result (decruft-central-xml (:content doc)) 25 | dep (if (= (result "a") (result "g")) 26 | (result "a") 27 | (str (result "g") "/" (result "a")))] 28 | (println (format "[%s \"%s\"]" dep (result "latestVersion"))))))) 29 | 30 | (defn search-clojars [query] 31 | (let [url (str "https://clojars.org/search?format=xml&q=" query)] 32 | (doseq [{result :attrs} (:content (parse url))] 33 | (let [dep (if (= (result :jar_name) (result :group_name)) 34 | (result :jar_name) 35 | (str (result :group_name) "/" (result :jar_name)))] 36 | (println (format "[%s \"%s\"]" dep (result :version))) 37 | (when-let [desc (and (not= (string/trim (result :description "")) "") 38 | (result :description))] 39 | (println " " (string/trim (first (string/split desc #"\n"))))))))) 40 | 41 | (defn ^:no-project-needed search 42 | "Search Central and Clojars for published artifacts." 43 | [project query] 44 | (let [project (or project (project/make {})) 45 | repos (into {} (:repositories project))] 46 | (doseq [[repo searcher] [["central" search-central] 47 | ["clojars" search-clojars]]] 48 | (when (repos repo) 49 | (try (println "Searching" repo "...") 50 | (searcher (URLEncoder/encode query "UTF-8")) 51 | (catch java.io.IOException e 52 | (binding [*out* *err*] 53 | (if (re-find #"HTTP response code: (400|505)" (str e)) 54 | (println "Query syntax unsupported.") 55 | (println "Remote error" (.getMessage e)))))))))) 56 | -------------------------------------------------------------------------------- /test/leiningen/test/help.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.help 2 | (:use [leiningen.help] 3 | [clojure.test])) 4 | 5 | (def formatted-docstring @#'leiningen.help/formatted-docstring) 6 | (def get-subtasks-and-docstrings-for 7 | @#'leiningen.help/get-subtasks-and-docstrings-for) 8 | (def formatted-help @#'leiningen.help/formatted-help) 9 | (def resolve-task @#'leiningen.help/resolve-task) 10 | 11 | (deftest blank-subtask-help-for-pom 12 | (let [subtask-pom (apply subtask-help-for (resolve-task "pom"))] 13 | (is (= nil subtask-pom)))) 14 | 15 | (deftest subtask-help-for-new 16 | (let [subtask-help (apply subtask-help-for (resolve-task "new"))] 17 | (is (re-find #"Subtasks available" subtask-help)) 18 | (is (re-find #"default\s+A general project template." subtask-help)) 19 | (is (re-find #"plugin\s+A leiningen plugin project template." subtask-help)) 20 | (is (re-find #"template\s+A meta-template for 'lein new' templates." 21 | subtask-help)))) 22 | 23 | (deftest subtask-help-for-new-default 24 | (let [subtask-help (help-for-subtask "new" "default")] 25 | (is (re-find #"^A general project template." subtask-help)) 26 | (is (re-find #"Arguments: \(\[name\]\)" subtask-help)))) 27 | 28 | (deftest test-docstring-formatting 29 | (is (= "This is an 30 | AWESOME command 31 | For real!" 32 | (formatted-docstring 33 | "install" 34 | "This is an\n AWESOME command\nFor real!" 5)))) 35 | 36 | (deftest test-formatted-help 37 | (is (= "install This is an 38 | AWESOME command 39 | For real!" 40 | (formatted-help "install" "This is an\nAWESOME command\nFor real!" 15)))) 41 | 42 | (deftest ^:disabled test-get-subtasks 43 | (let [m (get-subtasks-and-docstrings-for (second (resolve-task "plugin")))] 44 | (is (= ["install" "uninstall"] 45 | (sort (keys m)))))) 46 | 47 | (deftest test-alias-docstrings 48 | (testing "default alias docstrings" 49 | (is (re-find #"is an alias for" (help-for {} "--version"))) 50 | (is (re-find #"is an alias" (help-for {} "-o"))) 51 | (is (re-find #"not found" (help-for {} "not-a-task")))) 52 | (testing "own alias docstrings" 53 | (let [custom-aliases {:aliases {"foobar" ^{:doc "Foos the bar."} 54 | ["foo" "bar"], 55 | "vsn" "version" 56 | "multipart" ["multi" "part"]}}] 57 | (is (re-find #"is an alias for" (help-for custom-aliases "vsn"))) 58 | (is (re-find #"is an alias" (help-for custom-aliases "multipart"))) 59 | (is (re-find #"Foos the bar\." (help-for custom-aliases "foobar"))) 60 | (is (re-find #"not found" (help-for custom-aliases "not-a-task")))))) 61 | -------------------------------------------------------------------------------- /src/leiningen/trampoline.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.trampoline 2 | "Run a task without nesting the project's JVM inside Leiningen's." 3 | (:refer-clojure :exclude [trampoline]) 4 | (:require [clojure.string :as string] 5 | [leiningen.core.eval :as eval] 6 | [leiningen.core.main :as main] 7 | [leiningen.core.utils :as utils] 8 | [leiningen.core.project :as project] 9 | [clojure.java.io :as io] 10 | [clojure.pprint :as pprint])) 11 | 12 | (def ^:dynamic *trampoline?* false) 13 | 14 | (defn- trampoline-file [] 15 | (System/getenv "TRAMPOLINE_FILE")) 16 | 17 | (defn- win-batch? [] 18 | (if-let [t (trampoline-file)] 19 | (.endsWith t ".bat"))) 20 | 21 | (defn- quote-arg [arg] 22 | (if (win-batch?) 23 | (format "\"%s\"" arg) 24 | (format "'%s'" arg))) 25 | 26 | (defn trampoline-command-string [project forms profiles] 27 | ;; each form is (do init & body) 28 | (let [forms (map rest forms) ;; strip off do 29 | inits (map first forms) 30 | rests (mapcat rest forms) 31 | command (eval/shell-command project (concat '(do) inits rests))] 32 | (string/join " " (map quote-arg command)))) 33 | 34 | (defn write-trampoline [project forms profiles] 35 | (let [command (trampoline-command-string project forms profiles) 36 | trampoline (trampoline-file)] 37 | (main/debug "Trampoline command:" command) 38 | (utils/mkdirs (.getParentFile (io/file trampoline))) 39 | (spit trampoline command))) 40 | 41 | (defn ^:higher-order trampoline 42 | "Run a task without nesting the project's JVM inside Leiningen's. 43 | 44 | Calculates the Clojure code to run in the project's process for the 45 | given task and allows Leiningen's own JVM process to exit before 46 | running it rather than launching a subprocess of Leiningen's JVM. 47 | 48 | Use this to save memory or to work around stdin issues. 49 | 50 | Note that this can be unpredictable on account of collapsing all 51 | eval-in-project calls into one run. For example, tasks chained 52 | together under different profiles end up all running together." 53 | 54 | [project task-name & args] 55 | (when (= :leiningen (:eval-in project)) 56 | (main/info "Warning: trampoline has no effect with :eval-in-leiningen.")) 57 | (binding [*trampoline?* true] 58 | (main/apply-task (main/lookup-alias task-name project) 59 | (-> (assoc project :eval-in :trampoline) 60 | (vary-meta update-in [:without-profiles] assoc 61 | :eval-in :trampoline)) 62 | args)) 63 | (if (seq @eval/trampoline-forms) 64 | (write-trampoline @eval/trampoline-project 65 | @eval/trampoline-forms 66 | @eval/trampoline-profiles) 67 | (main/abort task-name "did not run any project code for trampolining."))) 68 | -------------------------------------------------------------------------------- /web/img/favicon/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /resources/leiningen/bootclasspath-deps.clj: -------------------------------------------------------------------------------- 1 | ;; This file is used to warn users when they attempt to load a plugin that 2 | ;; pulls in a dependency which conflicts with something already in use 3 | ;; by Leiningen itself. 4 | 5 | ;; This code regenerates the map 6 | #_(do (require '[leiningen.core.project :as project]) 7 | (require '[leiningen.core.classpath :as cp]) 8 | (require '[clojure.pprint :as pp]) 9 | 10 | (defn artifacts [h] 11 | (apply concat (keys h) (map artifacts (vals h)))) 12 | 13 | (let [hierarchy (cp/managed-dependency-hierarchy :dependencies 14 | :managed-dependencies 15 | (project/read))] 16 | (-> (into {} (for [[a v] (artifacts hierarchy)] 17 | [a v])) 18 | ;; Unhelpful to warn on these: 19 | (dissoc 'org.clojure/clojure) 20 | (dissoc 'leiningen-core) 21 | (pp/pprint)))) 22 | { 23 | clj-commons/pomegranate "1.2.0" 24 | clojure-complete "0.2.5" 25 | com.hypirion/io "0.3.1" 26 | commons-codec "1.11" 27 | commons-io "2.8.0" 28 | commons-lang "2.6" 29 | commons-logging "1.2" 30 | javax.inject "1" 31 | net.cgrand/parsley "0.9.3" 32 | net.cgrand/regex "1.1.0" 33 | nrepl "0.8.3" 34 | org.apache.commons/commons-lang3 "3.8.1" 35 | org.apache.httpcomponents/httpclient "4.5.13" 36 | org.apache.httpcomponents/httpcore "4.4.13" 37 | org.apache.maven.resolver/maven-resolver-api "1.3.3" 38 | org.apache.maven.resolver/maven-resolver-connector-basic "1.3.3" 39 | org.apache.maven.resolver/maven-resolver-impl "1.3.3" 40 | org.apache.maven.resolver/maven-resolver-spi "1.3.3" 41 | org.apache.maven.resolver/maven-resolver-transport-file "1.3.3" 42 | org.apache.maven.resolver/maven-resolver-transport-http "1.3.3" 43 | org.apache.maven.resolver/maven-resolver-transport-wagon "1.3.3" 44 | org.apache.maven.resolver/maven-resolver-util "1.3.3" 45 | org.apache.maven.wagon/wagon-http "3.3.2" 46 | org.apache.maven.wagon/wagon-http-shared "3.3.2" 47 | org.apache.maven.wagon/wagon-provider-api "3.3.2" 48 | org.apache.maven/maven-artifact "3.6.1" 49 | org.apache.maven/maven-builder-support "3.6.1" 50 | org.apache.maven/maven-model "3.6.1" 51 | org.apache.maven/maven-model-builder "3.6.1" 52 | org.apache.maven/maven-repository-metadata "3.6.1" 53 | org.apache.maven/maven-resolver-provider "3.6.1" 54 | org.clojars.trptcolin/sjacket "0.1.1.1" 55 | org.clojure/core.specs.alpha "0.2.44" 56 | org.clojure/data.codec "0.1.0" 57 | org.clojure/data.xml "0.2.0-alpha5" 58 | org.clojure/spec.alpha "0.2.176" 59 | org.clojure/tools.macro "0.1.5" 60 | org.codehaus.plexus/plexus-component-annotations "1.7.1" 61 | org.codehaus.plexus/plexus-interpolation "1.25" 62 | org.codehaus.plexus/plexus-utils "3.2.0" 63 | org.flatland/classlojure "0.7.1" 64 | org.jsoup/jsoup "1.11.3" 65 | org.slf4j/slf4j-api "1.7.25" 66 | org.slf4j/slf4j-nop "1.7.25" 67 | org.tcrawley/dynapath "1.0.0" 68 | quoin "0.1.2" 69 | robert/hooke "1.3.0" 70 | scout "0.1.1" 71 | stencil "0.5.0" 72 | timofreiberg/bultitude "0.3.0" 73 | } 74 | -------------------------------------------------------------------------------- /zsh_completion.zsh: -------------------------------------------------------------------------------- 1 | #compdef lein 2 | 3 | # Lein ZSH completion function 4 | # Drop this somewhere in your $fpath (like /usr/share/zsh/site-functions) 5 | # and rename it _lein 6 | 7 | _lein() { 8 | if (( CURRENT > 2 )); then 9 | # shift words so _arguments doesn't have to be concerned with second command 10 | (( CURRENT-- )) 11 | shift words 12 | # use _call_function here in case it doesn't exist 13 | _call_function 1 _lein_${words[1]} 14 | else 15 | _values "lein command" \ 16 | "change[Rewrite project.clj by applying a function.]" \ 17 | "check[Check syntax and warn on reflection.]" \ 18 | "classpath[Print the classpath of the current project.]" \ 19 | "clean[Remove all files from project's target-path.]" \ 20 | "compile[Compile Clojure source into .class files.]" \ 21 | "deploy[Build and deploy jar to remote repository.]" \ 22 | "deps[Download all dependencies.]" \ 23 | "do[Higher-order task to perform other tasks in succession.]" \ 24 | "help[Display a list of tasks or help for a given task.]" \ 25 | "install[Install the current project to the local repository.]" \ 26 | "jar[Package up all the project's files into a jar file.]" \ 27 | "javac[Compile Java source files.]" \ 28 | "new[Generate project scaffolding based on a template.]" \ 29 | "plugin[DEPRECATED. Please use the :user profile instead.]" \ 30 | "pom[Write a pom.xml file to disk for Maven interoperability.]" \ 31 | "release[Perform :release-tasks.]" \ 32 | "repl[Start a repl session either with the current project or standalone.]" \ 33 | "retest[Run only the test namespaces which failed last time around.]" \ 34 | "run[Run a -main function with optional command-line arguments.]" \ 35 | "search[Search remote maven repositories for matching jars.]" \ 36 | "show-profiles[List all available profiles or display one if given an argument.]" \ 37 | "test[Run the project's tests.]" \ 38 | "trampoline[Run a task without nesting the project's JVM inside Leiningen's.]" \ 39 | "uberjar[Package up the project files and dependencies into a jar file.]" \ 40 | "update-in[Perform arbitrary transformations on your project map.]" \ 41 | "upgrade[Upgrade Leiningen to specified version or latest stable.]" \ 42 | "vcs[Interact with the version control system.]" \ 43 | "version[Print version for Leiningen and the current JVM.]" \ 44 | "with-profile[Apply the given task with the profile(s) specified.]" 45 | fi 46 | } 47 | 48 | _lein_plugin() { 49 | _values "lein plugin commands" \ 50 | "install[Download, package, and install plugin jarfile into ~/.lein/plugins]" \ 51 | "uninstall[Delete the plugin jarfile: \[GROUP/\]ARTIFACT-ID VERSION]" 52 | } 53 | 54 | 55 | _lein_namespaces() { 56 | if [ -f "./project.clj" -a -d "$1" ]; then 57 | _values "lein valid namespaces" \ 58 | $(find "$1" -type f -name "*.clj" -exec awk '/^\(ns */ {gsub("\\)", "", $2); print $2}' '{}' '+') 59 | fi 60 | } 61 | 62 | 63 | _lein_run() { 64 | _lein_namespaces "src/" 65 | } 66 | 67 | _lein_test() { 68 | _lein_namespaces "test/" 69 | } 70 | 71 | -------------------------------------------------------------------------------- /bin/release: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -u 4 | 5 | if [ "$1" = "" ]; then 6 | echo "usage: $0 VERSION" 7 | exit 1 8 | fi 9 | 10 | RELEASE_VERSION=$1 11 | CURRENT_VERSION="$RELEASE_VERSION-SNAPSHOT" 12 | 13 | # Would like to use `lein release` here, but we don't have a way to 14 | # update the bash scripts or watch for boot slowdowns that way. Maybe 15 | # try adding lein-shell? 16 | 17 | if [ ! -x `which lein-stable` ]; then 18 | echo "Install a stable version of Leiningen as lein-stable." 19 | exit 1 20 | fi 21 | 22 | grep $RELEASE_VERSION NEWS.md || (echo "Add $RELEASE_VERSION to NEWS.md" && exit 1) 23 | 24 | lein vcs assert-committed 25 | 26 | for f in bin/lein bin/lein-pkg bin/lein-sdkman bin/lein.bat bin/lein.ps1 project.clj leiningen-core/project.clj; do 27 | sed -i s/$CURRENT_VERSION/$RELEASE_VERSION/ $f 28 | done 29 | 30 | rm -rf target classes leiningen-core/target leiningen-core/classes leiningen-core/lib 31 | rm -rf $HOME/.lein/self-installs/leiningen-$RELEASE_VERSION-standalone.jar 32 | 33 | LEIN_ROOT=$PWD 34 | 35 | echo "Bootstrapping..." 36 | cd leiningen-core 37 | lein-stable do clean, bootstrap 38 | cd .. 39 | 40 | echo "Generating uberjar..." 41 | 42 | bin/lein uberjar 43 | RELEASE_JAR=$PWD/target/leiningen-$RELEASE_VERSION-standalone.jar 44 | RELEASE_JAR_CHECKSUM="$(sha256sum $RELEASE_JAR | awk '{ print $1 }')" 45 | SELF_INSTALL_JAR=$HOME/.lein/self-installs/$(basename $RELEASE_JAR) 46 | cp $RELEASE_JAR $SELF_INSTALL_JAR 47 | 48 | sed -i "s/export LEIN_CHECKSUM=.*/export LEIN_CHECKSUM='$RELEASE_JAR_CHECKSUM'/" bin/lein 49 | cp bin/lein /tmp/lein-$RELEASE_VERSION 50 | cd /tmp 51 | 52 | if [ ! -r test-project ]; then 53 | ./lein-$RELEASE_VERSION new test-project 54 | fi 55 | 56 | cd test-project 57 | 58 | echo "Running a few invocations in order to check boot time..." 59 | 60 | time ../lein-$RELEASE_VERSION run -m clojure.main/main -e nil 61 | time ../lein-$RELEASE_VERSION run -m clojure.main/main -e nil 62 | time ../lein-$RELEASE_VERSION run -m clojure.main/main -e nil 63 | 64 | echo "Check that these are about the same boot times as with the last version." 65 | echo "Run this in a project: time lein-stable run -m clojure.main/main -e nil" 66 | echo "Proceeding here will publish the new version to the git repo." 67 | echo "Are these acceptable times? (~3s) [Y\n]" 68 | read CONTINUE 69 | case "$CONTINUE" in 70 | y|Y|"") 71 | gpg -ab $RELEASE_JAR;; 72 | *) 73 | echo "Aborted." 74 | exit 1;; 75 | esac 76 | 77 | cd $LEIN_ROOT 78 | 79 | git commit -a -m "Release $RELEASE_VERSION" 80 | git tag -s $RELEASE_VERSION -m "Release $RELEASE_VERSION" 81 | git push && git push --tags && git push origin master:stable 82 | 83 | echo "Upload $SELF_INSTALL_JAR and $SELF_INSTALL_JAR.asc to GitHub" 84 | echo "but rename the jar to .zip first to work around GitHub foolishness." 85 | echo "https://github.com/technomancy/leiningen/releases/tag/$RELEASE_VERSION" 86 | echo "Copy this version's section of NEWS.md to the GitHub release description." 87 | 88 | rm -rf target leiningen-core/target 89 | echo "Test self-install. If things are good, run this:" 90 | echo "$ lein deploy clojars && cd leiningen-core && lein deploy clojars" 91 | echo "" 92 | echo "Then bump the version to the next SNAPSHOT." 93 | -------------------------------------------------------------------------------- /test/leiningen/test/new/templates.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.new.templates 2 | (:use clojure.test 3 | leiningen.new.templates) 4 | (:require [leiningen.test.helper :refer [abort-msg] :as lthelper] 5 | [leiningen.core.user :as user] 6 | [clojure.java.io :as io]) 7 | (:import [java.io File])) 8 | 9 | (defn- getenv [s] 10 | (System/getenv s)) 11 | 12 | (deftest line-separators 13 | (testing "that nothing changes when we're on unix systems" 14 | (with-redefs [user/getprop (constantly "\n")] 15 | (is (= (fix-line-separators "foo") "foo")) 16 | (is (= (fix-line-separators "bar\nbaz") "bar\nbaz")) 17 | (is (= (fix-line-separators "quux\n\n\nsycorax") "quux\n\n\nsycorax")))) 18 | 19 | (testing "that newlines are correctly converted on '\\r\\n' systems" 20 | (with-redefs [user/getprop (constantly "\r\n")] 21 | (is (= (fix-line-separators "foo") "foo")) 22 | (is (= (fix-line-separators "bar\nbaz") "bar\r\nbaz")) 23 | (is (= (fix-line-separators "quux\n\n\nsycorax") 24 | "quux\r\n\r\n\r\nsycorax")))) 25 | 26 | (testing "that other bizarre systems get same treatment" 27 | (with-redefs [user/getprop (constantly "\t\t")] 28 | (is (= (fix-line-separators "foo") "foo")) 29 | (is (= (fix-line-separators "bar\nbaz") "bar\t\tbaz")) 30 | (is (= (fix-line-separators "quux\n\n\nsycorax") 31 | "quux\t\t\t\t\t\tsycorax")))) 32 | 33 | (testing "that one can override the normal system newline" 34 | (with-redefs [user/getprop (constantly "\r\n") 35 | user/getenv (fn [s] (if (= s "LEIN_NEW_UNIX_NEWLINES") 36 | "y" 37 | (getenv s)))] 38 | (is (= (fix-line-separators "foo") "foo")) 39 | (is (= (fix-line-separators "bar\nbaz") "bar\nbaz")) 40 | (is (= (fix-line-separators "quux\n\n\nsycorax") "quux\n\n\nsycorax"))))) 41 | 42 | (deftest project-names 43 | (is (= (project-name "org.example/foo.bar") "foo.bar")) 44 | (is (= (project-name "example") "example")) 45 | (is (= (sanitize-ns "org.example/foo-bar") "org.example.foo-bar")) 46 | (is (= (sanitize-ns "foo-bar") "foo-bar")) 47 | (is (= (sanitize-ns "foo_bar") "foo-bar"))) 48 | 49 | (deftest namespaces 50 | (is (= (multi-segment "foo") "foo.core")) 51 | (is (= (multi-segment "foo" "api") "foo.api")) 52 | (is (= (multi-segment "multi.segment" "last") "multi.segment"))) 53 | 54 | (deftest paths 55 | (is (= (name-to-path "foo-bar.baz") (lthelper/fix-path-delimiters "foo_bar/baz")))) 56 | 57 | (deftest renderers 58 | (is (.contains (abort-msg (renderer "my-template") "boom" {}) 59 | "Template resource 'leiningen/new/my_template/boom' not found.")) 60 | (is (.contains (abort-msg (renderer "my-template") "boom") 61 | "Template resource 'leiningen/new/my_template/boom' not found."))) 62 | 63 | (deftest slurp-resource-compatibility ; can be removed in 3.0.0 64 | (is (= (slurp-resource "leiningen/new/template/temp.clj") 65 | (slurp-resource (io/resource "leiningen/new/template/temp.clj"))))) 66 | 67 | 68 | (deftest files 69 | (testing "that files marked as executable are set executable" 70 | (let [file (File/createTempFile "lein" "template") 71 | path [(.getName file) (.getAbsolutePath file) :executable true]] 72 | (binding [*dir* (.getParentFile file) 73 | *force?* true] 74 | (.deleteOnExit file) 75 | (->files {} path) 76 | (is (.canExecute file)))))) 77 | -------------------------------------------------------------------------------- /test_projects/uberjar-components-merging/components1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.apache.maven.doxia.Doxia 5 | org.apache.maven.doxia.DefaultDoxia 6 | Simple implementation of the Doxia interface: 7 | uses a ParserManager to lookup a parser. 8 | 9 | 10 | org.apache.maven.doxia.parser.manager.ParserManager 11 | parserManager 12 | 13 | 14 | 15 | 16 | org.apache.maven.doxia.macro.Macro 17 | echo 18 | org.apache.maven.doxia.macro.EchoMacro 19 | A simple macro that prints out the key and value of some supplied parameters. 20 | 21 | 22 | org.apache.maven.doxia.macro.manager.MacroManager 23 | org.apache.maven.doxia.macro.manager.DefaultMacroManager 24 | Default implementation of <code>MacroManager</code> 25 | 26 | 27 | org.apache.maven.doxia.macro.Macro 28 | macros 29 | 30 | 31 | 32 | 33 | org.apache.maven.doxia.macro.Macro 34 | snippet 35 | org.apache.maven.doxia.macro.snippet.SnippetMacro 36 | A macro that prints out the content of a file or a URL. 37 | 38 | 39 | org.apache.maven.doxia.macro.Macro 40 | swf 41 | org.apache.maven.doxia.macro.SwfMacro 42 | Macro for embedding Flash (SWF) within Maven documentation. 43 | 44 | 45 | org.apache.maven.doxia.macro.Macro 46 | toc 47 | org.apache.maven.doxia.macro.toc.TocMacro 48 | Macro to display a <code>Table Of Content</code> in a given <code>Sink</code>. 49 | 50 | 51 | org.apache.maven.doxia.module.site.manager.SiteModuleManager 52 | org.apache.maven.doxia.module.site.manager.DefaultSiteModuleManager 53 | Simple implementation of the SiteModuleManager interface. 54 | 55 | 56 | org.apache.maven.doxia.module.site.SiteModule 57 | siteModules 58 | 59 | 60 | 61 | 62 | org.apache.maven.doxia.parser.manager.ParserManager 63 | org.apache.maven.doxia.parser.manager.DefaultParserManager 64 | Simple implementation of the <code>ParserManager</code> interface. 65 | 66 | 67 | org.apache.maven.doxia.parser.Parser 68 | parsers 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /pcmpl-lein.el: -------------------------------------------------------------------------------- 1 | ;;; pcmpl-lein.el --- pcomplete for Leiningen tasks; works with eshell 2 | 3 | ;; Copyright (C) 2011 Phil Hagelberg 4 | ;; 5 | ;; Author: Phil Hagelberg 6 | ;; URL: http://github.com/technomancy/leiningen 7 | ;; Version: 0.1 8 | ;; Keywords: eshell completion 9 | ;; Created: 2011-01-15 10 | 11 | ;; This file is not part of GNU Emacs or Leiningen. 12 | 13 | ;;; Commentary: 14 | 15 | ;; Provides completion of leiningen tasks using pcomplete, suitable 16 | ;; for eshell. Does not support custom :source-path or :test-path. 17 | 18 | ;;; License: 19 | 20 | ;; This program is free software; you can redistribute it and/or 21 | ;; modify it under the terms of the GNU General Public License 22 | ;; as published by the Free Software Foundation; either version 3 23 | ;; of the License, or (at your option) any later version. 24 | ;; 25 | ;; This program is distributed in the hope that it will be useful, 26 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | ;; GNU General Public License for more details. 29 | ;; 30 | ;; You should have received a copy of the GNU General Public License 31 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 32 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 33 | ;; Boston, MA 02110-1301, USA. 34 | 35 | ;;; Code: 36 | 37 | (require 'cl) 38 | (require 'pcomplete) 39 | (require 'esh-util) 40 | 41 | (defvar pcmpl-lein-tasks-alist nil 42 | "Cached alist of project roots to task lists.") 43 | 44 | (defvar pcmpl-lein-project-root nil) 45 | 46 | (defun pcmpl-lein-tasks () 47 | (or (cdr (assoc pcmpl-lein-project-root pcmpl-lein-tasks-alist)) 48 | (let* ((help (progn (message "Getting Leiningen task list...") 49 | (shell-command-to-string "lein help"))) 50 | (tasks (split-string help "\n")) 51 | (tasks (subseq tasks 4 -3)) 52 | (tasks (mapcar (lambda (line) 53 | (substring line 0 (string-match " " line))) 54 | tasks))) 55 | ;; OHAI MEMOIZE. 56 | (add-to-list 'pcmpl-lein-tasks-alist 57 | (cons pcmpl-lein-project-root tasks)) 58 | tasks))) 59 | 60 | (defun pcmpl-lein-namespaces-dir () 61 | (let ((task (cadr pcomplete-args))) 62 | (cond ((equal "test" task) "test") 63 | ((or (equal "run" task) (equal "compile" task)) "src")))) 64 | 65 | (defun pcmpl-lein-transform-filename (file) 66 | (subst-char-in-string ?/ ?. 67 | (substring file (+ (length pcmpl-lein-project-root) 68 | (length namespaces-dir) 1) -4))) 69 | 70 | (defun pcmpl-lein-namespaces-in-dir (file) 71 | (if (not (file-directory-p file)) 72 | (if (string-match "\\.clj$" file) 73 | (pcmpl-lein-transform-filename file)) 74 | (eshell-flatten-list (mapcar 'pcmpl-lein-namespaces-in-dir 75 | (directory-files file t "^[^\\.]"))))) 76 | 77 | (defun pcmpl-lein-namespaces () 78 | (let ((namespaces-dir (pcmpl-lein-namespaces-dir))) 79 | (when namespaces-dir 80 | (pcmpl-lein-namespaces-in-dir namespaces-dir)))) 81 | 82 | ;;;###autoload 83 | (defun pcomplete/lein () 84 | (let ((pcmpl-lein-project-root (expand-file-name 85 | (locate-dominating-file 86 | default-directory "project.clj")))) 87 | (pcomplete-here (pcmpl-lein-tasks)) 88 | (if (not (string= "run" (cadr pcomplete-args))) 89 | (pcomplete-here (pcmpl-lein-namespaces)) 90 | (pcomplete-here (list "-m")) 91 | (pcomplete-here (pcmpl-lein-namespaces))))) 92 | 93 | (provide 'pcmpl-lein) 94 | ;;; pcmpl-lein.el ends here 95 | -------------------------------------------------------------------------------- /src/leiningen/with_profile.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.with-profile 2 | "Apply the given task with the profile(s) specified." 3 | (:require [clojure.string :as string] 4 | [leiningen.core.main :as main] 5 | [leiningen.core.project :as project] 6 | [robert.hooke :as hooke])) 7 | 8 | (defn ^:internal with-profiles* 9 | "Apply the given task with a comma-separated profile list." 10 | [project profiles task-name args] 11 | (hooke/with-scope 12 | (let [project (and project (project/set-profiles project profiles)) 13 | task-name (main/lookup-alias task-name project)] 14 | (main/apply-task task-name project args)))) 15 | 16 | (defn profiles-in-group 17 | [project profile-group] 18 | (let [profiles (.split profile-group ",") 19 | prefixes (map first profiles)] 20 | (cond 21 | (every? #{\+ \-} prefixes) 22 | (distinct 23 | (reduce (fn [result profile] 24 | (let [pm (first profile), profile (keyword (subs profile 1)) 25 | profiles (project/expand-profile project profile)] 26 | (if (= \+ pm) 27 | (concat result profiles) 28 | (remove (set profiles) result)))) 29 | (mapcat (partial project/expand-profile project) 30 | (:active-profiles (meta project))) 31 | profiles)) 32 | 33 | (not-any? #{\+ \-} prefixes) 34 | (distinct 35 | (mapcat (comp #(project/expand-profile project %) keyword) 36 | profiles)) 37 | 38 | :else 39 | (throw 40 | (ex-info 41 | "Profiles in with-profile must either all be qualified, or none qualified" 42 | {:exit-code 1}))))) 43 | 44 | 45 | (defn- apply-task-with-profiles 46 | [project profiles task-name args failures multi-group] 47 | (when multi-group 48 | (main/info (format "Performing task '%s' with profile(s): '%s'" 49 | task-name 50 | (string/join "," (map name profiles))))) 51 | (binding [main/*exit-process?* false] 52 | (try 53 | (with-profiles* project profiles task-name args) 54 | (catch Exception e 55 | (main/info 56 | (format "Error encountered performing task '%s' with profile(s): '%s'" 57 | task-name (string/join "," (map name profiles)))) 58 | (if (and (:exit-code (ex-data e)) (not main/*debug*)) 59 | (main/info (.getMessage e)) 60 | (.printStackTrace e)) 61 | (swap! failures inc))))) 62 | 63 | (defn ^:no-project-needed ^:higher-order with-profile 64 | "Apply the given task with the profile(s) specified. 65 | 66 | Comma-separated profiles may be given to merge profiles and perform the task. 67 | Colon-separated profiles may be given for sequential profile task application. 68 | 69 | A profile list may either be a list of profiles to use, or may specify the 70 | profiles to add or remove from the active profile list using + or - prefixes. 71 | 72 | For example: 73 | 74 | lein with-profile user,dev test 75 | lein with-profile -dev test 76 | lein with-profile +1.4:+1.4,-dev:base,user test 77 | 78 | To list all profiles or show a single one, see the show-profiles task. 79 | For a detailed description of profiles, see `lein help profiles`." 80 | [project profiles task-name & args] 81 | (let [profile-groups (seq (.split profiles ":")) 82 | failures (atom 0) 83 | result (->> profile-groups 84 | (map (partial profiles-in-group project)) 85 | (mapv #(apply-task-with-profiles 86 | project % task-name args failures 87 | (> (count profile-groups) 1))))] 88 | (when (pos? @failures) 89 | (main/abort)) 90 | result)) 91 | -------------------------------------------------------------------------------- /leiningen-core/README.md: -------------------------------------------------------------------------------- 1 | # Leiningen Core 2 | 3 | This library provides the core functionality of Leiningen. This 4 | consists of the task execution implementation, project configuration, 5 | and helper functions. The built-in tasks and the launcher scripts are 6 | kept in the main `leiningen` project. 7 | 8 | More detailed [API reference](https://leiningen.org/reference.html) is 9 | available. 10 | 11 | ## Namespaces 12 | 13 | * **leiningen.core.main** contains the `-main` entry point along with 14 | task handling functions like `apply-task` and `resolve-task`. 15 | * **leiningen.core.project** has `read` and `defproject` for getting a 16 | project map from `project.clj` files. It also handles applying 17 | profiles to the project map and loading plugins. 18 | * **leiningen.core.classpath** is where the project's classpath is 19 | calculated. It handles Maven dependencies as well as checkout 20 | dependencies. 21 | * **leiningen.core.eval** houses the `eval-in-project` function which 22 | implements the isolation of project code from Leiningen's own code. 23 | * **leiningen.core.user** just has a handful of functions which handle 24 | user-level configuration. 25 | 26 | ## Running Tasks 27 | 28 | When Leiningen is invoked, it first reads the `project.clj` file and 29 | applies any active profiles to the resulting project map. (See 30 | Leiningen's own readme for a description of how profiles work.) Then 31 | it looks up the task which was invoked. Tasks are just functions named 32 | after the task they implement and defined in the `leiningen.the-task` 33 | namespace. They usually take a project map as their argument, but can 34 | also run outside the context of a project. See the 35 | [plugin guide](https://github.com/technomancy/leiningen/blob/stable/doc/PLUGINS.md) 36 | for more details on how tasks are written. The `apply-task` function 37 | looks up the task function, checks to make sure it can be applied to 38 | the provided arguments, and then calls it. 39 | 40 | ## Project Isolation 41 | 42 | When you launch Leiningen, it must start an instance of Clojure to 43 | load itself. But this instance must not affect the project that you're 44 | building. It may use a different version of Clojure or other 45 | dependencies from Leiningen itself, and Leiningen's code should not be 46 | visible to the project's functions. 47 | 48 | Leiningen currently implements this by launching a sub-process using 49 | `leiningen.core.eval/eval-in-project`. Any code that must execute 50 | within the context of the project (AOT compilation, test runs, repls) 51 | needs to go through this function. Before the process is launched, the 52 | project must be "prepped", which consists of running all the tasks 53 | named in the project's `:prep-tasks` key. This defaults to `javac` and 54 | `compile`, but `defproject` or profiles may add additional tasks as 55 | necessary. All prep tasks must be cheap to call if nothing has changed 56 | since their last invocation. 57 | 58 | The sub-process (referred to as the "project JVM") is an entirely new 59 | invocation of the `java` command with its own classpath calculated 60 | from functions in the `leiningen.core.classpath` namespace. It can 61 | even use a different version of the JVM from Leiningen if the 62 | `:java-cmd` key is provided. It can only communicate with Leiningen's 63 | process via the file system, sockets, and its exit code. 64 | 65 | The exception to this rule is when `:eval-in-leiningen` in 66 | `project.clj` is true, as is commonly used for Leiningen plugins. 67 | Since Leiningen plugins are intended to be used inside Leiningen 68 | itself, there's no need to enforce this isolation. 69 | 70 | ## License 71 | 72 | Copyright © 2011-2017 Phil Hagelberg and 73 | [contributors](https://www.ohloh.net/p/leiningen/contributors). 74 | 75 | Distributed under the Eclipse Public License, the same as Clojure. 76 | -------------------------------------------------------------------------------- /test/leiningen/test/run.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.run 2 | (:require [leiningen.core.project :as project] 3 | [leiningen.javac] 4 | [clojure.java.io :as io] 5 | [leiningen.test.helper :as helper 6 | :refer [bad-require-project tmp-dir tricky-name-project 7 | java-main-project file-not-found-thrower-project 8 | with-system-out-str with-system-err-str]]) 9 | (:use [clojure.test] 10 | [leiningen.run])) 11 | 12 | (def out-file (format "%s/lein-test" tmp-dir)) 13 | 14 | (deftest test-arg-map 15 | (let [parse-args #'leiningen.run/parse-args] 16 | (is (= (:main (parse-args ["-m" "my-main"])) 17 | "my-main")) 18 | (is (= ((juxt :main :args) (parse-args ["-m" "my-main" "-m" "foo"])) 19 | ["my-main" ["-m" "foo"]])) 20 | (is (= (:arg-conversion (parse-args ["-m" "my-main"])) 21 | :stringify)) 22 | (is (= (:arg-conversion (parse-args ["-m" "my-main" "--quote-args"])) 23 | :quote)) 24 | (is (= (:arg-conversion (parse-args ["--quote-args" "-m" "my-main"])) 25 | :quote)) 26 | (is (= (:args (parse-args ["--" "--quote-args" "-m" "my-main"])) 27 | ["--quote-args" "-m" "my-main"])) 28 | (is (= (:args (parse-args ["--" "--" "-m" "my-main"])) 29 | ["--" "-m" "my-main"])))) 30 | 31 | (use-fixtures :each (fn [f] 32 | (f) 33 | (io/delete-file out-file :silently))) 34 | 35 | (deftest test-basic 36 | (run tricky-name-project "/unreadable") 37 | (is (= "nom:/unreadable" (slurp out-file)))) 38 | 39 | (deftest test-alt-main 40 | (run tricky-name-project "-m" "org.domain.tricky-name.munch" "/unreadable") 41 | (is (= ":munched (\"/unreadable\")" (slurp out-file)))) 42 | 43 | (deftest test-valid-namespace-argument 44 | (is (re-find #"Option -m requires a valid namespace argument, not -1\." 45 | (helper/abort-msg run tricky-name-project "-m" "-1")))) 46 | 47 | (deftest test-nonexistant-ns-error-message 48 | (is (re-find #"Can't find 'nonexistant.ns' as \.class or \.clj for lein run" 49 | (with-system-err-str 50 | (try (run tricky-name-project "-m" "nonexistant.ns") 51 | (catch Exception _)))))) 52 | 53 | (deftest test-escape-args 54 | (run tricky-name-project "--" ":bbb") 55 | (is (= "nom::bbb" (slurp out-file))) 56 | (run tricky-name-project "--" "-m") 57 | (is (= "nom:-m" (slurp out-file)))) 58 | 59 | (deftest test-bad-require-error-msg 60 | (let [e-msg (with-system-err-str 61 | (try (run bad-require-project) 62 | (catch clojure.lang.ExceptionInfo e nil)))] 63 | ;; Don't throw the old ClassNotFoundException 64 | (is (not (re-find #"ClassNotFoundException: bad-require.core" e-msg))) 65 | ;; Do show a relevant error message 66 | (is (re-find #"FileNotFoundException" e-msg)) 67 | (is (re-find #"this/namespace/does/not/exist.clj" e-msg)))) 68 | 69 | (deftest test-run-java-main 70 | (leiningen.javac/javac java-main-project) 71 | (let [out-result (with-system-out-str (run java-main-project))] 72 | (is (= (.trim out-result) ;; To avoid os-specific newline handling 73 | "Hello from Java!")))) 74 | 75 | ;; Regression test for https://github.com/technomancy/leiningen/issues/1469 76 | (deftest file-not-found-exception-test 77 | (let [s (with-system-err-str 78 | (try (run file-not-found-thrower-project 79 | "-m" "file-not-found-thrower.core") 80 | (catch clojure.lang.ExceptionInfo e nil)))] 81 | ;; testing that the true exception is printed immediately and 82 | ;; the inappropriate error message "Can't find 83 | ;; 'file-not-found-thrower.core' as .class or .clj for lein run: 84 | ;; please check the spelling." is not 85 | (is (.contains s "Exception in thread \"main\" java.io.FileNotFoundException")))) 86 | -------------------------------------------------------------------------------- /src/leiningen/clean.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.clean 2 | "Remove all files from project's target-path." 3 | (:require [clojure.java.io :as io] 4 | [leiningen.core.utils :as utils] 5 | [leiningen.core.main :as main]) 6 | (:import [java.io IOException])) 7 | 8 | (defn real-directory? 9 | "Returns true if this file is a real directory, false if it is a symlink or a 10 | normal file." 11 | [f] 12 | (if (= :windows (utils/get-os)) 13 | (.isDirectory f) 14 | (and (.isDirectory f) 15 | (not (utils/symlink? f))))) 16 | 17 | (defn delete-file-recursively 18 | "Delete file f. If it's a directory, recursively delete all its contents. 19 | Raise an exception if any deletion fails unless silently is true." 20 | [f & [silently]] 21 | (let [f (io/file f)] 22 | (when (real-directory? f) 23 | (doseq [child (.listFiles f)] 24 | (delete-file-recursively child silently))) 25 | (.setWritable f true) 26 | (io/delete-file f silently))) 27 | 28 | (defn- protected-paths 29 | "Returns a set of leiningen project source directories and important files." 30 | [project] 31 | (let [root-dir (:root project)] 32 | (->> [:source-paths :java-source-paths :test-paths :resource-paths] 33 | (select-keys project) 34 | (mapcat val) 35 | (list* (io/file root-dir "doc") 36 | (io/file root-dir "project.clj")) 37 | (map io/file) 38 | (map #(.getCanonicalPath %)) 39 | set))) 40 | 41 | (defn- protected-path? 42 | "Is path one of the leiningen project files or directories (which we expect to 43 | be version controlled), or a descendant?" 44 | [project path] 45 | (let [protected-paths (protected-paths project)] 46 | (or (protected-paths (.getCanonicalPath (io/file path))) 47 | (some #(utils/ancestor? % path) protected-paths)))) 48 | 49 | (defn- protect-clean-targets? 50 | "Returns the value of :protect in the metadata map for the :clean-targets 51 | value." 52 | [project] 53 | (-> project :clean-targets meta (get :protect true))) 54 | 55 | (defn- error-msg [& args] 56 | (apply str (concat args 57 | "\nCheck :clean-targets" 58 | " or override this behavior by adding metadata ->" 59 | "\n :clean-targets ^{:protect false} [...targets...]"))) 60 | 61 | (defn- sanity-check 62 | "Ensure that a clean-target string refers to a directory that is sensible to 63 | delete." 64 | [project clean-target] 65 | (when (and (string? clean-target) 66 | (protect-clean-targets? project)) 67 | (cond (not (utils/ancestor? (:root project) clean-target)) 68 | (main/abort (error-msg "Deleting path outside of the project root [\"" 69 | clean-target "\"] is not allowed.")) 70 | (protected-path? project clean-target) 71 | (main/abort (error-msg "Deleting non-target project paths [\"" 72 | clean-target "\"] is not allowed."))))) 73 | 74 | (defn- with-parent-target-path 75 | "Assoc the :target-path sans the profile suffix, if any format 76 | specifier is detected in the raw :target-path" 77 | [project] 78 | (if-let [tp (->> project meta :without-profiles :target-path (re-find #"(.*?)/[^/]*%") second)] 79 | (assoc project :target-path (if (.isAbsolute (io/file tp)) 80 | tp 81 | (str (io/file (:root project) tp)))) 82 | project)) 83 | 84 | (defn clean 85 | "Removes all files from paths in clean-targets for a project" 86 | [project] 87 | (let [project (with-parent-target-path project)] 88 | (doseq [target-key (:clean-targets project)] 89 | (when-let [target (cond (vector? target-key) (get-in project target-key) 90 | (keyword? target-key) (target-key project) 91 | (string? target-key) target-key)] 92 | (doseq [f (flatten [target])] 93 | (sanity-check project f) 94 | (delete-file-recursively f :silently)))))) 95 | -------------------------------------------------------------------------------- /doc/ja/lein_ja.1: -------------------------------------------------------------------------------- 1 | .\"to render: groff -Dutf8 -Tutf8 -man doc/ja/lein_ja.1 > lein_ja.man" 2 | .TH LEININGEN 1 "2017 August 10" 3 | .SH 名前 4 | lein \- Clojure プロジェクトの自動化 5 | 6 | .SH 書式 7 | 8 | .B lein 9 | [\fB\-o\fR] [\fB\-U\fR] [\fITASK\fR [\fIARGS\fR]] 10 | .br 11 | .B lein 12 | [\fB\-h\fR|\fB\-\-help\fR] 13 | .br 14 | .B lein 15 | [\fB\-v\fR|\fB\-\-version\fR] 16 | 17 | .SH 説明 18 | 19 | Leiningen は Clojure プロジェクトを、髪の毛が燃え上がるような思いをせずに、 20 | 自動化するためのものです。 21 | 22 | Java のために設計されたツールを使って Clojure プロジェクトの仕事をすると、 23 | 非常に大変な思いをしてイライラすることがあります。 24 | Leiningen を使うことで、あなたは Clojure を書くだけでよくなります。 25 | 26 | .SH タスク 27 | 28 | .B lein help 29 | は、完全なタスクのリストを表示します。また、 30 | .B lein help TASK 31 | は、特定の一つのタスクの使用方法を表示します。 32 | 33 | .B lein help tutorial 34 | は、色々なタスクの通しでの使い方を詳細に説明します。 35 | 最もよく使われるのは以下のタスクです: 36 | 37 | .RS 38 | .TP 39 | .B lein new NAME 40 | 新しい空のプロジェクトを生成します。 41 | .TP 42 | .B lein test [TESTS] 43 | TESTS 名前空間のテスト、もしくは全てのテストを実行します。 44 | .TP 45 | .B lein repl 46 | ネットワーク REPL サーバで対話的 REPL セッションを開始します。 47 | .TP 48 | .B lein uberjar 49 | プロジェクトとその依存関係をスタンドアロンの .jar ファイルとしてパッケージ化します。 50 | .TP 51 | .B lein install 52 | あなたのローカルレポジトリにプロジェクトをインストールします。 53 | .TP 54 | .B lein deploy [REPOSITORY] 55 | リモートレポジトリにライブラリをデプロイします。 56 | .RE 57 | 58 | .TP 59 | 更に以下のようなタスクが利用可能です: 60 | 61 | .RS 62 | .TP 63 | .B lein change 64 | 関数を適用して project.clj を書き換えます。 65 | 66 | .TP 67 | .B lein check 68 | 構文をチェックしてリフレクションについて警告します。 69 | 70 | .TP 71 | .B lein classpath 72 | 現在のプロジェクトのクラスパスを印字します。 73 | 74 | .TP 75 | .B lein clean 76 | プロジェクトのターゲットパスから全てのファイルを取り除きます。 77 | 78 | .TP 79 | .B lein compile 80 | Clojure ソースコードを .class ファイルにコンパイルします。 81 | 82 | .TP 83 | .B lein deps 84 | 全ての依存関係をダウンロードします。 85 | 86 | .TP 87 | .B lein do [TASK], ... 88 | 他のタスクを連続して起動する、高階タスクです。 89 | 90 | .TP 91 | .B lein jar 92 | プロジェクトの全てのファイルを jar ファイルにパッケージ化します。 93 | 94 | .TP 95 | .B lein javac 96 | Java ソースファイルをコンパイルします。 97 | 98 | .TP 99 | .B lein pom 100 | Maven を使ったインターオペラビリティのために、pom.xml ファイルをディスクに書き出します。 101 | 102 | .TP 103 | .B lein release 104 | :release-tasks を実行します。 105 | 106 | .TP 107 | .B lein retest 108 | 前回失敗したテスト名前空間のみを実行します。 109 | 110 | .TP 111 | .B lein run 112 | オプションのコマンドライン引数を付けて、-main 関数を実行します。 113 | 114 | .TP 115 | .B lein search 116 | リモートの maven レポジトリから一致するjar ファイルを探し出します。 117 | 118 | .TP 119 | .B lein show-profiles 120 | 全ての利用可能なプロファイルを一覧表示するか、引数で与えられたプロファイルを表示します。 121 | 122 | .TP 123 | .B lein trampoline [TASK] 124 | Leiningen 内部でプロジェクトの JVM をネストさせずにタスクを実行します。 125 | 126 | .TP 127 | .B lein update-in 128 | プロジェクトマップに任意の変換を行います。 129 | 130 | .TP 131 | .B lein vcs 132 | バージョンコントロールシステムと対話します。 133 | 134 | .TP 135 | .B lein version 136 | Leiningen と現在の JVM のバージョンを印字します。 137 | 138 | .TP 139 | .B lein with-profile [PROFILE] [TASK] 140 | 指定されたプロファイルで指定されたタスクを適用します。 141 | .RE 142 | 143 | .SH オプション 144 | 145 | .TP 146 | .BI \-o 147 | オフラインでタスクを実行する。 148 | 149 | .TP 150 | .BI \-U 151 | スナップショットのアップデートを強制した後タスクを実行する。 152 | 153 | .TP 154 | .BR \-h ", " \-\-help 155 | このヘルプか指定されたタスクのヘルプを印字する。 156 | 157 | .TP 158 | .BR \-v ", " \-\-version 159 | Leiningen のバージョンを印字する。 160 | 161 | .SH 設定 162 | 163 | Leiningen はその設定ファイルとして、プロジェクトのルートディレクトリにある 164 | .B project.clj 165 | を読み込みます。もしこのファイルがなければ、 166 | .B lein new 167 | を実行して起点となる新しいプロジェクトを作成するか、そうでなければ 168 | \fBlein help sample\fR. 169 | を実行して設定項目の完全なリストを読んでください。 170 | 171 | プロファイルを使用することで何時でもプロジェクトマップをカスタマイズできます。以下を参考にしてください: 172 | \fBlein help profiles\fR. 173 | 174 | .SH バグ 175 | 176 | https://github.com/technomancy/leiningen/issues を見て、 177 | あなたの問題が既知のものかどうか確認してください。 178 | 179 | その際には、 180 | .B lein version 181 | のアウトプットとあなたの 182 | .B project.clj 183 | ファイルを含めてください、 184 | また可能な限りあなたのプロジェクトの関連するコードも含めてください。 185 | 186 | .SH 著作権 187 | 188 | Copyright 189 | .if t \(co 190 | .if n (C) 191 | 2009-2017 Phil Hagelberg and contributors. 192 | 193 | Distributed under the Eclipse Public License, the same as Clojure 194 | uses. See the file /usr/share/doc/leiningen/copyright. 195 | 196 | .SH 著者 197 | この manpage は Phil Hagelberg によって書かれました。 198 | この manpage は Kazutaka Nakamura によって、日本語に翻訳されました。 199 | -------------------------------------------------------------------------------- /leiningen-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | leiningen-core 5 | leiningen-core 6 | jar 7 | 2.9.6 8 | leiningen-core 9 | Library for core functionality of Leiningen. 10 | https://github.com/technomancy/leiningen 11 | 12 | 13 | Eclipse Public License 14 | http://www.eclipse.org/legal/epl-v10.html 15 | 16 | 17 | 18 | 79a4742e4b5c490133220443d68d14232b1655dd 19 | 20 | 21 | src 22 | test 23 | 24 | 25 | resources 26 | 27 | 28 | 29 | 30 | resources 31 | 32 | 33 | target 34 | target/classes 35 | 36 | 37 | 38 | 39 | central 40 | https://repo1.maven.org/maven2/ 41 | 42 | false 43 | 44 | 45 | true 46 | 47 | 48 | 49 | clojars 50 | https://repo.clojars.org/ 51 | 52 | true 53 | 54 | 55 | true 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.clojure 65 | clojure 66 | 1.10.1 67 | 68 | 69 | timofreiberg 70 | bultitude 71 | 0.3.0 72 | 73 | 74 | clojure 75 | org.clojure 76 | 77 | 78 | 79 | 80 | org.flatland 81 | classlojure 82 | 0.7.1 83 | 84 | 85 | robert 86 | hooke 87 | 1.3.0 88 | 89 | 90 | clj-commons 91 | pomegranate 92 | 1.2.1 93 | 94 | 95 | jcl-over-slf4j 96 | org.slf4j 97 | 98 | 99 | 100 | 101 | com.hypirion 102 | io 103 | 0.3.1 104 | 105 | 106 | org.slf4j 107 | slf4j-nop 108 | 1.7.25 109 | 110 | 111 | org.clojure 112 | tools.macro 113 | 0.1.5 114 | 115 | 116 | 117 | 118 | 122 | -------------------------------------------------------------------------------- /leiningen-core/dev-resources/leiningen/downloads.clj: -------------------------------------------------------------------------------- 1 | (use '[cemerick.pomegranate :only (add-dependencies)]) 2 | 3 | (add-dependencies :coordinates '[[clj-aws-s3 "0.3.6"] 4 | [tentacles "0.2.4"]] 5 | :repositories (merge cemerick.pomegranate.aether/maven-central 6 | {"clojars" "https://clojars.org/repo"})) 7 | 8 | (ns leiningen.downloads 9 | "Calculate download statistics from logs." 10 | (:require [aws.sdk.s3 :as s3] 11 | [clojure.java.io :as io] 12 | [tentacles.repos :as repo] 13 | [clojure.pprint :refer [pprint]] 14 | [leiningen.core.main :as main]) 15 | (:import (java.io File))) 16 | 17 | (defn ^:internal aws-cred [] 18 | 19 | ;; in order to run, you need to define a map with the appropriate AWS 20 | ;; credentials in ~/.secrets/leiningen_downloads_aws_cred.clj: 21 | 22 | ;; {:access-key "AWS_ACCESS_KEY" 23 | ;; :secret-key "AWS_SECRET_KEY"} 24 | (let [f (File. (System/getenv "HOME") 25 | "/.secrets/leiningen_downloads_aws_cred.clj")] 26 | (if (.exists f) 27 | (read-string (slurp f)) 28 | (main/abort "Missing credentials file:" f)))) 29 | 30 | (defn- list-all-objects 31 | [bucket & [objects next-marker]] 32 | (let [response (s3/list-objects (aws-cred) bucket {:marker next-marker}) 33 | truncated? (:truncated? response) 34 | next-marker (:next-marker response) 35 | objects (concat objects (:objects response))] 36 | (if (not truncated?) 37 | objects 38 | (recur bucket [objects next-marker])))) 39 | 40 | (defn- fetch-all-objects 41 | [bucket] 42 | (for [object (list-all-objects bucket)] 43 | (do 44 | (println (str "Processing: " (:key object))) 45 | (s3/get-object (aws-cred) bucket (:key object))))) 46 | 47 | (defn- file-for-line 48 | [line] 49 | (let [[_ file] (re-find #"\"GET ([^ ]+) " line)] 50 | (if file 51 | (last (.split file "/"))))) 52 | 53 | (defn- ip-for-line 54 | [line] 55 | (re-find #"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b" line)) 56 | 57 | (defn- status-for-line 58 | [line] 59 | (second (re-find #"\" (\d\d\d)" line))) 60 | 61 | (defn- parse-files 62 | [content] 63 | (with-open [rdr (io/reader content)] 64 | (doall (for [line (line-seq rdr)] 65 | {:file (file-for-line line) 66 | :status (status-for-line line) 67 | :ip (ip-for-line line)})))) 68 | 69 | (defn- s3-downloads 70 | [] 71 | (flatten 72 | (for [logfile (map :content (fetch-all-objects "leiningen-logs"))] 73 | (filter #(and (get % :file) ;; file is present 74 | (re-find #"\.jar\b" (get % :file)) ;; file is a jar 75 | (= "200" (get % :status))) ;; and only HTTP 200 responses 76 | (parse-files logfile))))) 77 | 78 | (defn- github-downloads 79 | [] 80 | (reverse 81 | (sort-by #(first (vals %)) 82 | (filter #(re-find #"\.jar$" (first (keys %))) 83 | (let [downloads {}] 84 | (for [download (repo/downloads "technomancy" "leiningen")] 85 | (assoc downloads 86 | (:name download) 87 | (:download_count download)))))))) 88 | 89 | (defn ^:no-project-needed downloads [project] 90 | (let [s3-downloads (s3-downloads) 91 | s3-download-count (count s3-downloads) 92 | github-downloads (github-downloads) 93 | github-download-count 94 | (reduce + (map #(first (vals %)) github-downloads))] 95 | (println (str "GitHub Downloads: " github-download-count)) 96 | (println (str "S3 Downloads: " s3-download-count)) 97 | (println (str "Unique IP Addresses (S3 Downloads Only): " 98 | (count (distinct (map :ip s3-downloads))))) 99 | (println (str "Total Downloads: " 100 | (+ github-download-count s3-download-count))) 101 | (print "\n\n") 102 | (println "GitHub downloads by file:") 103 | (print "\n\n") 104 | (pprint github-downloads) 105 | (print "\n\n") 106 | (println "S3 downloads by file:") 107 | (print "\n\n") 108 | (pprint (frequencies (map :file s3-downloads))) 109 | (println ""))) ;; need this last println for some reason or else 110 | ;; the above doesn't print out using lein run... 111 | -------------------------------------------------------------------------------- /test/leiningen/test/deploy.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.deploy 2 | (:use [clojure.test] 3 | [clojure.java.io :only [file]] 4 | [leiningen.deploy] 5 | [leiningen.test.helper :only [delete-file-recursively 6 | tmp-dir sample-project 7 | sample-deploy-project]])) 8 | 9 | (defn- repo-path 10 | [relative-repo-path] 11 | (clojure.string/replace 12 | (format "%s/%s" tmp-dir relative-repo-path) 13 | "\\" "/")) ;make path delimiters look the same / even under Windows 14 | 15 | (defn- repo-url 16 | [absolute-repo-path] 17 | (str "file://" absolute-repo-path)) 18 | 19 | (defn- deploy-snapshots 20 | [project relative-repo-path & [explicit-deploy-repo?]] 21 | (let [repo-path (repo-path relative-repo-path) 22 | repo-url (repo-url repo-path)] 23 | (delete-file-recursively repo-path :silently) 24 | (deploy project (if explicit-deploy-repo? 25 | repo-url 26 | "snapshots")) 27 | (let [dir (file repo-path "nomnomnom/nomnomnom/0.5.0-SNAPSHOT/") 28 | files (.list dir)] 29 | (is (seq files)) 30 | ;; TODO: this is vulnerable to the y3k bug! 31 | (is (seq (filter #(re-find #"nomnomnom-0.5.0-2\d{7}\." %) files)))))) 32 | 33 | (deftest ^:online test-deploy 34 | (testing "simple deployment to `snapshots` already defined in project.clj" 35 | (deploy-snapshots sample-project "lein-repo"))) 36 | 37 | (deftest ^:online test-deploy-custom-url 38 | (testing "deployment to a repo specified as a URL argument to `deploy`" 39 | (deploy-snapshots sample-project "lein-custom-repo" true))) 40 | 41 | (deftest ^:online test-deploy-repositories-key 42 | (testing "preferring repository in :deploy-repositories over :repositories" 43 | (deploy-snapshots (assoc sample-project 44 | :deploy-repositories 45 | {"snapshots" {:url (-> "deploy-only-repo" 46 | repo-path repo-url)}}) 47 | "deploy-only-repo"))) 48 | 49 | (deftest ^:online test-deploy-classifier 50 | (testing "deployment with explicit file names uploads classifiers to repo" 51 | (let [deploy-dir (repo-path "deploy-classifier") 52 | project (assoc sample-deploy-project 53 | :deploy-repositories 54 | {"snapshots" {:url (repo-url deploy-dir)}})] 55 | (delete-file-recursively deploy-dir :silently) 56 | (deploy project "snapshots" 57 | "deploy-me/deploy-me" 58 | (:version project) 59 | (str (:root project) "/deploy-me-0.1.0-SNAPSHOT-fat.jarr")) 60 | (let [dir (file deploy-dir "deploy-me/deploy-me/0.1.0-SNAPSHOT/") 61 | files (.list dir)] 62 | (is (seq (filter #(re-find #"deploy-me-0.1.0-[\d.]+-\d+-fat.jarr$" %) files))))))) 63 | 64 | (deftest signing 65 | (testing "GPG invocation" 66 | (is (= (signing-args "foo.jar" nil) 67 | ["--yes" "-ab" "--" "foo.jar"])) 68 | (is (= (signing-args "foo.jar" {:gpg-key "123456"}) 69 | ["--yes" "-ab" "--default-key" "123456" "--" "foo.jar"]))) 70 | (testing "Key selection" 71 | (is (= (:gpg-key (signing-opts {:signing {:gpg-key "key-project"}} 72 | ["repo" {:signing {:gpg-key "key-repo"}}])) 73 | "key-repo")) 74 | (is (= (:gpg-key (signing-opts {:signing {:gpg-key "key-project"}} 75 | ["repo" {}])) 76 | "key-project"))) 77 | (testing "Whether to sign" 78 | (is (= (sign-for-repo? ["foo" {:sign-releases true}]) true)) 79 | (is (= (sign-for-repo? ["foo" {:sign-releases false}]) false)) 80 | (is (= (sign-for-repo? ["foo" {}]) true)))) 81 | 82 | (deftest validate-input 83 | (testing "Fail if project data is missing" 84 | (is (thrown? clojure.lang.ExceptionInfo (deploy nil)))) 85 | (testing "Fail if project data is missing" 86 | (is (thrown? clojure.lang.ExceptionInfo (deploy nil "snapshots"))))) 87 | 88 | (deftest classifiying 89 | (are [expected version file] (= expected (classifier version file)) 90 | "fat" "1.2.3" "some-project-1.2.3-fat.jar" 91 | "fat" "1.2.3-alpha6" "some-project-1.2.3-alpha6-fat.jar" 92 | "fat" "1.2.3-SNAPSHOT" "some-project-1.2.3-SNAPSHOT-fat.jar" 93 | nil "1.2.3" "some-project-1.2.3-.jar" 94 | nil "1.2.3" "some-project-1.2.3.jar" 95 | nil "0.1.0" "/opt/workspace/mylib-0.1.0-builddir/target/mylib-0.1.0.jar" 96 | "RC2" "0.1.0" "\\opt\\workspace\\mylib-0.1.0-builddir\\target\\mylib-0.1.0-RC2.jar")) 97 | -------------------------------------------------------------------------------- /src/leiningen/vcs.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.vcs 2 | "Interact with the version control system." 3 | (:require [clojure.java.io :as io] 4 | [bultitude.core :as b] 5 | [leiningen.core.eval :as eval] 6 | [leiningen.core.main :as main] 7 | [leiningen.core.utils :as utils])) 8 | 9 | ;; TODO: make pom task use this ns by adding a few more methods 10 | 11 | (def supported-systems (atom [:git])) 12 | 13 | (defn uses-vcs [project vcs] 14 | (let [vcs-dir (io/file (:root project) 15 | (get-in project [:scm :dir] "") 16 | (str "." (name vcs)))] 17 | (and (.exists vcs-dir) vcs))) 18 | 19 | (defn which-vcs [project & _] 20 | (or (:vcs project) (some (partial uses-vcs project) @supported-systems))) 21 | 22 | (defn parse-tag-args [args] 23 | (loop [parsed-args {:sign? true :annotate? true} 24 | args args] 25 | (case (first args) 26 | ("--sign" "-s") (recur (assoc parsed-args :sign? true) (rest args)) 27 | "--no-sign" (recur (assoc parsed-args :sign? false) (rest args)) 28 | "--annotate" (recur (assoc parsed-args :annotate? true) (rest args)) 29 | "--no-annotate" (recur (assoc parsed-args :annotate? false) (rest args)) 30 | nil parsed-args ;; We're finished and can exit 31 | (recur (assoc parsed-args :prefix (first args)) (rest args))))) 32 | 33 | (def default-commit-message "Version %s") 34 | 35 | ;;; Methods 36 | 37 | (defmulti push "Push to your remote repository." 38 | which-vcs :default :none) 39 | 40 | (defmulti commit 41 | "Commit changes to current repository. Takes an optional format 42 | string for the commit message that will be provided the version." 43 | which-vcs :default :none) 44 | 45 | (defmulti tag 46 | "Apply a version control tag. Takes an optional tag prefix. 47 | Pass --no-sign option to skip signing, or --no-annotate to create 48 | non-release tags." 49 | which-vcs :default :none) 50 | 51 | (defmulti assert-committed "Abort if uncommitted changes exist." 52 | which-vcs :default :none) 53 | 54 | 55 | ;;; VCS not found 56 | 57 | (defn- unknown-vcs [task] 58 | (binding [*out* *err*] 59 | (println (str "Unknown VCS detected for 'vcs " task "'"))) 60 | (System/exit 1)) 61 | 62 | (defmethod push :none [project & [args]] (unknown-vcs "push")) 63 | 64 | (defmethod commit :none [project & _] (unknown-vcs "commit")) 65 | 66 | (defmethod tag :none [project] (unknown-vcs "tag")) 67 | 68 | (defmethod assert-committed :none [project] (unknown-vcs "assert-committed")) 69 | 70 | 71 | ;;; Git 72 | 73 | (defmethod push :git [project & args] 74 | (binding [eval/*dir* (:root project)] 75 | (apply eval/sh-with-exit-code "Couldn't push to the remote" "git" "push" "--follow-tags" args))) 76 | 77 | (defmethod commit :git 78 | ([project] 79 | (commit project default-commit-message)) 80 | ([project message-template] 81 | (binding [eval/*dir* (:root project)] 82 | (let [message (format message-template (:version project))] 83 | (eval/sh-with-exit-code "Couldn't commit" "git" "commit" "-a" "-m" message))))) 84 | 85 | (defmethod tag :git [{:keys [root version]} & args] 86 | (binding [eval/*dir* root] 87 | (let [{:keys [annotate? sign? prefix]} (parse-tag-args args) 88 | tag (if prefix 89 | (str prefix version) 90 | version) 91 | cmd (->> ["git" "tag" (if sign? "--sign") tag (if annotate? "-a") "-m" (str "Release " version)] 92 | (filter some?))] 93 | (apply eval/sh-with-exit-code "Couldn't tag" cmd)))) 94 | 95 | (defmethod assert-committed :git [project] 96 | (binding [eval/*dir* (:root project)] 97 | (when (re-find #"Changes (not staged for commit|to be committed)" 98 | (utils/with-system-out-str (eval/sh-with-exit-code "Couldn't get status" "git" "status"))) 99 | (main/abort "Uncommitted changes in" (:root project) "directory.")))) 100 | 101 | (defn- not-found [subtask] 102 | (partial #'main/task-not-found (str "vcs " subtask))) 103 | 104 | (defn- load-methods [] 105 | (doseq [n (b/namespaces-on-classpath :prefix "leiningen.vcs.")] 106 | (swap! supported-systems conj (keyword (last (.split (name n) "\\.")))) 107 | (require n))) 108 | 109 | (defn ^{:subtasks [#'push #'commit #'tag #'assert-committed]} vcs 110 | "Interact with the version control system." 111 | [project subtask & args] 112 | (load-methods) 113 | (let [subtasks (:subtasks (meta #'vcs) {}) 114 | [subtask-var] (filter #(= subtask (name (:name (meta %)))) subtasks)] 115 | (apply (or subtask-var (not-found subtask)) project args))) 116 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Leiningen is the most widely-contributed-to Clojure project. We 4 | welcome potential contributors and do our best to try to make it easy 5 | to help out. 6 | 7 | Discussion occurs primarily in the #leiningen channel on Libera chat. 8 | 9 | Please report issues on the 10 | [GitHub issue tracker](https://github.com/technomancy/leiningen/issues). 11 | 12 | Code submissions should 13 | be sent as GitHub pull requests. Please use topic branches when 14 | sending pull requests rather than committing directly to master in 15 | order to minimize unnecessary merge commit clutter. Direct pull 16 | requests towards the master branch, not the stable branch. 17 | 18 | Leiningen is [mirrored at GitLab](https://gitlab.com/technomancy/leiningen) 19 | and [tested on CircleCI](https://circleci.com/gh/technomancy/leiningen). 20 | 21 | ## Codebase 22 | 23 | The definitions of the various tasks reside in `src/leiningen` in the 24 | top-level project. The underlying mechanisms for things like 25 | `project.clj` parsing, classpath calculation, and subprocess launching 26 | are implemented inside the `leiningen-core` subproject. 27 | 28 | See the 29 | [readme for the leiningen-core library](https://github.com/technomancy/leiningen/blob/master/leiningen-core/README.md) 30 | and `doc/PLUGINS.md` for more details on how Leiningen's codebase is 31 | structured. 32 | 33 | Try to be aware of the conventions in the existing code, except the 34 | one where we don't write tests. Make a reasonable attempt to avoid 35 | lines longer than 80 columns or function bodies longer than 20 36 | lines. Don't use `when` unless it's for side-effects. Don't introduce 37 | new protocols. Use `^:internal` metadata to mark vars which can't be 38 | private but shouldn't be considered part of the public API. 39 | 40 | ## Bootstrapping 41 | 42 | You don't need to "build" Leiningen per se, but when you're developing on a 43 | checkout you will need to get its dependencies in place and compile some of the 44 | tasks. Assuming you are in Leiningen's project root, you can do that like this: 45 | 46 | ```bash 47 | $ cd leiningen-core 48 | $ lein bootstrap # or lein.bat on Windows. 49 | ``` 50 | 51 | The `lein` command is a stable release of Leiningen on your `$PATH` – preferably 52 | the newest one. If you don't have a stable `lein` installed, simply check out 53 | the `stable` branch and copy `bin/lein` to somewhere on your `$PATH`, then 54 | switch your branch back. 55 | 56 | If you want to use your development copy for everyday usage, symlink 57 | `bin/lein` to somewhere on your `$PATH`. You'll want to rename your 58 | stable installation to keep them from interfering; typically you can 59 | name that `lein2` or `lein-stable`. 60 | 61 | When dependencies in Leiningen change, you may have to do `rm .lein-classpath` 62 | in the project root, though in most cases this will be done automatically. If 63 | dependencies in leiningen-core change, you have to redo the `lein bootstrap` 64 | step mentioned earlier. 65 | 66 | Using `bin/lein` alone from the master branch without a full checkout 67 | is not supported. If you want to just grab a shell script to work 68 | with, use the `stable` branch. 69 | 70 | ### Uberjar from Master 71 | 72 | Since a development version is not uberjared, it can be rather slow compared to 73 | a stable release. If this is annoying and you depend on a recent fix or 74 | enhancement, you can build an uberjar from master as follows: 75 | 76 | ```bash 77 | # NB! You have to use *bin*/lein to build the uberjar 78 | $ bin/lein uberjar 79 | # ^ Last line printed from this command will tell the location of the standalone 80 | $ cp target/leiningen-2.5.2-SNAPSHOT-standalone.jar $HOME/.lein/self-installs 81 | $ cp bin/lein $HOME/bin/lein-master 82 | ``` 83 | 84 | Here, 2.5.2-SNAPSHOT is the version we've built, and we have `$HOME/bin` on our 85 | $PATH. 86 | 87 | Note that changes on master won't be visible in the uberjared version unless you 88 | overwrite both the lein script and a freshly created uberjar. 89 | 90 | ## Tests 91 | 92 | Before you're asking for a pull request, we would be very happy if you ensure 93 | that the changes you've done doesn't break any of the existing test cases. While 94 | there is a test suite, it's not terribly thorough, so don't put too much trust 95 | in it. Patches which add test coverage for the functionality they change are 96 | especially welcome. 97 | 98 | To run the test cases, run `bin/lein test` in the root directory: This will test 99 | both `leiningen-core` and `leiningen` itself. Do not attempt to run the tests 100 | with a stable version of Leiningen, as the namespaces conflict and you may end 101 | up with errors during the test run. 102 | -------------------------------------------------------------------------------- /doc/lein.1: -------------------------------------------------------------------------------- 1 | .\"to render: groff -Tascii -man doc/lein.1 > lein.man" 2 | .TH LEININGEN 1 "2017 August 10" 3 | .SH NAME 4 | lein \- Automate Clojure projects 5 | 6 | .SH SYNOPSIS 7 | 8 | .B lein 9 | [\fB\-o\fR] [\fB\-U\fR] [\fITASK\fR [\fIARGS\fR]] 10 | .br 11 | .B lein 12 | [\fB\-h\fR|\fB\-\-help\fR] 13 | .br 14 | .B lein 15 | [\fB\-v\fR|\fB\-\-version\fR] 16 | 17 | .SH DESCRIPTION 18 | 19 | Leiningen is for automating Clojure projects without setting your hair 20 | on fire. 21 | 22 | Working on Clojure projects with tools designed for Java can be an 23 | exercise in frustration. With Leiningen, you just write Clojure. 24 | 25 | .SH TASKS 26 | 27 | .B lein help 28 | will show the complete list of tasks, while 29 | .B lein help TASK 30 | shows usage for a specific one. 31 | 32 | .B lein help tutorial 33 | has a detailed walk-through of the various tasks, but the most 34 | commonly-used are: 35 | 36 | .RS 37 | .TP 38 | .B lein new NAME 39 | generate a new project skeleton 40 | .TP 41 | .B lein test [TESTS] 42 | run the tests in the TESTS namespaces, or all tests 43 | .TP 44 | .B lein repl 45 | launch an interactive REPL session in a networked REPL server 46 | .TP 47 | .B lein uberjar 48 | package up the project and its dependencies as a standalone .jar file 49 | .TP 50 | .B lein install 51 | install a project into your local repository 52 | .TP 53 | .B lein deploy [REPOSITORY] 54 | deploy a library to a remote repository 55 | .RE 56 | 57 | .TP 58 | Other tasks available include: 59 | 60 | .RS 61 | .TP 62 | .B lein change 63 | Rewrite project.clj by applying a function. 64 | 65 | .TP 66 | .B lein check 67 | Check syntax and warn on reflection. 68 | 69 | .TP 70 | .B lein classpath 71 | Print the classpath of the current project. 72 | 73 | .TP 74 | .B lein clean 75 | Remove all files from project's target-path. 76 | 77 | .TP 78 | .B lein compile 79 | Compile Clojure source into .class files. 80 | 81 | .TP 82 | .B lein deps 83 | Download all dependencies. 84 | 85 | .TP 86 | .B lein do [TASK], ... 87 | Higher-order task to perform other tasks in succession. 88 | 89 | .TP 90 | .B lein jar 91 | Package up all the project's files into a jar file. 92 | 93 | .TP 94 | .B lein javac 95 | Compile Java source files. 96 | 97 | .TP 98 | .B lein pom 99 | Write a pom.xml file to disk for Maven interoperability. 100 | 101 | .TP 102 | .B lein release 103 | Perform :release-tasks. 104 | 105 | .TP 106 | .B lein retest 107 | Run only the test namespaces which failed last time around. 108 | 109 | .TP 110 | .B lein run 111 | Run a -main function with optional command-line arguments. 112 | 113 | .TP 114 | .B lein search 115 | Search remote maven repositories for matching jars. 116 | 117 | .TP 118 | .B lein show-profiles 119 | List all available profiles or display one if given an argument. 120 | 121 | .TP 122 | .B lein trampoline [TASK] 123 | Run a task without nesting the project's JVM inside Leiningen's. 124 | 125 | .TP 126 | .B lein update-in 127 | Perform arbitrary transformations on your project map. 128 | 129 | .TP 130 | .B lein vcs 131 | Interact with the version control system. 132 | 133 | .TP 134 | .B lein version 135 | Print version for Leiningen and the current JVM. 136 | 137 | .TP 138 | .B lein with-profile [PROFILE] [TASK] 139 | Apply the given task with the profile(s) specified. 140 | .RE 141 | 142 | .SH OPTIONS 143 | 144 | .TP 145 | .BI \-o 146 | Run a task offline. 147 | 148 | .TP 149 | .BI \-U 150 | Run a task after forcing update of snapshots. 151 | 152 | .TP 153 | .BR \-h ", " \-\-help 154 | Print this help or help for a specific task. 155 | 156 | .TP 157 | .BR \-v ", " \-\-version 158 | Print Leiningen's version. 159 | 160 | .SH CONFIGURATION 161 | 162 | Leiningen reads its configuration from the 163 | .B project.clj 164 | file in your project root. Either use 165 | .B lein new 166 | to create a fresh project from which to work, or see the exhaustive 167 | list of configuration options with 168 | \fBlein help sample\fR. 169 | 170 | You can customize your project map further with profiles; see 171 | \fBlein help profiles\fR. 172 | 173 | .SH BUGS 174 | 175 | Check https://github.com/technomancy/leiningen/issues to see if your 176 | problem is a known issue. If not, please open a new issue on that site. 177 | Please include the output of 178 | .B lein version 179 | as well as your 180 | .B project.clj 181 | file and as much of the relevant code from your project as possible. 182 | 183 | .SH COPYING 184 | 185 | Copyright 186 | .if t \(co 187 | .if n (C) 188 | 2009-2017 Phil Hagelberg and contributors. 189 | 190 | Distributed under the Eclipse Public License, the same as Clojure 191 | uses. See the file /usr/share/doc/leiningen/copyright. 192 | 193 | .SH AUTHOR 194 | This manpage is written by Phil Hagelberg 195 | -------------------------------------------------------------------------------- /test/leiningen/test/test.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.test 2 | (:refer-clojure :exclude [test]) 3 | (:require [clojure.test :refer :all] 4 | [leiningen.test :refer :all] 5 | [leiningen.test.helper :refer [tmp-dir sample-no-aot-project 6 | lein-test-exit-code-project 7 | lein-test-reload-bug-project 8 | sample-reader-cond-project 9 | sample-failing-project 10 | sample-fixture-error-project 11 | with-system-err-str]] 12 | [clojure.java.io :as io] 13 | [leiningen.core.main :as main] 14 | [leiningen.core.project :as project])) 15 | 16 | (use-fixtures :each 17 | (fn [f] 18 | (f) 19 | (.delete (java.io.File. tmp-dir "lein-test-ran")))) 20 | 21 | (defn runs [] 22 | (let [ran-file (io/file tmp-dir "lein-test-ran")] 23 | (and (.exists ran-file) 24 | (-> ran-file 25 | (slurp) 26 | (.split "\n") 27 | (->> (map read-string) 28 | (frequencies)))))) 29 | 30 | (defn ran? [] (-> (runs) keys set)) 31 | 32 | (deftest test-project-selectors 33 | (is (= #{:default :integration :int2 :no-custom} 34 | (set (keys (:test-selectors sample-no-aot-project))))) 35 | (is (every? ifn? (map eval (vals (:test-selectors sample-no-aot-project)))))) 36 | 37 | (deftest test-default-selector 38 | (test sample-no-aot-project ":default") 39 | (is (= (ran?) #{:regular :int2 :not-custom :fixture}))) 40 | 41 | (deftest fixture-runs-appropriate-number-of-times 42 | ;; Issue #1269 43 | (test sample-no-aot-project) 44 | ;; Because three tests ran 45 | (is (= 3 ((runs) :fixture)))) 46 | 47 | (deftest test-no-args-defaults-to-default-selector 48 | (test sample-no-aot-project) 49 | (is (= (ran?) #{:regular :int2 :not-custom :fixture}))) 50 | 51 | (deftest test-basic-selector 52 | (test sample-no-aot-project ":integration") 53 | (is (= (ran?) #{:integration :integration-ns :fixture}))) 54 | 55 | (deftest test-complex-selector 56 | (test sample-no-aot-project ":no-custom") 57 | (is (= (ran?) #{:integration :integration-ns :regular :int2 :fixture}))) 58 | 59 | (deftest test-two-selectors 60 | (test sample-no-aot-project ":integration" ":int2") 61 | (is (= (ran?) #{:integration :integration-ns :int2 :fixture}))) 62 | 63 | (deftest test-override-namespace-selector 64 | (test sample-no-aot-project ":int2") 65 | (is (= (ran?) #{:integration-ns :int2 :fixture}))) 66 | 67 | (deftest test-only-selector 68 | (test sample-no-aot-project ":only" "selectors/regular") 69 | (is (= (ran?) #{:regular :fixture}))) 70 | 71 | (deftest test-namespace-argument 72 | (test sample-no-aot-project "selectors") 73 | (is (= (ran?) #{:regular :not-custom :int2 :fixture}))) 74 | 75 | (deftest test-reader-conditional-tests 76 | (test sample-reader-cond-project) 77 | (is (= (ran?) #{:clj-test :cljc-test}))) 78 | 79 | (deftest test-namespaces-load-in-order 80 | ;; Issue #2715 81 | (test lein-test-reload-bug-project)) 82 | 83 | (deftest test-failure-exit-code 84 | (is (= 1 85 | (try 86 | ;; suppress output; there's a lot of bad-looking stuff here 87 | (with-out-str (test lein-test-exit-code-project)) 88 | false 89 | (catch clojure.lang.ExceptionInfo e 90 | (:exit-code (ex-data e))))))) 91 | 92 | (deftest test-invalid-namespace-argument 93 | (is (.contains 94 | (with-system-err-str 95 | (try 96 | (test sample-no-aot-project "boom") 97 | (catch clojure.lang.ExceptionInfo e 98 | (when-not (:exit-code (ex-data e)) 99 | (throw e))))) 100 | "java.io.FileNotFoundException: Could not locate"))) 101 | 102 | (deftest test-file-argument 103 | (let [file (io/file (first (:test-paths sample-no-aot-project)) "selectors.clj")] 104 | (test sample-no-aot-project (.getPath file))) 105 | (is (= (ran?) #{:regular :not-custom :int2 :fixture}))) 106 | 107 | (deftest test-unreadable-test-fails 108 | (let [project (project/merge-profiles sample-failing-project 109 | [{:aot ^:replace [] 110 | :dependencies ^:replace 111 | [['org.clojure/clojure (clojure-version)]]}])] 112 | (binding [main/*exit-process?* false] 113 | (is (= "EOF while reading" (try (test project) false 114 | (catch Exception e 115 | (.getMessage e)))))))) 116 | 117 | (deftest test-catch-fixture-errors 118 | (test sample-fixture-error-project) 119 | (is (= (ran?) #{:test-a :test-c}))) 120 | -------------------------------------------------------------------------------- /leiningen-core/test/leiningen/core/test/eval.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.core.test.eval 2 | (:require [clojure.test :refer :all] 3 | [leiningen.core.eval :refer :all] 4 | [clojure.java.io :as io] 5 | [clojure.set :as set] 6 | [leiningen.core.classpath :as classpath] 7 | [leiningen.test.helper :as lthelper] 8 | [leiningen.core.project :as project]) 9 | (:import (java.io File))) 10 | 11 | (def project {:managed-dependencies '[[org.clojure/clojure "1.3.0"]] 12 | :dependencies '[[org.clojure/clojure]] 13 | :root "/tmp/lein-sample-project" 14 | :repositories project/default-repositories 15 | :target-path "/tmp/lein-sample-project/target" 16 | :source-paths ["/tmp/lein-sample-project/src"] 17 | :resource-paths ["/tmp/lein-sample-project/resources"] 18 | :test-paths ["/tmp/lein-sample-project/test"] 19 | :compile-path "/tmp/lein-sample-project/classes" 20 | :name "test" :group "test" :version "1.0.0"}) 21 | 22 | (deftest test-eval-in-project 23 | (doseq [where [:subprocess :leiningen :classloader]] 24 | (let [file (File/createTempFile "lein-eval-test" "")] 25 | (eval-in-project (assoc project :eval-in where 26 | :prep-tasks []) 27 | `(spit ~(.getPath file) (eval "{:foo \"bar\"}"))) 28 | (is (= "{:foo \"bar\"}" (slurp file))) 29 | (.delete file)))) 30 | 31 | (deftest test-classpath-directories-created 32 | (doseq [path (concat (:source-paths project) 33 | (:test-paths project) 34 | (:resource-paths project))] 35 | (let [file (File/createTempFile "lein-eval-test" "")] 36 | (eval-in-project project 37 | `(do (.mkdirs (clojure.java.io/file ~path)) 38 | (spit ~(str path "/foo.txt") "Hello World") 39 | (when-let [f# (clojure.java.io/resource "foo.txt")] 40 | (spit ~(.getPath file) (slurp f#)))) 41 | `(require 'clojure.java.io)) 42 | (is (= "Hello World" (slurp file))) 43 | (.delete (io/file (str path "/foo.txt"))) 44 | (.delete (io/file path)) 45 | (.delete file)))) 46 | 47 | (deftest test-jvm-opts 48 | (is (= ["-Dhello=\"guten tag\"" "-XX:+HeapDumpOnOutOfMemoryError"] 49 | (get-jvm-opts-from-env (str "-Dhello=\"guten tag\" " 50 | "-XX:+HeapDumpOnOutOfMemoryError")))) 51 | (is (= ["-Dfoo=bar" "-Dbar=baz"] 52 | (get-jvm-opts-from-env (str " -Dfoo=bar" 53 | " -Dbar=baz")))) 54 | (is (= ["-Dfoo='ba\"r'" "-Dbar=\"ba\"'z'" "arg"] 55 | (get-jvm-opts-from-env (str " -Dfoo='ba\"r'" 56 | " -Dbar=\"ba\"'z'" 57 | " arg")))) 58 | (is (nil? (parse-d-property "-Xmx1g"))) 59 | (is (= ["line.separator" "\n"] 60 | (parse-d-property "-Dline.separator=\n")))) 61 | 62 | (deftest test-file-encoding-in-jvm-args 63 | (is (contains? 64 | (set (#'leiningen.core.eval/get-jvm-args project)) 65 | (str "-Dfile.encoding=" (System/getProperty "file.encoding"))))) 66 | 67 | (deftest test-get-jvm-args-with-proxy-settings 68 | ;; Mock get-proxy-settings to return test values 69 | (with-redefs [classpath/get-proxy-settings 70 | (fn ([] {:host "foo.com" :port 8080}) 71 | ([https] {:host "secure-foo.com", :port 443}))] 72 | (let [args (set (shell-command project 'repl))] 73 | (is (and (contains? args "-Dhttp.proxyHost=foo.com") 74 | (contains? args "-Dhttp.proxyPort=8080") 75 | (contains? args "-Dhttps.proxyHost=secure-foo.com") 76 | (contains? args "-Dhttps.proxyPort=443")))))) 77 | 78 | (deftest test-java-agent 79 | (let [p {:java-agents '[[com.newrelic.agent.java/newrelic-agent "2.18.0" 80 | :bootclasspath true] 81 | [nodisassemble "0.1.2" :options "hello"]] 82 | :dependencies '[[slamhound "1.3.0"]] 83 | :repositories project/default-repositories} 84 | [newrelic newrelic-bootcp nodisassemble] (classpath-arg p)] 85 | (is (.endsWith newrelic (lthelper/fix-path-delimiters 86 | (str "/com/newrelic/agent/java/newrelic-agent" 87 | "/2.18.0/newrelic-agent-2.18.0.jar")))) 88 | (is (re-find #"bootclasspath.*newrelic.*jar" newrelic-bootcp)) 89 | (is (re-find #"-javaagent:.*nodisassemble-0.1.2.jar=hello" nodisassemble)))) 90 | 91 | (deftest test-sh-with-exit-code-successful-command 92 | (with-redefs [sh (constantly 0)] 93 | (is (= 0 (sh-with-exit-code "Shouldn't see me." "ls"))))) 94 | 95 | (deftest test-sh-with-exit-code-failed-command 96 | (with-redefs [sh (constantly 1)] 97 | (is (thrown-with-msg? Exception #"Should see me. ls exit code: 1" (sh-with-exit-code "Should see me" "ls"))))) 98 | -------------------------------------------------------------------------------- /bin/lein-pkg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This variant of the lein script is meant for downstream packagers. 4 | # It has all the cross-platform stuff stripped out as well as the 5 | # logic for running from a source checkout and self-install/upgrading. 6 | 7 | export LEIN_VERSION="2.9.7-SNAPSHOT" 8 | 9 | # cd to the project root, if applicable 10 | NOT_FOUND=1 11 | ORIGINAL_PWD="$PWD" 12 | while [ ! -r "$PWD/project.clj" ] && [ "$PWD" != "/" ] && [ $NOT_FOUND -ne 0 ]; do 13 | cd .. 14 | if [ "$(dirname "$PWD")" = "/" ]; then 15 | NOT_FOUND=0 16 | cd "$ORIGINAL_PWD" 17 | fi 18 | done 19 | 20 | if [[ "$CLASSPATH" != "" ]]; then 21 | echo "WARNING: You have \$CLASSPATH set, probably by accident." 22 | echo "It is strongly recommended to unset this before proceeding." 23 | fi 24 | 25 | # User init 26 | export LEIN_HOME="${LEIN_HOME:-"$HOME/.lein"}" 27 | 28 | # Support $JAVA_OPTS for backwards-compatibility. 29 | JVM_OPTS=${JVM_OPTS:-"$JAVA_OPTS"} 30 | JAVA_CMD=${JAVA_CMD:-"java"} 31 | 32 | for f in "/etc/leinrc" "$LEIN_HOME/leinrc" ".leinrc"; do 33 | if [ -e "$f" ]; then 34 | source "$f" 35 | fi 36 | done 37 | 38 | export LEIN_JVM_OPTS="${LEIN_JVM_OPTS-"-XX:+TieredCompilation -XX:TieredStopAtLevel=1"}" 39 | 40 | grep -E -q '^\s*:eval-in\s+:classloader\s*$' project.clj 2> /dev/null && 41 | LEIN_JVM_OPTS="${LEIN_JVM_OPTS:-'-Xms64m -Xmx512m'}" 42 | 43 | # If you're not using an uberjar you'll need to list each dependency 44 | # and add them individually to the classpath/bootclasspath as well. 45 | 46 | LEIN_JAR=/usr/share/java/leiningen-$LEIN_VERSION-standalone.jar 47 | 48 | # Do not use installed leiningen jar during self-compilation 49 | if ! { [ "$1" = "compile" ] && 50 | grep -qsE 'defproject leiningen[[:space:]]+"[[:digit:].]+"' \ 51 | project.clj ;}; then 52 | CLASSPATH="$CLASSPATH":"$LEIN_JAR" 53 | if [ "$LEIN_USE_BOOTCLASSPATH" != "no" ]; then 54 | LEIN_JVM_OPTS="-Xbootclasspath/a:$LEIN_JAR $LEIN_JVM_OPTS" 55 | fi 56 | fi 57 | 58 | # apply context specific CLASSPATH entries 59 | if [ -f .lein-classpath ]; then 60 | CLASSPATH="$(cat .lein-classpath):$CLASSPATH" 61 | fi 62 | 63 | if [ -n "$DEBUG" ]; then 64 | echo "Leiningen's classpath: $CLASSPATH" 65 | fi 66 | 67 | # Which Java? 68 | 69 | export JAVA_CMD="${JAVA_CMD:-"java"}" 70 | export LEIN_JAVA_CMD="${LEIN_JAVA_CMD:-$JAVA_CMD}" 71 | 72 | if [[ "$(basename "$LEIN_JAVA_CMD")" == *drip* ]]; then 73 | export DRIP_INIT="$(printf -- '-e\n(require (quote leiningen.repl))')" 74 | fi 75 | 76 | # Support $JAVA_OPTS for backwards-compatibility. 77 | export JVM_OPTS="${JVM_OPTS:-"$JAVA_OPTS"}" 78 | 79 | function command_not_found { 80 | >&2 echo "Leiningen couldn't find $1 in your \$PATH ($PATH), which is required." 81 | exit 1 82 | } 83 | 84 | if [ -r .lein-fast-trampoline ]; then 85 | export LEIN_FAST_TRAMPOLINE='y' 86 | fi 87 | 88 | if [ "$LEIN_FAST_TRAMPOLINE" != "" ] && [ -r project.clj ]; then 89 | INPUTS="$* $(cat project.clj) $LEIN_VERSION $(test -f "$LEIN_HOME/profiles.clj" && cat "$LEIN_HOME/profiles.clj") $(test -f profiles.clj && cat profiles.clj)" 90 | 91 | if command -v shasum >/dev/null 2>&1; then 92 | SUM="shasum" 93 | elif command -v sha1sum >/dev/null 2>&1; then 94 | SUM="sha1sum" 95 | else 96 | command_not_found "sha1sum or shasum" 97 | fi 98 | 99 | INPUT_CHECKSUM=$(echo "$INPUTS" | $SUM | cut -f 1 -d " ") 100 | # Just don't change :target-path in project.clj, mkay? 101 | TRAMPOLINE_FILE="target/trampolines/$INPUT_CHECKSUM" 102 | else 103 | TRAMPOLINE_FILE="$(mktemp /tmp/lein-trampoline-XXXXXXXXXXXXX)" 104 | trap 'rm -f $TRAMPOLINE_FILE' EXIT 105 | fi 106 | 107 | if [ "$1" = "upgrade" ]; then 108 | echo "This version of Leiningen was installed with a package manager, but" 109 | echo "the upgrade task is intended for manual installs. Please use your" 110 | echo "package manager's built-in upgrade facilities instead." 111 | exit 1 112 | fi 113 | 114 | if [ "$INPUT_CHECKSUM" != "" ] && [ -r "$TRAMPOLINE_FILE" ]; then 115 | if [ -n "$DEBUG" ]; then 116 | echo "Fast trampoline with $TRAMPOLINE_FILE." 117 | fi 118 | exec sh -c "exec $(cat $TRAMPOLINE_FILE)" 119 | else 120 | export TRAMPOLINE_FILE 121 | "$LEIN_JAVA_CMD" \ 122 | -Dfile.encoding=UTF-8 \ 123 | -Dmaven.wagon.http.ssl.easy=false \ 124 | -Dmaven.wagon.rto=10000 \ 125 | $LEIN_JVM_OPTS \ 126 | -Dleiningen.input-checksum="$INPUT_CHECKSUM" \ 127 | -Dleiningen.original.pwd="$ORIGINAL_PWD" \ 128 | -Dleiningen.script="$0" \ 129 | -classpath "$CLASSPATH" \ 130 | clojure.main -m leiningen.core.main "$@" 131 | 132 | EXIT_CODE=$? 133 | 134 | if [ -r "$TRAMPOLINE_FILE" ] && [ "$LEIN_TRAMPOLINE_WARMUP" = "" ]; then 135 | TRAMPOLINE="$(cat "$TRAMPOLINE_FILE")" 136 | if [ "$INPUT_CHECKSUM" = "" ]; then # not using fast trampoline 137 | rm "$TRAMPOLINE_FILE" 138 | fi 139 | if [ "$TRAMPOLINE" = "" ]; then 140 | exit $EXIT_CODE 141 | else 142 | exec sh -c "exec $TRAMPOLINE" 143 | fi 144 | else 145 | exit $EXIT_CODE 146 | fi 147 | fi 148 | -------------------------------------------------------------------------------- /test/leiningen/test/uberjar.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.test.uberjar 2 | (:require [leiningen.uberjar :refer :all] 3 | [clojure.test :refer :all] 4 | [clojure.java.io :refer [delete-file]] 5 | [clojure.java.shell :refer [sh]] 6 | [clojure.xml :as xml] 7 | [leiningen.test.helper :refer [unmemoize 8 | sample-no-aot-project 9 | uberjar-merging-project 10 | data-readers-backwards-compatibility-project 11 | provided-project 12 | managed-deps-project 13 | managed-deps-snapshot-project]]) 14 | (:import (java.io File FileOutputStream) 15 | (java.util.zip ZipFile))) 16 | 17 | (deftest test-uberjar 18 | (uberjar sample-no-aot-project) 19 | (let [filename (str "test_projects/sample-no-aot/target/" 20 | "nomnomnom-0.5.0-SNAPSHOT-standalone.jar") 21 | uberjar-file (File. filename)] 22 | (is (= true (.exists uberjar-file))) 23 | (when (.exists uberjar-file) 24 | (let [entries (->> (ZipFile. uberjar-file) 25 | .entries 26 | enumeration-seq 27 | (map (memfn getName)) 28 | set)] 29 | (.deleteOnExit uberjar-file) 30 | (is (entries "nom/nom/nom.clj")) 31 | (is (entries "org/codehaus/janino/Compiler$1.class")) 32 | (is (not (some #(re-find #"dummy" %) entries))))))) 33 | 34 | (deftest test-uberjar-merge-with 35 | (uberjar uberjar-merging-project) 36 | (let [filename (str "test_projects/uberjar-merging/target/" 37 | "nomnomnom-0.5.0-SNAPSHOT-standalone.jar") 38 | uberjar-file (File. filename)] 39 | (is (= true (.exists uberjar-file))) 40 | (when (.exists uberjar-file) 41 | (.deleteOnExit uberjar-file) 42 | (with-open [zf (ZipFile. uberjar-file)] 43 | (is (= '{nomnomnom/identity clojure.core/identity 44 | mf/i nomnomnom/override 45 | mf/s method.fn/static 46 | ordered/set flatland.ordered.set/into-ordered-set 47 | ordered/map flatland.ordered.map/ordered-map} 48 | (->> (.getEntry zf "data_readers.clj") 49 | (.getInputStream zf) 50 | slurp read-string))))))) 51 | 52 | (deftest test-uberjar-data-readers-backwards-compatibility 53 | (uberjar data-readers-backwards-compatibility-project) 54 | (let [filename (str "test_projects/data-readers-backwards-compatibility/" 55 | "target/bug-bug-standalone.jar") 56 | uberjar-file (File. filename)] 57 | (is (= true (.exists uberjar-file))) 58 | (when (.exists uberjar-file) 59 | (.deleteOnExit uberjar-file) 60 | (with-open [zf (ZipFile. uberjar-file)] 61 | (let [contents (->> (.getEntry zf "data_readers.clj") 62 | (.getInputStream zf) 63 | slurp)] 64 | (is (.startsWith contents "{")) ;; not a namespaced map 65 | (is (= '{ordered/set flatland.ordered.set/into-ordered-set 66 | ordered/map flatland.ordered.map/ordered-map} 67 | (read-string contents)))))))) 68 | 69 | (deftest test-components-merger 70 | (let [file1 (str "test_projects/uberjar-components-merging/components1.xml") 71 | file2 (str "test_projects/uberjar-components-merging/components2.xml") 72 | readxml (components-merger 0) 73 | combine (components-merger 1) 74 | writexml (components-merger 2) 75 | combined-xml (combine (readxml file1) (readxml file2)) 76 | expected-xml (xml/parse "test_projects/uberjar-components-merging/expected-components.xml") 77 | result-file "test_projects/uberjar-components-merging/result-components.xml" 78 | out-file (FileOutputStream. (File. result-file))] 79 | (writexml out-file combined-xml) 80 | (is (= expected-xml (xml/parse result-file))) 81 | (delete-file result-file true))) 82 | 83 | ;; TODO: this breaks on Java 6 84 | (deftest ^:disabled test-uberjar-provided 85 | (let [bootclasspath "-Xbootclasspath/a:leiningen-core/lib/clojure-1.4.0.jar" 86 | filename "test_projects/provided/target/provided-0-standalone.jar" 87 | _ (uberjar provided-project)] 88 | (is (= 1 (:exit (sh "java" "-jar" filename)))) 89 | (is (= 0 (:exit (sh "java" bootclasspath "-jar" filename)))))) 90 | 91 | (deftest test-uberjar-managed-dependencies 92 | (unmemoize #'leiningen.core.classpath/get-dependencies-memoized 93 | #'leiningen.core.classpath/get-dependencies*) 94 | (doseq [[proj jarfile] [[managed-deps-snapshot-project 95 | (str "test_projects/managed-deps-snapshot/target/" 96 | "mgmt-0.99.0-SNAPSHOT-standalone.jar")] 97 | [managed-deps-project 98 | (str "test_projects/managed-deps/target/" 99 | "mgmt-0.99.0-standalone.jar")]]] 100 | (uberjar proj) 101 | (let [uberjar-file (File. jarfile)] 102 | (is (= true (.exists uberjar-file)) 103 | (format "File '%s' does not exist!" uberjar-file))))) 104 | -------------------------------------------------------------------------------- /leiningen-core/src/leiningen/core/ssl.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.core.ssl 2 | (:require [cemerick.pomegranate.aether :as aether] 3 | [clojure.java.io :as io] 4 | [leiningen.core.user :as user]) 5 | (:import java.security.KeyStore 6 | java.security.KeyStore$TrustedCertificateEntry 7 | java.security.Security 8 | java.security.cert.CertificateFactory 9 | javax.net.ssl.KeyManagerFactory 10 | javax.net.ssl.SSLContext 11 | javax.net.ssl.TrustManagerFactory 12 | javax.net.ssl.X509TrustManager 13 | java.io.FileInputStream 14 | org.apache.http.config.RegistryBuilder 15 | org.apache.http.conn.socket.PlainConnectionSocketFactory 16 | org.apache.http.conn.ssl.DefaultHostnameVerifier 17 | org.apache.http.conn.ssl.SSLConnectionSocketFactory 18 | org.apache.http.impl.conn.PoolingHttpClientConnectionManager 19 | org.apache.maven.wagon.providers.http.HttpWagon)) 20 | 21 | (defn ^TrustManagerFactory trust-manager-factory [^KeyStore keystore] 22 | (doto (TrustManagerFactory/getInstance "PKIX") 23 | (.init keystore))) 24 | 25 | (defn default-trust-managers [] 26 | (let [tmf (trust-manager-factory nil) 27 | tms (.getTrustManagers tmf)] 28 | (filter #(instance? X509TrustManager %) tms))) 29 | 30 | (defn key-manager-props [] 31 | (let [read #(java.lang.System/getProperty %)] 32 | (merge {:file (read "javax.net.ssl.keyStore") 33 | :type (read "javax.net.ssl.keyStoreType") 34 | :provider (read "javax.net.ssl.keyStoreProvider") 35 | :password (read "javax.net.ssl.keyStorePassword")} 36 | (-> (user/profiles) :user :key-manager-properties)))) 37 | 38 | (defn key-manager-factory [{:keys [file type provider password]}] 39 | (let [type (or type (KeyStore/getDefaultType)) 40 | fis (if-not (empty? file) (FileInputStream. file)) 41 | pwd (and password (.toCharArray password)) 42 | store (if provider 43 | (KeyStore/getInstance type provider) 44 | (KeyStore/getInstance type))] 45 | (.load store fis pwd) 46 | (when fis (.close fis)) 47 | (doto (KeyManagerFactory/getInstance 48 | (KeyManagerFactory/getDefaultAlgorithm)) 49 | (.init store pwd)))) 50 | 51 | (defn default-trusted-certs 52 | "Lists the CA certificates trusted by the JVM." 53 | [] 54 | (mapcat #(.getAcceptedIssuers %) (default-trust-managers))) 55 | 56 | (defn read-certs 57 | "Read one or more X.509 certificates in DER or PEM format." 58 | [f] 59 | (let [cf (CertificateFactory/getInstance "X.509") 60 | in (io/input-stream (or (io/resource f) (io/file f)))] 61 | (.generateCertificates cf in))) 62 | 63 | (defn make-keystore 64 | "Construct a KeyStore that trusts a collection of certificates." 65 | [certs] 66 | (let [ks (KeyStore/getInstance "jks")] 67 | (.load ks nil nil) 68 | (doseq [[i cert] (map vector (range) certs)] 69 | (.setEntry ks (str i) (KeyStore$TrustedCertificateEntry. cert) nil)) 70 | ks)) 71 | 72 | ;; TODO: honor settings from project.clj, not just user profile 73 | (defn make-sslcontext 74 | "Construct an SSLContext that trusts a collection of certificates." 75 | [trusted-certs] 76 | (let [ks (make-keystore trusted-certs) 77 | kmf (key-manager-factory (key-manager-props)) 78 | tmf (trust-manager-factory ks)] 79 | (doto (SSLContext/getInstance "TLS") 80 | (.init (.getKeyManagers kmf) (.getTrustManagers tmf) nil)))) 81 | 82 | (alter-var-root #'make-sslcontext memoize) 83 | 84 | (defn https-registry 85 | "Constructs a registry map that uses a given SSLContext for https." 86 | [context] 87 | (let [factory (SSLConnectionSocketFactory. context (DefaultHostnameVerifier.))] 88 | {"https" factory 89 | "http" PlainConnectionSocketFactory/INSTANCE})) 90 | 91 | (defn ^:deprecated https-scheme 92 | "Constructs a registry map that uses a given SSLContext for https. 93 | 94 | DEPRECATED: Use https-registry instead." 95 | ([context port] 96 | (if (not= port 443) ;; TODO: Should we support this? 97 | (throw (ex-info "Specifying port for https-scheme is not possible anymore." 98 | {:context context :port port})) 99 | (https-scheme context))) 100 | ([context] 101 | (binding [*out* *err*] 102 | (println "https-scheme is deprecated, use https-registry instead")) 103 | (https-registry context))) 104 | 105 | (defn- map->registry 106 | "Creates a Registry based of the given map." 107 | [m] 108 | (let [rb (RegistryBuilder/create)] 109 | (doseq [[scheme conn-sock-factory] m] 110 | (.register rb scheme conn-sock-factory)) 111 | (.build rb))) 112 | 113 | (defn override-wagon-registry! 114 | "Override the registry scheme used by the HTTP Wagon's Connection 115 | manager (used for Aether)." 116 | [registry] 117 | (let [cm (PoolingHttpClientConnectionManager. (map->registry registry))] 118 | (HttpWagon/setPoolingHttpClientConnectionManager cm))) 119 | 120 | (defn ^:deprecated register-scheme 121 | "Override the registry scheme used by the HTTP Wagon's Connection 122 | manager (used for Aether). 123 | 124 | DEPRECATED: Use override-wagon-registry! instead." 125 | [scheme] 126 | (binding [*out* *err*] 127 | (println "register-scheme is deprecated, use override-wagon-registry! instead")) 128 | (override-wagon-registry! scheme)) 129 | --------------------------------------------------------------------------------