[
  {
    "path": ".build.yml",
    "content": "# -*- js -*-\n{\n    \"image\": \"debian/stable\",\n    \"packages\": [\"gnupg\", \"leiningen\", \"openssh-client\"],\n    \"sources\": [\"https://codeberg.org/leiningen/leiningen\"],\n    \"tasks\": [{\"build\": \"cd leiningen/leiningen-core && lein bootstrap && cd .. && bin/lein test\"}],\n}\n"
  },
  {
    "path": ".circleci/config.yml",
    "content": "# -*- js -*-\n{\n  \"version\": 2.1,\n  \"executors\": {\n    \"clojure\": {\n      \"docker\": [{\"image\": \"clojure:<< parameters.java_version >>-lein\"}],\n      \"parameters\": {\n        \"java_version\": {\n          \"description\": \"Java version\",\n          \"default\": \"openjdk-17\",\n          \"type\": \"string\"\n        }\n      },\n      \"working_directory\": \"~/leiningen\"\n    }\n  },\n  \"jobs\": {\n    \"build\": {\n      \"executor\": \"clojure\",\n      \"parameters\": {\n        \"java_version\": {\n          \"description\": \"Java version\",\n          \"default\": \"<< parameters.java_version >>\",\n          \"type\": \"string\"\n        }\n      },\n      \"steps\": [\n        \"checkout\",\n        {\n          \"run\": \"apt update -qq && apt install -y gnupg openssh-client\"\n        },\n        {\n          \"restore_cache\": {\n            \"key\": \"leiningen-{{ checksum \\\"project.clj\\\" }}-{{ checksum \\\"leiningen-core/project.clj\\\" }}\"\n          }\n        },\n        {\n          \"run\": {\n            \"name\": \"Bootstrap leiningen-core\",\n            \"working_directory\": \"~/leiningen/leiningen-core\",\n            \"command\": \"lein bootstrap\"\n          }\n        },\n        {\n          \"run\": {\n            \"name\": \"Test Leiningen\",\n            \"command\": \"bin/lein test\"\n          }\n        },\n        {\n          \"save_cache\": {\n            \"paths\": [\"~/.m2/repository\"],\n            \"key\": \"leiningen-{{ checksum \\\"project.clj\\\" }}-{{ checksum \\\"leiningen-core/project.clj\\\" }}\"\n          }\n        }\n      ]\n    }\n  },\n  \"workflows\": {\n    \"test-with-matrix\": {\n      \"jobs\": [\n        {\"build\": {\"name\": \"openjdk17\", \"java_version\": \"openjdk-17\"}},\n        {\"build\": {\"name\": \"openjdk21\", \"java_version\": \"openjdk-21\"}}\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "#disable autocrlf for all .bat files since they already have CRLF in raw format\n*.bat -crlf\n"
  },
  {
    "path": ".github/README.md",
    "content": "# Hello Github User!\n\nThe Leiningen project is in the process of [moving off\nGithub](https://sfconservancy.org/GiveUpGitHub/).\n\nThis repository will continue to be sporadically updated as a mirror\nfor a while as we work to complete the move, but please switch your\ngit remotes over to https://codeberg.org/leiningen/leiningen\n\nCodeberg works just like Github, and you can even use your Github\naccount to log in there, but it is operated like a user-owned\ncooperative with a [democratic governance model](https://join.codeberg.org/)\ninstead of being an extractive arm of an unaccountable abusive megacorp.\n\nAs usual, you can join the `#leiningen` IRC channel on\n[Libera.Chat](https://libera.chat) to discuss issues.\n\nAny use of this project's code by Github Copilot, past or present, is done\nwithout our permission. We do not consent to Github's use of this project's\ncode in training Copilot or any other language model.\n\n## For your consideration\n\nI get it, Github is what *everyone* uses. But it's never been a good\nidea to allow one company to have a monopoly, and it's an even worse\nidea when that company has a history of abusing their monopoly.\n\nIf you haven't taken a look at Github alternatives, now's a great time\nto evaluate a new home for your project! If you took a look at Gitlab\na few years ago and were put off by its clunkiness and bugs, you\nshould know that there are much better alternatives now.\n\n[Codeberg](https://codeberg.org/) is perhaps the most polished\nalternative, but [Sourcehut](https://git.sr.ht/) is also quite nice\nfor minimalists, and if you're adventurous you could try running your\nown [Forgejo](https://forgejo.org/). Or maybe you [don't even need a\nforge](https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/git-no-forge/)?\n"
  },
  {
    "path": ".gitignore",
    "content": "**/target\n*.bak\n*.swp\n*.class\n*asc\n*jar\n*~\n.lein*\n/.classpath\n/.nrepl-port\n/.prepl-port\n/.project\n/.settings\n/hs_err_pid*.log\n/lein.man\n/lein_ja.man\n/leiningen-core/.lein-plugins/checksum\n/leiningen-core/.nrepl-port\n/leiningen-core/.prepl-port\n/leiningen-core/dev-resources/target\n/lein-pprint/.nrepl-port\n/lein-pprint/.prepl-port\n/logs\n/scratch.clj\n/scratch\n/target\n/wiki\nTAGS\ntest_projects/*/target\npom.xml\ndeps.txt\nprofiles.clj\n/test/.gnupg/crls.d/DIR.txt\n/test_projects/sample/project.clj.sig\n/web/deploy.html\n/web/faq.html\n/web/plugins.html\n/web/profiles.html\n/web/templates.html\n/web/tutorial.html\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nLeiningen is the most widely-contributed-to Clojure project a the time\nof this writing. We welcome potential contributors and do our best to\ntry to make it easy to help out.\n\nDiscussion occurs primarily in the #leiningen channel on [Libera\nchat](https://libera.chat).\n\nPlease report issues on the\n[issue tracker](https://codeberg.org/leiningen/leiningen/issues). Issues used\nto be reported in the [GitHub tracker](https://github.com/technomancy/leiningen/issues)\nso you may want to check there to see if things have already been reported.\n\nCode submissions should be sent as [pull\nrequests](https://codeberg.org/leiningen/leiningen/pulls). Please\nuse topic branches when sending pull requests rather than committing\ndirectly to `main` in order to minimize unnecessary merge commit\nclutter. Direct pull requests towards the `main` branch, not the\nstable branch.\n\nYou can add a 1-line summary of your change to `NEWS.md` if it's a\nuser-visible issue that affects more than a handful of people.\n\nPlease note that it is ethically unacceptable to submit patches (to\nthis project or any other) which you did not author yourself without\ngiving clear attribution to the original author. Note that this\nincludes submitting changes generated by most so-called \"artificial\nintelligence\" language models as these systems often make it\nimpossible to even identify (much less credit) the original author.\n\nNote: the canonical repository for Leiningen is [on\nCodeberg](https://codeberg.org/leiningen/leiningen) but we maintain [a\nmirror on GitHub](https://github.com/technomancy/leiningen) for the\ntime being in order to ease the transition. Please update your links\nand git remotes.\n\n## Codebase\n\nThe definitions of the various tasks reside in `src/leiningen` in the\ntop-level project. The underlying mechanisms for things like\n`project.clj` parsing, classpath calculation, and subprocess launching\nare implemented inside the `leiningen-core` subproject.\n\nSee the\n[readme for the leiningen-core library](https://codeberg.org/leiningen/leiningen/src/main/leiningen-core/README.md)\nand `doc/PLUGINS.md` for more details on how Leiningen's codebase is\nstructured.\n\nTry to be aware of the conventions in the existing code, except the\none where we don't write tests. Make a reasonable attempt to avoid\nlines longer than 80 columns or function bodies longer than 20\nlines. Don't use `when` unless it's for side-effects. Don't introduce\nnew protocols. Use `^:internal` metadata to mark vars which can't be\nprivate but shouldn't be considered part of the public API.\n\n## Bootstrapping\n\nYou don't need to \"build\" Leiningen per se, but when you're developing on a\ncheckout you will need to get its dependencies in place and compile some of the\ntasks. Assuming you are in Leiningen's project root, you can do that like this:\n\n```bash\n$ cd leiningen-core\n$ lein bootstrap # or lein.bat on Windows.\n```\n\nThe `lein` command is a stable release of Leiningen on your `$PATH` – preferably\nthe newest one. If you don't have a stable `lein` installed, simply check out\nthe `stable` branch and copy `bin/lein` to somewhere on your `$PATH`, then\nswitch your branch back.\n\nIf you want to use your development copy for everyday usage, symlink\n`bin/lein` to somewhere on your `$PATH`. You'll want to rename your\nstable installation to keep them from interfering; typically you can\nname that `lein2` or `lein-stable`.\n\nWhen dependencies in Leiningen change, you may have to do `rm .lein-classpath`\nin the project root, though in most cases this will be done automatically. If\ndependencies in leiningen-core change, you have to redo the `lein bootstrap`\nstep mentioned earlier.\n\nUsing `bin/lein` alone from the main branch without a full checkout\nis not supported. If you want to just grab a shell script to work\nwith, use the `stable` branch.\n\nYou can also bootstrap using [Maven](https://maven.apache.org/) to work\naround the chicken/egg bootstrapping problem if you cannot or do not want to\ninstall a stable Leiningen build.\n\n```bash\n$ cd leiningen-core\n$ mvn install\n$ mvn dependency:build-classpath -Dmdep.outputFile=cp.txt\n```\n\n### Uberjar from main\n\nSince a development version is not uberjared, it can be rather slow compared to\na stable release. If this is annoying and you depend on a recent fix or\nenhancement, you can build an uberjar from main as follows:\n\n```bash\n# NB! You have to use *bin*/lein to build the uberjar\n$ bin/lein uberjar\n# ^ Last line printed from this command will tell the location of the standalone\n$ cp target/leiningen-2.5.2-SNAPSHOT-standalone.jar $HOME/.lein/self-installs\n$ cp bin/lein $HOME/bin/lein-main\n```\n\nHere, 2.5.2-SNAPSHOT is the version we've built, and we have `$HOME/bin` on our\n$PATH.\n\nNote that changes on main won't be visible in the uberjared version unless you\noverwrite both the lein script and a freshly created uberjar.\n\n## Tests\n\nBefore you submit a pull request, we would be very happy if you ensure\nthat the changes you've done doesn't break any of the existing test cases. While\nthere is a test suite, it's not terribly thorough, so don't put too much trust\nin it. Patches which add test coverage for the functionality they change are\nespecially welcome.\n\nTo run the test cases, run `bin/lein test` in the root directory: This will test\nboth `leiningen-core` and `leiningen` itself. Do not attempt to run the tests\nwith a stable version of Leiningen, as the namespaces conflict and you may end\nup with errors during the test run.\n"
  },
  {
    "path": "COPYING",
    "content": "Source code distributed under the Eclipse Public License - v 1.0:\n\nTHE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE\nPUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION OF\nTHE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\na) in the case of the initial Contributor, the initial code and\ndocumentation distributed under this Agreement, and\n\nb) in the case of each subsequent Contributor:\n\ni) changes to the Program, and\n\nii) additions to the Program;\n\nwhere such changes and/or additions to the Program originate from and\nare distributed by that particular Contributor. A Contribution\n'originates' from a Contributor if it was added to the Program by such\nContributor itself or anyone acting on such Contributor's\nbehalf. Contributions do not include additions to the Program which:\n(i) are separate modules of software distributed in conjunction with\nthe Program under their own license agreement, and (ii) are not\nderivative works of the Program.\n\n\"Contributor\" means any person or entity that distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor\nwhich are necessarily infringed by the use or sale of its Contribution\nalone or when combined with the Program.\n\n\"Program\" means the Contributions distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this\nAgreement, including all Contributors.\n\n2. GRANT OF RIGHTS\n\na) Subject to the terms of this Agreement, each Contributor hereby\ngrants Recipient a non-exclusive, worldwide, royalty-free copyright\nlicense to reproduce, prepare derivative works of, publicly display,\npublicly perform, distribute and sublicense the Contribution of such\nContributor, if any, and such derivative works, in source code and\nobject code form.\n\nb) Subject to the terms of this Agreement, each Contributor hereby\ngrants Recipient a non-exclusive, worldwide, royalty-free patent\nlicense under Licensed Patents to make, use, sell, offer to sell,\nimport and otherwise transfer the Contribution of such Contributor, if\nany, in source code and object code form.  This patent license shall\napply to the combination of the Contribution and the Program if, at\nthe time the Contribution is added by the Contributor, such addition\nof the Contribution causes such combination to be covered by the\nLicensed Patents. The patent license shall not apply to any other\ncombinations which include the Contribution. No hardware per se is\nlicensed hereunder.\n\nc) Recipient understands that although each Contributor grants the\nlicenses to its Contributions set forth herein, no assurances are\nprovided by any Contributor that the Program does not infringe the\npatent or other intellectual property rights of any other entity. Each\nContributor disclaims any liability to Recipient for claims brought by\nany other entity based on infringement of intellectual property rights\nor otherwise. As a condition to exercising the rights and licenses\ngranted hereunder, each Recipient hereby assumes sole responsibility\nto secure any other intellectual property rights needed, if any. For\nexample, if a third party patent license is required to allow\nRecipient to distribute the Program, it is Recipient's responsibility\nto acquire that license before distributing the Program.\n\nd) Each Contributor represents that to its knowledge it has sufficient\ncopyright rights in its Contribution, if any, to grant the copyright\nlicense set forth in this Agreement.\n\n3. REQUIREMENTS\n\nA Contributor may choose to distribute the Program in object code form\nunder its own license agreement, provided that:\n\na) it complies with the terms and conditions of this Agreement; and\n\nb) its license agreement:\n\ni) effectively disclaims on behalf of all Contributors all warranties\nand conditions, express and implied, including warranties or\nconditions of title and non-infringement, and implied warranties or\nconditions of merchantability and fitness for a particular purpose;\n\nii) effectively excludes on behalf of all Contributors all liability\nfor damages, including direct, indirect, special, incidental and\nconsequential damages, such as lost profits;\n\niii) states that any provisions which differ from this Agreement are\noffered by that Contributor alone and not by any other party; and\n\niv) states that source code for the Program is available from such\nContributor, and informs licensees how to obtain it in a reasonable\nmanner on or through a medium customarily used for software exchange.\n\nWhen the Program is made available in source code form:\n\na) it must be made available under this Agreement; and\n\nb) a copy of this Agreement must be included with each copy of the Program.\n\nContributors may not remove or alter any copyright notices contained\nwithin the Program.\n\nEach Contributor must identify itself as the originator of its\nContribution, if any, in a manner that reasonably allows subsequent\nRecipients to identify the originator of the Contribution.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain\nresponsibilities with respect to end users, business partners and the\nlike. While this license is intended to facilitate the commercial use\nof the Program, the Contributor who includes the Program in a\ncommercial product offering should do so in a manner which does not\ncreate potential liability for other Contributors. Therefore, if a\nContributor includes the Program in a commercial product offering,\nsuch Contributor (\"Commercial Contributor\") hereby agrees to defend\nand indemnify every other Contributor (\"Indemnified Contributor\")\nagainst any losses, damages and costs (collectively \"Losses\") arising\nfrom claims, lawsuits and other legal actions brought by a third party\nagainst the Indemnified Contributor to the extent caused by the acts\nor omissions of such Commercial Contributor in connection with its\ndistribution of the Program in a commercial product offering.  The\nobligations in this section do not apply to any claims or Losses\nrelating to any actual or alleged intellectual property\ninfringement. In order to qualify, an Indemnified Contributor must: a)\npromptly notify the Commercial Contributor in writing of such claim,\nand b) allow the Commercial Contributor to control, and cooperate with\nthe Commercial Contributor in, the defense and any related settlement\nnegotiations. The Indemnified Contributor may participate in any such\nclaim at its own expense.\n\nFor example, a Contributor might include the Program in a commercial\nproduct offering, Product X. That Contributor is then a Commercial\nContributor. If that Commercial Contributor then makes performance\nclaims, or offers warranties related to Product X, those performance\nclaims and warranties are such Commercial Contributor's responsibility\nalone. Under this section, the Commercial Contributor would have to\ndefend claims against the other Contributors related to those\nperformance claims and warranties, and if a court requires any other\nContributor to pay any damages as a result, the Commercial Contributor\nmust pay those damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS\nPROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\nKIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY\nWARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY\nOR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely\nresponsible for determining the appropriateness of using and\ndistributing the Program and assumes all risks associated with its\nexercise of rights under this Agreement , including but not limited to\nthe risks and costs of program errors, compliance with applicable\nlaws, damage to or loss of data, programs or equipment, and\nunavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR\nANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING\nWITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR\nDISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED\nHEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of\nthe remainder of the terms of this Agreement, and without further\naction by the parties hereto, such provision shall be reformed to the\nminimum extent necessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nthe Program itself (excluding combinations of the Program with other\nsoftware or hardware) infringes such Recipient's patent(s), then such\nRecipient's rights granted under Section 2(b) shall terminate as of\nthe date such litigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it\nfails to comply with any of the material terms or conditions of this\nAgreement and does not cure such failure in a reasonable period of\ntime after becoming aware of such noncompliance. If all Recipient's\nrights under this Agreement terminate, Recipient agrees to cease use\nand distribution of the Program as soon as reasonably\npracticable. However, Recipient's obligations under this Agreement and\nany licenses granted by Recipient relating to the Program shall\ncontinue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement,\nbut in order to avoid inconsistency the Agreement is copyrighted and\nmay only be modified in the following manner. The Agreement Steward\nreserves the right to publish new versions (including revisions) of\nthis Agreement from time to time. No one other than the Agreement\nSteward has the right to modify this Agreement. The Eclipse Foundation\nis the initial Agreement Steward. The Eclipse Foundation may assign\nthe responsibility to serve as the Agreement Steward to a suitable\nseparate entity. Each new version of the Agreement will be given a\ndistinguishing version number. The Program (including Contributions)\nmay always be distributed subject to the version of the Agreement\nunder which it was received. In addition, after a new version of the\nAgreement is published, Contributor may elect to distribute the\nProgram (including its Contributions) under the new version. Except as\nexpressly stated in Sections 2(a) and 2(b) above, Recipient receives\nno rights or licenses to the intellectual property of any Contributor\nunder this Agreement, whether expressly, by implication, estoppel or\notherwise. All rights in the Program not expressly granted under this\nAgreement are reserved.\n\nThis Agreement is governed by the laws of the State of New York and\nthe intellectual property laws of the United States of America. No\nparty to this Agreement will bring a legal action under this Agreement\nmore than one year after the cause of action arose. Each party waives\nits rights to a jury trial in any resulting litigation.\n\n\f\n\nImages distributed under the Creative Commons Attribution + ShareAlike\nLicense version 3.0:\n\nTHE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS\nCREATIVE COMMONS PUBLIC LICENSE (\"CCPL\" OR \"LICENSE\"). THE WORK IS\nPROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE\nWORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS\nPROHIBITED.\n\nBY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND\nAGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS\nLICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU\nTHE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH\nTERMS AND CONDITIONS.\n\n1. Definitions\n\n    \"Adaptation\" means a work based upon the Work, or upon the Work\n    and other pre-existing works, such as a translation, adaptation,\n    derivative work, arrangement of music or other alterations of a\n    literary or artistic work, or phonogram or performance and\n    includes cinematographic adaptations or any other form in which\n    the Work may be recast, transformed, or adapted including in any\n    form recognizably derived from the original, except that a work\n    that constitutes a Collection will not be considered an Adaptation\n    for the purpose of this License. For the avoidance of doubt, where\n    the Work is a musical work, performance or phonogram, the\n    synchronization of the Work in timed-relation with a moving image\n    (\"synching\") will be considered an Adaptation for the purpose of\n    this License.\n\n    \"Collection\" means a collection of literary or artistic works,\n    such as encyclopedias and anthologies, or performances, phonograms\n    or broadcasts, or other works or subject matter other than works\n    listed in Section 1(f) below, which, by reason of the selection\n    and arrangement of their contents, constitute intellectual\n    creations, in which the Work is included in its entirety in\n    unmodified form along with one or more other contributions, each\n    constituting separate and independent works in themselves, which\n    together are assembled into a collective whole. A work that\n    constitutes a Collection will not be considered an Adaptation (as\n    defined below) for the purposes of this License.\n\n    \"Creative Commons Compatible License\" means a license that is\n    listed at https://creativecommons.org/compatiblelicenses that has\n    been approved by Creative Commons as being essentially equivalent\n    to this License, including, at a minimum, because that license:\n    (i) contains terms that have the same purpose, meaning and effect\n    as the License Elements of this License; and, (ii) explicitly\n    permits the relicensing of adaptations of works made available\n    under that license under this License or a Creative Commons\n    jurisdiction license with the same License Elements as this\n    License.\n\n    \"Distribute\" means to make available to the public the original\n    and copies of the Work or Adaptation, as appropriate, through sale\n    or other transfer of ownership.\n\n    \"License Elements\" means the following high-level license\n    attributes as selected by Licensor and indicated in the title of\n    this License: Attribution, ShareAlike.\n\n    \"Licensor\" means the individual, individuals, entity or entities\n    that offer(s) the Work under the terms of this License.\n\n    \"Original Author\" means, in the case of a literary or artistic\n    work, the individual, individuals, entity or entities who created\n    the Work or if no individual or entity can be identified, the\n    publisher; and in addition (i) in the case of a performance the\n    actors, singers, musicians, dancers, and other persons who act,\n    sing, deliver, declaim, play in, interpret or otherwise perform\n    literary or artistic works or expressions of folklore; (ii) in the\n    case of a phonogram the producer being the person or legal entity\n    who first fixes the sounds of a performance or other sounds; and,\n    (iii) in the case of broadcasts, the organization that transmits\n    the broadcast.\n\n    \"Work\" means the literary and/or artistic work offered under the\n    terms of this License including without limitation any production\n    in the literary, scientific and artistic domain, whatever may be\n    the mode or form of its expression including digital form, such as\n    a book, pamphlet and other writing; a lecture, address, sermon or\n    other work of the same nature; a dramatic or dramatico-musical\n    work; a choreographic work or entertainment in dumb show; a\n    musical composition with or without words; a cinematographic work\n    to which are assimilated works expressed by a process analogous to\n    cinematography; a work of drawing, painting, architecture,\n    sculpture, engraving or lithography; a photographic work to which\n    are assimilated works expressed by a process analogous to\n    photography; a work of applied art; an illustration, map, plan,\n    sketch or three-dimensional work relative to geography,\n    topography, architecture or science; a performance; a broadcast; a\n    phonogram; a compilation of data to the extent it is protected as\n    a copyrightable work; or a work performed by a variety or circus\n    performer to the extent it is not otherwise considered a literary\n    or artistic work.\n\n    \"You\" means an individual or entity exercising rights under this\n    License who has not previously violated the terms of this License\n    with respect to the Work, or who has received express permission\n    from the Licensor to exercise rights under this License despite a\n    previous violation.\n\n    \"Publicly Perform\" means to perform public recitations of the Work\n    and to communicate to the public those public recitations, by any\n    means or process, including by wire or wireless means or public\n    digital performances; to make available to the public Works in\n    such a way that members of the public may access these Works from\n    a place and at a place individually chosen by them; to perform the\n    Work to the public by any means or process and the communication\n    to the public of the performances of the Work, including by public\n    digital performance; to broadcast and rebroadcast the Work by any\n    means including signs, sounds or images.\n\n    \"Reproduce\" means to make copies of the Work by any means\n    including without limitation by sound or visual recordings and the\n    right of fixation and reproducing fixations of the Work, including\n    storage of a protected performance or phonogram in digital form or\n    other electronic medium.\n\n2. Fair Dealing Rights. Nothing in this License is intended to reduce,\nlimit, or restrict any uses free from copyright or rights arising from\nlimitations or exceptions that are provided for in connection with the\ncopyright protection under copyright law or other applicable laws.\n\n3. License Grant. Subject to the terms and conditions of this License,\nLicensor hereby grants You a worldwide, royalty-free, non-exclusive,\nperpetual (for the duration of the applicable copyright) license to\nexercise the rights in the Work as stated below:\n\n    to Reproduce the Work, to incorporate the Work into one or more\n    Collections, and to Reproduce the Work as incorporated in the\n    Collections;\n\n    to create and Reproduce Adaptations provided that any such\n    Adaptation, including any translation in any medium, takes\n    reasonable steps to clearly label, demarcate or otherwise identify\n    that changes were made to the original Work. For example, a\n    translation could be marked \"The original work was translated from\n    English to Spanish,\" or a modification could indicate \"The\n    original work has been modified.\";\n\n    to Distribute and Publicly Perform the Work including as\n    incorporated in Collections; and,\n\n    to Distribute and Publicly Perform Adaptations.\n\n    For the avoidance of doubt:\n\n        Non-waivable Compulsory License Schemes. In those\n        jurisdictions in which the right to collect royalties through\n        any statutory or compulsory licensing scheme cannot be waived,\n        the Licensor reserves the exclusive right to collect such\n        royalties for any exercise by You of the rights granted under\n        this License;\n\n        Waivable Compulsory License Schemes. In those jurisdictions in\n        which the right to collect royalties through any statutory or\n        compulsory licensing scheme can be waived, the Licensor waives\n        the exclusive right to collect such royalties for any exercise\n        by You of the rights granted under this License; and,\n\n        Voluntary License Schemes. The Licensor waives the right to\n        collect royalties, whether individually or, in the event that\n        the Licensor is a member of a collecting society that\n        administers voluntary licensing schemes, via that society,\n        from any exercise by You of the rights granted under this\n        License.\n\nThe above rights may be exercised in all media and formats whether now\nknown or hereafter devised. The above rights include the right to make\nsuch modifications as are technically necessary to exercise the rights\nin other media and formats. Subject to Section 8(f), all rights not\nexpressly granted by Licensor are hereby reserved.\n\n4. Restrictions. The license granted in Section 3 above is expressly\nmade subject to and limited by the following restrictions:\n\n    You may Distribute or Publicly Perform the Work only under the\n    terms of this License. You must include a copy of, or the Uniform\n    Resource Identifier (URI) for, this License with every copy of the\n    Work You Distribute or Publicly Perform. You may not offer or\n    impose any terms on the Work that restrict the terms of this\n    License or the ability of the recipient of the Work to exercise\n    the rights granted to that recipient under the terms of the\n    License. You may not sublicense the Work. You must keep intact all\n    notices that refer to this License and to the disclaimer of\n    warranties with every copy of the Work You Distribute or Publicly\n    Perform. When You Distribute or Publicly Perform the Work, You may\n    not impose any effective technological measures on the Work that\n    restrict the ability of a recipient of the Work from You to\n    exercise the rights granted to that recipient under the terms of\n    the License. This Section 4(a) applies to the Work as incorporated\n    in a Collection, but this does not require the Collection apart\n    from the Work itself to be made subject to the terms of this\n    License. If You create a Collection, upon notice from any Licensor\n    You must, to the extent practicable, remove from the Collection\n    any credit as required by Section 4(c), as requested. If You\n    create an Adaptation, upon notice from any Licensor You must, to\n    the extent practicable, remove from the Adaptation any credit as\n    required by Section 4(c), as requested.\n\n    You may Distribute or Publicly Perform an Adaptation only under\n    the terms of: (i) this License; (ii) a later version of this\n    License with the same License Elements as this License; (iii) a\n    Creative Commons jurisdiction license (either this or a later\n    license version) that contains the same License Elements as this\n    License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative\n    Commons Compatible License. If you license the Adaptation under\n    one of the licenses mentioned in (iv), you must comply with the\n    terms of that license. If you license the Adaptation under the\n    terms of any of the licenses mentioned in (i), (ii) or (iii) (the\n    \"Applicable License\"), you must comply with the terms of the\n    Applicable License generally and the following provisions: (I) You\n    must include a copy of, or the URI for, the Applicable License\n    with every copy of each Adaptation You Distribute or Publicly\n    Perform; (II) You may not offer or impose any terms on the\n    Adaptation that restrict the terms of the Applicable License or\n    the ability of the recipient of the Adaptation to exercise the\n    rights granted to that recipient under the terms of the Applicable\n    License; (III) You must keep intact all notices that refer to the\n    Applicable License and to the disclaimer of warranties with every\n    copy of the Work as included in the Adaptation You Distribute or\n    Publicly Perform; (IV) when You Distribute or Publicly Perform the\n    Adaptation, You may not impose any effective technological\n    measures on the Adaptation that restrict the ability of a\n    recipient of the Adaptation from You to exercise the rights\n    granted to that recipient under the terms of the Applicable\n    License. This Section 4(b) applies to the Adaptation as\n    incorporated in a Collection, but this does not require the\n    Collection apart from the Adaptation itself to be made subject to\n    the terms of the Applicable License.\n\n    If You Distribute, or Publicly Perform the Work or any Adaptations\n    or Collections, You must, unless a request has been made pursuant\n    to Section 4(a), keep intact all copyright notices for the Work\n    and provide, reasonable to the medium or means You are utilizing:\n    (i) the name of the Original Author (or pseudonym, if applicable)\n    if supplied, and/or if the Original Author and/or Licensor\n    designate another party or parties (e.g., a sponsor institute,\n    publishing entity, journal) for attribution (\"Attribution\n    Parties\") in Licensor's copyright notice, terms of service or by\n    other reasonable means, the name of such party or parties; (ii)\n    the title of the Work if supplied; (iii) to the extent reasonably\n    practicable, the URI, if any, that Licensor specifies to be\n    associated with the Work, unless such URI does not refer to the\n    copyright notice or licensing information for the Work; and (iv) ,\n    consistent with Ssection 3(b), in the case of an Adaptation, a\n    credit identifying the use of the Work in the Adaptation (e.g.,\n    \"French translation of the Work by Original Author,\" or\n    \"Screenplay based on original Work by Original Author\"). The\n    credit required by this Section 4(c) may be implemented in any\n    reasonable manner; provided, however, that in the case of a\n    Adaptation or Collection, at a minimum such credit will appear, if\n    a credit for all contributing authors of the Adaptation or\n    Collection appears, then as part of these credits and in a manner\n    at least as prominent as the credits for the other contributing\n    authors. For the avoidance of doubt, You may only use the credit\n    required by this Section for the purpose of attribution in the\n    manner set out above and, by exercising Your rights under this\n    License, You may not implicitly or explicitly assert or imply any\n    connection with, sponsorship or endorsement by the Original\n    Author, Licensor and/or Attribution Parties, as appropriate, of\n    You or Your use of the Work, without the separate, express prior\n    written permission of the Original Author, Licensor and/or\n    Attribution Parties.\n\n    Except as otherwise agreed in writing by the Licensor or as may be\n    otherwise permitted by applicable law, if You Reproduce,\n    Distribute or Publicly Perform the Work either by itself or as\n    part of any Adaptations or Collections, You must not distort,\n    mutilate, modify or take other derogatory action in relation to\n    the Work which would be prejudicial to the Original Author's honor\n    or reputation. Licensor agrees that in those jurisdictions\n    (e.g. Japan), in which any exercise of the right granted in\n    Section 3(b) of this License (the right to make Adaptations) would\n    be deemed to be a distortion, mutilation, modification or other\n    derogatory action prejudicial to the Original Author's honor and\n    reputation, the Licensor will waive or not assert, as appropriate,\n    this Section, to the fullest extent permitted by the applicable\n    national law, to enable You to reasonably exercise Your right\n    under Section 3(b) of this License (right to make Adaptations) but\n    not otherwise.\n\n5. Representations, Warranties and Disclaimer\n\nUNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING,\nLICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR\nWARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED,\nSTATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF\nTITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE,\nNONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY,\nOR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT\nDISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED\nWARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.\n\n6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY\nAPPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY\nLEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR\nEXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK,\nEVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n7. Termination\n\n    This License and the rights granted hereunder will terminate\n    automatically upon any breach by You of the terms of this\n    License. Individuals or entities who have received Adaptations or\n    Collections from You under this License, however, will not have\n    their licenses terminated provided such individuals or entities\n    remain in full compliance with those licenses. Sections 1, 2, 5,\n    6, 7, and 8 will survive any termination of this License.\n\n    Subject to the above terms and conditions, the license granted\n    here is perpetual (for the duration of the applicable copyright in\n    the Work). Notwithstanding the above, Licensor reserves the right\n    to release the Work under different license terms or to stop\n    distributing the Work at any time; provided, however that any such\n    election will not serve to withdraw this License (or any other\n    license that has been, or is required to be, granted under the\n    terms of this License), and this License will continue in full\n    force and effect unless terminated as stated above.\n\n8. Miscellaneous\n\n    Each time You Distribute or Publicly Perform the Work or a\n    Collection, the Licensor offers to the recipient a license to the\n    Work on the same terms and conditions as the license granted to\n    You under this License.\n\n    Each time You Distribute or Publicly Perform an Adaptation,\n    Licensor offers to the recipient a license to the original Work on\n    the same terms and conditions as the license granted to You under\n    this License.\n\n    If any provision of this License is invalid or unenforceable under\n    applicable law, it shall not affect the validity or enforceability\n    of the remainder of the terms of this License, and without further\n    action by the parties to this agreement, such provision shall be\n    reformed to the minimum extent necessary to make such provision\n    valid and enforceable.\n\n    No term or provision of this License shall be deemed waived and no\n    breach consented to unless such waiver or consent shall be in\n    writing and signed by the party to be charged with such waiver or\n    consent.\n\n    This License constitutes the entire agreement between the parties\n    with respect to the Work licensed here. There are no\n    understandings, agreements or representations with respect to the\n    Work not specified here. Licensor shall not be bound by any\n    additional provisions that may appear in any communication from\n    You. This License may not be modified without the mutual written\n    agreement of the Licensor and You.\n\n    The rights granted under, and the subject matter referenced, in\n    this License were drafted utilizing the terminology of the Berne\n    Convention for the Protection of Literary and Artistic Works (as\n    amended on September 28, 1979), the Rome Convention of 1961, the\n    WIPO Copyright Treaty of 1996, the WIPO Performances and\n    Phonograms Treaty of 1996 and the Universal Copyright Convention\n    (as revised on July 24, 1971). These rights and subject matter\n    take effect in the relevant jurisdiction in which the License\n    terms are sought to be enforced according to the corresponding\n    provisions of the implementation of those treaty provisions in the\n    applicable national law. If the standard suite of rights granted\n    under applicable copyright law includes additional rights not\n    granted under this License, such additional rights are deemed to\n    be included in the License; this License is not intended to\n    restrict the license of any rights under applicable law.\n"
  },
  {
    "path": "NEWS.md",
    "content": "# Leiningen News -- history of user-visible changes\n\n## 2.12.0 / 2025-09-12\n\nThis will be the last release of Leiningen that is still mirrored on\nGithub; future releases will be Codeberg-only.\n\n* Use `:managed-dependencies` instead of `:exclusions` for version ranges. (Phil Hagelberg)\n* Add `:plugin-tree-data` subcommand to deps task. (Gabriel Giussi)\n* Fix a bug in `:active-profiles` in middleware plugins. (Rob Browning)\n* Update to nREPL 1.3.0 (oyakushev)\n* Update Clojure version (Justin Polchlopek)\n\n## 2.11.2 / 2024-02-13\n\n* Add `:preserve-eval-meta` setting to avoid project code reflection. (Marco Biscaro)\n* Fix a bug where metadata on project code caused plugin incompatibilities. (Marco Biscaro)\n\n## 2.11.1 / 2024-01-28\n\n* Fix a bug when deploying using passwords read from the console. (Phil Hagelberg)\n\n## 2.11.0 / 2024-01-27\n\n* Top-level `:exclusions` can now affect top-level `:dependencies`. (Juan Monetta)\n* Fix a bug where `:eval-in :nrepl` couldn't detect running repl. (Phil Hagelberg)\n* Fix a bug where `:eval-in :nrepl` would crash. (Marco Biscaro)\n* Fix a bug where files on test path could be visible during jar. (Phil Hagelberg)\n* Fix an issue with `check` in namespaces that rely on AOT. (Phil Hagelberg)\n* Fix a redundant confusing dependencies warning. (Phil Hagelberg)\n* Add `static-classpath` task for static analysis. (Phil Hagelberg)\n* Major performance improvements handling pathological dependency trees. (Marco Biscaro)\n* Improve error reporting for search failures. (rome user)\n* Support XDG config directories. (Phil Hagelberg)\n* Use `$XDG_CACHE_HOME` for self-installs if it exists. (Phil Hagelberg)\n* Add warnings for buggy composite profiles. (Phil Hagelberg)\n\n## 2.10.0 / 2022-12-09\n\n* Update to nREPL 1.0.0 (Phil Hagelberg)\n* Fix a bug where `:eval-in :leiningen` could suppress test exit code. (Phil Hagelberg)\n* Add the ability to sign deployed files using SSH keys, not just GPG. (Phil Hagelberg)\n* Fix a bug where uberjar splices profiles into target path incorrectly. (Phil Hagelberg)\n\n## 2.9.10 / 2022-08-09\n\n* Fix a bug where dev-resources could leak into jars/uberjars. (Phil Hagelberg)\n* Avoid illegal reflective access doing XML parsing in uberjar/search. (Phil Hagelberg)\n\n## 2.9.9 / 2022-08-05\n\n* Migrate the repository from Github to Codeberg. (Phil Hagelberg)\n* Fix a bug in `new` where template group-ids could be ignored. (Phil Hagelberg)\n* Work around a change in Java 9 which broke template listing. (Phil Hagelberg)\n* Fix a bug in pedantic checks which resulted in infinite loops. (Phil Hagelberg)\n* Prevent `module-info.class` files from being included in uberjars. (Phil Hagelberg)\n* Prevent duplicate warnings in `resource-paths` when creating jars. (Phil Hagelberg)\n* Fix an issue with `check` where AOT would shadow reflection warnings. (Phil Hagelberg)\n* Allow `change` to edit dependency versions. (Eric Schoen)\n* Fix a bug where composite profiles would leak dependencies downstream. (Phil Hagelberg)\n* Allow `repl` to bind to filesystem sockets via `:headless :socket PATH` (Rob Browning)\n\n## 2.9.8 / 2021-11-11\n\n* Fix a bug where certain deep dependency trees would overflow stack. (Phil Hagelberg)\n* Allow `LEIN_JAR` to be overridden if you install elsewhere. (Ahmed Sajid)\n\n## 2.9.7 / 2021-09-15\n\n* Detect certain pathological dependency trees and warn. (Phil Hagelberg)\n* Bump to Clojure 1.10.3. (Grzegorz Smajdor)\n* Don't warn on version ranges which point to a single version. (Pierre-Yves Ritschard)\n* Fix a bug where verifying deps could loop forever. (James Carnegie)\n* Get better error messages when deploys fail. (Toby Crawley)\n\n## 2.9.6 / 2021-04-15\n\n* Look for templates in a way that reflects new Clojars group rules. (Phil Hagelberg)\n* Update template-generating template to reflect new Clojars rules. (Phil Hagelberg)\n* Don't `:reload` in tests unless connecting to an nrepl. (Ambrose Bonnaire-Sergeant)\n\n## 2.9.5 / 2020-12-07\n\n* Several dependency version bumps. (Bozhidar Batsov, Utkarsh Gupta, Chris Thunes)\n\n## 2.9.4 / 2020-07-08\n\n* Fix a bug where dependency conflict resolution errors were wrong. (Phil Hagelberg)\n* Make test selectors skip non-test vars. (Mourjo Sen)\n* Fix a bug where `deps :query` would report incorrect results. (Chris Thunes)\n* Update nREPL to 0.7. (Bozhidar Batsov)\n* Add scheme configuration support to REPL-y and use configured transport when starting the ack-server. (Paulo Feodrippe, Bozhidar Batsov)\n\n## 2.9.3 / 2020-03-16\n\n* Fix a bug where deploying would fail to send signature checksums. (Antonin Hildebrand)\n* Memoize application of project middleware. (Chris Thunes)\n* Fix a bug where checksum verification failed on non-GNU systems. (Antonio Hernández Blas)\n\n## 2.9.2 / 2020-02-28\n\n* Bump to Clojure 1.10.1. (Phil Hagelberg)\n* Fix a bug where disabling implicit middleware disabled explicit ones. (radhika reddy)\n* Add checksum check during self-install process. (Toyam Cox)\n* Include repository auth when verifying dependencies. (David Bürgin)\n* Fix bugs in certain kinds of profile merging. (David Bürgin)\n* Include `:repositories` from `project.clj` in `pom.xml` file. (David Bürgin)\n\n## 2.9.1 / 2019-02-26\n\n* Fix a bug where provided namespace compilation order was overridden. (Phil Hagelberg)\n* Don't emit namespaced maps when merging data readers for uberjar. (Joel Kaasinen)\n\n## 2.9.0 / 2019-02-10\n\n* Re-enable bootclasspath optimization by default. (Phil Hagelberg)\n* Sort namespace order consistently during AOT. (Logan Girard)\n* Use Clojure 1.10.0 for plugins and new templates projects. (Alex Miller, Phil Hagelberg)\n* Update nREPL to 0.6. (Bozhidar Batsov)\n\n## 2.8.3 / 2018-12-14\n\n* Fix a warning in the powershell script. (Florian Anderiasch)\n* Fix a bug where the repl wouldn't launch. (Bozhidar Batsov)\n* Remove broken unattended GPG deploy feature.\n* Fix a bug where the repl didn't use `:main` as the initial ns. (Phil Hagelberg)\n\n## 2.8.2 / 2018-12-11\n\n* Fix a bug where hidden files would be included in jars. (James Elliott)\n* Add support for repository-overrides.clj to bootstrap repository info. (Greg Haskins)\n* Use stderr consistently for diagnostics. (Rob Browning)\n* Fix a bug in aliases that come from profiles. (Arnout Roemers)\n* Fix TLS errors in self-install on Windows. (Florian Anderiasch)\n* Templates use EPL-2.0 with GPL secondary license. (Yegor Timoshenko)\n* Allow GPG to be invoked unattended with passphrase. (Neil Okamoto)\n* Add pprint `--not-pretty` argument that prints instead of pprinting. (Rob Browning)\n* Always send diagnostic messages to standard error. (Rob Browning)\n* Add project coordinate data to jar metadata. (Conor McDermottroe)\n* Allow freeform `:pom-plugin` configuration. (Hannu Hartikainen)\n* **(Breaking)** Switch to [nREPL 0.5](https://metaredux.com/posts/2018/10/29/nrepl-redux.html). See the [upgrade notes](https://nrepl.org/nrepl/installation.html#upgrading) if you experience any problems with the `lein repl` task. (Bozhidar Batsov)\n\n## 2.8.1 / 2017-10-27\n\n* Fix a bug where `lein help` couldn't list built-in tasks on Java 9. (Phil Hagelberg)\n* Fix a bug where `lein` installed from package managers would obscure exit code. (Phil Hagelberg)\n* Fix an errant reflection warning on Java 9. (Toby Crawley)\n* Fix an error when no `:plugins` are specified. (Phil Hagelberg)\n* Fix a bug where launching project subprocesses would encounter unreadable forms. (Phil Hagelberg)\n* Remove auto-setting of cgroups memory limit. (Florian Anderiasch)\n\n## 2.8.0 / 2017-10-17\n\n* Support `LEIN_USE_BOOTCLASSPATH` for users on Java 8. (Phil Hagelberg)\n* Disable bytecode verification in Leiningen's own JVM for Java 9 compatibility. (Ghadi Shayban)\n* Infer values for pom `<scm>` tag from `.git` directory. (Nicolas Berger)\n\n## 2.8.0-RC1 / 2017-09-18\n\n* Project middleware, hooks, and the `:test` profile are considered deprecated. (Phil Hagelberg)\n* Help output no longer includes TOC output. (Irina Renteria)\n* The `vcs` task allows the commit message to be customized. (Toby Crawley)\n* JVMs on 8u131 and newer will default to using cgroups settings for memory limits. (Phil Hagelberg)\n* Add `:query` subcommand to `deps` to quickly find latest versions. (Phil Hagelberg)\n* Fix a bug where dependency resolution wasn't cached correctly. (Phil Hagelberg)\n* Support for HTTP nREPL has been moved out; requires drawbridge plugin now. (Phil Hagelberg)\n* Warn when `$CLASSPATH` is set. (Phil Hagelberg)\n* Default to requiring TLS for remote repositories. (Phil Hagelberg)\n* Remove warning when running as root. (Phil Hagelberg)\n* Add `:why` subtask to `deps` for tracing individual deps. (Phil Hagelberg)\n* Remove clj-http and cheshire dependencies, reducing likelihood of conflict. (Phil Hagelberg)\n* Warn when plugin dependencies conflict with Leiningen's own. (Phil Hagelberg)\n* Fix a bug where repls outside a project were not run in Leiningen's own process. (Phil Hagelberg)\n* Add `:plugin-tree` and `:tree-data` subtasks to `deps`. (Ken Restivo)\n* Support skipping bootclasspath for Java 9 compatibility. (Phil Hagelberg)\n* Allow `vcs` task to skip signing tags. (Nicolas Berger)\n* The `search` task no longer downloads indices but hits live search APIs. (Phil Hagelberg)\n* Remove duplicate exclusions in `lein deps`. (Emlyn Corrin)\n* Leiningen is now installable again via chocolatey. (Florian Anderiasch)\n* Dependency names can be specified as strings in addition to symbols. (Wes Morgan)\n\n## 2.7.1 / 2016-09-22\n\n* Add support for SDKMAN! as installation alternative. (Jean Niklas L'orange)\n* Improved explanation in some errors. (Jean Niklas L'orange)\n* Don't require `nil` for version in managed deps. (Chris Price)\n* Fix a bug with snapshot dependencies for managed deps. (Chris Price)\n\n## 2.7.0 / 2016-08-24\n\n* Add PowerShell script for Windows users. (Brian Lalonde)\n* Run `:prep-tasks` before `lein test`, so generated test namespaces will be tested. (Martin Reck)\n* Better error message when attempting to do `lein run` without `project.clj`. (Eduardo Seabra Silva)\n* Add support for `:managed-dependencies`. (Chris Price)\n* Provide the current clojars certificate. (Toby Crawley)\n* Add `*eval-print-dup*` to evaluate forms passed to `eval-in-leiningen` with `*print-dup*`. (Eduardo Seabra Silva)\n* Update bash completions. (Zack Dever)\n* Respect `:scm :dir` in `lein vcs` commands. (Ian Kerins)\n* Improve whitespace handling from `JVM_OPTS`. (Stephen Nelson)\n* Catch and handle fixture errors during `lein test`. (Alex Hall)\n* Fix a bug where spaces in directory names on Windows caused crashes. (Leon Mergen, Tobias Kiertscher, Jean Niklas L'orange)\n* Fix a bug where `lein search` would take forever downloading clojars.org. (Paul Dorman)\n* Retain user defined private repositories when building jars, uberjars and deploy. (Rick Moynihan)\n* Honor whitelist settings when `lein javac` is called via `lein jar`. (Chris Price)\n* `lein vsc push` for git will now only push branch-related tags. (Łukasz Klich)\n\n## 2.6.1 / 2016-02-08\n\n* Fix a bug where some plugins crashed when used. (Jean Niklas L'orange)\n\n## 2.6.0 / 2016-02-05\n\n* The templates, repl and Leiningen itself now use Clojure 1.8.\n* Support for Clojure 1.1.0 and older is now dropped.\n* Warn if possibly stale native dependencies end up in `:native-path`. (Jean Niklas L'orange)\n* Speed up restarts after `:dependency` changes. (Jean Niklas L'orange)\n* `lein release` now supports SNAPSHOT on qualifiers. (Chris Price)\n* Synchronise `lein-pkg` and `lein` scripts. (Thu Trang Pham)\n* Decrease timeout for the Clojure compiler agent thread pool. (Ryan Fowler)\n* Fix a bug where implicit resource directories were created by default. (Jean Niklas L'orange)\n* Avoid optimizing away stack traces by default. (solicode)\n* Fix a bug where duplicate profiles were merged when profile merging. (Jean Niklas L'orange)\n* Improved GPG artifact signing feedback. (Jean Niklas L'orange, Andrea Richiardi)\n* Add function to support binary files with `lein-new`. (Sergiy Bondaryev)\n* Show better error message when java is not found on the path. (Pavel Prokopenko, Jürgen Hötzel)\n* Fix a bug with non-GitHub SCM urls in pom files. (Ralf Schmitt)\n* Don't send aot warning if `:aot` contains regex matching the main namespace. (Emlyn Corrin)\n\n## 2.5.3 / 2015-09-21\n\n* Add CHANGELOG.md to default lein templates. (Daniel Compton)\n* `lein vcs tag` now supports the `--no-sign` flag. (Daniel Compton)\n* Fix a bug where javac errors were not printed to terminal. (Brandon Shimanek)\n* Fix a bug where environment variables were not propagated down to GPG. (Brandon Shimanek)\n* `lein retest` now saves information on which tests that fail. (Shalaka Patil)\n* `lein release` now honors exit codes from `git` and throws if non-0 occurs. (Tim Visher)\n\n## 2.5.2 / 2015-08-09\n\n* Allow repl dependencies to be specified in default user profiles. (Jean Niklas L'orange)\n* Fix a bug where transitive dependencies on tools.nrepl failed. (Jean Niklas L'orange)\n* Fix a bug preventing custom certificates to work. (Jean Niklas L'orange)\n* Add support for reader conditional files. (Stephen Nelson)\n* Add `--template-version` flag to `lein new`. (Ohta Shogo)\n* Bail immediately if snapshot dependencies are discovered during uberjaring. (Justin Smith)\n* Use powershell by default in `lein.bat`. (Frederick Giasson, Florian Anderiasch)\n* Fix bug where manifest files could contain duplicate entries. (Michael Blume)\n* Allow template designers to use a custom rendering function. (Dmitri Sotnikov)\n* Fix a bug where `:uberjar-name` wasn't used when inside the `:uberjar` profile. (Kyle Harrington)\n\n## 2.5.1 / 2015-01-09\n\n* No longer skip certificate checking when upgrading on Windows. (Phil Hagelberg)\n* Fix password prompt for Cygwin users. (Carsten Behring)\n* Fix a bug where `lein pom` did not add the project's SCM URL to pom.xml. (Fredrick Giasson)\n* `lein clean` now cleans up all profile targets. (Jeb Beich, Jim Crossley)\n* The order included profiles are merged in is now retained. (Jim Crossley)\n* Fix a bug preventing `update-in` to use functions not yet required. (Phil Hagelberg)\n* Allow multiple `:repl` profiles. (Hugo Duncan)\n* Fix an infinite recursion bug with aliases and `with-profile`. (Hugo Duncan)\n* Add flexibility in jar manifest declarations. (Fabio Tudone)\n* Fix a bug preventing extra profiles from being included in jars. (Hugo Duncan)\n* Fix a bug in self-install on Windows. (Sindunata Sudarmaji)\n\n## 2.5.0 / 2014-09-14\n\n* Allow certain profiles to be `^:leaky` and affect downstream. (Hugo Duncan)\n* Allow profiles to be loaded out of plugins. (Phil Hagelberg, Hugo Duncan)\n* Make `leiningen.core.project/read` init the project and merge default profiles. (Phil Hagelberg)\n* Move auto-clean to jar task for consistency. (Phil Hagelberg)\n* Make compilation messages honor `$LEIN_SILENT` (Jean Niklas L'orange)\n* Fix a bug around EOF in the repl. (Colin Jones)\n* Add `:implicits` subtask to `deps` task. (Phil Hagelberg)\n* Update zsh completion rules. (Joshua Davey)\n* Fix a stack overflow with :pedantic. (Nelson Morris)\n* Fix a bug where repls outside of a project were broken. (Phil Hagelberg)\n\n## 2.4.3 / 2014-08-05\n\n* Allow implicit hooks/middleware to be disabled. (Phil Hagelberg)\n* Print compilation errors as they occur. (Paul Legato)\n* Switch Central repository to using HTTPS. (Manfred Moser)\n* Add `LEIN_NO_USER_PROFILES` to avoid loading user profile. (Hugo Duncan)\n* Fix deploy task to work with signature files. (Phil Hagelberg)\n* Allow vcs tags to be created with a prefix. (Yannick Scherer)\n* Default to warning when version ranges are present. (Phil Hagelberg)\n* Let templates be loaded from `:plugin-repositories`. (Jason Felice)\n\n## 2.4.2 / 2014-06-15\n\n* Fix a bug preventing out-of-project runs. (Phil Hagelberg)\n* Only load Clojars SSL cert on-demand to improve boot time. (Phil Hagelberg)\n\n## 2.4.1 / 2014-06-15\n\n* Don't commit untracked files in `lein vcs commit`. (Phil Hagelberg)\n* Fix a bug where `:mirrors` could not be configured. (Phil Hagelberg)\n* Expose `pom.properties` for access to version number during development. (Phil Hagelberg)\n* Fix a bug preventing the release task from loading. (Phil Hagelberg)\n\n## 2.4.0 / 2014-06-09\n\n* Allow aliases to splice in values from the project map. (Phil Hagelberg)\n* Allow plugins to override built-in tasks. (Phil Hagelberg)\n* Add `release` task for automating common release steps. (Wayne Warren, Chris Truter, Phil Hagelberg)\n* Add `change` task for programmatc `project.clj` manipulation. (Chris Truter, Max Barnash)\n* Abort when `defproject` contains duplicate keys. (Peter Garbers)\n* Add `vcs` task to automate version control. (Phil Hagelberg, Wayne Warren)\n* Automatically `clean` before `deploy` to avoid AOT in libraries. (Phil Hagelberg)\n* Emit warnings to stderr. (Andy Chambers)\n* Use `clojure.main` for uberjars that don't declare their own `:main`. (Phil Hagelberg)\n* Allow templates to load from `:plugin-repositories`. (Phil Hagelberg)\n* Fix a race condition on printing during dependency resolution. (Phil Hagelberg)\n* Allow `new` templates to operate on existing directories with `--force` option. (Matthew Blair)\n* Fix `search` task to allow queries on multiple fields. (Colin Jones)\n* Fix a bug where errors in `run` task were mis-reported. (Gary Fredericks)\n* Report download progress of search indices. (Matthew Blair)\n* Protection from harmful `:clean-targets` settings. (Craig McDaniel)\n* Faster loading of help text. (David Grayson, Ryan Mulligan)\n* Add `LEIN_SILENT` option to suppress `*info*` output. (Phil Hagelberg)\n\n## 2.3.4 / 2013-11-18\n\n* Suggest `:exclusions` to possibly confusing `:pedantic?` dependencies. (Nelson Morris, Phil Hagelberg)\n* Optionally look for snapshot templates in `new` task. (Travis Vachon)\n* Allow task chains to be declared without commas in project.clj. (Jean Niklas L'orange)\n* Support extra configurability in `:pom-plugins`. (Dominik Dziedzic)\n* Fix a bug where implicit :aot warning triggered incorrectly. (Jean Niklas L'orange)\n* Fix a bug where `lein repl connect` ignored port argument. (Toby Crawley)\n\n## 2.3.3 / 2013-10-05\n\n* Add support for `:uberjar-merge-with`. (Marshall Bockrath-Vandegrift)\n* Better error message for `-m` arg in `run` task. (Aleksandar Simic)\n* Support stdin when using `:eval-in :nrepl`. (Phil Hagelberg)\n* Add directory entries to jar files. (Vadim Platonov)\n* Fix a bug where `-main` was hard-coded to initial directory. (Phil Hagelberg)\n\n## 2.3.2 / 2013-08-19\n\n* Write `.nrepl-port` file for better tool interoperability. (Phil Hagelberg)\n* Support targeted upgrades in `lein.bat`. (Shantanu Kumar)\n* Warn when projects rely on implicit AOT of `:main`. (Phil Hagelberg)\n* Fix a bug where implicit AOT of `:main` was disabled. (Phil Hagelberg)\n* Disable profile isolation by default. Will be back in 3.x. (Phil Hagelberg)\n\n## 2.3.1 / 2013-08-13\n\n* Fix self-install bug. (Sam Aaron, Steven Harms)\n* Fix bug with AOT classes not being included in jars. (Phil Hagelberg)\n* Support disabling test task's monkeypatch of `clojure.test`. (Phil Hagelberg)\n* Allow project map to be readable. (Phil Hagelberg)\n\n## 2.3.0 / 2013-08-08\n\n* Add `:eval-in :pprint` for debugging. (Phil Hagelberg)\n* Support cleaning extra dirs with `:clean-targets`. (Yoshinori Kohyama)\n* Test-selectors skip fixtures too, not just running tests. (Gary Fredericks)\n* Place licenses and readmes into jars. (Phil Hagelberg)\n* Include LICENSE as separate file in templates. (Wolodja Wentland)\n* Allow aborting on ambiguous version resolution with `:pedantic`. (Nelson Morris, Phil Hagelberg)\n* Scope `:compile-path` and `:native-path` under profile-specific target dir. (Phil Hagelberg)\n* Fix bug where uberjar filename would include provided profile. (Phil Hagelberg)\n* Deprecate explicit `self-install` command. (Phil Hagelberg)\n* Fix bugs around long lines in jar manifests. (Leon Barrett)\n* Support nested checkout dependencies. (Phil Hagelberg)\n* Fix bugs around `:filespecs`. (Jean Niklas L'orange)\n\n## 2.2.0 / 2013-05-28\n\n* Support setting custom welcome message when repl connects. (Colin Jones)\n* Fix a bug where old template versions were always fetched. (Nelson Morris)\n* Support `:java-agents` for tooling and instrumenting. (Phil Hagelberg)\n* Allow checkout dependencies to operate recursively. (Phil Hagelberg)\n* Introduce `:uberjar` profile. (Phil Hagelberg)\n* Isolate target paths by profiles. (Phil Hagelberg)\n* Support deploying ad-hoc files. (Phil Hagelberg)\n* Set `*command-line-args*` in run task. (Anthony Grimes)\n* Allow templates to specify executable files. (Joe Littlejohn)\n* Remove clojuredocs repl support to reduce dependency conflicts. (Phil Hagelberg)\n\n## 2.1.3 / 2013-04-12\n\n* Fix fast trampoline to work without user profiles. (Malcolm Sparks)\n* Fix a bug where duplicate files in jars would blow up. (Phil Hagelberg)\n* Fix a bug where cyclical dependencies could cause a crash. (Nelson Morris)\n* Allow aliases to have docstrings. (Jean Niklas L'orange)\n* Read credentials from GPG for mirrors. (bdollard)\n* Fix bugs in `update-in` around profiles and more. (Marko Topolnik)\n\n## 2.1.2 / 2013-02-28\n\n* Add new way to specify no-proxy hosts. (Joe Littlejohn)\n* Allow TieredCompilation to be disabled for old JVMs. (Phil Hagelberg)\n* Fix a bug merging keywords in profiles. (Jean Niklas L'orange)\n* Fix a bug where tests wouldn't run under with-profiles. (Phil Hagelberg)\n* Support for calling set! on arbitrary vars on startup. (Gary Verhaegen)\n* Allow update-in to work on top-level keys. (Marko Topolnik)\n* Fix a bug breaking certain templates. (Colin Jones)\n* Fix a bug where trampolined repl would hang. (Marko Topolnik)\n\n## 2.1.1 / 2013-03-21\n\n* Add `:test-paths` to directories shared by checkout deps. (Phil Hagelberg)\n* Allow `run` task to function outside projects. (Phil Hagelberg)\n* Fix a bug preventing `with-profiles` working outside projects. (Colin Jones)\n* Fix a bug in trampolined `repl`. (Colin Jones)\n* Fix a bug in `update-in` task causing stack overflow. (David Powell)\n* Fix a bug in `lein upgrade`. (Phil Hagelberg)\n\n## 2.1.0 / 2013-03-19\n\n* Compile task accepts regexes as command-line args. (Joshua P. Tilles)\n* Allow key to be specified to use when signing artifacts. (Tim McCormack)\n* Added GPG introductory guide. (Toby Crawley)\n* Many bug fixes in batch file launcher. (David Powell)\n* Self install via lein.bat no longer requires curl/wget. (slahn)\n* Allow stdin of project processes to be closed. (Jean Niklas L'orange)\n* Better behaviour when GPG or keys are missing. (Toby Crawley)\n* Support customizing key-managers for SSL. (Stephen Nelson)\n* Add update-in task for arbitrary project map changes. (Phil Hagelberg)\n* Warn when version ranges are detected. (Nelson Morris)\n* Add support for msys on Windows machines. (megri)\n* Allow use of :mirrors when building jars/uberjars. (Tim McCormack)\n* Dependencies may include native components more flexibly. (Marc Liberatore)\n* Implement system-level profiles. (Phil Hagelberg)\n* Accept repo credentials on the CLI for deploy. (Max Prokopiev)\n* Fix a bug breaking recursive aliases. (Hugo Duncan)\n* Add support for preventing deployment of branches. (Anthony Grimes)\n* Improve boot time by limiting tiered compilation in dev. (Phil Hagelberg)\n* Allow building jars with classifiers. (Hugo Duncan)\n* Allow :init-ns to be honored by other nrepl clients. (Marko Topolnik)\n* Add experimental support for :eval-in :nrepl. (Phil Hagelberg)\n* Don't follow symlinks in clean task. (Jean Niklas L'orange)\n* Add support for ~/.lein/profiles.d. (Jean Niklas L'orange)\n* Allow ctrl-c to interrupt repl input (Colin Jones)\n* Allow `lein test` to take files as arguments (Gabriel Horner)\n\n## 2.0.0 / 2013-01-19\n\n* Allow implicit repl profiles to be overridden.\n* Accept `:main` as an alias for `-m` in `run` task.\n* Reader fixes for `repl`. (Colin Jones, Chas Emerick)\n* Fix bug around stdin for subprocesses that have stopped. (Jean Niklas L'orange)\n* Warn when `:user` profile is found in `project.clj`. (Michael Grubb)\n* Treat `:user` profile as project map outside of project. (Jean Niklas L'orange)\n\n## 2.0.0-RC2 / 2013-01-12\n\n* Fix bug where newnew wouldn't be loaded from outside a project.\n* Fix Windows bug in project generation.\n* Fix `lein upgrade` bug.\n\n## 2.0.0-RC1 / 2013-01-10\n\n* Fix some reader bugs in repl task. (Colin Jones)\n* Fix a bug where Leiningen's deps could affect javac. (Jean Niklas L'orange)\n* Test selectors may allow entire namespaces to be skipped. (Anthony Grimes)\n* Allow project's git repo to be different than project root. (David Greenberg)\n* Don't AOT the `:main` namespace outside of jar/uberjar task.\n* Allow hooks from profiles to apply with limited scope. (Hugo Duncan)\n* Fix a bug where profile-specific paths were ignored in trampoline.\n* Support reading from stdin inside project process.\n* Add `:only` test selector. (Anthony Grimes)\n* Support partial application for test selectors. (Anthony Grimes)\n* Un-deprecate `:auth` profile for full-disk-encryption users.\n* Add documentation for mixed-source projects. (Michael Klishin)\n* Make later profiles take precedence in with-profile task. (Justin Balthrop)\n* Improve help for subtasks. (Tobias Crawley)\n* Allow vectors to specify multiple credential sources. (Chas Emerick)\n* Look up credentials in environment using namespaced keywords. (Chas Emerick)\n* Support overriding repl profile from project.clj or profiles.clj.\n* Allow test selectors to operate on namespace. (Jim Crossley)\n* Honor environment variables in project.clj. (Justin Balthrop)\n* Allow searching over fields other than artifact id. (Michael Klishin)\n* Honor per-project REPL history. (Michael Klishin, Colin Jones)\n* Reduce output during dependency resolution. (Nelson Morris)\n* Fix search task outside project. (Bruce Adams)\n\n## 2.0.0-preview10 / 2012-08-25\n\n* Fix a bug where repositories wouldn't be checked running outside a project.\n* Make repl listen on 127.0.0.1 instead of localhost to address IPv6 issues.\n\n## 2.0.0-preview9 / 2012-08-24\n\n* Use provided profile by default everywhere except uberjar. (Marshall Vandegrift)\n* Unify format for auto-loading middleware and hooks. (Justin Balthrop)\n* Allow more declarative :nrepl-middleware settings. (Chas Emerick)\n* Fix `:eval-in :classloader` for native dependencies. (Justin Balthrop)\n* Support project and user leinrc file for shell-level customization. (Justin Balthrop)\n* Cache trampoline commands for fast boot. Set `$LEIN_FAST_TRAMPOLINE` to enable.\n* Support setting HTTPS proxies.\n* Improved resilience when self-install is interrupted. (Bruce Adams)\n* Fix a bug where profile dependencies weren't honored in trampoline task.\n\n## 2.0.0-preview8 / 2012-08-16\n\n* Place SCM revision in pom.properties in jar files.\n* Allow middleware and hooks to be inferred from plugins. (Justin Balthrop)\n* Offer similar suggestions when no task is found for input. (Joe Gallo)\n* Support `TERM=dumb` in repl task. (Colin Jones)\n* Fix reader mismatches between repl client and server. (Colin Jones)\n* Use new search index format, support incremental updates. (Christoph Seibert)\n* Accept nREPL handlers and middleware from project config.\n* Support emitting arbitrary elements in pom.xml. (Esa Laine)\n* Fix a bug where repl task was binding to 0.0.0.0.\n* Honor `$http_no_proxy` host settings. (Jon Pither)\n* Profiles can be specified as compositions of other profiles. (Justin Balthrop)\n* Allow for `:prep-tasks` with arguments. (Anthony Marcar)\n* Check for \"help\" after task name. (Bruce Adams)\n* Read dependency transport wagons from plugins.\n* Allow successive eval-in-project calls with trampoline.\n* Bring back selective post-compile cleaning. (Arlen Cuss)\n* Fix memory leak in repl task.\n\n## 2.0.0-preview7 / 2012-06-27\n\n* Fix a bug where failed javac wouldn't abort. (Michael Klishin)\n* Check task aliases everywhere tasks are invoked.\n* Sign jars and poms of releases upon deploy by default.\n* Don't decrypt `credentials.clj.gpg` for every request.\n* Support setting `:mirrors` in project.clj. (Chas Emerick, Nelson Morris)\n* Allow aliases shadowing task names to invoke shadowed tasks.\n* Emit `doc/intro.md` in new project templates.\n* Allow `:scm` to be set in project.clj for pom inclusion. (Florian Anderiasch)\n* Fix a bug where dependency `:classifier` and `:extension` would be ignored.\n* Speed up subprocess launches when `:bootclasspath` is set.\n* Set user agent for HTTP requests. (Bruce Adams)\n* Verify signatures of dependencies with `lein deps :verify`.\n* Move task chaining to `do` task in order to allow for higher-order use.\n\n## 2.0.0-preview6 / 2012-06-01\n\n* Allow lookup of `:repositories` credentials from environment variables.\n* Perform more SSL certificate validity checks.\n* Fix a bug where repl dependency was conflicting.\n* Add certificate for Clojars to default project settings.\n* Allow custom SSL `:certificates` to be specified for repositories.\n\n## 2.0.0-preview5 / 2012-05-31\n\n* Fix a repl bug where namespaced keywords weren't read right. (Colin Jones)\n* Prompt for credentials upon deploy when none are configured.\n* Support encrypted deploy credentials using GPG.\n* Warn about missing metadata when deploying.\n* Default to refusing downloaded jars when checksums don't match.\n* Apply middleware before calculating profiles so they work in with-profile.\n* Allow reply dependency to be upgraded independently of Leiningen.\n* Don't write \"stale\" directory when running outside a project.\n* Proxy settings are passed on to project subprocesses. (Craig McDaniel)\n* Revamp tutorial, spin off profiles guide and faq.\n* Fix bug that would cause repl task to hang. (Colin Jones)\n\n## 2.0.0-preview4 / 2012-05-11\n\n* Checkout dependencies are not applied with production profile.\n* Move pom.xml back to the project root.\n* Add -U alias for forcing updates of snapshots.\n* Support setting :update and :checksum profiles at top level of project.\n* Blink matching parens in repl. (Colin Jones)\n* Fix a bug where repl would interfere with project agents. (Chas Emerick)\n* Show repl output that is emitted after return value. (Colin Jones)\n* Make it easier for plugins to undo profile merging. (David Santiago)\n* Add -o alias for activating offline profile.\n* Ignore $CLASSPATH environment variable.\n* Fix bug where repl task couldn't be trampolined. (Colin Jones)\n* Allow jar manifest entries to be dynamically calculated.\n* Support map-style :javac-opts like Leiningen 1.x used. (Michael Klishin)\n* Allow group-id to be specified when creating new projects. (Michael Klishin)\n* Fix a bug where :dev dependencies would be exposed in pom.\n* Use Clojure 1.4.0 internally; plugins have access to new Clojure features.\n\n## 2.0.0-preview3 / 2012-04-12\n\n* Add HTTP nREPL support for repl task via :connect option. (Chas Emerick,\n  Phil Hagelberg)\n* Improve repl startup time, output consistency, Windows support. (Lee Hinman,\n  Colin Jones)\n* Stop using numeric exit codes for task failures.\n* Dynamically resolve unknown templates in new task.\n* Automatically activate offline profile when needed.\n* Honor $http_proxy environment variable. (Juergen Hoetzel)\n* Allow arbitrary :filespecs to be included in jars.\n* Let custom :prep-tasks be specified in project.clj.\n* Include :java-source-paths and dev/test deps in pom. (Nelson Morris)\n* Add offline profile.\n* Prevent project JVMs from outlasting Leiningen's process. (Colin Jones)\n* Update lein.bat to work with version 2. (Andrew Kondratovich)\n* Show a dependency tree in deps task. (Chas Emerick, Nelson Morris)\n* Support connecting to nrepl server in repl task. (Chas Emerick, Colin Jones)\n* Pretty-print pom.xml. (Nelson Morris)\n* Display task aliases in help task. (Michael S. Klishin)\n* Only compile stale java source files. (Stephen C. Gilardi)\n* Respect :java-cmd in project.clj. (Michael S. Klishin)\n* Show progress when downloading search indices. (Justin Kramer)\n\n## 2.0.0-preview2 / 2012-03-08\n\n* Honor :default and :user profiles when running outside a project.\n* Fix a bug where subtask help wasn't showing.\n\n## 2.0.0-preview1 / 2012-03-07\n\n* Split out leiningen-core into independent library.\n* Construct classpath out of ~/.m2 instead of copying jars to lib/.\n* Replace maven-ant-tasks with Pomegranate library. (Chas Emerick,\n  Nelson Morris)\n* Move build artifacts to target/ directory.\n* Add experimental support for running project code in-process with\n  :eval-in :classloader. (Justin Balthrop)\n* Support profiles for alternate project configurations.\n* Switch to using plural :source-paths, :test-paths, and :resource-paths.\n* Complete rewrite of repl task. (Colin Jones, Chas Emerick, Anthony Grimes)\n* Remove special case of implicit org.clojure group-id in :dependencies.\n* Replace :dev-dependencies with :dev profile.\n* Support customized :source-paths with :eval-in :leiningen projects.\n* Rewrite pom task. (Nelson Morris, Alan Malloy)\n* Allow tasks and projects to add custom :injections into project code.\n* Support changing :prep-tasks for running tasks other than javac and\n  compile before eval-in-project calls.\n* Rewrite new task. (Anthony Grimes)\n* New check task for catching reflection and other issues. (David Santiago)\n* Check project.clj for :aliases.\n* Allow partial application of aliases.\n* Drop :extra-classpath-dirs option.\n* Load :plugins without trampolining the process.\n* Remove plugin task in favour of :user profile.\n* Allow :repository-auth to be specified using a regular expression.\n* Support arbitrary project map transformation functions via :middleware.\n* Support changing :local-repo path in project.clj.\n\n## 1.7.1 / 2012-03-27\n\n* Fix a bug where the repl task left JVM processes running.\n* Make upgrade task accept arbitrary versions.\n* Fix a bug where javac classes would get removed before AOT compilation.\n* Allow :aot to contain both symbols and regexes. (Dan Lidral-Porter)\n* Fix bug where clean task would be incredibly slow.\n* Apply :jvm-opts with :eval-in-leiningen.\n* Prevent misbehaving plugins from pulling in conflicting Clojure versions.\n\n## 1.7.0 / 2012-02-06\n\n* Allow any task to perform trampolining.\n* Fix a bug where JVM_OPTS with spaces would cause failures.\n* Keep pom dependencies off the classpath.\n* Block plugins from erroneously including their own Clojure version.\n* Allow poms to set parent element. (Nelson Morris)\n* Support emitting Maven extensions in pom. (Max Penet)\n* Allow faster booting on 64-bit JVMs with tiered compilation.\n* Fix a bug where shell wrappers had the wrong classpath. (Tavis Rudd)\n* Exclude all signature files from uberjars. (Tim McCormack)\n* Allow test selectors to apply to entire namespaces. (Kevin Downey)\n* Use LEIN_JAVA_CMD to allow different JVM for Leiningen itself. (Tavis Rudd)\n* Honor :plugins key inside project.clj.\n* Accept :repl-init namespace as argument to repl task.\n* Allow :java-source-path to be nested inside :source-path. (Anthony Grimes)\n* Fix a bug where native deps weren't made available. (Anthony Grimes)\n\n## 1.6.2 / 2011-11-11\n\n* Let run task work with main functions from Java classes.\n* Fix bug where exceptions would break interactive task.\n* Default to Clojure 1.3.0 for new projects.\n* Allow Leiningen home to exist inside project directory. (Heinz N. Gies)\n* Remove old versions of plugins when upgrading.\n* Add user-level :deploy-repositories list. (Michał Marczyk)\n* Fix a bug where class files from proxy objects weren't considered\n  part of the project. (Stephen Compall)\n* Make deps cause implicit clean to avoid AOT version mismatches.\n* Include Java source files in jar. (Nathan Marz)\n* Add separate :deploy-repositories list. (Chas Emerick)\n* Maintain order in repositories list. (Colin Jones)\n* Fix a bug where :omit-default-repos wouldn't skip Maven Central. (Chas Emerick)\n* Make deps extract native dependencies for all architectures, not just current.\n* Fix page count on search results.\n* Fix a bug where \"lein plugin install\" could skip dependencies.\n* Reimplement eval-in-project to use clojure.java.shell instead of Ant.\n* Separate LEIN\\_JVM\\_OPTS from JVM_OPTS.\n\n## 1.6.1.1 / 2011-09-06\n\n* Turn off workaround for Clojure's agent thread pool keeping the JVM alive\n  by default. Use :shutdown-agents in project.clj to enable it.\n\n## 1.6.1 / 2011-07-06\n\n* Allow alternate main namespace to be used during uberjar creation.\n* Add :checkout-deps-shares to share more directories in checkout dependencies.\n* Fix a bug where agent thread pool would be shut down in repl task.\n* Support :project-init in project.clj to allow pprint to be used in :repl-options.\n* Fix a bug where tests would not run using Clojure 1.3.\n* Support for .classpath file to include context specific classpath elements.\n\n## 1.6.0 / 2011-06-29\n\n* Enforce project names as readable symbols.\n* Add trampoline task.\n* Fix a bug where plugins would be unavailable in MinGW.\n* Allow functions other than -main to be called using run task.\n* Support constructing classpath out of ~/.m2 instead of copying to lib/.\n* Fix a bug where help output could be truncated by plugin issues.\n* Support native dependencies.\n* Test selectors no longer require additional hooke dependency.\n* Add retest task.\n* Add search task.\n* Remove deprecated build.clojure.org repositories.\n* Remove user/\\*classpath\\* var.\n* Support :extra-classpath-dirs in project.clj.\n\n## 1.5.2 / 2011-04-13\n\n* Check rlwrap for support of custom quotes before using.\n* Improve Solaris support. (Donald Clark Jackson)\n* Fix curl error relating to missing $https_proxy. (Pirmin Fix)\n\n## 1.5.1 / 2011-04-12\n\n* Improve rlwrap quote support. (Ambrose Bonnaire-Sergeant)\n* Prevent ns load exceptions from halting help.\n* Fix :repl-init namespace handling.\n* Make deps for :eval-in-leiningen projects available to lein process.\n* Pass $https_proxy environment variable to curl.\n* Fix :eval-in-leiningen when used with init arg.\n* Pom now includes dev-dependencies as test-scoped. (Thomas Engelschmidt)\n* Fix handling of arguments with spaces. (Stuart Fehr)\n* Fix a plugin bug where it would look for dev-dependencies.\n* Fix :min-lein-version checking. (Colin Jones)\n* Honor user settings in more places.\n* Fix running-as-root warning.\n* Revert back to warning when repository checksums don't match.\n\n## 1.5.0 / 2011-03-22\n\n* New projects now use Clojure 1.2.1.\n* Honor per-repository :update/:checksum policies.\n* Allow some repositories to be releases/snapshots-only.\n* Honor global :exclusions. (Joe Gallo)\n* Honor :class-file-whitelist to make classes/ deletion more manageable.\n* Accept :repl-init namespace in project.clj.\n* Warn when falling back to jline if rlwrap is not found.\n* Add prepend-task macro for simple hook usage.\n* Add flexibility to clean task with :extra-files-to-clean\n  and :regex-to-clean.\n* Fix bug in interactive task that would cause infinite loop.\n* Add version into shell wrapper template.\n* Add pcmpl-lein.el for eshell completion.\n* Skip fetching dependencies when they haven't changed in project.clj\n  if :checksum-deps is set.\n* Add system property for $PROJECT.version.\n* Add deploy task.\n* Reload tests in interactive mode.\n* Make test! task accept namespace list as argument. (Joe Gallo)\n* Use current year in readme for project skeleton. (Joe Gallo)\n\n## 1.4.2 / 2010-12-31\n\n* Fix a bug where init to eval-in-project was ignored in interactive task.\n* Fix a bug in path calculation for native dependencies. (wburke)\n* Fix a bug where built-in tasks shadowed plugins (javac, run).\n* Allow a seq of regexes in :clean-non-project-classes for more flexibility.\n* Fix a bug where the first argument to run would be parsed wrong. (Alex Osborne)\n* Use JVM\\_OPTS environment variable instead of JAVA\\_OPTS, though the latter\n  is still supported for backwards-compatibility.\n\n## 1.4.1 / 2010-12-16\n\n* Allow boosting :repl-retry-limit in project.clj for slow-starting projects.\n* Turn :clean-non-project-classes off by default.\n* Support :skip-aot metadata on :main in project.clj.\n* Alias :deps/:dev-deps to :dependencies/:dev-dependencies in project.clj.\n* Support setting clojure.debug property.\n* Don't allow stable versions to depend upon snapshots.\n* Fix exit code for chained tasks.\n\n## 1.4.0 / 2010-12-02\n\n* Support readme, tutorial, news, and copying in help task.\n* Show short help summaries in help task overview.\n* Keep project JVM running between task runs in interactive task.\n* Support :uberjar-exclusions as a seq of regexes in project.clj.\n* Support :repl-options in project.clj that get passed to clojure.main/repl.\n* Shell wrappers are installed on Windows. (Matjaz Gregoric)\n* Windows and Cygwin path fixes. (Matjaz Gregoric)\n* Solaris compatibility fixes. (Heinz Gies)\n* Deprecated :jar-dir in favour of :target-dir.\n* Deprecated unused eval-in-project arguments. (handler, skip-auto-compile)\n* Deprecated :namespaces and :test-resources-path in project.clj.\n* Delete non-project .class files after AOT compilation. (Luc Prefontaine)\n* Merge run task from lein-run plugin. (Siddhartha Reddy)\n* Improve subtask help output. (Colin Jones)\n* Support :eval-in-leiningen for easier testing of plugins.\n* Merge javac task from lein-javac plugin. (Antonio Garrote)\n* Add init argument to eval-in-project to help with the Gilardi Scenario.\n  See https://technomancy.us/143 for details.\n* Fix bug involving repl I/O flushing.\n* Run subset of test suite using test selector predicates.\n* Specify what file patterns to exclude from jars. (Zehua Liu)\n* Sort and de-dupe help output. (Sergio Arbeo)\n* Add plugin task: easily install user-level plugins (Colin Jones, Michael Ivey)\n\n## 1.3.1 / 2010-09-07\n\n* Support regex matching in :aot list. (Alex Ott)\n* Run self-install automatically if uberjar is missing.\n* Fix bugs that caused standalone install task to fail.\n* Allow dependency type to be specified in project.clj. (John Sanda)\n* Stop jar/uberjar task if compile fails. (Alan Dipert)\n* Support :min-lein-version in project.clj so if a project uses newer Leiningen\n  features it will warn users of old lein versions. (Isaac Hodes)\n* Fix a bug where tests would get skipped if their first form was not ns.\n* Fix a bug where \"lein help\" would hang if run from a dir with a large src/.\n* Fix a bug where repl task would hang on unreadable input. (Isaac Hodes)\n* Allow repl task to work outside project. (Colin Jones)\n* If curl/wget is found, self-install works on Windows. (Shantanu Kumar)\n* Fix bug causing standalone install task to fail.\n* Allow custom shell-wrappers.\n* Start repls in user ns if no :main is in project.clj.\n\n## 1.3.0 / 2010-08-19\n\n* Add :omit-source option to project.clj for shipping aot-only jars.\n* Make repl task listen on a socket as well as the command-line.\n* Write shell wrapper scripts at installation time. See TUTORIAL.md.\n* Put user-level plugins in ~/.lein/plugins on the classpath.\n* Load ~/.lein/init.clj on startup.\n* Execution of per-project initialization script, specified in :repl-init-script option.\n  (Alex Ott)\n* Switch to /bin/sh instead of bash. (Mike Meyer)\n* Allow multiple tasks to be chained from the command-line. (Colin Jones)\n* Add test! task that cleans and does deps before testing.\n* Add interactive task for entering tasks in a shell-like environment.\n* Work around argument escaping bug on Windows. (Laurence Hygate)\n* Require hooks to be specified in project.clj.\n* Detect download failures in self-install.\n* Add resources and test-resources paths to pom. (Brian Weber)\n* Fix bug causing crash if OS name wasn't recognized.\n* Improve AOT staleness determination heuristic.\n* Fix bug where uberjar left out dependencies for non-AOT'd projects. (Alex Ott)\n\n## 1.2.0 / 2010-07-18\n\n* Don't enable repl rlwrap when unnecessary. (dumb terms, Emacs, etc.)\n* Add support for password-protected repositories.\n* Allow :jar-name and :uberjar-name to be customized.\n* Allow unquoting in defproject form.\n* Support classifiers in dependencies.\n* Clean before running uberjar task.\n* Implicitly clean lib/ before running deps.\n* Add support for test-resources directory.\n* Fix help output that AOT sometimes drops.\n* Clear out lib/dev on lein clean even if :library-path is customized.\n* Some tasks suppress useless output.\n* Snapshot versions now allow self-install.\n* Allow compile task to take a list of namespaces overriding project.clj.\n* Handle more types of project metadata.\n* Add plugin creation guide.\n* Include arglists in help output.\n* Make lein script usable from any subdirectory in the project root.\n* Fix repl task to work with forked subprocess.\n* Fork subprocess unconditionally for greater compatibility.\n* Allow $JAVA_CMD to be customized.\n* Fix a bug causing everything to recompile in tests. Thanks, Stuart!\n* Fix exit code for test runs.\n* Automatically compile and fetch deps when needed.\n* Allow :jvm-opts and :warn-on-reflection to be set in project.clj.\n* Merge lein-swank plugin into swank-clojure.\n* Add :aot as an alias in project.clj for :namespaces to AOT-compile.\n* Add option to omit-default-repositories.\n* Allow group-id to be omitted when depending on Clojure and Contrib.\n* Keep dev-dependencies in lib/dev, exclude them from uberjars.\n* Include version numbers in jar filenames.\n* Fix repl task to use project subclassloader.\n* Don't allow \"new\" task to create *jure names.\n* Add classpath command.\n* Implement Checkout Dependencies. See README.\n* Add option to symlink deps into lib/ instead of copying.\n* Fixed bug for file timestamps inside jars.\n* Generated poms should work in Java IDEs.\n* Improved Cygwin support.\n* Added TUTORIAL.md file for introductory concepts.\n\n## 1.1.0 / 2010-02-16\n\n* Added \"lein upgrade\" task\n* Don't download snapshot releases unless actually needed.\n* Make subclassloader's classpath available to projects.\n* Fixed \"install\" task to place pom in local repository.\n* Bug fixes to \"new\" task.\n* Only AOT-compile namespaces specified in project.clj.\n* Better error handling.\n* Add exclusions support for dependencies.\n* Support dependencies with native code.\n* Added experimental Windows support.\n\n## 1.0.1 / 2009-12-10\n\n* Added bash completion.\n* Honor $JAVA_OPTS.\n* Fix new task.\n* Add version task.\n* Use jline for repl task.\n* Fix pom task for Java 1.5 compatibility.\n\n## 1.0.0 / 2009-12-05\n\n* Source, test, and compilation paths can be set in project.clj.\n* Project code runs in an isolated classloader; can now compile/test\n  projects that require a different version of Clojure from\n  Leiningen. (Does not support 1.0's test-is yet.)\n* Install task no longer requires maven to be installed.\n* Only compile namespaces whose .class files are older than .clj files.\n* Add \"new\" task for generating blank projects.\n* Set <scm> tag when generating pom.xml.\n* Include pom.xml, pom.properties, and more detailed manifest in jars.\n* Summarize pass/fail counts from test runs across all namespaces.\n* Accept a list of namespaces for test task rather than testing all.\n* Create $PROJECT-standalone.jar file from uberjar to distinguish from\n  regular jar files.\n* Plugins have more flexibility to set the classpath and other\n  arguments for running project code.\n* Add resources/ directory to classpath and generated jars.\n* Start Leiningen faster by using -Xbootclasspath argument.\n\n## 0.5.0 / 2009-11-17\n\n* Initial release!\n"
  },
  {
    "path": "README.md",
    "content": "# Leiningen\n\n[![builds.sr.ht status](https://builds.sr.ht/~technomancy/leiningen.svg)](https://builds.sr.ht/~technomancy/leiningen?)\n\n<img src=\"https://leiningen.org/img/leiningen.jpg\"\n alt=\"Leiningen logo\" title=\"The man himself\" align=\"right\" />\n\n> \"Leiningen!\" he shouted. \"You're insane! They're not creatures you can\n> fight&mdash;they're an elemental&mdash;an 'act of God!' Ten miles long, two\n> miles wide&mdash;ants, nothing but ants! And every single one of them a\n> fiend from hell...\"\n> - from [Leiningen Versus the Ants](http://www.classicshorts.com/stories/lvta.html) by Carl Stephenson\n\nLeiningen is for automating Clojure projects without setting your hair on fire.\n\nNote: the canonical repository for Leiningen is [on\nCodeberg](https://codeberg.org/leiningen/leiningen) but we temporarily\nmaintain [a mirror on\nGitHub](https://github.com/technomancy/leiningen). Please update your\nlinks and git remotes.\n\n## Installation\n\nIf your preferred [package manager](https://wiki.leiningen.org/Packaging)\noffers a recent version of Leiningen, try that first.\n\nLeiningen installs itself on the first run of the `lein` shell script; there is no\nseparate install script.  Follow these instructions to install Leiningen manually:\n\n1. Make sure you have Java installed; [OpenJDK](https://adoptium.net) is recommended\n2. [Download the `lein` script from the `stable` branch](https://codeberg.org/leiningen/leiningen/raw/branch/stable/bin/lein)\n of this project\n3. Place it on your `$PATH` (`/usr/local/bin` for example)\n4. Set it to be executable. (`sudo chmod +x /usr/local/bin/lein`)\n5. Run it.\n\nWindows users can use the above script in the Linux subsystem or try\n[the batch file](https://codeberg.org/leiningen/leiningen/raw/branch/stable/bin/lein.bat) or\n[PowerShell version](https://codeberg.org/leiningen/leiningen/raw/branch/stable/bin/lein.ps1)\ninstead.\n\n## Basic Usage\n\nThe\n[tutorial](https://codeberg.org/leiningen/leiningen/src/stable/doc/TUTORIAL.md)\nhas a detailed walk-through of the steps involved in creating a new\nproject, but here are the commonly-used tasks:\n\n    $ lein new [TEMPLATE] NAME # generate a new project skeleton\n\n    $ lein test [TESTS] # run the tests in the TESTS namespaces, or all tests\n\n    $ lein repl # launch an interactive REPL session\n\n    $ lein run -m my.namespace # run the -main function of a namespace\n\n    $ lein uberjar # package the project and dependencies as standalone jar\n\n    $ lein deploy clojars # publish the project to Clojars as a library\n\nUse `lein help` to see a complete list. `lein help $TASK` shows the\nusage for a specific task.\n\nYou can also chain tasks together in a single command by using the\n`do` task with comma-separated tasks:\n\n    $ lein do clean, test foo.test-core, jar\n\nMost tasks need to be run from somewhere inside a project directory to\nwork, but some (`new`, `help`, `search`, `version`, and `repl`) may\nrun from anywhere.\n\n## Configuration\n\nThe `project.clj` file in the project root should look like this:\n\n```clj\n(defproject myproject \"0.5.0-SNAPSHOT\"\n  :description \"A project for doing things.\"\n  :license \"Eclipse Public License 1.0\"\n  :url \"https://codelab.org/technomancy/myproject\"\n  :dependencies [[org.clojure/clojure \"1.8.0\"]]\n  :plugins [[lein-tar \"3.2.0\"]])\n```\n\nThe `lein new` task generates a project skeleton with an appropriate\nstarting point from which you can work. See the\n[sample.project.clj](https://codeberg.org/leiningen/leiningen/src/stable/sample.project.clj)\nfile (also available via `lein help sample`) for a detailed listing of\nconfiguration options.\n\nThe `project.clj` file can be customized further with the use of\n[profiles](https://codeberg.org/leiningen/leiningen/src/stable/doc/PROFILES.md).\n\n## Documentation\n\nLeiningen documentation is organized as a number of guides:\n\n### Usage\n\n * [Tutorial](https://codeberg.org/leiningen/leiningen/src/stable/doc/TUTORIAL.md) (start here if you are new)\n * [FAQ](https://codeberg.org/leiningen/leiningen/src/stable/doc/FAQ.md)\n * [Profiles](https://codeberg.org/leiningen/leiningen/src/stable/doc/PROFILES.md)\n * [Deployment & Distribution of Libraries](https://codeberg.org/leiningen/leiningen/src/stable/doc/DEPLOY.md)\n * [Sample project.clj](https://codeberg.org/leiningen/leiningen/src/stable/sample.project.clj)\n * [Polyglot (e.g. Clojure/Java) projects](https://codeberg.org/leiningen/leiningen/src/stable/doc/MIXED_PROJECTS.md)\n\n### Development\n\n* [Writing Plugins](https://codeberg.org/leiningen/leiningen/src/stable/doc/PLUGINS.md)\n* [Writing Templates](https://codeberg.org/leiningen/leiningen/src/stable/doc/TEMPLATES.md)\n* [Contributing](https://codeberg.org/leiningen/leiningen/src/stable/CONTRIBUTING.md)\n* [Building Leiningen](https://codeberg.org/leiningen/leiningen/src/stable/CONTRIBUTING.md#bootstrapping)\n\n## Plugins\n\nLeiningen supports plugins which may introduce new tasks. See\n[the plugins wiki page](https://wiki.leiningen.org/Plugins)\nfor a full list. If a plugin is needed for successful test or build\nruns, (such as `lein-tar`) then it should be added to `:plugins` in\nproject.clj, but if it's for your own convenience (such as\n`lein-pprint`) then it should be added to the `:plugins` list in the\n`:user` profile in `~/.lein/profiles.clj`. See the\n[profiles guide](https://codeberg.org/leiningen/leiningen/src/stable/doc/PROFILES.md)\nfor details on how to add to your `:user` profile. The\n[plugin guide](https://codeberg.org/leiningen/leiningen/src/stable/doc/PLUGINS.md)\nexplains how to write plugins.\n\n## License\n\nSource Copyright © 2009-2025 Phil Hagelberg, Alex Osborne, Dan Larkin, and\ncontributors.\nDistributed under the Eclipse Public License, the same as Clojure\nuses. See the file COPYING.\n\nThanks to Stuart Halloway for Lancet and Tim Dysinger for convincing\nme that good builds are important.\n\nImages Copyright © 2010 Phil Hagelberg. Distributed under the Creative\nCommons Attribution + ShareAlike\nLicense 4.0. [Full-size version](https://leiningen.org/img/leiningen-full.jpg)\navailable.\n"
  },
  {
    "path": "bash_completion.bash",
    "content": "_lein_completion() {\n    local cur prev tasks\n    COMPREPLY=()\n    cur=\"${COMP_WORDS[COMP_CWORD]}\"\n    prev=\"${COMP_WORDS[COMP_CWORD-1]}\"\n    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\"\n\n    case \"${prev}\" in\n        change | check | classpath | clean | deploy | deps | do | install | jar | javac | new | plugin | pom | release | repl | show-profiles | uberjar | update-in | vcs | version)\n            COMPREPLY=()\n            ;;\n        help)\n            # Show tasks again, but only once; don't infinitely recurse\n            local prev2=\"${COMP_WORDS[COMP_CWORD-2]}\"\n            if [ \"$prev2\" == \"help\" ]; then\n                COMPREPLY=()\n            else\n                COMPREPLY=( $(compgen -W \"${tasks}\" -- ${cur}) )\n            fi\n            ;;\n        test | retest )\n            # list project's test namespaces:\n            local namespaces=$(find test/ -type f -name \"*.clj\" -exec sed -n 's/^(ns[ ]*//p' '{}' '+')\n            COMPREPLY=( $(compgen -W \"${namespaces}\" -- ${cur}) )\n            ;;\n        run | compile)\n            # list project's src namespaces:\n            local namespaces=$(find src/ -type f -name \"*.clj\" -exec sed -n 's/^(ns[ ]*//p' '{}' '+')\n            COMPREPLY=( $(compgen -W \"${namespaces}\" -- ${cur}) )\n            ;;\n        lein)\n            COMPREPLY=( $(compgen -W \"${tasks}\" -- ${cur}) )\n            ;;\n    esac\n\n    return 0\n}\ncomplete -F _lein_completion lein\n"
  },
  {
    "path": "bin/bump",
    "content": "#!/bin/bash\n\nCURRENT_VERSION=$1\nSNAPSHOT_VERSION=$2\n\nif [ \"$CURRENT_VERSION\" = \"\" ] || [ \"$SNAPSHOT_VERSION\" = \"\" ] ; then\n   echo \"Usage: bin/bump 2.9.7 2.9.8-SNAPSHOT\"\n   exit 1\nfi\n\nfor f in bin/lein bin/lein-pkg bin/lein.bat bin/lein.ps1 project.clj leiningen-core/project.clj; do\n    sed -i s/$CURRENT_VERSION/$SNAPSHOT_VERSION/ $f\ndone\n"
  },
  {
    "path": "bin/issues.clj",
    "content": ";; This is just a one-off tool to classify/summarize issues programmatically.\n\n(try (require 'tentacles.issues)\n     (catch java.io.FileNotFoundException _\n       (cemerick.pomegranate/add-dependencies\n        :repositories [[\"clojars\" {:url \"https://clojars.org/repo/\"}]]\n        :coordinates '[[tentacles \"0.2.7\"]])\n       (require 'tentacles.issues)))\n\n(defn labeled? [label issue] (some #(= (:name %) label) (:labels issue)))\n(def low-priority? #{1566 1544 1319 1363 1155})\n(def order [\"2.4.3\" \"other\" \"Enhancement\" \"docs\" \"low\" \"3.0.0\"])\n\n(defn categorize [i]\n  (cond (labeled? \"Windows\" i) nil\n        (:title (:milestone i)) (:title (:milestone i))\n        (labeled? \"Enhancement\" i) \"Enhancement\"\n        (labeled? \"docs\" i) \"docs\"\n        (low-priority? (:number i)) \"low\"\n        :else \"other\"))\n\n(defn report []\n  (doseq [[category issues] (->> (tentacles.issues/issues\n                                  \"technomancy\" \"leiningen\")\n                                 (group-by categorize)\n                                 (sort-by #(.indexOf order (key %))))\n          :when category]\n    (println \"\\n#\" category)\n    (doseq [i issues]\n      (println (:number i) \"-\" (:title i)))))\n"
  },
  {
    "path": "bin/lein",
    "content": "#!/usr/bin/env bash\n\n# Ensure this file is executable via `chmod a+x lein`, then place it\n# somewhere on your $PATH, like ~/bin. The rest of Leiningen will be\n# installed upon first run into the ~/.lein/self-installs directory.\n\nexport LEIN_VERSION=\"2.12.0\"\n# Must be sha256sum, will be replaced by bin/release\nexport LEIN_CHECKSUM='b721a573af631784f27ccb52e719e6d1287d9d3951ad56d316d38f7ecfa81aa2'\n\ncase $LEIN_VERSION in\n    *SNAPSHOT) SNAPSHOT=\"YES\" ;;\n    *) SNAPSHOT=\"NO\" ;;\nesac\n\nif [[ \"$CLASSPATH\" != \"\" ]]; then\n    cat <<-'EOS' 1>&2\n\tWARNING: You have $CLASSPATH set, probably by accident.\n\tIt is strongly recommended to unset this before proceeding.\n\tEOS\nfi\n\nif [[ \"$OSTYPE\" == \"cygwin\" ]] || [[ \"$OSTYPE\" == \"msys\" ]]; then\n    delimiter=\";\"\nelse\n    delimiter=\":\"\nfi\n\nif [[ \"$OSTYPE\" == \"cygwin\" ]]; then\n  cygwin=true\nelse\n  cygwin=false\nfi\n\nfunction msg {\n    echo \"$@\" 1>&2\n}\n\nfunction command_not_found {\n    msg \"Leiningen couldn't find $1 in your \\$PATH ($PATH), which is required.\"\n    exit 1\n}\n\nfunction make_native_path {\n    # ensure we have native paths\n    if $cygwin && [[ \"$1\"  == /* ]]; then\n    echo -n \"$(cygpath -wp \"$1\")\"\n    elif [[ \"$OSTYPE\" == \"msys\" && \"$1\"  == /?/* ]]; then\n    echo -n \"$(sh -c \"(cd $1 2</dev/null && pwd -W) || echo $1 | sed 's/^\\\\/\\([a-z]\\)/\\\\1:/g'\")\"\n    else\n    echo -n \"$1\"\n    fi\n}\n\n#  usage : add_path PATH_VAR [PATH]...\nfunction add_path {\n    local path_var=\"$1\"\n    shift\n    while [ -n \"$1\" ];do\n        # http://bashify.com/?Useful_Techniques:Indirect_Variables:Indirect_Assignment\n        if [[ -z ${!path_var} ]]; then\n          export ${path_var}=\"$(make_native_path \"$1\")\"\n        else\n          export ${path_var}=\"${!path_var}${delimiter}$(make_native_path \"$1\")\"\n        fi\n    shift\n    done\n}\n\nfunction download_failed_message {\n    cat <<-EOS 1>&2\n\tFailed to download $1 (exit code $2)\n\tIt's possible your HTTP client's certificate store does not have the\n\tcorrect certificate authority needed. This is often caused by an\n\tout-of-date version of libssl. It's also possible that you're behind a\n\tfirewall and haven't set HTTP_PROXY and HTTPS_PROXY.\n\tEOS\n}\n\nfunction checksum_failed_message {\n    cat <<-EOS 1>&2\n\tFailed to properly download $1\n\tThe checksum was mismatched. and we could not verify the downloaded\n\tfile. We expected a sha256 of\n\t$2 and actually had\n\t$3.\n\tWe used '$SHASUM_CMD' to verify the downloaded file.\n\tEOS\n}\n\nfunction self_install {\n  if [ -r \"$LEIN_JAR\" ]; then\n    cat <<-EOS 1>&2\n\tThe self-install jar already exists at $LEIN_JAR.\n\tIf you wish to re-download, delete it and rerun \"$0 self-install\".\n\tEOS\n    exit 1\n  fi\n  msg \"Downloading Leiningen to $LEIN_JAR now...\"\n  mkdir -p \"$(dirname \"$LEIN_JAR\")\"\n  LEIN_URL=\"https://github.com/technomancy/leiningen/releases/download/$LEIN_VERSION/leiningen-$LEIN_VERSION-standalone.jar\"\n  $HTTP_CLIENT \"$LEIN_JAR.pending\" \"$LEIN_URL\"\n  local exit_code=$?\n  if [ $exit_code == 0 ]; then\n      printf \"$LEIN_CHECKSUM  $LEIN_JAR.pending\\n\" > \"$LEIN_JAR.pending.shasum\"\n      $SHASUM_CMD -c \"$LEIN_JAR.pending.shasum\"\n      if [ $? == 0 ]; then\n        mv -f \"$LEIN_JAR.pending\" \"$LEIN_JAR\"\n      else\n        got_sum=\"$($SHASUM_CMD \"$LEIN_JAR.pending\" | cut -f 1 -d ' ')\"\n        checksum_failed_message \"$LEIN_URL\" \"$LEIN_CHECKSUM\" \"$got_sum\"\n        rm \"$LEIN_JAR.pending\" 2> /dev/null\n        exit 1\n      fi\n  else\n      rm \"$LEIN_JAR.pending\" 2> /dev/null\n      download_failed_message \"$LEIN_URL\" \"$exit_code\"\n      exit 1\n  fi\n}\n\nfunction run_from_source() {\n    LEIN_DIR=\"$(cd $(dirname \"$BIN_DIR\");pwd -P)\"\n\n    # Need to use lein release to bootstrap the leiningen-core library (for aether)\n    if [ ! -r \"$LEIN_DIR/leiningen-core/.lein-bootstrap\" ]; then\n        cat <<-'EOS' 1>&2\n\tLeiningen is missing its dependencies.\n\tPlease run \"lein bootstrap\" in the leiningen-core/ directory\n\twith a stable release of Leiningen. See CONTRIBUTING.md for details.\n\tEOS\n        exit 1\n    fi\n\n    # If project.clj for lein or leiningen-core changes, we must recalculate\n    LAST_PROJECT_CHECKSUM=$(cat \"$LEIN_DIR/.lein-project-checksum\" 2> /dev/null)\n    PROJECT_CHECKSUM=$(sum \"$LEIN_DIR/project.clj\" \"$LEIN_DIR/leiningen-core/project.clj\")\n    if [ \"$PROJECT_CHECKSUM\" != \"$LAST_PROJECT_CHECKSUM\" ]; then\n        if [ -r \"$LEIN_DIR/.lein-classpath\" ]; then\n            rm \"$LEIN_DIR/.lein-classpath\"\n        fi\n    fi\n\n    # Use bin/lein to calculate its own classpath.\n    if [ ! -r \"$LEIN_DIR/.lein-classpath\" ] && [ \"$1\" != \"classpath\" ]; then\n        msg \"Recalculating Leiningen's classpath.\"\n        cd \"$LEIN_DIR\"\n\n        LEIN_NO_USER_PROFILES=1 \"$LEIN_DIR/bin/lein\" classpath .lein-classpath\n        sum \"$LEIN_DIR/project.clj\" \"$LEIN_DIR/leiningen-core/project.clj\" > \\\n            .lein-project-checksum\n        cd -\n    fi\n\n    mkdir -p \"$LEIN_DIR/target/classes\"\n    export LEIN_JVM_OPTS=\"$LEIN_JVM_OPTS -Dclojure.compile.path=$LEIN_DIR/target/classes\"\n    add_path CLASSPATH \"$LEIN_DIR/leiningen-core/src/\" \"$LEIN_DIR/leiningen-core/resources/\" \\\n        \"$LEIN_DIR/test:$LEIN_DIR/target/classes\" \"$LEIN_DIR/src\" \":$LEIN_DIR/resources\"\n\n    if [ -r \"$LEIN_DIR/.lein-classpath\" ]; then\n        add_path CLASSPATH \"$(cat \"$LEIN_DIR/.lein-classpath\" 2> /dev/null)\"\n    else\n        add_path CLASSPATH \"$(cat \"$LEIN_DIR/leiningen-core/.lein-bootstrap\" 2> /dev/null)\"\n    fi\n}\n\nfunction run_from_checkout() {\n    add_path CLASSPATH \"$LEIN_JAR\"\n\n    if [ \"$LEIN_USE_BOOTCLASSPATH\" != \"no\" ]; then\n        LEIN_JVM_OPTS=\"-Xbootclasspath/a:$LEIN_JAR $LEIN_JVM_OPTS\"\n    fi\n}\n\nfunction cmd_self_install() {\n    if [ -r \"$BIN_DIR/../src/leiningen/version.clj\" ]; then\n        cat <<-'EOS' 1>&2\n\tRunning self-install from a checkout is not supported.\n\tSee CONTRIBUTING.md for SNAPSHOT-specific build instructions.\n\tEOS\n        exit 1\n    fi\n    msg \"Manual self-install is deprecated; it will run automatically when necessary.\"\n    self_install\n}\n\nfunction cmd_up_downgrade() {\n    if [ \"$LEIN_DIR\" != \"\" ]; then\n        msg \"The upgrade task is not meant to be run from a checkout.\"\n        exit 1\n    fi\n    if [ $SNAPSHOT = \"YES\" ]; then\n        cat <<-'EOS' 1>&2\n\tThe upgrade task is only meant for stable releases.\n\tSee the \"Bootstrapping\" section of CONTRIBUTING.md.\n\tEOS\n        exit 1\n    fi\n    if [ ! -w \"$SCRIPT\" ]; then\n        msg \"You do not have permission to upgrade the installation in $SCRIPT\"\n        exit 1\n    else\n        TARGET_VERSION=\"${2:-stable}\"\n        echo \"The script at $SCRIPT will be upgraded to the latest $TARGET_VERSION version.\"\n        echo -n \"Do you want to continue [Y/n]? \"\n        read RESP\n        case \"$RESP\" in\n            y|Y|\"\")\n                echo\n                msg \"Upgrading...\"\n                if hash mktemp 2>/dev/null; then\n                    TARGET=\"(mktemp -t lein-upgrade.XXXXXXXXX)\"\n                else\n                    TARGET=\"/tmp/lein-${$}-upgrade\"\n                fi\n                if $cygwin; then\n                    TARGET=$(cygpath -w \"$TARGET\")\n                fi\n                LEIN_SCRIPT_URL=\"https://github.com/technomancy/leiningen/raw/$TARGET_VERSION/bin/lein\"\n                $HTTP_CLIENT \"$TARGET\" \"$LEIN_SCRIPT_URL\"\n                if [ $? == 0 ]; then\n                    cmp -s \"$TARGET\" \"$SCRIPT\"\n                    if [ $? == 0 ]; then\n                        msg \"Leiningen is already up-to-date.\"\n                    fi\n                    mv \"$TARGET\" \"$SCRIPT\" && chmod +x \"$SCRIPT\"\n                    unset CLASSPATH\n                    exec \"$SCRIPT\" version\n                else\n                    download_failed_message \"$LEIN_SCRIPT_URL\"\n                fi;;\n            *)\n                msg \"Aborted.\"\n                exit 1;;\n        esac\n    fi\n}\n\nfunction cmd_run {\n    if $cygwin; then\n        # When running on Cygwin, use Windows-style paths for java\n        ORIGINAL_PWD=$(cygpath -w \"$ORIGINAL_PWD\")\n    fi\n\n    # apply context specific CLASSPATH entries\n    if [ -f .lein-classpath ]; then\n        add_path CLASSPATH \"$(cat .lein-classpath)\"\n    fi\n\n    if [ -n \"$DEBUG\" ]; then\n        msg \"Leiningen's classpath: $CLASSPATH\"\n    fi\n\n    if [ -r .lein-fast-trampoline ]; then\n        export LEIN_FAST_TRAMPOLINE='y'\n    fi\n\n    if [ \"$LEIN_FAST_TRAMPOLINE\" != \"\" ] && [ -r project.clj ]; then\n        INPUTS=\"$* $(cat project.clj) $LEIN_VERSION $(test -f \"$LEIN_HOME/profiles.clj\" && cat \"$LEIN_HOME/profiles.clj\") $(test -f profiles.clj && cat profiles.clj)\"\n\n        INPUT_CHECKSUM=$(echo \"$INPUTS\" | $SHASUM_CMD | cut -f 1 -d \" \")\n        # Just don't change :target-path in project.clj, mkay?\n        TRAMPOLINE_FILE=\"target/trampolines/$INPUT_CHECKSUM\"\n    else\n        if hash mktemp 2>/dev/null; then\n            # Check if mktemp is available before using it\n            TRAMPOLINE_FILE=\"$(mktemp -t lein-trampoline-XXXXXXXXXXXXX)\"\n        else\n            TRAMPOLINE_FILE=\"/tmp/lein-trampoline-$$\"\n        fi\n        trap 'rm -f $TRAMPOLINE_FILE' EXIT\n    fi\n\n    if $cygwin; then\n        TRAMPOLINE_FILE=$(cygpath -w \"$TRAMPOLINE_FILE\")\n    fi\n\n    if [ \"$INPUT_CHECKSUM\" != \"\" ] && [ -r \"$TRAMPOLINE_FILE\" ]; then\n        if [ -n \"$DEBUG\" ]; then\n            msg \"Fast trampoline with $TRAMPOLINE_FILE.\"\n        fi\n        exec sh -c \"exec $(cat \"$TRAMPOLINE_FILE\")\"\n    else\n        export TRAMPOLINE_FILE\n        \"$LEIN_JAVA_CMD\" \\\n            -Dfile.encoding=UTF-8 \\\n            -Dmaven.wagon.http.ssl.easy=false \\\n            $LEIN_JVM_OPTS \\\n            -Dleiningen.input-checksum=\"$INPUT_CHECKSUM\" \\\n            -Dleiningen.original.pwd=\"$ORIGINAL_PWD\" \\\n            -Dleiningen.script=\"$SCRIPT\" \\\n            -classpath \"$CLASSPATH\" \\\n            clojure.main -m leiningen.core.main \"$@\"\n\n        EXIT_CODE=$?\n\n        if $cygterm ; then\n          stty icanon echo > /dev/null 2>&1\n        fi\n\n        if [ -r \"$TRAMPOLINE_FILE\" ] && [ \"$LEIN_TRAMPOLINE_WARMUP\" = \"\" ]; then\n            TRAMPOLINE=\"$(cat \"$TRAMPOLINE_FILE\")\"\n            if [ \"$INPUT_CHECKSUM\" = \"\" ]; then # not using fast trampoline\n                rm \"$TRAMPOLINE_FILE\"\n            fi\n            if [ \"$TRAMPOLINE\" = \"\" ]; then\n                exit $EXIT_CODE\n            else\n                exec sh -c \"exec $TRAMPOLINE\"\n            fi\n        else\n            exit $EXIT_CODE\n        fi\n    fi\n}\n\n# cd to the project root, if applicable\nNOT_FOUND=1\nORIGINAL_PWD=\"$PWD\"\nwhile [ ! -r \"$PWD/project.clj\" ] && [ \"$PWD\" != \"/\" ] && [ $NOT_FOUND -ne 0 ]\ndo\n    cd ..\n    if [ \"$(dirname \"$PWD\")\" = \"/\" ]; then\n        NOT_FOUND=0\n        cd \"$ORIGINAL_PWD\"\n    fi\ndone\n\n# User init\nif [ \"$LEIN_HOME\" = \"\" ]; then\n    # Prefer the old location if present\n    if [ -d \"$HOME/.lein\" ]; then\n        export LEIN_HOME=\"$HOME/.lein\"\n    elif [ -d \"$XDG_CACHE_HOME/leiningen\" ]; then\n        export LEIN_HOME=\"$XDG_CACHE_HOME/leiningen\"\n    else\n        export LEIN_HOME=\"$HOME/.lein\"\n    fi\nfi\n\nfor f in \"/etc/leinrc\" \"$LEIN_HOME/leinrc\" \".leinrc\"; do\n  if [ -e \"$f\" ]; then\n    source \"$f\"\n  fi\ndone\n\nif $cygwin; then\n    export LEIN_HOME=$(cygpath -m \"$LEIN_HOME\")\nfi\n\n# normalize $0 on certain BSDs\nif [ \"$(dirname \"$0\")\" = \".\" ]; then\n    SCRIPT=\"$(which \"$(basename \"$0\")\")\"\n    if [ -z \"$SCRIPT\" ]; then\n        SCRIPT=\"$0\"\n    fi\nelse\n    SCRIPT=\"$0\"\nfi\n\n# resolve symlinks to the script itself portably\nwhile [ -h \"$SCRIPT\" ] ; do\n    ls=$(ls -ld \"$SCRIPT\")\n    link=$(expr \"$ls\" : '.*-> \\(.*\\)$')\n    if expr \"$link\" : '/.*' > /dev/null; then\n        SCRIPT=\"$link\"\n    else\n        SCRIPT=\"$(dirname \"$SCRIPT\"$)/$link\"\n    fi\ndone\n\nBIN_DIR=\"$(dirname \"$SCRIPT\")\"\n\n\nLEIN_JAR=\"${LEIN_JAR:-${LEIN_HOME}/self-installs/leiningen-${LEIN_VERSION}-standalone.jar}\"\n\nexport LEIN_JVM_OPTS=\"${LEIN_JVM_OPTS-\"-XX:+TieredCompilation -XX:TieredStopAtLevel=1\"}\"\n\n# This needs to be defined before we call HTTP_CLIENT below\nif [ \"$HTTP_CLIENT\" = \"\" ]; then\n    if type -p curl >/dev/null 2>&1; then\n        if [ \"$https_proxy\" != \"\" ]; then\n            CURL_PROXY=\"-x $https_proxy\"\n        fi\n        HTTP_CLIENT=\"curl $CURL_PROXY -f -L -o\"\n    else\n        HTTP_CLIENT=\"wget -O\"\n    fi\nfi\n\n# This needs to be defined before we call SHASUM_CMD below\nif [ \"$SHASUM_CMD\" = \"\" ]; then\n    if type -p sha256sum >/dev/null 2>&1; then\n        export SHASUM_CMD=\"sha256sum\"\n    elif type -p shasum >/dev/null 2>&1; then\n        export SHASUM_CMD=\"shasum --algorithm 256\"\n    elif type -p sha256 >/dev/null 2>&1; then\n        export SHASUM_CMD=\"sha256 -q\"\n    else\n        command_not_found sha256sum\n    fi\nfi\n\n# When :eval-in :classloader we need more memory\ngrep -E -q '^\\s*:eval-in\\s+:classloader\\s*$' project.clj 2> /dev/null && \\\n    export LEIN_JVM_OPTS=\"$LEIN_JVM_OPTS -Xms64m -Xmx512m\"\n\nif [ -r \"$BIN_DIR/../src/leiningen/version.clj\" ]; then\n    run_from_source \"$1\"\nelse\n    run_from_checkout \"$1\"\n\n    if [ ! -r \"$LEIN_JAR\" -a \"$1\" != \"self-install\" ]; then\n        self_install\n    fi\nfi\n\nif [ ! -x \"$JAVA_CMD\" ] && ! type -f java >/dev/null\nthen\n    msg \"Leiningen couldn't find 'java' executable, which is required.\"\n    msg \"Please either set JAVA_CMD or put java (>=1.6) in your \\$PATH ($PATH).\"\n    exit 1\nfi\n\nexport LEIN_JAVA_CMD=\"${LEIN_JAVA_CMD:-${JAVA_CMD:-java}}\"\n\nif [[ -z \"${DRIP_INIT+x}\" && \"$(basename \"$LEIN_JAVA_CMD\")\" == *drip* ]]; then\n    export DRIP_INIT=\"$(printf -- '-e\\n(require (quote leiningen.repl))')\"\n    export DRIP_INIT_CLASS=\"clojure.main\"\nfi\n\n# Support $JAVA_OPTS for backwards-compatibility.\nexport JVM_OPTS=\"${JVM_OPTS:-\"$JAVA_OPTS\"}\"\n\n# Handle jline issue with cygwin not propagating OSTYPE through java subprocesses: https://github.com/jline/jline2/issues/62\ncygterm=false\nif $cygwin; then\n  case \"$TERM\" in\n    rxvt* | xterm* | vt*) cygterm=true ;;\n  esac\nfi\n\nif $cygterm; then\n  LEIN_JVM_OPTS=\"$LEIN_JVM_OPTS -Djline.terminal=jline.UnixTerminal\"\n  stty -icanon min 1 -echo > /dev/null 2>&1\nfi\n\n# If you're packaging this for a package manager (.deb, homebrew, etc)\n# you need to remove the self-install and upgrade functionality or see lein-pkg.\nif [ \"$1\" = \"self-install\" ]; then\n    cmd_self_install\nelif [ \"$1\" = \"upgrade\" ] || [ \"$1\" = \"downgrade\" ]; then\n    cmd_up_downgrade \"$@\"\nelse\n    cmd_run \"$@\"\nfi\n"
  },
  {
    "path": "bin/lein-pkg",
    "content": "#!/usr/bin/env bash\n\n# This variant of the lein script is meant for downstream packagers.\n# It has all the cross-platform stuff stripped out as well as the\n# logic for running from a source checkout and self-install/upgrading.\n\nexport LEIN_VERSION=\"2.12.0\"\n\nif [[ \"$CLASSPATH\" != \"\" ]]; then\n    cat <<-'EOS' 1>&2\n\tWARNING: You have $CLASSPATH set, probably by accident.\n\tIt is strongly recommended to unset this before proceeding.\n\tEOS\nfi\n\nif [[ \"$OSTYPE\" == \"cygwin\" ]] || [[ \"$OSTYPE\" == \"msys\" ]]; then\n    delimiter=\";\"\nelse\n    delimiter=\":\"\nfi\n\nif [[ \"$OSTYPE\" == \"cygwin\" ]]; then\n  cygwin=true\nelse\n  cygwin=false\nfi\n\nfunction msg {\n    echo \"$@\" 1>&2\n}\n\nfunction command_not_found {\n    msg \"Leiningen couldn't find $1 in your \\$PATH ($PATH), which is required.\"\n    exit 1\n}\n\nfunction make_native_path {\n    # ensure we have native paths\n    if $cygwin && [[ \"$1\"  == /* ]]; then\n    echo -n \"$(cygpath -wp \"$1\")\"\n    elif [[ \"$OSTYPE\" == \"msys\" && \"$1\"  == /?/* ]]; then\n    echo -n \"$(sh -c \"(cd $1 2</dev/null && pwd -W) || echo $1 | sed 's/^\\\\/\\([a-z]\\)/\\\\1:/g'\")\"\n    else\n    echo -n \"$1\"\n    fi\n}\n\n#  usage : add_path PATH_VAR [PATH]...\nfunction add_path {\n    local path_var=\"$1\"\n    shift\n    while [ -n \"$1\" ];do\n        # http://bashify.com/?Useful_Techniques:Indirect_Variables:Indirect_Assignment\n        if [[ -z ${!path_var} ]]; then\n          export ${path_var}=\"$(make_native_path \"$1\")\"\n        else\n          export ${path_var}=\"${!path_var}${delimiter}$(make_native_path \"$1\")\"\n        fi\n    shift\n    done\n}\n\nfunction run_from_checkout() {\n    add_path CLASSPATH \"$LEIN_JAR\"\n\n    if [ \"$LEIN_USE_BOOTCLASSPATH\" != \"no\" ]; then\n        LEIN_JVM_OPTS=\"-Xbootclasspath/a:$LEIN_JAR $LEIN_JVM_OPTS\"\n    fi\n}\n\nfunction cmd_run {\n    if $cygwin; then\n        # When running on Cygwin, use Windows-style paths for java\n        ORIGINAL_PWD=$(cygpath -w \"$ORIGINAL_PWD\")\n    fi\n\n    # apply context specific CLASSPATH entries\n    if [ -f .lein-classpath ]; then\n        add_path CLASSPATH \"$(cat .lein-classpath)\"\n    fi\n\n    if [ -n \"$DEBUG\" ]; then\n        msg \"Leiningen's classpath: $CLASSPATH\"\n    fi\n\n    if [ -r .lein-fast-trampoline ]; then\n        export LEIN_FAST_TRAMPOLINE='y'\n    fi\n\n    if [ \"$LEIN_FAST_TRAMPOLINE\" != \"\" ] && [ -r project.clj ]; then\n        INPUTS=\"$* $(cat project.clj) $LEIN_VERSION $(test -f \"$LEIN_HOME/profiles.clj\" && cat \"$LEIN_HOME/profiles.clj\") $(test -f profiles.clj && cat profiles.clj)\"\n\n        INPUT_CHECKSUM=$(echo \"$INPUTS\" | $SHASUM_CMD | cut -f 1 -d \" \")\n        # Just don't change :target-path in project.clj, mkay?\n        TRAMPOLINE_FILE=\"target/trampolines/$INPUT_CHECKSUM\"\n    else\n        if hash mktemp 2>/dev/null; then\n            # Check if mktemp is available before using it\n            TRAMPOLINE_FILE=\"$(mktemp -t lein-trampoline-XXXXXXXXXXXXX)\"\n        else\n            TRAMPOLINE_FILE=\"/tmp/lein-trampoline-$$\"\n        fi\n        trap 'rm -f $TRAMPOLINE_FILE' EXIT\n    fi\n\n    if $cygwin; then\n        TRAMPOLINE_FILE=$(cygpath -w \"$TRAMPOLINE_FILE\")\n    fi\n\n    if [ \"$INPUT_CHECKSUM\" != \"\" ] && [ -r \"$TRAMPOLINE_FILE\" ]; then\n        if [ -n \"$DEBUG\" ]; then\n            msg \"Fast trampoline with $TRAMPOLINE_FILE.\"\n        fi\n        exec sh -c \"exec $(cat \"$TRAMPOLINE_FILE\")\"\n    else\n        export TRAMPOLINE_FILE\n        \"$LEIN_JAVA_CMD\" \\\n            -Dfile.encoding=UTF-8 \\\n            -Dmaven.wagon.http.ssl.easy=false \\\n            $LEIN_JVM_OPTS \\\n            -Dleiningen.input-checksum=\"$INPUT_CHECKSUM\" \\\n            -Dleiningen.original.pwd=\"$ORIGINAL_PWD\" \\\n            -Dleiningen.script=\"$SCRIPT\" \\\n            -classpath \"$CLASSPATH\" \\\n            clojure.main -m leiningen.core.main \"$@\"\n\n        EXIT_CODE=$?\n\n        if $cygterm ; then\n          stty icanon echo > /dev/null 2>&1\n        fi\n\n        if [ -r \"$TRAMPOLINE_FILE\" ] && [ \"$LEIN_TRAMPOLINE_WARMUP\" = \"\" ]; then\n            TRAMPOLINE=\"$(cat \"$TRAMPOLINE_FILE\")\"\n            if [ \"$INPUT_CHECKSUM\" = \"\" ]; then # not using fast trampoline\n                rm \"$TRAMPOLINE_FILE\"\n            fi\n            if [ \"$TRAMPOLINE\" = \"\" ]; then\n                exit $EXIT_CODE\n            else\n                exec sh -c \"exec $TRAMPOLINE\"\n            fi\n        else\n            exit $EXIT_CODE\n        fi\n    fi\n}\n\n# cd to the project root, if applicable\nNOT_FOUND=1\nORIGINAL_PWD=\"$PWD\"\nwhile [ ! -r \"$PWD/project.clj\" ] && [ \"$PWD\" != \"/\" ] && [ $NOT_FOUND -ne 0 ]\ndo\n    cd ..\n    if [ \"$(dirname \"$PWD\")\" = \"/\" ]; then\n        NOT_FOUND=0\n        cd \"$ORIGINAL_PWD\"\n    fi\ndone\n\n# User init\nexport LEIN_HOME=\"${LEIN_HOME:-\"$HOME/.lein\"}\"\n\nfor f in \"/etc/leinrc\" \"$LEIN_HOME/leinrc\" \".leinrc\"; do\n  if [ -e \"$f\" ]; then\n    source \"$f\"\n  fi\ndone\n\nif $cygwin; then\n    export LEIN_HOME=$(cygpath -w \"$LEIN_HOME\")\nfi\n\n# normalize $0 on certain BSDs\nif [ \"$(dirname \"$0\")\" = \".\" ]; then\n    SCRIPT=\"$(which \"$(basename \"$0\")\")\"\n    if [ -z \"$SCRIPT\" ]; then\n        SCRIPT=\"$0\"\n    fi\nelse\n    SCRIPT=\"$0\"\nfi\n\n# resolve symlinks to the script itself portably\nwhile [ -h \"$SCRIPT\" ] ; do\n    ls=$(ls -ld \"$SCRIPT\")\n    link=$(expr \"$ls\" : '.*-> \\(.*\\)$')\n    if expr \"$link\" : '/.*' > /dev/null; then\n        SCRIPT=\"$link\"\n    else\n        SCRIPT=\"$(dirname \"$SCRIPT\"$)/$link\"\n    fi\ndone\n\nBIN_DIR=\"$(dirname \"$SCRIPT\")\"\n\n# If you're not using an uberjar you'll need to list each dependency\n# and add them individually to the classpath/bootclasspath as well.\n\nLEIN_JAR=/usr/share/java/leiningen-$LEIN_VERSION-standalone.jar\n\nexport LEIN_JVM_OPTS=\"${LEIN_JVM_OPTS-\"-XX:+TieredCompilation -XX:TieredStopAtLevel=1\"}\"\n\n# This needs to be defined before we call SHASUM_CMD below\nif [ \"$SHASUM_CMD\" = \"\" ]; then\n    if type -p sha256sum >/dev/null 2>&1; then\n        export SHASUM_CMD=\"sha256sum\"\n    elif type -p shasum >/dev/null 2>&1; then\n        export SHASUM_CMD=\"shasum --algorithm 256\"\n    elif type -p sha256 >/dev/null 2>&1; then\n        export SHASUM_CMD=\"sha256 -q\"\n    else\n        command_not_found sha256sum\n    fi\nfi\n\n# When :eval-in :classloader we need more memory\ngrep -E -q '^\\s*:eval-in\\s+:classloader\\s*$' project.clj 2> /dev/null && \\\n    export LEIN_JVM_OPTS=\"$LEIN_JVM_OPTS -Xms64m -Xmx512m\"\n\nrun_from_checkout \"$1\"\n\nif [ ! -x \"$JAVA_CMD\" ] && ! type -f java >/dev/null\nthen\n    msg \"Leiningen couldn't find 'java' executable, which is required.\"\n    msg \"Please either set JAVA_CMD or put java (>=1.6) in your \\$PATH ($PATH).\"\n    exit 1\nfi\n\nexport LEIN_JAVA_CMD=\"${LEIN_JAVA_CMD:-${JAVA_CMD:-java}}\"\n\nif [[ -z \"${DRIP_INIT+x}\" && \"$(basename \"$LEIN_JAVA_CMD\")\" == *drip* ]]; then\n    export DRIP_INIT=\"$(printf -- '-e\\n(require (quote leiningen.repl))')\"\n    export DRIP_INIT_CLASS=\"clojure.main\"\nfi\n\n# Support $JAVA_OPTS for backwards-compatibility.\nexport JVM_OPTS=\"${JVM_OPTS:-\"$JAVA_OPTS\"}\"\n\n# Handle jline issue with cygwin not propagating OSTYPE through java subprocesses: https://github.com/jline/jline2/issues/62\ncygterm=false\nif $cygwin; then\n  case \"$TERM\" in\n    rxvt* | xterm* | vt*) cygterm=true ;;\n  esac\nfi\n\nif $cygterm; then\n  LEIN_JVM_OPTS=\"$LEIN_JVM_OPTS -Djline.terminal=jline.UnixTerminal\"\n  stty -icanon min 1 -echo > /dev/null 2>&1\nfi\n\nif [ \"$1\" = \"upgrade\" ]; then\n    echo \"This version of Leiningen was installed with a package manager, but\"\n    echo \"the upgrade task is intended for manual installs. Please use your\"\n    echo \"package manager's built-in upgrade facilities instead.\"\n    exit 1\nfi\n\ncmd_run \"$@\"\n"
  },
  {
    "path": "bin/lein.bat",
    "content": "@echo off\r\n\r\nsetLocal EnableExtensions EnableDelayedExpansion\r\n\r\nset LEIN_VERSION=2.12.0\r\n\r\nif \"%LEIN_VERSION:~-9%\" == \"-SNAPSHOT\" (\r\n    set SNAPSHOT=YES\r\n) else (\r\n    set SNAPSHOT=NO\r\n)\r\n\r\nset ORIGINAL_PWD=%CD%\r\n:: If ORIGINAL_PWD ends with a backslash (such as C:\\),\r\n:: we need to escape it with a second backslash.\r\nif \"%ORIGINAL_PWD:~-1%x\" == \"\\x\" set \"ORIGINAL_PWD=%ORIGINAL_PWD%\\\"\r\n\r\ncall :FIND_DIR_CONTAINING_UPWARDS project.clj\r\nif \"%DIR_CONTAINING%\" neq \"\" cd \"%DIR_CONTAINING%\"\r\n\r\n:: LEIN_JAR and LEIN_HOME variables can be set manually.\r\n:: Only set LEIN_JAR manually if you know what you are doing.\r\n:: Having LEIN_JAR pointing to one version of Leiningen as well as\r\n:: having a different version in PATH has been known to cause problems.\r\n\r\nif \"x%LEIN_HOME%\" == \"x\" (\r\n    set LEIN_HOME=!USERPROFILE!\\.lein\r\n)\r\nSET RC=1\r\n\r\nif \"x%LEIN_JAR%\" == \"x\" set \"LEIN_JAR=!LEIN_HOME!\\self-installs\\leiningen-!LEIN_VERSION!-standalone.jar\"\r\n\r\nif \"%1\" == \"self-install\" goto SELF_INSTALL\r\nif \"%1\" == \"upgrade\"      goto UPGRADE\r\nif \"%1\" == \"downgrade\"    goto UPGRADE\r\n\r\nif not exist \"%~dp0..\\src\\leiningen\\version.clj\" goto RUN_NO_CHECKOUT\r\n\r\n    :: Running from source checkout.\r\n    call :SET_LEIN_ROOT \"%~dp0..\"\r\n\r\n\r\n\tset \"bootstrapfile=!LEIN_ROOT!\\leiningen-core\\.lein-bootstrap\"\r\n\trem in .lein-bootstrap there is only one line where each path is concatenated to each other via a semicolon, there's no semicolon at the end\r\n\trem each path is NOT inside double quotes and may contain spaces (even semicolons but this is not supported here) in their names, \r\n\trem  but they won't/cannot contain double quotes \" or colons :  in their names (at least on windows it's not allowed/won't work)\r\n\t\r\n\trem tested when folders contain spaces and when LEIN_ROOT contains semicolon\r\n\t\r\n\t\r\n\tif not \"x%DEBUG%\" == \"x\" echo LEIN_ROOT=!LEIN_ROOT!\r\n\t\r\n\trem if not \"%LEIN_ROOT:;=%\" == \"%LEIN_ROOT%\" (\r\n\r\n\t\r\n\trem oddly enough /G:/ should've worked but doesn't where / they say it's console\r\n\trem findstr is C:\\Windows\\System32\\findstr.exe\r\n\techo.!LEIN_ROOT! | findstr /C:\";\" >nul 2>&1 && (\r\n\t\trem aka errorlevel is 0 aka the string \";\" was found\r\n\t\techo Your folder structure !LEIN_ROOT! contains at least one semicolon in its name\r\n\t\techo This is not allowed and would break things with the generated bootstrap file\r\n\t\techo Please correct this by renaming the folders to not contain semicolons in their name\r\n\t\tdel !bootstrapfile! >nul 2>&1\r\n\t\techo You'll also have to recreate the bootstrap file just to be sure it has semicolon-free names inside\r\n\t\techo the bootstrap file ^(which was just deleted^) is: !bootstrapfile!\r\n\t\techo  and the info on how to do that is:\r\n\t\tgoto RUN_BOOTSTRAP\r\n\t)\r\n\r\n\tif not exist !bootstrapfile! goto NO_DEPENDENCIES\r\n\r\n\tfindstr \\^\" \"!bootstrapfile!\" >nul 2>&1\r\n\tif errorlevel 1 goto PARSE_BOOTSTRAPFILE\r\n\t\techo double quotes detected inside file: !bootstrapfile!\r\n\t\techo this should not be happening\r\n\t\tgoto RUN_BOOTSTRAP\r\n\r\n:PARSE_BOOTSTRAPFILE\r\nrem will proceed to set LEIN_LIBS and surround each path from bootstrap file in double quotes and separate it from others with a semicolon\r\nrem the paths inside the bootstrap file do not already contain double quotes but may contain spaces\r\n\trem note worthy: the following won't work due to a hard 1022bytes limit truncation in the variable that was set\r\n\trem set /p LEIN_LIBS=<!bootstrapfile!\r\n\trem so this will work instead:\r\n\trem for /f \"usebackq delims=\" %%j in (!bootstrapfile!) do set LEIN_LIBS=%%j\r\n\trem just  set LEIN_LIBS=\"%%j\"  is uglier/hacky but would also work here instead of the below:\r\n\tfor /f \"usebackq delims=\" %%j in (\"!bootstrapfile!\") do (\r\n\t\tset tmpline=%%j\r\n\t\tcall :PROCESSPATH\r\n\t)\r\n\r\n\trem remove trailing semicolon, if any\r\n\tif \"!LEIN_LIBS:~-1!x\" == \";x\" SET LEIN_LIBS=!LEIN_LIBS:~0,-1!\r\n\tif not \"x%DEBUG%\" == \"x\" echo LEIN_LIBS=!LEIN_LIBS!\r\n\r\n    if \"x!LEIN_LIBS!\" == \"x\" goto NO_DEPENDENCIES\r\n\r\n\r\n\trem semicolons in pathes are not supported, spaces are supported by quoting CLASSPATH as a whole\r\n\trem (no end semicolon required)\r\n    set CLASSPATH=!LEIN_LIBS!;!LEIN_ROOT!\\src;!LEIN_ROOT!\\resources\r\n\r\n    :: Apply context specific CLASSPATH entries\r\n    if exist \"%~dp0..\\.lein-classpath\" (\r\n        for /f \"tokens=* delims= \" %%i in (\"%~dp0..\\.lein-classpath\") do (\r\n            set CONTEXT_CP=%%i\r\n        )\r\n\r\n        if NOT \"x!CONTEXT_CP!\"==\"x\" (\r\n            set CLASSPATH=!CONTEXT_CP!;!CLASSPATH!\r\n        )\r\n    )\r\n    goto SETUP_JAVA\r\n\r\n:RUN_NO_CHECKOUT\r\n\r\n    :: Not running from a checkout.\r\n    if not exist \"%LEIN_JAR%\" goto NO_LEIN_JAR\r\n    set CLASSPATH=%LEIN_JAR%\r\n  \r\n    if exist \".lein-classpath\" (\r\n        for /f \"tokens=* delims= \" %%i in (.lein-classpath) do (\r\n            set CONTEXT_CP=%%i\r\n        )\r\n\r\n        if NOT \"x!CONTEXT_CP!\"==\"x\" (\r\n            set CLASSPATH=!CONTEXT_CP!;!CLASSPATH!\r\n        )\r\n    )\r\n\r\n:SETUP_JAVA\r\n\r\nif not \"x%DEBUG%\" == \"x\" echo CLASSPATH=!CLASSPATH!\r\n:: ##################################################\r\n\r\nif \"x!JAVA_CMD!\" == \"x\" set JAVA_CMD=java\r\nif \"x!LEIN_JAVA_CMD!\" == \"x\" set LEIN_JAVA_CMD=%JAVA_CMD%\r\n\r\nrem remove quotes from around java commands\r\nfor /f \"usebackq delims=\" %%i in ('!JAVA_CMD!') do set JAVA_CMD=%%~i\r\nfor /f \"usebackq delims=\" %%i in ('!LEIN_JAVA_CMD!') do set LEIN_JAVA_CMD=%%~i\r\n\r\nif \"x%JVM_OPTS%\" == \"x\" set JVM_OPTS=%JAVA_OPTS%\r\ngoto RUN\r\n\r\n:DownloadFile\r\nset LAST_HTTP_CLIENT=\r\nrem parameters: TargetFileName Address\r\nif \"x%HTTP_CLIENT%\" == \"x\" goto TRY_POWERSHELL\r\n    %HTTP_CLIENT% %1 %2\r\n    SET RC=%ERRORLEVEL%\r\n    goto EXITRC\r\n\r\n:TRY_POWERSHELL\r\ncall powershell -? >nul 2>&1\r\nif NOT ERRORLEVEL 0 goto TRY_WGET\r\n    set LAST_HTTP_CLIENT=powershell\r\n    rem By default: Win7 = PS2, Win 8.0 = PS3 (maybe?), Win 8.1 = PS4, Win10 = PS5\r\n    powershell -Command \"& {param($a,$f) if (($PSVersionTable.PSVersion | Select-Object -ExpandProperty Major) -lt 4) { exit 111; } else { $client = New-Object System.Net.WebClient; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $client.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; $client.DownloadFile($a, $f); }}\" \"\"%2\"\" \"\"%1\"\"\r\n    SET RC=%ERRORLEVEL%\r\n    goto EXITRC\r\n\r\n:TRY_WGET\r\ncall wget --help >nul 2>&1\r\nif NOT ERRORLEVEL 0 goto TRY_CURL\r\n    set LAST_HTTP_CLIENT=wget\r\n    call wget -O %1 %2\r\n    SET RC=%ERRORLEVEL%\r\n    goto EXITRC\r\n\r\n:TRY_CURL\r\ncall curl --help >nul 2>&1\r\nif NOT ERRORLEVEL 0 GOTO NO_HTTP_CLIENT\r\n    rem We set CURL_PROXY to a space character below to pose as a no-op argument\r\n    set LAST_HTTP_CLIENT=curl\r\n    set CURL_PROXY= \r\n    if NOT \"x%HTTPS_PROXY%\" == \"x\" set CURL_PROXY=\"-x %HTTPS_PROXY%\"\r\n    call curl %CURL_PROXY% -f -L -o  %1 %2\r\n    SET RC=%ERRORLEVEL%\r\n    goto EXITRC\r\n\r\n:NO_LEIN_JAR\r\necho.\r\necho %LEIN_JAR% can not be found.\r\necho You can try running \"lein self-install\"\r\necho or change LEIN_JAR environment variable\r\necho or edit lein.bat to set appropriate LEIN_JAR path.\r\necho.\r\ngoto EXITRC\r\n\r\n:NO_DEPENDENCIES\r\necho.\r\necho Leiningen is missing its dependencies.\r\n:RUN_BOOTSTRAP\r\necho Please run \"lein bootstrap\" in the leiningen-core/ directory\r\necho with a stable release of Leiningen. See CONTRIBUTING.md for details.\r\necho.\r\ngoto EXITRC\r\n\r\n:SELF_INSTALL\r\nif exist \"%LEIN_JAR%\" (\r\n    echo %LEIN_JAR% already exists. Delete and retry.\r\n    goto EXITRC\r\n)\r\n\r\nfor %%f in (\"%LEIN_JAR%\") do set LEIN_INSTALL_DIR=\"%%~dpf\"\r\nif not exist %LEIN_INSTALL_DIR% mkdir %LEIN_INSTALL_DIR%\r\n\r\necho Downloading Leiningen now...\r\n\r\nset LEIN_JAR_URL=https://github.com/technomancy/leiningen/releases/download/%LEIN_VERSION%/leiningen-%LEIN_VERSION%-standalone.jar\r\ncall :DownloadFile \"%LEIN_JAR%.pending\" \"%LEIN_JAR_URL%\"\r\nSET RC=%ERRORLEVEL%\r\nif not %RC% == 0 goto DOWNLOAD_FAILED\r\nif not exist \"%LEIN_JAR%.pending\" goto DOWNLOAD_FAILED\r\nmove /y \"%LEIN_JAR%.pending\" \"%LEIN_JAR%\" >nul 2>&1\r\nSET RC=%ERRORLEVEL%\r\ngoto EXITRC\r\n\r\n:DOWNLOAD_FAILED\r\nSET RC=3\r\nif \"%ERRORLEVEL%\" == \"111\" (\r\n    echo.\r\n    echo You seem to be using an old version of PowerShell that\r\n    echo can't download files via TLS 1.2.\r\n    echo Please upgrade your PowerShell to at least version 4.0, e.g. via\r\n    echo https://www.microsoft.com/en-us/download/details.aspx?id=50395\r\n    echo.\r\n    echo Alternatively you can manually download\r\n    echo %LEIN_JAR_URL%\r\n    echo and save it as\r\n    echo %LEIN_JAR%\r\n    echo.\r\n    echo If you have \"curl\" or \"wget\" you can try setting the HTTP_CLIENT\r\n    echo variable, but the TLS problem might still persist.\r\n    echo.\r\n    echo   a^) set HTTP_CLIENT=wget -O\r\n    echo   b^) set HTTP_CLIENT=curl -f -L -o\r\n    echo.\r\n    echo NOTE: Make sure to *not* add double quotes when setting the value\r\n    echo       of HTTP_CLIENT\r\n    goto EXITRC\r\n)\r\nSET RC=3\r\ndel \"%LEIN_JAR%.pending\" >nul 2>&1\r\necho.\r\necho Failed to download %LEIN_JAR_URL%\r\necho.\r\necho It is possible that the download failed due to \"powershell\", \r\necho \"curl\" or \"wget\"'s inability to retrieve GitHub's security certificate.\r\necho.\r\n\r\nif \"%LAST_HTTP_CLIENT%\" == \"powershell\" (\r\n  echo The PowerShell failed to download the latest Leiningen version.\r\n  echo Try to use \"curl\" or \"wget\" to download Leiningen by setting up\r\n  echo the HTTP_CLIENT environment variable with one of the following \r\n  echo values:\r\n  echo.\r\n  echo   a^) set HTTP_CLIENT=wget -O\r\n  echo   b^) set HTTP_CLIENT=curl -f -L -o\r\n  echo.\r\n  echo NOTE: Make sure to *not* add double quotes when setting the value\r\n  echo       of HTTP_CLIENT\r\n)\r\n\r\nif \"%LAST_HTTP_CLIENT%\" == \"curl\" (\r\n  echo Curl failed to download the latest Leiningen version.\r\n  echo Try to use \"wget\" to download Leiningen by setting up\r\n  echo the HTTP_CLIENT environment variable with one of the following \r\n  echo values:\r\n  echo.\r\n  echo   a^) set HTTP_CLIENT=wget -O\r\n  echo.\r\n  echo NOTE: Make sure to *not* add double quotes when setting the value\r\n  echo       of HTTP_CLIENT\r\n  echo. \r\n  echo If neither curl nor wget can download Leiningen, please seek\r\n  echo for help on Leiningen's GitHub project issues page.\r\n)\r\n\r\nif \"%LAST_HTTP_CLIENT%\" == \"wget\" (\r\n  echo Curl failed to download the latest Leiningen version.\r\n  echo Try to use \"wget\" to download Leiningen by setting up\r\n  echo the HTTP_CLIENT environment variable with one of the following \r\n  echo values:\r\n  echo.\r\n  echo.   a^) set HTTP_CLIENT=curl -f -L -o\r\n  echo.\r\n  echo NOTE: make sure *not* to add double quotes to set the value of \r\n  echo       HTTP_CLIENT\r\n  echo. \r\n  echo If neither curl nor wget can download Leiningen, please seek\r\n  echo for help on Leiningen's GitHub project issues page.\r\n)\r\n\r\nif %SNAPSHOT% == YES echo See README.md for SNAPSHOT build instructions.\r\necho.\r\ngoto EOF\r\n\r\n\r\n:UPGRADE\r\nset LEIN_BAT=%~dp0%~nx0\r\nset TARGET_VERSION=%2\r\nif \"x%2\" == \"x\" set TARGET_VERSION=stable\r\necho The script at %LEIN_BAT% will be upgraded to the latest %TARGET_VERSION% version.\r\nset /P ANSWER=Do you want to continue (Y/N)?\r\nif /i {%ANSWER%}=={y}   goto YES_UPGRADE\r\nif /i {%ANSWER%}=={yes} goto YES_UPGRADE\r\necho Aborted.\r\ngoto EXITRC\r\n\r\n\r\n:YES_UPGRADE\r\necho Downloading latest Leiningen batch script...\r\n\r\nset LEIN_BAT_URL=https://github.com/technomancy/leiningen/raw/%TARGET_VERSION%/bin/lein.bat\r\nset TEMP_BAT=%~dp0temp-lein-%RANDOM%%RANDOM%.bat\r\ncall :DownloadFile \"%LEIN_BAT%.pending\" \"%LEIN_BAT_URL%\"\r\nif ERRORLEVEL 0 goto EXEC_UPGRADE\r\n    del \"%LEIN_BAT%.pending\" >nul 2>&1\r\n    echo Failed to download %LEIN_BAT_URL%\r\n    goto EXITRC\r\n:EXEC_UPGRADE\r\nmove /y \"%LEIN_BAT%.pending\" \"%TEMP_BAT%\" >nul 2>&1\r\necho.\r\necho Upgrading...\r\nset LEIN_JAR=\r\ncall \"%TEMP_BAT%\" self-install\r\n(\r\n   rem This is self-modifying batch code. Use brackets to pre-load the exit command.\r\n   rem This way, script execution does not depend on whether the replacement script\r\n   rem has that command at the *very same* file position as the calling batch file.\r\n   move /y \"%TEMP_BAT%\" \"%LEIN_BAT%\" >nul 2>&1\r\n   exit /B %ERRORLEVEL%\r\n)\r\n\r\n:NO_HTTP_CLIENT\r\necho.\r\necho ERROR: Neither PowerShell, Wget, or Curl could be found.\r\necho        Make sure at least one of these tools is installed\r\necho        and is in PATH. You can get them from URLs below:\r\necho.\r\necho PowerShell: \"http://www.microsoft.com/powershell\"\r\n\r\nrem echo Wget:       \"http://users.ugent.be/~bpuype/wget/\"\r\nrem Note: Stale URL. HTTP 404.\r\nrem Alternative: wget64.exe compiled by J. Simoncic, rename to wget.exe\r\nrem MD5 1750c130c5daca8b347d3f7e34824c9b\r\nrem Check: https://www.virustotal.com/en/file/abf507f8240ed41aac74c9df6de558c88c2f11d7770f02.8.4-SNAPSHOT5f1cc544b9c08b/analysis/\r\necho Wget:       \"https://eternallybored.org/misc/wget/\"\r\n\r\necho Curl:       \"http://curl.haxx.se/dlwiz/?type=bin&os=Win32&flav=-&ver=2000/XP\"\r\necho.\r\ngoto EXITRC\r\n\r\n\r\n:SET_LEIN_ROOT\r\nset LEIN_ROOT=%~f1\r\ngoto EOF\r\n\r\n:: Find directory containing filename supplied in first argument\r\n:: looking in current directory, and looking up the parent\r\n:: chain until we find it, or run out\r\n:: returns result in %DIR_CONTAINING%\r\n:: empty string if we don't find it\r\n:FIND_DIR_CONTAINING_UPWARDS\r\nset DIR_CONTAINING=%CD%\r\nset LAST_DIR=\r\n\r\n:LOOK_AGAIN\r\nif \"%DIR_CONTAINING%\" == \"%LAST_DIR%\" (\r\n    :: didn't find it\r\n    set DIR_CONTAINING=\r\n    goto EOF\r\n)\r\n\r\nif EXIST \"%DIR_CONTAINING%\\%1\" (\r\n    :: found it - use result in DIR_CONTAINING\r\n    goto EOF\r\n)\r\n\r\nset LAST_DIR=%DIR_CONTAINING%\r\ncall :GET_PARENT_PATH \"%DIR_CONTAINING%\\..\"\r\nset DIR_CONTAINING=%PARENT_PATH%\r\ngoto LOOK_AGAIN\r\n\r\n:GET_PARENT_PATH\r\nset PARENT_PATH=%~f1\r\ngoto EOF\r\n\r\n\r\n:RUN\r\n:: We need to disable delayed expansion here because the %* variable\r\n:: may contain bangs (as in test!). There may also be special\r\n:: characters inside the TRAMPOLINE_FILE.\r\nsetLocal DisableDelayedExpansion\r\n\r\nset \"TRAMPOLINE_FILE=%TEMP%\\lein-trampoline-%RANDOM%.bat\"\r\ndel \"%TRAMPOLINE_FILE%\" >nul 2>&1\r\n\r\nset ERRORLEVEL=\r\nset RC=0\r\n\"%LEIN_JAVA_CMD%\" -client %LEIN_JVM_OPTS% ^\r\n -Dfile.encoding=UTF-8 ^\r\n -Dclojure.compile.path=\"%DIR_CONTAINING%/target/classes\" ^\r\n -Dleiningen.original.pwd=\"%ORIGINAL_PWD%\" ^\r\n -cp \"%CLASSPATH%\" clojure.main -m leiningen.core.main %*\r\nSET RC=%ERRORLEVEL%\r\nif not %RC% == 0 goto EXITRC\r\n\r\nif not exist \"%TRAMPOLINE_FILE%\" goto EOF\r\ncall \"%TRAMPOLINE_FILE%\"\r\ndel \"%TRAMPOLINE_FILE%\" >nul 2>&1\r\ngoto EOF\r\n\r\n\r\n:PROCESSPATH\r\nrem will surround each path with double quotes before appending it to LEIN_LIBS\r\n\tfor /f \"tokens=1* delims=;\" %%a in (\"%tmpline%\") do (\r\n\t\tset LEIN_LIBS=!LEIN_LIBS!\"%%a\";\r\n\t\tset tmpline=%%b\r\n\t)\r\n\tif not \"%tmpline%\" == \"\" goto PROCESSPATH\r\n\tgoto EOF\r\n\r\n:EXITRC\r\nexit /B %RC%\r\n\r\n:EOF\r\n\r\n"
  },
  {
    "path": "bin/lein.cmd",
    "content": "@echo off\r\nsetlocal\r\nset ps1=%~dpn0.ps1\r\nshift\r\npowershell -NoProfile -ExecutionPolicy Bypass -File \"%ps1%\" %*\r\n"
  },
  {
    "path": "bin/lein.ps1",
    "content": "﻿<#\r\n.Synopsis\r\n    Leiningen bootstrap.\r\n\r\n.Parameter Command\r\n    The command to pass to leiningen.\r\n\r\n.Notes\r\n    This is a very literal port of lein.bat to PowerShell.\r\n\r\n    TODO:\r\n    - Determine which (if any) environment variables are used from within Leiningen/Clojure\r\n      and convert the rest to local- or script-scoped variables.\r\n    - Probably should parse the version from the newest .jar filename, rather than hard-code\r\n      it and search for the .jar file from it.\r\n    - Further reduce/simplify/refactor away from batch-file idioms toward idiomatic PowerShell.\r\n\r\n.Link\r\n    https://leiningen.org/\r\n#>\r\n\r\n#require -version 3\r\n[CmdletBinding(SupportsShouldProcess=$true)] Param(\r\n[Parameter(Position=0,ValueFromRemainingArguments=$true)][string[]]$Command = 'help'\r\n)\r\n\r\nfunction Set-ParentLocation([string]$file)\r\n{\r\n    for($dir = [IO.DirectoryInfo]\"$PWD\"; $dir.Parent; $dir = $dir.Parent)\r\n    {\r\n        if(Test-Path (Join-Path $dir.FullName $file) -PathType Leaf) { cd $dir.FullName; break }\r\n    }\r\n}\r\n\r\nfunction Initialize-Environment\r\n{\r\n    $env:LEIN_VERSION = '2.12.0'\r\n    $env:SNAPSHOT = if($env:LEIN_VERSION -like '*-SNAPSHOT'){'YES'}else{'NO'} #TODO: Still needed?\r\n    $env:ORIGINAL_PWD = $PWD -replace '\\\\$','\\\\'\r\n    Set-ParentLocation project.clj\r\n    if(!$env:LEIN_HOME) {$env:LEIN_HOME = \"$env:USERPROFILE\\.lein\"}\r\n    if(!$env:LEIN_JAR) {$env:LEIN_JAR = \"$env:LEIN_HOME\\self-installs\\leiningen-$env:LEIN_VERSION-standalone.jar\"}\r\n    if($PSVersionTable.PSVersion.Major -gt 5) {\r\n        if(!($([System.Net.WebProxy]::new()).IsBypassed('https://github.com/')))\r\n        {\r\n            $proxy = $([System.Net.WebProxy]::new()).GetProxy('https://github.com/')\r\n            Write-Verbose \"Using proxy: $proxy\"\r\n            $Script:PSBoundParameters = @{\r\n                'Invoke-WebRequest:Proxy' = $proxy\r\n                'Invoke-WebRequest:ProxyUseDefaultCredentials' = $true\r\n            }\r\n        }\r\n    } else {\r\n        if(!([Net.WebRequest]::DefaultWebProxy.IsBypassed('https://github.com/')))\r\n        {\r\n            $proxy = [Net.WebRequest]::DefaultWebProxy.GetProxy('https://github.com/')\r\n            Write-Verbose \"Using proxy: $proxy\"\r\n            $Script:PSBoundParameters = @{\r\n                'Invoke-WebRequest:Proxy' = $proxy\r\n                'Invoke-WebRequest:ProxyUseDefaultCredentials' = $true\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nfunction Use-ClassPath([string]$Value)\r\n{\r\n    $env:CLASSPATH =\r\n        if(!(Test-Path .lein-classpath -PathType Leaf)) {$Value}\r\n        else {\"$(gc .lein-classpath |? {$_} |select -Last 1);$Value\"}\r\n}\r\n\r\nfunction Initialize-Binary\r\n{\r\n    if(!(Test-Path $env:LEIN_JAR -PathType Leaf))\r\n    {throw \"$env:LEIN_JAR cannot be found. Try running 'lein self-install' or change the LEIN_JAR environment variable.\"}\r\n    Use-ClassPath $env:LEIN_JAR\r\n}\r\n\r\nfunction Initialize-Source\r\n{\r\n    $env:LEIN_ROOT = $PSScriptRoot\r\n    $env:bootstrapfile = \"$env:LEIN_ROOT\\leiningen-core\\.lein-bootstrap\"\r\n    Write-Verbose \"LEIN_ROOT=$env:LEIN_ROOT\"\r\n    if($env:bootstrapfile -like '*;*') #TODO: Still important?\r\n    {throw \"bootstrap file ($env:bootstrapfile) should not contain semicolons!\"}\r\n    if(!(Test-Path $env:bootstrapfile -PathType Leaf)) \r\n    {throw @'\r\nLeiningen is missing its dependencies. Run 'lein bootstrap' in the leiningen-core/ directory with a stable release.\r\nSee CONTRIBUTING.md for details.\r\n'@}\r\n    if((Get-Content $env:bootstrapfile -raw) -like '*\"*')\r\n    {throw \"Double quotes detected inside bootstrap file $env:bootstrapfile!?\"}\r\n    $env:LEIN_LIBS = (Get-Content $env:bootstrapfile |% {$_ -split ';'} |% {\"$_\"}) -join ';'\r\n    Write-Verbose \"LEIN_LIBS=$env:LEIN_LIBS\"\r\n    Use-ClassPath \"$env:LEIN_LIBS;$env:LEIN_ROOT\\src;$env:LEIN_ROOT\\resources\"\r\n}\r\n\r\nfunction Install-Self\r\n{\r\n    if(Test-Path $env:LEIN_JAR -PathType Leaf) {throw \"$env:LEIN_JAR already exists. Delete and retry.\"}\r\n    $jardir = ([IO.FileInfo]$env:LEIN_JAR).Directory.FullName\r\n    if(!(Test-Path $jardir -PathType Container)) {mkdir $jardir |Out-Null}\r\n    @{ # splatting Invoke-WebRequest due to long URI\r\n        Uri = \"https://github.com/technomancy/leiningen/releases/download/$env:LEIN_VERSION/leiningen-$env:LEIN_VERSION-standalone.jar\"\r\n        OutFile = $env:LEIN_JAR\r\n    } |% {Write-Progress 'Install-Self' $_.Uri -CurrentOperation \"Downloading to $env:LEIN_JAR\" ; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest @_}\r\n    Write-Progress 'Install-Self' -Completed\r\n}\r\n\r\nfunction Update-Self\r\n{\r\n    $targetVersion = if($Command.Length -gt 1) {$Command[1]} else {'stable'}\r\n    if(!$PSCmdlet.ShouldProcess($PSCommandPath,\"upgrade to $targetVersion\")) {throw 'Cancelled'}\r\n    @{ # splatting Invoke-WebRequest due to long URI\r\n        Uri = \"https://github.com/technomancy/leiningen/raw/$targetVersion/bin/lein.cmd\"\r\n        OutFile = \"$PSScriptRoot\\lein.cmd.pending\"\r\n    } |% {Write-Progress 'Update-Self' $_.Uri -CurrentOperation \"Downloading to $PSScriptRoot\\lein.cmd.pending\" ; Invoke-WebRequest @_}\r\n    @{ # splatting Invoke-WebRequest due to long URI\r\n        Uri = \"https://github.com/technomancy/leiningen/raw/$targetVersion/bin/lein.ps1\"\r\n        OutFile = \"$PSCommandPath.pending\"\r\n    } |% {Write-Progress 'Update-Self' $_.Uri -CurrentOperation \"Downloading to $PSCommandPath.pending\" -PercentComplete 50 ; Invoke-WebRequest @_}\r\n    Write-Progress 'Update-Self' -Completed\r\n    Move-Item \"$PSScriptRoot\\lein.cmd.pending\" \"$PSScriptRoot\\lein.cmd\" -force\r\n    Move-Item \"$PSCommandPath.pending\" \"$PSCommandPath\" -force\r\n    . \"$PSCommandPath\" self-install\r\n}\r\n\r\nfunction Invoke-Java\r\n{\r\n    Write-Verbose \"CLASSPATH=$env:CLASSPATH\"\r\n    $env:JAVA_CMD = if($env:JAVA_CMD){$env:JAVA_CMD -replace '\\A\"|\"\\Z',''}else{'java'}\r\n    $env:LEIN_JAVA_CMD = if($env:LEIN_JAVA_CMD){$env:LEIN_JAVA_CMD -replace '\\A\"|\"\\Z',''}else{$env:JAVA_CMD}\r\n    if(!$env:JVM_OPTS){$env:JVM_OPTS = $env:JAVA_OPTS}\r\n    $JavaArgs = @(\r\n        '-client',$env:LEIN_JVM_OPTS,\r\n        '-Dfile.encoding=UTF-8',\r\n        \"`\"-Dclojure.compile.path=$PWD/target/classes`\"\", #TODO: Add this line only when we're initializing from source\r\n        \"`\"-Dleiningen.original.pwd=$env:ORIGINAL_PWD`\"\",\r\n        '-cp',$env:CLASSPATH,\r\n        'clojure.main',\r\n        '-m','leiningen.core.main'\r\n    )\r\n    &$env:LEIN_JAVA_CMD @JavaArgs @Command\r\n}\r\n\r\nfunction Invoke-Leiningen\r\n{\r\n    Initialize-Environment\r\n    switch($Command[0])\r\n    {\r\n        self-install {Install-Self}\r\n        upgrade      {Update-Self }\r\n        downgrade    {Update-Self }\r\n        default\r\n        {\r\n            if(Test-Path \"$PSCommandPath\\..\\src\\leiningen\\version.clj\" -PathType Leaf) {Initialize-Source}\r\n            else {Initialize-Binary}\r\n            Invoke-Java\r\n        }\r\n    }\r\n}\r\n\r\nInvoke-Leiningen\r\n"
  },
  {
    "path": "bin/release",
    "content": "#!/bin/bash\n\nif [ \"$1\" = \"\" ]; then\n    echo \"usage: $0 VERSION\"\n    exit 1\nfi\n\nRELEASE_VERSION=$1\nCURRENT_VERSION=\"$RELEASE_VERSION-SNAPSHOT\"\n\nif [ \"$LEIN_STABLE\" = \"\" ]; then\n    LEIN_STABLE=/usr/bin/lein\nfi\n\nset -e -u\n\n# Would like to use `lein release` here, but we don't have a way to\n# update the bash scripts or watch for boot slowdowns that way. Maybe\n# try adding lein-shell?\n\nif [ ! -x `which $LEIN_STABLE` ]; then\n    echo \"Install a stable version of Leiningen as $LEIN_STABLE.\"\n    exit 1\nfi\n\ngrep $RELEASE_VERSION NEWS.md || (echo \"Add $RELEASE_VERSION to NEWS.md\" && exit 1)\n\nlein vcs assert-committed\n\nfor f in bin/lein bin/lein-pkg bin/lein.bat bin/lein.ps1 project.clj leiningen-core/project.clj; do\n    sed -i s/$CURRENT_VERSION/$RELEASE_VERSION/ $f\ndone\n\nrm -rf target classes leiningen-core/target leiningen-core/classes leiningen-core/lib\nrm -rf $HOME/.lein/self-installs/leiningen-$RELEASE_VERSION-standalone.jar\n\nLEIN_ROOT=$PWD\n\necho \"Bootstrapping...\"\ncd leiningen-core\n$LEIN_STABLE do clean, bootstrap\ncd ..\n\necho \"Generating uberjar...\"\n\nbin/lein uberjar\nRELEASE_JAR=$PWD/target/leiningen-$RELEASE_VERSION-standalone.jar\nRELEASE_JAR_CHECKSUM=\"$(sha256sum $RELEASE_JAR | awk '{ print $1 }')\"\nSELF_INSTALL_JAR=$HOME/.lein/self-installs/$(basename $RELEASE_JAR)\nmkdir -p $HOME/.lein/self-installs\ncp $RELEASE_JAR $SELF_INSTALL_JAR\n\nsed -i \"s/export LEIN_CHECKSUM=.*/export LEIN_CHECKSUM='$RELEASE_JAR_CHECKSUM'/\" bin/lein\ncp bin/lein /tmp/lein-$RELEASE_VERSION\ncd /tmp\n\nif [ ! -r test-project ]; then\n    ./lein-$RELEASE_VERSION new test-project\nfi\n\ncd test-project\n\necho \"Running a few invocations in order to check boot time...\"\n\ntime ../lein-$RELEASE_VERSION run -m clojure.main/main -e nil\ntime ../lein-$RELEASE_VERSION run -m clojure.main/main -e nil\ntime ../lein-$RELEASE_VERSION run -m clojure.main/main -e nil\n\necho \"Check that these are about the same boot times as with the last version.\"\necho \"Run this in a project: time $LEIN_STABLE run -m clojure.main/main -e nil\"\necho \"Proceeding here will publish the new version to the git repo.\"\necho \"Are these acceptable times? (~3s) [Y\\n]\"\nread CONTINUE\ncase \"$CONTINUE\" in\n    y|Y|\"\")\n        gpg -ab $RELEASE_JAR;;\n    *)\n        echo \"Aborted.\"\n        exit 1;;\nesac\n\ncd $LEIN_ROOT\n\ngit commit -a -m \"Release $RELEASE_VERSION\"\ngit tag -s $RELEASE_VERSION -m \"Release $RELEASE_VERSION\"\ngit push && git push --tags && git push origin main:stable\n\necho \"Upload to Codeberg and Github:\"\necho \"    $SELF_INSTALL_JAR\"\necho \"    $SELF_INSTALL_JAR.asc\"\necho\necho \"https://codeberg.org/leiningen/leiningen/releases/new?tag=$RELEASE_VERSION\"\necho \"https://github.com/technomancy/leiningen/releases/new?tag=$RELEASE_VERSION\"\necho \"Copy this version's section of NEWS.md to the release description.\"\n\nrm -rf target leiningen-core/target\necho \"Test self-install. If things are good, run this:\"\necho \"    lein deploy clojars && cd leiningen-core && lein deploy clojars\"\necho \"\"\necho \"Then run: bin/bump $RELEASE_VERSION NEXT_VERSION-SNAPSHOT\"\n"
  },
  {
    "path": "doc/BEGINNER_MISTAKES.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [BEGINNER_MISTAKES](#beginner_mistakes)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# Beginner Mistakes\n\n**Q:** When I have no `project.clj` the command `lein repl` works, but I\n       added one and now `lein repl` crashes with:\n```\nError: Could not find or load main class clojure.main\nCaused by: java.lang.ClassNotFoundException: clojure.main\nSubprocess failed (exit code: 1)\n```\n**A:** When you don't have a `project.clj` Leiningen automatically includes\n      the core Clojure language for you.  When you add a `project.clj`,\n      Leiningen expects you to specify which version of Clojure you'll\n      use. If you're just experimenting with Clojure, remove `project.clj`.\n      Otherwise, make sure your `project.clj` has a `:dependencies` section\n      with at least `[org.clojure/clojure \"1.11.1\"]` in it. (Change the version\n      from `1.11.1` as necessary.)\n\n"
  },
  {
    "path": "doc/DEPLOY.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Deploying Libraries](#deploying-libraries)\n  - [Private Repositories](#private-repositories)\n    - [Static HTTP](#static-http)\n    - [SCP](#scp)\n    - [S3](#s3)\n    - [Artifactory/Nexus/Archiva](#artifactorynexusarchiva)\n    - [Other Non-standard Repository Protocols](#other-non-standard-repository-protocols)\n  - [Authentication](#authentication)\n    - [GPG](#gpg)\n    - [Full-disk Encryption](#full-disk-encryption)\n    - [Credentials in the Environment](#credentials-in-the-environment)\n  - [Deployment](#deployment)\n  - [Releasing Simplified](#releasing-simplified)\n    - [Overriding the default `:release-tasks`](#overriding-the-default-release-tasks)\n    - [Tagging](#tagging)\n  - [Deploying to Maven Central](#deploying-to-maven-central)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# Deploying Libraries\n\nGetting your library into [Clojars](https://clojars.org) is fairly\nstraightforward as is documented near the end of\n[the Leiningen tutorial](https://codeberg.org/leiningen/leiningen/src/stable/doc/TUTORIAL.md).\nHowever, deploying elsewhere is not always that straightforward.\n\n## Private Repositories\n\nThere may be times when you want to make a library available to your\nteam without making it public. This is best done by setting up a\nprivate repository. There are several types of repositories.\n\n### Static HTTP\n\nThe simplest kind of private repository is a web server pointed at a\ndirectory full of static files. You can use a `file:///` URL in your\n`:repositories` to deploy that way if the directory is local to the\nmachine on which Leiningen is running.\n\n### SCP\n\nIf you already have a server set up with your SSH public keys, the\n`scp` transport is a simple way to publish and consume private\ndependencies. Place the following inside `defproject`:\n\n```clj\n:plugins [[org.apache.maven.wagon/wagon-ssh-external \"2.6\"]]\n:repositories [[\"releases\" \"scp://somerepo.com/home/repo/\"]]\n```\n\nThen place the following outside the `defproject`:\n\n```clj\n(cemerick.pomegranate.aether/register-wagon-factory!\n \"scp\" #(let [c (resolve 'org.apache.maven.wagon.providers.ssh.external.ScpExternalWagon)]\n          (clojure.lang.Reflector/invokeConstructor c (into-array []))))\n```\n\nIt's also possible to deploy to a repository using the `scp` transport\nand consume from it over `http` if you set up nginx or something\nsimilar to serve the repository directory over HTTP.\n\nN.B. SCP deploys to Clojars are no longer supported.\n\n### S3\n\nIf you don't already have a server running,\n[Amazon S3](https://aws.amazon.com/s3/) is a low-maintenance choice;\nyou can deploy to S3 buckets using the\n[S3 wagon private](https://github.com/s3-wagon-private/s3-wagon-private) plugin.\n\n### Artifactory/Nexus/Archiva\n\nThe most full-featured and complex route is to run a full-fledged\nrepository manager. Both [Artifactory](https://www.jfrog.com/open-source/#os-arti), [Archiva](https://archiva.apache.org/) and\n[Nexus](https://nexus.sonatype.org/) provide this. They also proxy to\nother repositories, so you can set `^:replace` metadata on\n`:repositories` in project.clj, and dependency downloads will speed up\nby quite a bit since Clojars and Maven Central won't need to be\nchecked.\n\nThe private server will need to be added to the `:repositories`\nlisting in project.clj. Artifactory, Archiva and Nexus offer separate repositories\nfor snapshots and releases, so you'll want two entries for them:\n\n```clj\n:repositories [[\"snapshots\" \"https://blueant.com/archiva/snapshots\"]\n               [\"releases\" \"https://blueant.com/archiva/internal\"]]\n```\n\nIf you are deploying to a repository that is _only_ used for deployment\nand never for dependency resolution, then it should be specified in a\n`:deploy-repositories` slot instead of included in the more general-purpose\n`:repositories` map; the former is checked by `lein deploy` before the latter.\nDeployment-only repositories useful across a number of locally developed\nprojects may also be specified in the `:user` profile in `~/.lein/profiles.clj`:\n\n```clj\n{:user {:deploy-repositories [[\"internal\" \"https://blueant.com/archiva/internal\"]]}}\n```\n\n### Other Non-standard Repository Protocols\n\nIf you are deploying to a repository that doesn't use one of the\nstandard protocols (`file:` or `https:`), you may need to\nprovide a wagon factory for that protocol. You can do so by specifying\nthe wagon provider as a plugin dependency:\n\n```clj\n:plugins [[org.apache.maven.wagon/wagon-webdav-jackrabbit \"2.4\"]]\n```\n\nthen registering a wagon factory function at the bottom of your project.clj:\n\n```clj\n(cemerick.pomegranate.aether/register-wagon-factory! \"dav\"\n  #(eval '(org.apache.maven.wagon.providers.webdav.WebDavWagon.)))\n```\n\nThis step is unnecessary for plugins that include explicit Leiningen\nsupport like\n[S3 wagon private](https://github.com/technomancy/s3-wagon-private)\nand [lein-webdav](https://github.com/tobias/lein-webdav) as these declare\ntheir wagons in ways that can be inferred automatically.\n\n## Authentication\n\nDeploying and reading from private repositories needs authentication\ncredentials. Check your repository's documentation for details, but\nyou'll usually need to provide a `:username` and `:password` (for a repository)\nor `:passphrase` (for GPG). Leiningen will prompt you for a password if you\nhaven't set up credentials, but it's convenient to set it so you don't have to\nre-enter it every time you want to deploy. You will need\n[gpg](https://www.gnupg.org/) installed and a key pair configured.  If\nyou need help with either of those, see the\n[GPG guide](https://codeberg.org/leiningen/leiningen/src/stable/doc/GPG.md).\n\n### GPG\n\nIf you specify a `:creds :gpg` entry in one of your `:repositories` settings\nmaps, Leiningen will decrypt `~/.lein/credentials.clj.gpg` and use that to find\nthe proper credentials for the given repository.\n\n```clj\n:repositories [[\"releases\" {:url \"https://blueant.com/archiva/internal\"\n                            :creds :gpg}]]\n```\n\nFirst write your credentials map to `~/.lein/credentials.clj` like so:\n\n```clj\n{#\"blueant\" {:password \"locative1\"}\n #\"https://repo.clojars.org\"\n {:username \"milgrim\" :password \"CLOJARS_677eb77a08974e2797bbd17a402464e5cd0f987689487633895e649b312e\"}\n \"s3p://s3-repo-bucket/releases\"\n {:username \"AKIAIN...\" :passphrase \"1TChrGK4s...\"}}\n```\n\nWhen storing credentials for Clojars, it's recommended to generate a\n[deploy token](https://clojars.org/tokens) per machine and store that\ninstead rather than having a single deploy token in order to limit\nthe scope of the damage if the credential is leaked.\n\nThen encrypt it with `gpg`:\n\n    $ gpg --default-recipient-self -e \\\n        ~/.lein/credentials.clj > ~/.lein/credentials.clj.gpg\n\nRemember to delete the plaintext `credentials.clj` once you've\nencrypted it. Due to a bug in `gpg` you currently need to use\n`gpg-agent` and have already unlocked your key before Leiningen\nlaunches, but with `gpg-agent` you only have to enter your passphrase\nperiodically; it will keep it cached for a given period.\n\nNote to windows users: Be sure to download the full version of \n[Gpg4win](https://gpg4win.org/download.html) and\nselect GPA for installation. You then need to run \n`gpg-connect-agent /bye` from the command line before starting lein.\n\n### Full-disk Encryption\n\nIf you use full-disk encryption, it may be safe to store your\ncredentials without using GPG. In this case, you can create an `:auth`\nprofile containing a `:repository-auth` key mapping URL regexes to\ncredentials. Your `~/.lein/profiles.clj` file would look something\nlike this:\n\n```clj\n{:user {...}\n :auth {:repository-auth {#\"blueant\" {:username \"milgrim\"\n                                      :password \"locative1\"}}}}\n```\n\n### Credentials in the Environment\n\nUnattended builds can specify `:env` instead of `:gpg` in the\nrepository specification to have credentials looked up in the\nenvironment. For example, specifying `:password :env` will cause\nLeiningen to look up `(System/getenv \"LEIN_PASSWORD\")` for that value.\nYou can control which environment variable is looked up for each value\nby using a namespaced keyword, like so:\n\n```clj\n:repositories [[\"releases\" {:url \"https://blueant.com/archiva/internal\"\n                            :username :env/archiva_username\n                            :password :env/archiva_password}]]\n```\n\nFinally, you can opt to load credentials from the environment _or_ GPG credentials\nby using a vector of `:gpg` and `:env/*` values to define the priority of each:\n\n```clj\n:repositories [[\"releases\" {:url \"https://blueant.com/archiva/internal\"\n                            :username [:gpg :env/archiva_username]\n                            :password [:gpg :env/archiva_password]}]]\n```\n\nIn this example, both `:username` and `:password` will be looked up in\n`~/.lein/credentials.clj.gpg` first, and only if a value is not available there will\nthe `ARCHIVA_*` env vars be checked.  This allows you to avoid creating profiles\njust to use different credential sources in e.g. a local development environment\nvs. a centralized build environment.\n\nNote that the forms `:env` and `:env/varname` are only supported within the\n`:repositories` key. Plugins may decide to implement this themselves, but this\nis not default behaviour.\n\n## Deployment\n\nOnce you've set up a private repository and configured project.clj\nappropriately, you can deploy to it:\n\n    $ lein deploy [repository-name]\n\nIf the project's current version is a `SNAPSHOT`, it will default to deploying\nto the `\"snapshots\"` repository; otherwise it will default to `\"releases\"`. In\norder to make `lein deploy` with no argument target Clojars, include this in\nyour `project.clj`:\n\n```clj\n{:deploy-repositories [[\"releases\" :clojars]\n                       [\"snapshots\" :clojars]]}\n```\n\nYou can use this to alias any `:repositories` entry; Clojars is just the most\ncommon use case.\n\n## Signing Artifacts\n\nBy default Leiningen will attempt to sign all artifacts that are deployed\nusing GPG. If you prefer, you can [sign them using\nSSH](https://www.agwa.name/blog/post/ssh_signatures) instead. If you don't\nalready use GPG, this may be more convenient for you. Edit your\n`~/.lein/profiles.clj` file to add a `:user` profile with a `:signing` map:\n\n```clj\n{:user {:signing {:gpg-key false\n                  :ssh-key \"~/.ssh/id_rsa\"}}}\n```\n\nIf you want to keep signing with both SSH and GPG at the same time, you can\nomit the `:gpg-key false` setting.\n\n## Releasing Simplified\n\nOnce you have your repositories and user credentials configured for deploying,\nmuch of the work involved in actually deploying a release version can be tedious\nand difficult to perform in a consistent fashion from one release to the next.\nTo simplify the release process, there is a `lein release [$LEVEL]` task where\n`$LEVEL` can be refer to any of `:major`, `:minor`, `:patch`, `:alpha`, `:beta`,\nor `:rc`. The simplification lies in the list of `:release-tasks` that get run\non each call to `lein release`. For example, suppose that your `project.clj`\nstarts off as follows:\n\n```clojure\n(defproject leiningen \"2.4.0-SNAPSHOT\" ...)\n```\n\nUsing the default `:release-tasks` and the following command line:\n\n    $ lein release :patch\n\nThe following events will happen:\n\n1. The `change` task is run to remove whatever qualifier is currently on\n   the version in `project.clj`. In this case, `project.clj` should\n   look something like ```(defproject leiningen \"2.4.0\" ...)```.\n\n2. `vcs` tasks will be run to commit this change and then tag the repository\n   with the `release` version number.\n\n3. The `deploy` task will be the same as if `lein deploy` had been run from the\n   command line. **NOTE** This will require a valid `\"releases\"` entry either in\n   `:deploy-repositories` or `:repositories`\n\n4. The `change` task is run once more to \"bump\" the version number in\n   `project.clj`. Which version level is decided by the argument\n   passed to `lein release`, in this case `:patch`. Afterward, `project.clj` will\n   look something like ```(defproject leiningen \"2.4.1-SNAPSHOT\" ...)```.\n\n5. Finally, `vcs` tasks will be run once more to commit the new change to\n   `project.clj` and then push these two new commits to the default remote\n   repository.\n\nThe release process will fail if there are uncommitted changes.\n\n### Overriding the default `:release-tasks`\n\nYou can use the `lein-pprint` plugin to see the default value of `:release-tasks`:\n\n```\n$ lein pprint :release-tasks\n[[\"vcs\" \"assert-committed\"]\n [\"change\" \"version\" \"leiningen.release/bump-version\" \"release\"]\n [\"vcs\" \"commit\"]\n [\"vcs\" \"tag\"]\n [\"deploy\"]\n [\"change\" \"version\" \"leiningen.release/bump-version\"]\n [\"vcs\" \"commit\"]\n [\"vcs\" \"push\"]]\n```\n\nThis `:release-tasks` value can be overridden in `project.clj`. An example might\nbe a case in which you want the default workflow up to `lein deploy` but don't\nwant to automatically bump the version in `project.clj`:\n\n```clojure\n  :release-tasks [[\"vcs\" \"assert-committed\"]\n                  [\"change\" \"version\"\n                   \"leiningen.release/bump-version\" \"release\"]\n                  [\"vcs\" \"commit\"]\n                  [\"vcs\" \"tag\"]\n                  [\"deploy\"]]\n```\n\nThe `:release-tasks` vector should have every element be either a task name or a\ncollection in which the first element is a task name and the rest are arguments\nto that task, just like `:prep-tasks` or `:aliases` entries.\n\nOf course, `:release-tasks` doesn't have to look anything like the\ndefault, the default is just an assumed convention among most Clojure\nlibraries using Leiningen. Applications will have different requirements\nthat are varied enough that Leiningen doesn't attempt to support them\nout of the box.\n\nIf you just want to change the `deploy` step so it goes to Clojars, you don't\nhave to replace the whole `:release-tasks` vector, just set this:\n\n```clojure\n:deploy-repositories {\"releases\" {:url \"https://repo.clojars.org\" :creds :gpg}}\n```\n\n### Committing\n\nBy default, `[\"vcs\" \"commit\"]` will commit with the message `\"Version\n<version>\"`. You can override that by passing a `format`-ready string\nto the task, like so: `[\"vcs\" \"commit\" \"Version %s [skip ci]\"]`.\n\n### Tagging\n\nBy default `[\"vcs\" \"tag\"]` will create a signed tag with your project version\nnumber. You can add a tag prefix by passing the prefix after `\"tag\"`,\nfor example: `[\"vcs\" \"tag\" \"v\"]`. You can disable tag signing by passing `--no-sign`,\nfor example: `[\"vcs\" \"tag\" \"v\" \"--no-sign\"]` or `[\"vcs\" \"tag\" \"--no-sign\"]`.\n\n## Deploying to Maven Central\n\nDeploying your libraries and other artifacts to [Maven\nCentral](https://search.maven.org/) is often desirable.  Most tools that\nuse the Maven repository format (including Leiningen, Gradle, sbt, and\nMaven itself) include Maven Central or one of its mirrors as a default\nrepository for resolving project dependencies.  So deploying your\nlibraries to Maven Central offers the widest distribution, especially if\nyour users are likely to be in languages other than Clojure.\n\nThankfully, Leiningen can deploy your libraries to Maven Central, with\na few additional bits of configuration.  All of the guidance about\ndeploying to private repositories laid out above applies; but, here's a\nstep-by-step recipe from start to finish:\n\n1. Register an account and groupId on `oss.sonatype.org`; refer to\n[this](https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide)\nfor details on how to get registered (you can ignore most of the info on\nthat page regarding configuring Maven and/or ant, since we'll not be\ntouching those tools).  Note that all artifacts you deploy to Sonatype OSS will\nneed to use the groupId(s) you choose, so your project coordinates\nshould be set up to match; e.g.:\n\n```clojure\n(defproject your.group.id/projectname \"x.y.z\" ...)\n```\n\n2. Add your credentials for `oss.sonatype.org` to your\n`~/.lein/credentials.clj.gpg` file.  Something like this will do:\n\n```clojure\n{#\"https://oss.sonatype.org/.*\"\n {:username \"username\" :password \"password\"}}\n```\n\nRefer to the instructions earlier on this page for how to encrypt a\nplain-text `credentials.clj` using GPG.\n\n3. Add the Sonatype OSS deployment repository endpoints to your project.clj, e.g.:\n```clojure\n:deploy-repositories [[\"releases\" {:url \"https://oss.sonatype.org/service/local/staging/deploy/maven2/\"\n                                   :creds :gpg}\n                       \"snapshots\" {:url \"https://oss.sonatype.org/content/repositories/snapshots/\"\n                                    :creds :gpg}]]\n```\n\n4. Conform to Sonatype OSS' requirements for uploaded artifacts' `pom.xml` files;\nall you need to do is make sure the following slots are populated\nproperly in your `project.clj`:\n\n```clojure\n  :description\n  :url\n  :license\n  :scm\n  :pom-addition\n  :classifiers\n```\n\nExamples of OSS-acceptable values for these entries can be seen in this\n[`project.clj`\nfile](https://github.com/operatr-io/kpow-streams-agent/blob/main/project.clj).\nNote that all of them should be appropriate for *your* project; blind\ncopy/paste is not appropriate here.\n\n5. Run `lein deploy`.  Leiningen will push all of the files it would\notherwise send to Clojars or your other private repository to the proper\nOSS repository (either releases or snapshots depending on whether your\nproject's version number has `-SNAPSHOT` in it or not).\n\n6. If you're deploying a release, log in to `oss.sonatype.org`, and\nclose and release/promote your staged repository.  (This manual step\nwill eventually be automated through the use of a plugin.) The release\nwill show up in OSS' releases repository immediately, and sync to Maven\nCentral on the next cycle (~ 1-4 hours usually). \n"
  },
  {
    "path": "doc/FAQ.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [FAQ](#faq)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# FAQ\n\n**Q:** How do you pronounce Leiningen?  \n**A:** It's LINE-ing-en. ['laɪnɪŋən]\n\n**Q:** What's a group ID? How do snapshots work?  \n**A:** See the\n  [tutorial](https://codeberg.org/leiningen/leiningen/src/stable/doc/TUTORIAL.md)\n  for background.\n\n**Q:** How should I pick my version numbers?  \n**A:** Use [semantic versioning](https://semver.org) to communicate\n  intentions to downstream users of your library, but don't make\n  assumptions that libraries you use stick with it consistently. Remember\n  that the difference between a breaking change and a bug fix is often\n  subjective.\n\n**Q:** What if my project depends on jars that aren't in any repository?  \n**A:** You will need to get them in a repository. The\n  [deploy guide](https://codeberg.org/leiningen/leiningen/src/stable/doc/DEPLOY.md)\n  explains how to set up a private repository. In general it's easiest\n  to deploy them to a static HTTP server or a private S3 bucket. Once\n  the repo is set up, `lein deploy private-repo com.mycorp/somejar\n  1.0.0 somejar.jar pom.xml` will push the artifacts out. If you don't\n  have a pom, you can create a dummy project with `lein new` and\n  generate a pom from that. If you are just doing exploratory coding\n  you can deploy to `file:///$HOME/.m2/repository` and the jars will\n  be available locally.\n\n**Q:** I want to hack a project and one of its dependencies, but it's annoying to switch between them.  \n**A:** Leiningen provides a feature called *checkout dependencies* to\n  make this smoother.  See the\n  [tutorial](https://codeberg.org/leiningen/leiningen/src/stable/doc/TUTORIAL.md)\n  to learn more.\n\n**Q:** Is it possible to exclude indirect dependencies?  \n**A:** Yes. Some libraries, such as log4j, depend on projects that are\n  not included in public repositories and unnecessary for basic\n  functionality.  Projects listed as `:dependencies` may exclude\n  any of their dependencies by using the `:exclusions` key. See\n  `lein help sample` for details.\n\n**Q:** I specified a dependency on version X but am getting version Y; what's up?  \n**A:** One of your dependencies' dependencies has declared a\n  dependency on a hard version range, which overrides your \"soft\"\n  declaration. Running `lein deps :tree` will identify which of your\n  dependencies are responsible for the version range. You can add an\n  `:managed-dependencies` clause to prevent that from affecting the\n  rest of your dependencies. See [the managed dependencies\n  guide](doc/MANAGED_DEPS.md) for details. You may also want to report\n  a bug with the dependency that uses hard version ranges as they\n  cause all kinds of problems and exhibit unintuitive behaviour.\n\n**Q:** I have two dependencies, X and Y, which depends on Z. How is the version\n  of Z decided?  \n**A:** The decision depends on which depth and which order the dependencies come\n  in the `:dependencies` vector: The dependency at the lowest depth will be\n  picked. If there are multiple versions of a single group/artifact at that\n  depth, the first of those will be picked. For instance, in the dependency\n  graph\n\n    [Z \"1.0.9\"]\n    [X \"1.3.2\"]\n      [Z \"2.0.1\"]\n\n  the direct dependency (`[Z \"1.0.9\"]`) is picked, as it is closest to the root.\n  For the dependency graph\n\n    [X \"1.3.2\"]\n      [Z \"2.0.1\"]\n    [Y \"1.0.5\"]\n      [Z \"2.1.3\"]\n\n  the dependency X comes first, and therefore `[Z \"2.0.1\"]` is picked. If we\n  place Y before X however, `[Z \"2.1.3\"]` will be picked.\n  \n  Note that this only applies to soft dependencies, and `lein deps :tree` will\n  only warn if the latest version is not chosen.\n\n**Q:** I'm behind an HTTP proxy; how can I fetch my dependencies?  \n**A:** Set the `$http_proxy` environment variable in Leiningen 2.x. You can also\n  set `$http_no_proxy` for a list of hosts that should be reached directly, bypassing\n  the proxy. This is a list of patterns separated by `|` and may start or end with\n  a `*` for wildcard, e.g. `localhost|*.mydomain.com`.\n  For Leiningen 1.x versions, see the instructions for\n  [configuring a Maven proxy](https://maven.apache.org/guides/mini/guide-proxies.html)\n  using `~/.m2/settings.xml`.\n\n**Q:** What can be done to speed up launch?  \n**A:** The main delay involved in Leiningen comes from starting two\n  JVMs: one for your project and one for Leiningen itself. Most people\n  use a development cycle that involves keeping a single project REPL\n  process running for as long as they're working on that project.\n  Depending on your editor you may be able to do this via its Clojure\n  integration. (See [cider](https://github.com/clojure-emacs/cider) or\n  [fireplace](https://github.com/tpope/vim-fireplace), for example.)\n  Otherwise you can use the basic `lein repl`.\n\n**Q:** Still too slow; what else can make startup faster?  \n**A:** The wiki has a page covering\n  [ways to improve startup time](https://wiki.leiningen.org/Faster).\n\n**Q:** What if I care more about long-term performance than startup time?  \n**A:** Leiningen gets a startup time speed boost by disabling optimized\n  compilation (which only benefits long-running processes).  This can\n  negatively affect performance in the long run, or lead to inaccurate\n  benchmarking results.  If want the JVM to fully optimize, you can\n  switch profiles with `lein with-profiles production run ...`.\n\n**Q:** I'm attempting to run a project as a background process (`lein run &`),\n  but the process suspends until it is in the foreground. How do I run a program\n  in the background?  \n**A:** For long-lasting processes, it's better to create an uberjar\n  and run that or use `lein trampoline run &`. For short-lived ones,\n  both `lein run <&- &` and `bash -c \"lein run &\"` will work fine.\n\n**Q:** How do I determine my project's version at runtime?  \n**A:** Leiningen writes a file called `pom.properties` into\n  `target/classes` which contains the version number and current git\n  revision of the project. In previous versions of Leiningen this was\n  only available when running from jar files, but as of 2.4.1 it's\n  available during `lein run ...`, etc. You can read it by running\n  this code (replace \"group\" and \"artifact\" with values appropriate to\n  your project):\n\n```clj\n(with-open [pom-properties-reader (io/reader (io/resource \"META-INF/maven/group/artifact/pom.properties\"))]\n  (doto (java.util.Properties.)\n    (.load pom-properties-reader)))\n```\n\n**Q:** How can I read my project map at runtime?  \n**A:** Usually you do not need the complete project map, only a specific subset\n  of some values. If you want different configuration based on different tasks,\n  then [environ](https://github.com/weavejester/environ) is probably a good fit.\n  If you want information like the project's version number or git revision,\n  read the question and answer above.\n\n  Generally those solutions are sufficient, but if you need more than this, you\n  should rather read the `project.clj` yourself. The project map changes based\n  on the task you use, and so different tasks (repl, jar, uberjar to name a few)\n  will make it hard to make the testing- and production project map identical.\n  `project.clj` is added as a resource in\n  `META-INF/leiningen/group/artifact/project.clj` (replace \"group\" and\n  \"artifact\" with values appropriate to your project). You can read it as\n  follows:\n\n```clj\n(read-string (slurp (io/resource \"META-INF/leiningen/group/artifact/project.clj\")))\n```\n\n**Q:** I need to do AOT for an uberjar; can I avoid it during development?  \n**A:** Yes, it is strongly recommended to do AOT only in the uberjar task\n  if possible. But by default the AOT'd files will still be visible during \n  development unless you also change `:target-path` to something like\n  `\"target/uberjar\"` in the `:uberjar` profile as well.\n\n**Q:** Is there a way to use an uberjar without AOT?  \n**A:** If you omit `:main` in `project.clj`, your uberjars will use\n  `clojure.main` as their entry point. You can launch with `java -jar\n  my-app-standalone.jar -m my.entry.namespace arg1 arg2 [...]` without\n  any AOT, but it will take longer to launch.\n\n**Q:** Why does `lein jar` package some namespaces from dependencies into my jar?  \n**A:** This is likely because you have AOT-compiled namespaces. An\n  AOT-compiled namespace can only depend on AOT-compiled namespaces. Therefore,\n  if you depend on a namespace in a dependency that is not AOT-compiled, it will\n  be AOT-compiled and bundled with the jar. It is strongly recommended not to\n  perform AOT other than during the creation of an uberjar.\n\n**Q:** I'd like to have certain config active only on a certain OS.  \n**A:** You can do this by using unquote in the `:dev` profile:\n\n```clj\n:profiles {:dev [:dev/all ~(leiningen.core.utils/get-os)]\n           :dev/all {...}\n           :linux {...}\n           :windows {...}\n           :macosx {...}}\n```\n\nYou can also check things like `(System/getProperty\n\"java.specification.version\")` to use the JVM version or any other\nproperty.\n\n**Q:** I get a `java.security.KeyException` or `sun.security.provider.certpath.SunCertPathBuilderException` when running `lein`  \n**A:** The `java.security.KeyException` indicates an ssl error when\n  trying to communicate with the HTTPS server via Java. This could be\n  because you need to update the JDK, or some other package (e.g. with\n  old versions of the nss package).\n\n* On Fedora, you might just try running a `sudo yum update` to update all of your packages or `sudo yum update nss`.\n* On Debian/Ubuntu, `sudo update-ca-certificates -f` might help, or `sudo /var/lib/dpkg/info/ca-certificates-java.postinst configure`\n* You should also check your system clock and make sure the time is accurate; it's possible to run into SSL connection failures if your clock is way out of sync.\n* If it still doesn't work, please see if any of [these 'ssl' labelled issues](https://github.com/technomancy/leiningen/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Assl%20) might help\n\n**Q:** I got `Tried to use insecure HTTP repository without TLS`, what is that about?  \n**A:** This means your project was configured to download dependencies\nfrom a repository that does not use TLS encryption. This is very\ninsecure and exposes you to trivially-executed man-in-the-middle\nattacks.  In the rare event that you don't care about the security of\nthe machines running your project or can ensure that the only http\ntraffic is going out over a trusted network, you can re-enable support\nfor unsafe repositories by putting this in your `project.clj` file:\n\n    ;; never do this\n    (require 'cemerick.pomegranate.aether)\n    (cemerick.pomegranate.aether/register-wagon-factory!\n     \"http\" #(org.apache.maven.wagon.providers.http.HttpWagon.))\n\nIt's also possible you have a dependency which includes a reference to\nan insecure repository for retrieving its own dependencies. If this\nhappens it is strongly recommended to add an `:exclusion` and report a\nbug with the dependency which does this.\n\n**Q:** `lein`/`lein.bat` won't download `leiningen-x.y.z-SNAPSHOT.jar`  \n\n**A:** You probably downloaded `lein`/`lein.bat` from the main\n  branch. Unless you plan to build leiningen yourself or help develop\n  it, we suggest you use the latest stable version:\n  [lein](https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein)/[lein.bat](https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat)\n\n**Q:** I have a dependency whose group ID and/or artifact ID starts with a\nnumber (which is invalid for symbols in Clojure). How can I add it to my\nproject's dependencies?  \n**A:** Leiningen supports string dependency names like this:\n\n```clj\n:dependencies [[\"net.3scale/3scale-api\" \"3.0.2\"]]\n```\n\n**Q:** I'm getting warnings for implicit hooks.  \n**A:** Hooks are a deprecated feature where plugins can modify the\n  behavior of built-in Leiningen functionality; they result in\n  situations which can be very difficult to debug and usually point\n  to situations in which the original API is not flexible enough.\n\nAdding `:implicits false` to `project.clj` will disable all implicit features.\n"
  },
  {
    "path": "doc/GPG.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Using GPG](#using-gpg)\n  - [What is it?](#what-is-it)\n  - [Installing GPG](#installing-gpg)\n    - [Linux](#linux)\n        - [Debian based distributions](#debian-based-distributions)\n      - [Fedora based distributions](#fedora-based-distributions)\n    - [Mac](#mac)\n    - [Windows](#windows)\n  - [Creating a keypair](#creating-a-keypair)\n  - [Listing keys](#listing-keys)\n  - [Publishing your public key](#publishing-your-public-key)\n  - [How Leiningen uses GPG](#how-leiningen-uses-gpg)\n    - [Signing a file](#signing-a-file)\n    - [Overriding the gpg defaults](#overriding-the-gpg-defaults)\n  - [Troubleshooting](#troubleshooting)\n    - [Debian based distributions](#debian-based-distributions-1)\n      - [gpg: can't query passphrase in batch mode](#gpg-cant-query-passphrase-in-batch-mode)\n    - [Mac OS](#mac-os)\n      - [Unable to get GPG installed via Homebrew and OS Keychain to work](#unable-to-get-gpg-installed-via-homebrew-and-osx-keychain-to-work)\n      - [GPG doesn't ask for a passphrase](#gpg-doesnt-ask-for-a-passphrase)\n    - [GPG prompts for passphrase but does not work with Leiningen](#gpg-prompts-for-passphrase-but-does-not-work-with-leiningen)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# Using GPG\n\nThis is an introduction to setting up and using\n[GPG](https://www.gnupg.org/) keys with\n[Leiningen](https://leiningen.org) to sign artifacts for publication to\n[Clojars](https://clojars.org/) and to encrypt repository credentials.\n\nThere are two versions of GPG available: v1.x and v2.x. For our\npurposes, they are functionally equivalent. Package managers generally\ninstall v2.x as `gpg2`, and v1.x as `gpg`, except for Homebrew which\ninstalls v2.x as `gpg`, and v1.x as `gpg1`. By default, Leiningen\nexpects the GPG command to be `gpg`. You're welcome to use any version\nyou like, but this primer will only cover installing v1.x (except under\nmacOS), and has only been tested under v1.x.\n\n## What is it?\n\n[GPG](https://www.gnupg.org/) (or Gnu Privacy Guard) is a set of tools\nfor cryptographic key creation/management and encryption/signing of\ndata. If you are unfamiliar with the concepts of public key\ncryptography, this\n[Wikipedia entry](https://en.wikipedia.org/wiki/Public-key_cryptography)\nserves as a good introduction.\n\nAn important concept to understand in public key cryptography is that\nyou are really dealing with two keys (a *keypair*): one public, the\nother private (or secret). The public key can be freely shared, and is\nused by yourself and others to encrypt data that only you, as the\nholder of the private key, can decrypt. It can also be used to verify\nthe signature of a file, confirming that the file was signed by the\nholder of the private key, and the contents of the file have not been\naltered since it was signed. **You should guard your private key\nand passphrase closely, and share them with no one.**\n\n## Installing GPG\n\n### Linux\n\n##### Debian based distributions\n\nApt uses GPG v1, so it should already be installed. If not:\n\n    apt-get install gnupg\n    \n#### Fedora based distributions\n\nFedora and friends may have GPG v2 installed by default, but GPG v1 is\navailable via:\n    \n    yum install gnupg\n    \n### Mac\n\nThere are several options here, depending on which package manager you\nhave installed (if any):\n\n1. via [homebrew](https://brew.sh/): `brew install gnupg2`\n2. via [macports](https://www.macports.org/): `port install gnupg2`\n3. via a [binary installer](https://www.gpgtools.org/installer/index.html) \n   (this installs gpg2 as gpg)\n\n### Windows\n\n[GPG4Win](https://gpg4win.org/) provides a binary installer that\nprovides some possibly useful GUI tools in addition to providing the\n`gpg` command.\n\n## Creating a keypair\n\nCreate a keypair with:\n\n    gpg --gen-key\n\nThis will prompt you for details about the keypair to be generated,\nand store the resulting keypair in `~/.gnupg/`.\n\nThe default key type (RSA and RSA) is fine for our purposes, as is the\ndefault keysize (2048). We recommend a validity period of 2 years. \n\nYou'll be prompted for a passphrase to protect your private key - it's\nimportant to use a strong one to help protect the integrity of your key.\n\n## Listing keys\n\nGPG stores keys in a keystore located in `~/.gnupg/`. This keystore\nholds your keypair(s), along with any other public keys you have used.\n    \nTo list all of the public keys in your keystore:\n\n    gpg --list-keys\n    \nThis will include any public keys you have used, including keys from\nothers (if you've never used GPG before and just created your first\nkeypair, you should just see your own key).\n\nThe output of the `--list-keys` option will include the id of your\npublic key in the 'pub' line in the key listing (you'll need that id \nfor other commands described here):\n\n    $ gpg --list-keys\n\n                ↓↓↓↓↓↓↓↓\n    pub   2048R/2ADFB13E 2013-03-16 [expires: 2014-03-16]\n    uid                  Bob Bobson <bob@bobsons.net>\n    sub   2048R/8D2344D0 2013-03-16 [expires: 2014-03-16]\n\nThe `--fingerprint` option will act just like `--list-keys`, but will\ninclude the fingerprint of each certificate in the output. You can\nfilter the output of the `--fingerprint` option by providing a key id\nor any substring from the uid (this trick also works for the\n`--list-keys` option):\n\n    $ gpg --fingerprint 2ADFB13E\n\n    pub   2048R/2ADFB13E 2013-03-16 [expires: 2014-03-16]\n          Key fingerprint = 3367 5FD0 D67B 3218 5815  51A3 97D4 06D0 2ADF B13E\n    uid                  Bob Bobson <bob@bobsons.net>\n    sub   2048R/8D2344D0 2013-03-16 [expires: 2014-03-16]\n\n## Publishing your public key\n\nTo make it easier for others that need your public key to find it,\nyou can publish it to a key server with:\n\n    gpg --send-keys 2ADFB13E # use your id instead\n\nThis pushes a copy of your public key to one of a cluster of free key\nservers, and the key is propagated to all of the other servers in the\ncluster in short order.\n\nIf your keypair is compromised, you can publish a revocation\ncertificate to the key server to let others know that your key can no\nlonger be trusted for any future signing or encryption. It's a good\nidea to generate a revocation certificate whenever you create a new\nkeypair, and store it in a safe place. As long as you have that\nrevocation certificate, you can revoke a keypair even if you no longer\nhave the private key. You can generate a revocation certificate with:\n\n    $ gpg --output 2ADFB13E-revoke.asc --gen-revoke 2ADFB13E\n\nBe sure to protect your revocation certificate carefully - anyone who\ngains access to it can use it to revoke your keypair. The GPG\nmaintainers recommend printing it out and storing the hardcopy in a\nsafe place.\n\nTo revoke your certificate **when the time comes (not now!)**, do the\nfollowing:\n\n    $ gpg --import 2ADFB13E-revoke.asc  # ONLY WHEN YOU NEED TO REVOKE\n    $ gpg --send-keys 2ADFB13E          # ONLY WHEN YOU NEED TO REVOKE\n\n## How Leiningen uses GPG\n\nLeiningen uses GPG for three things: decrypting credential files,\nsigning release artifacts, and signing tags. We'll focus on artifact\nsigning here; for information on credentials encryption/decryption,\nsee the\n[deploy guide](https://codeberg.org/leiningen/leiningen/src/stable/doc/DEPLOY.md). Once\nyou are configured to sign releases, signing tags should be\nstraightforward.\n\nOn some systems you will be prompted for your GPG passphrase when it\nis needed if you haven't entered it. If yours does not, you can\ninstall [Keychain](https://github.com/funtoo/keychain), which provides\nthis functionality portably. \n\n### Signing a file\n\nWhen you deploy a non-SNAPSHOT artifact via the `deploy`\ntask, Leiningen will attempt to create GPG signatures of the jar and\npom files. It does so by shelling out to `gpg` and using your default\nprivate key to sign each artifact. This will create a signature file\nfor each artifact named by appending `.asc` to the artifact name.\n\nBoth signatures are then uploaded along with the artifacts. If you're\ndeploying to Clojars, you'll want to provide it with your *public* key\n(see below) in order that the signatures can be verified.\n\nTo disable signing of releases, set `:sign-releases` to false in the\n`:repositories` entry you are targeting. If you do this, everyone who\nis depending on your library will not be able to confirm that the copy\nthey get has not been tampered with, so this is not recommended.\n\n### Overriding the gpg defaults\n\nBy default, Leiningen will try to call GPG as `gpg`, which assumes\nthat `gpg` is in your path, and your GPG binary is actually called\n`gpg`. If either of those are false, you can override the command\nLeiningen uses for GPG by setting the `LEIN_GPG` environment variable.\n\nGPG by default will select the first private key it finds (which will\nbe the first key listed by `gpg --list-secret-keys`). If you have\nmultiple keys and want to sign with one other than first, or want to\nuse specific keys for a particular release repository, you can specify\nwhich key to use either globally, per-project, or\nper-deploy-repository. All three places use the same configuration\nsyntax, it's all about where you put it. You can specify the key by id\nor by the uid.\n\nTo set a key globally, add it to your user profile in\n`~/.lein/profiles.clj`:\n\n    {:user {...\n            :signing {:gpg-key \"2ADFB13E\"}}} ;; using the key id\n\nTo set a key for a particular project, add it to the project\ndefinition:\n\n    (defproject ham-biscuit \"0.1.0\"\n       ...\n       :signing {:gpg-key \"bob@bobsons.net\"} ;; using the key uid\n       ...)\n    \nTo set a key for a particular deploy repository, add it to the\nrepository specification in your project definition:\n\n    (defproject ham-biscuit \"0.1.0\"\n       ...\n       :deploy-repositories \n         [[\"releases\" {:url \"https://blueant.com/archiva/internal/releases\"\n                       :signing {:gpg-key \"2ADFB13E\"}}]\n         [\"snapshots\" \"https://blueant.com/archiva/internal/snapshots\"]]\n       ...)\n\n## Troubleshooting\n\n### Debian based distributions\n\n#### gpg: can't query passphrase in batch mode\n\n\tCould not decrypt credentials from /home/xxx/.lein/credentials.clj.gpg\n\tgpg: can't query passphrase in batch mode\n\tgpg: decryption failed: secret key not available\n\n\nThis error happens with gpg 1.4.12. Make sure that you have `use-agent` option explicitly enabled in `~/.gnupg/gpg.conf`. See gpg option list.\n\nYou can test whether this solution works with\n\n\tgpg --quiet --batch --decrypt ~/.lein/credentials.clj.gpg\n\nIf the system asked your passphrase then problem solved.\n\n### Mac OS\n\n#### Unable to get GPG installed via Homebrew and OS Keychain to work\n\nInstalling GPG from here instead: https://www.gpgtools.org/installer/index.html\n\n#### GPG doesn't ask for a passphrase\n\nMake sure that you have \"use-agent\" option explicitly enabled in ~/.gnupg/gpg.conf. See gpg option list.\n\nYou can test the config with\n\n    gpg --quiet --batch --decrypt ~/.lein/credentials.clj.gpg\n    \nLeiningen should pick it up automatically when the command above works correctly.\n\n#### gpg: decryption failed: secret key not available\n\nWhen you run\n\n    gpg --quiet --batch --decrypt ~/.lein/credentials.clj.gpg\n\nyou get the error message\n\n    gpg: decryption failed: secret key not available\n\ntry running it without `--quiet`\n\n    gpg  --use-agent --decrypt ~/.lein/credentials.clj.gpg\n\nIf you get\n\n    gpg: encrypted with RSA key, ID DEAD8F70\n    gpg: decryption failed: secret key not available\n\nrun `gpg -k` and check that `DEAD8F70` is in the known keys list. If it isn't, `~/.lein/credentials.clj.gpg` may have been encrypted with a different key.\n\n### GPG prompts for passphrase but does not work with Leiningen\n\n    gpg --quiet --batch --decrypt ~/.lein/credentials.clj.gpg\n\nIt's hanging for a while after executing lein repl and then prints out these messages:\n\n    $ lein repl\n    Could not decrypt credentials from /Users/xxx/.lein/credentials.clj.gpg\n    pinentry-curses: no LC_CTYPE known - assuming UTF-8\n    pinentry-curses: no LC_CTYPE known - assuming UTF-8\n    pinentry-curses: no LC_CTYPE known - assuming UTF-8\n    pinentry-curses: no LC_CTYPE known - assuming UTF-8\n    pinentry-curses: no LC_CTYPE known - assuming UTF-8\n    gpg-agent[1009]: command get_passphrase failed: Invalid IPC response\n    gpg: problem with the agent: Invalid IPC response\n    gpg: decryption failed: No secret key\n    \nLeiningen can't present enter-passphrase page of gpg. It's an issue with Leiningen or gpg2 or gpg-agent or pinentry.\n\nUse the GUI version of gpg, GPG Suite. Now when executing 'lein repl', it prompts for passphrase on the GUI instead.\n"
  },
  {
    "path": "doc/MANAGED_DEPS.md",
    "content": "# Managed Dependencies With Leiningen\n\nManaged dependencies allow you to specify overrides for dependencies that you\nmay encounter into your dependency tree, in order to ensure consistency.\n\nThere are two main reasons you may want to do this. The main one is that your\nproject's dependency tree might have some dependencies in it that are specified\nas ranges. Ranges are antithetical to repeatability. Today you might get one\nresult from a range, and tomorrow after a new release happens, your result will\nchange. This is absolutely unacceptable for a tool that strives to provide\nconsistency, but the dependency resolving library we use unfortunately has this\nbehavior anyway. Managed dependencies allow us to work around this design flaw\nby locking in a specific version in a way that will override whatever ranges\nyou might encounter.\n\nThe other reason managed dependencies are useful is that they allow you to lock\nin consistent dependency sets across several projects.\n\n## `:managed-dependencies`\n\nThe `:managed-dependencies` section of your `project.clj` file is just like the\nregular `:dependencies` section, with two exceptions:\n\n1. It does not actually introduce any dependencies to your project.  It only says,\n  \"hey leiningen, if you encounter one of these dependencies later, here are the\n  versions that you should use instead of whatever is specified.\"\n2. It allows the version number to be omitted from the `:dependencies` section,\n  for any artifact that you've listed in your `:managed-dependencies` section.\n  Directly declared versions in `:dependencies` will take precedence over\n  managed version numbers, but versions that are pulled in transitively will not.\n\nHere's an example:\n\n```clj\n(defproject superfun/happyslide \"1.0.0-SNAPSHOT\"\n  :description \"A Clojure project with managed dependencies\"\n  :min-lein-version  \"2.7.0\"\n  :managed-dependencies [[clj-time \"0.12.0\"]\n                         [me.raynes/fs \"1.4.6\"]\n                         [ring/ring-codec \"1.0.1\"]]\n  :dependencies [[clj-time]\n                 [me.raynes/fs]])\n```\n\nIn the example above, the final, resolved project will end up using the specified\n versions of `clj-time` and `me.raynes/fs`.  It will not have an actual dependency\n on `ring/ring-codec` at all, since that is not mentioned in the \"real\" `:dependencies`\n section.\n\nIn the absence of ranges, this feature is not all that useful on its own,\nbecause in the example above, we're specifying the `:managed-dependencies` and\n`:dependencies` sections right alongside one another, and you could just as\neasily include the version numbers directly in the `:dependencies` section.\nThe feature becomes more powerful when your build workflow includes some other\nway of sharing the `:managed-dependencies` section across multiple projects.\n\n## A note on modifiers (`:exclusions`, `:classifier`, etc.)\n\nThe managed dependencies support in leiningen *does* work with modifiers such as\n`:exclusions` and `:classifier`.  There are two legal syntaxes; you can explicitly\nspecify a `nil` for the version string, or you can simply omit the version string:\n\n```clj\n(defproject superfun/happyslide \"1.0.0-SNAPSHOT\"\n  :description \"A Clojure project with managed dependencies\"\n  :min-lein-version  \"2.7.0\"\n  :managed-dependencies [[clj-time \"0.12.0\"]]\n  :dependencies [[clj-time :exclusions [foo]]])\n```\n\nor\n\n```clj\n(defproject superfun/happyslide \"1.0.0-SNAPSHOT\"\n  :description \"A Clojure project with managed dependencies\"\n  :min-lein-version  \"2.7.0\"\n  :managed-dependencies [[clj-time \"0.12.0\"]]\n  :dependencies [[clj-time nil :exclusions [foo]]])\n```\n\nNote that `:classifier` is actually a part of the maven coordinates for an\nartifact, so for `:classifier` artifacts you will need to specify the `:classifier`\nvalue in both the `:managed-dependencies` and the normal `:dependencies` section:\n\n\n```clj\n(defproject superfun/happyslide \"1.0.0-SNAPSHOT\"\n  :description \"A Clojure project with managed dependencies\"\n  :min-lein-version  \"2.7.0\"\n  :managed-dependencies [[commons-math \"1.2\" :classifier \"sources\"]]\n  :dependencies [[commons-math :classifier \"sources\"]])\n```\n\n## Lein \"parent\" projects\n\nOne way of leveraging `:managed-dependencies` across multiple projects is to use\nthe [`lein-parent` plugin](https://github.com/achin/lein-parent).  This plugin\nwill allow you to define a single \"parent\" project that is inherited by multiple\n\"child\" projects; e.g.:\n\n```clj\n(defproject superfun/myparent \"1.0.0\"\n   :managed-dependencies [[clj-time \"0.12.0\"]\n                            [me.raynes/fs \"1.4.6\"]\n                            [ring/ring-codec \"1.0.1\"]])\n\n(defproject superfun/kid-a \"1.0.0-SNAPSHOT\"\n   :parent-project [:coords [superfun/myparent \"1.0.0\"]\n                    :inherit [:managed-dependencies]]\n   :dependencies [[clj-time]\n                  [me.raynes/fs]])\n\n(defproject superfun/kid-b \"1.0.0-SNAPSHOT\"\n :parent-project [:coords [superfun/myparent \"1.0.0\"]\n                  :inherit [:managed-dependencies]]\n :dependencies [[clj-time]\n                [ring/ring-codec]])\n```\n\nIn this example, we've consolidated the task of managing common version dependencies\nin the parent project, and defined two child projects that will inherit those\ndependency versions from the parent without needing to specify them explicitly.\n\nThis makes it easier to ensure that all of your projects are using the same versions\nof your common dependencies, which can help make sure that your uberjar builds are\nmore predictable and repeatable.\n\n## Other ways to share 'managed-dependencies'\n\nSince the `defproject` form is a macro, it would be possible to write other plugins\nthat generated the value for a `:managed-dependencies` section dynamically.  That\ncould provide other useful ways to take advantage of the `:managed-dependencies`\nfunctionality without needing to explicitly populate that section in all of your\n`project.clj` files.\n"
  },
  {
    "path": "doc/MIXED_PROJECTS.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Polyglot (Clojure, Java) Projects With Leiningen](#polyglot-clojure-java-projects-with-leiningen)\n  - [Source Layout](#source-layout)\n  - [Java Source Compilation](#java-source-compilation)\n  - [Setting Java Compiler Options With Leiningen](#setting-java-compiler-options-with-leiningen)\n  - [Interleaving Compilation Steps](#interleaving-compilation-steps)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# Polyglot (Clojure, Java) Projects With Leiningen\n\nClojure is a hosted language that encourages interoperability with its\nplatform. It is not uncommon to find some amount of Java code in Clojure\nprojects managed by Leiningen.\n\nThis guide explains how you can control source code layout with Leiningen,\ncompile Java sources and other topics related to polyglot codebases.\n\n\n## Source Layout\n\nBy default, Leiningen assumes your project only has Clojure source code under\n`src`. When using both Clojure and Java in the same codebase, however, it is\nnecessary to tell Leiningen where to find Java sources.\n\nTo do so, use `:source-paths` and `:java-source-paths` options in the project\ndefinition:\n\n```clojure\n(defproject megacorp/superservice \"1.0.0-SNAPSHOT\"\n  :description \"A Clojure project with a little bit of Java sprinkled here and there\"\n  :min-lein-version  \"2.0.0\"\n  :source-paths      [\"src/clojure\"]\n  :java-source-paths [\"src/java\"])\n```\n\nHaving one source root contain another (e.g. `src` and `src/java`) can\ncause obscure problems.\n\n\n## Java Source Compilation\n\nTo compile Java sources, you can explicitly run\n\n    lein javac\n\nHowever, it is usually not necessary because tasks that need to run\nproject code (`lein test`, `lein run`, etc.) will trigger compilation\nautomatically. Manually running `lein javac` may be necessary when\nusing `lein do`, `lein with-profiles` or `lein repl` actively while\nalso actively changing Java sources in the project.\n\nRunning\n\n    lein clean\n\nwill remove all compilation artifacts.\n\n\n## Setting Java Compiler Options With Leiningen\n\nWhen compiling Java sources, it may be necessary to pass extra arguments to the\ncompiler. For example, it is very important to target the JVM version you are\ngoing to deploy your project to.\n\nThis is done via the `:javac-options` which takes a vector of arguments as you\nwould pass them to `javac` on the command line. In this case we say that Java\nsources use features up to JDK 6 and target JVM is also version 6:\n\n```clojure\n(defproject megacorp/superservice \"1.0.0-SNAPSHOT\"\n  :description \"A Clojure project with a little bit of Java sprinkled here and there\"\n  :min-lein-version \"2.0.0\"\n  :source-paths [\"src/clojure\"]\n  :java-source-paths [\"src/java\"]\n  :javac-options     [\"-target\" \"1.6\" \"-source\" \"1.6\"])\n```\n\nFailing to specify the target version will lead JDK compiler to target whatever JDK\nLeiningen is running on. It is a good practice to explicitly specify target JVM\nversion in mixed Clojure/Java projects.\n\n## Interleaving Compilation Steps\n\nIn some cases it may be necessary to alternate between compiling\ndifferent languages. For instance, systems that generate and\nreference Java sources may also provide Clojure code for the generated\nsources to use.\n\nAny Clojure code referenced by Java sources must be\n[AOT compiled](https://clojure.org/compilation) to make it available to\nthe Java compiler. Similarly, the Java classes produced by `javac`\nmust be available for Clojure code that depends on it. This results\nin steps of `compile` `javac` `compile`, whereas the default task\norder is simply `javac` `compile`.\n\nThis sequence can be accomplished by executing lein with different\nprofiles. A profile can be built to perform the initial steps, while\nanother profile continues to the final compilation stage. For\ninstance, the following is an example of a profile called `:precomp`\nthat AOT compiles the `ex.ast` namespace. The sources for this first\nstep are kept in separate directory from the source directory used by\nthe default profile:\n\n```clojure\n  :profiles { :precomp { :source-paths [\"src/pre/clojure\"]\n                         :aot [ex.ast] } }\n```\n\nThis profile can then be compiled using: `lein with-profile precomp compile`\nn\nOnce this is done, the default profile can be used in a separate\ninvocation of `lein` to perform the `javac` and `compile` steps.\n\nThe following is a complete example of a project that interleaves\nClojure and Java compiling. The entire project uses Clojure, except\nfor generated Java sources. In this case, the project uses the Beaver\nparser generator to create Java source code which calls code written\nin Clojure. The resulting parser is then referenced by Clojure code.\n\n```clojure\n(defproject example/parser \"0.0.1\"\n  :description \"Parser written in Clojure, with generated Java sources\"\n  :min-lein-version \"2.0.0\"\n  :dependencies [[org.clojure/clojure \"1.5.0\"]\n                 [net.sf.beaver/beaver-ant \"0.9.9\"]]\n  :plugins [[lein-beaver \"0.1.2-SNAPSHOT\"]]\n  :source-paths [\"src/clojure\"]\n  :java-source-paths [\"target/src\"]\n  :grammar-src-dir \"src/grammar\"\n  :grammar-dest-dir \"target/src\"\n  :profiles { :precomp { :prep-tasks ^:replace [\"beaver\" \"compile\"]\n                         :source-paths [\"src/pre/clojure\"]\n                         :aot [parser.ast] } })\n ```\n\nThe `:prep-tasks` attribute in the profile adds the source-code\ngeneration step into the sequence of operations to be performed when\ncompiling (though this could have been added to the default profile\ninstead - so long as it occurs before the javac). The `:beaver` task\nuses `:grammar-src-dir` to find the grammar files and creates the Java\nsources in the directory specified by `:grammar-dest-dir` (this is\nplaced in \"target/\" to ensure that it gets removed during a clean). It\nshould be apparent that the generated code is going to use classes\nand/or protocols found in the `parser.ast` namespace, which is why\nthis namespace is AOT compiled. Also, note that the target of the\n`beaver` step matches the sources of the default profile for the\nsubsequent `javac` step.\n\nRunning the `precomp` profile generates the .java sources and compiles\nthe `parser.ast` namespace:\n\n```bash\n$ lein with-profile precomp compile\n```\n\nThe project is now ready to complete compilation normally. For\ninstance, invoking `lein test` or `lein uberjar` will cause `javac`\nand `compile` to run first.\n\n## Other Languages\n\nJava is not the only language you can mix with Leiningen, but it's the\nonly one supported out of the box. Plugins exist for\n[Scala](https://github.com/technomancy/lein-scalac) and\n[Groovy](https://github.com/kurtharriger/lein-groovyc) as well.\n"
  },
  {
    "path": "doc/PLUGINS.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Leiningen Plugins](#leiningen-plugins)\n  - [Writing a Plugin](#writing-a-plugin)\n    - [Local development](#local-development)\n    - [Task Arguments](#task-arguments)\n    - [Documentation and subtasks](#documentation-and-subtasks)\n  - [Code Evaluation](#code-evaluation)\n    - [Evaluating In Project Context](#evaluating-in-project-context)\n  - [Other Plugin Contents](#other-plugin-contents)\n    - [Profiles](#profiles)\n    - [Hooks](#hooks)\n    - [Project Middleware](#project-middleware)\n    - [Maven Wagons](#maven-wagons)\n    - [VCS Methods](#vcs-methods)\n  - [Requiring Plugins](#requiring-plugins)\n  - [Clojure Version](#clojure-version)\n  - [Upgrading Existing Plugins](#upgrading-existing-plugins)\n  - [Projects vs Standalone Execution](#projects-vs-standalone-execution)\n  - [Overriding Built-in Tasks](#overriding-built-in-tasks)\n  - [1.x Compatibility](#1x-compatibility)\n    - [Project-specific Tasks](#project-specific-tasks)\n  - [Have Fun](#have-fun)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n[Japanese](ja/PLUGINS_ja.md)\n\n# Leiningen Plugins\n\nLeiningen tasks are simply functions named `$TASK` in a `leiningen.$TASK`\nnamespace. So writing a Leiningen plugin is just a matter of creating\na project that contains such a function, but much of this\ndocumentation applies equally to the tasks that ship with Leiningen\nitself.\n\nUsing the plugin is a matter of declaring it in the `:plugins` entry\nof the project map. If a plugin is a matter of user convenience rather\nthan a requirement for running the project, users should place the\nplugin declaration in the `:user` profile in `~/.lein/profiles.clj`\ninstead of directly in the `project.clj` file.\n\n## Not Writing a Plugin (无为)\n\nThe first thing to do when writing a plugin is to try to accomplish\nwhat you're doing without a plugin.\n\nEarly on in the days of Leiningen many plugins were written which did\nnothing but provide a short command to run a specific function using\n`eval-in-project`. Once Leiningen added the support for\npartially-applied aliases these became largely redundant, because you\ncan add an alias to the `run` task:\n\n    :aliases {\"mytest\" [\"run\" \"-m\" \"mylib.test/go\"]}\n\nNot only does this allow `lein mytest` to run the `mylib.test/go`\nfunction inside the context of your project, it also passes additional\narguments (such as in the case of `lein run mytest :integration`) on\nto the function specified. However, for some plugins this wasn't\nenough as they needed access to values in the project map. For\ninstance, a test runner would need to know the value of `:test-paths`\nto know which directory to scan for tests.\n\nIt's possible to get this data from an alias, removing the need for a\nplugin.\n\n    :aliases {\"mytest\" [\"run\" \"-m\" \"mylib.test/go\" :project/test-paths]}\n\nThis will load the `:test-paths` value from the project map and pass a\nstring representation of it as the first argument to the function\nspecified in the alias, followed by any command-line arguments given\nto the `mytest` alias. It's up to the function to call `read-string`\non that argument.\n\nHowever, if you need to call other Leiningen functions or have no need\nto run anything inside the context of the project's own process,\nmaking a plugin might be the right choice if one doesn't\n[exist already](https://wiki.leiningen.org/Plugins).\n\n## Writing a Plugin\n\nStart by generating a new project with `lein new plugin\nmyplugin`, and edit the `myplugin` defn in the\n`leiningen.myplugin` namespace. You'll notice the `project.clj` file\nhas `:eval-in-leiningen true`, which causes all tasks to operate\ninside the leiningen process rather than starting a subprocess to\nisolate the project's code. Plugins need not declare a dependency on\nClojure itself; in fact\n[all of Leiningen's own dependencies](https://codeberg.org/leiningen/leiningen/src/stable/project.clj)\nwill be available.\n\nSee the `lein-pprint` directory\n[in the Leiningen source](https://codeberg.org/leiningen/leiningen/src/stable/lein-pprint)\nfor a sample of a very simple plugin.\n\nWhen emitting output, please use `leiningen.core.main/info`,\n`leiningen.core.main/warn`, and `leiningen.core.main/debug` rather than\n`println` since these will respect the user's output settings.\n\n### Local development\n\nWhen you're ready to test your plugin in a separate project you can include it via the following (example a plugin named sample-plugin):\n\n```\nlein install\nCreated ~/sample-plugin/target/sample-plugin-0.1.0-SNAPSHOT.jar\nWrote ~/sample-plugin/pom.xml\nInstalled jar and pom into local repo.\n```\n\nThis will build a jar using the :version listed in the plugin's project.clj file (see above for example project.clj) and install it into your local m2 repository (~/.m2/repository)\n\nAfter this step completes you can now list your plugin in your separate project with the version outputted from above. This example would look like this:\n\n```\n...\n:plugins [[sample-plugin \"0.1.0-SNAPSHOT\"]]\n...\n```\n\nDuring local development, having to re-run `lein install` in your\nplugin project and then switch to a test project can be very\ncumbersome. In order to avoid this annoyance, you can do the following:\n\n 1. If you haven't done it yet, run `lein install` in the plugin's project\n    directory.\n 2. Just to make sure, run `lein help <plugin-name>` in your test project\n    directory. A help message for your plugin should be displayed now. Or an\n    exception originating in your plugin.\n 3. Add the path to the `src` directory of your plugin to the file\n    `.lein-classpath` in your test project directory. Probably you'll have to\n    create that file.\n 4. If your plugin depends on another library that you are also working on, then\n    that needs to be added to `.lein-classpath` with the classpath separator,\n    either `:` for unix, or `;` for Windows. The same goes for your plugin's\n    other direct dependencies. Run `lein classpath` in order to get an idea how\n    the contents of `.lein-classpath` are supposed to look.\n 5. Remove the entry for your plugin from the test project's `project.clj`.\n    Otherwise it would override what you've added to `.lein-classpath`, because\n    Leiningen loads those things before it loads plugins.\n\n### Task Arguments\n\nThe first argument to your task function should be the current\nproject. It will be a map which is based on the `project.clj` file,\nbut it also has `:name`, `:group`, `:version`, and `:root` keys added\nin, among other things. Try using the `lein-pprint` plugin to see what\nproject maps look like; you can invoke the `pprint` task to examine\nany project or combination of profiles.\n\nIf you want your task to take parameters from the command-line\ninvocation, you can make the function take more than one argument. In\norder to underscore the fact that tasks are just Clojure functions,\narguments which act as flags are usually accepted as `:keywords`\nrather than unixy traditional `--dashed` syntax. Note that all arguments are\nstill passed in as strings; it's up to your function to call `read-string`\non the arguments if you want keywords, symbols, integers, etc. Keep\nthis in mind when calling other tasks as functions too.\n\nMost tasks may only be run in the context of a project. If your\ntask can be run outside a project directory, add `^:no-project-needed`\nas metadata to your task defn to indicate so. Your task must still\naccept a project as its first argument, but it will be allowed to be\nnil. Leiningen will still pass you the project as first argument if\nlein is called from within a project. If called outside of a project,\nlein will send in profile information from `$HOME/.lein/profiles.clj`\nand similar sources as a map similar to a project map. Other tools using\nthe `leiningen-core` library (IDE integration, etc) may decide to just\npass in nil. To distinguish between a project and non-project, check for\nthe `:root` key. If it's set, then you are in a project, otherwise you\nare not.\n\n### Documentation and subtasks\n\nThe `lein help` task uses docstrings. A namespace-level docstring will\nbe used as the short summary if present; if not then it will take the\nfirst line of your function's docstring. Try to keep the summary under\n68 characters for formatting purposes. The full docstring can of\ncourse be much longer but should still be wrapped at 80 columns. The\nfunction's arglists will also be shown, so pick argument names that\nare clear and descriptive. If you set `:help-arglists` in the\nfunction's metadata, it will be used instead for those cases where\nalternate arities exist that aren't intended to be exposed to the\nuser. Be sure to explain all these arguments in the docstring. Note\nthat all your arguments will be strings, so it's up to you to call\n`read-string` on them if you want keywords, numbers, or symbols.\n\nOften more complicated tasks get divided up into subtasks. Placing\n`:subtasks` metadata on a task defn which contains a vector of subtask\nvars will allow `lein help $TASK_CONTAINING_SUBTASKS` to list them.\nThis list of subtasks will show the first line of the docstring for each\nsubtask. The full help for a subtask can be viewed via\n`lein help $TASK_CONTAINING_SUBTASKS $SUBTASK`.\n\nNote that Leiningen doesn't have a mechanism for automatically invoking\nsubtasks. You'll have to do that yourself in the main task. A dumb\nimplementation of it all might look like this:\n\n```clojure\n(defn my-task\n  \"Automatically write all the project's code.\"\n  {:subtasks [#'my-subtask-0 #'my-subtask-1]}\n  [project & [sub-name]]\n  (case sub-name\n    \"my-subtask-0\" (my-subtask-0 project args)\n    \"my-subtask-1\" (my-subtask-1 project args)\n    nil            :not-implemented-yet\n    (leiningen.core.main/warn \"Unknown task.\")))\n```\n\nLeiningen will intercept calls to `lein $MYTASK help` by default and\nturn them into `lein help $MYTASK`. If your task provides its own help\nsubtask you can add `^:pass-through-help` metadata to your task defn\nto opt-out of this behaviour.\n\n## Code Evaluation\n\nPlugin functions run inside Leiningen's process, so they have access\nto all the existing Leiningen functions. The public API of Leiningen\nshould be considered all public functions inside the\n`leiningen.core.*` namespaces not labeled with `^:internal` metadata\nas well as each individual task functions. Other non-task functions in\ntask namespaces should be considered internal and may change inside\npoint releases.\n\n### Evaluating In Project Context\n\nMany tasks need to execute code inside the context of the project\nitself. The `leiningen.core.eval/eval-in-project` function is used for\nthis purpose. It accepts a project argument as well as a form to\nevaluate, and the final (optional) argument is another form called\n`init` that is evaluated up-front before the main form. This may be\nused to require a namespace earlier in order to avoid the\n[Gilardi Scenario](https://technomancy.us/143).\n\nInside the `eval-in-project` call the project's own classpath will be\nactive and Leiningen's own internals and plugins will not be\navailable.\n\nYou can modify the project map before you pass it into `eval-in-project`.\nHowever, it's recommended that you make your modifications by merging a\nprofile in so users can override your changes if necessary. Use\n`leiningen.core.project/merge-profiles` to make your changes:\n\n```clj\n(def swank-profile {:dependencies [['swank-clojure \"1.4.3\"]]})\n\n(defn swank\n  \"Launch swank server for Emacs to connect. Optionally takes PORT and HOST.\"\n  [project port host & opts]\n    (let [profile (or (:swank (:profiles project)) swank-profile)\n          project (project/merge-profiles project [profile])]\n      (eval-in-project project\n                       `(swank.core/-main ~@opts)\n                       '(require 'swank.core))))\n```\n\nThe code in the `swank-clojure` dependency is needed inside the\nproject, so it's declared in its own profile map and merged\nin. However, we defer to the `:swank` profile in the project map if\nit's present so that the user can pick their own version of the\ndependency if they like rather than relying on the hard-coded profile\nin the plugin.\n\nNote that the snippet above is not a good example of a plugin since it\nsimply wraps `eval-in-project` and `merge-profiles`. If that is all\nyou want, you can do it without implementing a plugin; just define an\nalias that uses the `with-profiles` and `run` tasks to call the\nfunction you need.\n\nBefore `eval-in-project` is invoked, Leiningen must \"prep\" a project,\nusually by ensuring that all Java code and all necessary Clojure code\nhas been AOT compiled to bytecode. This is done by running all the\ntasks in the `:prep-tasks` key of the project, which defaults to\n`[\"javac\" \"compile\"]`. If your plugin requires another kind of\nprepping, (for instance, compiling protocol buffers) you can instruct\nusers to add another entry to `:prep-tasks`. Note that this task will\nbe invoked for **every** `eval-in-project`, so take care that it runs\nquickly if nothing has changed since the last run.\n\n## Other Plugin Contents\n\nPlugins are primarily about providing tasks, but they can also contain\nprofiles, hooks, middleware, wagons (dependency transport methods),\nand vcs methods.\n\n### Profiles\n\nIf there is configuration that is likely to be used by many projects\nusing your plugin, yet for some reason you can't make that\nconfiguration active by default, you can include profiles inside your\nplugin.\n\nCreate a file called `resources/myplugin/profiles.clj` in your plugin that\ncontains a map:\n\n```clj\n{:default {:x \"y and z\"}\n :extra {:other \"settings\"}}\n```\n\nEach value here is a profile that your users can merge into their\nproject. You can do this explicitly on a per-invocation basis using\n`with-profile`:\n\n    $ lein with-profile plugin.myplugin/extra test\n\nUsers can also have profiles activated automatically by changing the `:default` profile:\n\n```clj\n:profiles {:default [:base :system :user :provided :dev :plugin.myplugin/default]\n           :other {...}}\n```\n\nEverything in the `:default` profile is active for all\nnon-`with-profile` task invocations except for those which produce\ndownstream artifacts, like `jar`, `uberjar`, and `pom`.\n\n### Hooks\n\n**Note**: Leiningen supports loading hooks from plugins; however this\nmechanism is extremely error-prone and difficult to debug. It should\nbe considered deprecated as of 2.8.0 onward and will continue to work\nuntil version 3.0 but is strongly advised against.\n\nYou can modify the behaviour of built-in Leiningen tasks to a degree\nusing hooks. Hook functionality is provided by the\n[Robert Hooke](https://github.com/technomancy/robert-hooke) library,\nwhich is included with Leiningen.\n\nInspired by clojure.test's fixtures functionality, hooks are functions\nwhich wrap other functions (often tasks) and may alter their behaviour\nby binding other vars, altering the return value, only running the function\nconditionally, etc. The `add-hook` function takes a var of the task it's\nmeant to apply to and a function to perform the wrapping:\n\n```clj\n(ns lein-integration.plugin\n  (:require [robert.hooke]\n            [leiningen.test]))\n\n(defn add-test-var-println [f & args]\n  `(binding [~'clojure.test/assert-expr\n             (fn [msg# form#]\n               (println \"Asserting\" form#)\n               ((.getRawRoot #'clojure.test/assert-expr) msg# form#))]\n     ~(apply f args)))\n\n;; Place the body of the activate function at the top-level for\n;; compatibility with Leiningen 1.x\n(defn activate []\n  (robert.hooke/add-hook #'leiningen.test/form-for-testing-namespaces\n                         #'add-test-var-println))\n```\n\nHooks compose, so be aware that your hook may be running inside\nanother hook. See\n[the documentation for Hooke](https://github.com/technomancy/robert-hooke/blob/master/README.md)\nfor more details. Note that calls to `add-hook` should use the var for\nboth the first and second argument so that hooks can be loaded\nrepeatedly without re-adding the hook. This is because in Clojure\nbare functions cannot be compared for equality, but vars can.\n\nIf you want your hooks to be loaded automatically when other projects\ninclude your plugin, activate them in a function called\n`plugin-name.plugin/hooks`. So in the example above the plugin is\ncalled `lein-integration`, and the function\n`lein-integration.plugin/hooks` is automatically called to activate\nhooks when the `lein-integration` plugin is loaded.\n\nHooks can also be loaded manually by setting the `:hooks` key in project.clj to\na seq of vars to call to activate your hooks. For backward compatibility, you\ncan also specify namespaces instead of vars in `:hooks`, and the `activate`\nfunction in that namespace will be called. Note: automatic hooks are activated\nbefore manually specified hooks.\n\n### Project Middleware\n\nProject middleware is just a function that is called on a project map\nreturning a new project map. Middleware gives a plugin the power to do\nany kind of transformation on the project map. However, problems with\nmiddleware can be difficult to debug due to their flexibility and\nopaqueness. If you can do what you need using profiles inside your\nplugins instead, that is a much more declarative, introspectable way\nto do things which will save a lot of headache down the line.\n\nProjects use middleware by adding `:middleware` as a vector of var\nnames into their `project.clj`:\n\n```clj\n  :middleware [leiningen.inject/middleware]\n```\n\nAlso note that the currently active middleware depends on which\nprofiles are active. This means we need to reapply the middleware\nfunctions to the project map whenever the active profiles change. We\naccomplish this by storing the fresh project map and starting from\nthat whenever we call `merge-profiles`, `unmerge-profiles` or\n`set-profiles`. It also means your middleware functions shouldn't have\nany non-idempotent side-effects since they could be called repeatedly.\n\nIf you need to include a profile in the project map, please add it as a plugin\nprofile and ask your users to add it to the `:base` profile as outlined in the\n\"Plugin\" subsection of \"Other Plugin Contents\" in this document. This makes the\n\"injection\" more explicit and easier to debug. The only times one should use\nmiddleware to inject values into the project map is if the profiles has to be\nprogrammatically computed, or if you have to modify the project map in a way\nthat is not possible with `merge-profiles`.\n\nNote that middleware application will be memoized unless the\n`:memoize-middleware?` key is set to `false`.\n\n**Note**: Leiningen supports loading middleware implicitly when the\nmiddleware is named `plugin-name.plugin/middleware`; however this\nmechanism is even more difficult to debug than regular middleware. It\nis strongly advised against using.\n\n### Maven Wagons\n\n[Pomegranate](https://github.com/cemerick/pomegranate) (the library\nused by Leiningen to resolve dependencies) supports registering\n\"wagon\" factories. Wagons are used to handle non-standard transport\nprotocols for repositories, and are looked up based on the protocol of\nthe repository url. If your plugin needs to register a wagon factory,\nit can do so by providing a `leiningen/wagons.clj` file containing a\nmap of protocols to functions that return wagon instances for the\nprotocol. For example, the following `wagons.clj` will register a\nwagon factory function for `dav:` urls:\n\n```clj\n{\"dav\" #(org.apache.maven.wagon.providers.webdav.WebDavWagon.)}\n```\n\nSee [S3 wagon private](https://github.com/technomancy/s3-wagon-private) or\n[lein-webdav](https://github.com/tobias/lein-webdav) for full examples of\nplugins using this technique.\n\n### VCS Methods\n\nLeiningen ships with a `vcs` task which performs a handful of\nrelease-related version control tasks via multimethods. Out of the box\nit contains implementations for Git, but plugins can add support for\nmore systems by including a `leiningen.vcs.$SYSTEM` namespace. All\nnamespaces under the `leiningen.vcs.` prefix will be loaded when the\n`vcs` task is invoked. These namespaces should simply define methods\nfor the `defmulti`s in `leiningen.vcs` that invoke the specific\nversion control system.\n\n## Requiring Plugins\n\nTo use a plugin in your project, just add a `:plugins` key to your project.clj\nwith the same format as `:dependencies`. In addition to the options allowed by\n`:dependencies`, `:plugins` also allows you to disable auto-loading of hooks or\nmiddleware.\n\n```clj\n(defproject foo \"0.1.0\"\n  :plugins [[lein-pprint \"1.1.1\"]\n            [lein-foo \"0.0.1\" :hooks false]\n            [lein-bar \"0.0.1\" :middleware false]])\n```\n\n## Clojure Version\n\nIf you need to use a specific, fixed version of Clojure from within a\nLeiningen plugin, you can use `eval-in-project` with a dummy project\nargument:\n\n```clj\n(eval-in-project {:dependencies '[[org.clojure/clojure \"1.4.0\"]]}\n                 '(println \"hello from\" *clojure-version*))\n```\n\n## Projects vs Standalone Execution\n\nSome Leiningen tasks can be executed from any directory (e.g. `lein repl`).\nSome only make sense in the context of a project.\n\nTo check whether Leiningen is running in the context of a project\n(that is, if a `project.clj` is present in the current directory),\ncheck for the `:root` key in the project map:\n\n``` clojure\n(if (:root project)\n  (comment \"Running in a project directory\")\n  (comment \"Running standalone\"))\n```\n\nIf your plugin may run outside the context of the project entirely,\nyou should still leave room in the arguments list for a project map;\njust expect that it will be nil if there's no project present. Use\n`^:no-project-needed` metadata to indicate this is acceptable.\n\nTasks should call the `leiningen.core.main/abort` function when a\nfatal error is encountered. If the\n`leiningen.core.main/*exit-process?*` var is bound to true, then this\nwill trigger an exit, but in some contexts (like `with-profiles`) it\nwill simply trigger an exception and go on to the next task.\n\n## Overriding Built-in Tasks\n\nNormally if you create a plugin containing (say) a `leiningen.compile`\nnamespace, it won't be used when `lein compile` is run; the built-in\ntask will override it. If you'd like to shadow a built-in task, you\ncan either create an alias or put it in the `leiningen.plugin.compile`\nnamespace.\n\n## Project-specific Tasks\n\nOccasionally, the need arises for a task to be included in a project's\ncodebase. However, this is much less common than people think. If you\nsimply have some code that needs to be invoked from the command-line\nit's much simpler to have your code run in a `-main` function inside your\nproject and invoke it with an alias like `lein garble`:\n\n```clj\n:aliases {\"garble\" [\"run\" \"-m\" \"myproject.garble\" \"supergarble\"]}\n```\n\nNote that aliases vectors result in partially applied task functions,\nso with the above config, `lein garble seventeen` would be equivalent\nto `lein run -m myproject.garble supergarble seventeen` (or\n`(myproject.garble/-main \"supergarble\" \"seventeen\")` from the\nrepl). The arguments in the alias are concatenated to the arguments\nprovided when it's invoked.\n\nYou only need to write a Leiningen task if you need to operate outside\nthe context of your project, for instance if you need to adjust the\nproject map before calling `eval-in-project` or some other task where\nyou need direct access to Leiningen internals. You can even read values\nfrom the project map with an alias:\n\n```clj\n:aliases {\"garble\" [\"run\" \"-m\" \"myproject.garble\" :project/version]}\n```\n\nThis will splice the value of the project map's `:version` field into\nthe argument list so that the `-main` function running inside the\nproject code gets access to it.\n\nThe vast majority of these cases are already covered by\n[existing plugins](https://wiki.leiningen.org/Plugins),\nbut if you have a case that doesn't exist and for some reason can't\nspin it off into its own separate plugin, you can enable this behavior\nby placing the `foo.clj` file defining the new task in\n`tasks/leiningen/` and add `tasks` to your `.lein-classpath`:\n\n```\n$ ls\nREADME.md project.clj src tasks test\n$ ls -R tasks\nleiningen\n\ntasks/leiningen:\nfoo.clj\n$ echo -ne \":tasks\" | cat >> .lein-classpath\n$ lein foo\nHello, Foo!\n```\n\nNote that in most cases it's better to spin off tasks into their own\nplugin projects; using `.lein-classpath` is mainly appropriate for\nexperimentation or cases when there isn't enough time to create a\nproper plugin.\n\n## Have Fun\n\nPlease add your plugin to [the list on the\nwiki](https://wiki.leiningen.org/Plugins) once it's ready.\n\nHopefully the plugin mechanism is simple and flexible enough to let\nyou bend Leiningen to your will.\n"
  },
  {
    "path": "doc/PROFILES.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Profiles](#profiles)\n  - [Declaring Profiles](#declaring-profiles)\n  - [Default Profiles](#default-profiles)\n  - [Task Specific Profiles](#task-specific-profiles)\n  - [Profile Metadata](#profile-metadata)\n  - [Merging](#merging)\n  - [Activating Profiles](#activating-profiles)\n  - [Composite Profiles](#composite-profiles)\n  - [Dynamic Eval](#dynamic-eval)\n  - [Debugging](#debugging)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# Profiles\n\nYou can change the configuration of your project by applying various\nprofiles. For instance, you may want to have a few extra test data\ndirectories on the classpath during development without including them\nin the jar, or you may want to have development tools like\n[Slamhound](https://github.com/technomancy/slamhound) available in\nevery project you hack on without modifying every single `project.clj`\nyou use.\n\nYou can place any arbitrary key/value pairs supported by `defproject`\ninto a given profile and they will be merged into the project map when\nthat profile is activated.\n\nThe example below adds a \"dummy-data\" resources directory during\ndevelopment and a dependency upon \"expectations\" that's only used for\ntests/development.\n\n```clj\n(defproject myproject \"0.5.0-SNAPSHOT\"\n  :description \"A project for doing things.\"\n  :dependencies [[org.clojure/clojure \"1.4.0\"]]\n  :profiles {:dev {:resource-paths [\"dummy-data\"]\n                   :dependencies [[expectations \"1.4.41\"]]}})\n```\n\nUse the `show-profiles` task to list the project's profiles.\n\n## Declaring Profiles\n\nIn addition to `project.clj`, profiles also can be specified in `profiles.clj`\nwithin the project root. Profiles specified in `profiles.clj` will override\nprofiles in `project.clj` (via [merging](#merging) logic described below), so\nthis can be used for project-specific overrides that you don't want committed\nin version control.\n\nUser-wide profiles can also be specified in\n`~/.lein/profiles.clj`. These will be available in all projects\nmanaged by Leiningen, though those profiles will be overridden by\nprofiles of the same name specified in the project.  System-wide\nprofiles can be placed in `/etc/leiningen/profiles.clj`. They are\ntreated the same as user profiles, but with lower precedence.\n\nYou can also define user-wide profiles within `clj`-files inside\n`~/.lein/profiles.d`. The semantics within such files differ slightly\nfrom other profile files: rather than a map of maps, the profile map\nis the top-level within the file, and the name of the profile comes\nfrom the file itself (without the `.clj` part). Defining the same\nuser-wide profile in both `~/.lein/profiles.clj` and in\n`~/.lein/profiles.d` is considered an error.\n\n## Default Profiles\n\nCertain profiles are active by default unless you specify another set\nof profiles using the `with-profile` task. Each of the default\nprofiles have different semantics:\n\nIf you want to access dependencies or plugins during development time\nfor any project place them in your `:user` profile. Your\n`~/.lein/profiles.clj` file could look something like this:\n\n```clj\n{:user {:plugins [[lein-pprint \"1.1.1\"]]\n        :dependencies [[slamhound \"1.3.1\"]]}}\n```\n\nThe `:dev` profile is used to specify project specific development\ntooling. Put things here if they are required for builds or tests,\nrather than just convenience tooling.\n\nThe `:user` profile is separate from `:dev`; the latter is intended to\nbe specified in the project itself. In order to avoid collisions, the\nproject should never define a `:user` profile, nor should a user-wide\n`:dev` profile be defined.  Likewise, system profiles should use the\n`:system` profile, and define neither `:user` nor `:dev` profiles.\n\nThe `:system` profile is similar to `:user`, except it applies\nsystem-wide instead of merely to a single user.\n\nThe `:base` profile provides dependencies necessary for basic repl\nfunctionality, adds `dev-resources` to the `:resource-paths`, and sets\ndefaults for `:jvm-opts`, `:checkout-deps-share` and\n`:test-selectors`. It is part of Leiningen itself; you shouldn't need\nto change it.\n\nThe profiles listed above are active during development, but they are\nunmerged before the jar and pom files are created, making them\ninvisible to code that depends upon your project.\n\nThe `:provided` profile is used to specify dependencies that should be\navailable during jar creation, but not propagated to other code that\ndepends on your project. These are dependencies that the project\nassumes will be provided by whatever environment the jar is used in,\nbut are needed during the development of the project. This is often\nused for frameworks like Hadoop that provide their own copies of\ncertain libraries.\n\nThe `:default` profile specifies the profiles that are active by\ndefault when running lein tasks.  If not overridden, this is set to\n`:leiningen/default`, which is a composite profile with\n`[:base :system :user :provided :dev]`.\n\n## Task Specific Profiles\n\nSome tasks automatically merge a profile if specified.  Examples of\nthese are the `:test` profile, when running the `test` task, and the\n`:repl` profile, when running the `repl` task. Please note that\nputting things in the `:test` profile is strongly advised against as\nit can result in tests which can't be run from the repl.\n\n## Profile Metadata\n\nIf you mark your profile with `^:leaky` metadata, then the profile\nwill not be stripped out when the pom and jar files are created.\n\nIf you mark a profile with `^{:pom-scope :test}` metadata, then the\nprofile's `:dependencies` will be added with a `test` scope in the\ngenerated pom and jar when active. The `:dev`, `:test`, and `:base`\nprofiles have this set automatically.\n\nIf you mark a profile with `^{:pom-scope :provided}` metadata, then\nthe profile's `:dependencies` will be added with a `provided` scope in\nthe generated pom and jar when active. The `:provided` profile has\nthis set automatically.\n\n## Merging\n\nProfiles are merged by taking each key in the project map or profile\nmap, combining the value if it's a collection and replacing it if it's\nnot. Profiles specified later take precedence when replacing, just\nlike the `clojure.core/merge` function. The dev profile takes\nprecedence over user by default. Maps are merged recursively, sets are\ncombined with `clojure.set/union`, and lists/vectors are\nconcatenated. You can add hints via metadata that a given value should\ntake precedence (`:replace`) or defer to values from a different\nprofile (`:displace`) if you want to override this logic:\n\n```clj\n{:profiles {:dev {:prep-tasks ^:replace [\"clean\" \"compile\"]\n                  :aliases ^:displace {\"launch\" \"run\"}}}}\n```\n\nThe exception to this merge logic is that `:plugins` and `:dependencies`\nhave custom de-duplication logic since they must be specified as\nvectors even though they behave like maps (because it only makes sense\nto have a single version of a given dependency present at once). The\nreplace/displace metadata hints still apply though.\n\nRemember that if a profile with the same name is specified in multiple\nlocations, only the profile with the highest \"priority\" is picked – no merging\nis done. The \"priority\" is – from highest to lowest – `profiles.clj`,\n`project.clj`, user-wide profiles, and finally system-wide profiles.\n\nIf you need to enable personal overrides of parts of a profile, you can use a\ncomposite profile with common and personal parts - something like `:dev\n[:dev-common :dev-overrides]`; you would then have just `:dev-overrides {}` in\n`project.clj` and override it in `profiles.clj`.\n\nAnother use of profiles is to test against various sets of dependencies:\n\n```clj\n(defproject swank-clojure \"1.5.0-SNAPSHOT\"\n  :description \"Swank server connecting Clojure to Emacs SLIME\"\n  :dependencies [[org.clojure/clojure \"1.2.1\"]\n                 [clj-stacktrace \"0.2.4\"]\n                 [cdt \"1.2.6.2\"]]\n  :profiles {:1.3 {:dependencies [[org.clojure/clojure \"1.3.0\"]]}\n             :1.4 {:dependencies [[org.clojure/clojure \"1.4.0-beta1\"]]}})\n```\n\n## Activating Profiles\n\nTo activate a different set of profiles for a given task, use the\n`with-profile` higher-order task:\n\n    $ lein with-profile 1.3 test :database\n\nMultiple profiles may be combined with commas:\n\n    $ lein with-profile qa,user test :database\n\nMultiple profiles may be executed in series with colons:\n\n    $ lein with-profile 1.3:1.4 test :database\n\nThe above invocations activate the given profiles in place of the\ndefaults. To activate the profiles in addition to the defaults, prepend\nthem with a `+`:\n\n    $ lein with-profile +server,+fast run\n\nYou can also use `-` to deactivate profiles.\n\nBy default all profiles will share the same `:target-path`, which can\ncause problems if settings from one profile leak over into\nanother. It's recommended to set `:target-path` to `\"target/%s\"`,\nwhich will isolate each profile set and prevent anything from bleeding over.\n\n## Composite Profiles\n\nSometimes it is useful to define a profile as a combination of other\nprofiles. To do this, just use a vector instead of a map as the profile value.\nThis can be used to avoid duplication:\n\n```clj\n{:shared {:port 9229, :protocol \"https\"}\n :qa-servers {:servers [\"qa.mycorp.com\"]}\n :prod-servers {:servers [\"prod1.mycorp.com\", \"prod1.mycorp.com\"]}\n :qa [:shared :qa-servers]\n :production [:shared :prod-servers]}\n```\n\nThe vector should contain keywords referencing other profiles which\nwill be merged together.\n\nWhile it is possible to make a composite profile which contains both\nkeywords and maps, this will become an error in a future version of Leiningen.\n\nComposite profiles also cannot have certain types of metadata\npropagated, which makes them incompatible with the `:provided`\nprofile. If you get the error \"Composite profiles are incompatible with :provided.\"\nconsider adding `^{:pom-scope :provided}` metadata to the profile map\nwhich contains the dependencies instead.\n\n## Dynamic Eval\n\nOften you want to read an environment variable or execute a function to capture\na value to use in your profiles. In order to do such a thing with the profiles.clj\nyou'll need to use the read-eval syntax.\n\nHere is an example of such a case:\n\n```clj\n{:user {:compile-path  #=(eval (System/getenv \"ci.compile-path\")),\n        :target-path #=(eval (System/getenv \"ci.target-path\"))}}\n```\n\n## Debugging\n\nTo see how a given profile affects your project map, use the\n[lein-pprint](https://codeberg.org/leiningen/leiningen/src/stable/lein-pprint)\nplugin:\n\n    $ lein with-profile 1.4 pprint\n    {:compile-path \"/home/phil/src/leiningen/lein-pprint/classes\",\n     :group \"lein-pprint\",\n     :source-path (\"/home/phil/src/leiningen/lein-pprint/src\"),\n     :dependencies\n     ([nrepl \"0.8.3\" :exclusions [org.clojure/clojure]]\n      [incomplete \"0.1.0\" :exclusions [org.clojure/clojure]]\n      [org.thnetos/cd-client \"0.3.3\" :exclusions [org.clojure/clojure]]),\n     :target-path \"/home/phil/src/leiningen/lein-pprint/target\",\n     :name \"lein-pprint\",\n     [...]\n     :description \"Pretty-print a representation of the project map.\"}\n\nIn order to prevent profile settings from being propagated to other\nprojects that depend upon yours, the `:default` profiles are removed\nfrom your project when generating the pom, jar, and uberjar, and an\n`:uberjar` profile, if present, is included when creating\nuberjars. (This can be useful if you want to specify a `:main`\nnamespace for uberjar use without triggering AOT during regular\ndevelopment.) Profiles activated through an explicit `with-profile`\ninvocation will be preserved.\n"
  },
  {
    "path": "doc/TEMPLATES.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Writing Templates](#writing-templates)\n  - [Structure](#structure)\n  - [Templating System](#templating-system)\n      - [A warning about Mustache tag delimiters](#a-warning-about-mustache-tag-delimiters)\n  - [Distributing your Template](#distributing-your-template)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n# Writing Templates\n\nSuppose you've written a fabulously popular library, used the world\nover by adoring fans. For the purposes of this document, let's say\nthis library is called \"liquid-cool\". If using liquid-cool takes a bit\nof setup, or if you'd just like to give your users a little guidance\non how one might best create a new project which uses liquid-cool, you\nmight want to provide a template for it (just like how `lein` already\nprovides built-in templates for \"app\", \"plugin\", and so on).\n\nLet's assume you have a library called \"liquid cool\" which lives on\nClojars as `us.technomancy/liquid-cool`. You can name your template\nafter your library. You could also use a different name, but note that\nin order to comply with the new [Clojars\npolicies](https://github.com/clojars/clojars-web/wiki/Verified-Group-Names)\nyou can't create a new group-id unless you can verify ownership of it.\n\nCreate a template for it like so:\n\n    lein new template us.technomancy/liquid-cool --to-dir liquid-cool-template\n\nYour new template would look like:\n\n    liquid-cool-template/\n    ├── CHANGELOG.md\n    ├── LICENSE\n    ├── project.clj\n    ├── README.md\n    ├── resources\n    │   └── leiningen\n    │       └── new\n    │           └── liquid_cool\n    │               └── foo.clj\n    └── src\n        └── leiningen\n            └── new\n                └── liquid_cool.clj\n\nNote that you'll now have a new and separate project named\n\"liquid-cool-template\". It will have a group-id of \"us.technomancy\", and\nan artifact-id of \"lein-template.liquid-cool\".\n\n## Structure\n\nThe files that your template will provide to users are in\n`resources/leiningen/new/liquid_cool`. The template generator\nstarts you off with just one, named \"foo.clj\". You can see it referenced in\n`src/leiningen/new/liquid_cool.clj`, right underneath the\n`->files data` line.\n\nYou can delete `foo.clj` if you like (and its corresponding line in\n`liquid_cool.clj`), and start populating that\n`resources/leiningen/new/liquid_cool` directory with the files\nyou wish to be part of your template. For everything you add, make sure the\n`liquid_cool.clj` file receives corresponding entries in that `->files`\ncall. For examples to follow, have a look inside [the \\*.clj files for the\nbuilt-in\ntemplates](https://codeberg.org/leiningen/leiningen/src/stable/resources/leiningen/new).\n\n## Testing Your Template\n\nWhile developing a template, if you're in the template project directory, \nleiningen will pick it up and you'll be able to test it.  e.g. from the\n`liquid-cool-template` dir:\n\n    $ lein new us.technomancy/liquid-cool myproject\n\nwill create a directory called `myproject`, built from your template.\nAlternately, if you want to test your template from another directory on\nyour system (without publishing your template to clojars yet), just run:\n\n    $ lein install\n\nYou should then be able to run `lein new us.technomancy/liquid-cool myproject`\nfrom any directory on your system.\n\n## Templating System\n\nThe default generated template uses [stencil][] for templating, which implements the\nlanguage-agnostic templating system [Mustache][]. All the available tag types\ncan be found in the [Mustache manual][mustache-manual]; we will only go through\nthe most common tag type here.\n\nSuppose we want to add in a standard markdown readme file where the input name\nis the main header of the file. To be able to do so, we must do two things:\nEnsure that the input name is contained within the `data` mapped to the key X,\nand that we have a template file which looks up the key X by wrapping it in\ndouble mustaches like so: `{{X}}`. As for our input name, `data` already\ncontains the line `:name name`, which means we can lookup the input name by\nwriting `{{name}}` in the template file. To try it out, save the following\ncontents in the file `resources/leiningen/new/liquid_cool/README.md`:\n\n```markdown\n# {{name}}\n\nThis is our readme!\n```\n\nAnd add the following line right underneath the `->files data` line:\n\n```clj\n[\"README.md\" (render \"README.md\" data)]\n```\n\nNow, if we for instance say `lein new us.technomancy/liquid-cool\nliquid-cool-app`, the newly generated project will contain a file named\n`README.md` where the header is `liquid-cool-app`.\n\n[stencil]: https://github.com/davidsantiago/stencil\n[Mustache]: https://mustache.github.io/\n[mustache-manual]: https://mustache.github.io/mustache.5.html\n\n#### A warning about Mustache tag delimiters\nClojure syntax can conflict with the default mustache tag delimiter. For \nexample, when destructuring a nested map:\n\n```clj\n(let [{{:keys [a b]} :ab} some-map]\n  (do-something a b))\n```\n\nStencil will interpret the `{{` as the start of a mustache tag, but since the\ncontents are not valid mustache, the render fails. To get around this, we can \nchange the mustache delimiter temporarily, like so:\n\n```clj\n{{! Change mustache delimiter to <% and %> }}\n{{=<% %>=}}\n\n(let [{{:keys [a b]} :ab} some-map]\n  (do-something a b))\n\n<%! Reset mustache delimiter %>\n<%={{ }}=%>\n```\n\n## Distributing your Template\n\nTemplates are just maven artifacts, aka dependencies. Particularly,\nthey need only be on the classpath when `lein new` is called. So, as a\nside-effect, you can just put your templates in a jar and toss them on\nClojars and have people install them like normal Leiningen\nplugins. Templates get fetched on demand if they're not found. So\nfor instance `lein new com.heroku/hello myproject` will find the\nlatest version of the `com.heroku/lein-template.hello` project from\nClojars and use that.\n\n## Legacy Templates\n\nPrior to Leiningen 2.9.6, templates defaulted to using the template\nname as the group-id and \"lein-template\" as the artifact-id. Changes\nto [Clojars policy](https://github.com/clojars/clojars-web/wiki/Verified-Group-Names)\nhave necessitated using a new style where every template name includes\na group-id and an artifact-id. The template artifact takes the\ngroup-id but prepends \"lein-template.\" to the artifact-id given in the\ntemplate name.\n\nThe old style is still supported when using an existing template, but it is not\nrecommended for creating new templates.\n"
  },
  {
    "path": "doc/TUTORIAL.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Tutorial](#tutorial)\n  - [What This Tutorial Covers](#what-this-tutorial-covers)\n  - [Getting Help](#getting-help)\n  - [Leiningen Projects](#leiningen-projects)\n  - [Creating a Project](#creating-a-project)\n    - [Directory Layout](#directory-layout)\n    - [Filename-to-Namespace Mapping Convention](#filename-to-namespace-mapping-convention)\n  - [project.clj](#projectclj)\n  - [Dependencies](#dependencies)\n    - [Overview](#overview)\n    - [Artifact IDs, Groups, and Versions](#artifact-ids-groups-and-versions)\n    - [Snapshot Versions](#snapshot-versions)\n    - [Repositories](#repositories)\n    - [Checkout Dependencies](#checkout-dependencies)\n    - [Search](#search)\n  - [Setting JVM Options](#setting-jvm-options)\n  - [Running Code](#running-code)\n  - [Tests](#tests)\n  - [Profiles](#profiles)\n  - [What to do with it](#what-to-do-with-it)\n    - [Uberjar](#uberjar)\n    - [Framework (Uber)jars](#framework-uberjars)\n    - [Server-side Projects](#server-side-projects)\n    - [Publishing Libraries](#publishing-libraries)\n  - [That's It!](#thats-it)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n\n\n# Tutorial\n\nLeiningen is for automating Clojure projects without setting your hair\non fire. If you experience your hair catching on fire or any other\nfrustrations while following this tutorial, please\n[let us know](https://codeberg.org/leiningen/leiningen/issues/new).\n\nIt offers various project-related tasks and can:\n\n * create new projects\n * fetch dependencies for your project\n * run tests\n * run a fully-configured REPL\n * compile Java sources (if any)\n * run the project (if the project isn't a library)\n * generate a maven-style \"pom\" file for the project for interop\n * compile and package projects for deployment\n * publish libraries to repositories such as [Clojars](https://clojars.org)\n * run custom automation tasks written in Clojure (leiningen plug-ins)\n\nIf you come from the Java world, Leiningen could be thought of as\n\"Maven meets Ant without the pain\". For Ruby and Python folks,\nLeiningen combines RubyGems/Bundler/Rake and pip/Fabric in a single\ntool.\n\n\n## What This Tutorial Covers\n\nThis tutorial will briefly cover project structure, dependency\nmanagement, running tests, the REPL, and topics related to deployment.\n\n## Getting Help\n\nAlso keep in mind that Leiningen ships with fairly comprehensive help;\n`lein help` gives a list of tasks while `lein help $TASK` provides\ndetails. Further documentation such as the readme, sample\nconfiguration, and even this tutorial are also provided.\n\n\n## Leiningen Projects\n\nLeiningen works with *projects*. A project is a directory containing a\ngroup of Clojure (and possibly Java) source files, along with a bit of\nmetadata about them. The metadata is stored in a file named\n`project.clj` in the project's root directory, which is how you tell\nLeiningen about things like\n\n * Project name\n * Project description\n * What libraries the project depends on\n * What Clojure version to use\n * Where to find source files\n * What's the main namespace of the app\n\nand more.\n\nMost Leiningen tasks only make sense in the context of a project. Some\n(for example, `repl` or `help`) can also be called from any directory.\n\nNext let's take a look at how projects are created.\n\n## Creating a Project\n\nWe'll assume you've got Leiningen installed as per the\n[README](https://codeberg.org/leiningen/leiningen/src/stable/README.md).\nGenerating a new project is easy:\n\n    $ lein new app my-stuff\n    Generating a project called my-stuff based on the 'app' template.\n\n    $ # see how it looks like using the \"tree\" command\n    $ tree -F -a --dirsfirst my-stuff/\n\n    my-stuff/\n    ├── doc/\n    │   └── intro.md\n    ├── resources/\n    ├── src/\n    │   └── my_stuff/\n    │       └── core.clj\n    ├── test/\n    │   └── my_stuff/\n    │       └── core_test.clj\n    ├── CHANGELOG.md\n    ├── .gitignore\n    ├── .hgignore\n    ├── LICENSE\n    ├── project.clj\n    └── README.md\n\nIn this example we're using the `app` template, which is intended for\nan application project rather than a library. Omitting the `app`\nargument will use the `default` template, which is suitable for\nlibraries.\n\n### Directory Layout\n\nHere we've got your project's README, a `src/` directory containing the\ncode, a `test/` directory, and a `project.clj` file which describes your\nproject to Leiningen. The `src/my_stuff/core.clj` file corresponds to\nthe `my-stuff.core` namespace.\n\n### Filename-to-Namespace Mapping Convention\n\nNote that we use `my-stuff.core` instead of just `my-stuff` since\n[single-segment namespaces are discouraged in Clojure](https://stackoverflow.com/questions/13567078/whats-wrong-with-single-segment-namespaces) as using those would imply classes are being assigned\nto the default (no-name) package.\n\nAlso note that if a Clojure namespaces segment contains a dash (`-`), the\ncorresponding path/filename will contain an underscore (`_`) instead. This is due to the fact that\n[Java disallows dashes in identifiers](https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.8),\nin particular in package and class names. A Clojure \"dash-adorned\" namespace identifier is thus mapped\nto a Java-compatible \"underscore-adorned\" package identifier. This change is reflected in pathnames\nas these must match the package and class names.\n\nThe intricacies of namespaces are a common source of confusion for newcomers, and while they are\nmostly outside the scope of this tutorial you can\nread up on them elsewhere, for example [here](https://8thlight.com/blog/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html) and [here](https://stuartsierra.com/2016/clojure-how-to-ns.html).\n\n## project.clj\n\nYour `project.clj` file will start off looking something like this:\n\n```clojure\n(defproject my-stuff \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.11.4\"]]\n  :main ^:skip-aot my-stuff.core\n  :target-path \"target/%s\"\n  :profiles {:uberjar {:aot :all}})\n```\n\nIf you don't fill in the `:description` with a short sentence, your\nproject will be harder to find in search results, so start there. Be\nsure to fix the `:url` as well. At some point you'll need to flesh out\nthe `README.md` file too, but for now let's skip ahead to setting\n`:dependencies`. Note that Clojure is just another dependency here.\nUnlike most languages, it's easy to swap out any version of Clojure.\n\n## Dependencies\n\n### Overview\n\nClojure is a hosted language and Clojure libraries are distributed the same\nway as in other JVM languages: as [jar](https://en.wikipedia.org/wiki/JAR_(file_format)) files.\n\nJar files are basically just `.zip` files with a little extra JVM-specific\nmetadata. They usually contain `.class` files (JVM bytecode) and `.clj` source\nfiles, but they can also contain other things like config\nfiles, JavaScript files or text files with static data.\n\nPublished JVM libraries have *identifiers* (artifact group, artifact id) and\n*versions* based on [Maven naming conventions](https://maven.apache.org/guides/mini/guide-naming-conventions.html).\n\n### Artifact IDs, Groups, and Versions\n\nYou can [search Clojars](https://clojars.org/search?q=clj-http) using\nits web interface or via `lein search $TERM`. On the Clojars page for\n`clj-http` at the time of this writing it shows this:\n\n```clj\n[clj-http \"3.13.1\"]\n```\n\nYou can copy the Leiningen version directly into the `:dependencies`\nvector in `project.clj`.  So for instance, if you change the\n`:dependencies` line in the example `project.clj` above to\n\n```clj\n:dependencies [[org.clojure/clojure \"1.8.0\"]\n               [clj-http \"3.13.1\"]]\n```\n\nLeiningen will automatically download the `clj-http` jar file and make sure\nit is on your classpath. If you want to explicitly tell `lein` to\ndownload new dependencies, you can do so with `lein deps`, but it will\nhappen on-demand if you don't.\n\nWithin the vector, \"clj-http\" is referred to as the \"artifact id\".\n\"2.0.0\" is the version. Some libraries will also have \"group ids\",\nwhich are displayed like this:\n\n```clj\n[com.cedarsoft.utils.legacy/hibernate \"1.3.7\"]\n```\n\nThe group id is the part before the slash. Especially for Java\nlibraries, it's often a reversed domain name. Clojure libraries often\nuse the same group-id and artifact-id (as with clj-http), in which case\nyou can omit the group-id. If there is a library that's part of a\nlarger group (such as `ring-jetty-adapter` being part of the `ring`\nproject), the group-id is often the same across all the sub-projects.\n\n### Snapshot Versions\n\nSometimes versions will end in \"-SNAPSHOT\". This means that it is not\nan official release but a development build. Relying on snapshot\ndependencies is discouraged but is sometimes necessary if you need bug\nfixes, etc. that have not made their way into a release yet. However,\nsnapshot versions are not guaranteed to stick around, so it's\nimportant that non-development releases never depend upon snapshot versions that\nyou don't control. Adding a snapshot dependency to your project will\ncause Leiningen to actively go seek out the latest version of the\ndependency daily (whereas normal release versions are cached in the local\nrepository) so if you have a lot of snapshots it will slow things\ndown.\n\nNote that some libraries make their group-id and artifact-id\ncorrespond with the namespace they provide inside the jar, but this is\njust a convention. There is no guarantee they will match up at all, so\nconsult the library's documentation before writing your `:require`\nand `:import` clauses.\n\n### Repositories\n\nDependencies are stored in *artifact repositories*. If you are\nfamiliar with Perl's CPAN, Python's PyPi, Ruby's\nrubygems.org, or Node.js's NPM, it's the same thing. Leiningen reuses\nexisting JVM repository infrastructure. There are several popular\nopen source repositories. Leiningen by default will use two of them:\n[clojars.org](https://clojars.org) and\n[Maven Central](https://search.maven.org/).\n\n[Clojars](https://clojars.org/) is the Clojure community's centralized\nMaven repository, while [Central](https://search.maven.org/) is for the\nwider JVM community.\n\nYou can add third-party repositories by setting the `:repositories` key\nin project.clj. See the\n[sample.project.clj](https://codeberg.org/leiningen/leiningen/src/stable/sample.project.clj)\nfor examples on how to do so. This sample uses additional repositories such as the Sonatype\nrepository which gives access to the latest SNAPSHOT development version of a library (Clojure or Java).\nIt also contains other relevant settings regarding repositories such as update frequency.\n\n### Checkout Dependencies\n\nSometimes it is necessary to develop two or more projects in parallel,\nthe main project and its dependencies, but it is very inconvenient to\nrun `lein install` and restart your repl all the time to get your\nchanges picked up. Leiningen provides a solution called *checkout\ndependencies* (or just *checkouts*). To use it, create a directory\ncalled `checkouts` in the project root, like so:\n\n    my-stuff/\n    │\n    ├── checkouts/    <--- here\n    │\n    ├── doc/\n    │   └── intro.md\n    ├── resources/\n    ├── src/\n    │   └── my_stuff/\n    │       └── core.clj\n    ├── test/\n    │   └── my_stuff/\n    │       └── core_test.clj\n    ├── CHANGELOG.md\n    ├── .gitignore\n    ├── .hgignore\n    ├── LICENSE\n    ├── project.clj\n    └── README.md\n\nThen, under the checkouts directory, create symlinks to the root directories of projects you need.\nThe names of the symlinks don't matter: Leiningen just follows all of them to find\n`project.clj` files to use. Traditionally, they have the same name as the directory they point to.\n\n    my-stuff/\n    ├── checkouts/\n    │   ├── commons -> [link to /code/company/commons]\n    │   └── suchwow -> [link to /code/oss/suchwow]\n    .\n\nLibraries located under the `checkouts` directory take precedence over\nlibraries pulled from repositories, but this is not a replacement for listing\nthe project in your main project's `:dependencies`; it simply supplements\nthat for convenience. The project in `:dependencies` must be able to be\nresolved, either from a remote repo or via `lein install` locally. That is,\ngiven the above directory hierarchy, `project.clj` should contain something\nlike:\n\n```clj\n:dependencies [[org.clojure/clojure \"1.9.0\"]\n               ...\n               [suchwow \"0.3.9\"]\n               [com.megacorp/commons \"1.3.5\"]\n               ...]\n```\n\nNote here that the Maven groupid `com.megacorp` has no effect on the way checkouts work.\nThe `suchwow` and `commons` links look the same in `checkouts`, and the groupid\nhierarchy doesn't need to appear in the way `commons` is actually laid out on disk.\n\nAfter you've updated `:dependencies`, `lein` will still need to be able\nto find the library in some repository like clojars or your `~/.m2`\ndirectory.  If `lein` complains with a message like `\"Could not find artifact suchwow:jar:0.3.9\"`,\nit's possible that `project.clj` and `suchwow/project.clj` use different version numbers.\nIt's also possible that you're working on the main project and `suchwow` at the same time,\nhave bumped the version number in both project files, but still have the old version in your\nlocal Maven repository. Run `lein install` in the `suchwow` directory. That is: the `suchwow`\nversion number must be the same in *three* places:\nin suchwow's `project.clj`, in the main project's `project.clj`, *and in some repository the main project uses*.\n\nIf you change the\ndependencies of a checkout project you will still have to run `lein\ninstall` and restart your repl; it's just that source changes will be\npicked up immediately.\n\nCheckouts are an opt-in feature; not everyone who is working on the\nproject will have the same set of checkouts, so your project should\nwork without checkouts before you push or merge.\n\nMake sure not to override the `base` profile while using checkouts. In\npractice that usually means using `lein with-profile +foo run` rather\nthan `lein with-profile foo run`.\n\n### Search\n\nLeiningen supports searching remote Maven repositories for matching\njars with the command `lein search $TERM`. Currently only searching\nCentral and Clojars is supported.\n\n### Maven Read Timeout\n\nThe underlying [Maven Wagon](https://maven.apache.org/wagon/)\ntransport reads the `maven.wagon.rto` system property to determine the\ntimeout (in milliseconds) used when communicating with a repository.\nIf the default timeout isn't right, it can be overridden via\n`LEIN_JVM_OPTS`:\n\n```bash\nexport LEIN_JVM_OPTS=\"-Dmaven.wagon.rto=30000\"\n```\n\n## Setting JVM Options\n\nTo pass extra arguments to the JVM, set the `:jvm-opts` vector. This will override\nany default JVM opts set by Leiningen.\n\n```clj\n:jvm-opts [\"-Xmx1g\"]\n```\n\nIf you want to pass [compiler options](https://clojure.org/reference/compilation#_compiler_options)\nto the Clojure compiler, you also do this here.\n\n```clj\n:jvm-opts [\"-Dclojure.compiler.disable-locals-clearing=true\"\n           \"-Dclojure.compiler.elide-meta=[:doc :file :line :added]\"\n           ; notice the array is not quoted like it would be if you passed it directly on the command line.\n           \"-Dclojure.compiler.direct-linking=true\"]\n```\n\nYou can also pass options to Leiningen in the `JVM_OPTS` environment variable. If you\nwant to provide the Leiningen JVM with custom options, set them in `LEIN_JVM_OPTS`.\n\n## Running Code\n\nEnough setup; let's see some code running. Start with a REPL\n(read-eval-print loop):\n\n    $ cd my-stuff\n    $ lein repl\n    nREPL server started on port 55568 on host 127.0.0.1 - nrepl://127.0.0.1:55568\n    REPL-y 0.5.1, nREPL 0.8.3\n    Clojure 1.10.1\n    OpenJDK 64-Bit Server VM 1.8.0_222-b10\n        Docs: (doc function-name-here)\n              (find-doc \"part-of-name-here\")\n      Source: (source function-name-here)\n     Javadoc: (javadoc java-object-or-class-here)\n        Exit: Control+D or (exit) or (quit)\n     Results: Stored in vars *1, *2, *3, an exception in *e\n\n    my-stuff.core=>\n\nThe REPL is an interactive prompt where you can enter arbitrary code\nto run in the context of your project. Since we've added `clj-http` to\n`:dependencies` earlier, we are able to load it here along with code from the\n`my-stuff.core` namespace in your project's own `src/` directory:\n\n    my-stuff.core=> (require 'my-stuff.core)\n    nil\n    my-stuff.core=> (my-stuff.core/-main)\n    Hello, World!\n    nil\n    my-stuff.core=> (require '[clj-http.client :as http])\n    nil\n    my-stuff.core=> (def response (http/get \"https://leiningen.org\"))\n    #'my-stuff.core/response\n    my-stuff.core=> (keys response)\n    (:status :headers :body :request-time :trace-redirects :orig-content-encoding)\n\nThe call to `-main` shows both println output (\"Hello, World!\") and\nthe return value (nil) together.\n\nBuilt-in documentation is available via `doc`, and you can examine the\nsource of functions with `source`:\n\n    my-stuff.core=> (source -main)\n    (defn -main\n      \"I don't do a whole lot ... yet.\"\n      [& args]\n      (println \"Hello, World!\"))\n    nil\n\n    my-stuff.core=> ; use control+d to exit\n\nIf you already have code in a `-main` function ready to go and don't\nneed to enter code interactively, the `run` task is simpler:\n\n    $ lein run\n    Hello, World!\n\nProviding a `-m` argument will tell Leiningen to look for\nthe `-main` function in another namespace. Setting a default `:main` in\n`project.clj` lets you omit `-m`.\n\nFor long-running `lein run` processes, you may wish to save memory\nwith the higher-order trampoline task, which allows the Leiningen JVM\nprocess to exit before launching your project's JVM.\n\n    $ lein trampoline run -m my-stuff.server 5000\n\nIf you have any Java to be compiled in `:java-source-paths` or Clojure\nnamespaces listed in `:aot`, they will always be compiled before\nLeiningen runs any other code, via any `run`, `repl`,\netc. invocations.\n\n## Tests\n\nWe haven't written any tests yet, but we can run the failing tests\nincluded from the project template:\n\n    $ lein test\n\n    lein test my-stuff.core-test\n\n    lein test :only my-stuff.core-test/a-test\n\n    FAIL in (a-test) (core_test.clj:7)\n    FIXME, I fail.\n    expected: (= 0 1)\n      actual: (not (= 0 1))\n\n    Ran 1 tests containing 1 assertions.\n    1 failures, 0 errors.\n    Tests failed.\n\nOnce we fill it in the test suite will become more useful. Sometimes\nif you've got a large test suite you'll want to run just one or two\nnamespaces at a time; `lein test my-stuff.core-test` will do that. You\nalso might want to break up your tests using test selectors; see `lein\nhelp test` for more details.\n\nThe built-in `test` command wraps the basic runner from `clojure.test`\nand adds a few small features, but many people prefer to replace it\nwith a more full-featured test runner like [kaocha](https://github.com/lambdaisland/kaocha).\nBy adding an alias for `test` along with an entry in `:dependencies`,\nit's easy to make a third-party runner replace the built-in test task:\n\n```clj\n:aliases {\"test\" [\"run\" \"-m\" \"kaocha.runner\"]}\n```\n\nRunning `lein test` from the command-line is suitable for regression\ntesting, but the slow startup time of the JVM makes it a poor fit for\ntesting styles that require tighter feedback loops. In these cases,\neither keep a repl open for running the appropriate call to\n[clojure.test/run-tests](https://clojuredocs.org/clojure.test/run-tests)\nor look into editor integration such as\n[clojure-test-mode](https://github.com/technomancy/clojure-mode).\n\nKeep in mind that while keeping a running process around is convenient,\nit's easy for that process to get into a state that doesn't reflect\nthe files on disk: functions that are loaded and then deleted from the\nfile will remain in memory, making it easy to miss problems arising\nfrom missing functions (often referred to as \"getting\nslimed\"). Because of this it's advised to do a `lein test` run with a\nfresh instance periodically in any case, perhaps before you commit.\n\n## Profiles\n\nProfiles are used to add various things into your project map in\ndifferent contexts. For instance, during `lein test` runs, the\ncontents of the `:test` profile, if present, will be merged into your\nproject map. You can use this to enable configuration that should only\nbe applied during test runs, either by adding directories containing\nconfig files to your classpath via `:resource-paths` or by other\nmeans. See `lein help profiles` for more details.\n\nUnless you tell it otherwise, Leiningen will merge the default set of\nprofiles into the project map. This includes user-wide settings from\nyour `:user` profile, the `:dev` profile from `project.clj` if\npresent, and the built-in `:base` profile which contains dev tools\nlike nREPL and optimizations which help startup time at the expense of\nruntime performance. Never benchmark with the default profiles. (See\nthe FAQ entry for \"tiered compilation\")\n\n## What to do with it\n\nGenerally speaking, there are three different goals that are typical\nof Leiningen projects:\n\n* An application you can distribute to end-users\n* A server-side application\n* A library for other Clojure projects to consume\n\nFor the first, you typically build an uberjar. For libraries, you will\nwant to have them published to a repository like Clojars or a private\nrepository. For server-side applications it varies as described below.\nGenerating a project with `lein new app myapp` will start you out with\na few extra defaults suitable for non-library projects, or you can\nbrowse the\n[available templates on Clojars](https://clojars.org/search?q=lein-template)\nfor things like specific web technologies or other project types.\n\n### Uberjar\n\nThe simplest thing to do is to distribute an\n[uberjar](https://stackoverflow.com/questions/11947037/what-is-an-uber-jar). This is a single\nstandalone executable jar file most suitable for giving to\nnontechnical users. For this to work you'll need to specify a\nnamespace as your `:main` in `project.clj` and ensure it's also AOT (Ahead Of Time)\ncompiled by adding it to `:aot`. By this point, our `project.clj` file\nshould look like this:\n\n```clj\n(defproject my-stuff \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]\n                 [clj-http \"3.13.1\"]]\n  :profiles {:dev {:dependencies [[ring/ring-devel \"1.4.0\"]]}}\n  :main my-stuff.core\n  :aot [my-stuff.core])\n```\n\nWe have also added a development dependency, `ring-devel`. `ring-devel` will not\nbe available in uberjars, and will not be considered a dependency if you publish\nthis project to a repository.\n\nThe namespace you specify will need to contain a `-main` function that\nwill get called when your standalone jar is run. This namespace should\nhave a `(:gen-class)` declaration in the `ns` form at the top. The\n`-main` function will get passed the command-line arguments. Let's try\nsomething easy in `src/my_stuff/core.clj`:\n\n```clj\n(ns my-stuff.core\n  (:gen-class))\n\n(defn -main [& args]\n  (println \"Welcome to my project! These are your args:\" args))\n```\n\nNow we're ready to generate your uberjar:\n\n    $ lein uberjar\n    Compiling my-stuff.core\n    Created /home/phil/my-stuff/target/uberjar+uberjar/my-stuff-0.1.0-SNAPSHOT.jar\n    Created /home/phil/my-stuff/target/uberjar/my-stuff-0.1.0-SNAPSHOT-standalone.jar\n\nThis creates a single jar file that contains the contents of all your\ndependencies. Users can run it with a simple `java` invocation,\nor on some systems just by double-clicking the jar file.\n\n    $ java -jar my-stuff-0.1.0-SNAPSHOT-standalone.jar Hello world.\n    Welcome to my project! These are your args: (Hello world.)\n\nYou can run a regular (non-uber) jar with the `java`\ncommand-line tool, but that requires constructing the classpath\nyourself, so it's not a good solution for end-users.\n\nOf course if your users already have Leiningen installed, you can\ninstruct them to use `lein run` as described above.\n\n### Framework (Uber)jars\n\nMany Java frameworks expect deployment of a jar file or derived archive\nsub-format containing a subset of the application's necessary\ndependencies.  The framework expects to provide the missing dependencies\nitself at run-time.  Dependencies which are provided by a framework in\nthis fashion may be specified in the `:provided` profile.  Such\ndependencies will be available during compilation, testing, etc., but\nwon't be included by default by the `uberjar` task or plugin tasks\nintended to produce stable deployment artifacts.\n\nFor example, Hadoop job jars may be just regular (uber)jar files\ncontaining all dependencies except the Hadoop libraries themselves:\n\n```clj\n(project example.hadoop \"0.1.0\"\n  ...\n  :profiles {:provided\n             {:dependencies\n              [[org.apache.hadoop/hadoop-core \"1.2.1\"]]}}\n  :main example.hadoop)\n```\n\n    $ lein uberjar\n    Compiling example.hadoop\n    Created /home/xmpl/src/example.hadoop/example.hadoop-0.1.0.jar\n    Created /home/xmpl/src/example.hadoop/example.hadoop-0.1.0-standalone.jar\n    $ hadoop jar example.hadoop-0.1.0-standalone.jar\n    12/08/24 08:28:30 INFO util.Util: resolving application jar from found main method on: example.hadoop\n    12/08/24 08:28:30 INFO flow.MultiMapReducePlanner: using application jar: /home/xmpl/src/example.hadoop/./example.hadoop-0.1.0-standalone.jar\n    ...\n\nPlugins are required to generate framework deployment jar derivatives\n(such as [war files](https://en.wikipedia.org/wiki/WAR_(file_format))) which include additional metadata, but the\n`:provided` profile provides a general mechanism for handling the\nframework dependencies.\n\n### Server-side Projects\n\nThere are many ways to get your project deployed as a server-side\napplication. Aside from the obvious uberjar approach, simple programs can be\npackaged up as [tarballs](https://en.wikipedia.org/wiki/Tar_(computing)) with\naccompanied shell scripts using the [lein-tar plugin](https://github.com/technomancy/lein-tar)\nand then deployed using [chef](https://chef.io/) or other mechanisms.\n\nWeb applications may be deployed as uberjars using embedded Jetty with\n`ring-jetty-adapter` or as [war (web application archive) files](https://en.wikipedia.org/wiki/WAR_(file_format))\ncreated by the [lein-ring plugin](https://github.com/weavejester/lein-ring). For\nthings beyond uberjars, server-side deployments are so varied that they\nare better-handled using plugins rather than tasks that are built-in\nto Leiningen itself.\n\nIt's possible to involve Leiningen during production, but there are\nmany subtle gotchas to that approach; it's strongly recommended to use\nan uberjar if you can. If you need to launch with the `run` task, you\nshould use `lein trampoline run` in order to save memory, otherwise\nLeiningen's own JVM will stay up and consume unnecessary memory.\n\nIn addition it's very important to ensure you take steps to freeze all\nthe dependencies before deploying, otherwise it could be easy to end\nup with\n[unrepeatable deployments](https://wiki.leiningen.org/Repeatability).\nConsider including `~/.m2/repository` in your unit of deployment\n(tarball, .deb file, etc) along with your project code. It's\nrecommended to use Leiningen to create a deployable artifact in a\ncontinuous integration setting. For example, you could have a\n[Jenkins](https://jenkins-ci.org) CI server run your project's full\ntest suite, and if it passes, upload a tarball to S3. Then deployment\nis just a matter of pulling down and extracting the known-good tarball\non your production servers. Simply launching Leiningen from a checkout\non the server will work for the most basic deployments, but as soon as\nyou get a number of servers you run the risk of running with a\nheterogeneous cluster since you're not guaranteed that each machine\nwill be running with the exact same codebase.\n\nAlso remember that the default profiles are included unless you\nspecify otherwise, which is not suitable for production. Using `lein\ntrampoline with-profile production run -m myapp.main` is\nrecommended. By default the production profile is empty, but if your\ndeployment includes the `~/.m2/repository` directory from the CI run\nthat generated the tarball, then you should add its path as\n`:local-repo` along with `:offline? true` to the `:production`\nprofile. Staying offline prevents the deployed project from diverging\nat all from the version that was tested in the CI environment.\n\nGiven these pitfalls, it's best to use an uberjar if possible.\n\n### Publishing Libraries\n\nIf your project is a library and you would like others to be able to\nuse it as a dependency in their projects, you will need to get it into\na public repository. While it's possible to [maintain your own private\nrepository](https://codeberg.org/leiningen/leiningen/src/stable/doc/DEPLOY.md)\nor get it into [Central](https://search.maven.org), the easiest way is\nto publish it at [Clojars](https://clojars.org). Once you have\n[created an account](https://clojars.org/register) there, publishing\nis straightforward. You'll need to have a [verified group\nname](https://github.com/clojars/clojars-web/wiki/Groups), but you get\nsome for free just for having a Clojars account. You'll need to change\nthe name of your project to include the group name. Edit the first\nline of your `project.clj` to look like:\n\n```clj\n(defproject org.clojars.my-clojars-username/my-stuff \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  ...\n```\n\nClojars doesn't use passwords, so you'll need to [generate a deploy\ntoken](https://github.com/clojars/clojars-web/wiki/Deploy-Tokens). Once\nyou have that, you are ready to deploy:\n\n    $ lein deploy clojars\n    No credentials found for clojars\n    See `lein help deploying` for how to configure credentials to avoid prompts.\n    Username: me\n    Password:\n    Created ~/src/my-stuff/target/my-stuff-0.1.0-SNAPSHOT.jar\n    Wrote ~/src/my-stuff/pom.xml\n    Retrieving org/clojars/my-clojars-username/my-stuff/0.1.0-SNAPSHOT/maven-metadata.xml\n        from https://repo.clojars.org/\n    Sending org/clojars/my-clojars-username/my-stuff/0.1.0-SNAPSHOT/my-stuff-0.1.0-20190525.161117-2.jar (9k)\n        to https://repo.clojars.org/\n    Sending org/clojars/my-clojars-username/my-stuff/0.1.0-SNAPSHOT/my-stuff-0.1.0-20190525.161117-2.pom (2k)\n        to https://repo.clojars.org/\n    Retrieving org/clojars/my-clojars-username/my-stuff/maven-metadata.xml\n        from https://repo.clojars.org/\n    Sending org/clojars/my-clojars-username/my-stuff/0.1.0-SNAPSHOT/maven-metadata.xml (1k)\n        to https://repo.clojars.org/\n    Sending org/clojars/my-clojars-username/my-stuff/maven-metadata.xml (1k)\n        to https://repo.clojars.org/\n\nOnce that succeeds it will be available as a package on which other\nprojects may depend. For instructions on storing your credentials so\nthey don't have to be re-entered every time, see `lein help\ndeploying`. When deploying a release that's not a snapshot, Leiningen\nwill attempt to sign it using [GPG](https://gnupg.org) or\n[SSH](https://www.agwa.name/blog/post/ssh_signatures) to prove your\nauthorship of the release. See the\n[deploy guide](https://codeberg.org/leiningen/leiningen/src/stable/doc/DEPLOY.md)\nfor details of how to set that up. The deploy guide includes\ninstructions for deploying to other repositories as well.\n\n## That's It!\n\nNow go start coding your next project!\n"
  },
  {
    "path": "doc/ja/PLUGINS_ja.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [Leiningen プラグイン](#leiningen-%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3)\n  - [プラグインを書く](#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%92%E6%9B%B8%E3%81%8F)\n    - [タスクの引数](#%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%AE%E5%BC%95%E6%95%B0)\n    - [ドキュメンテーション](#%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)\n  - [コード評価](#%E3%82%B3%E3%83%BC%E3%83%89%E8%A9%95%E4%BE%A1)\n    - [プロジェクトコンテクスト内での評価](#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AF%E3%82%B9%E3%83%88%E5%86%85%E3%81%A7%E3%81%AE%E8%A9%95%E4%BE%A1)\n  - [他のプラグインコンテンツ](#%E4%BB%96%E3%81%AE%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84)\n    - [プロファイル](#%E3%83%97%E3%83%AD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB)\n    - [フック](#%E3%83%95%E3%83%83%E3%82%AF)\n    - [プロジェクト ミドルウェア](#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88-%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2)\n    - [Maven Wagon](#maven-wagon)\n    - [VCSメソッド](#vcs%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)\n  - [プラグインの呼び出し](#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%AE%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97)\n  - [Clojureのバージョン](#clojure%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3)\n  - [既存のプラグインのアップグレード](#%E6%97%A2%E5%AD%98%E3%81%AE%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89)\n  - [プロジェクト vs スタンドアロンでの実行](#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88-vs-%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%89%E3%82%A2%E3%83%AD%E3%83%B3%E3%81%A7%E3%81%AE%E5%AE%9F%E8%A1%8C)\n  - [標準タスクの上書き](#%E6%A8%99%E6%BA%96%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%AE%E4%B8%8A%E6%9B%B8%E3%81%8D)\n  - [1.x互換性](#1x%E4%BA%92%E6%8F%9B%E6%80%A7)\n    - [特定のプロジェクト向けタスク](#%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%90%91%E3%81%91%E3%82%BF%E3%82%B9%E3%82%AF)\n  - [楽しんでください](#%E6%A5%BD%E3%81%97%E3%82%93%E3%81%A7%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n[English](../PLUGINS.md)\n\n# Leiningen プラグイン\n\nLeiningenのタスクはleiningen.$TASK名前空間にある$TASKという名前の関数に過ぎません。ですから、Leiningenのプラグインを記述するのは、単にそのような関数を含むプロジェクトを作るだけのことで、下記の内容の多くは、Leiningenそのものに含まれているタスクにも同様に当てはまります。\n\nプラグインを使用するには、プロジェクトマップの`:plugins`にそのプラグインを宣言するだけです。プロジェクトの実行用ではなく、使い勝手を向上させるプラグインは、`project.clj`ファイルに直接記述する代わりに`~/.lein/profiles.clj`の`:user`プロファイルに記述してください。\n\n## プラグインを書く\n\n`lein new plugin myplugin`でプロジェクトを作成するところからはじめ、`leiningen.myplugin`名前空間の`myplugin`関数を編集してください。`project.clj`内にある`:eval-in-leningen true`によって、タスクはサブプロセスではなく、leiningenプロセス内部で動作します。プラグインは、clojureそのものへの依存関係を宣言する必要はありません。\n[Leiningen本体の依存関係全て](https://codeberg.org/leiningen/leiningen/src/stable/project.clj)がプラグインから利用可能です。\n\n非常に単純なプラグインの例として、 [ソースコード内の](https://codeberg.org/leiningen/leiningen/src/stable/lein-pprint)\n`lein-pprint`ディレクトリを参照してください。\n\nプラグインの開発中、プロジェクト内で`lein install`を再実行し、それからテストプロジェクトに切り替えるのは非常に手間がかかります。一度プラグインをインストールすれば、テストプロジェクト内の`.lein-classpath`ファイルに、プラグインの`src`ディレクトリのパスを記述しておくことでこの手間を省くことができます。そのプラグインが別の開発中のライブラリに依存している場合は、`.lein-classpath`にUNIXでは`:`、Windowsでは`;`のクラスパスセパレータで区切ってライブラリのディレクトリを追加することができます。\n\n出力をする場合は、`println`の代わりに、`leiningen.core.main/info`、`leiningen.core.main/warn`、`leiningen.core.main/debug`のいずれかを使用してください。ユーザの出力設定の制御が適用されます。\n\n### タスクの引数\n\nタスク関数の最初の引数は現在のプロジェクトにしてください。これは`project.clj`を元にしたマップですが、`:name`、`:group`、`:version`、`:root`などのキーが追加されています。このプロジェクトマップがどのようなものか確認するためには、`lein-pprint`プラグインを使ってみてください。プロジェクトと、プロファイルの組み合わせを確認するために`pprint`タスクを実行することができます。\n\nコマンドラインからパラメタをとるタスクが必要な場合、ひとつ以上の引数をとる関数を作ることができます。タスクは単なるClojureの関数であることを強調するために、引数は通常、UNIXの伝統的な`--dashed`スタイルでなく、`:keywords`を受け付けるように記述します。引数は全てStringとして渡されることに留意してください。引数をキーワード、シンボル、整数として扱いたい場合には`read-string`を呼び出すことができますが、それはあなたが記述する関数次第です。他のタスクを関数として呼び出す際も、この点を留意してください。\n\nほとんどのタスクは、他のプロジェクトの内部でのみ実行されます。もしタスクを、プロジェクトディレクトリの外側で実行できるようにしたい場合は、`^:no-project-needed`メタデータをタスク関数に追加してください。その場合であっても、タスク関数の第一引数はプロジェクトをとるように記述し、プロジェクト外で実行した際に渡されるnilを受け入れるようにしてください。プロジェクト内で実行した場合は、LeiningenはJVMを起動する前に、プロジェクトのルートディレクトに`cd`しますが、IDE連携など、`leiningen-core`ライブラリを使用しているツールは同じようにふるまわない可能性があるため、プロジェクトの`:root`キーワードを確認し、そのディレクトリを起点とすると最大限の移植性が得られます。\n\n### ドキュメンテーション\n\n`lein help`タスクはdocstringを使っています。名前空間レベルのdocstringが定義されていれば、それを短いサマリとして使用します。なければ、関数のdocstringの第一文が使用されます。フォーマットの都合上、サマリは68文字以内に収めるようにしてください。関数の引数名も表示されるので、明快で説明的な引数名を選ぶようにしてください。ユーザーに見せたくない代替の引数を持つ場合、関数のメタデータに`:help-arglists`を設定することができます。その場合は全ての引数について説明するようにしてください。引数は全てStringなので、キーワード、数字、シンボルが必要な場合は`read-string`を呼び出す必要があることに留意してください。\n\n複雑なタスクはサブタスクに分割することがよくあります。サブタスクの変数のベクターを含んだ`:subtasks`メタデータをタスク関数に渡すことによって、`lein help $TASK_CONTAINING_SUBTASKS`を実行した際に、サブタスクを表示することができます。サブタスク一覧は、それぞれのサブタスクのdocstringの第一文を表示します。サブタスクの完全版のヘルプは、`lein help $TASK_CONTAINING_SUBTASKS $SUBTASK`で表示することができます。\n\n特別な指定がない場合、Leiningenは`lein $MYTASK help`の呼び出しを横取りして`lein help $MYTASK`に変換します。タスク内で独自のhelpサブタスクを表示したい場合はタスク関数に`^:pass-through-help`メタデータを指定してこのふるまいを無効化することができます。\n\n## コード評価\n\nプラグインの関数は、Leiningenのプロセス内で実行されるので、既存のLeiningenの関数全てにアクセスすることができます。`leiningen.core.*`名前空間内の、`^:internal`メタデータが付与されていない関数全てとタスク関数は全て公開されているAPIと考えてください。タスク名前空間のタスク以外の関数は内部用で、マイナーバージョンリリースでも変更される可能性があります。\n\n### プロジェクトコンテクスト内での評価\n\nタスクの多くはプロジェクトのコンテクスト内でコードを実行する必要があります。`leiningen.core.eval/eval-in-project`関数はこの目的で使用されます。この関数はプロジェクト引数、評価するフォーム、そして最後にオプションとして、メインフォームの前に評価される、初期化用のフォームをとることができます。この最後のフォームは[ジラルディシナリオ](https://technomancy.us/143)を防ぐために、名前空間を事前にrequireするために用いることができます。\n\n`eval-in-project`関数内ではプロジェクトのクラスパスが有効になっており、Leiningen自体の内部関数とプラグインは無効化されています。\n\nプロジェクトマップは`eval-in-project`に渡す前に改変することができますが、プロファイルをマージすることで変更する方法が、ユーザーによるオーバーライドを可能にするので推奨されます。変更を加えるために、`leiningen.core.project/merge-profiles`を使用してください。\n\n```clj\n(def swank-profile {:dependencies [['swank-clojure \"1.4.3\"]]})\n\n(defn swank\n  \"Launch swank server for Emacs to connect. Optionally takes PORT and HOST.\"\n  [project port host & opts]\n    (let [profile (or (:swank (:profiles project)) swank-profile)\n          project (project/merge-profiles project [profile])]\n      (eval-in-project project \n                       `(swank.core/-main ~@opts)\n                       '(require 'swank.core))))\n```\n\n`swank-clojure`依存関係のコードがプロジェクト内で必要なため、独自のプロファイルマップを宣言し、マージしています。しかし、`:swank`プロファイルがプロジェクトマップに定義されている場合はそれを使うため、ユーザはプラグイン内にハードコードされたバージョンに依存したくない場合は自分で違うバージョンを選択することができます。\n\n上記で用いたコードは単に`eval-in-project`と`merge-profiles`をラップしただけなので、プラグインの例としてはふさわしくないことに留意してください。もし実現したいことがこれだけなのであれば、プラグインを実装することなく実現することができます。単に`with-profiles`と必要な関数を呼び出す`run`タスクを使ったエイリアスを定義すればよいのです。\n\n`eval-in-project`を実行する前に、Leiningenは全てのJavaコードと実行に必要なClojureコードをバイトコードに事前にコンパイルして、プロジェクトが実行可能な状態になるよう準備しなければなりません。これはプロジェクトの`:prep-tasks`キーに定義されているタスク全てを実行することで行われます。標準では`[\"javac\" \"compile\"]`です。もしあなたのプラグインが他の準備作業を必要とする場合、（例えばプロトコルバッファのコンパイル）、ユーザに別のエントリを`:prep-tasks`に追加してもらうよう指示することができます。このタスクは`eval-in-project`を実行するたびに評価されることに留意してください。前回の実行時から何も変わっていなければ素早く終了するように実装してください。\n\n## 他のプラグインコンテンツ\n\nプラグインは主にタスクを提供するためのものですが、他にもプロファイル、フック、ミドルウェア、wagon(依存関係トランスポートメソッド）、バージョン管理方法を含めることができます。\n\n### プロファイル\n\nあなたのプラグインを使用するプロジェクトの多くで必要になりそうなものの、何らかの理由でデフォルトで有効化できない設定があるとき、プラグイン内でプロファイルとして含めることができます。\n\n`src/myplugin/profiles.clj`というファイルをプラグイン内に作成して、下記のマップを定義してください。\n\n```clj\n{:default {:x \"y and z\"}\n :extra {:other \"settings\"}}\n```\n\nマップ内のそれぞれの値がプロファイルで、ユーザーがプロジェクトにマージすることができます。`with-profile`を用いて、実行時に明示的に指定することができます。\n\n    $ lein with-profile plugin.myplugin/extra test\n\nユーザは`:default`プロファイルを変更することで自動的に有効化することもできます。\n\n```clj\n:profiles {:default [:base :system :user :provided :dev :plugin.myplugin/default]\n           :other {...}}\n```\n\n`:default`プロファイル内のエントリは、`jar`、`uberjar`、`pom`など、下流向けに成果物を生成するタスクと、`with-profile`を指定したタスクを除いた、他の全てのタスクで有効化されます。\n\n### フック\n\nフックを用いて、Leiningen標準タスクのふるまいをある程度変更することができます。フック機能は、Leiningenに含まれている\n[Robert Hooke](https://github.com/technomancy/robert-hooke)ライブラリによって提供されています。\n\nclojure.testのフィクスチャ機能に着想を得て、フックは他の関数、多くの場合はタスクをラップし、他の変数をバインディングしたり、返り値を改変したり、関数の実行を条件で制御したりすることでふるまいを変えます。`add-hook`関数は適用するタスクの変数とラッピングする関数を引数にとります。\n\n```clj\n(ns lein-integration.plugin\n  (:require [robert.hooke]\n            [leiningen.test]))\n\n(defn add-test-var-println [f & args]\n  `(binding [~'clojure.test/assert-expr\n             (fn [msg# form#]\n               (println \"Asserting\" form#)\n               ((.getRawRoot #'clojure.test/assert-expr) msg# form#))]\n     ~(apply f args)))\n\n;; Place the body of the activate function at the top-level for\n;; compatibility with Leiningen 1.x\n(defn activate []\n  (robert.hooke/add-hook #'leiningen.test/form-for-testing-namespaces\n                         #'add-test-var-println))\n```\n\nフックは関数合成(compose)しますので、あなたのフックが他のフックの内側で実行される場合があることに気をつけてください。詳細は\n[Hookeのドキュメンテーション](https://github.com/technomancy/robert-hooke/blob/master/README.md)を参照してください。`add-hook`への呼び出しは第一、第二引数の両方にVarを用いるべきであることに留意してください。そうすることでフックを重複して追加することなく繰り返しローディング可能になります。これは、Clojureでは関数は同一性が比較できませんが、Varは可能だからです。\n\nもしあなたのフックが、あなたのプラグインを含むプロジェクトで自動的にロードされるようにしたい場合は、`plugin-name.plugin/hooks`関数で呼び出して有効化してください。上記の例ではプラグインは`lein-integration`という名前なので、`lein-integration.plugin/hooks`関数が、`lein-integration`プラグインのロード時に自動的に呼び出されます。\n\nフックは、project.clj内の`:hooks`キーに有効化するためのVarのシークエンスを設定することで、手動でロードすることもできます。下位互換性のために、`:hooks`内でVarの代わりに名前空間も指定しすることもできます。その名前空間内の`activate`関数が呼び出されます。自動ローディングのフックは手動で指定されたフックより前に有効化されます。\n\n### プロジェクト ミドルウェア\n\nプロジェクトミドルウェアは、プロジェクトマップを引数にとり、新しいプロジェクトマップを返す関数にすぎません。ミドルウェアによって、プラグインはプロジェクトマップを変換することができるようになります。しかしミドルウェアは柔軟で透過的なので、デバッグを難しくするという問題点があります。もしプラグイン内のプロファイルを使って必要なことができるのであれば、そのほうがより宣言的で、ふるまいを観察しやすいので、後で起こる頭痛の種を減らすことができます。\n\n下記のミドルウェアはプロジェクトマップの内容をプロジェクトのリソースフォルダ内に挿入してコードから読み取り可能にします。\n\n```clj\n(ns lein-inject.plugin)\n\n(defn middleware [project]\n  (update-in project [:injections] concat\n             `[(spit \"resources/project.clj\" ~(prn-str project))]))\n```\n\nフックと同様、ミドルウェアも`plugin-name.plugin/middleware`内に定義すれば自動的に適用されます。また、project.clj内の`:middleware`キーにプロジェクトマップを変換するVarのシークエンスを定義することで手動でローディングすることもできます。ミドルウェアの自動ローディングが手動で定義されたミドルウェアよりも前に適用されることに留意してください。\n\nまた、現在有効なミドルウェアは有効になっているプロファイルに依存していることにも注意してください。つまりアクティブなプロファイルが切り替わるたびにミドルウェア関数を再適用する必要があるということです。オリジナルのプロジェクトマップを保存しておき、`merge-profiles`、`unmerge-profiles`、`set-profiles`を呼び出すたびに元の状態から変換することによって実現しています。ミドルウェア関数は繰り返し呼び出される可能性があるので、冪等性(idempotent)のない副作用を含むべきでありません。\n\n### Maven Wagon\n\n[Pomegranate](https://github.com/cemerick/pomegranate) (依存解決のためにLeiningenによって用いられているライブラリ)は\"wagon\"ファクトリの登録をサポートしています。wagonはリポジトリ用の非標準トランスポートプロトコルを扱うために用いられ、リポジトリURLのプロトコルに応じて選択されます。もし、あなたのプラグインがwagonファクトリを登録する必要があるのであれば、プロトコルと、そのプロトコル用のwagonインスタンスを返す関数のマップを含む`leiningen/wagons.clj`ファイルを含めることで実現できます。例えば、下記の`wagons.clj`は`dav:`URL用のwagonファクトリを登録します。\n\n```clj\n{\"dav\" #(org.apache.maven.wagon.providers.webdav.WebDavWagon.)}\n```\n\nこのテクニックを用いたプラグインの例として、[S3 wagon private](https://github.com/technomancy/s3-wagon-private)や \n[lein-webdav](https://github.com/tobias/lein-webdav)を参考にしてください。\n\n\n### VCSメソッド\n\nLeiningenにはマルチメソッドを用いてリリース関連のバージョン管理タスクを行う、`vcs`タスクが含まれています。標準では、Git向けの実装が含まれていますが、`leiningen.vcs.$SYSTEM`名前空間に含めることで他のシステムのサポートを追加することができます。`vcs`タスクが呼び出される際、`leiningen.vcs`プレフィックス配下の名前空間全てがローディングされます。これらの名前空間では、`leiningen.vcs`内で定義されている`defmulti`向けのメソッドのみを特定のバージョン管理システム用に定義するようにしてください。\n\n## プラグインの呼び出し\n\nプラグインをプロジェクト内で用いるためには、`:dependencies`と同じフォーマットで、`:plugins`キーをproject.cljに追加するだけです。`:dependencies`で扱えるオプションに加え、`:plugins`にはフックやミドルウェアの自動ローディングを無効化するオプションが追加されています。\n\n```clj\n(defproject foo \"0.1.0\"\n  :plugins [[lein-pprint \"1.1.1\"]\n            [lein-foo \"0.0.1\" :hooks false]\n            [lein-bar \"0.0.1\" :middleware false]])\n```\n## Clojureのバージョン\n\nLeiningen2.4.0以上はClojure1.6.0を使用しています。もしLeiningenのプラグイン内で別のバージョンのClojureを使う必要がある場合は、`eval-in-project`をダミーのプロジェクト引数と共に用いることができます。\n\n```clj\n(eval-in-project {:dependencies '[[org.clojure/clojure \"1.4.0\"]]}\n                 '(println \"hello from\" *clojure-version*))\n```\n\n## 既存のプラグインのアップグレード\n\nLeiningenの以前のバージョンはプラグインの動き方に違いがいくつかありますが、アップグレードをするのはそれほど難しくないはずです。\n\nバージョン1.xと2.xの最も大きな違いは`:dev-dependencies`がなくなったことです。Leiningenのプロセスとプロジェクトのプロセスの両方に存在する依存関係はもはや存在しません。Leiningenは`:plugins`だけを参照し、プロジェクトは`:dependencies`だけを参照します。ただしこれらのマップは現在有効化されているプロファイルによって影響を受ける場合があります。\n\nもしあなたのプロジェクトが`eval-in-project`を使用する必要が全くないのであれば、移植は比較的容易です。移動したLeiningen関数への参照を更新するだけで十分です。`leiningen.util.*`名前空間内の関数は全てなくなり、`leiningen.core`は`leiningen.core.main`に移動しました。\n\n`eval-in-project`を使用しているプラグインについては、プラグインの依存関係とソースコードがプロジェクト内では利用可能ではなくなるということに気をつけてください。もしあなたのプラグインが、プラグインとプロジェクトの両方のコンテクストで実行する必要のあるコードを含んでいる場合は、複数のプロジェクトに分割し、それぞれを`:plugins`と`:dependencies`に登録する必要があります。`eval-in-project`の呼び出しで`:dependencies`を挿入する方法については上記の`lein-swank`の例を参照してください。\n\n\n## プロジェクト vs スタンドアロンでの実行\n\nLeiningenタスクの中にはどのディレクトリからでも実行可能なものがあります。（例：`lein repl`)。プロジェクトコンテクスト内でのみ有効なタスクもあります。\n\nLeiningenがプロジェクトのコンテクスト内で実行されているかどうか（つまり、現在のディレクトリに`project.clj`があるかどうか）を調べるには、プロジェクトマップの`:root`キーを調べます。\n\n``` clojure\n(if (:root project)\n  (comment \"Running in a project directory\")\n  (comment \"Running standalone\"))\n```\n\nもしあなたのプラグインがプロジェクトコンテクストの外側で動作するとしても、プロジェクトマップ用の引数リストの余地を残しておくべきです。プロジェクトが存在しない場合はnilが渡ってくるものと考えてください。`^:no-project-needed`メタデータを使って、プロジェクトを必要としてないことを示してください。\n\nLeiningen 1.xでは、数値を返すタスク関数はプロセスのexit値を出力する方法として使われていましたが、2.xでは致命的なエラーが起こった際には`leiningen.core.main/abort`を呼び出すべきです。`leiningen.core.main/*exit-process?*`変数にtrueが設定されている場合、この関数の呼び出しはexitを引き起こしますが、`with-profiles`など、コンテクストによっては、単に例外をスローして次のタスクに進む場合もあります。\n\n## 標準タスクの上書き\n\n通常は、例えば`leiningen.compile`という名前空間を持つプラグインを作ったとしても、それは`lein compile`を実行した時に呼び出されることはありません。標準タスクがあなたのプラグインを上書きします。もし標準タスクを隠したい場合、エイリアスを作るか、プラグインを`leiningen.plugin.compile`名前空間内に作ることで実現することができます。\n\n## 1.x互換性\n\nひとたび2.xとの互換性を確保するのに必要な変更点を特定すれば、同一のコードベース内でバージョン1.xと2.xの両方をサポートするかどうかを決めることができます。別のブランチで管理したほうが楽な場合もありますし、両方のバージョンをサポートしたほうが簡単な場合もあります。幸運なことに、`:plugins`を用いて、`eval-in-project`のためだけに`:dependencies`を追加する戦略はLeiningen 1.7上ではうまく動作します。\n\nもし2.xで移動してしまった関数を使いたい場合は、コンパイル時に解決する代わりに実行時に解決し、もし見つからなければ1.xバージョンの関数に縮退する方法を試してみてください。`lein-swank`プラグインはこの互換性シムを使った例を提供しています。\n\n```clj\n(defn eval-in-project\n  \"Support eval-in-project in both Leiningen 1.x and 2.x.\"\n  [project form init]\n  (let [[eip two?] (or (try (require 'leiningen.core.eval)\n                            [(resolve 'leiningen.core.eval/eval-in-project)\n                             true]\n                            (catch java.io.FileNotFoundException _))\n                       (try (require 'leiningen.compile)\n                            [(resolve 'leiningen.compile/eval-in-project)]\n                            (catch java.io.FileNotFoundException _)))]\n    (if two?\n      (eip project form init)\n      (eip project form nil nil init))))\n```\n\nもちろん、関数がとる引数の数が変わったり、関数が完全になくなった場合はこの手法は適用できませんが、ほとんどの場合はこれで充分なはずです。\n\n2.xで変更された関数のうち、広く用いられていたものは、1.xと2.xの両方をサポートする互換性シムを提供する、[leinjacker](https://github.com/sattvik/leinjacker)プロジェクト経由で利用可能です。\n\n他の重要な変更点として、`:source-path`、`:resources-path`、`:java-source-path`、`:test-path`は、`:source-paths`、`:resource-paths`、`:java-source-paths`、`:test-paths`に変更され、Stringの代わりにベクターをとるようになりました。以前の`:dev-resources`キーは、`:dev`プロファイルが有効な場合のみ`:resource-paths`のエントリの一つとして含まれるようになりました。\n\n後方互換性を保つ方法でタスクをプロジェクトディレクトリの外側で実行させるのは、2.xが単にプロジェクトを引数として渡し、なければnilにしておくのに対し、1.xは必要以上に賢く、引数リストが実際にプロジェクトの引数として渡せるかチェックをするため、簡単ではありません。最初の引数がプロジェクトマップかどうかを判定することはできますが、引数が二つ以上の場合、このチェックは非常に難しくなります。このような状況では、二つのブランチで管理するほうがよいかもしれません。\n\n### 特定のプロジェクト向けタスク\n\nプロジェクトのコードベースにタスクを含めなければいけない場合もときとしてありますが、これは思ったほど頻繁におこることではありません。コマンドラインから実行する必要があるだけなら、プロジェクト内の`-main`関数として実行させ、`lein garble`のようなエイリアスとして起動するほうがはるかに簡単です。\n\n```clj\n:aliases {\"garble\" [\"run\" \"-m\" \"myproject.garble\" \"supergarble\"]}\n```\n\nエイリアスのベクターは部分適用されたタスク関数になりますから、上記の設定の場合、`lein garble seventeen`は、`lein run -m myproject.garble supergarble seventeen`（あるいはreplから`(myproject.garble/-main \"supergarble\" \"seventeen\")`を実行した場合）と同等であることに注意してください。エイリアスの引数は実行時に、あらかじめ渡されている引数の後ろに追加されます。\n\nLeiningenタスクを記述する必要があるのは、例えば`eval-in-project`やLeiningenの内部へ直接アクセスするタスクを呼び出す前にプロジェクトマップを調整する必要がある場合など、プロジェクトコンテクストの外側で操作する必要がある場合のみです。エイリアスを使って、プロジェクトマップから値を読み取ることさえできます。\n\n```clj\n:aliases {\"garble\" [\"run\" \"-m\" \"myproject.garble\" :project/version]}\n```\n\nこの例ではプロジェクトマップの`:version`フィールドを引数リストに渡すことで、プロジェクト内で実行される`-main`関数が値にアクセスできるようにしています。\n\nこういった例の多くは[既存のプラグイン](https://wiki.leiningen.org/Plugins)でカバーされているはずですが、もし類似の例が見つからず、何らかの理由で別のブラグインに分離できない場合、`tasks/leiningen/`の下に新しいタスクを定義した`foo.clj`ファイルを作成し、`tasks`を`.lein-classpath`に追加することでこのふるまいを実現することができます。\n\n```\n$ ls\nREADME.md project.clj src tasks test\n$ ls -R tasks\nleiningen\n\ntasks/leiningen:\nfoo.clj\n$ echo -ne \":tasks\" | cat >> .lein-classpath\n$ lein foo\nHello, Foo!\n```\n\nただし、ほとんどの場合、別のプラグインプロジェクトにタスクを分離するのが望ましいです。`.lein-classpath`は主に実験用か、適切なプラグインを作る時間がない緊急の場合のためにあるものだからです。\n\n## 楽しんでください\n\nあなたのプラグインができあがったら、[Wiki上のリスト](https://github.com/technomnacy/leiningen/wiki/plugins)に追加してください。\n\nこのプラグインシステムが、あなたの思いのままにLeiningenをカスタマイズするための簡単で、柔軟なシステムを提供していることを願っています。\n\n\n"
  },
  {
    "path": "doc/ja/TUTORIAL_ja.md",
    "content": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents**\n\n- [チュートリアル](#%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB)\n  - [このチュートリアルの取り扱い範囲](#%E3%81%93%E3%81%AE%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%E3%81%AE%E5%8F%96%E3%82%8A%E6%89%B1%E3%81%84%E7%AF%84%E5%9B%B2)\n  - [ヘルプを読むには](#%E3%83%98%E3%83%AB%E3%83%97%E3%82%92%E8%AA%AD%E3%82%80%E3%81%AB%E3%81%AF)\n  - [Leiningen プロジェクト](#leiningen-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88)\n  - [プロジェクトの作成](#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)\n    - [ディレクトリのレイアウト](#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88)\n    - [ファイル名から名前空間への対応づけの変換](#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D%E3%81%8B%E3%82%89%E5%90%8D%E5%89%8D%E7%A9%BA%E9%96%93%E3%81%B8%E3%81%AE%E5%AF%BE%E5%BF%9C%E3%81%A5%E3%81%91%E3%81%AE%E5%A4%89%E6%8F%9B)\n  - [project.clj](#projectclj)\n  - [依存関係](#%E4%BE%9D%E5%AD%98%E9%96%A2%E4%BF%82)\n    - [概要](#%E6%A6%82%E8%A6%81)\n    - [アーティファクト ID 、アーティファクトグループ、バージョン](#%E3%82%A2%E3%83%BC%E3%83%86%E3%82%A3%E3%83%95%E3%82%A1%E3%82%AF%E3%83%88-id-%E3%82%A2%E3%83%BC%E3%83%86%E3%82%A3%E3%83%95%E3%82%A1%E3%82%AF%E3%83%88%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3)\n    - [スナップショットのバージョン](#%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3)\n    - [レポジトリ](#%E3%83%AC%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA)\n    - [依存関係のチェックアウト](#%E4%BE%9D%E5%AD%98%E9%96%A2%E4%BF%82%E3%81%AE%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88)\n    - [検索](#%E6%A4%9C%E7%B4%A2)\n    - [Maven 読み込みタイムアウト](#maven-%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88)\n  - [JVM オプションの設定](#jvm-%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%A8%AD%E5%AE%9A)\n  - [コードの実行](#%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%AE%9F%E8%A1%8C)\n  - [テスト](#%E3%83%86%E3%82%B9%E3%83%88)\n  - [プロファイル](#%E3%83%97%E3%83%AD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB)\n  - [Leiningen で何をするか](#leiningen-%E3%81%A7%E4%BD%95%E3%82%92%E3%81%99%E3%82%8B%E3%81%8B)\n    - [Uberjar](#uberjar)\n    - [フレームワークの(Uber)jars](#%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AEuberjars)\n    - [サーバサイドプロジェクト](#%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88)\n    - [ライブラリの公開](#%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E5%85%AC%E9%96%8B)\n  - [おわり!](#%E3%81%8A%E3%82%8F%E3%82%8A)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n\n\n# チュートリアル\n\nLeiningen は Clojure プロジェクトを、髪の毛が燃え上がるような思いをせずに、\n自動化するためのものです。もしこのチュートリアルにしたがっていて、\n髪の毛が燃え上がるような思いをしたり何かイライラするようなことがあった場合は、\nぜひ[私達に知らせてください](https://codeberg.org/leiningen/leiningen/issues/new)。\n\nLeiningen は様々なプロジェクトに関連するタスクを提案します:\n\n * 新しいプロジェクトを作成する\n * プロジェクトの依存関係をダウンロードする\n * テストを実行する\n * 完全に設定された REPL の実行\n * Java ソースコード(もしあれば)のコンパイル\n * プロジェクトの実行(もしプロジェクトがライブラリでなければ)\n * プロジェクト相互運用のための maven スタイルの pom ファイルの生成\n * 開発時のプロジェクトのコンパイルとパッケージ\n * [Clojars](https://clojars.org)などのレポジトリを使ったライブラリの公開\n * Clojure で書かれたカスタム自動化タスクの実行(leiningen のプラグイン)\n\nもしあなたが Java の世界からやってきたのであれば、\n「Leiningen は Maven と Ant のいい感じのあいのこ」と考えればよいでしょう。\nRuby や Python の仲間たちにとっては、 Leiningen は\nRubyGems と Bundler と Rake\nもしくは pip と Fabric を一つのツールに組み合わせたものです。\n\n\n## このチュートリアルの取り扱い範囲\n\nこのチュートリアルはプロジェクトの構造、依存関係の管理、\nテストの実行、 REPL 、及び開発に関するトピックを簡単に説明します。\n\nJVM は完全に初めての人たち、 Ant や Maven に怒りを感じたことのない人も\n慌てないでください。 Leiningen はあなたたちのために設計されています。\nこのチュートリアルはあなたが Leiningen を使い始めるのを助けて、\nプロジェクト自動化と JVM の世界での依存関係管理の\nLeiningen の取り組みについて説明します。\n\n\n## ヘルプを読むには\n\nLeiningen はかなり包括的なヘルプと、\n一緒に配布されていることに留意してください:\n`lein help` はタスクの一覧を出してくれますし、\n`lein help $TASK` は詳細を提供します。\nさらに色々なドキュメント、 readme や サンプルの設定、\nこのチュートリアルなども同様に提供されています。\n\n\n## Leiningen プロジェクト\n\nLeiningen は*プロジェクト*とともに動作します。\n一つのプロジェクトは、\n一連の Clojure (Java であることもあるかもしれません)ソースファイルと、\nそれらに関するメタデータを格納するディレクトリです。\nメタデータは `project.clj` という名前の、\nプロジェクトのルートディレクトリにあるファイルに格納されています。\nこれは Leiningen に以下のような情報を提供します:\n\n * プロジェクトの名前\n * プロジェクトの説明\n * プロジェクトが依存するライブラリはどれか\n * どのクロージャのバージョンを使うか\n * ソースファイルはどこを探せばよいか\n * アプリケーションのメインの名前空間は何か\n\nなどなど\n\n多くの Leiningen タスクはプロジェクトの文脈でのみ理解できるものです。\nいくつか(たとえば、 `repl` や `help`)などは任意のディレクトリから呼ぶこともできます。\n\n続いてプロジェクトがどのように作られるのか見てみましょう。\n\n## プロジェクトの作成\n\nわたしたちは、あなたが\n[README](https://codeberg.org/leiningen/leiningen/src/stable/README.md)\nにしたがって Leiningen をインストールしたと仮定します。\nこの時新しいプロジェクトを生成することは簡単です:\n\n    $ lein new app my-stuff\n\n\tmy-stuff という名前のプロジェクトを 'app' テンプレートに基づいて生成\n\n    $ cd my-stuff\n    $ find .\n    .\n    ./.gitignore\n    ./doc\n    ./doc/intro.md\n    ./LICENSE\n    ./project.clj\n    ./README.md\n    ./resources\n    ./src\n    ./src/my_stuff\n    ./src/my_stuff/core.clj\n    ./test\n    ./test/my_stuff\n    ./test/my_stuff/core_test.clj\n\nこの例では `app` テンプレートを使用しています。\nこのテンプレートはライブラリではなく\nアプリケーションのプロジェクトのためのものです。\n引数の `app` を省略すると `default` テンプレートが使用されますが、\nこれはライブラリに適したテンプレートです。\n\n### ディレクトリのレイアウト\n\nここで、プロジェクトの README 、コードの入った `src/` ディレクトリ、\n`test/` ディレクトリ、 Leiningen のためにプロジェクトについて記述された\n`project.clj` ファイルが得られます。 `src/my_stuff/core.clj` は\n名前空間 `my-stuff.core` に対応します。\n\n### ファイル名から名前空間への対応づけの変換\n\nここで、ただの `my-stuff` ではなく、\n`my-stuff.core` を使ったことに注意してください。\nこれは Clojure では単一セグメントの名前空間は非推奨であるためです。\n同様に名前にダッシュの入った名前空間は、\nアンダースコアの入ったファイル名に対応することに注意してください。\nこれは JVM は名前にダッシュの入ったファイルをロードしようとすると\nトラブルを引き起こすためです。\n名前空間の複雑さは新しくはじめた人たちにとってよくある混乱の元です。\nそういった話題についてはほとんどがこのチュートリアルの範囲外で、\n[別の場所で読むことが出来ます](https://8thlight.com/blog/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html)。\n\n## project.clj\n\nあなたの `project.clj` ファイルは以下のような見た目で始まっているでしょう:\n\n```clj\n(defproject my-stuff \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]]\n  :main ^:skip-aot my-stuff.core\n  :target-path \"target/%s\"\n  :profiles {:uberjar {:aot :all}})\n```\n\nもしあなたが `:description` に簡単な一文を記入しないと、\nあなたのプロジェクトを検索結果から見つける事は難しくなるので、\nここから初めましょう。同様に `:url` も間違いなく修正するようにしましょう。\n`README.md` ファイルも同様です。しかし今は飛ばして前に進み、\n`:dependencies` を設定しましょう。\nClojure はここでは単に依存関係の一つでしかないことに留意してください。\n多くの言語とはちがい、 Clojure のどのバージョンにも簡単に差し替えられます。\n\n## 依存関係\n\n### 概要\n\nClojure はホスト言語であり Clojure ライブラリは\nその他の JVM 言語と同じ方法で配布されます: jar ファイルとして。\n\nJar ファイルは基本的には `.zip` ファイルに\nJVM 特有のメタデータを追加したものです。\nJar ファイルは通常 `.class` ファイル(JVM のバイトコード)と\n`.clj` ソースを格納しており、また設定ファイルや JavaScript ファイルや、\n静的データのテキストファイルなども同様に格納しています。\n\n配布されている JVM ライブラリは*識別子*(アーティファクトグループ、アーティファクト ID)と、*バージョン*を持っています。\n\n### アーティファクト ID 、アーティファクトグループ、バージョン\n\nあなたは\n[Clojars を Web インターフェースから検索したり](https://clojars.org/search?q=clj-http)\n`lein search $TERM` によって検索することが出来ます。\nこのチュートリアルを書いている時点での\n`clj-http` についての Clojars ページは以下のようになっています:\n\n```clj\n[clj-http \"2.0.0\"]\n```\n\n依存関係は Maven や Gradle の文法でも表示されます。\nLeiningen の出したバージョンは、\nそのまま `project.clj` の `:dependencies` 配列にコピーできます。\nなのでたとえば、前の例の `project.clj` の\n`:dependencies` 行を変更する場合以下のようになります:\n\n```clj\n:dependencies [[org.clojure/clojure \"1.8.0\"]\n               [clj-http \"2.0.0\"]]\n```\n\nLeiningen は `clj-http` の jar を自動的にダウンロードし、\nあなたのクラスパスに存在するようにする。\nlein で明示的に依存関係をダウンロードしたい場合は\n`lein deps` を実行すればよいですが、\nこれはわざわざ実行せずとも必要に応じて実行されます。\n\n配列中で  \"clj-http\" は \"アーティファクト ID\" として参照されます。\n\"2.0.0\" はバージョンです。いくつかのライブラリは \"グループ ID\" を持っており、\nこれは以下のように表示されます。\n\n```clj\n[com.cedarsoft.utils.legacy/hibernate \"1.3.7\"]\n```\n\nグループ ID はスラッシュの前の部分です。\n特に Java ライブラリでは、しばしばドメイン名として予約されています。\nClojure ライブラリはしばしば同じグループ ID とアーティファクト ID を使い\n(clj-http のように)、その場合にはグループID を省略できます。\nより大きのグループの一部分であるライブラリ\n(たとえば `ring-jetty-adapter` は `ring` プロジェクトの一部です)\nがある場合、グループ ID はしばしば全てのサブプロジェクトで同じになります。\n\n### スナップショットのバージョン\n\nバージョンは \"-SNAPSHOT\" で終わることがあります。\nこれの意味するところは、それは正式なリリースではなく、\n開発ビルドだということです。スナップショットの依存関係に頼ることは\nおすすめできませんが、リリース前にバグを修正する必要があるときなど、\n必要な場合もあります。しかしスナップショットバージョンが\nstick around であることは保証されないので、\n開発リリース以外のケースで自分の管理下にないスナップショットバージョンに\n依存しないようにすることが重要です。\nスナップショットの依存関係をプロジェクトに追加すると、\nLeiningen がよりアクティブに毎日最新の依存関係のバージョンを\n取得するようになるので\n(一方で通常のリリースバージョンはローカルレポジトリにキャッシュされます)、\n多くのスナップショットを抱えている場合は色々と時間がかかるようになります。\n\n注意点として、いくつかのライブラリは、グループ ID とアーティファクト ID と\nそれらが jar で提供する名前空間の対応をづけるということです。\nこれは単なる慣習です。全ての場合に当てはまるという保証はありません。\nそのため `:require` 節と `:import` を記述する前に\nライブラリのドキュメントを熟読してください。\n\n### レポジトリ\n\n依存関係は*アーティファクトレポジトリ*に格納されています。\nPerl で言えば CPAN 、 Python で言えば Cheeseshop (PyPi ともいいます)、\nRuby であれば rubygems.org 、 Node.js であれば NPM などと、\n同じものです。 Leiningen は既存の JVM レポジトリのインフラを再利用します。\nいくつかのよく知られたオープンソースのレポジトリがあります。\nLeiningen はデフォルトでそれらを使います:\n[clojars.org](https://clojars.org) と [Maven Central](https://search.maven.org/) です。\n\n[Clojars](https://clojars.org/) は Clojure コミュニティの集約的な\nmaven レポジトリで、 [Central](https://search.maven.org/) は\nより幅広い JVM コミュにエィのレポジトリです。\n\nサードパーティのレポジトリは `:repositories` キーを project.clj に指定することで追加出来ます。\nどのようにすれば良いのか\n[sample.project.clj](https://codeberg.org/leiningen/leiningen/src/stable/sample.project.clj)\nを見てみましょう。このサンプルは追加のレポジトリとして Sonatype レポジトリを使っていますが、\nこれは(Clojure や Java の)ライブラリの、最新のスナップショット開発バージョンへのアクセスを提供します。\nこのサンプルには同様に、レポジトリに関連する更新頻度などの設定が含まれています。\n\n### 依存関係のチェックアウト\n\n時には複数のプロジェクト、メインのプロジェクトとそれが依存するプロジェクトを、\n並行して開発する必要もあるでしょう。そんな場合、何か変更を反映しようとするたびに、\n`lein install` を実行して REPL を再起動するのは、とても不便です。\nLeiningen は*依存関係のチェックアウト*(もしくは単に *チェックアウト*)\nという解決策を提供しています。この機能を使うためには、 `checkouts`\nというディレクトリを、以下のようにプロジェクトのルートディレクトリに作成します:\n\n    .\n    |-- project.clj\n    |-- README.md\n    |-- checkouts\n    |-- src\n    |   `-- my_stuff\n    |       `-- core.clj\n    `-- test\n        `-- my_stuff\n            `-- core_test.clj\n\nそして、 checkouts ディレクトリの下に、必要なプロジェクトのルートディレクトリへの\nシンボリックリンクを作成します。シンボリックリンクの名前は重要ではありません。\nLeiningen はそれらの全てを辿って `project.clj` ファイルを探します。\n習慣的には、シンボリックリンクはそれが指すディレクトリと同じ名前にします。\n\n    .\n    |-- project.clj\n    |-- README.md\n    |-- checkouts\n    |   `-- suchwow [link to ~/code/oss/suchwow]\n    |   `-- commons [link to ~/code/company/commons]\n    |-- src\n    |   `-- my_stuff\n    |       `-- core.clj\n    `-- test\n        `-- my_stuff\n            `-- core_test.clj\n\n`checkouts` ディレクトリ以下に配置されたライブラリは、\nレポジトリからプルするライブラリより優先されるようになりますが、\nメインのプロジェクトの `:dependencies` にそのプロジェクトを\n記述することの代わりにはなりません。チェックアウト機能は、\n単に利便性のために、依存関係の探索場所を追加するものです。\nしたがって、上述のディレクトリ構造では、 `project.clj` は以下のような内容を含むべきです:\n\n      :dependencies [[org.clojure/clojure \"1.9.0\"]\n                     ...\n                     [suchwow \"0.3.9\"]\n                     [com.megacorp/commons \"1.3.5\"]\n                     ...]\n                 \n\nMaven のグループ ID の `com.megacorp` はチェックアウトの挙動にはなんの影響も無いことに注意してください。\n`suchwow` と `commons` の２つのリンクは、 `checkouts` のなかでは同じものとして扱われるので、\nグループ ID の階層構造が、 `commons` がディスク上に実際の配置の仕方で表現される必要はありません。\n\n`:dependencies` を更新したときには、 `lein` が、 clojars や\n`~/.m2` ディレクトリといったいくつかのレポジトリに、\nライブラリを見つけることが出来る必要があります。\n`lein` が \"Could not find artifact suchwow:jar:0.3.9\"\n(アーティファクト suchwow:jar:0.3.9 が見つかりません)などと言い出したときは、\n`project.clj` と `suchwow/project.clj` が異なるバージョン番号を使っている可能性があります。\n別の可能性として、メインのプロジェクトと  `suchwow` で同時に作業をしていて、\n両方のプロジェクトファイルでバージョン番号を上げても、\n古いバージョンがローカルの Maven レポジトリに残っていることもあります。\n`suchwow` ディレクトリで `lein install` を実行してください。\nつまり、 `suchwow` のバージョン番号は*３つ*の場所で同じでなければなりません。\nまず suchwow の `project.clj` 、メインのプロジェクトの `project.clj` 、\n*そしてメインのレポジトリが使っている使っているいくつかのレポジトリ*です。\n\nチェックアウトプロジェクトの依存関係を変えるときには、\nやはり同様に `lein install` を実行し REPL を再起動する必要があります。\nソースの変更が直ちに取り込まれるでしょう。\n\nチェックアウトはオプトインの機能です。あるプロジェクトで作業をする全ての人が\n同じプロジェクト群をチェックアウトしているひつようはありません。\nですので、プロジェクトはプッシュしたりマージする前に、\nチェックアウトなしでも動くようにすべきです。\n\nチェックアウトを使っていても `base` プロファイルが上書きしないよう注意してください。\n実際には、これは `lein with-profile foo run` ではなく、\n`lein with-profile +foo run` を使うという事を通常は意味します。\n\n### 検索\n\nLeiningen はリモートの Maven の検索をサポートしています。\n一致する jar を `lein search $TERM` で検索できます。\n現時点では Central と Clojars のみがサポートされています。\n\n### Maven 読み込みタイムアウト\n\nLeiningen の使用している Maven Wagon 転送はシステムプロパティ  `maven.wagon.rto` を読み込み、\nアーティファクトをレポジトリからダウンロードする際のタイムアウト値を決定します。\n`lein` スクリプトはそのプロパティを 10000 に設定しています。\nもしタイムアウトの長さが十分でない場合(例えば企業の遅いミラーサイトをつかている場合)、\nLEIN_JVM_OPTS を通してオーバーライドすることが出来ます:\n\n```bash\nexport LEIN_JVM_OPTS=\"-Dmaven.wagon.rto=1800000\"\n``` \n\n## JVM オプションの設定\n\nJVM に追加の引数を渡すには、配列  `:jvm-opts`  をセットします。\nこれにより Leiningen が任意の JVM オプションのデフォルト値を上書きします。\n\n```clj\n :jvm-opts [\"-Xmx1g\"]\n```\n\nもし　Clojure コンパイラに[コンパイラオプション](https://clojure.org/reference/compilation#_compiler_options)を渡したいのであれば、\nこのときに同じようにして渡すことが出来ます。\n\n```\n:jvm-opts [\"-Dclojure.compiler.disable-locals-clearing=true\"\n           \"-Dclojure.compiler.elide-meta=[:doc :file :line :added]\" \n           ; notice the array is not quoted like it would be if you passed it directly on the command line.\n           \"-Dclojure.compiler.direct-linking=true\"]\n```\n\n同様にして `JVM_OPTS` 環境変数を通じて、 Leiningen にオプションを渡すことが出来ます。\nカスタムオプションつきの Leiningen JVM を起動したいのであれば、 `LEIN_JVM_OPTS` に設定してください。\n\n## コードの実行\n\n十分セットアップをしました。いよいよコードが実行されるのを見てみましょう。\nREPL(read-eval-print loop)を起動します:\n\n    $ lein repl\n    nREPL server started on port 55568 on host 127.0.0.1 - nrepl://127.0.0.1:55568\n    REPL-y 0.3.0\n    Clojure 1.5.1\n        Docs: (doc function-name-here)\n              (find-doc \"part-of-name-here\")\n      Source: (source function-name-here)\n     Javadoc: (javadoc java-object-or-class-here)\n        Exit: Control+D or (exit) or (quit)\n     Results: Stored in vars *1, *2, *3, an exception in *e\n\n    user=>\n\nREPL は対話的インターフェースで、任意のコードを入力してプロジェクトの文脈で実行出来ます。\n`clj-http` を `:dependencies` に追加したので、\nここでプロジェクトの `src/` ディレクトリにあるコードの\n名前空間 `my-stuff.core` からロードすることが出来ます:\n\n    user=> (require 'my-stuff.core)\n    nil\n    user=> (my-stuff.core/-main)\n    Hello, World!\n    nil\n    user=> (require '[clj-http.client :as http])\n    nil\n    user=> (def response (http/get \"https://leiningen.org\"))\n    #'user/response\n    user=> (keys response)\n    (:status :headers :body :request-time :trace-redirects :orig-content-encoding)\n\n`-main` の呼び出しは println の出力(\"Hello, World!\")と、\n返り値(nil)の両方を表示しています。\n\nビルトインのドキュメントは `doc` を通じて利用可能です。\n関数のソースコードは `source` で確認することが出来ます:\n\n    user=> (source my-stuff.core/-main)\n    (defn -main\n      \"I don't do a whole lot.\"\n      [& args]\n      (println \"Hello, World!\"))\n\n    user=> ; use control+d to exit\n\nすでに `-main` 関数に実行出来るだけのコードを実装しているなら、\n対話的にコードを入力するひつようはなく、 `run` タスクを実行するのが簡単です:\n\n    $ lein run\n    Hello, World!\n\n`-m` 引数を与えると、 Leiningen は `-main` 関数を他の名前空間から探します。\n`project.clj` でデフォルトの `:main` を指定する事で、  `-m` を省略することができます。\n\n`lein run` で実行するプロセスが非常に長時間に渡る場合、\n高次のトランポリンタスクによりメモリを節約したいと思うかもしれません。\nこのタスクはプロジェクトの JVM が起動する前に、\nLeiningen JVM のプロセスが終了出来るようにするものです。\n\n    $ lein trampoline run -m my-stuff.server 5000\n\nなにかコンパイルされるべき Java コードが、\n`:java-source-paths` や `:aot` で列挙された Clojure 名前空間にあった場合、\nLeiningen は `run` や `repl` などのタスクにより他のコードを実行する前に、\nそれらをコンパイルします。\n\n## テスト\n\nまだ一行もテストを書いて居ませんでした。\nしかし必ず失敗するテストがプロジェクトのテンプレートに含まれています:\n\n    $ lein test\n\n    lein test my-stuff.core-test\n\n    lein test :only my-stuff.core-test/a-test\n\n    FAIL in (a-test) (core_test.clj:7)\n    FIXME, I fail.\n    expected: (= 0 1)\n      actual: (not (= 0 1))\n\n    Ran 1 tests containing 1 assertions.\n    1 failures, 0 errors.\n    Tests failed.\n\nこれを埋めるとテストスィートはより便利になります。\n大きなテストスィートの場合には、\n一度に一つか２つの名前空間を実行したいこともあるでしょう。\n`lein test my-stuff.core-test` により可能です。\n同様にテストセレクタを使ってテストを分割したいと思うかもしれません。\n`lein help test` で詳細を確認してください。\n\nコマンドラインから `lein test` を実行することは、\nリグレッションテストに最適です。\nしかし JVM の起動時間の遅さは、\nよりタイトなフィードバックループを要求するテストスタイルには、\nあまり合いません。\nそのような場合は、 REPL を開けたままにしておき、\n[clojure.test/run-tests](https://clojuredocs.org/clojure.test/run-tests)\nを呼び出すか、エディタに統合された、\n[clojure-test-mode](https://github.com/technomancy/clojure-mode)\nを確認するなどしましょう。\n\n走行中のプロセスをそのままにしておくことは便利ですが、\nそのプロセスはディスク上のファイルを反映していない状態に\n簡単になってしまいます。\n関数がロードされた後にファイルから削除してもメモリに残るので、\n存在しない関数の引き起こす問題を見逃しやすくなります\n(よく「スライム化する」などと呼ばれます)。\nこのため、コミット前などに `lein test` をかならず定期的に\n新しいインスタンスで実行することが推奨されます。\n\n## プロファイル\n\nプロファイルは異なる文脈でプロジェクトマップに\n色々な要素を追加するために使われます。たとえば、\n`:test` プロファイルの内容は、それがもし存在するなら、\n`lein test` で実行されているあいだは、\nプロジェクトマップにマージされます。\n`:resource-paths` を通じてクラスパスに\n設定ファイルを含むディレクトリを追加するなどの方法で、\nテストが実行される間にだけ適用される設定を有効にするために\nこれを使う事が出来ます。 `lein help profiles` で詳細を確認してください。\n\n特に明言しない限り、 Leiningen はデフォルトのプロファイルセットを\nプロジェクトマップにマージします。\nこれには\n`:user` プロファイルのなかのユーザ全体の設定や、\nもしあるなら `project.clj` の `:dev` プロファイル、\nnREPL などの開発ツールとランタイム性能を犠牲にした\n起動時間の最適化などが含まれた組み込みの `:base` プロファイルを含みます。\nデフォルトのプロファイルでベンチマークを実行しないでください。\n(「段階的コンパイル」に関する FAQ の項目を参考にしてください)\n\n## Leiningen で何をするか\n\n一般的に言って、Leiningen を使ったプロジェクトでは\n以下の 3 つのゴールが一般的です:\n\n* エンドユーザに配布するアプリケーション\n* サーバサイドアプリケーション\n* 他の Clojure プロジェクトが利用するライブラリ\n\n最初のケースでは、 uberjar をビルドするのが一般的でしょう。\nライブラリを開発する場合、 Clojars や\nプライベートレポジトリといったレポジトリでそれを公開したいとことでしょう。\nサーバサイドアプリケーションの場合は以下に述べるような\nいくつかの場合があります。 `lein new app myapp` でプロジェクトを生成すると、\nライブラリの開発ではないプロジェクトに適した、\nいくつかの追加のデフォルトとともにプロジェクトを開始することが出来ます。\n[利用可能なテンプレートは Clojars で閲覧可能で](https://clojars.org/search?q=lein-template)、\n特定の Web テクノロジーを利用するためのものや、\nそのほかのタイプのプロジェクトのためのテンプレートがあります。\n\n### Uberjar\n\nuberjar ファイルを配布することは非常に簡単です。\nこれは単一のスタンドアロンで実行可能な jar ファイルで、\n非技術者のユーザに配布するのに適しています。\nuberjar ファイルを配布するには、\n`project.clj` の `:main` に名前空間を指定し、`:aot` にも追加することで、\nその名前空間が真っ先にコンパイルされるようにします。\nこの時点で `project.clj` ファイルは以下のようになっているはずです:\n\n```clj\n(defproject my-stuff \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]\n                 [clj-http \"2.0.0\"]]\n  :profiles {:dev {:dependencies [[ring/ring-devel \"1.4.0\"]]}}\n  :main my-stuff.core\n  :aot [my-stuff.core])\n```\n\n同様に開発時の依存関係、 `ring-devel` を追加しています。\n`ring-devel` はコンパイルされた uberjars では使えません。\nレポジトリにこのプロジェクトを公開する時には依存関係ではないとみなされます。\n\n指定された名前空間は `-main` 関数を含む必要がでてきます。\n`-main` 関数は、スタンドアロンの jar が実行されるときに呼ばれます。\nこの名前空間は、ファイルの一番上の、 `ns` フォームの中に\n`(:gen-class)` 宣言が書かれていなければなりません。\n`-main` 関数には、コマンドライン引数が渡されます。\n`src/my_stuff/core.clj` で何か簡単な事を試してみましょう:\n\n```clj\n(ns my-stuff.core\n  (:gen-class))\n\n(defn -main [& args]\n  (println \"Welcome to my project! These are your args:\" args))\n```\n\nこれで uberjar を生成する準備ができました:\n\n    $ lein uberjar\n    Compiling my-stuff.core\n    Created /home/phil/my-stuff/target/uberjar+uberjar/my-stuff-0.1.0-SNAPSHOT.jar\n    Created /home/phil/my-stuff/target/uberjar/my-stuff-0.1.0-SNAPSHOT-standalone.jar\n\nこの操作は一つの jar ファイルを生成します。\n生成された jar ファイルには全ての依存関係のファイルが含まれます。\nユーザは jar ファイルを単純に `java` を起動して実行できます。\nいくつかのシステムではダブルクリックで jar ファイルを実行できます。\n\n    $ java -jar my-stuff-0.1.0-SNAPSHOT-standalone.jar Hello world.\n    Welcome to my project! These are your args: (Hello world.)\n\n通常の(uber ではない) jar ファイルは、\nコマンドラインツールの `java` を使って実行できます。\nしかしこの方法はクラスパスの組み立てが必要であり、\nエンドユーザが対象のばあい、良い解決策ではありません。\n\nもちろん、ユーザがすでに Leiningen をインストールしている場合は、\n上で述べたようにユーザに `lein run` を使うように言うのも一つでしょう。\n\n### フレームワークの(Uber)jars\n\n多くの Java フレームワークはデプロイは、jar ファイルか、\nもしくはアプリケーションが必要とする依存関係の部分集合を含んだ派生の\n圧縮ファイルの形式によるという前提に立っています。\nそういったフレームワークは足りない依存関係は\n実行時に提供されるものと期待しています。\nそういった依存関係はコンパイルやテストの際には利用可能ですが、\n`uberjar` タスクやプラグインタスクのような\n安定したデプロイメントアーティファクトを作成することが目的の場合は、\nデフォルトで含まれることはありません。\n\n例えば Hadoop のジョブの jar は通常の(uber)jar ファイルで、\nHadoop ライブラリそれ自体を除く全ての依存関係を含んでいます:\n\n```clj\n(project example.hadoop \"0.1.0\"\n  ...\n  :profiles {:provided\n             {:dependencies\n              [[org.apache.hadoop/hadoop-core \"1.2.1\"]]}}\n  :main example.hadoop)\n```\n\n    $ lein uberjar\n    Compiling example.hadoop\n    Created /home/xmpl/src/example.hadoop/example.hadoop-0.1.0.jar\n    Created /home/xmpl/src/example.hadoop/example.hadoop-0.1.0-standalone.jar\n    $ hadoop jar example.hadoop-0.1.0-standalone.jar\n    12/08/24 08:28:30 INFO util.Util: resolving application jar from found main method on: example.hadoop\n    12/08/24 08:28:30 INFO flow.MultiMapReducePlanner: using application jar: /home/xmpl/src/example.hadoop/./example.hadoop-0.1.0-standalone.jar\n    ...\n\nプラグインはフレームワークの jar 派生のデプロイファイル(WAR ファイルなど)を\n生成することを必要とします。これは追加のメタデータを含みます。\nただし `:provided` プロファイルがフレームワークの依存関係を取り扱うための\n一般的なメカニズムを提供しています。\n\n### サーバサイドプロジェクト\n\nサーバサードアプリケーションとしてプロジェクトをデプロイする方法は沢山あります。\n明らかな uberjar のアプローチをべつにすると、\n単純なプログラムは、 [lein-tar プラグイン](https://github.com/technomancy/lein-tar)を使ってシェルスクリプトつきの tar ファイルとしてパッケージ化して、\n[pallet](https://hugoduncan.github.com/pallet/) や [chef](https://chef.io/) などの仕組みをつかってデプロイします。\nWeb アプリケーションは、 `ring-jetty-adapter` で組み込みの Jetty を使った uberjar としてデプロイするか、\n[lein-ring プラグイン](https://github.com/weavejester/lein-ring)によって作られた\n.war (web アプリケーションアーカイブ)ファイルとしてデプロイされます。\nuberjar 以上のことをしようとした場合、サーバサイドデプロイは多様であり、\nプラグインによって取り扱うほうが、 Leiningen 組み込みのタスクよりも良いのです。\n\nプロダクション環境で Leiningen を実行することも可能ですが、それには沢山の微妙な問題があります。\n可能であれば uberjar を使うことが強く推奨されます。 `run` タスクを立ち上げる必要があるときは、\nメモリを節約するために `lein trampoline run` を使うべきです。そうでなければ、\nLeiningen の自分自身の JVM は実行され続け、不必要なメモリを消費します。\n\n加えて非常に重要なこととして、デプロイする前に全ての依存関係を凍結するステップを踏まなければなりません。\nそうしなければ[繰り返せないデプロイ](https://wiki.leiningen.org/Repeatability)\n問題によって止まってしまいます。一つのデプロイ(tar ファイル, .deb ファイルなど)にプロジェクトのコードに加えて、\n`~/.m2/repository` を含むことを検討すべきです。継続インテグレーションを設定する際には、\nデプロイ可能なアーティファクトを作るために Leiningen を使う事が推奨されます。\nたとえば [Jenkins](https://jenkins-ci.org) CI サーバを持っていて、プロジェクトの完全なテストスィートを実行しており、\nテストを全て通るなら、 tar ファイルを S3 にアップロードするというような具合です。\nこの場合デプロイはプロダクションサーバに、便利だとよく知られた tar ファイルを取得して抽出するだけのことです。\nサーバ上でチェックアウトから単純に Leiningen を起動することは、最も基本的なデプロイの役に立ちます。\nしかしサーバの数が増えてくると、異種混合クラスタを動作させるリスクが出てきます。\nこれは各マシンが全く同じコードベースで実行されるという保証がないからです。\n\n特に指定しない限り、デフォルトのプロファイルが含まれることに注意してください。\nデフォルトのプロファイルはプロダクションに適しています。\n`lein trampoline with-profile production run -m myapp.main` の使用が推奨されます。\nデフォルトではプロダクションプロファイルは空です。しかし、tar ファイルを生成する CI の実行により、\nデプロイに `~/.m2/repository` ディレクトリが含まれるなら、`:local-repo` という形でそのパスを追加し、\n`:offline? true` を、 `:production` プロファイルに追加します。オフラインのままにしておくと、\nデプロイされたプロジェクトが CI 環境でテストされたバージョンから、完全に逸脱することを防ぎます。\n\nこういった落とし穴があるので、可能な限り urberjar を使う事が最善です。\n\n### ライブラリの公開\n\nもしプロジェクトがライブラリで、他の人がプロジェクトの中で\n依存関係としてそのライブラリを使えるようにしたいときは、\nそのライブラリをパブリックレポジトリに置く必要が出てきます。\n自分自身の[プライベートレポジトリを運用する](https://codeberg.org/leiningen/leiningen/src/stable/doc/DEPLOY.md)\nこともできますし、\n[Central](https://search.maven.org)に置くことも出来ますが、\n最も簡単なのは[Clojars](https://clojars.org)で公開する方法でしょう。\n一度[アカウントを作れば](https://clojars.org/register)、公開は容易です:\n\n    $ lein deploy clojars\n    No credentials found for clojars\n    See `lein help deploying` for how to configure credentials to avoid prompts.\n    Username: me\n    Password:\n    Created ~/src/my-stuff/target/my-stuff-0.1.0-SNAPSHOT.jar\n    Wrote ~/src/my-stuff/pom.xml\n    Retrieving my-stuff/my-stuff/0.1.0-SNAPSHOT/maven-metadata.xml\n        from https://repo.clojars.org/\n    Sending my-stuff/my-stuff/0.1.0-SNAPSHOT/my-stuff-0.1.0-20190525.161117-2.jar (9k)\n        to https://repo.clojars.org/\n    Sending my-stuff/my-stuff/0.1.0-SNAPSHOT/my-stuff-0.1.0-20190525.161117-2.pom (2k)\n        to https://repo.clojars.org/\n    Retrieving my-stuff/my-stuff/maven-metadata.xml\n        from https://repo.clojars.org/\n    Sending my-stuff/my-stuff/0.1.0-SNAPSHOT/maven-metadata.xml (1k)\n        to https://repo.clojars.org/\n    Sending my-stuff/my-stuff/maven-metadata.xml (1k)\n        to https://repo.clojars.org/\n\n一度このプロセスが成功すると、\n他のプロジェクトが依存できるパッケージとして利用出来るようになります。\nクレデンシャルを保存することで、毎回入力せずとも良くする方法があります。\n`lein help deploying` を参考にしてください。\nスナップショット版ではなくリリース版をデプロイするときは、\nLeiningen は [GPG](https://gnupg.org) を使って署名を行い、\nリリースの著作権を証明します。どのように設定を行うかの詳細については、\n[デプロイガイド](https://codeberg.org/leiningen/leiningen/src/stable/doc/DEPLOY.md)を参考にしてください。\nデプロイガイドでは他のレポジトリへのデプロイ方法の説明もしています。\n\n## おわり!\n\nさあ、次のあなたのプロジェクトのコーディングをはじめましょう!\n"
  },
  {
    "path": "doc/ja/lein_ja.1",
    "content": ".\\\"to render: groff -Dutf8 -Tutf8 -man doc/ja/lein_ja.1 > lein_ja.man\"\n.TH LEININGEN 1 \"2017 August 10\"\n.SH 名前\nlein \\- Clojure プロジェクトの自動化\n\n.SH 書式\n\n.B lein\n[\\fB\\-o\\fR] [\\fB\\-U\\fR] [\\fITASK\\fR [\\fIARGS\\fR]]\n.br\n.B lein\n[\\fB\\-h\\fR|\\fB\\-\\-help\\fR]\n.br\n.B lein\n[\\fB\\-v\\fR|\\fB\\-\\-version\\fR]\n\n.SH 説明\n\nLeiningen は Clojure プロジェクトを、髪の毛が燃え上がるような思いをせずに、\n自動化するためのものです。\n\nJava のために設計されたツールを使って Clojure プロジェクトの仕事をすると、\n非常に大変な思いをしてイライラすることがあります。\nLeiningen を使うことで、あなたは Clojure を書くだけでよくなります。\n\n.SH タスク\n\n.B lein help\nは、完全なタスクのリストを表示します。また、\n.B lein help TASK\nは、特定の一つのタスクの使用方法を表示します。\n\n.B lein help tutorial\nは、色々なタスクの通しでの使い方を詳細に説明します。\n最もよく使われるのは以下のタスクです:\n\n.RS\n.TP\n.B lein new NAME\n新しい空のプロジェクトを生成します。\n.TP\n.B lein test [TESTS]\nTESTS 名前空間のテスト、もしくは全てのテストを実行します。\n.TP\n.B lein repl\nネットワーク REPL サーバで対話的 REPL セッションを開始します。\n.TP\n.B lein uberjar\nプロジェクトとその依存関係をスタンドアロンの .jar ファイルとしてパッケージ化します。\n.TP\n.B lein install\nあなたのローカルレポジトリにプロジェクトをインストールします。\n.TP\n.B lein deploy [REPOSITORY]\nリモートレポジトリにライブラリをデプロイします。\n.RE\n\n.TP\n更に以下のようなタスクが利用可能です:\n\n.RS\n.TP\n.B lein change\n関数を適用して project.clj を書き換えます。\n\n.TP\n.B lein check\n構文をチェックしてリフレクションについて警告します。\n\n.TP\n.B lein classpath\n現在のプロジェクトのクラスパスを印字します。\n\n.TP\n.B lein clean\nプロジェクトのターゲットパスから全てのファイルを取り除きます。\n\n.TP\n.B lein compile\nClojure ソースコードを .class ファイルにコンパイルします。\n\n.TP\n.B lein deps\n全ての依存関係をダウンロードします。\n\n.TP\n.B lein do [TASK], ...\n他のタスクを連続して起動する、高階タスクです。\n\n.TP\n.B lein jar\nプロジェクトの全てのファイルを jar ファイルにパッケージ化します。\n\n.TP\n.B lein javac\nJava ソースファイルをコンパイルします。\n\n.TP\n.B lein pom\nMaven を使ったインターオペラビリティのために、pom.xml ファイルをディスクに書き出します。\n\n.TP\n.B lein release\n:release-tasks を実行します。\n\n.TP\n.B lein retest\n前回失敗したテスト名前空間のみを実行します。\n\n.TP\n.B lein run\nオプションのコマンドライン引数を付けて、-main 関数を実行します。\n\n.TP\n.B lein search\nリモートの maven レポジトリから一致するjar ファイルを探し出します。\n\n.TP\n.B lein show-profiles\n全ての利用可能なプロファイルを一覧表示するか、引数で与えられたプロファイルを表示します。\n\n.TP\n.B lein trampoline [TASK]\nLeiningen 内部でプロジェクトの JVM をネストさせずにタスクを実行します。\n\n.TP\n.B lein update-in\nプロジェクトマップに任意の変換を行います。\n\n.TP\n.B lein vcs\nバージョンコントロールシステムと対話します。\n\n.TP\n.B lein version\nLeiningen と現在の JVM のバージョンを印字します。\n\n.TP\n.B lein with-profile [PROFILE] [TASK]\n指定されたプロファイルで指定されたタスクを適用します。\n.RE\n\n.SH オプション\n\n.TP\n.BI \\-o\nオフラインでタスクを実行する。\n\n.TP\n.BI \\-U\nスナップショットのアップデートを強制した後タスクを実行する。\n\n.TP\n.BR \\-h \", \" \\-\\-help\nこのヘルプか指定されたタスクのヘルプを印字する。\n\n.TP\n.BR \\-v \", \" \\-\\-version\nLeiningen のバージョンを印字する。\n\n.SH 設定\n\nLeiningen はその設定ファイルとして、プロジェクトのルートディレクトリにある\n.B project.clj\nを読み込みます。もしこのファイルがなければ、\n.B lein new\nを実行して起点となる新しいプロジェクトを作成するか、そうでなければ\n\\fBlein help sample\\fR.\nを実行して設定項目の完全なリストを読んでください。\n\nプロファイルを使用することで何時でもプロジェクトマップをカスタマイズできます。以下を参考にしてください:\n\\fBlein help profiles\\fR.\n\n.SH バグ\n\nhttps://codeberg.org/leiningen/leiningen/issues を見て、\nあなたの問題が既知のものかどうか確認してください。\n\nその際には、\n.B lein version\nのアウトプットとあなたの\n.B project.clj\nファイルを含めてください、\nまた可能な限りあなたのプロジェクトの関連するコードも含めてください。\n\n.SH 著作権\n\nCopyright\n.if t \\(co\n.if n (C)\n2009-2017 Phil Hagelberg and contributors.\n\nDistributed under the Eclipse Public License, the same as Clojure\nuses. See the file /usr/share/doc/leiningen/copyright.\n\n.SH 著者\nこの manpage は Phil Hagelberg <technomancy@gmail.com> によって書かれました。\nこの manpage は Kazutaka Nakamura <kaznak.at.work@gmail.com> によって、日本語に翻訳されました。\n"
  },
  {
    "path": "doc/lein.1",
    "content": ".\\\"to render: groff -Tascii -man doc/lein.1 > lein.man\"\n.TH LEININGEN 1 \"2017 August 10\"\n.SH NAME\nlein \\- Automate Clojure projects\n\n.SH SYNOPSIS\n\n.B lein\n[\\fB\\-o\\fR] [\\fB\\-U\\fR] [\\fITASK\\fR [\\fIARGS\\fR]]\n.br\n.B lein\n[\\fB\\-h\\fR|\\fB\\-\\-help\\fR]\n.br\n.B lein\n[\\fB\\-v\\fR|\\fB\\-\\-version\\fR]\n\n.SH DESCRIPTION\n\nLeiningen is for automating Clojure projects without setting your hair\non fire.\n\nWorking on Clojure projects with tools designed for Java can be an\nexercise in frustration. With Leiningen, you just write Clojure.\n\n.SH TASKS\n\n.B lein help\nwill show the complete list of tasks, while\n.B lein help TASK\nshows usage for a specific one.\n\n.B lein help tutorial\nhas a detailed walk-through of the various tasks, but the most\ncommonly-used are:\n\n.RS\n.TP\n.B lein new NAME\ngenerate a new project skeleton\n.TP\n.B lein test [TESTS]\nrun the tests in the TESTS namespaces, or all tests\n.TP\n.B lein repl\nlaunch an interactive REPL session in a networked REPL server\n.TP\n.B lein uberjar\npackage up the project and its dependencies as a standalone .jar file\n.TP\n.B lein install\ninstall a project into your local repository\n.TP\n.B lein deploy [REPOSITORY]\ndeploy a library to a remote repository\n.RE\n\n.TP\nOther tasks available include:\n\n.RS\n.TP\n.B lein change\nRewrite project.clj by applying a function.\n\n.TP\n.B lein check\nCheck syntax and warn on reflection.\n\n.TP\n.B lein classpath\nPrint the classpath of the current project.\n\n.TP\n.B lein clean\nRemove all files from project's target-path.\n\n.TP\n.B lein compile\nCompile Clojure source into .class files.\n\n.TP\n.B lein deps\nDownload all dependencies.\n\n.TP\n.B lein do [TASK], ...\nHigher-order task to perform other tasks in succession.\n\n.TP\n.B lein jar\nPackage up all the project's files into a jar file.\n\n.TP\n.B lein javac\nCompile Java source files.\n\n.TP\n.B lein pom\nWrite a pom.xml file to disk for Maven interoperability.\n\n.TP\n.B lein release\nPerform :release-tasks.\n\n.TP\n.B lein retest\nRun only the test namespaces which failed last time around.\n\n.TP\n.B lein run\nRun a -main function with optional command-line arguments.\n\n.TP\n.B lein search\nSearch remote maven repositories for matching jars.\n\n.TP\n.B lein show-profiles\nList all available profiles or display one if given an argument.\n\n.TP\n.B lein trampoline [TASK]\nRun a task without nesting the project's JVM inside Leiningen's.\n\n.TP\n.B lein update-in\nPerform arbitrary transformations on your project map.\n\n.TP\n.B lein vcs\nInteract with the version control system.\n\n.TP\n.B lein version\nPrint version for Leiningen and the current JVM.\n\n.TP\n.B lein with-profile [PROFILE] [TASK]\nApply the given task with the profile(s) specified.\n.RE\n\n.SH OPTIONS\n\n.TP\n.BI \\-o\nRun a task offline.\n\n.TP\n.BI \\-U\nRun a task after forcing update of snapshots.\n\n.TP\n.BR \\-h \", \" \\-\\-help\nPrint this help or help for a specific task.\n\n.TP\n.BR \\-v \", \" \\-\\-version\nPrint Leiningen's version.\n\n.SH CONFIGURATION\n\nLeiningen reads its configuration from the\n.B project.clj\nfile in your project root. Either use\n.B lein new\nto create a fresh project from which to work, or see the exhaustive\nlist of configuration options with\n\\fBlein help sample\\fR.\n\nYou can customize your project map further with profiles; see\n\\fBlein help profiles\\fR.\n\n.SH BUGS\n\nCheck https://codeberg.org/leiningen/leiningen/issues to see if your\nproblem is a known issue. If not, please open a new issue on that site.\nPlease include the output of\n.B lein version\nas well as your\n.B project.clj\nfile and as much of the relevant code from your project as possible.\n\n.SH COPYING\n\nCopyright\n.if t \\(co\n.if n (C)\n2009-2017 Phil Hagelberg and contributors.\n\nDistributed under the Eclipse Public License, the same as Clojure\nuses. See the file /usr/share/doc/leiningen/copyright.\n\n.SH AUTHOR\nThis manpage is written by Phil Hagelberg <technomancy@gmail.com>\n"
  },
  {
    "path": "lein-pprint/README.md",
    "content": "# lein-pprint\n\nPretty-print a representation of the project map.\n\nThis is a sample of how a simple plugin would work.\n\n## Usage\n\nAdd `[lein-pprint \"1.3.2\"]` to `:plugins`.\n\n```bash\n$ lein pprint\n```\n\n```clj\n{:compile-path \"/home/phil/src/leiningen/lein-pprint/classes\",\n :group \"lein-pprint\",\n :source-path (\"/home/phil/src/leiningen/lein-pprint/src\"),\n :dependencies nil,\n :target-path \"/home/phil/src/leiningen/lein-pprint/target\",\n :name \"lein-pprint\",\n :root \"/home/phil/src/leiningen/lein-pprint\",\n :version \"1.0.0\",\n :jar-exclusions [#\"^\\.\"],\n :test-path (\"/home/phil/src/leiningen/lein-pprint/test\"),\n :repositories\n ([\"central\" {:url \"https://repo1.maven.org/maven2\"}]\n  [\"clojars\" {:url \"https://repo.clojars.org/\"}]),\n :uberjar-exclusions [#\"^META-INF/DUMMY.SF\"],\n :eval-in :leiningen,\n :plugins [[lein-swank \"1.4.0-SNAPSHOT\"]],\n :resources-path\n (\"/home/phil/src/leiningen/lein-pprint/dev-resources\"\n  \"/home/phil/src/leiningen/lein-pprint/resources\"),\n :native-path \"/home/phil/src/leiningen/lein-pprint/native\",\n :description \"Pretty-print a representation of the project map.\"}\n```\n\nUse the `--no-pretty` flag to just print rather than pretty-print.\n\n```bash\n$ lein pprint :version\n\"1.0.0\"\n$ lein pprint --no-pretty -- :version\n1.0.0\n```\n\n## License\n\nCopyright © 2012-2020 Phil Hagelberg and contributors.\n\nDistributed under the Eclipse Public License, the same as Clojure.\n"
  },
  {
    "path": "lein-pprint/project.clj",
    "content": "(defproject lein-pprint \"1.3.3-SNAPSHOT\"\n  :description \"Pretty-print a representation of the project map.\"\n  :url \"https://codeberg.org/leiningen/leiningen\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :eval-in-leiningen true)\n"
  },
  {
    "path": "lein-pprint/src/leiningen/pprint.clj",
    "content": "(ns leiningen.pprint\n  (:require [clojure.pprint :as pprint]))\n\n(defn- parse-flags [args]\n  (let [[flag separator & rest] args]\n    (if (= [flag separator] [\"--no-pretty\" \"--\"])\n      [println rest]\n      [pprint/pprint args])))\n\n(defn- get-values [project keys]\n  (if (seq keys)\n    (map #(let [key (read-string %)\n                f (if (sequential? key) get-in get)]\n            (f project key)) keys)\n    [project]))\n\n(defn ^:no-project-needed pprint\n  \"Usage: pprint [--no-pretty] [--] [selector...]\n\n  When no selectors are specified, pretty-prints a representation of\n  the entire project map.  Otherwise pretty-prints the item(s)\n  retrieved by (get-in project selector) when reading a selector\n  produces something sequential, or (get project selector) when it\n  doesn't.  If \\\"--no-pretty\\\" is specified, doesn't pretty-print,\n  just prints.\"\n  [project & args]\n  (let [[show keys] (parse-flags args)]\n    (run! show (get-values project keys)))\n  (flush))\n"
  },
  {
    "path": "lein-pprint/test/leiningen/test/pprint.clj",
    "content": "(ns leiningen.test.pprint\n  (:require [clojure.test :refer :all]\n            [leiningen.pprint :refer :all]))\n\n(def project {:foo {:bar \"str\"}})\n\n(defn check [desc keys output]\n  (is (= output (with-out-str (apply pprint project keys)))) desc)\n\n(defn check-no-pretty [desc keys output]\n  (check desc (concat [\"--no-pretty\" \"--\"] keys) output))\n\n(deftest test-pprint\n  (check \"pretty-print a key\" [\":foo\"] \"{:bar \\\"str\\\"}\\n\")\n\n  (check-no-pretty \"print a key\" [\":foo\"] \"{:bar str}\\n\")\n\n  (check \"pretty-print a sequence\" [\"[:foo :bar]\"] \"\\\"str\\\"\\n\")\n\n  (check-no-pretty \"print a sequence\" [\"[:foo :bar]\"] \"str\\n\")\n\n  (check \"pretty-print a project\" [] \"{:foo {:bar \\\"str\\\"}}\\n\")\n\n  (check-no-pretty \"print a project\" [] \"{:foo {:bar str}}\\n\")\n\n  (check \"pretty-print multiple\" [\":foo\" \"[:foo :bar]\"] \"{:bar \\\"str\\\"}\\n\\\"str\\\"\\n\")\n\n  (check-no-pretty \"print multiple\" [\":foo\" \"[:foo :bar]\"] \"{:bar str}\\nstr\\n\"))\n"
  },
  {
    "path": "leiningen-core/README.md",
    "content": "# Leiningen Core\n\nThis library provides the core functionality of Leiningen. This\nconsists of the task execution implementation, project configuration,\nand helper functions. The built-in tasks and the launcher scripts are\nkept in the main `leiningen` project.\n\n## Namespaces\n\n* **leiningen.core.main** contains the `-main` entry point along with\n    task handling functions like `apply-task` and `resolve-task`.\n* **leiningen.core.project** has `read` and `defproject` for getting a\n    project map from `project.clj` files. It also handles applying\n    profiles to the project map and loading plugins.\n* **leiningen.core.classpath** is where the project's classpath is\n    calculated. It handles Maven dependencies as well as checkout\n    dependencies.\n* **leiningen.core.eval** houses the `eval-in-project` function which\n    implements the isolation of project code from Leiningen's own code.\n* **leiningen.core.user** just has a handful of functions which handle\n    user-level configuration.\n\n## Running Tasks\n\nWhen Leiningen is invoked, it first reads the `project.clj` file and\napplies any active profiles to the resulting project map. (See\nLeiningen's own readme for a description of how profiles work.) Then\nit looks up the task which was invoked. Tasks are just functions named\nafter the task they implement and defined in the `leiningen.the-task`\nnamespace. They usually take a project map as their argument, but can\nalso run outside the context of a project. See the\n[plugin guide](https://codeberg.org/leiningen/leiningen/src/stable/doc/PLUGINS.md)\nfor more details on how tasks are written. The `apply-task` function\nlooks up the task function, checks to make sure it can be applied to\nthe provided arguments, and then calls it.\n\n## Project Isolation\n\nWhen you launch Leiningen, it must start an instance of Clojure to\nload itself. But this instance must not affect the project that you're\nbuilding. It may use a different version of Clojure or other\ndependencies from Leiningen itself, and Leiningen's code should not be\nvisible to the project's functions.\n\nLeiningen currently implements this by launching a sub-process using\n`leiningen.core.eval/eval-in-project`. Any code that must execute\nwithin the context of the project (AOT compilation, test runs, repls)\nneeds to go through this function. Before the process is launched, the\nproject must be \"prepped\", which consists of running all the tasks\nnamed in the project's `:prep-tasks` key. This defaults to `javac` and\n`compile`, but `defproject` or profiles may add additional tasks as\nnecessary. All prep tasks must be cheap to call if nothing has changed\nsince their last invocation.\n\nThe sub-process (referred to as the \"project JVM\") is an entirely new\ninvocation of the `java` command with its own classpath calculated\nfrom functions in the `leiningen.core.classpath` namespace. It can\neven use a different version of the JVM from Leiningen if the\n`:java-cmd` key is provided. It can only communicate with Leiningen's\nprocess via the file system, sockets, and its exit code.\n\nThe exception to this rule is when `:eval-in-leiningen` in\n`project.clj` is true, as is commonly used for Leiningen plugins.\nSince Leiningen plugins are intended to be used inside Leiningen\nitself, there's no need to enforce this isolation.\n\n## License\n\nCopyright © 2011-2022 Phil Hagelberg and contributors.\n\nDistributed under the Eclipse Public License, the same as Clojure.\n"
  },
  {
    "path": "leiningen-core/dev-resources/checkouts/lib1/project.clj",
    "content": "(defproject checkout-lib1 \"0.0.1\"\n  :description \"Test some checkouts.\")\n"
  },
  {
    "path": "leiningen-core/dev-resources/checkouts/lib2/project.clj",
    "content": "(defproject checkout-lib2 \"0.0.1\"\n  :description \"Test some checkouts.\")\n"
  },
  {
    "path": "leiningen-core/dev-resources/p1.clj",
    "content": "(defproject leiningen \"2.0.0-SNAPSHOT\"\n  :description \"Automate Clojure projects without setting your hair on fire.\"\n  :url \"https://github.com/technomancy/leiningen\"\n  :license {:name \"Eclipse Public License\"}\n  :dependencies [[leiningen-core \"2.0.0-SNAPSHOT\"]\n                 [clucy \"0.2.2\" :exclusions [org.clojure/clojure]]\n                 [lancet \"1.0.1\"]\n                 [robert/hooke \"1.1.2\"]\n                 [stencil \"0.2.0\"]\n                 [\"net.3scale/3scale-api\" \"3.0.2\"]\n                 [\"clj-http\" \"3.4.1\"]]\n  :twelve ~(+ 6 2 4)\n  :disable-implicit-clean true\n  :eval-in-leiningen true)\n"
  },
  {
    "path": "leiningen-core/dev-resources/p2.clj",
    "content": "(defproject middler \"0.0.1\"\n  :description \"Test some middleware.\"\n  :middleware [leiningen.core.test.project/add-seven])\n"
  },
  {
    "path": "leiningen-core/dev-resources/p3.clj",
    "content": "(defproject middlest \"0.0.1\"\n  :description \"Test explicit middleware inside a plugin.\"\n  :plugins [[lein-maven \"0.1.0\"]]\n  :middleware [leiningen.mvn/maven-checkouts])\n"
  },
  {
    "path": "leiningen-core/dev-resources/p4.clj",
    "content": "(defproject middler-no-implicits \"0.0.1\"\n  :description \"Test some middleware.\"\n  :middleware [leiningen.core.test.project/add-seven]\n  :implicits false)\n"
  },
  {
    "path": "leiningen-core/dev-resources/p5.clj",
    "content": "(defproject middler-no-implicit-middleware \"0.0.1\"\n  :description \"Test some middleware.\"\n  :middleware [leiningen.core.test.project/add-seven]\n  :implicit-middleware false)\n"
  },
  {
    "path": "leiningen-core/dev-resources/profile-metadata.clj",
    "content": "(defproject metadata-check \"0.1.0\"\n  :description \"Check that profile metadata is retained.\"\n  :license {:name \"Eclipse Public License\"}\n  :dependencies [[leiningen-core \"2.0.0-SNAPSHOT\"]\n                 [clucy \"0.2.2\" :exclusions [org.clojure/clojure]]\n                 [lancet \"1.0.1\"]\n                 [robert/hooke \"1.1.2\"]\n                 [stencil \"0.2.0\"]]\n  :profiles {:bar {:dependencies ^:please-keep-me [[lancet \"1.0.2\"]\n                                                   [stencil \"0.3.0\"]]\n                   :repositories ^:replace []}\n             :baz {:dependencies ^:hello []\n                   :repositories ^:displace []\n                   :java-opts [\"my\" \"java\" \"opts\"]}})\n"
  },
  {
    "path": "leiningen-core/dev-resources/replace-repositories.clj",
    "content": "(defproject metadata-check \"0.1.0\"\n  :description \"Check that repositories can be replaced.\"\n  :license {:name \"Eclipse Public License\"}\n  :dependencies [[robert/hooke \"1.1.2\"]\n                 [stencil \"0.2.0\"]]\n  :repositories ^:replace [[\"nexus\" {:url \"https://clojars.org/repo/\"}]])\n"
  },
  {
    "path": "leiningen-core/project.clj",
    "content": "(defproject leiningen-core \"2.12.0\"\n  :url \"https://codeberg.org/leiningen/leiningen\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :description \"Library for core functionality of Leiningen.\"\n  ;; If you update these, update resources/leiningen/bootclasspath-deps.clj too\n  :dependencies [[org.clojure/clojure \"1.12.2\"]\n                 [timofreiberg/bultitude \"0.3.0\"\n                  :exclusions [org.clojure/clojure\n                               org.tcrawley/dynapath]]\n                 [org.flatland/classlojure \"0.7.1\"]\n                 [robert/hooke \"1.3.0\"]\n                 [clj-commons/pomegranate \"1.2.24\"\n                  :exclusions [org.slf4j/jcl-over-slf4j org.slf4j/slf4j-api\n                               org.apache.maven.wagon/wagon-provider-api\n                               org.apache.httpcomponents/httpcore\n                               org.apache.httpcomponents/httpclient]]\n                 [com.hypirion/io \"0.3.1\"]\n                 [org.slf4j/slf4j-nop \"1.7.25\"] ; wagon-http uses slf4j\n                 ;; we pull this in transitively but want a newer version\n                 [org.clojure/tools.macro \"0.1.5\"]\n                 ;; this new version doesn't bring in a dependency on\n                 ;; an insecure version of jsoup\n                 [org.apache.maven.wagon/wagon-http \"3.5.3\"\n                  :exclusions [org.slf4j/slf4j-api]]\n                 [commons-io/commons-io \"2.6\"]]\n  :scm {:dir \"..\"}\n  :dev-resources-path \"dev-resources\"\n  :aliases {\"bootstrap\" [\"with-profile\" \"base\"\n                         \"do\" \"install,\" \"classpath\" \".lein-bootstrap\"]})\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/classpath.clj",
    "content": "(ns leiningen.core.classpath\n  \"Calculate project classpaths by resolving dependencies via Aether.\"\n  (:require [cemerick.pomegranate.aether :as aether]\n            [cemerick.pomegranate :as pomegranate]\n            [clojure.java.io :as io]\n            [clojure.string :as str]\n            [clojure.set :as set]\n            [leiningen.core.user :as user]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.pedantic :as pedantic])\n  (:import (java.io File)\n           (java.util.jar JarEntry JarFile)\n           (org.eclipse.aether.resolution DependencyResolutionException)))\n\n(defn- warn [& args]\n  ;; TODO: remove me once #1227 is merged\n  (require 'leiningen.core.main)\n  (apply (resolve 'leiningen.core.main/warn) args))\n\n(def ^:private warn-once (memoize warn))\n\n(defn ^:deprecated extract-native-deps [files native-path native-prefixes]\n  (doseq [file files\n          :let [native-prefix (get native-prefixes file \"native/\")\n                jar (try (JarFile. file)\n                      (catch Exception e\n                        (throw (Exception. (format \"Problem opening jar %s\" file) e))))]\n          entry (enumeration-seq (.entries jar))\n          :when (.startsWith (.getName entry) native-prefix)]\n    (let [f (io/file native-path (subs (.getName entry) (count native-prefix)))]\n      (if (.isDirectory entry)\n        (utils/mkdirs f)\n        (do (utils/mkdirs (.getParentFile f))\n            (io/copy (.getInputStream jar entry) f))))))\n\n(defn extract-native-dep!\n  \"Extracts native content into the native path. Returns true if at least one\n  file was extracted.\"\n  [native-path ^File file native-prefix]\n  (let [native? (volatile! false)\n        native-prefix (or native-prefix \"native/\")\n        ^JarFile jar (try (JarFile. file)\n                          (catch Exception e\n                            (throw (Exception. (format \"Problem opening jar %s\" file) e))))]\n    (doseq [^JarEntry entry (enumeration-seq (.entries jar))\n            :when (.startsWith (.getName entry) native-prefix)]\n      (vreset! native? true)\n      (let [f (io/file native-path (subs (.getName entry) (count native-prefix)))]\n        (if (.isDirectory entry)\n          (utils/mkdirs f)\n          (do (utils/mkdirs (.getParentFile f))\n              (io/copy (.getInputStream jar entry) f)))))\n    @native?))\n\n(defn- stale-extract-native-deps\n  \"Extract native dependencies by comparing what has already been extracted to\n  avoid redoing work. If stale files end up in some native path, new or old, the\n  user will receive a warning -- we cannot delete files as the native path may\n  be used for other things as well (or stuff generated earlier may be put in\n  there).\"\n  [{old-deps :dependencies\n    old-native-path :native-path} new-raw-deps relative-native-path native-path]\n  (let [renamed-old-deps (utils/map-vals\n                          old-deps\n                          #(set/rename-keys % {:vsn :old-vsn\n                                               :native-prefix :old-native-prefix\n                                               :native? :old-native?}))\n        renamed-new-raw-deps (utils/map-vals\n                              new-raw-deps\n                              #(set/rename-keys % {:vsn :new-vsn\n                                                   :native-prefix :new-native-prefix\n                                                   :file :new-file}))\n        join (merge-with merge renamed-old-deps renamed-new-raw-deps)\n        new-native-path? (and old-native-path\n                              (not= (io/file old-native-path) (io/file relative-native-path)))\n        maybe-stale (volatile! false)]\n    ;; Why all the warnings? Well, we cannot really delete a directory, as it\n    ;; may be populated by things created by others, either in a prep-step\n    ;; before us OR as manual work (adding some self-made native stuff into\n    ;; said). :native-path does not have to be in :target, which makes this\n    ;; stuff kind of hard to avoid. However, it is likely that this path is in\n    ;; the :target-path, which makes life easier for us. TODO: Fix this up for\n    ;; Lein 3.0 by enforcing native to be inside :target-path and stating that\n    ;; it should only be used by native deps.\n    (when new-native-path?\n      (warn-once \"Warning: You changed :native-path to\" (pr-str relative-native-path)\n                 \", but old native data is still available at\" (pr-str old-native-path))\n      (vreset! maybe-stale true)\n      (doseq [[_ {:keys [native-prefix file]}] new-raw-deps]\n        (extract-native-dep! native-path file native-prefix)))\n    (let [newly-extracted-deps\n          (->>\n           (for [[dep {:keys [old-vsn old-native-prefix old-native?\n                              new-vsn new-native-prefix new-file]}] join]\n             (cond (and (= old-vsn new-vsn) ;; no change, stuff already in directory\n                        (= old-native-prefix new-native-prefix))\n                   [dep {:vsn old-vsn\n                         :native-prefix old-native-prefix\n                         :native? old-native?}]\n\n                   (nil? old-vsn) ;; no old version, attempt to extract\n                   (let [native? (extract-native-dep! native-path new-file new-native-prefix)]\n                     [dep {:vsn new-vsn\n                           :native-prefix new-native-prefix\n                           :native? native?}])\n\n                   (nil? new-vsn) ;; dependency was removed\n                   (when (and (not new-native-path?) old-native?)\n                     (vreset! maybe-stale true)\n                     (warn-once \"Warning:\" dep old-vsn \"will still have its native content in :native-path\"))\n\n                   ;; prefix changed (possibly version as well)\n                   (not= old-native-prefix new-native-prefix)\n                   (let [native? (extract-native-dep! native-path new-file new-native-prefix)]\n                     (when (and (not new-native-path?) old-native?)\n                       (vreset! maybe-stale true)\n                       (warn-once \"Warning:\" dep \"had its native prefix changed, but content\"\n                                  \"from\"  (pr-str old-native-prefix) \"is still in :native-path\"))\n                     [dep {:vsn new-vsn\n                           :native-prefix new-native-prefix\n                           :native? native?}])\n\n                   ;; version changed (all options are now exhausted)\n                   (not= old-vsn new-vsn)\n                   (let [native? (extract-native-dep! native-path new-file new-native-prefix)]\n                     (when (and (not new-native-path?) old-native?)\n                       (vreset! maybe-stale true)\n                       (warn-once \"Warning: Native dependencies from the old version of\"\n                                  dep (str \"(\" old-vsn \") is still in :native-path\")))\n                     [dep {:vsn new-vsn\n                           :native-prefix new-native-prefix\n                           :native? native?}])))\n           (filter identity)\n           (into {}))]\n      (when @maybe-stale\n        (warn-once \"  Consider doing `lein clean` to remove potentially stale native files\"))\n      {:native-path relative-native-path\n       :dependencies newly-extracted-deps})))\n\n(defn- read-string-or-error\n  \"Like read-string, but will return ::error if the reader threw an error.\"\n  [s]\n  (try\n    (read-string s)\n    (catch Exception e\n       ::error)))\n\n(defn outdated-swap!\n  \"Performs f if cmp-val is not equal to the old compare value. f is\n  then called with (f outdated-val args...). If no previous cached\n  result is found, then outdated-val is set to nil.\n\n  The comparison value and cached value is stored\n  in :target-path/stale/`identifier`. Make sure your identifier is\n  unique, e.g. by providing your namespace and function name. The\n  values will be read through read-string and printed with pr-str.\n\n  outdated-swap! will not run outside of projects.\"\n  [project identifier cmp-val f & args]\n  (when (and (:root project) (:target-path project))\n    (let [file (io/file (:target-path project) \"stale\" identifier)\n          file-content (if (.exists file)\n                         (read-string-or-error (slurp file)))\n          [old-cmp-val outdated-val] (if (not= ::error file-content)\n                                       file-content)]\n      (when (= ::error file-content)\n        (warn-once \"Could not read the old stale value for\" identifier \", rerunning stale task\"))\n      (when (or (= ::error file-content)\n                (not= old-cmp-val cmp-val))\n        (utils/mkdirs (.getParentFile file))\n        (let [result (apply f outdated-val args)]\n          (spit file (pr-str [cmp-val result]))\n          result)))))\n\n(defn ^:deprecated when-stale\n  \"DEPRECATED: Use outdated-swap! instead.\n\n  Call f with args when keys in project.clj have changed since the last\n  run. Stores value of project keys in stale directory inside :target-path.\n  Because multiple callers may check the same keys, you must also provide a\n  token to keep your stale value separate. Returns true if the code was executed\n  and nil otherwise.\"\n  [token keys project f & args]\n  (warn-once \"leiningen.core.classpath/when-stale is deprecated, use outdated-swap! instead.\")\n  (let [file (io/file (:target-path project) \"stale\"\n                      (str (name token) \".\" (str/join \"+\" (map name keys))))\n        current-value (pr-str (map (juxt identity project) keys))\n        old-value (and (.exists file) (slurp file))]\n    (when (and (:name project) (:target-path project)\n               (not= current-value old-value))\n      (apply f args)\n      (utils/mkdirs (.getParentFile file))\n      (spit file (doall current-value))\n      true)))\n\n;; The new version of aether (lein 2.8.0+) is more strict about authentication\n;; settings; it will ignore :passphrase if :private-key-file is not set.\n;; s3-wagon-private uses :passphrase, so if you've got a private s3 repo, we'll\n;; set :private-key-file to an empty string here so that aether will allow the\n;; wagon to see it instead of silently discarding it.\n(defn- hack-private-key [repo]\n  (if-not (re-find #\"^s3p\" (:url repo \"\"))\n    repo\n    (update repo :private-key-file #(or % \"\"))))\n\n(defn add-repo-auth\n  \"Repository credentials (a map containing some of\n  #{:username :password :passphrase :private-key-file}) are discovered\n  from:\n\n  1. Looking up the repository URL in the ~/.lein/credentials.clj.gpg map\n  2. Scanning that map for regular expression keys that match the\n     repository URL.\n\n  So, a credentials map that contains an entry:\n\n    {#\\\"https://maven.company.com/.*\\\" {:username \\\"abc\\\" :password \\\"xyz\\\"}}\n\n  would be applied to all repositories with URLs matching the regex key\n  that didn't have an explicit entry.\"\n  [[id repo]]\n  [id (-> repo user/profile-auth user/resolve-credentials hack-private-key)])\n\n(defn get-non-proxy-hosts []\n  (let [system-no-proxy (System/getenv \"no_proxy\")\n        lein-no-proxy (System/getenv \"http_no_proxy\")]\n    (if (and (empty? lein-no-proxy) (not-empty system-no-proxy))\n      (->> (str/split system-no-proxy #\",\")\n           (map #(str \"*\" %))\n           (str/join \"|\"))\n      (System/getenv \"http_no_proxy\"))))\n\n(defn get-proxy-settings\n  \"Returns a map of the JVM proxy settings\"\n  ([] (get-proxy-settings \"http_proxy\"))\n  ([key]\n   (let [proxy (System/getenv key)]\n     (when-not (str/blank? proxy)\n       (let [url (utils/build-url proxy)\n             user-info (.getUserInfo url)\n             [username password] (and user-info (.split user-info \":\"))]\n         {:host (.getHost url)\n          :port (.getPort url)\n          :username username\n          :password password\n          :non-proxy-hosts (get-non-proxy-hosts)})))))\n\n(defn- update-policies [update checksum [repo-name opts]]\n  (let [project-policies (cond-> {}\n                           update (assoc :update update)\n                           checksum (assoc :checksum checksum))]\n    [repo-name (merge project-policies opts)]))\n\n(defn ^:internal default-aether-args\n  \"Returns a map of keyword arguments to be used with Pomegranate Aether\n  dependency resolution for the given project.\"\n  [{:keys [repositories local-repo offline? update checksum mirrors] :as project}]\n  {:local-repo local-repo\n   :offline? offline?\n   :repositories (->> repositories\n                      (map add-repo-auth)\n                      (map (partial update-policies update checksum)))\n   :mirrors (->> mirrors\n                 (map add-repo-auth)\n                 (map (partial update-policies update checksum)))\n   :proxy (get-proxy-settings)})\n\n(defn- print-failures [e]\n  (doseq [result (.getArtifactResults (.getResult e))\n          :when (not (.isResolved result))\n          exception (.getExceptions result)]\n    (warn (.getMessage exception)))\n  (doseq [ex (.getCollectExceptions (.getResult e))]\n    (warn (.getMessage ex))))\n\n(defn- root-cause [e]\n  (last (take-while identity (iterate (memfn getCause) e))))\n\n(def ^:private ^:dynamic *dependencies-session*\n  \"This is dynamic in order to avoid memoization issues.\")\n\n(defn- get-dependencies*\n  [dependencies-key managed-dependencies-key\n   {:keys [offline?] :as project}\n   {:keys [add-classpath?] :as args}]\n  {:pre [(every? vector? (get project dependencies-key))\n         (every? vector? (get project managed-dependencies-key))]}\n  (try\n    (apply\n      (if add-classpath?\n        pomegranate/add-dependencies\n        aether/resolve-dependencies)\n      (apply concat\n        (merge\n          (default-aether-args project)\n          {:managed-coordinates (get project managed-dependencies-key)\n           :coordinates (get project dependencies-key)\n           :repository-session-fn *dependencies-session*\n           :transfer-listener\n           (bound-fn [e]\n             (let [{:keys [type resource error]} e\n                   {:keys [repository name size trace]} resource\n                   aether-repos (if trace (.getRepositories (.getData trace)))\n                   find-repo #(or (= (.getUrl %) repository)\n                                  ;; sometimes the \"base\" url\n                                  ;; doesn't have a slash on it\n                                  (= (str (.getUrl %) \"/\") repository))]\n               (when-let [repo (and (= type :started)\n                                    (first (filter find-repo aether-repos)))]\n                 (locking *err*\n                   (warn \"Retrieving\" name \"from\" (.getId repo))))))})))\n    (catch DependencyResolutionException e\n      ;; Cannot recur from catch/finally so have to put this in its own defn\n      (print-failures e)\n      (warn \"This could be due to a typo in :dependencies, file system permissions, or network issues.\")\n      (warn \"If you are behind a proxy, try setting the 'http_proxy' environment variable.\")\n      (throw (ex-info \"Could not resolve dependencies\" {:suppress-msg true\n                                                        :exit-code 1} e)))\n    (catch Exception e\n      (let [exception-cause (root-cause e)]\n        (if (and (or (instance? java.net.UnknownHostException exception-cause)\n                     (instance? java.net.NoRouteToHostException exception-cause))\n                 (not offline?))\n          (get-dependencies* dependencies-key managed-dependencies-key\n                             (assoc project :offline? true) args)\n          (throw e))))))\n\n(def ^:private get-dependencies-memoized (memoize get-dependencies*))\n\n(defn ^:internal get-dependencies [dependencies-key managed-dependencies-key\n                                   project & args]\n  (let [ranges (atom []), overrides (atom [])\n        trimmed (select-keys project [dependencies-key managed-dependencies-key\n                                      :repositories :checksum :local-repo\n                                      :offline? :update :mirrors :memoize-buster])\n        deps-result (binding [*dependencies-session* (pedantic/session\n                                                      project ranges overrides)]\n                      (get-dependencies-memoized dependencies-key\n                                                 managed-dependencies-key\n                                                 trimmed (apply hash-map args)))]\n    (pedantic/warn-or-abort (:pedantic? project) @ranges @overrides)\n    deps-result))\n\n(defn- get-original-dependency\n  \"Return a match to dep (a single dependency vector) in\n  dependencies (a dependencies vector, such as :dependencies in\n  project.clj). Matching is done on the basis of the group/artifact id\n  and version.\"\n  [dep dependencies]\n  (some (fn [v] ; not certain if this is the best matching fn\n          (when (= (subvec dep 0 2) (subvec v 0 2 )) v))\n        dependencies))\n\n(defn get-native-prefix\n  \"Return the :native-prefix of a dependency vector, or nil.\"\n  [[id version & {:as opts}]]\n  (get opts :native-prefix))\n\n(defn native-dependency-info\n  \"Returns the dependency information about a dependency on the form\n  [id version native-prefix] if the dependency is not nil.\"\n  [dependency]\n  (if dependency\n    (let [[id version & {:as opts}] dependency]\n      [id version (get opts :native-prefix)])))\n\n(defn- native-dependency-map\n  \"Given a dependencies vector (such as :dependencies in project.clj) and a\n  dependencies tree, as returned by get-dependencies, return a map from\n  dependency identifier to :vsn, :file and :native-prefix (may be nil) for ALL\n  dependencies this project depends on -- including transitive ones.\"\n  [dependencies dependencies-tree]\n  (let [native-dep-info (->> (map #(or (get-original-dependency % dependencies) %)\n                                  (keys dependencies-tree))\n                             (map native-dependency-info))]\n    (->> (aether/dependency-files dependencies-tree)\n         (#(map vector % native-dep-info))\n         (filter #(re-find #\"\\.(jar|zip)$\" (.getName (first %))))\n         (map (fn [[file [id version native-prefix]]]\n                [id {:file file :vsn version :native-prefix native-prefix}]))\n         (into {}))))\n\n(defn- extract-native-dependencies\n  \"extract-native-dependencies calculates the native dependency map for all\n  dependencies, including transitive ones. It then extracts new native content\n  from native dependencies,\"\n  [{:keys [native-path dependencies] :as project} jars dependencies-tree]\n  ;; FIXME: This is a hack for a bug I noticed (issue #2077): Sometimes the\n  ;; project comes through without having an init-profiles call ran on it. This\n  ;; means that native-path is on an uninitialised form. The sane way to fix\n  ;; this up is to check if this is the case, and if so, just ignore it. (Don't\n  ;; worry, this call is done a ton of times)\n  ;; To check this, just check if the path is absolute:\n  (when (and native-path (.isAbsolute (io/file native-path)))\n    (let [relative-native-path (utils/relativize (:root project) native-path)\n          native-dep-map (native-dependency-map dependencies dependencies-tree)\n          snap-deps (utils/filter-vals native-dep-map\n                                       #(.endsWith (:vsn %) \"SNAPSHOT\"))\n          stale-check {:dependencies (utils/map-vals native-dep-map\n                                                     #(select-keys % [:vsn :native-prefix]))\n                       :native-path relative-native-path}]\n      (or (outdated-swap!\n           project \"leiningen.core.classpath.extract-native-dependencies\"\n           stale-check\n           stale-extract-native-deps\n           native-dep-map\n           relative-native-path\n           native-path)\n          ;; Always extract native deps from SNAPSHOT deps.\n          (doseq [[_ {:keys [native-prefix file]}] snap-deps]\n            (extract-native-dep! native-path file native-prefix))))))\n\n(def ^:private bootclasspath-deps\n  (if-let [deps-file (io/resource \"leiningen/bootclasspath-deps.clj\")]\n    (read-string (slurp deps-file))\n    {}))\n\n(defn- warn-conflicts\n  \"When using the bootclasspath (for boot speed), resources already on the\n  bootclasspath cannot be overridden by plugins, so notify the user about it.\"\n  [project dependencies]\n  (when (#{:warn :abort} (:pedantic? project))\n    (let [warned (atom false)]\n      (doseq [[artifact version] dependencies\n              :when (and (bootclasspath-deps artifact)\n                         (= :leiningen (:eval-in project))\n                         (not= (bootclasspath-deps artifact) version))]\n        (reset! warned true)\n        (warn-once \"Tried to load\" artifact \"version\" version \"but\"\n                   (bootclasspath-deps artifact) \"was already loaded.\"))\n      (when (and @warned\n                 (not (:root project))\n                 (not (:suppress-conflict-warnings project)))\n        (warn-once \"You can set :eval-in :subprocess in your :user profile;\"\n                   \"however this will increase repl load time.\")))))\n\n(defn resolve-managed-dependencies\n  \"Delegate dependencies to pomegranate. This will ensure they are\n  downloaded into ~/.m2/repository and that native components of\n  dependencies have been extracted to :native-path. If :add-classpath?\n  is logically true, will add the resolved dependencies to Leiningen's\n  classpath.\n\n  Supports inheriting 'managed' dependencies, e.g. to allow common dependency\n  versions to be specified from an alternate location in the project file, or\n  from a parent project file.\n\n  Returns a seq of the dependencies' files.\"\n  [dependencies-key managed-dependencies-key project & rest]\n  (let [dependencies-tree (apply get-dependencies dependencies-key\n                                 managed-dependencies-key project rest)\n        jars (->> dependencies-tree\n                  (aether/dependency-files)\n                  (filter #(re-find #\"\\.(jar|zip)$\" (.getName %))))]\n    (when (some #{:add-classpath?} rest)\n      (warn-conflicts project (concat (keys dependencies-tree)\n                                      (reduce into (vals dependencies-tree)))))\n    (when (and (= :dependencies dependencies-key)\n               (:root project))\n      (extract-native-dependencies project jars dependencies-tree))\n    jars))\n\n(defn ^:deprecated resolve-dependencies\n  \"Delegate dependencies to pomegranate. This will ensure they are\n  downloaded into ~/.m2/repository and that native components of\n  dependencies have been extracted to :native-path. If :add-classpath?\n  is logically true, will add the resolved dependencies to Leiningen's\n  classpath.\n\n  Returns a seq of the dependencies' files.\n\n  NOTE: deprecated in favor of `resolve-managed-dependencies`.\"\n  [dependencies-key project & rest]\n  (let [managed-dependencies-key (if (= dependencies-key :dependencies)\n                                   :managed-dependencies)]\n    (apply resolve-managed-dependencies dependencies-key managed-dependencies-key project rest)))\n\n(defn normalize-dep-vector\n  \"Normalize the vector for a single dependency, to ensure it is compatible with\n  the format expected by pomegranate.  The main purpose of this function is to\n  to detect the case where the version string for a dependency has been omitted,\n  due to the use of `:managed-dependencies`, and to inject a `nil` into the\n  vector in the place where the version string should be.\"\n  [dep]\n  ;; Some plugins may replace a keyword with a version string later on, so\n  ;; assume that even length vectors are alright. If not, then they will blow up\n  ;; at a later stage.\n  (if (even? (count dep))\n    dep\n    (let [id (first dep)\n          opts (rest dep)]\n      ;; it's important to preserve the metadata, because it is used for\n      ;; profile merging, etc.\n      (with-meta\n       (into [id nil] opts)\n       (meta dep)))))\n\n(defn normalize-dep-vectors\n  \"Normalize the vectors for the `:dependencies` section of the project.  This\n  ensures that they are compatible with the format expected by pomegranate.\n  The main purpose of this function is to to detect the case where the version\n  string for a dependency has been omitted, due to the use of `:managed-dependencies`,\n  and to inject a `nil` into the vector in the place where the version string\n  should be.\"\n  [deps]\n  (map normalize-dep-vector deps))\n\n(defn merge-versions-from-managed-coords\n  [deps managed-deps]\n  (aether/merge-versions-from-managed-coords\n   (normalize-dep-vectors deps)\n   managed-deps))\n\n(defn managed-dependency-hierarchy\n  \"Returns a graph of the project's dependencies.\n\n  Supports inheriting 'managed' dependencies, e.g. to allow common dependency\n  versions to be specified from an alternate location in the project file, or\n  from a parent project file.\"\n  [dependencies-key managed-dependencies-key project & options]\n  (if-let [deps-list (merge-versions-from-managed-coords\n                      (get project dependencies-key)\n                      (get project managed-dependencies-key))]\n    (aether/dependency-hierarchy deps-list\n                                 (apply get-dependencies dependencies-key\n                                        managed-dependencies-key\n                                        project options))))\n\n(defn dependency-hierarchy\n  \"Returns a graph of the project's dependencies.\"\n  [dependencies-key project & options]\n  (apply managed-dependency-hierarchy dependencies-key nil project options))\n\n(defn- normalize-path [root path]\n  (let [f (io/file path) ; http://tinyurl.com/ab5vtqf\n        abs (.getAbsolutePath (if (or (.isAbsolute f)\n                                      (.startsWith (.getPath f) \"\\\\\"))\n                                f (io/file root path)))\n        sep (System/getProperty \"path.separator\")]\n    (str/replace abs sep (str \"\\\\\" sep))))\n\n(defn ext-dependency?\n  \"Should the given dependency be loaded in the extensions classloader?\"\n  [dep]\n  (second\n   (some #(if (= :ext (first %)) dep)\n         (partition 2 dep))))\n\n(defn ext-classpath\n  \"Classpath of the extensions dependencies in project as a list of strings.\"\n  [project]\n  (seq\n   (->> (filter ext-dependency? (:dependencies project))\n        (assoc project :dependencies)\n        (resolve-managed-dependencies :dependencies :managed-dependencies)\n        (map (memfn getAbsolutePath)))))\n\n(defn- visit-project!\n  \"Records a visit to a project into the volatile `seen`, returning nil if the project has already been visited.\"\n  [seen {:keys [root] :as project}]\n  (when-not (@seen root)\n    (vswap! seen conj root)\n    project))\n\n(defn- project-paths\n  \"Returns a function that applies each function in checkout-paths to a given project and returns a flattened list of\n  classpath entries.\"\n  [checkout-paths]\n  (if (seq checkout-paths)\n    (comp flatten (apply juxt checkout-paths))\n    (constantly nil)))\n\n(def ^:internal ^:dynamic *seen* nil)\n\n(defn ^:internal checkout-deps-paths\n  \"Checkout dependencies are used to place source for a dependency\n  project directly on the classpath rather than having to install the\n  dependency and restart the dependent project.\"\n  [{:keys [checkout-deps-shares root] :as project}]\n  (require 'leiningen.core.project)\n  (try\n    ;; This function needs to be re-entrant as it is one of the default members of `:checkout-deps-shares`.\n    ;; Use *seen* to communicate visit state between invocations.\n    (binding [*seen* (or *seen* (volatile! #{root}))]\n      ;; Visit each project and accumulate classpaths into a vector. This cannot be lazy as *seen* must be bound.\n      (into []\n            (comp (keep (partial visit-project! *seen*))\n                  (mapcat (project-paths checkout-deps-shares)))\n            ((resolve 'leiningen.core.project/read-checkouts) project)))\n    (catch Exception e\n      (throw (Exception. (format \"Problem loading %s checkouts\" project) e)))))\n\n(defn get-classpath\n  \"Return the classpath for project as a list of strings.\"\n  [project]\n  (for [path (concat (:test-paths project)\n                     (:source-paths project)\n                     (:resource-paths project)\n                     [(:compile-path project)]\n                     (checkout-deps-paths project)\n                     (for [dep (resolve-managed-dependencies\n                                :dependencies :managed-dependencies project)]\n                       (.getAbsolutePath dep)))\n        :when path]\n    (normalize-path (:root project) path)))\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/eval.clj",
    "content": "(ns leiningen.core.eval\n  \"Evaluate code inside the context of a project.\"\n  (:require [classlojure.core :as cl]\n            [clojure.java.io :as io]\n            [clojure.string :as string]\n            [cemerick.pomegranate.aether :as aether]\n            [leiningen.core.project :as project]\n            [leiningen.core.main :as main]\n            [leiningen.core.classpath :as classpath]\n            [leiningen.core.utils :as utils])\n  (:import (com.hypirion.io Pipe ClosingPipe)\n           (java.io File)))\n\n(def ^:private arch-options\n  {:x86 [\"-d32\"] :x86_64 [\"-d64\"]})\n\n(def ^:deprecated get-os\n  \"Returns a keyword naming the host OS. Deprecated, use\n  leiningen.core.utils/get-os instead.\"\n  utils/get-os)\n\n(def ^:deprecated get-arch\n  \"Returns a keyword naming the host architecture. Deprecated, use\n  leiningen.core.utils/get-arch instead.\"\n  utils/get-arch)\n\n(def ^:deprecated platform-nullsink\n  \"Returns a file destination that will discard output.  Deprecated, use\n  leiningen.core.utils/platform-nullsink instead.\"\n  utils/platform-nullsink)\n\n(def ^:dynamic *eval-print-dup* false)\n\n;; # Preparing for eval-in-project\n\n(defn- write-pom-properties [{:keys [compile-path group name] :as project}]\n  (when (and (:root project) (:write-pom-properties project true))\n    (let [path (format \"%s/META-INF/maven/%s/%s/pom.properties\"\n                       (or compile-path \"target/classes\") group name)]\n      (utils/mkdirs (.getParentFile (io/file path)))\n      (spit path (project/make-project-properties project)))))\n\n(defn run-prep-tasks\n  \"Execute all the prep-tasks. A task can either be a string, or a\n  vector if it takes arguments. see :prep-tasks in sample.project.clj\n  for examples\"\n  [{:keys [prep-tasks] :as project}]\n  (doseq [task prep-tasks]\n    (let [[task-name & task-args] (if (vector? task) task [task])\n          task-name (main/lookup-alias task-name project)]\n      (main/apply-task task-name (dissoc project :prep-tasks) task-args))))\n\n;; Some tasks\n(defonce ^{:doc \"Block on this to wait till the project is fully prepped.\"}\n  prep-blocker (atom (promise)))\n\n(defn- remove-default-paths\n  ;; Hack to get around #2010. I'm sorry =(\n  ;; We track down metadata keys on the form :default-path/foo, then absolutize\n  ;; foo and remove it from the list ONCE if we see it.\n  [project paths]\n  (let [paths-to-remove (for [k (keys (meta paths))\n                              :when (and (keyword? k)\n                                         (= \"default-path\" (namespace k)))]\n                          (str (io/file (:root project) (name k))))]\n    (loop [acc []\n           to-remove (set paths-to-remove)\n           [fst & rst :as ps] paths]\n      (cond (not (seq ps)) acc\n            (to-remove fst) (recur acc (disj to-remove fst) rst)\n            :else (recur (conj acc fst) to-remove rst)))))\n\n(defn prep\n  \"Before we can run eval-in-project we need to prep the project by running\n  javac, compile, and any other tasks the project specifies.\"\n  [project]\n  ;; These must exist before the project is launched.\n  (when (:root project)\n    (utils/mkdirs (io/file (:compile-path project \"/tmp\")))\n    ;; hack to not create default projects. For now only.\n    (doseq [path (mapcat #(remove-default-paths project %)\n                         ((juxt :source-paths :test-paths :resource-paths) project))]\n      (utils/mkdirs (io/file path))))\n  (write-pom-properties project)\n  (classpath/resolve-managed-dependencies :dependencies :managed-dependencies project)\n  (run-prep-tasks project)\n  (deliver @prep-blocker true)\n  (reset! prep-blocker (promise)))\n\n;; # Subprocess stuff\n\n(defn native-arch-paths\n  \"Paths to the os/arch-specific directory containing native libs.\"\n  [project]\n  (let [os (:os project (utils/get-os))\n        arch (:arch project (utils/get-arch))\n        native-path (:native-path project)]\n    (if (and os arch)\n      (conj\n       (->> (:dependencies project)\n            (map classpath/get-native-prefix)\n            (remove nil?)\n            (map #(io/file native-path %)))\n       (io/file native-path (name os) (name arch))))))\n\n(defn- as-str [x]\n  (if (instance? clojure.lang.Named x)\n    (name x)\n    (str x)))\n\n(defn- d-property [[k v]]\n  (format \"-D%s=%s\" (as-str k) v))\n\n(defn ^:internal get-jvm-opts-from-env [env-opts]\n  (and (seq env-opts)\n       (re-seq #\"(?:[^\\s\\\"']+|\\\"[^\\\"]*\\\"|'[^']*')+\" (string/trim env-opts))))\n\n(defn- get-jvm-args\n  \"Calculate command-line arguments for launching java subprocess.\"\n  [project]\n  (let [native-arch-paths (native-arch-paths project)]\n    `(~(d-property [:file.encoding (or (System/getProperty \"file.encoding\") \"UTF-8\")])\n      ~@(get-jvm-opts-from-env (System/getenv \"JVM_OPTS\"))\n      ~@(:jvm-opts project)\n      ~@(get arch-options (:arch project))\n      ;; TODO: support -Xverify:none\n      ~@(map d-property {:clojure.compile.path (:compile-path project)\n                         (str (:name project) \".version\") (:version project)\n                         :clojure.debug (boolean (or (System/getenv \"DEBUG\")\n                                                     (:debug project)))})\n      ~@(if native-arch-paths\n          (let [extant-paths (filter #(.exists %) native-arch-paths)]\n            (if (seq extant-paths)\n              [(d-property [:java.library.path\n                            (string/join java.io.File/pathSeparatorChar\n                                         extant-paths)])])))\n      ~@(when-let [{:keys [host port non-proxy-hosts]} (classpath/get-proxy-settings)]\n          [(d-property [:http.proxyHost host])\n           (d-property [:http.proxyPort port])\n           (d-property [:http.nonProxyHosts non-proxy-hosts])])\n      ~@(when-let [{:keys [host port]} (classpath/get-proxy-settings \"https_proxy\")]\n          [(d-property [:https.proxyHost host])\n           (d-property [:https.proxyPort port])]))))\n\n(def ^:dynamic *dir*\n  \"Directory in which to start subprocesses with eval-in-project or sh.\"\n  (System/getProperty \"user.dir\"))\n\n(def ^:dynamic *env*\n  \"Environment map with which to start subprocesses with eval-in-project or sh.\n  Merged into the current environment unless ^:replace metadata is attached.\"\n  nil)\n\n(def ^:dynamic *pump-in*\n  \"Rebind this to false to disable forwarding *in* to subprocesses.\"\n  true)\n\n(def drip-env\n  {\"DRIP_INIT\" nil\n   \"DRIP_INIT_CLASS\" nil})\n\n(defn- overridden-env\n  \"Returns an overridden version of the current environment as an Array of\n  Strings of the form name=val, suitable for passing to Runtime#exec.\"\n  [env]\n  (->> (if (:replace (meta env))\n         env\n         (merge {} (System/getenv) drip-env env))\n       (filter val)\n       (map #(str (name (key %)) \"=\" (val %)))\n       (into-array String)))\n\n(def ^:dynamic *sh-silent?* false)\n\n(defn sh ;; TODO 3.0.0 - move to independent namespace. e.g. io.clj\n  \"A version of clojure.java.shell/sh that streams in/out/err.\"\n  [& cmd]\n  (when *pump-in*\n    (utils/rebind-io!))\n  (let [env (overridden-env *env*)\n        proc (.exec (Runtime/getRuntime) (into-array String cmd) env (io/file *dir*))]\n    (.addShutdownHook (Runtime/getRuntime)\n                      (Thread. (fn [] (.destroy proc))))\n    (with-open [out (.getInputStream proc)\n                err (.getErrorStream proc)\n                in (.getOutputStream proc)]\n      (let [pump-out (or *sh-silent?* (doto (Pipe. out System/out) .start))\n            pump-err (or *sh-silent?* (doto (Pipe. err System/err) .start))\n            ;; TODO: this prevents nrepl need-input msgs from being propagated\n            ;; in the case of connecting to Leiningen over nREPL.\n            pump-in (ClosingPipe. System/in in)]\n        (when *pump-in* (.start pump-in))\n        (when (not *sh-silent?*)\n          (.join pump-out)\n          (.join pump-err))\n        (let [exit-value (.waitFor proc)]\n          (when *pump-in*\n            (.kill System/in)\n            (.join pump-in)\n            (.resurrect System/in))\n          exit-value)))))\n\n(defn sh-with-exit-code\n  \"Applies SH to CMD and on a non-0 exit code, throws an Exception\n  using FAILURE-MESSAGE. A period is appended to FAILURE-MESSAGE.\n  Returns the exit code on success.\n\n  FAILURE-MESSAGE must satisfy `string?`.\n  (first CMD) must satisfy `string?`.\"\n  [failure-message & cmd]\n  {:pre [(string? failure-message)\n         (string? (first cmd))]}\n  (let [exit-code (apply sh cmd)]\n    (when-not (= 0 exit-code)\n      (throw (Exception. (format \"%s. %s exit code: %d\" failure-message (first cmd) exit-code))))\n    exit-code))\n\n(defn- agent-arg [coords file]\n  (let [{:keys [options bootclasspath]} (apply hash-map coords)]\n    (concat [(str \"-javaagent:\" file (and options (str \"=\" options)))]\n            (if bootclasspath [(str \"-Xbootclasspath/a:\" file)]))))\n\n(defn ^:internal classpath-arg [project]\n  (let [classpath-string (string/join java.io.File/pathSeparatorChar\n                                      (classpath/get-classpath project))\n        agent-tree (classpath/get-dependencies :java-agents nil project)\n        ;; Seems like you'd expect dependency-files to walk the whole tree\n        ;; here, but it doesn't, which is what we want. but maybe a bug?\n        agent-jars (aether/dependency-files (aether/dependency-hierarchy\n                                             (:java-agents project) agent-tree))]\n    `(~@(mapcat agent-arg (:java-agents project) agent-jars)\n      ~@(if (:bootclasspath project)\n          [(str \"-Xbootclasspath/a:\" classpath-string)]\n          [\"-classpath\" classpath-string]))))\n\n(defn shell-command\n  \"Calculate vector of strings needed to evaluate form in a project subprocess.\"\n  [project form]\n  (let [checksum (System/getProperty \"leiningen.input-checksum\")\n        init-file (if (empty? checksum)\n                    (File/createTempFile \"form-init\" \".clj\")\n                    (io/file (:target-path project) (str checksum \"-init.clj\")))]\n    (spit init-file\n          ;; NOTE: we can't include metadata in the printed forms by default, because this breaks\n          ;;       some plugins (when metadata includes objects that don't have a tagged\n          ;;       literal reader). Requires opt-in via `:preserve-eval-meta true`.\n          ;;       See https://github.com/technomancy/leiningen/issues/2328 and\n          ;;       https://github.com/technomancy/leiningen/issues/2814\n          (binding [*print-dup* *eval-print-dup*\n                    *print-meta* (:preserve-eval-meta project)]\n            (pr-str (when-not (System/getenv \"LEIN_FAST_TRAMPOLINE\")\n                      `(.deleteOnExit (File. ~(.getCanonicalPath init-file))))\n                    form)))\n    `(~(or (:java-cmd project) (System/getenv \"JAVA_CMD\") \"java\")\n      ~@(classpath-arg project)\n      ~@(get-jvm-args project)\n      \"clojure.main\" \"-i\" ~(.getCanonicalPath init-file))))\n\n;; # eval-in multimethod\n\n(defmulti eval-in\n  \"Evaluate the given form in various contexts.\"\n  ;; Force it to be a keyword so that we can accept symbols too. That\n  ;; way ^:replace and ^:displace metadata can be applied.\n  (fn [project _] (keyword (name (:eval-in project :default)))))\n\n(defmethod eval-in :default [project form]\n  (eval-in (assoc project :eval-in :subprocess) form))\n\n(defmethod eval-in :subprocess [project form]\n  (binding [*dir* (:root project)]\n    (let [exit-code (apply sh (shell-command project form))]\n      (when (pos? exit-code)\n        (throw (ex-info (format \"Subprocess failed (exit code: %d)\" exit-code)\n                        {:exit-code exit-code}))))))\n\n(defonce trampoline-project (atom nil))\n(defonce trampoline-forms (atom []))\n(defonce trampoline-profiles (atom []))\n\n(defmethod eval-in :trampoline [project form]\n  (reset! trampoline-project project)\n  (swap! trampoline-forms conj form)\n  (swap! trampoline-profiles conj (select-keys project\n                                               [:dependencies :source-paths\n                                                :resource-paths :test-paths])))\n\n(defn ^:internal parse-d-property [jvm-arg]\n  (if-let [[_ k v] (re-matches #\"-D(.*?)=(?s)(.*)\" jvm-arg)]\n    [k v]))\n\n(defmethod eval-in :classloader [project form]\n  (when-let [classpath (map io/file (classpath/ext-classpath project))]\n    (cl/wrap-ext-classloader classpath))\n  (let [classpath   (map io/file (classpath/get-classpath project))\n        classloader (cl/classlojure classpath)]\n    (doseq [[k v] (keep parse-d-property (get-jvm-args project))]\n      (if (= k \"java.library.path\")\n        (cl/alter-java-library-path!\n         (constantly (string/split v (re-pattern java.io.File/pathSeparator))))\n        (System/setProperty k v)))\n    (try (cl/eval-in classloader form)\n         (catch Exception e\n           (println (str \"Error evaluating in classloader: \"\n                         (class e) \":\" (.getMessage e)))\n           (.printStackTrace e)\n           (throw (ex-info \"Classloader eval failed\" {:exit-code 1}))))))\n\n(defn- send-input [message client session pending]\n  (let [id (str (java.util.UUID/randomUUID))]\n    (swap! pending conj id)\n    (message client {:id id :op \"stdin\" :stdin (str (read-line) \"\\n\")\n                     :session session})))\n\n(defn- done? [{:keys [id status] :as msg} pending]\n  (let [pending? (@pending id)]\n    (swap! pending disj id)\n    (and (not pending?) (some #{\"done\" \"interrupted\" \"error\"} status))))\n\n(defmethod eval-in :nrepl [project form]\n  (require 'nrepl.core)\n  (require 'nrepl.transport)\n  (let [port-file (io/file (:root project) \".nrepl-port\")\n        connect (resolve 'nrepl.core/connect)\n        client (resolve 'nrepl.core/client)\n        client-session (resolve 'nrepl.core/client-session)\n        message (resolve 'nrepl.core/message)\n        recv (resolve 'nrepl.transport/recv)]\n    (if (.exists port-file)\n      (let [transport (connect :host \"localhost\"\n                               :port (Integer. (slurp port-file)))\n            client (client-session (client transport Long/MAX_VALUE))\n            pending (atom #{})]\n        (message client {:op \"eval\" :code (binding [*print-dup* *eval-print-dup*\n                                                    *print-meta* (:preserve-eval-meta project)]\n                                            (pr-str form))})\n        (doseq [{:keys [out err status session] :as msg} (repeatedly\n                                                          #(recv transport 100))\n                :while (not (done? msg pending))]\n          (when out (print out) (flush))\n          (when err (binding [*out* *err*] (print err) (flush)))\n          (when (some #{\"need-input\"} status)\n            (send-input message client session pending))))\n      ;; TODO: warn that repl couldn't be used?\n      (eval-in (assoc project :eval-in :subprocess) form))))\n\n(defmethod eval-in :leiningen [project form]\n  (when (:debug project)\n    (System/setProperty \"clojure.debug\" \"true\"))\n  ;; :dependencies are loaded the same way as plugins in eval-in-leiningen\n  (project/load-plugins project :dependencies :managed-dependencies)\n  (project/init-lein-classpath project)\n  (doseq [[k v] (keep parse-d-property (get-jvm-args project))]\n    (System/setProperty k v))\n  (eval form))\n\n(defmethod eval-in :pprint [project form]\n  (require 'clojure.pprint)\n  (println \"Java:\" (or (:java-cmd project) (System/getenv \"JAVA_CMD\") \"java\"))\n  (apply println \"Classpath:\" (classpath-arg project))\n  (apply println \"JVM args:\" (get-jvm-args project))\n  ;; Can't use binding with dynamic require\n  (let [dispatch-var (resolve 'clojure.pprint/*print-pprint-dispatch*)\n        code-dispatch @(resolve 'clojure.pprint/code-dispatch)]\n    (try (push-thread-bindings {dispatch-var code-dispatch})\n         (binding [*print-meta* (:preserve-eval-meta project)]\n           ((resolve 'clojure.pprint/pprint) form))\n         (finally (pop-thread-bindings)))))\n\n(defn eval-in-project\n  \"Executes form in isolation with the classpath and compile path set correctly\n  for the project. If the form depends on any requires, put them in the init arg\n  to avoid the Gilardi Scenario: https://technomancy.us/143\"\n  ([project form] (eval-in-project project form nil))\n  ([project form init]\n     (prep project)\n     (when (:warn-on-reflection project)\n       (main/warn \";; WARNING: :warn-on-reflection is deprecated in project.clj;\"\n                  \"use :global-vars.\"))\n     (eval-in project\n              `(do (set! ~'*warn-on-reflection*\n                         ~(:warn-on-reflection project))\n                   ~@(map (fn [[k v]] `(set! ~k ~v)) (:global-vars project))\n                   ~init\n                   ~@(:injections project)\n                   ~form))))\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/main.clj",
    "content": "(ns leiningen.core.main\n  (:require [leiningen.core.user :as user]\n            [leiningen.core.project :as project]\n            [leiningen.core.classpath :as classpath]\n            [leiningen.core.utils :as utils]\n            [clojure.java.io :as io]\n            [clojure.string :as string]\n            [clojure.stacktrace :as stacktrace]\n            [bultitude.core :as b]\n            [cemerick.pomegranate.aether :as aether]))\n\n(def aliases {\"-h\" \"help\", \"-help\" \"help\", \"--help\" \"help\", \"-?\" \"help\",\n              \"-v\" \"version\", \"-version\" \"version\", \"--version\" \"version\",\n              \"überjar\" \"uberjar\",\n              \"-o\" [\"with-profile\" \"+offline\"]\n              \"-U\" [\"with-profile\" \"+update\"]\n              \"cp\" \"classpath\" \"halp\" \"help\"\n              \"with-profiles\" \"with-profile\"\n              \"readme\" [\"help\" \"readme\"]\n              \"tutorial\" [\"help\" \"tutorial\"]\n              \"sample\" [\"help\" \"sample\"]})\n\n;; without a delay this loads profiles at the top-level which can\n;; result in exceptions thrown outside of a nice catching context.\n(def ^:private profile-aliases\n  \"User profile aliases, used only when Lein is not within a project.\"\n  (delay (atom (-> (user/profiles) :user :aliases))))\n\n(defn- get-and-dissoc!\n  \"Returns a value associated with a key in a hash map contained in an atom,\n  removing it if it exists.\"\n  [atom key]\n  (when-let [[k v] (find @atom key)]\n    (swap! atom dissoc key)\n    v))\n\n(defn- merge-alias-meta [task-vector task-name]\n  (merge (select-keys (meta task-vector) [:pass-through-help])\n         (meta task-name)))\n\n(defn lookup-alias\n  \"Recursively look up aliases until the task is not an alias anymore. If\n  task-name is a vector, calls lookup-alias on the first argument and returns a\n  partially applied task. Discards already used aliases.\"\n  [task-name project & [not-found]]\n  (if (vector? task-name)\n    (let [[t & args] task-name ;; never mind the poor naming here.\n          resolved-task (lookup-alias t project not-found)\n          task-vector (if (vector? resolved-task)\n                        resolved-task\n                        [resolved-task])\n          merged-meta (merge-alias-meta task-vector task-name)]\n      (-> task-vector\n          (into args)\n          (with-meta merged-meta)))\n    (let [project-wo-alias (update-in project [:aliases] dissoc task-name)\n          resolved-task (or (aliases task-name)\n                            (get (:aliases project) task-name)\n                            (when-not project\n                              (get-and-dissoc! @profile-aliases task-name)))]\n      (cond (nil? resolved-task) (or task-name not-found \"help\")\n            (= task-name resolved-task) task-name\n            :else (recur resolved-task project-wo-alias not-found)))))\n\n(defn- lookup-task-var\n  \"Require and resolve a leiningen task from its name.\"\n  [task-name]\n  (or (utils/require-resolve (str \"leiningen.plugin\" task-name) task-name)\n      (utils/require-resolve (str \"leiningen.\" task-name) task-name)))\n\n(declare remove-alias)\n\n(defn- pass-through-help? [task-name project]\n  (let [de-aliased (lookup-alias task-name project)]\n    (if (vector? de-aliased)\n      (or (:pass-through-help (meta de-aliased))\n          (pass-through-help? (first de-aliased)\n                              (remove-alias project task-name)))\n      (:pass-through-help (meta (lookup-task-var de-aliased))))))\n\n(defn task-args [[task-name & args] project]\n  (let [pass-through? (pass-through-help? task-name project)]\n    (if (and (= \"help\" (aliases (first args))) (not pass-through?))\n      [\"help\" (cons task-name (rest args))]\n      [(lookup-alias task-name project) (vec args)])))\n\n(defn option-arg [str]\n  (and str (cond (.startsWith str \"--\") (keyword str)\n                 (.startsWith str \":\") (keyword (subs str 1)))))\n\n(defn parse-options\n  \"Given a sequence of strings, return a map of command-line-esque\n  options with keyword-ized keys and a list of additional args:\n\n  (parse-options [\\\"--chicken\\\"])\n  => [{:--chicken true} []]\n\n  (parse-options [\\\"--beef\\\" \\\"rare\\\"])\n  => [{:--beef \\\"rare\\\"} []]\n\n  (parse-options [\\\":fish\\\" \\\"salmon\\\"])\n  => [{:fish \\\"salmon\\\"} []]\n\n  (parse-options [\\\"salmon\\\" \\\"trout\\\"])\n  => [{} [\\\"salmon\\\" \\\"trout\\\"]]\n\n  (parse-options [\\\"--to-dir\\\" \\\"test2\\\" \\\"--ham\\\"])\n  => [{:--ham true, :--to-dir \\\"test2\\\"} []]\n\n  (parse-options [\\\"--to-dir\\\" \\\"test2\\\" \\\"--ham\\\" \\\"--\\\" \\\"pate\\\"])\n  => [{:--ham true, :--to-dir \\\"test2\\\"} [\\\"pate\\\"]]\"\n  [options]\n  (loop [m {}\n         [first-arg second-arg & rest :as args] options]\n    (if-let [option (and (not= \"--\" first-arg) (option-arg first-arg))]\n      (if (or (not second-arg) (option-arg second-arg))\n        (recur (assoc m option true) (if second-arg\n                                       (cons second-arg rest)\n                                       rest))\n        (recur (assoc m option second-arg) rest))\n      [m (if (= \"--\" first-arg)\n           (if second-arg (cons second-arg rest) [])\n           (or args []))])))\n\n;; TODO for 3.0.0: debug, info and exit should be in a separate namespace\n;; (io.clj?) to avoid cyclic deps.\n\n(def ^:dynamic *debug* (System/getenv \"DEBUG\"))\n\n(defn debug\n  \"Print if *debug* (from DEBUG environment variable) is truthy.\"\n  [& args]\n  (when *debug* (apply println args)))\n\n(def ^:dynamic *info* (not (System/getenv \"LEIN_SILENT\")))\n\n(defn info\n  \"Print if *info* (from LEIN_SILENT environment variable) is truthy.\"\n  [& args]\n  (when *info* (apply println args)))\n\n(defn warn\n  \"Print to stderr if *info* is truthy.\"\n  [& args]\n  (when *info*\n    (binding [*out* *err*]\n      (apply println args))))\n\n(def ^:dynamic *exit-process?*\n  \"Bind to false to suppress process termination.\" true)\n\n(defn exit\n  \"Exit the process. Rebind *exit-process?* in order to suppress actual process\n  exits for tools which may want to continue operating. Never call\n  System/exit directly in Leiningen's own process.\"\n  ([exit-code & msg]\n     (if *exit-process?*\n       (do (shutdown-agents)\n           (System/exit exit-code))\n       (throw (ex-info (if (seq msg)\n                         (apply print-str msg)\n                         \"Suppressed exit\")\n                       {:exit-code exit-code :suppress-msg (empty? msg)}))))\n  ([] (exit 0)))\n\n(defn abort\n  \"Print msg to standard err and exit with a value of 1.\n  Will not directly exit under some circumstances; see *exit-process?*.\"\n  [& msg]\n  (binding [*out* *err*]\n    (when (seq msg)\n      (apply println msg))\n    (apply exit 1 msg)))\n\n(defn- next-dist-row [s t x pprev prev]\n  (let [t-len (count t)\n        eq-chars (fn [x y] (= (nth s x) (nth t (dec y))))]\n    (reduce (fn [row y]\n              (let [min-step\n                    (cond->\n                     (min (inc (peek row)) ;; addition cost\n                          (inc (get prev y)) ;; deletion cost\n                          (cond-> (get prev (dec y)) ;; substitution cost\n                                  (not (eq-chars x y)) inc))\n                     (and (pos? x) (pos? (dec y)) ;; check for transposition\n                          (eq-chars x (dec y))\n                          (eq-chars (dec x) y)\n                          (not (eq-chars x y)))\n                     (min (inc (get pprev (- y 2)))))] ;; transposition cost\n                (conj row min-step)))\n            [(inc x)]\n            (range 1 (inc t-len)))))\n\n(defn- distance\n  \"Returns the Damerau–Levenshtein distance between two strings.\"\n  [s t]\n  (let [s-len (count s)\n        t-len (count t)\n        first-row (vec (range (inc t-len)))\n        matrix (reduce (fn [matrix x]\n                         (conj matrix\n                               (next-dist-row s t x\n                                              (peek (pop matrix))\n                                              (peek matrix))))\n                       [[] first-row]\n                       (range s-len))]\n    (peek (peek matrix))))\n\n;; workaround for #2345; need to update this list if a new task is added\n(def ^:private stock-tasks\n  '[leiningen.change leiningen.check leiningen.classpath leiningen.clean\n    leiningen.compile leiningen.deploy leiningen.deps leiningen.do\n    leiningen.help leiningen.install leiningen.jar leiningen.javac leiningen.new\n    leiningen.plugin leiningen.pom leiningen.release leiningen.repl\n    leiningen.retest leiningen.run leiningen.search leiningen.show-profiles\n    leiningen.test leiningen.trampoline leiningen.uberjar leiningen.update-in\n    leiningen.upgrade leiningen.vcs leiningen.version leiningen.with-profile])\n\n(defn tasks\n  \"Return a list of symbols naming all visible tasks.\"\n  []\n  (->> (b/namespaces-on-classpath :prefix \"leiningen\")\n       (into stock-tasks)\n       (filter #(re-find #\"^leiningen\\.(?!core|main|util)[^\\.]+$\" (name %)))\n       (distinct)\n       (sort)))\n\n(defn suggestions\n  \"Suggest possible misspellings for task from list of tasks.\"\n  [task tasks]\n  (let [suggestions (into {} (for [t tasks\n                                   :let [n (.replaceAll (name t)\n                                                        \"leiningen.\" \"\")]]\n                               [n (distance n task)]))\n        min (apply min (vals suggestions))]\n    (if (<= min 3)\n      (map first (filter #(= min (second %)) suggestions)))))\n\n(defn ^:no-project-needed task-not-found [task & _]\n  (binding [*out* *err*]\n    (println (str \"'\" task \"' is not a task. See 'lein help'.\"))\n    (when-let [suggestions (suggestions task (tasks))]\n      (println)\n      (println \"Did you mean this?\")\n      (doseq [suggestion suggestions]\n        (println \"        \" suggestion))))\n  (throw (ex-info \"Task not found\" {:exit-code 1 :suppress-msg true})))\n\n(defn ^:no-project-needed function-not-found [task & _]\n  (binding [*out* *err*]\n    (println (str \"leiningen.\" task\n                  \" is a Clojure namespace, but not a Leiningen task.\")))\n  (throw (ex-info \"Task not found\" {:exit-code 1 :suppress-msg true})))\n\n(defn- drop-partial-args\n  \"Returns a function that returns a new list of arglist, where the\n  args provided have been taken into consideration. All arglists\n  should start with the project argument.\n\n  A special case where the arglist is on the form [& ...] will be passed through\n  without being transformed.\"\n  [pargs]\n  (let [argcount (count pargs)]\n    (fn [arglists]\n      (for [[project-arg & arglist] arglists\n            :let [[fixed-args varargs] (split-with #(not= '& %) arglist)\n                  new-fixed-args (drop argcount fixed-args)]]\n        (if (= project-arg '&) ;; TODO: Clarify and remove this for 3.0.0\n          (cons project-arg arglist)\n          (cons project-arg (concat new-fixed-args varargs)))))))\n\n(defn- splice-into-args\n  \"Alias vectors may include :project/key entries.\nThese get replaced with the corresponding values from the project map.\"\n  [project args]\n  (into [] (for [arg args]\n             (if (and (keyword? arg) (= (namespace arg) \"project\"))\n               (project (keyword (name arg)))\n               arg))))\n\n(defn- partial-task [task-var pargs]\n  (with-meta\n    (fn [project & args]\n      (apply task-var project (splice-into-args project (concat pargs args))))\n    (update-in (meta task-var) [:arglists] (drop-partial-args pargs))))\n\n(defn resolve-task\n  \"Look up task function and perform partial application if applicable.\"\n  ([task not-found]\n     (let [[task & pargs] (if (coll? task) task [task])]\n       (if-let [task-var (lookup-task-var task)]\n         (partial-task task-var pargs)\n         (not-found task))))\n  ([task]\n     (resolve-task task (if (find-ns (symbol (str \"leiningen.\" task)))\n                          #'function-not-found\n                          #'task-not-found))))\n\n(defn ^:internal matching-arity? [task args]\n  (some (fn [parameters]\n          (and (if (= '& (last (butlast parameters)))\n                 (>= (count args) (- (count parameters) 3))\n                 (= (count parameters) (inc (count args))))\n               parameters))\n        (:arglists (meta task))))\n\n(defn- remove-alias\n  \"Removes an alias from the specified project and its metadata (which lies\n   within :without-profiles) to avoid recursive alias calls.\"\n  [project alias]\n  (-> project\n      (update-in [:aliases] #(if (map? %) (dissoc % alias) %))\n      (vary-meta update-in [:without-profiles :aliases] dissoc alias)\n      (vary-meta update-in [:profiles]\n                 #(zipmap\n                   (keys %)\n                   (map (fn [p] (if (map? p) (remove-alias p alias) p))\n                        (vals %))))))\n\n(defn apply-task\n  \"Resolve task-name to a function and apply project and args if arity matches.\"\n  [task-name project args]\n  (let [[task-alias] (for [[k v] (:aliases project) :when (= v task-name)] k)\n        project (and project (remove-alias project (or task-alias task-name)))\n        task (resolve-task task-name)]\n    (when-not (or (:root project) (:no-project-needed (meta task)))\n      (abort \"Couldn't find project.clj, which is needed for\" task-name))\n    (when-not (matching-arity? task args)\n      (abort \"Wrong number of arguments to\" task-name \"task.\"\n             \"\\nExpected\" (string/join \" or \" (map (comp vec next)\n                                                   (:arglists\n                                                    (meta task))))))\n    (debug \"Applying task\" task-name \"to\" args)\n    (apply task project args)))\n\n(defn resolve-and-apply\n  \"Entry point for tasks run other tasks as if they were called from the CLI.\"\n  [project args]\n  (let [[task-name args] (task-args args project)]\n    ;; See https://github.com/technomancy/leiningen/issues/2530\n    ;; We can't assume the project uses the same clojure version as lein does.\n    (binding [*print-namespace-maps* false]\n      (apply-task task-name project args))))\n\n(defn leiningen-version []\n  (or (System/getenv \"LEIN_VERSION\")\n      (with-open [reader (-> \"META-INF/maven/leiningen/leiningen/pom.properties\"\n                             io/resource\n                             io/reader)]\n        (-> (doto (java.util.Properties.)\n              (.load reader))\n            (.getProperty \"version\")))))\n\n(def ^:private exact-version-error\n  \"This project has :exact-lein-version set to \\\"%s\\\", while you have %s.\")\n\n(defn versions-match? [v1 v2]\n  (let [v1 (string/trim (first (string/split v1 #\"-\" 2)))\n        v2 (string/trim (first (string/split v2 #\"-\" 2)))]\n    (= v1 v2)))\n\n(defn- verify-exact-version\n  [{:keys [exact-lein-version]}]\n  (when-not (versions-match? exact-lein-version (leiningen-version))\n    (abort (format exact-version-error\n                   exact-lein-version\n                   (leiningen-version)))))\n\n(defn version-satisfies? [v1 v2]\n  (let [v1 (map #(Integer. %) (re-seq #\"\\d+\" (first (string/split v1 #\"-\" 2))))\n        v2 (map #(Integer. %) (re-seq #\"\\d+\" (first (string/split v2 #\"-\" 2))))]\n    (loop [versions (map vector v1 v2)\n           [seg1 seg2] (first versions)]\n      (cond (empty? versions) true\n            (= seg1 seg2) (recur (rest versions) (first (rest versions)))\n            (> seg1 seg2) true\n            (< seg1 seg2) false))))\n\n;; packagers should replace this string!\n(def ^:private min-version-warning\n  \";; *** Warning: This project requires Leiningen %s, but you have %s ***\n\n;; Get the latest version of Leiningen from your package manager or by executing\n;; \\\"lein upgrade\\\".\")\n\n(defn- verify-min-version\n  [{:keys [min-lein-version]}]\n  (when-not (version-satisfies? (leiningen-version) min-lein-version)\n    (warn (format min-version-warning min-lein-version (leiningen-version)))))\n\n(defn user-agent []\n  (format \"Leiningen/%s (Java %s; %s %s; %s)\"\n          (leiningen-version) (System/getProperty \"java.vm.name\")\n          (System/getProperty \"os.name\") (System/getProperty \"os.version\")\n          (System/getProperty \"os.arch\")))\n\n(defn- configure-http\n  \"Set Java system properties controlling HTTP request behavior.\"\n  []\n  (System/setProperty \"aether.connector.userAgent\" (user-agent))\n  (when-let [{:keys [host port non-proxy-hosts]} (classpath/get-proxy-settings)]\n    (System/setProperty \"http.proxyHost\" host)\n    (System/setProperty \"http.proxyPort\" (str port))\n    (when non-proxy-hosts\n      (System/setProperty \"http.nonProxyHosts\" non-proxy-hosts)))\n  (when-let [{:keys [host port]} (classpath/get-proxy-settings \"https_proxy\")]\n    (System/setProperty \"https.proxyHost\" host)\n    (System/setProperty \"https.proxyPort\" (str port))))\n\n(def ^:dynamic *cwd* (System/getProperty \"user.dir\"))\n\n(defn default-project\n  \"Return the default project used when not in a project directory.\"\n  []\n  (-> (project/make {:eval-in :leiningen :prep-tasks []\n                     :source-paths ^:replace []\n                     :resource-paths ^:replace []\n                     :test-paths ^:replace []})\n      (project/init-project)))\n\n(defn- init-dynamic []\n  (project/ensure-dynamic-classloader)\n  (user/init))\n\n(defn- init-static []\n  (require 'leiningen.static-classpath)\n  (let [no-load (fn [& _] (throw (Exception. \"static-classpath can't load\")))]\n    (alter-var-root #'*read-eval* (constantly false))\n    (alter-var-root #'eval (constantly no-load))\n    (alter-var-root #'load-file (constantly no-load))))\n\n(defn -main\n  \"Command-line entry point.\"\n  [& raw-args]\n  (try\n    ;; it would be tidier if this could be kept as metadata on the task var\n    ;; itself, but it's needed before we resolve the task, so we must hard-code\n    (if (= \"static-classpath\" (first raw-args))\n      (init-static)\n      (init-dynamic))\n    (binding [project/*memoize-middleware* true]\n      (let [project (cond (= \"static-classpath\" (first raw-args))\n                          {:root *cwd*}\n                          (.exists (io/file *cwd* \"project.clj\"))\n                          (project/read (str (io/file *cwd* \"project.clj\")))\n                          :else (default-project))]\n        (when (:exact-lein-version project) (verify-exact-version project))\n        (when (:min-lein-version project) (verify-min-version project))\n        (configure-http)\n        (resolve-and-apply project raw-args)))\n    (catch Exception e\n      (if (or *debug* (not (:exit-code (ex-data e))))\n        (stacktrace/print-cause-trace e)\n        (when-not (:suppress-msg (ex-data e))\n          (println (.getMessage e))))\n      (flush)\n      (exit (:exit-code (ex-data e) 1))))\n  (exit 0))\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/pedantic.clj",
    "content": "(ns leiningen.core.pedantic\n  \"This namespace exists to hook into Aether's dependency\n  resolution and provide feedback about the dependency tree. Using a\n  `DependencyGraphTransformer` allows us to look at the tree both before\n  and after conflict resolution so that downloading all of the\n  dependencies only occurs once.\n\n  Aether uses a `NearestVersionConflictResolver` to resolve which\n  versions to use in case of a conflict. The\n  `NearestVersionConflictResolver` uses a `ConflictIdSorter` to\n  determine those, and it will save the information in\n  `SORTED_CONFLICT_IDS` and `CONFLICT_IDS`. We can similarly use the\n  conflict information to determine which version is choosen in a\n  conflict.\n\n  Additional important classes from Aether:\n\n  * `DependencyGraphTransformationContext`\n  * `DependencyNode`\n  * `Dependency`\n  * `Artifact`\n  * `Version`\n  * `VersionConstraint`\"\n  (:require [cemerick.pomegranate.aether :as aether]\n            [clojure.set :as set])\n  (:import (java.util Map)\n           (org.eclipse.aether DefaultRepositorySystemSession)\n           (org.eclipse.aether.artifact Artifact)\n           (org.eclipse.aether.collection DependencyGraphTransformationContext\n                                          DependencyGraphTransformer)\n           (org.eclipse.aether.graph Dependency\n                                     DependencyNode\n                                     Exclusion)\n           (org.eclipse.aether.util.graph.transformer ConflictIdSorter\n                                                      TransformationContextKeys)))\n\n(defn- warn [& args]\n  ;; TODO: remove me once #1227 is merged\n  (require 'leiningen.core.main)\n  (apply (resolve 'leiningen.core.main/warn) args))\n\n(def ^:private warn-once (memoize warn))\n\n;; This namespace originated as an independent library which was at\n;; https://github.com/xeqi/pedantic in order to allow it to evolve\n;; at its own pace decoupled from Leiningen's release cycle, but now it's\n;; part of Leiningen as of 2.8.0.\n\n(defn- initialize-conflict-ids!\n  \"Make sure that `SORTED_CONFLICT_IDS` and `CONFLICT_IDS` have been\n  initialized. Similar to what a NearestVersionConflictResolver will do.\"\n  [node ^DependencyGraphTransformationContext context]\n  (when-not (.get context TransformationContextKeys/SORTED_CONFLICT_IDS)\n    (-> (ConflictIdSorter.)\n        (.transformGraph node context))))\n\n(defn- range?\n  \"Does the path point to a DependencyNode asking for a version range\n   which contains several versions?\"\n  [{:keys [^DependencyNode node]}]\n  (when-let [vc (.getVersionConstraint node)]\n    (let [range (.getRange vc)\n          lb    (some-> range .getLowerBound)\n          ub    (some-> range .getUpperBound)]\n      (and (some? range)\n           (some? lb)\n           (not (.equals lb ub))))))\n\n(defn- group-artifact [^Artifact artifact]\n  (if (= (.getGroupId artifact)\n         (.getArtifactId artifact))\n    (.getGroupId artifact)\n    (str (.getGroupId artifact)\n         \"/\"\n         (.getArtifactId artifact))))\n\n(defn- paths->ranges\n  \"Get a list of range nodes from the full list of paths.\"\n  [paths]\n  (let [by-artifact (group-by #(group-artifact (.getArtifact (:node %)))\n                              (filter range? paths))]\n    (for [[_ elements] by-artifact]\n      (last (sort-by #(.getVersion (:node %)) elements)))))\n\n(defn- node<\n  \"Is the version of node1 < version of node2.\"\n  [^DependencyNode node1 ^DependencyNode node2]\n  (< (compare (.getVersion node1) (.getVersion node2)) 0))\n\n(defn- node=\n  \"Check value equality instead of reference equality.\"\n  [^DependencyNode n1 ^DependencyNode n2]\n  (= (.getArtifact n1) (.getArtifact n2)))\n\n(defn- top-level?\n  \"Is the path a top level dependency in the project?\"\n  [{:keys [parents]}]\n  ;; Parent is root node\n  (= 1 (count parents)))\n\n(defn- different-paths?\n  \"Work around a bug in DependencyNode where equality is broken.\"\n  [{node1 :node parents1 :parents} {node2 :node parents2 :parents}]\n  (not (and (node= node1 node2)\n            (every? true? (map node= parents1 parents2)))))\n\n(defn- set-overrides!\n  \"Check each `accepted-path` against its conflicting paths. If a\n  conflicting path fails the pedantic criteria then add information\n  representing this possibly confusing situation to `overrides`.\"\n  [overrides conflicts accepted-paths ranges]\n  (doseq [{:keys [node parents] :as path} accepted-paths]\n    (let [ignoreds (for [conflict-path (conflicts node)\n                         :when (and (different-paths? path conflict-path)\n                                    ;; This is the pedantic criteria\n                                    (or (node< node (:node conflict-path))\n                                        (top-level? conflict-path)))]\n                     conflict-path)]\n      (when (not (empty? ignoreds))\n        (swap! overrides conj {:accepted path\n                               :ignoreds ignoreds\n                               :ranges\n                               (filter #(node= (:node %) node) ranges)})))))\n\n(defn- paths->deps\n  [paths]\n  (->> paths\n       (map (fn [{:keys [^DependencyNode node]}] (.getDependency node)))\n       (into #{})))\n\n(defn- all-paths\n  \"Breadth first traversal of the graph from DependencyNode node.\n  Short circuits a path when a cycle is detected.\"\n  [node]\n  (loop [paths [{:node node :parents []}]\n         results []\n         visited-deps #{}]\n    (if (empty? paths)\n      results\n      (recur (for [{:keys [^DependencyNode node parents]} paths\n                   :when (not (contains? visited-deps (.getDependency node)))\n                   c (.getChildren node)]\n               {:node c :parents (conj parents node)})\n             (into results paths)\n             (set/union visited-deps (paths->deps paths))))))\n\n(defn- transform-graph\n  \"Examine the tree with root `node` for version ranges, then\n  allow the original `transformer` to perform resolution, then check for\n  overriden dependencies.\"\n  [ranges overrides root-node\n   ^DependencyGraphTransformationContext context\n   ^DependencyGraphTransformer transformer]\n  ;; Force initialization of the context like NearestVersionConflictResolver\n  (initialize-conflict-ids! root-node context)\n  ;; Get all the paths of the graph before dependency resolution\n  (let [potential-paths (all-paths root-node)]\n    (reset! ranges (paths->ranges potential-paths))\n    (.transformGraph transformer root-node context)\n    ;; The original transformer should have done dependency resolution,\n    ;; so now we can gather just the accepted paths and use the ConflictId\n    ;; to match against the potential paths\n    (let [^Map node->id (.get context TransformationContextKeys/CONFLICT_IDS)\n          id->paths (reduce (fn [acc {:keys [node] :as path}]\n                              (update acc (.get node->id node) conj path))\n                            {}\n                            ;; Remove ranges as they cause problems and were\n                            ;; warned above\n                            (remove range? potential-paths))]\n      (set-overrides! overrides\n                      #(->> % (.get node->id) id->paths)\n                      (all-paths root-node)\n                      @ranges))))\n\n(defn- use-transformer\n  \"Wrap the session's current `DependencyGraphTransformer` with one that checks\n  for version ranges and overriden dependencies.\n\n  `ranges` and `overrides` are expect to be (atom []).  This provides a way to\n  send back information since the return value can't be used here.\n\n  After resolution:\n  `ranges` will be a vector of paths (see pedantic.path)\n  `overrides` will be a vector of maps with keys [:accepted :ignoreds :ranges].\n    `:accepted` is the path that was resolved. :ignored is a list of\n    paths that were not used.\n    `:ranges` is a list of paths containing version ranges that might\n    have affected the resolution.\"\n  [^DefaultRepositorySystemSession session ranges overrides]\n  (let [transformer (.getDependencyGraphTransformer session)]\n    (.setDependencyGraphTransformer\n     session\n     (reify DependencyGraphTransformer\n       (transformGraph [_ root-node context]\n         (try\n           (transform-graph ranges overrides root-node context transformer)\n           (catch java.lang.OutOfMemoryError _\n             (warn \"Pathological dependency tree detected.\")\n             (warn \"Consider setting :pedantic? false in project.clj to bypass.\")))\n         ;; Return the root in order to meet transformGraph's contract\n         root-node)))))\n\n(defn ^:internal session [project ranges overrides]\n  (if (:pedantic? project)\n    #(-> % aether/repository-session\n         (use-transformer ranges overrides))))\n\n(defn- exclusion-group-artifact [^Exclusion exclusion]\n  (if (= (.getGroupId exclusion)\n         (.getArtifactId exclusion))\n    (.getGroupId exclusion)\n    (str (.getGroupId exclusion)\n         \"/\"\n         (.getArtifactId exclusion))))\n\n(defn- dependency-str [^Dependency dependency & [version]]\n  (if-let [^Artifact artifact (and dependency (.getArtifact dependency))]\n    (str \"[\"\n         (group-artifact artifact)\n         \" \\\"\" (or version (.getVersion artifact)) \"\\\"\"\n         (if-let [classifier (.getClassifier artifact)]\n           (if (not (empty? classifier))\n             (str \" :classifier \\\"\" classifier \"\\\"\")))\n         (if-let [extension (.getExtension artifact)]\n           (if (not= extension \"jar\")\n             (str \" :extension \\\"\" extension \"\\\"\")))\n         (if-let [exclusions (seq (.getExclusions dependency))]\n           (str \" :exclusions \" (mapv (comp symbol exclusion-group-artifact)\n                                      exclusions)))\n         \"]\")))\n\n(defn- message-for [path & [show-constraint?]]\n  (->> path\n       (map (fn [^DependencyNode node]\n              (dependency-str (.getDependency node) (.getVersionConstraint node))))\n       (remove nil?)\n       (interpose \" -> \")\n       (apply str)))\n\n(defn- message-for-version [{:keys [node parents]}]\n  (message-for (conj parents node)))\n\n(defn- managed-for-range [^DependencyNode node parents]\n  (dependency-str (.getDependency node)\n                  (-> node .getDependency .getArtifact .getVersion)))\n\n(defn- message-for-range [{:keys [node parents]}]\n  (str (message-for (conj parents node) :constraints) \"\\n\"\n       \"Consider adding to :managed-dependencies: \"\n       (managed-for-range node parents)))\n\n(defn- managed-for-override [{:keys [node parents]}]\n  (managed-for-range node parents))\n\n(defn- message-for-override [{:keys [accepted ignoreds ranges]}]\n  {:accepted (message-for-version accepted)\n   :ignoreds (map message-for-version ignoreds)\n   :ranges (map message-for-range ranges)\n   :managed (map managed-for-override ignoreds)})\n\n(defn- pedantic-print-ranges [messages]\n  (when-not (empty? messages)\n    (warn \"WARNING!!! version ranges found for:\")\n    (doseq [dep-string messages]\n      (warn dep-string))\n    (warn)))\n\n(defn- pedantic-print-overrides [messages]\n  (when-not (empty? messages)\n    (warn \"Possibly confusing dependencies found:\")\n    (doseq [{:keys [accepted ignoreds ranges managed]} messages]\n      (warn accepted)\n      (warn \" overrides\")\n      (doseq [ignored (interpose \" and\" ignoreds)]\n        (warn ignored))\n      (when-not (empty? ranges)\n        (warn \" possibly due to a version range in\")\n        (doseq [r ranges]\n          (warn r)))\n      (warn \"\\nConsider using these :managed-dependencies: \")\n      (doseq [ex (distinct managed)]\n        (warn ex))\n      (warn))))\n\n(alter-var-root #'pedantic-print-ranges memoize)\n(alter-var-root #'pedantic-print-overrides memoize)\n\n(defn warn-or-abort [pedantic-setting ranges overrides]\n  ;; Need to turn everything into a string before calling\n  ;; pedantic-print-*, otherwise we can't memoize due to bad equality\n  ;; semantics on aether GraphEdge objects.\n  (let [key (keyword pedantic-setting)\n        abort-or-true (#{true :abort} key)]\n    (when (and key (not= key :overrides))\n      (pedantic-print-ranges (map message-for-range ranges)))\n    (when (and key (not= key :ranges))\n      (pedantic-print-overrides (map message-for-override overrides)))\n    (when (and abort-or-true\n               (not (empty? (concat ranges overrides))))\n      (require 'leiningen.core.main)\n      ((resolve 'leiningen.core.main/abort) ; cyclic dependency =\\\n       \"Aborting due to :pedantic? :abort\"))))\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/project.clj",
    "content": "(ns leiningen.core.project\n  \"Read project.clj files.\"\n  (:refer-clojure :exclude [read])\n  (:require [clojure.walk :as walk]\n            [clojure.java.io :as io]\n            [clojure.set :as set]\n            [cemerick.pomegranate :as pomegranate]\n            [cemerick.pomegranate.aether :as aether]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.user :as user]\n            [leiningen.core.classpath :as classpath]\n            [clojure.string :as str])\n  (:import (clojure.lang DynamicClassLoader)\n           (java.io PushbackReader Reader File)\n           (java.util.regex Pattern)))\n\n(defn make-project-properties [project]\n  (with-open [baos (java.io.ByteArrayOutputStream.)]\n    (let [properties (doto (java.util.Properties.)\n                       (.setProperty \"version\" (:version project))\n                       (.setProperty \"groupId\" (:group project))\n                       (.setProperty \"artifactId\" (:name project)))\n          git-head (utils/resolve-git-dir project)]\n      (when (.exists git-head)\n        (if-let [revision (utils/read-git-head git-head)]\n          (.setProperty properties \"revision\" revision)))\n      (.store properties baos nil))\n    (-> baos\n        str\n        ;; Strip off all the comments printed by java.util.Properties: by default the timestamp is printed\n        utils/strip-properties-comments)))\n\n(defn- warn [& args]\n  ;; TODO: remove with 3.0.0\n  (require 'leiningen.core.main)\n  (apply (resolve 'leiningen.core.main/warn) args))\n\n(def ^:internal warn-once (memoize warn))\n\n(defn- update-each-contained [m keys f & args]\n  (reduce (fn [m k]\n            (if (contains? m k)\n              (apply update m k f args)\n              m)) m keys))\n\n(defn- update-first [coll pred f]\n  (let [[pre [existing & post]] (split-with (complement pred) coll)]\n    (concat pre [(f existing)] post)))\n\n;; # Project definition and normalization\n\n(defn composite-profile?\n  \"Returns true if the profile is composite, false otherwise.\"\n  [profile]\n  (vector? profile))\n\n(defn group-id\n  [id]\n  (if (string? id)\n    (first (str/split id #\"/\"))\n    (or (namespace id) (name id))))\n\n(defn artifact-id\n  [id]\n  (if (string? id)\n    (last (str/split id #\"/\"))\n    (name id)))\n\n(defn artifact-map\n  [id]\n  {:artifact-id (artifact-id id)\n   :group-id (group-id id)})\n\n(defn exclusion-map\n  \"Transform an exclusion vector into a map that is easier to combine with\n  meta-merge. This allows a profile to override specific exclusion options.\"\n  [spec]\n  (if-let [[id & {:as opts}] (if (symbol? spec) [spec] spec)]\n    (-> opts\n        (merge (artifact-map id))\n        (with-meta (meta spec)))))\n\n(defn exclusion-vec\n  \"Transform an exclusion map back into a vector of the form:\n  [name/group & opts]\"\n  [exclusion]\n  (if-let [{:keys [artifact-id group-id]} exclusion]\n    (into [(symbol group-id artifact-id)]\n          (apply concat (dissoc exclusion :artifact-id :group-id)))))\n\n(defn dependency-map\n  \"Transform a dependency vector into a map that is easier to combine with\n  meta-merge. This allows a profile to override specific dependency options.\"\n  [dep]\n  (if-let [[id version & {:as opts}] (classpath/normalize-dep-vector dep)]\n    (-> opts\n        (merge (artifact-map id))\n        (assoc :version version)\n        (update-each-contained [:exclusions] (partial map exclusion-map))\n        (with-meta (meta dep)))))\n\n(defn dependency-vec\n  \"Transform a dependency map back into a vector of the form:\n  [name/group \\\"version\\\" & opts]\"\n  [dep]\n  (if-let [{:keys [artifact-id group-id version]} dep]\n    (-> dep\n        (update-each-contained [:exclusions] (partial map exclusion-vec))\n        (update-each-contained [:exclusions] distinct)\n        (dissoc :artifact-id :group-id :version)\n        (->> (apply concat)\n             (into [(symbol group-id artifact-id) version]))\n        (with-meta (meta dep)))))\n\n(defn- meta*\n  \"Returns the metadata of an object, or nil if the object cannot hold\n  metadata.\"\n  [obj]\n  (if (instance? clojure.lang.IObj obj)\n    (meta obj)\n    nil))\n\n(defn- with-meta*\n  \"Returns an object of the same type and value as obj, with map m as its\n  metadata if the object can hold metadata.\"\n  [obj m]\n  (if (instance? clojure.lang.IObj obj)\n    (with-meta obj m)\n    obj))\n\n(defn- vary-meta*\n  \"Returns an object of the same type and value as obj, with\n  (apply f (meta obj) args) as its metadata, if the object can hold\n  metadata.\"\n  [obj f & args]\n  (if (instance? clojure.lang.IObj obj)\n    (apply vary-meta obj f args)\n    obj))\n\n(defn- displace?\n  \"Returns true if the object is marked as displaceable\"\n  [obj]\n  (-> obj meta* :displace))\n\n(defn- replace?\n  \"Returns true if the object is marked as replaceable\"\n  [obj]\n  (-> obj meta* :replace))\n\n(defn- top-displace?\n  \"Returns true if the object is marked as top-displaceable\"\n  [obj]\n  (-> obj meta* :top-displace))\n\n(defn- different-priority?\n  \"Returns true if either left has a higher priority than right or vice versa.\"\n  [left right]\n  (boolean\n   (or (some (some-fn nil? displace? replace?) [left right])\n       (top-displace? left))))\n\n(defn- remove-top-displace [obj]\n  (if-not (top-displace? obj)\n    obj\n    (vary-meta obj dissoc :top-displace)))\n\n(defn- pick-prioritized\n  \"Picks the highest prioritized element of left and right and merge their\n  metadata.\"\n  [left right]\n  (cond (nil? left) right\n        (nil? right) (remove-top-displace left)\n\n        ;; TODO: support :reverse?\n        (top-displace? left) right\n        (and (displace? left) (top-displace? right)) left\n\n        (and (displace? left)   ;; Pick the rightmost\n             (displace? right)) ;; if both are marked as displaceable\n        (with-meta* right\n          (merge (meta* left) (meta* right)))\n\n        (and (replace? left)    ;; Pick the rightmost\n             (replace? right))  ;; if both are marked as replaceable\n        (with-meta* right\n          (merge (meta* left) (meta* right)))\n\n        (or (displace? left)\n            (replace? right))\n        (with-meta* right\n          (merge (-> left meta* (dissoc :displace))\n                 (-> right meta* (dissoc :replace))))\n\n        (or (replace? left)\n            (displace? right))\n        (with-meta* left\n          (merge (-> right meta* (dissoc :displace))\n                 (-> left meta* (dissoc :replace))))))\n\n(declare meta-merge)\n\n;; TODO: drop this and use read-eval syntax in 3.0\n(defn- unquote-project\n  \"Inside defproject forms, unquoting (~) allows for arbitrary evaluation.\"\n  [args]\n  (walk/walk (fn [item]\n               (cond (and (seq? item) (= `unquote (first item))) (second item)\n                     ;; needed if we want fn literals preserved\n                     (or (seq? item) (symbol? item)) (list 'quote item)\n                     :else (let [result (unquote-project item)]\n                             ;; clojure.walk strips metadata\n                             (if-let [m (meta item)]\n                               (with-meta result m)\n                               result))))\n             identity\n             args))\n\n(def defaults\n  ;; TODO: move :repositories here in 3.0\n  {:source-paths ^:top-displace ^:default-path/src [\"src\"]\n   :resource-paths ^:top-displace ^:default-path/resources [\"resources\"]\n   :test-paths ^:top-displace ^:default-path/test [\"test\"]\n   :native-path \"%s/native\"\n   :compile-path \"%s/classes\"\n   :target-path \"target\"\n   :clean-targets ^:top-displace [:target-path]\n   ;; TODO: remove :top-displace for :prep-tasks in 3.0\n   :prep-tasks ^:top-displace [\"javac\" \"compile\"]\n   ;; If these change, be sure to update release docstring and DEPLOY.md\n   :release-tasks ^:top-displace [[\"vcs\" \"assert-committed\"]\n                                  [\"change\" \"version\"\n                                   \"leiningen.release/bump-version\" \"release\"]\n                                  [\"vcs\" \"commit\"]\n                                  [\"vcs\" \"tag\"]\n                                  [\"deploy\"]\n                                  [\"change\" \"version\"\n                                   \"leiningen.release/bump-version\"]\n                                  [\"vcs\" \"commit\"]\n                                  [\"vcs\" \"push\"]]\n   :pedantic? (quote ^:top-displace ranges)\n   :jar-exclusions [#\"^\\.\" (re-pattern (Pattern/quote (str File/separator \".\")))]\n   :eval-in :default\n   :offline? (not (nil? (System/getenv \"LEIN_OFFLINE\")))\n   :uberjar-exclusions [#\"(?i)^META-INF/[^/]*\\.(SF|RSA|DSA)$\"\n                        #\"^module-info.class$\"]\n   :uberjar-merge-with {\"META-INF/plexus/components.xml\"\n                        'leiningen.uberjar/components-merger,\n                        \"data_readers.clj\"\n                        'leiningen.uberjar/clj-map-merger,\n                        ;; So we don't break Java's ServiceLoader mechanism\n                        ;; during uberjar construction\n                        #\"META-INF/services/.*\" `[slurp #(str %1 \"\\n\" %2) spit]}\n   :global-vars {}})\n\n(defn dep-key\n  \"The unique key used to dedupe dependencies.\"\n  [dep]\n  (-> (dependency-map dep)\n      (select-keys [:group-id :artifact-id :classifier :extension])))\n\n(defn- reduce-dep-step [deps dep]\n  (let [k (dep-key dep)]\n    (update-first deps #(= k (dep-key %))\n                  (fn [existing]\n                    (dependency-vec\n                     (meta-merge (dependency-map existing)\n                                 (dependency-map dep)))))))\n\n(defn normalize-aot [project]\n  (if (= :all (:aot project))\n    (assoc project :aot ^:replace [:all])\n    project))\n\n(defn- normalize-repo\n  \"Normalizes a repository to the canonical repository form.\"\n  [[id opts :as repo]]\n  (with-meta\n    [id (if (string? opts) {:url opts} opts)]\n    (meta repo)))\n\n(defn- normalize-repos\n  \"Normalizes a vector of repositories to the canonical repository form.\"\n  [repos]\n  (with-meta\n    (mapv normalize-repo repos)\n    (meta repos)))\n\n(defn- reduce-repo-step [repos [id opts :as repo]]\n  (update-first repos #(= id (first %))\n                (fn [[_ existing :as original]]\n                  (let [opts (if (keyword? opts)\n                               (-> (filter #(= (first %) (name opts)) repos)\n                                   first second)\n                               opts)\n                        repo (with-meta [id opts] (meta repo))]\n                    (if (different-priority? repo original)\n                      (pick-prioritized repo original)\n                      (with-meta [id (meta-merge existing opts)]\n                        (merge (meta original) (meta repo))))))))\n\n(def empty-dependencies\n  (with-meta [] {:reduce reduce-dep-step}))\n\n(def empty-repositories\n  (with-meta [] {:reduce reduce-repo-step}))\n\n(def empty-paths\n  (with-meta [] {:prepend true}))\n\n(def default-repositories\n  (with-meta\n    [[\"central\" {:url \"https://repo1.maven.org/maven2/\" :snapshots false}]\n     [\"clojars\" {:url \"https://repo.clojars.org/\"}]]\n    {:reduce reduce-repo-step}))\n\n(def deploy-repositories\n  (with-meta\n    [[\"clojars\" {:url \"https://repo.clojars.org/\"\n                 :password :gpg :username :gpg}]]\n    {:reduce reduce-repo-step}))\n\n(defn- mark-with-replace [obj]\n  (vary-meta* obj assoc :replace true))\n\n(defn normalize-values\n  \"Transform values within a project or profile map to normalized values, such\n  that internal functions can assume that the values are already normalized.\"\n  [map]\n  (-> map\n      (update-each-contained [:repositories :deploy-repositories\n                              :mirrors :plugin-repositories] normalize-repos)\n      (update-each-contained [:profiles] utils/map-vals normalize-values)\n      (update-each-contained [:aliases] utils/map-vals mark-with-replace)\n      (normalize-aot)))\n\n(def ^:private empty-meta-merge-defaults\n  {:repositories empty-repositories\n   :plugin-repositories empty-repositories\n   :deploy-repositories deploy-repositories\n   :plugins empty-dependencies\n   :dependencies empty-dependencies\n   :source-paths empty-paths\n   :resource-paths empty-paths\n   :test-paths empty-paths})\n\n(defn- setup-map-defaults\n  \"Transform a project or profile map by merging empty default values containing\n  reducing functions and other metadata properties, replacing aliases and\n  normalizing values inside the map.\"\n  [raw-map empty-defaults]\n  (with-meta\n    (merge-with\n     (fn [left right]\n       ;; Assumes that left always contains :reduce OR :prepend in its meta\n       (with-meta\n         (cond (different-priority? left right) (pick-prioritized left right)\n               (-> left meta :reduce) (-> left meta :reduce\n                                          (reduce left right))\n               (-> left meta :prepend) (concat right left))\n         (merge (meta left)\n                (dissoc (meta right) :top-displace))))\n     empty-defaults\n     (-> raw-map\n         (cond-> (and (:java-opts raw-map) (not (:jvm-opts raw-map)))\n                 (assoc :jvm-opts (:java-opts raw-map))\n                 (and (:eval-in-leiningen raw-map) (not (:eval-in raw-map)))\n                 (assoc :eval-in :leiningen))\n         (dissoc :eval-in-leiningen :java-opts)\n         (normalize-values)))\n    (meta raw-map)))\n\n(defn- with-normalized-deps\n  [profile]\n  (if-let [deps (:dependencies profile)]\n    (assoc profile\n      :dependencies\n      (with-meta\n       (classpath/normalize-dep-vectors deps)\n       (meta deps)))\n    profile))\n\n(defn- setup-profile-with-empty\n  \"Setup a profile map with empty defaults.\"\n  [raw-profile]\n  (if (composite-profile? raw-profile)\n    ;; TODO: drop support for partially-composite profiles in 3.0\n    (with-meta\n      (mapv #(cond-> % (map? %) setup-profile-with-empty) raw-profile)\n      (meta raw-profile))\n    (let [empty-defaults (select-keys empty-meta-merge-defaults\n                                      (keys raw-profile))]\n      (setup-map-defaults\n       (with-normalized-deps raw-profile)\n       empty-defaults))))\n\n(defn- setup-map-of-profiles\n  \"Setup a map of profile maps with empty defaults.\"\n  [map-of-profiles]\n  (utils/map-vals map-of-profiles setup-profile-with-empty))\n\n(defn make\n  ([project project-name version root]\n     (make (with-meta (assoc project\n                        :name (name project-name)\n                        :group (or (namespace project-name)\n                                   (name project-name))\n                        :version version\n                        :root root)\n             (meta project))))\n  ([project]\n     (let [repos (if (:omit-default-repositories project)\n                   (do (warn-once \"WARNING:\"\n                                  \":omit-default-repositories is deprecated;\"\n                                  \"use :repositories ^:replace [...] instead.\")\n                       empty-repositories)\n                   default-repositories)]\n       (setup-map-defaults\n        (-> (meta-merge defaults project)\n            (dissoc :eval-in-leiningen :omit-default-repositories)\n            (assoc :eval-in (or (:eval-in project)\n                                (if (:eval-in-leiningen project)\n                                  :leiningen, :subprocess)))\n            (update-each-contained [:profiles] setup-map-of-profiles)\n            (with-meta (meta project)))\n        (assoc empty-meta-merge-defaults\n          :repositories repos\n          :plugin-repositories repos)))))\n\n(defn- argument-list->argument-map\n  [args]\n  (let [keys (map first (partition 2 args))\n        unique-keys (set keys)]\n    (if (= (count keys) (count unique-keys))\n      (apply hash-map args)\n      (let [duplicates (->> (frequencies keys)\n                            (remove #(> 2 (val %)))\n                            (map first))]\n        (throw\n         (IllegalArgumentException.\n          (format \"Duplicate keys: %s\"\n                  (clojure.string/join \", \" duplicates))))))))\n\n(defmacro defproject\n  \"The project.clj file must either def a project map or call this macro.\n  See `lein help sample` to see what arguments it accepts.\"\n  [project-name version & args]\n  (let [f (io/file *file*)]\n    `(let [args# ~(unquote-project (argument-list->argument-map args))\n           root# ~(if f (.getParent f))]\n       (def ~'project\n         (make args# '~project-name ~version root#)))))\n\n(defn- add-exclusions [exclusions dep]\n  (dependency-vec\n   (update-in (dependency-map dep) [:exclusions]\n              into (map exclusion-map exclusions))))\n\n(defn- add-global-exclusions [project]\n  (let [{:keys [dependencies exclusions]} project]\n    (if-let [exclusions (and (seq dependencies) (seq exclusions))]\n      (assoc project\n        :dependencies (with-meta\n                        (mapv (partial add-exclusions exclusions)\n                              dependencies)\n                        (meta dependencies)))\n      project)))\n\n(defn- remove-self-excluded-deps\n  \"Remove any dependency that contains it's dependency id inside it's own\n  :exclusions vec.\"\n  [{:keys [dependencies] :as project}]\n  (if dependencies\n    (update project :dependencies\n            (fn [deps]\n              (when deps\n                (let [self-excluded? (fn [dep]\n                                       (let [{:keys [artifact-id group-id exclusions]} (dependency-map dep)]\n                                         (some (fn [{excl-art-id :artifact-id, excl-grp-id :group-id}]\n                                                 (and\n                                                  (= group-id excl-grp-id)\n                                                  (= artifact-id excl-art-id)))\n                                               exclusions)))]\n                  (with-meta\n                    (remove self-excluded? deps)\n                    (meta deps))))))\n    project))\n\n(defn- absolutize [root path]\n  (str (if (.isAbsolute (io/file path))\n         path\n         (io/file root path))))\n\n(defn- absolutize-path [{:keys [root] :as project} key]\n  (cond (re-find #\"-path$\" (name key))\n        (update project key (partial absolutize root))\n\n        (re-find #\"-paths$\" (name key))\n        (update project key #(with-meta* (map (partial absolutize root) %)\n                               (meta %)))\n\n        :else project))\n\n(defn absolutize-paths [project]\n  (reduce absolutize-path project (keys project)))\n\n(defn- sha1 [content]\n  (.toString (BigInteger. 1 (-> (java.security.MessageDigest/getInstance \"SHA1\")\n                                (.digest (.getBytes content)))) 16))\n\n(defn- keyword-composite-profile? [profile]\n  (and (composite-profile? profile) (every? keyword? profile)))\n\n(defn- ordered-keyword-composite-profiles [project]\n  (->> project meta :profiles\n       (filter (comp keyword-composite-profile? val))\n       (remove (comp empty? val))\n       (sort-by count)\n       (reverse)))\n\n(defn- first-matching-composite [profiles composites]\n  (->> composites\n       (filter (fn [[_ v]] (= v (take (count v) profiles))))\n       (first)))\n\n(defn- normalize-profile-names [project profiles]\n  (let [composites (ordered-keyword-composite-profiles project)]\n    (loop [profiles'  profiles\n           normalized ()]\n      (if (seq profiles')\n        (if-let [[k v] (first-matching-composite profiles' composites)]\n          (recur (drop (count v) profiles') (cons k normalized))\n          (recur (rest profiles') (cons (first profiles') normalized)))\n        (if (= (count profiles) (count normalized))\n          profiles\n          (normalize-profile-names project (reverse normalized)))))))\n\n(defn profile-scope-target-path [project profiles]\n  (let [n #(if (map? %) (subs (sha1 (pr-str %)) 0 8) (name %))]\n    (if (:target-path project)\n      (update-in project [:target-path] format\n                 (str/join \"+\" (->> (normalize-profile-names project profiles)\n                                    (map n)\n                                    (remove #{\"default\"}))))\n      project)))\n\n(defn target-path-subdirs [{:keys [target-path] :as project} key]\n  (if (project key)\n    (update-in project [key] format target-path)\n    project))\n\n;; # Profiles: basic merge logic\n\n(def ^:private hooke-injection\n  (with-open [rdr (-> \"robert/hooke.clj\" io/resource io/reader PushbackReader.)]\n    `(do (ns ~'leiningen.core.injected)\n         ~@(doall (take-while #(not= % ::eof)\n                              (rest (repeatedly #(clojure.core/read\n                                                  rdr false ::eof)))))\n         (ns ~'user))))\n\n;; users of old JVMs will have to set LEIN_JVM_OPTS to turn off tiered\n;; compilation, so if they've done that we should do the same for project JVMs\n(def tiered-jvm-opts\n  (if (.contains (or (System/getenv \"LEIN_JVM_OPTS\") \"\") \"Tiered\")\n    [\"-XX:+TieredCompilation\" \"-XX:TieredStopAtLevel=1\"]))\n\n(def default-jvm-opts\n  [;; actually does the opposite; omits trace unless this is set\n   \"-XX:-OmitStackTraceInFastThrow\"])\n\n(def default-profiles\n  \"Profiles get merged into the project map. The :dev, :provided, and :user\n  profiles are active by default.\"\n  (atom {:default [:leiningen/default]\n         :leiningen/default [:base :system :user :provided :dev]\n         :base {:resource-paths ^:default-path/dev-resources [\"dev-resources\"]\n                :jvm-opts (with-meta `[~@default-jvm-opts\n                                       ~@tiered-jvm-opts]\n                            {:displace true})\n                :test-selectors {:default (with-meta '(constantly true)\n                                            {:displace true})}\n                ;; bump deps in leiningen's own project.clj with these\n                :dependencies '[^:displace [nrepl/nrepl \"1.0.0\"\n                                            :exclusions [org.clojure/clojure]]\n                                ^:displace [org.nrepl/incomplete \"0.1.0\"\n                                            :exclusions [org.clojure/clojure]]]\n                :checkout-deps-shares [:source-paths\n                                       :test-paths\n                                       :resource-paths\n                                       :compile-path\n                                       #'classpath/checkout-deps-paths]\n                :aliases {\"downgrade\" \"upgrade\"}}\n         :leiningen/test {:injections [hooke-injection]\n                          :test-selectors {:default (with-meta\n                                                      '(constantly true)\n                                                      {:displace true})}}\n         :uberjar {} ; TODO: use :aot :all here in 3.0\n         :update {:update :always}\n         :offline {:offline? true}\n         :debug {:debug true}}))\n\n(def default-profile-metadata\n  {:dev {:pom-scope :test}\n   :test {:pom-scope :test}\n   :uberjar {:leaky true}\n   :provided {:pom-scope :provided}\n   :repl {:repl true}})\n\n(defn meta-merge\n  \"Recursively merge values based on the information in their metadata.\"\n  [left right]\n  (cond (different-priority? left right)\n        (pick-prioritized left right)\n\n        (-> left meta :reduce)\n        (-> left meta :reduce\n            (reduce left right)\n            (with-meta (meta left)))\n\n        (and (map? left) (map? right))\n        (merge-with meta-merge left right)\n\n        (and (set? left) (set? right))\n        (set/union right left)\n\n        (and (coll? left) (coll? right))\n        (if (or (-> left meta :prepend)\n                (-> right meta :prepend))\n          (-> (concat right left)\n              (with-meta (merge (meta right) (meta left))))\n          (-> (concat left right)\n              (with-meta (merge (meta left) (meta right)))))\n\n        (= (class left) (class right)) right\n\n        :else\n        (do (warn-once left \"and\" right \"have a type mismatch merging profiles.\")\n            right)))\n\n(defn ^:internal apply-profiles [project profiles]\n  (reduce (fn [project profile]\n            (with-meta\n              (meta-merge project profile)\n              (meta-merge (meta project) (meta profile))))\n          project\n          profiles))\n\n(defn- warn-composite [profile]\n  (when (and (composite-profile? profile)\n             (not (keyword-composite-profile? profile)))\n    ;; TODO: include suggestion for how to move map to top-level profile\n    (warn-once\n     \"Composite profiles containing maps are strongly recommended against.\"\n     \"\\nSupport will be removed in future versions of Leiningen due to subtle\"\n     \"\\nunexpected behavior. Move the map from the composite profile to its own\"\n     \"\\ntop-level named profile to avoid issues.\\n\" (pr-str profile))))\n\n(defn- lookup-profile*\n  \"Lookup a profile in the given profiles map, warning when the profile doesn't\n  exist. Recurse whenever a keyword or vector is found, combining all profiles\n  in the vector.\"\n  [profiles profile]\n  (cond (keyword? profile)\n        (let [result (get profiles profile)]\n          (when-not (or result (#{:provided :dev :user :test :base :default\n                                  :production :system :repl}\n                                profile))\n            (warn-once \"Warning: profile\" profile \"not found.\"))\n          (when (and (= :provided profile) (composite-profile? result))\n            (throw (Exception.\n                    \"Composite profiles are incompatible with :provided.\")))\n          (lookup-profile* profiles result))\n\n        (composite-profile? profile)\n        (apply-profiles {} (map (partial lookup-profile* profiles)\n                                (doto profile warn-composite)))\n\n        :else (or profile {})))\n\n(defn- lookup-profile\n  \"Equivalent with lookup-profile*, except that it will attach the profile name\n  as an active profile in the profile metadata if the profile is a keyword.\"\n  [profiles profile]\n  (cond-> (lookup-profile* profiles profile)\n          (keyword? profile)\n          (vary-meta update-in [:active-profiles] (fnil conj []) profile)))\n\n(defn- expand-profile* [profiles profile-meta profile]\n  (let [content (or (get profiles profile) (get @default-profiles profile))]\n    ;; TODO: drop \"support\" for partially-composite profiles in 3.0\n    (if (or (nil? content)\n            (map? content)\n            (and (sequential? content)\n                 (some map? content)))\n      [[profile profile-meta]]\n      (mapcat (partial expand-profile*\n                       profiles (merge profile-meta (meta content)))\n              (if (sequential? content)\n                content\n                [content])))))\n\n(defn expand-profile-with-meta\n  \"Recursively expand the keyword `profile` in `project` to a sequence of\n  vectors of atomic (non-composite) profile keywords and their inherited\n  metadata.\"\n  [project profile]\n  (expand-profile* (:profiles (meta project)) nil profile))\n\n(defn expand-profiles-with-meta\n  \"Recursively expand a collection of profiles\"\n  [project profiles]\n  (mapcat (partial expand-profile-with-meta project) profiles))\n\n(defn expand-profile\n  \"Recursively expand the keyword `profile` in `project` to a sequence of\n  atomic (non-composite) profile keywords.\"\n  [project profile]\n  (->> (expand-profile* (:profiles (meta project)) nil profile)\n       (map first)))\n\n(defn expand-profiles\n  \"Recursively expand a collection of profiles\"\n  [project profiles]\n  (mapcat (partial expand-profile project) profiles))\n\n(defn- warn-user-repos [profiles]\n  (let [has-url? (fn [entry] (or (string? entry) (:url entry)))\n        repo-profiles (filter #(->> (second %)\n                                    :repositories\n                                    (map second)\n                                    (some has-url?))\n                              profiles)]\n    (when (and (seq repo-profiles)\n               (not (System/getenv \"LEIN_SUPPRESS_USER_LEVEL_REPO_WARNINGS\")))\n      (warn-once \":repositories detected in user-level profiles!\"\n                 (vec (map first repo-profiles)) \"\\nSee\"\n                 \"https://wiki.leiningen.org/Repeatability\"))))\n\n(defn- warn-user-profile [root profiles]\n  (when (and root (contains? profiles :user))\n    (warn-once \"WARNING: user-level profile defined in project files.\")))\n\n(defn- system-profiles []\n  (let [sys-profile-dir (if (= :windows (utils/get-os))\n                          (io/file (System/getenv \"AllUsersProfile\") \"Leiningen\")\n                          (io/file \"/etc\" \"leiningen\"))]\n    (user/load-profiles sys-profile-dir)))\n\n(defn ^:internal project-profiles [project]\n  (let [profiles (utils/read-file (io/file (:root project) \"profiles.clj\"))]\n    (warn-user-profile (:root project) profiles)\n    profiles))\n\n(defn read-profiles\n  \"Read profiles from a variety of sources.\n\n  We check Leiningen's defaults, system-level profiles (usually in\n  /etc), the profiles.clj file in ~/.lein, the profiles.clj file in\n  the project root, and the :profiles key from the project map.\"\n  [project]\n  ;; TODO: All profile reads (load-profiles and profiles, notable) should wrap\n  ;;   setup-profiles instead of doing stuff here, but as it is a cyclic\n  ;;   dependency, defer it to 3.0. Although I guess we don't need this\n  ;;   functionality for 3.0 if we're smart.\n  (let [sys-profiles (setup-map-of-profiles (system-profiles))\n        user-profiles (setup-map-of-profiles (user/profiles))\n        proj-profiles-file (setup-map-of-profiles (project-profiles project))]\n    (warn-user-repos (concat user-profiles sys-profiles))\n    (warn-user-profile (:root project) (:profiles project))\n    (merge @default-profiles sys-profiles user-profiles\n           (:profiles project) proj-profiles-file)))\n\n(defn- scope-plugin-profile [local-name plugin-name]\n  (keyword (str \"plugin.\" plugin-name) (name local-name)))\n\n(defn- read-plugin-profiles [project]\n  (let [p (for [[plugin version] (:plugins project)\n                :let [profiles (io/resource (format \"%s/profiles.clj\"\n                                                    (name plugin)))]\n                :when profiles]\n            (for [[local-name profile] (read-string (slurp profiles))]\n              [(scope-plugin-profile local-name (name plugin)) profile]))]\n    (into {} (apply concat p))))\n\n;; # Lower-level profile plumbing: loading plugins, hooks, middleware, certs\n\n(defn ensure-dynamic-classloader []\n  (let [thread (Thread/currentThread)\n        cl (.getContextClassLoader thread)]\n    (when-not (instance? DynamicClassLoader cl)\n      (.setContextClassLoader thread (DynamicClassLoader. cl)))))\n\n(def ^:private registered-wagon-files (atom #{}))\n\n(defn load-plugins\n  ([project dependencies-key managed-dependencies-key]\n     (when (seq (get project dependencies-key))\n       (let [repos-project (update-in project [:repositories] meta-merge\n                                      (:plugin-repositories project))]\n         (classpath/resolve-managed-dependencies\n          dependencies-key managed-dependencies-key repos-project\n          :add-classpath? true)))\n     (doseq [wagon-file (-> (.getContextClassLoader (Thread/currentThread))\n                            (.getResources \"leiningen/wagons.clj\")\n                            (enumeration-seq))\n             :when (not (@registered-wagon-files wagon-file))\n             [hint factory] (read-string (slurp wagon-file))]\n       (aether/register-wagon-factory! hint (eval factory))\n       (swap! registered-wagon-files conj wagon-file))\n     project)\n  ([project dependencies-key] (load-plugins project dependencies-key nil))\n  ([project] (load-plugins project :plugins)))\n\n(defn plugin-vars [project type]\n  (for [[plugin _ & {:as opts}] (:plugins project)\n        :when (get opts type true)]\n    (-> (symbol (str (name plugin) \".plugin\") (name type))\n        (with-meta {:optional true}))))\n\n(defn- plugin-hooks [project]\n  (plugin-vars project :hooks))\n\n(defn- plugin-middleware [project]\n  (plugin-vars project :middleware))\n\n(defn- load-hook [hook-name]\n  (if-let [hook (try (utils/require-resolve hook-name)\n                     (catch Exception e\n                       (utils/error \"problem requiring\" hook-name \"hook\")\n                       (throw e)))]\n    (try (hook)\n         (catch Exception e\n           (utils/error \"problem activating\" hook-name \"hook\")\n           (throw e)))\n    (when-not (:optional (meta hook-name))\n      (utils/error \"cannot resolve\" hook-name \"hook\"))))\n\n(defn load-hooks [project & [ignore-missing?]]\n  (doseq [hook-name (concat (when (and (:implicits project true) (:implicit-hooks project true))\n                              (plugin-hooks project))\n                            (:hooks project))]\n    ;; if hook-name is just a namespace assume hook fn is called activate\n    (let [hook-name (if (namespace hook-name)\n                      hook-name\n                      (symbol (name hook-name) \"activate\"))]\n      (load-hook hook-name)))\n  project)\n\n(def ^:dynamic *memoize-middleware*\n  \"Memoize middleware.\n  This is enabled when running lein from the command line, but is otherwise\n  disabled by default. Middleware memoization can be disabled by setting\n  `:memoize-middleware? false` in the project map or user profile.\"\n  false)\n\n(defn- memoize-middleware?\n  \"Returns true if middleware should be memoized for the given project.\"\n  [project]\n  (and *memoize-middleware*\n    (:memoize-middleware? (:without-profiles (meta project) project)\n      (:memoize-middleware? (:user (user/profiles))\n        true))))\n\n(defn- memoize-when\n  \"Returns a conditionally memoized version of a function.\n  Calls to the function will be memoized only when `test` returns logical\n  true. `test` will be called with the same arguments as the function.\"\n  [f test]\n  (let [f* (memoize f)]\n    (fn [& args]\n      (if (apply test args)\n        (apply f* args)\n        (apply f args)))))\n\n(def ^:private apply-middleware-memoized\n  (memoize-when\n    (fn [project middleware] (middleware project))\n    (fn [project _] (memoize-middleware? project))))\n\n(defn apply-middleware\n  ([project]\n   (reduce apply-middleware project\n           (concat (when (and (:implicits project true) (:implicit-middleware project true))\n                     (plugin-middleware project))\n                   (:middleware project))))\n  ([project middleware-name]\n   (if-let [middleware (utils/require-resolve middleware-name)]\n     (apply-middleware-memoized project middleware)\n     (do (when-not (:optional (meta middleware-name))\n           (utils/error \"cannot resolve\" middleware-name \"middleware\"))\n         project))))\n\n(defn load-certificates\n  \"Load the SSL certificates specified by the project and register\n   them for use by Aether.\"\n  [project]\n  (when (seq (:certificates project))\n    ;; lazy-loading might give a launch speed boost here\n    (require 'leiningen.core.ssl)\n    (let [make-context (resolve 'leiningen.core.ssl/make-sslcontext)\n          read-certs (resolve 'leiningen.core.ssl/read-certs)\n          default-certs (resolve 'leiningen.core.ssl/default-trusted-certs)\n          override-wagon-registry! (resolve 'leiningen.core.ssl/override-wagon-registry!)\n          https-registry (resolve 'leiningen.core.ssl/https-registry)\n          certs (mapcat read-certs (:certificates project))\n          context (make-context (into (default-certs) certs))]\n      (override-wagon-registry! (https-registry context))\n      project)))\n\n(defn activate-middleware\n  \"A helper function to apply middleware and then load certificates and hooks,\n  since we always do these three things together, at least so far.\"\n  [project]\n  (doto (apply-middleware project)\n    (load-certificates)\n    (load-hooks)))\n\n(defn project-with-profiles-meta [project profiles]\n  ;;; should this dissoc :default?\n  ;; (vary-meta project assoc :profiles (dissoc profiles :default))\n  (vary-meta project assoc\n             :profiles profiles))\n\n(defn- set-dependencies-pom-scope [profile]\n  (if-let [scope (:pom-scope (meta profile))]\n    (with-meta\n      (update-in profile [:dependencies]\n                 (fn [deps]\n                   (map\n                    (fn [dep]\n                      (if (some #(= :scope %) dep)\n                        dep\n                        (-> dep (conj :scope) (conj (name scope)))))\n                    deps)))\n      (meta profile))\n    profile))\n\n(defn- apply-profile-meta [default-meta profile]\n  (vary-meta profile (fn [m] (merge default-meta m))))\n\n(defn project-with-profiles\n  ([project profiles]\n   (project-with-profiles-meta\n    project\n    (->> (map (fn [[k p]]\n                [k (apply-profile-meta (default-profile-metadata k) p)])\n              profiles)\n         (into {}))))\n  ([project]\n   (project-with-profiles project (merge (read-plugin-profiles project)\n                                         (read-profiles project)))))\n\n(defn ^:internal init-profiles\n  \"Compute a fresh version of the project map, including and excluding the\n  specified profiles.\"\n  [project include-profiles & [exclude-profiles]]\n  (let [project (-> (:without-profiles (meta project) project)\n                    (with-meta (meta project))\n                    (vary-meta dissoc :active-profiles))\n        include-profiles-meta (->> (expand-profiles-with-meta\n                                    project include-profiles)\n                                   (utils/last-distinct-by first))\n        ;; We want to remove the exclude-profiles earlier, but if we expand\n        ;; earlier on we lose the pom-scope metadata from the profile.\n        effective-include-profiles (remove (set exclude-profiles)\n                                           (map first include-profiles-meta))\n        exclude-profiles (utils/last-distinct (expand-profiles project exclude-profiles))\n        profile-map (apply dissoc (:profiles (meta project)) exclude-profiles)\n        profiles (for [profile-name effective-include-profiles]\n                   (let [profile (lookup-profile profile-map profile-name)\n                         metas (into {} include-profiles-meta)\n                         profile-meta (metas profile-name)]\n                     (-> (vary-meta profile merge profile-meta)\n                         set-dependencies-pom-scope\n                         normalize-values)))]\n    (-> project\n        (apply-profiles profiles)\n        (profile-scope-target-path effective-include-profiles)\n        (target-path-subdirs :compile-path)\n        (target-path-subdirs :native-path)\n        (absolutize-paths)\n        (add-global-exclusions)\n        (remove-self-excluded-deps)\n        (vary-meta merge {:without-profiles project\n                          :included-profiles include-profiles\n                          :excluded-profiles exclude-profiles\n                          :profile-inherited-meta include-profiles-meta}))))\n\n(def whitelist-keys\n  \"Project keys which don't affect the production of the jar (sans its name)\n  should be propagated to the compilation phase and not stripped out.\"\n  [:certificates :jar-name :local-repo :mirrors :offline? :repositories :uberjar-name :warn-on-reflection])\n\n(defn retain-whitelisted-keys\n  \"Retains the whitelisted keys from the original map in the new one.\"\n  [new original]\n  (merge new (select-keys original whitelist-keys)))\n\n;; # High-level profile operations\n\n(defn set-profiles\n  \"Compute a fresh version of the project map, with middleware applied,\n  including and excluding the specified profiles.\"\n  [project include-profiles & [exclude-profiles]]\n  (-> project\n      (init-profiles include-profiles exclude-profiles)\n      (load-plugins)\n      (activate-middleware)))\n\n(defn merge-profiles\n  \"Compute a fresh version of the project map with the given profiles merged\n  into list of active profiles and the appropriate middleware applied.\"\n  [project profiles]\n  (let [{:keys [included-profiles excluded-profiles]} (meta project)\n        profiles (expand-profiles project profiles)]\n    (set-profiles project\n                  (concat included-profiles profiles)\n                  (remove (set profiles) excluded-profiles))))\n\n(defn unmerge-profiles\n  \"Compute a fresh version of the project map with the given profiles unmerged\n  from list of active profiles and the appropriate middleware applied.\"\n  [project profiles]\n  (let [{:keys [included-profiles excluded-profiles]} (meta project)\n        profiles (expand-profiles project profiles)]\n    (set-profiles project\n                  ;; we need un-expanded profiles here because if :dev was\n                  ;; a composite profile that included :foo, we need to start\n                  ;; from :dev in order to ensure :foo's dependencies have\n                  ;; test scope in the pom.\n                  (remove (set profiles) included-profiles)\n                  (concat excluded-profiles profiles))))\n\n(defn init-lein-classpath\n  \"Adds dependencies to Leiningen's classpath if required.\"\n  [project]\n  (when (= :leiningen (:eval-in project))\n    (doseq [path (classpath/get-classpath project)]\n      (pomegranate/add-classpath path))))\n\n(def ^:private repo-connection-keys\n  [:repositories :plugin-repositories :mirrors :certificates :local-repo])\n\n;; Since this feature was introduced, the initial profile loading sequence has\n;; been overhauled; repository overrides are no longer strictly necessary.\n(defn- load-repository-overrides\n  \"Loads any network-centric overrides specified in repository-overrides.clj.\n  This feature allows certain features to be defined outside of the project\n  file, they are loaded at the very beginning before the profiles are loaded.\"\n  [project]\n  (let [overrides (-> (io/file (:root project) \"repository-overrides.clj\")\n                      (utils/read-file)\n                      (select-keys repo-connection-keys))]\n    (merge project overrides)))\n\n(defn- focus-repo-connection [profile]\n  (cond\n    (map? profile) (select-keys profile (conj repo-connection-keys :plugins))\n    (composite-profile? profile) (mapv focus-repo-connection profile)\n    :else profile))\n\n(defn init-project\n  \"Initializes a project by loading certificates, plugins, middleware, etc.\nAlso merges default profiles.\"\n  ([project default-profiles]\n   ;; Initialization proceeds in two stages:\n   ;; 1. Initial setup of certificates, Leiningen classpath, plugins using a\n   ;;    project map supplemented with only connection-related settings\n   ;;    (repository overrides plus a selection of keys from default profiles).\n   ;; 2. Regular profile initialization followed by a second round of plugin\n   ;;    loading and middleware activation.\n   (let [initial-project (load-repository-overrides project)\n         profiles (read-profiles project)\n         ;; Initial project setup with stripped down default profiles merged.\n         repo-project (-> initial-project\n                          (project-with-profiles-meta\n                            (utils/map-vals profiles focus-repo-connection))\n                          (init-profiles default-profiles))\n         _ (doto repo-project\n             (load-certificates)\n             (init-lein-classpath)\n             (load-plugins))\n         plugin-profiles (read-plugin-profiles repo-project)]\n     ;; Regular project initialization using initial project map.\n     (-> initial-project\n         (project-with-profiles (merge plugin-profiles profiles))\n         (set-profiles default-profiles))))\n  ([project] (init-project project [:default])))\n\n(defn add-profiles\n  \"Add the profiles in the given profiles map to the project map, taking care\n  to preserve project map metadata. Note that these profiles are not merged,\n  merely made available to merge by name.\"\n  [project profiles-map]\n  (-> (update-in project [:profiles] merge profiles-map)\n      (vary-meta merge\n                 {:without-profiles\n                  (update-in (:without-profiles (meta project) project)\n                             [:profiles]\n                             merge profiles-map)})\n      (vary-meta update-in [:profiles] merge profiles-map)))\n\n(defn profile-annotations\n  \"Return a map of profile keyword to profile annotations for the profiles\n  in :include-profiles.\"\n  [project]\n  (->> (map\n        (juxt first (fn [[profile m]]\n                      (merge m (meta ((-> project meta :profiles) profile)))))\n        (-> project meta :profile-inherited-meta))\n       (into {})))\n\n(defn profiles-with-matching-meta\n  \"Return a sequence of profile keywords for the project profiles that\n  have metadata that satisfies the predicate, pred.\"\n  [project pred]\n  (->> (-> project meta :profiles)\n       (filter (comp pred meta val))\n       (map key)))\n\n(defn non-leaky-profiles\n  \"Return a sequence of profile keywords for the non-leaky profiles\n  currently included in the project.\"\n  [project]\n  (->> (profile-annotations project)\n       (remove (comp :leaky val))\n       (map key)))\n\n(defn pom-scope-profiles\n  \"Return a sequence of profile keywords for the currently active\n  project profiles with :pom-scope equal to scope.\"\n  [project scope]\n  (->> (profile-annotations project)\n       (filter (comp #(= scope (:pom-scope %)) val))\n       keys))\n\n(defn read-raw\n  \"Read project file without loading certificates, plugins, middleware, etc.\"\n  [source]\n  (locking read-raw\n    (binding [*ns* (find-ns 'leiningen.core.project)]\n      (try\n        (if (instance? Reader source)\n          (load-reader source)\n          (load-file source))\n        (catch Exception e\n          (throw (Exception. (format \"Error loading %s\" source) e)))))\n    (let [project (resolve 'leiningen.core.project/project)]\n      (when-not project\n        (throw (Exception. (format \"%s must define project map\" source))))\n      ;; return it to original state\n      (ns-unmap 'leiningen.core.project 'project)\n      @project)))\n\n(defn read\n  \"Read project map out of file, which defaults to project.clj.\nAlso initializes the project; see read-raw for a version that skips init.\"\n  ([file profiles] (init-project (read-raw file) profiles))\n  ([file] (read file [:default]))\n  ([] (read \"project.clj\")))\n\n;; Basically just for re-throwing a more comprehensible error.\n(defn- read-dependency-project [project-file]\n  (if (.exists project-file)\n    (let [project (.getAbsolutePath project-file)]\n      (try (read project)\n           (catch Exception e\n             (throw (Exception. (format \"Problem loading %s\" project) e)))))\n    (warn-once \"WARNING: ignoring checkouts directory\" (.getParent project-file)\n               \"as it does not contain a project.clj file.\")))\n\n(alter-var-root #'read-dependency-project memoize)\n\n(defn read-checkouts\n  \"Returns a list of project maps for this project's checkout\n  dependencies.\"\n  [project]\n  (for [dep (.listFiles (io/file (:root project) \"checkouts\"))\n        :let [project-file (.getCanonicalFile (io/file dep \"project.clj\"))\n              checkout-project (read-dependency-project project-file)]\n        :when checkout-project]\n    checkout-project))\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/ssl.clj",
    "content": "(ns leiningen.core.ssl\n  (:require [cemerick.pomegranate.aether :as aether]\n            [clojure.java.io :as io]\n            [leiningen.core.user :as user])\n  (:import java.security.KeyStore\n           java.security.KeyStore$TrustedCertificateEntry\n           java.security.Security\n           java.security.cert.CertificateFactory\n           javax.net.ssl.KeyManagerFactory\n           javax.net.ssl.SSLContext\n           javax.net.ssl.TrustManagerFactory\n           javax.net.ssl.X509TrustManager\n           java.io.FileInputStream\n           org.apache.http.config.RegistryBuilder\n           org.apache.http.conn.socket.PlainConnectionSocketFactory\n           org.apache.http.conn.ssl.DefaultHostnameVerifier\n           org.apache.http.conn.ssl.SSLConnectionSocketFactory\n           org.apache.http.impl.conn.PoolingHttpClientConnectionManager\n           org.apache.maven.wagon.providers.http.HttpWagon))\n\n(defn ^TrustManagerFactory trust-manager-factory [^KeyStore keystore]\n  (doto (TrustManagerFactory/getInstance \"PKIX\")\n    (.init keystore)))\n\n(defn default-trust-managers []\n  (let [tmf (trust-manager-factory nil)\n        tms (.getTrustManagers tmf)]\n    (filter #(instance? X509TrustManager %) tms)))\n\n(defn key-manager-props []\n  (let [read #(java.lang.System/getProperty %)]\n    (merge {:file (read \"javax.net.ssl.keyStore\")\n            :type (read \"javax.net.ssl.keyStoreType\")\n            :provider (read \"javax.net.ssl.keyStoreProvider\")\n            :password (read \"javax.net.ssl.keyStorePassword\")}\n           (-> (user/profiles) :user :key-manager-properties))))\n\n(defn key-manager-factory [{:keys [file type provider password]}]\n  (let [type (or type (KeyStore/getDefaultType))\n        fis (if-not (empty? file) (FileInputStream. file))\n        pwd (and password (.toCharArray password))\n        store (if provider\n                (KeyStore/getInstance type provider)\n                (KeyStore/getInstance type))]\n    (.load store fis pwd)\n    (when fis (.close fis))\n    (doto (KeyManagerFactory/getInstance\n           (KeyManagerFactory/getDefaultAlgorithm))\n      (.init store pwd))))\n\n(defn default-trusted-certs\n  \"Lists the CA certificates trusted by the JVM.\"\n  []\n  (mapcat #(.getAcceptedIssuers %) (default-trust-managers)))\n\n(defn read-certs\n  \"Read one or more X.509 certificates in DER or PEM format.\"\n  [f]\n  (let [cf (CertificateFactory/getInstance \"X.509\")\n        in (io/input-stream (or (io/resource f) (io/file f)))]\n    (.generateCertificates cf in)))\n\n(defn make-keystore\n  \"Construct a KeyStore that trusts a collection of certificates.\"\n  [certs]\n  (let [ks (KeyStore/getInstance \"jks\")]\n    (.load ks nil nil)\n    (doseq [[i cert] (map vector (range) certs)]\n      (.setEntry ks (str i) (KeyStore$TrustedCertificateEntry. cert) nil))\n    ks))\n\n;; TODO: honor settings from project.clj, not just user profile\n(defn make-sslcontext\n  \"Construct an SSLContext that trusts a collection of certificates.\"\n  [trusted-certs]\n  (let [ks (make-keystore trusted-certs)\n        kmf (key-manager-factory (key-manager-props))\n        tmf (trust-manager-factory ks)]\n    (doto (SSLContext/getInstance \"TLS\")\n      (.init (.getKeyManagers kmf) (.getTrustManagers tmf) nil))))\n\n(alter-var-root #'make-sslcontext memoize)\n\n(defn https-registry\n  \"Constructs a registry map that uses a given SSLContext for https.\"\n  [context]\n  (let [factory (SSLConnectionSocketFactory. context (DefaultHostnameVerifier.))]\n    {\"https\" factory\n     \"http\" PlainConnectionSocketFactory/INSTANCE}))\n\n(defn ^:deprecated https-scheme\n  \"Constructs a registry map that uses a given SSLContext for https.\n\n  DEPRECATED: Use https-registry instead.\"\n  ([context port]\n   (if (not= port 443) ;; TODO: Should we support this?\n     (throw (ex-info \"Specifying port for https-scheme is not possible anymore.\"\n                     {:context context :port port}))\n     (https-scheme context)))\n  ([context]\n   (binding [*out* *err*]\n     (println \"https-scheme is deprecated, use https-registry instead\"))\n   (https-registry context)))\n\n(defn- map->registry\n  \"Creates a Registry based of the given map.\"\n  [m]\n  (let [rb (RegistryBuilder/create)]\n    (doseq [[scheme conn-sock-factory] m]\n      (.register rb scheme conn-sock-factory))\n    (.build rb)))\n\n(defn override-wagon-registry!\n  \"Override the registry scheme used by the HTTP Wagon's Connection\n  manager (used for Aether).\"\n  [registry]\n  (let [cm (PoolingHttpClientConnectionManager. (map->registry registry))]\n    (HttpWagon/setPoolingHttpClientConnectionManager cm)))\n\n(defn ^:deprecated register-scheme\n  \"Override the registry scheme used by the HTTP Wagon's Connection\n  manager (used for Aether).\n\n  DEPRECATED: Use override-wagon-registry! instead.\"\n  [scheme]\n  (binding [*out* *err*]\n    (println \"register-scheme is deprecated, use override-wagon-registry! instead\"))\n  (override-wagon-registry! scheme))\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/user.clj",
    "content": "(ns leiningen.core.user\n  \"Functions exposing user-level configuration.\"\n  (:require [clojure.java.io :as io]\n            [clojure.string :as str]\n            [clojure.java.shell :as shell]\n            [leiningen.core.utils :as utils])\n  (:import (com.hypirion.io Pipe)\n           (org.apache.commons.io.output TeeOutputStream)\n           (java.util.regex Pattern)\n           (java.io ByteArrayOutputStream)))\n\n(defn getprop\n  \"Wrap System/getProperty for testing purposes.\"\n  [prop-name]\n  (System/getProperty prop-name))\n\n(defn getenv\n  \"Wrap System/getenv for testing purposes.\"\n  [name]\n  (System/getenv name))\n\n(defn- existing-file [f] (and f (.exists f) f))\n\n(def ^:private warn-once (memoize (fn [& args]\n                                    (binding [*out* *err*]\n                                      (apply println args)))))\n\n(defn leiningen-home\n  \"Return full path to the user's Leiningen home directory.\"\n  []\n  (let [home (System/getProperty \"user.home\")\n        explicit-home (getenv \"LEIN_HOME\")\n        home-home (io/file home \".lein\")\n        xdg-home (io/file (or (getenv \"XDG_CONFIG_HOME\")\n                              (str home \"/.config\")) \"leiningen\")]\n    (when (and (existing-file home-home) (existing-file xdg-home))\n      (warn-once \"Warning: found multiple config directories:\\n  \"\n                 (.getPath home-home) \"and\" (.getPath xdg-home))\n      (warn-once \"Using\" (.getPath home-home) \"for config.\"))\n    (.getAbsolutePath (or (and explicit-home (io/file explicit-home))\n                          (existing-file home-home)\n                          (existing-file xdg-home)\n                          home-home))))\n\n;; TODO: move all these memoized fns into delays\n(def init\n  \"Load the user's ~/.lein/init.clj file, if present.\"\n  (memoize (fn []\n             (let [init-file (io/file (leiningen-home) \"init.clj\")]\n               (when (.exists init-file)\n                 (try (load-file (.getAbsolutePath init-file))\n                      (catch Exception e\n                        (.printStackTrace e))))))))\n\n(defn- load-profiles-d-file\n  \"Returns a map entry containing the filename (without `.clj`) associated\n  with its contents. The content will be tagged with its origin.\"\n  [file]\n  (try\n    (let [kw (->> file .getName (re-find #\".+(?=\\.clj)\") keyword)\n          contents (vary-meta (utils/read-file file) ;; assumes the file exist\n                              merge {:origin (.getAbsolutePath file)})]\n      [kw contents])\n    (catch Exception e\n      (binding [*out* *err*]\n        (println \"Error reading\" (.getName file)\n                 \"from\" (-> file .getParentFile .getAbsolutePath (str \":\")))\n        (println (.getMessage e))))))\n\n(def profiles-d-profiles\n  \"Load all Clojure files from the profiles.d folder in your Leiningen home if\n  present. Returns a seq with map entries of the different profiles.\"\n  (memoize\n   (fn []\n     (let [profile-dir (io/file (leiningen-home) \"profiles.d\")]\n       (if (.isDirectory profile-dir)\n         (for [file (.listFiles profile-dir)\n               :when (-> file .getName (.endsWith \".clj\"))]\n           (load-profiles-d-file file)))))))\n\n(def ^:internal load-profiles\n  \"Load profiles.clj from dir if present. Tags all profiles with its origin.\"\n  (memoize\n   (fn [dir]\n       (if-let [contents (utils/read-file (io/file dir \"profiles.clj\"))]\n         (utils/map-vals contents vary-meta merge\n                         {:origin (str (io/file dir \"profiles.clj\"))})))))\n\n\n(def profiles\n  \"Load profiles.clj from your Leiningen home and profiles.d if present.\"\n  (memoize\n   (fn []\n     (let [error-fn\n           (fn [a b]\n             (binding [*out* *err*]\n               (println \"Error: A profile is defined in both\"\n                        (-> a meta :origin) \"and in\" (-> b meta :origin)))\n             (throw (ex-info \"Multiple profiles defined in ~/.lein\"\n                             {:exit-code 1})))]\n       (if (not (System/getenv \"LEIN_NO_USER_PROFILES\"))\n         (merge-with error-fn\n                     (load-profiles (leiningen-home))\n                     (into {} (profiles-d-profiles))))))))\n\n(defn gpg-program\n  \"Lookup the gpg program to use, defaulting to 'gpg'\"\n  []\n  (or (getenv \"LEIN_GPG\") \"gpg\"))\n\n(def ^:dynamic *gpg-home* (System/getenv \"GNUPGHOME\"))\n\n(defn- get-english-env\n  \"Returns env vars as a map with clojure keywords and LANGUAGE set to 'en'\"\n  []\n  (let [env (System/getenv)]\n    (assoc (zipmap (map keyword (keys env)) (vals env))\n           :LANGUAGE \"en\"\n           :GNUPGHOME *gpg-home*)))\n\n(defn- as-env-strings\n  [env]\n  (into-array String (map (fn [[k v]] (str (name k) \"=\" v))\n                          (remove #(nil? (val %)) env))))\n\n(defn gpg\n  \"Shells out to (gpg-program) with the given arguments\"\n  [& args]\n  (try\n    (let [proc-env (as-env-strings (get-english-env))\n          proc-args (into-array String (concat [(gpg-program)] args))\n          proc (.exec (Runtime/getRuntime) proc-args proc-env)]\n      (.addShutdownHook (Runtime/getRuntime)\n                        (Thread. (fn [] (.destroy proc))))\n      (with-open [out (.getInputStream proc)\n                  err-output (ByteArrayOutputStream.)]\n        (let [pump-err (doto (Pipe. (.getErrorStream proc)\n                                    (TeeOutputStream. System/err err-output))\n                         .start)]\n          (.join pump-err)\n          (let [exit-code (.waitFor proc)]\n            {:exit exit-code\n             :out (slurp (io/reader out))\n             :err (slurp (io/reader (.toByteArray err-output)))}))))\n    (catch java.io.IOException e\n      {:exit 1 :out \"\" :err (.getMessage e)})))\n\n(defn gpg-available?\n  \"Verifies (gpg-program) exists\"\n  []\n  (zero? (:exit (gpg \"--version\"))))\n\n(defn credentials-fn\n  \"Decrypt map from credentials.clj.gpg in Leiningen home if present.\"\n  ([] (let [cred-file (io/file (leiningen-home) \"credentials.clj.gpg\")]\n        (if (.exists cred-file)\n          (credentials-fn cred-file))))\n  ([file]\n     (let [{:keys [out err exit]} (gpg \"--quiet\" \"--batch\"\n                                       \"--decrypt\" \"--\" (str file))]\n       (if (pos? exit)\n         (binding [*out* *err*]\n           (println \"Could not decrypt credentials from\" (str file))\n           (println err)\n           (println \"See `lein help gpg` for how to install gpg.\"))\n         (binding [*read-eval* false]\n           (read-string out))))))\n\n(def credentials (memoize credentials-fn))\n\n(defn- match-credentials [settings auth-map]\n  (get auth-map (:url settings)\n       (first (for [[re? cred] auth-map\n                    :when (and (instance? Pattern re?)\n                               (re-find re? (:url settings)))]\n                cred))))\n\n(defn- resolve-credential\n  \"Resolve key-value pair from result into a credential, updating result.\"\n  [source-settings result [k v]]\n  (letfn [(resolve [v]\n            (cond (= :env v)\n                  (getenv (str \"LEIN_\" (str/upper-case (name k))))\n\n                  (and (keyword? v) (= \"env\" (namespace v)))\n                  (getenv (str/upper-case (name v)))\n\n                  (= :gpg v)\n                  (get (match-credentials source-settings (credentials)) k)\n\n                  (coll? v) ;; collection of places to look\n                  (->> (map resolve v)\n                       (remove nil?)\n                       first)\n\n                  :else v))]\n    (if (#{:username :password :passphrase :private-key-file} k)\n      (assoc result k (resolve v))\n      (assoc result k v))))\n\n(defn resolve-credentials\n  \"Applies credentials from the environment or ~/.lein/credentials.clj.gpg\n  as they are specified and available.\"\n  [settings]\n  (let [gpg-creds (if (= :gpg (:creds settings))\n                    (match-credentials settings (credentials)))\n        resolved (reduce (partial resolve-credential settings)\n                         (empty settings)\n                         settings)]\n    (if gpg-creds\n      (dissoc (merge gpg-creds resolved) :creds)\n      resolved)))\n\n(defn profile-auth\n  \"Look up credentials for a given repository in :auth profile.\"\n  [settings]\n  (if-let [repo-auth (-> (profiles) :auth :repository-auth)]\n    (merge settings (match-credentials settings repo-auth))\n    settings))\n"
  },
  {
    "path": "leiningen-core/src/leiningen/core/utils.clj",
    "content": "(ns leiningen.core.utils\n  (:require [clojure.java.io :as io]\n            [clojure.java.shell :as sh]\n            [clojure.string :as str])\n  (:import (com.hypirion.io RevivableInputStream)\n           (clojure.lang LineNumberingPushbackReader)\n           (java.io ByteArrayOutputStream PrintStream File FileDescriptor\n                    FileOutputStream FileInputStream InputStreamReader)\n           (java.net URL)\n           (java.nio.file Files)\n           (java.nio.file.attribute PosixFilePermissions)))\n\n(defn create-tmpdir\n  \"Creates a temporary directory in parent (something clojure.java.io/as-path\n  can handle) with the specified permissions string (something\n  PosixFilePermissions/asFileAttribute can handle i.e. \\\"rw-------\\\") and\n  returns its Path.\"\n  [parent prefix permissions]\n  (let [nio-path (.toPath (io/as-file parent))\n        perms (PosixFilePermissions/fromString permissions)\n        attr (PosixFilePermissions/asFileAttribute perms)]\n    (Files/createTempDirectory nio-path prefix (into-array [attr]))))\n\n(def rebound-io? (atom false))\n\n(defn rebind-io! []\n  (when-not @rebound-io?\n    (let [new-in (-> FileDescriptor/in FileInputStream. RevivableInputStream.)]\n      (System/setIn new-in)\n      (.bindRoot #'*in* (-> new-in InputStreamReader.\n                            LineNumberingPushbackReader.)))\n    (reset! rebound-io? true)))\n\n(defn build-url\n  \"Creates java.net.URL from string\"\n  ^URL [url]\n  (try (URL. url)\n       (catch java.net.MalformedURLException _\n         (URL. (str \"http://\" url)))))\n\n(defmacro with-write-permissions\n  \"Runs body only if path is writeable, or - if it does not already exist - can\n  be created.\"\n  [path & body]\n  `(let [p# ~path\n         f# (new File p#)]\n     (if (or (and (.exists f#) (.canWrite f#))\n             (and (not (.exists f#)) (some-> f# .getParentFile .canWrite)))\n       (do ~@body)\n       (throw (java.io.IOException.\n         (str \"Permission denied. Please check your access rights for \" p#))))))\n\n(defn read-file\n  \"Returns the first Clojure form in a file if it exists.\"\n  [file]\n  (if (.exists file)\n    (try (read-string (slurp file))\n        (catch Exception e\n         (binding [*out* *err*] ;; TODO: use main/warn for this in 3.0\n           (println \"Error reading\"\n                   (.getName file)\n                   \"from\"\n                   (.getParent file))\n           (if (zero? (.length file))\n             (println \"File cannot be empty\")\n             (if (.contains (.getMessage e) \"EOF while reading\")\n               (println \"Invalid content was found\")\n               (println (.getMessage e)))))))))\n\n(defn symlink?\n  \"Checks if a File is a symbolic link or points to another file.\"\n  [file]\n  (let [canon (if-not (.getParent file)\n                file\n                (-> (.. file getParentFile getCanonicalFile)\n                    (File. (.getName file))))]\n    (not= (.getCanonicalFile canon)\n          (.getAbsoluteFile canon))))\n\n(defn mkdirs\n  \"Make a given directory and its parents, but throw an Exception on failure.\"\n  [f] ; whyyyyy does .mkdirs fail silently ugh\n  (when f ; (io/file nil) returns nil, so we mimic a similar API instead of failing eagerly on nil inputs.\n    (when-not (or (.mkdirs (io/file f)) (.exists (io/file f)))\n      (throw (Exception. (str \"Couldn't create directories: \" (io/file f)))))))\n\n(defn relativize\n  \"Makes the filepath path relative to base. Assumes base is an ancestor to\n  path, and that the path contains no '..'.\"\n  [base path]\n  ;; TODO: When moving to Java 1.7, use Path's relativize instead\n  (let [base-uri (.toURI (io/file base))\n        path-uri (.toURI (io/file path))]\n    (.. base-uri (relativize path-uri) (getPath))))\n\n(defn ns-exists? [namespace]\n  (or (find-ns (symbol namespace))\n      (some (fn [suffix]\n              (-> (#'clojure.core/root-resource namespace)\n                 (subs 1)\n                 (str suffix)\n                 io/resource))\n            [\".clj\" \".cljc\" (str clojure.lang.RT/LOADER_SUFFIX \".class\")])))\n\n(defn error [& args]\n  (binding [*out* *err*] ;; TODO: use main/warn for this in 3.0\n    (apply println \"Error:\" args)))\n\n(defn require-resolve\n  \"Resolve a fully qualified symbol by first requiring its namespace.\"\n  ([sym]\n     (if-let [ns (namespace sym)]\n       (when (ns-exists? ns)\n         (let [ns (symbol ns)]\n           (when-not (find-ns ns)\n             (require ns)))\n         (resolve sym))\n       (resolve sym)))\n  ([ns sym] (require-resolve (symbol ns sym))))\n\n;; # OS detection\n\n(defn- get-by-pattern\n  \"Gets a value from map m, but uses the keys as regex patterns, trying\n  to match against k instead of doing an exact match.\"\n  [m k]\n  (m (first (drop-while #(nil? (re-find (re-pattern %) k))\n                        (keys m)))))\n\n(defn- get-with-pattern-fallback\n  \"Gets a value from map m, but if it doesn't exist, fallback\n   to use get-by-pattern.\"\n  [m k]\n  (let [exact-match (m k)]\n    (if (nil? exact-match)\n      (get-by-pattern m k)\n      exact-match)))\n\n(def ^:private native-names\n  {\"Mac OS X\" :macosx \"Windows\" :windows \"Linux\" :linux\n   \"FreeBSD\" :freebsd \"OpenBSD\" :openbsd\n   \"amd64\" :x86_64 \"x86_64\" :x86_64 \"x86\" :x86 \"i386\" :x86\n   \"arm\" :arm \"SunOS\" :solaris \"sparc\" :sparc \"Darwin\" :macosx \"aarch64\" :aarch_64})\n\n(defn get-os\n  \"Returns a keyword naming the host OS.\"\n  []\n  (get-with-pattern-fallback native-names (System/getProperty \"os.name\")))\n\n(defn get-arch\n  \"Returns a keyword naming the host architecture\"\n  []\n  (get-with-pattern-fallback native-names (System/getProperty \"os.arch\")))\n\n(defn platform-nullsink\n  \"Returns a file destination that will discard output.\"\n  []\n  (io/file (if (= :windows (get-os))\n             \"NUL\"\n             \"/dev/null\")))\n\n\n;; The ordering on map-vals and filter-vals may seem strange, but it helps out\n;; if you want to do stuff like (update m :foo map-vals f extra-args)\n\n(defn map-vals\n  \"Like 'update', but for all values in a map.\"\n  [m f & args]\n  (zipmap (keys m) (map #(apply f % args) (vals m))))\n\n(defn filter-vals\n  \"Like filter, but for values over a map: If pred is satisfied on a value in m,\n  then its entry is preserved, otherwise it is removed.\"\n  [m pred]\n  (->> (filter #(pred (val %)) m)\n       (into {})))\n\n;; # Git\n\n;; This is very similar to the read-file function above. The only differences\n;; are the error messages and the transformations done on the content.\n(defn- git-file-contents\n  \"Returns the (trimmed) contents by the given git path, or nil if it is\n  inacessible or nonexisting. If it exists and is not readable, a warning is\n  printed.\"\n  [git-dir ref-path]\n  (let [ref (io/file git-dir ref-path)]\n    (if (.canRead ref)\n      (.trim (slurp ref))\n      (do\n        (when (.exists ref)\n          (binding [*out* *err*] ;; TODO: use main/warn for this in 3.0\n            (println \"Warning: Contents of git file\"\n                     (str \".git/\" ref-path) \"is not readable.\")\n            (println \"(Check that you have the right permissions to read\"\n                     \"the .git repo)\")))\n        nil))))\n\n(defn ^:internal resolve-git-dir [project]\n  (let [alternate-git-root (io/file (get-in project [:scm :dir]))\n        git-dir-file (io/file (or alternate-git-root (:root project)) \".git\")]\n    (if (and (.isFile git-dir-file) (.canRead git-dir-file))\n      (io/file (second (re-find #\"gitdir: (\\S+)\" (slurp (str git-dir-file)))))\n      git-dir-file)))\n\n(defn- read-git-ref\n  \"Reads the commit SHA1 for a git ref path, or nil if no commit exist.\"\n  [git-dir ref-path]\n  (git-file-contents git-dir ref-path))\n\n(defn- read-git-head-file\n  \"Reads the current value of HEAD by attempting to read .git/HEAD, returning\n  the SHA1 or nil if none exists.\"\n  [git-dir]\n  (some->> (git-file-contents git-dir \"HEAD\")\n           (re-find #\"ref: (\\S+)\")\n           (second)\n           (read-git-ref git-dir)))\n\n;; TODO: de-dupe with pom namespace (3.0?)\n\n(defn ^:internal read-git-head\n  \"Reads the value of HEAD and returns a commit SHA1, or nil if no commit\n  exist.\"\n  [git-dir]\n  (try\n    (let [git-ref (sh/sh \"git\" \"rev-parse\" \"HEAD\" :dir git-dir)]\n      (if (= (:exit git-ref) 0)\n        (.trim (:out git-ref))\n        (read-git-head-file git-dir)))\n    (catch java.io.IOException e (read-git-head-file git-dir))))\n\n(defn last-distinct\n  \"Like distinct, but retains the last version instead of the first version of a\n  duplicate.\"\n  [coll]\n  (reverse (distinct (reverse coll))))\n\n;; Inspired by distinct-by from medley (https://github.com/weavejester/medley),\n;; also under the EPL 1.0.\n(defn last-distinct-by\n  \"Returns a lazy sequence of the elements of coll, removing any\n  elements that return duplicate values when passed to a function f.\n  Only the last element that is a duplicate is preserved.\"\n  [f coll]\n  (let [step (fn step [xs seen]\n               (lazy-seq\n                ((fn [[x :as xs] seen]\n                   (when-let [s (seq xs)]\n                     (let [fx (f x)]\n                       (if (contains? seen fx)\n                         (recur (rest s) seen)\n                         (cons x (step (rest s) (conj seen fx)))))))\n                 xs seen)))]\n    (reverse (step (reverse coll) #{}))))\n\n(defn ancestor?\n  \"Is a an ancestor of b?\"\n  [a b]\n  (let [hypothetical-ancestor (.getCanonicalPath (io/file a))\n        hypothetical-descendant (.getCanonicalPath (io/file b))]\n    (and (.startsWith hypothetical-descendant hypothetical-ancestor)\n         (not (= hypothetical-descendant hypothetical-ancestor)))))\n\n(defmacro with-system-out-str\n  \"Like with-out-str, but for System/out.\"\n  [& body]\n  `(try (let [o# (ByteArrayOutputStream.)]\n          (System/setOut (PrintStream. o#))\n          ~@body\n          (.toString o#))\n     (finally\n       (System/setOut\n        (-> FileDescriptor/out FileOutputStream. PrintStream.)))))\n\n(defmacro with-system-err-str\n  \"Like with-out-str, but for System/err.\"\n  [& body]\n  `(try (let [o# (ByteArrayOutputStream.)]\n          (System/setErr (PrintStream. o#))\n          ~@body\n          (.toString o#))\n     (finally\n       (System/setErr\n        (-> FileDescriptor/err FileOutputStream. PrintStream.)))))\n\n(defn strip-properties-comments\n  \"Takes a string containing serialized java.util.Properties\n  and removes all the comment lines (those beginning with #)\"\n  [s]\n  (str/replace s #\"(\\A|\\R)(#.+(\\R|\\z))+\" \"$1\"))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/bluuugh.clj",
    "content": "(ns leiningen.bluuugh\n  \"Dummy task for tests.\")\n\n(defn ^:no-project-needed bluuugh\n  [project]\n  (println \"This is a dummy task for tests.\"))"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/classpath.clj",
    "content": "(ns leiningen.core.test.classpath\n  (:use [clojure.test]\n        [leiningen.core.classpath])\n  (:require [clojure.java.io :as io]\n            [clojure.stacktrace :as stacktrace]\n            [leiningen.core.user :as user]\n            [leiningen.core.main :as main]\n            [leiningen.test.helper :as lthelper]\n            [leiningen.core.project :as project])\n  (:import (java.io File)))\n\n(use-fixtures :once\n              (fn [f]\n                ;; Can't have user-level profiles interfering!\n                (with-redefs [user/profiles (constantly {})\n                              user/credentials (constantly nil)]\n                  (f))))\n\n(defn m2-file [f]\n  (io/file (System/getProperty \"user.home\") \".m2\" \"repository\" f))\n\n(def project {:managed-dependencies '[[org.clojure/clojure \"1.3.0\"]]\n              :dependencies '[[org.clojure/clojure]\n                              [ring/ring-core \"1.0.0\"\n                               :exclusions [commons-codec]]]\n              :checkout-deps-shares [:source-paths :resource-paths\n                                     :compile-path #(lthelper/pathify (str (:root %) \"/foo\"))]\n              :repositories project/default-repositories\n              :root \"/tmp/lein-sample-project\"\n              :target-path \"/tmp/lein-sample-project/target\"\n              :source-paths [\"/tmp/lein-sample-project/src\"]\n              :resource-paths [\"/tmp/lein-sample-project/resources\"]\n              :test-paths [\"/tmp/lein-sample-project/test\"]})\n\n(defn- resolve-with-repo [repo-url]\n  (resolve-managed-dependencies :dependencies\n                                :managed-dependencies\n                                (assoc project\n                                       :repositories {\"repo\" {:url repo-url}}\n                                       :dependencies '[[lein-pprint \"99\"]])))\n\n(deftest test-resolve-deps\n  (doseq [f (reverse (file-seq (io/file (:root project))))]\n    (when (.exists f) (io/delete-file f)))\n  (testing \"checks certificate expiry\"\n    (is (instance? java.security.cert.CertificateExpiredException\n                   (try\n                     (binding [main/*info* false]\n                       (resolve-with-repo \"https://expired.badssl.com/\"))\n                     (catch Exception e\n                       (stacktrace/root-cause e))))))\n  (testing \"checks for host of cert\"\n    (let [ex (try\n               (binding [main/*info* false]\n                 (resolve-with-repo \"https://badssl.f5n.de/\"))\n               (catch Exception e\n                 (stacktrace/root-cause e)))]\n      (is (or (instance? javax.net.ssl.SSLException ex)\n              (instance? javax.net.ssl.SSLPeerUnverifiedException ex)\n              (instance? java.security.GeneralSecurityException ex)))))\n  (is (= #{(m2-file \"org/clojure/clojure/1.3.0/clojure-1.3.0.jar\")\n           (m2-file \"commons-io/commons-io/1.4/commons-io-1.4.jar\")\n           (m2-file \"javax/servlet/servlet-api/2.5/servlet-api-2.5.jar\")\n           (m2-file \"ring/ring-core/1.0.0/ring-core-1.0.0.jar\")\n           (m2-file (str \"commons-fileupload/commons-fileupload/1.2.1/\"\n                         \"commons-fileupload-1.2.1.jar\"))}\n         (set (resolve-managed-dependencies :dependencies\n                                            :managed-dependencies\n                                            project)))))\n\n(deftest test-dependency-hierarchy\n  (doseq [f (reverse (file-seq (io/file (:root project))))]\n    (when (.exists f) (io/delete-file f)))\n  (is (= '{[org.clojure/clojure \"1.3.0\"] nil\n          [ring/ring-core \"1.0.0\"\n           :exclusions [[commons-codec]]]\n          {[commons-fileupload \"1.2.1\"] nil\n           [commons-io \"1.4\"] nil\n           [javax.servlet/servlet-api \"2.5\"] nil}}\n         (managed-dependency-hierarchy :dependencies\n                                       :managed-dependencies\n                                       project))))\n\n(def directories\n  (vec (map lthelper/pathify\n  [\"/tmp/lein-sample-project/test\"\n   \"/tmp/lein-sample-project/src\"\n   \"/tmp/lein-sample-project/resources\"])))\n\n(def libs\n  #{(str (m2-file \"commons-io/commons-io/1.4/commons-io-1.4.jar\"))\n    (str (m2-file \"javax/servlet/servlet-api/2.5/servlet-api-2.5.jar\"))\n    (str (m2-file \"ring/ring-core/1.0.0/ring-core-1.0.0.jar\"))\n    (str (m2-file \"commons-fileupload/commons-fileupload/1.2.1/commons-fileupload-1.2.1.jar\"))\n    (str (m2-file \"org/clojure/clojure/1.3.0/clojure-1.3.0.jar\"))})\n\n(deftest test-classpath\n  (let [classpath (get-classpath project)]\n    (is (= (set classpath) (into libs directories)))\n    (is (= directories (take 3 classpath)))\n    (is (= libs (set (drop 3 classpath))))))\n\n(defn canonical [& args]\n  (.getCanonicalPath ^File (apply io/file args)))\n\n(deftest test-checkout-deps\n  (let [d1 (io/file (:root project) \"checkouts\" \"d1\")]\n    (try\n      (.mkdirs d1)\n      (spit (io/file d1 \"project.clj\")\n            (pr-str '(defproject hello \"1.0\")))\n      (is (= (for [path [\"src\" \"dev-resources\" \"resources\" \"target/classes\" \"foo\"]]\n               (lthelper/pathify (canonical \"/tmp/lein-sample-project/checkouts/d1\" path)))\n             (#'leiningen.core.classpath/checkout-deps-paths project)))\n      (finally\n        ;; can't recur from finally\n        (dorun (map #(.delete ^File %) (reverse (file-seq d1))))))))\n\n(try\n  ;; nio is required for symlinks but requires Java 7\n  (import (java.nio.file Files Paths)\n          (java.nio.file.attribute FileAttribute))\n  (deftest test-checkout-symlink-unification\n    (let [link! (fn link! [from to]\n                  (java.nio.file.Files/createSymbolicLink (.toPath (io/file from))\n                                            (.toPath (io/file to))\n                                            (into-array java.nio.file.attribute.FileAttribute nil)))\n          d1    (io/file (:root project) \"deps\" \"d1\")\n          d2    (io/file (:root project) \"deps\" \"d2\")\n          l1    (io/file (:root project) \"checkouts\" \"d1\")\n          l2a   (io/file (:root project) \"checkouts\" \"d2\")\n          l2b   (io/file d1 \"checkouts\" \"d2\")]\n      (try\n        (.mkdirs d1)\n        (.mkdirs d2)\n        (.mkdirs (io/file (:root project) \"checkouts\"))\n        (.mkdirs (io/file d1 \"checkouts\"))\n        (link! l1 d1)\n        (link! l2a d1)\n        (link! l2b (io/file \"../../d2\"))\n        (spit (io/file d1 \"project.clj\")\n              (str \"(defproject p1 \\\"1.0\\\" :dependencies [[p2 \\\"1.0\\\"]] \"\n                   \":checkout-deps-shares ^:replace \"\n                   \"[:source-paths #=(eval leiningen.core.classpath/checkout-deps-paths)])\"))\n        (spit (io/file d2 \"project.clj\")\n              \"(defproject p2 \\\"1.0\\\")\")\n        (is (= (for [dep  [\"d1\" \"d2\"]\n                     path [\"src\"]]\n                 (canonical (:root project) \"deps\" dep path))\n               (#'leiningen.core.classpath/checkout-deps-paths\n                 (assoc project :checkout-deps-shares\n                                [:source-paths #'leiningen.core.classpath/checkout-deps-paths]))))\n        (finally\n          ;; can't recur from finally\n          (doseq [d [d1 d2 l1 l2a l2b]\n                  f (reverse (file-seq d))]\n            (.delete ^File f)))\n        )))\n  (catch ClassNotFoundException ex\n    nil))\n\n(deftest test-add-auth\n  (with-redefs [user/credentials (constantly\n                                  {\"https://sekrit.info/repo\"\n                                   {:username \"milgrim\" :password \"reindur\"}})\n                user/profiles (constantly {:auth {:repository-auth\n                                                  {#\"clojars\"\n                                                   {:username \"flynn\"\n                                                    :password \"flotilla\"}}}})]\n    (is (= [[\"clojars\" {:url \"https://clojars.org/repo\"\n                        :username \"flynn\" :password \"flotilla\"}]\n            [\"sonatype\" {:url \"https://oss.sonatype.org/\"}]\n            [\"internal\" {:password \"reindur\" :username \"milgrim\"\n                         :url \"https://sekrit.info/repo\"}]]\n            (map add-repo-auth\n                [[\"clojars\" {:url \"https://clojars.org/repo\"}]\n                  [\"sonatype\" {:url \"https://oss.sonatype.org/\"}]\n                  [\"internal\" {:url \"https://sekrit.info/repo\"\n                               :username :gpg :password :gpg}]])))))\n\n(deftest test-normalize-dep-vectors\n  (testing \"dep vectors with string version\"\n    (is (= ['foo/bar \"1.0.0\"]\n           (normalize-dep-vector ['foo/bar \"1.0.0\"])))\n    (is (= ['foo/bar \"1.0.0\" :classifier \"test\"]\n           (normalize-dep-vector ['foo/bar \"1.0.0\" :classifier \"test\"])))\n    (is (= ['foo/bar \"1.0.0\" :classifier \"test\" :exclusions ['foo/baz]]\n           (normalize-dep-vector ['foo/bar \"1.0.0\" :classifier \"test\" :exclusions ['foo/baz]]))))\n  (testing \"dep vectors with keyword version (e.g., for use with lein-modules)\"\n    (is (= ['foo/bar :version]\n           (normalize-dep-vector ['foo/bar :version])))\n    (is (= ['foo/bar :version :classifier \"test\"]\n           (normalize-dep-vector ['foo/bar :version :classifier \"test\"])))\n    (is (= ['foo/bar :version :classifier \"test\" :exclusions ['foo/baz]]\n           (normalize-dep-vector ['foo/bar :version :classifier \"test\" :exclusions ['foo/baz]]))))\n  (testing \"dep vectors with explicit nils for versions (managed dependencies)\"\n    (is (= ['foo/bar nil]\n           (normalize-dep-vector ['foo/bar nil])))\n    (is (= ['foo/bar nil :classifier \"test\"]\n           (normalize-dep-vector ['foo/bar nil :classifier \"test\"])))\n    (is (= ['foo/bar nil :classifier \"test\" :exclusions ['foo/baz]]\n           (normalize-dep-vector ['foo/bar nil :classifier \"test\" :exclusions ['foo/baz]]))))\n  (testing \"dep vectors with implicit nils for versions (managed dependencies)\"\n    (is (= ['foo/bar nil]\n           (normalize-dep-vector ['foo/bar])))\n    (is (= ['foo/bar nil :classifier \"test\"]\n           (normalize-dep-vector ['foo/bar :classifier \"test\"])))\n    (is (= ['foo/bar nil :classifier \"test\" :exclusions ['foo/baz]]\n           (normalize-dep-vector ['foo/bar :classifier \"test\" :exclusions ['foo/baz]])))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/eval.clj",
    "content": "(ns leiningen.core.test.eval\n  (:require [clojure.test :refer :all]\n            [leiningen.core.eval :refer :all]\n            [clojure.java.io :as io]\n            [leiningen.core.classpath :as classpath]\n            [leiningen.test.helper :as lthelper]\n            [leiningen.core.project :as project])\n  (:import (java.io File)))\n\n(def project {:managed-dependencies '[[org.clojure/clojure \"1.3.0\"]]\n              :dependencies '[[org.clojure/clojure]]\n              :root \"/tmp/lein-sample-project\"\n              :repositories project/default-repositories\n              :target-path \"/tmp/lein-sample-project/target\"\n              :source-paths [\"/tmp/lein-sample-project/src\"]\n              :resource-paths [\"/tmp/lein-sample-project/resources\"]\n              :test-paths [\"/tmp/lein-sample-project/test\"]\n              :compile-path \"/tmp/lein-sample-project/classes\"\n              :name \"test\" :group \"test\" :version \"1.0.0\"})\n\n(deftest test-eval-in-project\n  (doseq [where [:subprocess :leiningen :classloader]]\n    (let [file (File/createTempFile \"lein-eval-test\" \"\")]\n      (eval-in-project (assoc project :eval-in where\n                              :prep-tasks [])\n                       `(spit ~(.getPath file) (eval \"{:foo \\\"bar\\\"}\")))\n      (is (= \"{:foo \\\"bar\\\"}\" (slurp file)))\n      (.delete file))))\n\n(deftest test-classpath-directories-created\n  (doseq [path (concat (:source-paths project)\n                       (:test-paths project)\n                       (:resource-paths project))]\n    (let [file (File/createTempFile \"lein-eval-test\" \"\")]\n      (eval-in-project project\n                       `(do (.mkdirs (clojure.java.io/file ~path))\n                            (spit ~(str path \"/foo.txt\") \"Hello World\")\n                            (when-let [f# (clojure.java.io/resource \"foo.txt\")]\n                              (spit ~(.getPath file) (slurp f#))))\n                       `(require 'clojure.java.io))\n      (is (= \"Hello World\" (slurp file)))\n      (.delete (io/file (str path \"/foo.txt\")))\n      (.delete (io/file path))\n      (.delete file))))\n\n(deftest test-jvm-opts\n  (is (= [\"-Dhello=\\\"guten tag\\\"\" \"-XX:+HeapDumpOnOutOfMemoryError\"]\n         (get-jvm-opts-from-env (str \"-Dhello=\\\"guten tag\\\" \"\n                                     \"-XX:+HeapDumpOnOutOfMemoryError\"))))\n  (is (= [\"-Dfoo=bar\" \"-Dbar=baz\"]\n         (get-jvm-opts-from-env (str \"    -Dfoo=bar\"\n                                     \"    -Dbar=baz\"))))\n  (is (= [\"-Dfoo='ba\\\"r'\" \"-Dbar=\\\"ba\\\"'z'\" \"arg\"]\n         (get-jvm-opts-from-env (str \"    -Dfoo='ba\\\"r'\"\n                                     \"    -Dbar=\\\"ba\\\"'z'\"\n                                     \"    arg\"))))\n  (is (nil? (parse-d-property \"-Xmx1g\")))\n  (is (= [\"line.separator\" \"\\n\"]\n         (parse-d-property \"-Dline.separator=\\n\"))))\n\n(deftest test-file-encoding-in-jvm-args\n  (is (contains?\n          (set (#'leiningen.core.eval/get-jvm-args project))\n          (str \"-Dfile.encoding=\" (System/getProperty \"file.encoding\")))))\n\n(deftest test-get-jvm-args-with-proxy-settings\n  ;; Mock get-proxy-settings to return test values\n  (with-redefs [classpath/get-proxy-settings\n                (fn ([] {:host \"foo.com\" :port 8080})\n                    ([https] {:host \"secure-foo.com\", :port 443}))]\n    (let [args (set (shell-command project 'repl))]\n      (is (and (contains? args \"-Dhttp.proxyHost=foo.com\")\n               (contains? args \"-Dhttp.proxyPort=8080\")\n               (contains? args \"-Dhttps.proxyHost=secure-foo.com\")\n               (contains? args \"-Dhttps.proxyPort=443\"))))))\n\n(deftest test-java-agent\n  (let [p {:java-agents '[[com.newrelic.agent.java/newrelic-agent \"2.18.0\"\n                           :bootclasspath true]\n                          [nodisassemble \"0.1.2\" :options \"hello\"]]\n           :dependencies '[[slamhound \"1.3.0\"]]\n           :repositories project/default-repositories}\n        [newrelic newrelic-bootcp nodisassemble] (classpath-arg p)]\n    (is (.endsWith newrelic (lthelper/fix-path-delimiters\n                              (str \"/com/newrelic/agent/java/newrelic-agent\"\n                                   \"/2.18.0/newrelic-agent-2.18.0.jar\"))))\n    (is (re-find #\"bootclasspath.*newrelic.*jar\" newrelic-bootcp))\n    (is (re-find #\"-javaagent:.*nodisassemble-0.1.2.jar=hello\" nodisassemble))))\n\n(deftest test-sh-with-exit-code-successful-command\n  (with-redefs [sh (constantly 0)]\n    (is (= 0 (sh-with-exit-code \"Shouldn't see me.\" \"ls\")))))\n\n(deftest test-sh-with-exit-code-failed-command\n  (with-redefs [sh (constantly 1)]\n    (is (thrown-with-msg? Exception #\"Should see me. ls exit code: 1\" (sh-with-exit-code \"Should see me\" \"ls\")))))\n\n(deftest preserve-eval-meta\n  (let [project (assoc project :eval-in :pprint)\n        form `(do (defn ~'str-bytes [^String s#] (.getBytes s#)))\n        tagged-arg #\"\\^java.lang.String s\"]\n    (is (not (re-find tagged-arg (with-out-str\n                                   (eval-in-project project form)))))\n\n    (is (re-find tagged-arg (with-out-str\n                              (eval-in-project (assoc project :preserve-eval-meta true) form))))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/helper.clj",
    "content": "(ns leiningen.core.test.helper)\n\n(defn abort-msg\n  \"Catches main/abort thrown by calling f on its args and returns its error\n message.\"\n  [f & args]\n  (with-out-str\n    (binding [*err* *out*]\n      (try\n        (apply f args)\n        (catch clojure.lang.ExceptionInfo e\n          (when-not (:exit-code (ex-data e))\n            (throw e)))))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/main.clj",
    "content": "(ns leiningen.core.test.main\n  (:use [clojure.test]\n        [leiningen.core.main]))\n\n;; Shamelessly stolen from\n;; https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/main.clj#L28\n(defmacro with-err-str\n  \"Evaluates exprs in a context in which *err* is bound to a fresh\n  StringWriter.  Returns the string created by any nested printing\n  calls.\"\n  [& body]\n  `(let [s# (new java.io.StringWriter)\n         p# (new java.io.PrintWriter s#)]\n     (binding [*err* p#]\n       ~@body\n       (str s#))))\n\n(deftest test-logs-sent-to-*err*\n  (testing \"main/warn sent to *err*\"\n    (is (= \"Warning message\\n\" (with-err-str\n                                     (warn \"Warning message\"))))))\n\n(deftest test-lookup-alias\n  (testing \"meta merging\"\n    (let [project {:aliases {\"a\" ^:foo [\"root\"]\n                             \"b\" ^:bar [\"a\"]\n                             \"c\" ^{:pass-through-help false :doc \"Yo\"} [\"b\"]\n                             \"d\" ^:pass-through-help [\"c\"]}}]\n      (are [task m] (= (meta (lookup-alias task project)) m)\n           \"a\" {:foo true}\n           \"b\" {:bar true}\n           \"c\" {:doc \"Yo\" :pass-through-help false}\n           \"d\" {:pass-through-help true}))))\n\n(deftest test-task-args-help-pass-through\n  (let [project {:aliases {\"sirius-p\" [\"sirius\" \"partial\"]\n                           \"s\" \"sirius\"\n                           \"s-p\" [\"s\" \"partial\"]\n                           \"sirius-pp\" [\"sirius-p\" \"foo\"]\n                           \"sp\" \"s-p\"\n                           \"test\" \"test\"\n                           \"ohai\" ^:pass-through-help [\"run\" \"-m\" \"o.hai\"]\n                           \"aliaso\" [\"ohai\"]\n                           \"aliaso2\" [\"ohai\"]}}]\n    (testing \"with :pass-through-help meta\"\n      (testing \"on a var\"\n        (are [res arg] (= res (task-args arg project))\n             [\"help\" [\"sirius\"]] [\"help\" \"sirius\"]\n             [\"sirius\" [\"-h\"]] [\"sirius\" \"-h\"]\n             [\"sirius\" [\"-?\"]] [\"sirius\" \"-?\"]\n             [\"sirius\" [\"--help\"]] [\"sirius\" \"--help\"]\n             [\"sirius\" []] [\"sirius\"]))\n      (testing \"on an alias\"\n        (are [res arg] (= res (task-args arg project))\n             [\"help\" [\"sirius-p\"]] [\"help\" \"sirius-p\"]\n             [\"help\" [\"s\"]] [\"help\" \"s\"]\n             [\"sirius\" [\"-h\"]] [\"s\" \"-h\"]\n             [[\"sirius\" \"partial\"] [\"-?\"]] [\"sirius-p\" \"-?\"]\n             [\"sirius\" [\"--help\"]] [\"s\" \"--help\"]\n             [[\"sirius\" \"partial\"] []] [\"sirius-p\"]\n             [[\"sirius\" \"partial\"] []] [\"s-p\"]\n             [[\"sirius\" \"partial\"] []] [\"sp\"]\n             [[\"sirius\" \"partial\" \"foo\"] [\"bar\"]] [\"sirius-pp\" \"bar\"]\n             [\"test\" []] [\"test\"]\n             [\"sirius\" []] [\"s\"]\n             [[\"run\" \"-m\" \"o.hai\"] [\"-h\"]] [\"ohai\" \"-h\"]\n             [[\"run\" \"-m\" \"o.hai\"] [\"-h\"]] [\"aliaso\" \"-h\"]\n             [[\"run\" \"-m\" \"o.hai\"] [\"-h\"]] [\"aliaso2\" \"-h\"]\n             [[\"run\" \"-m\" \"o.hai\"] [\"--help\"]] [\"ohai\" \"--help\"]\n             [[\"run\" \"-m\" \"o.hai\"] [\"help\"]] [\"ohai\" \"help\"])))))\n\n(deftest test-matching-arity\n  (is (not (matching-arity? (resolve-task \"bluuugh\") [\"bogus\" \"arg\" \"s\"])))\n  (is (matching-arity? (resolve-task \"bluuugh\") []))\n  (is (matching-arity? (resolve-task \"var-args\") []))\n  (is (matching-arity? (resolve-task \"var-args\") [\"test-core\" \"hey\"]))\n  (is (not (matching-arity? (resolve-task \"one-or-two\") [])))\n  (is (matching-arity? (resolve-task \"one-or-two\") [\"clojure\"]))\n  (is (matching-arity? (resolve-task \"one-or-two\") [\"clojure\" \"2\"]))\n  (is (not (matching-arity? (resolve-task \"one-or-two\") [\"clojure\" \"2\" \"3\"]))))\n\n(deftest partial-tasks\n  (are [task args] (matching-arity? (resolve-task task) args)\n       [\"one-or-two\" \"clojure\"] [\"2\"]\n       [\"one-or-two\" \"clojure\" \"2\"] []\n       [\"fixed-and-var-args\" \"one\"] [\"two\"]\n       [\"fixed-and-var-args\" \"one\" \"two\"] []\n       [\"fixed-and-var-args\" \"one\" \"two\"] [\"more\"])\n  (are [task args] (not (matching-arity? (resolve-task task) args))\n       [\"one-or-two\" \"clojure\"] [\"2\" \"3\"]\n       [\"one-or-two\" \"clojure\" \"2\"] [\"3\"]\n       [\"fixed-and-var-args\" \"one\"] []))\n\n(deftest test-versions-match\n  (is (versions-match? \"1.2.12\" \"1.2.12\"))\n  (is (versions-match? \"3.0\" \"3.0\"))\n  (is (versions-match? \" 12.1.2\" \"12.1.2 \"))\n  (is (not (versions-match? \"1.2\" \"1.3\")))\n  (is (not (versions-match? \"1.2.0\" \"1.2\")))\n  (is (not (versions-match? \"1.2\" \"1.2.0\")))\n  (is (versions-match? \"2.1.3-SNAPSHOT\" \"2.1.3\"))\n  (is (versions-match? \"  2.1.3-SNAPSHOT\" \"2.1.3\"))\n  (is (versions-match? \"2.1.3\" \"2.1.3-FOO\"))\n  (is (not (versions-match? \"3.0.0\" \"3.0.1-BAR\"))))\n\n(deftest test-version-satisfies\n  (is (version-satisfies? \"1.5.0\" \"1.4.2\"))\n  (is (not (version-satisfies? \"1.4.2\" \"1.5.0\")))\n  (is (version-satisfies? \"1.2.3\" \"1.1.1\"))\n  (is (version-satisfies? \"1.2.0\" \"1.2\"))\n  (is (version-satisfies? \"1.2\" \"1\"))\n  (is (not (version-satisfies? \"1.67\" \"16.7\"))))\n\n(deftest one-or-two-args\n  (try (binding [*err* (java.io.StringWriter.)]\n         (resolve-and-apply {:root true} [\"one-or-two\"]))\n       (catch clojure.lang.ExceptionInfo e\n         (re-find #\"(?s)Wrong number of arguments to one-or-two task.*Expected \\[one\\] or \\[one two\\]\"\n                  (.getMessage e)))))\n\n(deftest zero-args-msg\n  (try (binding [*err* (java.io.StringWriter.)]\n         (resolve-and-apply {:root true} [\"zero\" \"too\" \"many\" \"args\"]))\n       (catch clojure.lang.ExceptionInfo e\n         (re-find #\"(?s)Wrong number of arguments to zero task.*Expected \\[\\]\"\n                  (.getMessage e)))))\n\n(def ^:private distance @#'leiningen.core.main/distance)\n\n(deftest test-damerau-levensthein\n  (is (zero? (distance \"run\" \"run\")))\n  (is (zero? (distance \"uberjar\" \"uberjar\")))\n  (is (zero? (distance \"classpath\" \"classpath\")))\n  (is (zero? (distance \"with-profile\" \"with-profile\")))\n\n  (is (= 1 (distance \"rep\" \"repl\")))\n  (is (= 1 (distance \"est\" \"test\")))\n  (is (= 1 (distance \"java\" \"javac\")))\n  (is (= 1 (distance \"halp\" \"help\")))\n  (is (= 1 (distance \"lien\" \"lein\")))\n\n  (is (= 4 (distance \"\" \"repl\")))\n  (is (= 6 (distance \"foobar\" \"\")))\n\n  (is (= 2 (distance \"erlp\" \"repl\")))\n  (is (= 2 (distance \"deploy\" \"epdloy\")))\n  (is (= 3 (distance \"pugared\" \"upgrade\"))))\n\n(deftest test-parse-options\n  (is (= (parse-options [\"--chicken\"])\n         [{:--chicken true} '()]))\n\n  (is (= (parse-options [\"--beef\" \"rare\"])\n         [{:--beef \"rare\"} []]))\n\n  (is (= (parse-options [\":fish\" \"salmon\"])\n         [{:fish \"salmon\"} []]))\n\n  (is (= (parse-options [\"salmon\" \"trout\"])\n         [{} [\"salmon\" \"trout\"]]))\n\n  (is (= (parse-options [\"--to-dir\" \"test2\" \"--ham\"])\n         [{:--ham true, :--to-dir \"test2\"} []]))\n\n  (is (= (parse-options [\"--to-dir\" \"test2\" \"--ham\" \"--\" \"pate\"])\n         [{:--ham true, :--to-dir \"test2\"} [\"pate\"]]))\n\n  (is (= (parse-options [\"--ham\" \"--to-dir\" \"test2\" \"pate\"])\n         [{:--ham true, :--to-dir \"test2\"} [\"pate\"]]))\n\n  (is (= (parse-options [\"--to-dir\" \"test2\" \"--ham\" \"--\"])\n         [{:--ham true, :--to-dir \"test2\"} []])))\n\n(deftest test-spliced-project-values\n  (let [p {:aliases {\"go\" [\"echo\" \"write\" :project/version]}\n           :version \"seventeen\"\n           :eval-in :leiningen}\n        out (with-out-str (resolve-and-apply p [\"go\"]))]\n    (is (= \"write seventeen\\n\" out))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/mirrors.clj",
    "content": "(ns leiningen.core.test.mirrors\n  (:require [clojure.test :refer :all]\n            [cemerick.pomegranate :as pom]\n            [leiningen.core.project :refer [defproject init-project]]))\n\n\n;; Regression test for Issue #1555\n(defproject mirrors-work-ok-with-plugins-project \"0.0.0\"\n  ;; we need to use a sequence of pairs rather than a map to\n  ;; reproduce the bug; IRL maps got converted to seqs somehow or\n  ;; another anyhow, but apparently not by init-project.\n  :mirrors [[\"central\" {:name \"foo\"\n                        :url \"https://repo1.maven.org/maven2/\"}]]\n  ;; Have to have a plugin to reproduce\n  :plugins [[lein-pprint \"1.1.1\"]])\n\n(deftest ^:online mirrors-work-ok-with-plugins\n  ;; turn off add-classpath so we don't actually mutate the classpath;\n  ;; we're still hitting the internet, and there's probably something\n  ;; in pomegranate we could redef to prevent that, but I haven't\n  ;; figured out what it is exactly.\n  (with-redefs [pom/add-classpath (constantly nil)]\n    (is (init-project project))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/pedantic.clj",
    "content": "(ns leiningen.core.test.pedantic\n  (:require [clojure.test :refer :all]\n            [clojure.java.io :as io]\n            [leiningen.core.classpath :as cp]\n            [leiningen.core.pedantic :as pedantic]\n            [cemerick.pomegranate.aether :as aether])\n  (:import (org.eclipse.aether.graph DependencyNode)))\n\n(def tmp-dir (io/file (System/getProperty \"java.io.tmpdir\") \"pedantic\"))\n(def tmp-local-repo-dir (io/file tmp-dir \"local-repo\"))\n\n(defn delete-recursive [dir]\n  (when (.isDirectory dir)\n    (doseq [file (.listFiles dir)]\n      (delete-recursive file)))\n    (.delete dir))\n\n(defn clear-tmp [f]\n  (delete-recursive (io/file tmp-dir)) (f))\n\n(defn get-versions [name repo]\n  (let [name (symbol name)]\n    (map second (filter #(= name (first %)) (keys repo)))))\n\n(defn make-pom-string [name version deps]\n  (str \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\n  <project xmlns=\\\"http://maven.apache.org/POM/4.0.0\\\"\n           xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\"\n           xsi:schemaLocation=\\\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\\\">\n  <modelVersion>4.0.0</modelVersion>\n  <groupId>\" name \"</groupId>\n  <artifactId>\" name \"</artifactId>\n  <packaging>jar</packaging>\n  <version>\" version \"</version>\n  <name>\" name \"</name>\"\n  (if-not (empty? deps)\n    (apply str\n           \"<dependencies>\"\n           (clojure.string/join \"\\n\"\n                                (for [[n v] deps]\n                                  (str \"<dependency>\n                   <groupId>\" n \"</groupId>\n                   <artifactId>\"n\"</artifactId>\n                   <version>\"v\"</version>\n                   </dependency>\")))\n           \"</dependencies>\"))\n  \" </project>\"))\n\n(defn make-metadata [name versions]\n  (str \"<metadata>\n  <groupId>\" name \"</groupId>\n  <artifactId>\" name \"</artifactId>\n  <versioning>\n  <versions>\"\n  (clojure.string/join \"\\n\"\n                       (for [v versions]\n                         (str \"<version>\"v\"</version>\")))\n    \"</versions>\n    <lastUpdated>20120810193549</lastUpdated>\n  </versioning>\n  </metadata>\"))\n\n(defn add-repo [repo]\n  (fn [f]\n    (aether/register-wagon-factory!\n     \"fake\"\n     #(reify org.apache.maven.wagon.Wagon\n        (getRepository [_]\n          (proxy [org.apache.maven.wagon.repository.Repository] []))\n        (^void connect [_\n                        ^org.apache.maven.wagon.repository.Repository _\n                        ^org.apache.maven.wagon.authentication.AuthenticationInfo _\n                        ^org.apache.maven.wagon.proxy.ProxyInfoProvider _])\n        (disconnect [_])\n        (removeTransferListener [_ _])\n        (addTransferListener [_ _])\n        (setTimeout [_ _])\n        (setInteractive [_ _])\n        (get [_ name file]\n          (let [[n _ version] (clojure.string/split name #\"/\")]\n            (if (= name (str n \"/\" n \"/maven-metadata.xml\"))\n              (if-let [versions (get-versions n repo)]\n                (spit file (make-metadata n versions))\n                (spit file \"\"))\n              (if-let [deps (repo [(symbol n) version])]\n                (if (re-find #\".pom$\" name)\n                  (spit file (make-pom-string n version deps))\n                  (spit file \"\"))\n                (throw (org.apache.maven.wagon.ResourceDoesNotExistException. \"\"))))))))\n    (f)))\n\n(defn resolve-deps [ranges overrides coords]\n  (aether/resolve-dependencies\n   :coordinates coords\n   :repositories {\"test-repo\" {:url \"fake://ss\" :checksum :warn}}\n   :local-repo tmp-local-repo-dir\n   :repository-session-fn (pedantic/session {:pedantic? true} ranges overrides)))\n\n(defmulti translate type)\n\n(defmethod translate :default [x] x)\n\n(defmethod translate java.util.List [l]\n  (vec (remove nil? (map translate l))))\n\n(defmethod translate java.util.Map [m]\n  (into {} (map (fn [[k v]] [k (translate v)]) m)))\n\n(defn- node->artifact-map [^DependencyNode node]\n  (if-let [d (.getDependency node)]\n    (if-let [a (.getArtifact d)]\n      (let [b (bean a)]\n        (-> b\n            (select-keys [:artifactId :groupId :exclusions\n                          :version :extension :properties])\n            (update-in [:exclusions] vec))))))\n\n(defmethod translate DependencyNode [n]\n  (if-let [a (node->artifact-map n)]\n    [(if (= (:groupId a) (:artifactId a))\n       (symbol (:artifactId a))\n       (symbol (:groupId a) (:artifactId a)))\n     (:version a)]))\n\n(def repo\n  '{[a \"1\"] []\n    [a \"2\"] []\n    [aa \"2\"] [[a \"2\"]]\n    [range \"1\"] [[a \"[1,)\"]]\n    [range \"2\"] [[a \"[2,)\"]]})\n\n(use-fixtures :once (add-repo repo))\n\n(deftest top-level-overrides-transative-later\n  (let [ranges (atom [])\n        overrides (atom [])]\n    (resolve-deps ranges overrides\n                  '[[a \"1\"]\n                    [aa \"2\"]])\n    (is (= @ranges []))\n    (is (= (translate @overrides)\n           '[{:accepted {:node [a \"1\"]\n                         :parents []}\n              :ignoreds [{:node [a \"2\"]\n                          :parents [[aa \"2\"]]}]\n              :ranges []}]))))\n\n(deftest ranges-are-found\n  (let [ranges (atom [])\n        overrides (atom [])]\n    (resolve-deps ranges overrides '[[range \"1\"]])\n    (is (= (translate @ranges) '[{:node [a \"2\"]\n                                  :parents [[range \"1\"]]}]))\n    (is (= @overrides []))))\n\n(deftest range-causes-other-transative-to-ignore-top-level\n  (let [ranges (atom [])\n        overrides (atom [])]\n    (resolve-deps ranges overrides '[[a \"1\"]\n                                     [aa \"2\"]\n                                     [range \"2\"]])\n    (is (= (translate @ranges) '[{:node [a \"2\"]\n                                  :parents [[range \"2\"]]}]))\n    (is (= (translate @overrides)\n           '[{:accepted {:node [a \"2\"]\n                         :parents [[aa \"2\"]]}\n              :ignoreds [{:node [a \"1\"]\n                          :parents []}]\n              :ranges []}]))))\n\n(deftest netty-boringssl-works\n  (let [project {:root \"/tmp\"\n                 :dependencies '[[io.netty/netty-tcnative-boringssl-static\n                                  \"2.0.50.Final\"]]\n                 :pedantic? :warn\n                 :repositories [[\"c\" {:url \"https://repo1.maven.org/maven2/\"\n                                      :snapshots false}]]}]\n    ;; this will result in an infinite loop in lein 2.9.8\n    (is (cp/get-classpath project))))\n\n(deftest ^:online multiple-paths-to-ignored-dep\n  (let [ranges (atom [])\n        overrides (atom [])]\n    (aether/resolve-dependencies\n     :coordinates '[[com.amazonaws/aws-java-sdk-s3 \"1.12.402\"]]\n     :repository-session-fn\n     #(-> %\n          aether/repository-session\n          (#'pedantic/use-transformer ranges overrides)))\n\n    (is (empty? @ranges))\n    (is (= (translate @overrides)\n           '[{:accepted {:node    [commons-logging \"1.1.3\"]\n                         :parents [[com.amazonaws/aws-java-sdk-s3 \"1.12.402\"]\n                                   [com.amazonaws/aws-java-sdk-core \"1.12.402\"]]}\n              :ignoreds [; leiningen <= 2.10 used to also report this path,\n                                        ; now we only report the shortest path\n                         #_{:node    [commons-logging \"1.2\"]\n                            :parents [[com.amazonaws/aws-java-sdk-s3 \"1.12.402\"]\n                                      [com.amazonaws/aws-java-sdk-kms \"1.12.402\"]\n                                      [com.amazonaws/aws-java-sdk-core \"1.12.402\"]\n                                      [org.apache.httpcomponents/httpclient \"4.5.13\"]]}\n                         {:node    [commons-logging \"1.2\"]\n                          :parents [[com.amazonaws/aws-java-sdk-s3 \"1.12.402\"]\n                                    [com.amazonaws/aws-java-sdk-core \"1.12.402\"]\n                                    [org.apache.httpcomponents/httpclient \"4.5.13\"]]}]\n              :ranges   []}]))))\n\n(deftest dont-suggest-on-duplicates\n  (let [project {:root \"/tmp\"\n                 :repositories [[\"c\" {:url \"https://repo1.maven.org/maven2/\"\n                                      :snapshots false}]]\n                 :dependencies '[[commons-logging \"1.2\"]\n                                 [commons-logging \"1.2\"]]\n                 :pedantic? :abort}]\n    (is (cp/get-dependencies :dependencies nil project))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/project.clj",
    "content": "(ns leiningen.core.test.project\n  (:refer-clojure :exclude [read])\n  (:require [clojure.test :refer :all]\n            [leiningen.core.project :refer :all :as project]\n            [leiningen.core.user :as user]\n            [leiningen.core.test.helper :refer [abort-msg]]\n            [leiningen.test.helper :as lthelper]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.main :as main]\n            [clojure.java.io :as io])\n  (:import (java.io StringReader)))\n\n(use-fixtures :once\n              (fn [f]\n                ;; Can't have user-level profiles interfering!\n                (with-redefs [user/profiles (constantly {})\n                              user/credentials (constantly nil)\n                              project/warn-once #'project/warn]\n                  (f))))\n\n(defn make-project\n  \"Make put a project map's :profiles on it's metadata\"\n  [m]\n  (project-with-profiles-meta m (:profiles m)))\n\n(def paths {:source-paths [\"src\"],\n            :test-paths [\"test\"],\n            :resource-paths [\"dev-resources\" \"resources\"],\n            :compile-path \"target/classes\",\n            :native-path \"target/native\",\n            :target-path \"target\"})\n\n(def expected {:name \"leiningen\", :group \"leiningen\",\n               :version \"2.0.0-SNAPSHOT\",\n               :url \"https://github.com/technomancy/leiningen\"\n\n               :disable-implicit-clean true,\n               :eval-in :leiningen,\n               :license {:name \"Eclipse Public License\"}\n\n               :dependencies `[[leiningen-core/leiningen-core \"2.0.0-SNAPSHOT\"]\n                               [clucy/clucy \"0.2.2\" :exclusions [[org.clojure/clojure]]]\n                               [lancet/lancet \"1.0.1\"]\n                               [robert/hooke \"1.1.2\"]\n                               [stencil/stencil \"0.2.0\"]\n                               [~(symbol \"net.3scale\" \"3scale-api\") \"3.0.2\"]\n                               [clj-http/clj-http \"3.4.1\"]\n                               [nrepl/nrepl \"1.0.0\"\n                                :exclusions [[org.clojure/clojure]]]\n                               [org.nrepl/incomplete \"0.1.0\"\n                                :exclusions [[org.clojure/clojure]]]],\n               :twelve 12 ; testing unquote\n\n               :repositories [[\"central\" {:url \"https://repo1.maven.org/maven2/\"\n                                          :snapshots false}]\n                              [\"clojars\" {:url \"https://repo.clojars.org/\"}]]})\n\n(deftest test-read-project\n  (let [actual (binding [*err* (java.io.StringWriter.)]\n                 (read (.getFile (io/resource \"p1.clj\"))))]\n    (doseq [[k v] expected]\n      (is (= v (k actual))))\n    (doseq [[k path] paths\n            :when (string? path)]\n      (is (= (lthelper/pathify (str (:root actual) \"/\" path))\n             (k actual))))\n    (doseq [[k path] paths\n            :when (coll? path)]\n      (is (= (for [p path] (lthelper/pathify (str (:root actual) \"/\" p)))\n             (k actual))))))\n\n(deftest test-read-project-from-reader\n  (let [project-string \"(defproject foo \\\"0.0.1-SNAPSHOT\\\" :description \\\"foo\\\")\"\n        project-reader (StringReader. project-string)\n        project (read project-reader)]\n    (is (= \"foo\" (:group project)))\n    (is (= \"foo\" (:name project)))\n    (is (= \"foo\" (:description project)))))\n\n;; TODO: test omit-default\n;; TODO: test reading project that doesn't def project\n\n(deftest test-replace-repositories\n  (let [actual (read (.getFile (io/resource \"replace-repositories.clj\")))]\n    (is (= 1 (-> actual :repositories count)))))\n\n(deftest test-retain-profile-metadata\n  (let [actual (read (.getFile (io/resource \"profile-metadata.clj\")))\n        profiles (:profiles actual)]\n    (is (true? (-> profiles :bar :dependencies meta :please-keep-me)))\n    (is (true? (-> profiles :bar :repositories meta :replace)))\n    (is (true? (-> profiles :baz :dependencies meta :hello)))\n    (is (true? (-> profiles :baz :repositories meta :displace)))))\n\n(deftest test-alias-in-profiles\n  (let [actual (read (.getFile (io/resource \"profile-metadata.clj\")))]\n    (is (= [\"my\" \"java\" \"opts\"]\n           (-> actual :profiles :baz :jvm-opts)))))\n\n(deftest test-merge-profile-displace-replace\n  (let [test-profiles {:carmine {:foo [3 4]}\n                       :carmined {:foo ^:displace [3 4]}\n                       :carminer {:foo ^:replace [3 4]}\n                       :blue {:foo [5 6]}\n                       :blued {:foo ^:displace [5 6]}\n                       :bluer {:foo ^:replace [5 6]}\n                       :jade {:foo [7 8]}\n                       :jaded {:foo ^:displace [7 8]}\n                       :jader {:foo ^:replace [7 8]}}\n        test-project (fn [p]\n                       (project-with-profiles-meta\n                         p\n                         (merge test-profiles (:profiles p))))]\n    (testing \"that :^displace throws away the value if another exist\"\n      (is (= [1 2]\n             (-> (make (test-project {:foo [1 2]}))\n                 (merge-profiles [:carmined])\n                 :foo)))\n      (is (= [1 2 5 6]\n             (-> (make (test-project {:foo [1 2]}))\n                 (merge-profiles [:carmined :blue :jaded])\n                 :foo)))\n      (is (= [5 6]\n             (-> (make (test-project {:foo ^:displace [1 2]}))\n                 (merge-profiles [:carmined :blued])\n                 :foo)))\n      (is (= [7 8 5 6]\n             (-> (make (test-project {:foo ^:displace [1 2]}))\n                 (merge-profiles [:carmined :jade :blued :blue])\n                 :foo))))\n    (testing \"that :^displace preserves metadata\"\n      (is (= {}\n             (-> (make (test-project {:foo [1 2]}))\n                 (merge-profiles [:carmined])\n                 :foo meta)))\n      (is (= {:quux :frob}\n             (-> (make (test-project {:foo ^{:quux :frob} [1 2]}))\n                 (merge-profiles [:carmined])\n                 :foo meta)))\n      (is (= {:displace true, :quux :frob}\n             (-> (make (test-project\n                        {:foo ^{:displace true, :quux :frob} [1 2]}))\n                 (merge-profiles [:carmined :blued :jaded])\n                 :foo meta)))\n      (is (= {:displace true, :a 1, :b 2}\n             (-> (make (test-project\n                        {:foo ^{:displace true, :a 1} [1 2]\n                         :profiles\n                         {:bar {:foo\n                                ^{:displace true, :b 2} [9 0]}}}))\n                 (merge-profiles [:jaded :bar :carmined])\n                 :foo meta))))\n    (testing \"that ^:replace replaces other values (at most once)\"\n      (is (= [1 2]\n             (-> (make (test-project {:foo ^:replace [1 2]}))\n                 (merge-profiles [:carmine])\n                 :foo)))\n      (is (= [3 4]\n             (-> (make (test-project {:foo [1 2]}))\n                 (merge-profiles [:carminer])\n                 :foo)))\n      (is (= [1 2 5 6]\n             (-> (make (test-project {:foo ^:replace [1 2]}))\n                 (merge-profiles [:carmine :blue])\n                 :foo)))\n      (is (= [3 4]\n             (-> (make (test-project {:foo ^:replace [1 2]}))\n                 (merge-profiles [:carminer])\n                 :foo)))\n      (is (= [7 8]\n             (-> (make (test-project {:foo ^:replace [1 2]}))\n                 (merge-profiles [:jader :blue])\n                 :foo)))\n      (is (= [3 4]\n             (-> (make (test-project {:foo ^:replace [1 2]}))\n                 (merge-profiles [:carminer :jade])\n                 :foo))))\n    (testing \"that ^:replace preserves metadata\"\n      (is (= {}\n             (-> (make (test-project {:foo [1 2]}))\n                 (merge-profiles [:carminer])\n                 :foo meta)))\n      (is (= {:quux :frob}\n             (-> (make (test-project {:foo ^{:quux :frob} [1 2]}))\n                 (merge-profiles [:carminer])\n                 :foo meta)))\n      (is (= {:replace true, :quux :frob}\n             (-> (make (test-project\n                        {:foo ^{:replace true, :quux :frob} [1 2]}))\n                 (merge-profiles [:carminer :jader :bluer])\n                 :foo meta)))\n      (is (= {:replace true, :a 1, :b 2}\n             (-> (make (test-project\n                        {:foo ^{:replace true, :a 1} [1 2]\n                         :profiles {:bar {:foo\n                                          ^{:replace true, :b 2} [9 0]}}}))\n                 (merge-profiles [:jader :bar :carminer])\n                 :foo meta))))\n    (testing \"that ^:displace and ^:replace operates correctly together\"\n      (is (= [5 6]\n             (-> (make (test-project {:foo ^:displace [1 2]}))\n                 (merge-profiles [:bluer])\n                 :foo)))\n      (is (= [1 2]\n             (-> (make (test-project {:foo ^:replace [1 2]}))\n                 (merge-profiles [:blued])\n                 :foo)))\n      (is (= [7 8]\n             (-> (make (test-project {:foo [1 2]}))\n                 (merge-profiles [:jader :carmined])\n                 :foo)))\n      (is (= [7 8]\n             (-> (make (test-project {:foo [1 2]}))\n                 (merge-profiles [:carmined :jader])\n                 :foo))))\n    (testing \"that metadata is preserved at ^:displace/^:replace clashes\"\n      (is (= {:frob true}\n             (-> (make (test-project\n                        {:foo ^{:displace true, :frob true} [1 2]}))\n                 (merge-profiles [:carminer])\n                 :foo meta)))\n      (is (= {:frob true}\n             (-> (make (test-project\n                        {:foo ^{:replace true, :frob true} [1 2]}))\n                 (merge-profiles [:carmined])\n                 :foo meta)))\n      (is (= {:a 1, :b 2}\n             (-> (make (test-project\n                        {:foo ^{:replace true, :a 1} [1 2]\n                         :profiles\n                         {:bar {:foo ^{:displace true, :a 3, :b 2} [3 4]}}}))\n                 (merge-profiles [:bar])\n                 :foo meta)))\n      (is (= {:a 3, :b 2}\n             (-> (make (test-project\n                        {:foo ^{:displace true, :a 1} [1 2]\n                         :profiles\n                         {:bar {:foo ^{:replace true, :a 3, :b 2} [3 4]}}}))\n                 (merge-profiles [:bar])\n                 :foo meta))))\n    (testing \"that built-in ^:replace values are properly replaced\"\n      (is (= '(constantly false)\n             (-> (make {:test-selectors {:default '(constantly false)}})\n                 (merge-profiles [:base])\n                 :test-selectors :default))))\n    (testing \"that IObjs can be compared with non-IObjs without crashing\"\n      (is (= :keyword\n             (-> (make {:test-selectors {:default :keyword}})\n                 (merge-profiles [:base])\n                 :test-selectors :default)))\n      (is (= [1 2]\n             (-> (make (test-project\n                        {:foo ^:replace [1 2]\n                         :profiles\n                         {:bar {:foo 100}}}))\n                 (merge-profiles [:bar])\n                 :foo)))\n      (is (= [1 2]\n             (-> (make (test-project\n                        {:foo 100\n                         :profiles\n                         {:bar {:foo ^:replace [1 2]}}}))\n                 (merge-profiles [:bar])\n                 :foo)))\n      (is (= \"string\"\n             (-> (make (test-project\n                        {:foo \"string\"\n                         :profiles\n                         {:bar {:foo ^:displace [1 2]}}}))\n                 (merge-profiles [:bar])\n                 :foo)))\n      (is (= \"string\"\n             (-> (make (test-project\n                        {:foo ^:displace [1 2]\n                         :profiles\n                         {:bar {:foo \"string\"}}}))\n                 (merge-profiles [:bar])\n                 :foo))))\n    (testing \"that IObjs keep their metadata when compared to non-IObjs\"\n      (is (= {:frob true}\n             (-> (make (test-project\n                        {:foo 100\n                         :profiles\n                         {:bar {:foo ^{:replace true, :frob true} [1 2]}}}))\n                 (merge-profiles [:bar])\n                 :foo meta))))))\n\n(def test-profiles (atom {:qa {:resource-paths [\"/etc/myapp\"]}\n                          :test {:resource-paths [\"test/hi\"]}\n                          :repl {:dependencies\n                                 '[[nrepl/nrepl \"0.4.5\"\n                                    :exclusions [org.clojure/clojure]]\n                                   [org.thnetos/cd-client \"0.3.4\"\n                                    :exclusions [org.clojure/clojure]]]}\n                          :tes :test\n                          :dev {:test-paths [\"test\"]}}))\n\n(deftest test-merge-profile-paths\n  (let [test-project (fn [p]\n                       (project-with-profiles-meta\n                         p\n                         (merge @test-profiles (:profiles p))))]\n    (is (= (vec (map lthelper/fix-path-delimiters [\"/etc/myapp\" \"test/hi\" \"blue-resources\" \"resources\"]))\n           (-> (make\n                (test-project\n                 {:resource-paths [\"resources\"]\n                  :profiles {:blue {:resource-paths [\"blue-resources\"]}}}))\n               (merge-profiles [:blue :tes :qa])\n               :resource-paths)))\n    (is (= (vec (map lthelper/fix-path-delimiters [\"/etc/myapp\" \"test/hi\" \"blue-resources\"]))\n           (-> (make\n                (test-project\n                 {:resource-paths ^:displace [\"resources\"]\n                  :profiles {:blue {:resource-paths [\"blue-resources\"]}}}))\n               (merge-profiles [:blue :tes :qa])\n               :resource-paths)))\n    (is (= [\"replaced\"]\n           (-> (make\n                (test-project\n                 {:resource-paths [\"resources\"]\n                  :profiles {:blue {:resource-paths ^:replace [\"replaced\"]}}}))\n               (merge-profiles [:tes :qa :blue])\n               :resource-paths)))\n    (is (= {:url \"http://\" :username \"u\" :password \"p\"}\n           (-> (make\n                (test-project\n                 {:repositories [[\"foo\" {:url \"http://\" :creds :gpg}]]\n                  :profiles {:blue {:repositories {\"foo\"\n                                                   ^:replace {:url \"http://\"\n                                                              :username \"u\"\n                                                              :password \"p\"}}}}}))\n               (merge-profiles [:blue :qa :tes])\n               :repositories\n               last last)))))\n\n(deftest test-merge-profile-deps\n  (with-redefs [default-profiles test-profiles]\n    (let [project (make\n                   {:resource-paths [\"resources\"]\n                    :dependencies '[^:displace [org.foo/bar \"0.1.0\" :foo [1 2]]\n                                    [org.foo/baz \"0.2.0\" :foo [1 2]]\n                                    [org.foo/zap \"0.3.0\" :foo [1 2]]]\n                    :profiles {:dev {:dependencies\n                                     '[[org.foo/bar \"0.1.2\"]\n                                       [org.foo/baz \"0.2.1\"]\n                                       ^:replace [org.foo/zap \"0.3.1\"]]}}})]\n      (is (= '[[org.foo/bar \"0.1.2\"]\n               [org.foo/baz \"0.2.1\" :foo [1 2]]\n               [org.foo/zap \"0.3.1\"]]\n             (-> (make-project project)\n                 (merge-profiles [:dev])\n                 :dependencies))))))\n\n(deftest test-merge-profile-repos\n  (with-redefs [default-profiles test-profiles]\n    (let [project\n          (make\n           (make-project\n            {:profiles {:clojars {:repositories ^:replace\n                                  [[\"clojars.org\" \"https://clojars.org/repo/\"]]}\n                        :clj-2 {:repositories\n                                [[\"clojars.org\" \"https://new-link.org/\"]]}\n                        :blue {:repositories\n                               [[\"my-repo\" \"https://my-repo.org/\"]]}\n                        :red {:repositories\n                              [^:replace [\"my-repo\" \"https://my-repo.org/red\"]]}\n                        :green {:repositories\n                                [^:displace\n                                 [\"my-repo\" \"https://my-repo.org/green\"]]}\n                        :empty {:repositories ^:replace []}}}))]\n      (is (= default-repositories\n             (:repositories project)))\n      (is (= []\n             (-> (merge-profiles project [:empty])\n                 :repositories)))\n      (is (= [[\"my-repo\" {:url \"https://my-repo.org/\"}]]\n             (-> (merge-profiles project [:empty :blue])\n                 :repositories)))\n      (is (= [[\"clojars.org\" {:url \"https://clojars.org/repo/\"}]]\n             (-> (merge-profiles project [:clojars])\n                 :repositories)))\n      (is (= [[\"clojars.org\" {:url \"https://clojars.org/repo/\"}]\n              [\"my-repo\" {:url \"https://my-repo.org/\"}]]\n             (-> (merge-profiles project [:clojars :blue])\n                 :repositories)))\n      (is (= [[\"clojars.org\" {:url \"https://new-link.org/\"}]\n              [\"my-repo\" {:url \"https://my-repo.org/\"}]]\n             (-> (merge-profiles project [:clojars :blue :clj-2])\n                 :repositories)))\n      (is (= [[\"clojars.org\" {:url \"https://clojars.org/repo/\"}]\n              [\"my-repo\" {:url \"https://my-repo.org/\"}]]\n             (-> (merge-profiles project [:clojars :blue :green])\n                 :repositories)))\n      (is (= [[\"clojars.org\" {:url \"https://clojars.org/repo/\"}]\n              [\"my-repo\" {:url \"https://my-repo.org/red\"}]]\n             (-> (merge-profiles project [:blue :clojars :red])\n                 :repositories)))\n      (is (= [[\"my-repo\" {:url \"https://my-repo.org/red\"}]\n              [\"clojars.org\" {:url \"https://new-link.org/\"}]]\n             (-> (merge-profiles project [:empty :red :clj-2 :green])\n                 :repositories))))))\n\n(deftest test-merge-many-profiles\n  (let [profiles (into {} (map #(vector (-> % str keyword) {:foo [%]}) (range 10)))\n        project (make {:profiles profiles})]\n    (is (= (range 10)\n          (-> (make-project project)\n            (merge-profiles [:0 :1 :2 :3 :4 :5 :6 :7 :8 :9])\n            :foo)))))\n\n(deftest test-global-exclusions\n  (let [project {:dependencies\n                 '[[org.clojure/clojure \"1.11.1\"]\n                   [lancet \"1.0.1\"]\n                   [leiningen-core \"2.0.0-SNAPSHOT\" :exclusions [pomegranate]]\n                   [clucy \"0.2.2\" :exclusions [org.clojure/clojure]]]\n                 :exclusions '[org.clojure/clojure]}\n        dependencies (:dependencies (merge-profiles project [:default]))]\n    (is (= '[[[org.clojure/clojure]]\n             [[org.clojure/clojure] [pomegranate/pomegranate]]\n             [[org.clojure/clojure]]]\n           (map #(distinct (:exclusions (apply hash-map %))) dependencies)))\n    (is (= '[[lancet/lancet \"1.0.1\" :exclusions ([org.clojure/clojure])]\n             [leiningen-core/leiningen-core \"2.0.0-SNAPSHOT\" :exclusions ([org.clojure/clojure] [pomegranate/pomegranate])]\n             [clucy/clucy \"0.2.2\" :exclusions ([org.clojure/clojure])]]\n           dependencies))))\n\n(defn add-seven [project]\n  (assoc project :seven 7))\n\n(deftest test-middleware\n  (is (= 7 (:seven (init-project (read (.getFile (io/resource \"p2.clj\"))))))))\n\n(deftest test-middleware-no-implicits\n  (is (= 7 (:seven (init-project (read (.getFile (io/resource \"p4.clj\"))))))))\n\n(deftest test-middleware-no-implicit-middleware\n  (is (= 7 (:seven (init-project (read (.getFile (io/resource \"p5.clj\"))))))))\n\n(deftest test-checkouts\n  (let [project (binding [*err* (java.io.StringWriter.)]\n                  (read (.getFile (io/resource \"p1.clj\"))))]\n    (is (= #{\"checkout-lib1\" \"checkout-lib2\"} (set (map :name (read-checkouts project)))))))\n\n(deftest test-activate-middleware\n  (let [errors (atom [])]\n    (with-redefs [utils/error (fn [& args] (swap! errors conj args))]\n      (init-project (read (.getFile (io/resource \"p3.clj\")))))\n    (is (= [] @errors))))\n\n(deftest test-plugin-vars\n  (are [project hooks middleware] (= (list hooks middleware)\n                                     (map (partial plugin-vars project) [:hooks :middleware]))\n       {:plugins '[[lein-foo \"1.2.3\"]]}\n       '(lein-foo.plugin/hooks) '(lein-foo.plugin/middleware)\n\n       {:plugins '[[lein-foo \"1.2.3\" :hooks false]]}\n       '() '(lein-foo.plugin/middleware)\n\n       {:plugins '[[lein-foo \"1.2.3\" :middleware false]]}\n       '(lein-foo.plugin/hooks) '()\n\n       {:plugins '[[lein-foo \"1.2.3\" :hooks false :middleware false]]}\n       '() '()))\n\n(deftest test-add-profiles\n  (let [expected-result {:dependencies [] :profiles {:a1 {:src-paths [\"a1/\"]}\n                                                     :a2 {:src-paths [\"a2/\"]}}}]\n    (is (= expected-result\n           (-> {:dependencies []}\n               (add-profiles {:a1 {:src-paths [\"a1/\"]}\n                              :a2 {:src-paths [\"a2/\"]}}))))\n    (is (= expected-result\n           (-> {:dependencies []}\n               (add-profiles {:a1 {:src-paths [\"a1/\"]}\n                              :a2 {:src-paths [\"a2/\"]}})\n               meta\n               :without-profiles)))\n    (is (nil?\n         (-> {:dependencies []}\n             (add-profiles {:a1 {:src-paths [\"a1/\"]}\n                            :a2 {:src-paths [\"a2/\"]}})\n             :src-paths)))\n    (is (= [\"a1\"]\n           (-> {:dependencies []}\n               (add-profiles {:a1 {:src-paths [\"a1/\"]}\n                              :a2 {:src-paths [\"a2/\"]}})\n               (merge-profiles [:a1])\n               :src-paths)))))\n\n(deftest test-merge-anon-profiles\n  (is (= {:A 1, :C 3}\n         (-> (make-project {:profiles {:a {:A 1} :b {:B 2}}})\n             (merge-profiles [{:C 3} :a])\n             (dissoc :profiles)))))\n\n(deftest test-composite-profiles\n  (binding [main/*info* false]\n    (is (= {:A '(1 3 2), :B 2, :C 3}\n           (-> (make-project\n                {:profiles {:a [:b :c]\n                            :b [{:A [1] :B 1 :C 1} :d]\n                            :c {:A [2] :B 2}\n                            :d {:A [3] :C 3}}})\n               (merge-profiles [:a])\n               (dissoc :profiles))))))\n\n(deftest test-profiles-default-meta\n  (is (= [:repl]\n         (-> (init-project\n              {:profiles {:repl {:a {:A 1}}}})\n             (profiles-with-matching-meta :repl))))\n  (is (= [:repl]\n         (-> (init-project\n              {:profiles {:a {:A 1}\n                          :repl [:a]}})\n             (profiles-with-matching-meta :repl)))))\n\n(deftest test-override-default\n  (is (= {:A 1, :B 2, :C 3}\n         (-> (make-project\n               {:profiles {:a {:A 1 :B 2}\n                           :b {:B 2 :C 2}\n                           :c {:C 3}\n                           :default [:a :b :c]}})\n             (merge-profiles [:default])\n             (dissoc :profiles)))))\n\n(deftest test-unmerge-profiles\n  (let [expected {:A 1 :C 3}]\n    (is (= expected\n           (-> (make-project\n                {:profiles {:a {:A 1}\n                            :b {:B 2}\n                            :c {:C 3}}})\n               (merge-profiles [:a :b :c])\n               (unmerge-profiles [:b])\n               (dissoc :profiles))))\n    (is (= expected\n           (-> (make-project\n                {:profiles {:a {:A 1}\n                            :b {:B 2}\n                            :c {:C 3}}})\n               (merge-profiles [:a :b :c {:D 4}])\n               (unmerge-profiles [:b {:D 4}])\n               (dissoc :profiles))))\n    (is (= expected\n           (-> (make-project\n                {:profiles {:a {:A 1}\n                            :b {:B 2}\n                            :c {:C 3}\n                            :foo [:b]}})\n               (merge-profiles [:a :b :c])\n               (unmerge-profiles [:foo])\n               (dissoc :profiles))))\n    (testing \"unmerge composite profiles\"\n      (with-redefs [warn-once (fn [& _] (throw (Exception. \"no warning!\")))]\n        (let [project (project/init-project\n                       (make-project {:profiles {:dev [:project/dev]\n                                                 :project/dev {:dev? true}}\n                                      :dev? false})\n                       [:default])]\n          (is (not (:dev? (project/unmerge-profiles project [:dev])))))))))\n\n(deftest test-merge-coll-with-metadata\n  (binding [main/*info* false]\n    (let [profiles {:shared {:clean-targets ^{:protect false} [\"resources/a.txt\"]}\n                    :prod [:shared {:clean-targets\n                                    ^{:protect false} [\"resources/b.txt\"]}]}\n          project (-> (make-project {:profiles profiles})\n                      (merge-profiles [:prod]))]\n      (is (= (:clean-targets project) [\"resources/a.txt\" \"resources/b.txt\"]))\n      (is (false? (-> project :clean-targets meta :protect))))))\n\n(deftest test-dedupe-deps\n  (is (= '[[org.clojure/clojure \"1.3.0\"]\n           [org.clojure/clojure \"1.3.0\" :classifier \"sources\"]]\n         (-> (make\n              {:dependencies '[[org.clojure/clojure \"1.4.0\"]\n                               [org.clojure/clojure \"1.3.0\" :classifier \"sources\"]\n                               [org.clojure/clojure \"1.3.0\"]]})\n             (:dependencies)))))\n\n(deftest test-dedupe-non-group-deps\n  (is (= '[[foo/foo \"1.1\"]]\n        (-> (make-project\n              {:dependencies empty-dependencies\n               :profiles {:a {:dependencies '[[foo \"1.0\"]]}\n                          :b {:dependencies '[[foo \"1.1\"]]}}})\n          (merge-profiles [:a :b])\n          (:dependencies)))))\n\n(deftest test-warn-user-repos\n  (if (System/getenv \"LEIN_SUPPRESS_USER_LEVEL_REPO_WARNINGS\")\n    (testing \"no output with suppression\"\n      (is (= \"\"\n             (abort-msg\n              #'project/warn-user-repos\n              {:user {:repositories\n                      {\"central\" {:url \"https://repo1.maven.org/maven2/\"\n                                  :snapshots false}\n                       \"clojars\" {:url \"https://clojars.org/repo/\"}}}}))))\n    (testing \"with no suppression,\"\n      (testing \"no warning without user level repo\"\n        (is (= \"\" (abort-msg #'project/warn-user-repos {}))\n            \"No warning in base case\"))\n      (testing \"Warning with user level repo\"\n        (is (re-find\n             #\":repositories .* [:user].*\"\n             (abort-msg\n              #'project/warn-user-repos\n              {:user {:repositories\n                      {\"central\" {:url \"https://repo1.maven.org/maven2/\"\n                                  :snapshots false}\n                       \"clojars\" {:url \"https://clojars.org/repo/\"}}}}))))\n      (testing \"Warning with user level repo\"\n        (is (re-find\n             #\":repositories .* [:user].*\"\n             (abort-msg\n              #'project/warn-user-repos\n              {:user {:repositories\n                      {\"central\" \"https://repo1.maven.org/maven2/\"\n                       \"clojars\" \"https://clojars.org/repo/\"}}}))))\n      (testing \"Warning with user level repo\"\n        (is (re-find\n             #\":repositories .* [:user].*\"\n             (abort-msg\n              #'project/warn-user-repos\n              {:user\n               {:repositories\n                [[\"central\" {:url \"https://repo1.maven.org/maven2/\"\n                             :snapshots false}]\n                 [\"clojars\" {:url \"https://clojars.org/repo/\"}]]}})))))))\n\n(deftest test-profile-scope-target-path\n  (let [project (with-meta\n                  {:target-path \"target/%s\"}\n                  {:profiles {:ab  [:a :b]\n                              :abc [:ab :c]\n                              :bcd [:b :c :d]\n                              :a   {}\n                              :b   {}\n                              :c   {}\n                              :d   {}\n                              :e   {}}})]\n    (are [ps tp] (= (profile-scope-target-path project ps) {:target-path tp})\n      [:a :b]       \"target/ab\"\n      [:a :b :c]    \"target/abc\"\n      [:b :c]       \"target/b+c\"\n      [:b :a]       \"target/b+a\"\n      [:c :b :a]    \"target/c+b+a\"\n      [:c :a :b]    \"target/c+ab\"\n      [:a :b :c :d] \"target/abc+d\"\n      [:e :b :c :d] \"target/e+bcd\"\n      [:c :a :b :d] \"target/c+ab+d\"\n      [:a]          \"target/a\")))\n\n(deftest test-init-profiles\n  (let [profiles {:ring {:dependencies [['ring \"1.8.2\"]]}\n                  :dev  [:ring]\n                  :test {:dependencies [['clucy \"1.0.0\"]]}}\n        project (init-project {:dependencies '[[org.clojure/clojure \"1.10.1\"]]\n                               :profiles profiles}\n                              [:default])\n        result (init-profiles project [:dev :test])]\n    (is (= '[[org.clojure/clojure \"1.10.1\"]\n             [ring \"1.8.2\" :scope \"test\"]\n             [clucy \"1.0.0\" :scope \"test\"]]\n           (:dependencies result)))))\n\n(deftest test-unmerge-composite-profiles\n  (let [profiles {:ring {:dependencies [['ring \"1.8.2\"]]}\n                  :dev  [:ring]\n                  :test {:dependencies [['clucy \"1.0.0\"]]}}\n        project (init-project {:dependencies '[[org.clojure/clojure \"1.10.1\"]]\n                               :profiles profiles}\n                              [:default])\n        result (unmerge-profiles project [:system :base :provided :user])]\n    (is (= '[[org.clojure/clojure \"1.10.1\"]\n             [ring \"1.8.2\" :scope \"test\"]]\n           (:dependencies result)))\n    ;; Even though this isn't a part of the formal API, ensure\n    ;; that unmerging correctly adjust :active-profiles too.\n    (is (= [:ring] (-> result meta :active-profiles)))))\n\n(deftest test-target-path\n  (let [project (init-project {:dependencies '[[org.clojure/clojure \"1.10.1\"]]\n                               :target-path \"target/%s\"\n                               :profiles {:uberjar {}}}\n                              [:default])\n        project (merge-profiles project [:uberjar])]\n    (is (= \"target/uberjar\" (:target-path project)))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/user.clj",
    "content": "(ns leiningen.core.test.user\n  (:use clojure.test\n        leiningen.core.user))\n\n(deftest resolving-repo-creds\n  (with-redefs [credentials (constantly {#\"^https://clojars\\.org/.*\"\n                                         {:username \"u\" :password \"p\"\n                                          :passphrase \"looooong\"\n                                          :private-key-file \"./somewhere\"}})]\n    (testing \"Literal creds unmolested\"\n      (is (= (resolve-credentials {:url \"https://clojars.org/repo\"\n                                   :username \"easily\" :password \"stolen\"})\n             {:url \"https://clojars.org/repo\"\n              :username \"easily\" :password \"stolen\"})))\n    (testing \"Lookup in environment\"\n      (with-redefs [getenv {\"LEIN_USERNAME\" \"flynn\"\n                            \"CUSTOMENV\" \"flotilla\"}]\n        (is (= (resolve-credentials {:url \"https://clojars.org/repo\"\n                                     :username :env\n                                     :password :env/customenv})\n               {:url \"https://clojars.org/repo\"\n                :username \"flynn\" :password \"flotilla\"}))))\n    (testing \"Check multiple locations\"\n      (with-redefs [getenv {\"LEIN_USERNAME\" \"flynn\"\n                            \"CUSTOMENV\" \"flotilla\"}]\n        (is (= (resolve-credentials {:url \"https://clojars.org/repo\"\n                                     :username [:gpg :env]\n                                     :password [:env/customenv :gpg]})\n               {:url \"https://clojars.org/repo\"\n                :username \"u\" :password \"flotilla\"}))))\n    (testing \"Custom keys unmolested (and :creds expanded)\"\n      (is (= (resolve-credentials {:url \"https://clojars.org/repo\"\n                                   :creds :gpg\n                                   :foo [:gpg \"0x00D85767\"]})\n             {:url \"https://clojars.org/repo\"\n              :username \"u\" :password \"p\"\n              :passphrase \"looooong\" :private-key-file \"./somewhere\"\n              :foo [:gpg \"0x00D85767\"]})))\n    (testing \"Pulls string out when env/gpg are absent\"\n      (let [settings {:url \"https://clojars.private\"\n                      :username [:gpg :env/circle_jars_username \"ACTUAL\"]}]\n        (is (= \"ACTUAL\" (:username (resolve-credentials settings))))))))\n\n"
  },
  {
    "path": "leiningen-core/test/leiningen/core/test/utils.clj",
    "content": "(ns leiningen.core.test.utils\n  (:require [leiningen.core.utils :as utils]\n            [clojure.test :refer [deftest testing is]]\n            [clojure.java.io :as io]))\n\n(def profiles \"./leiningen-core/test/resources/\")\n\n(def sample-profile {:user {:plugins '[[lein-pprint \"1.1.1\"]]}})\n\n(deftest read-profiles\n  (testing \"Empty profile file\"\n    (is (nil? (with-redefs [println (constantly nil)]\n                (utils/read-file (io/file (str profiles \"profiles-empty.clj\")))))))\n  (testing \"Non-empty profile file\"\n    (is (= (utils/read-file (io/file (str profiles \"profiles.clj\"))) sample-profile))))\n\n(deftest properties-strip-comments\n  (with-open [baos (java.io.ByteArrayOutputStream.)]\n    (let [properties (doto (java.util.Properties.)\n                       (.setProperty \"version\" \"0.1.0-SNAPSHOT\")\n                       (.setProperty \"groupId\" \"groupId\")\n                       (.setProperty \"artifactId\" \"(:name project)\"))]\n      (.store properties baos \"Extra comment\")\n      (let [str (-> baos\n                    str\n                    utils/strip-properties-comments)]\n        (with-open [input-stream (io/input-stream (.getBytes str))]\n          (is (= properties (doto (java.util.Properties.) (.load input-stream)))))))))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/fixed_and_var_args.clj",
    "content": "(ns leiningen.fixed-and-var-args \"Dummy task for tests.\")\n\n(defn fixed-and-var-args [project one two & rest]\n  (println \"a dummy task for tests\"))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/one_or_two.clj",
    "content": "(ns leiningen.one-or-two \"Dummy task for tests\")\n\n(defn one-or-two\n  \"Dummy task for tests\"\n  ([project one])\n  ([project one two]))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/sirius.clj",
    "content": "(ns leiningen.sirius)\n\n(defn ^:pass-through-help sirius [project & args] args)\n"
  },
  {
    "path": "leiningen-core/test/leiningen/var_args.clj",
    "content": "(ns leiningen.var-args \"Dummy task for tests.\")\n\n(defn var-args [project & args]\n  (println \"a dummy task for tests.\"))\n"
  },
  {
    "path": "leiningen-core/test/leiningen/zero.clj",
    "content": "(ns leiningen.zero \"Dummy task for tests.\")\n\n(defn zero [project]\n  (println \"a dummy task for tests\"))\n"
  },
  {
    "path": "leiningen-core/test/resources/profiles-empty.clj",
    "content": ""
  },
  {
    "path": "pcmpl-lein.el",
    "content": ";;; pcmpl-lein.el --- pcomplete for Leiningen tasks; works with eshell\n\n;; Copyright (C) 2011 Phil Hagelberg\n;;\n;; Author: Phil Hagelberg\n;; URL: https://github.com/technomancy/leiningen\n;; Version: 0.1\n;; Keywords: eshell completion\n;; Created: 2011-01-15\n\n;; This file is not part of GNU Emacs or Leiningen.\n\n;;; Commentary:\n\n;; Provides completion of leiningen tasks using pcomplete, suitable\n;; for eshell. Does not support custom :source-path or :test-path.\n\n;;; License:\n\n;; This program is free software; you can redistribute it and/or\n;; modify it under the terms of the GNU General Public License\n;; as published by the Free Software Foundation; either version 3\n;; of the License, or (at your option) any later version.\n;;\n;; This program is distributed in the hope that it will be useful,\n;; but WITHOUT ANY WARRANTY; without even the implied warranty of\n;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n;; GNU General Public License for more details.\n;;\n;; You should have received a copy of the GNU General Public License\n;; along with GNU Emacs; see the file COPYING.  If not, write to the\n;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n;; Boston, MA 02110-1301, USA.\n\n;;; Code:\n\n(require 'cl)\n(require 'pcomplete)\n(require 'esh-util)\n\n(defvar pcmpl-lein-tasks-alist nil\n  \"Cached alist of project roots to task lists.\")\n\n(defvar pcmpl-lein-project-root nil)\n\n(defun pcmpl-lein-tasks ()\n  (or (cdr (assoc pcmpl-lein-project-root pcmpl-lein-tasks-alist))\n      (let* ((help (progn (message \"Getting Leiningen task list...\")\n                     (shell-command-to-string \"lein help\")))\n             (tasks (split-string help \"\\n\"))\n             (tasks (subseq tasks 4 -3))\n             (tasks (mapcar (lambda (line)\n                              (substring line 0 (string-match \" \" line)))\n                            tasks)))\n        ;; OHAI MEMOIZE.\n        (add-to-list 'pcmpl-lein-tasks-alist\n                     (cons pcmpl-lein-project-root tasks))\n        tasks)))\n\n(defun pcmpl-lein-namespaces-dir ()\n  (let ((task (cadr pcomplete-args)))\n    (cond ((equal \"test\" task) \"test\")\n          ((or (equal \"run\" task) (equal \"compile\" task)) \"src\"))))\n\n(defun pcmpl-lein-transform-filename (file)\n  (subst-char-in-string ?/ ?.\n                        (substring file (+ (length pcmpl-lein-project-root)\n                                           (length namespaces-dir) 1) -4)))\n\n(defun pcmpl-lein-namespaces-in-dir (file)\n  (if (not (file-directory-p file))\n      (if (string-match \"\\\\.clj$\" file)\n        (pcmpl-lein-transform-filename file))\n    (eshell-flatten-list (mapcar 'pcmpl-lein-namespaces-in-dir\n                                 (directory-files file t \"^[^\\\\.]\")))))\n\n(defun pcmpl-lein-namespaces ()\n  (let ((namespaces-dir (pcmpl-lein-namespaces-dir)))\n    (when namespaces-dir\n      (pcmpl-lein-namespaces-in-dir namespaces-dir))))\n\n;;;###autoload\n(defun pcomplete/lein ()\n  (let ((pcmpl-lein-project-root (expand-file-name\n                                  (locate-dominating-file\n                                   default-directory \"project.clj\"))))\n    (pcomplete-here (pcmpl-lein-tasks))\n    (if (not (string= \"run\" (cadr pcomplete-args)))\n        (pcomplete-here (pcmpl-lein-namespaces))\n      (pcomplete-here (list \"-m\"))\n      (pcomplete-here (pcmpl-lein-namespaces)))))\n\n(provide 'pcmpl-lein)\n;;; pcmpl-lein.el ends here\n"
  },
  {
    "path": "project.clj",
    "content": ";; This is Leiningen's own project configuration. See doc/TUTORIAL.md\n;; file as well as sample.project.clj for help writing your own.\n\n(defproject leiningen \"2.12.0\"\n  :description \"Automate Clojure projects without setting your hair on fire.\"\n  :url \"https://codeberg.org/leiningen/leiningen\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  ;; If you update these, update resources/leiningen/bootclasspath-deps.clj too\n  :dependencies [[leiningen-core \"2.12.0\"]\n                 ;; needed for pom\n                 [org.clojure/data.xml \"0.2.0-alpha6\"]\n                 ;; needed for test\n                 [timofreiberg/bultitude \"0.3.0\"\n                  :exclusions [org.clojure/clojure\n                               org.tcrawley/dynapath]]\n                 ;; needed for new\n                 [stencil \"0.5.0\" :exclusions [org.clojure/core.cache]]\n                 ;; needed for uberjar\n                 [commons-lang \"2.6\"]\n                 ;; needed for repl\n                 [nrepl \"1.3.0\"]\n                 ;; needed for change\n                 [org.clojars.trptcolin/sjacket \"0.1.1.1\"\n                  :exclusions [org.clojure/clojure]]\n                 ;; bump versions of various common transitive deps\n                 [net.cgrand/parsley \"0.9.3\" :exclusions [org.clojure/clojure]]\n                 [scout \"0.1.1\"]\n                 [commons-io \"2.8.0\"]\n                 [commons-codec \"1.15\"]]\n  :pedantic? :abort\n  ;; checkout-deps don't work with :eval-in :leiningen\n  :profiles {:dev {:resource-paths [\"leiningen-core/dev-resources\"]\n                   :test-paths [\"leiningen-core/test\"]}\n             :uberjar {:aot [#\"leiningen\"\n                             leiningen.core.ssl ; lazy-loaded\n                             cemerick.pomegranate\n                             cemerick.pomegranate.aether\n                             classlojure.core\n                             dynapath.dynamic-classpath\n                             dynapath.defaults\n                             dynapath.util\n                             bultitude.core\n                             nrepl.core]}}\n  :test-selectors {:default (complement :disabled)\n                   :offline (comp (partial not-any? identity)\n                                  (juxt :online :disabled))}\n  :source-paths [\"leiningen-core/src\" \"src\"]\n  :eval-in :leiningen)\n"
  },
  {
    "path": "resources/leiningen/bootclasspath-deps.clj",
    "content": ";; This file is used to warn users when they attempt to load a plugin that\n;; pulls in a dependency which conflicts with something already in use\n;; by Leiningen itself.\n\n;; This code regenerates the map\n#_(do (require '[leiningen.core.project :as project])\n      (require '[leiningen.core.classpath :as cp])\n      (require '[clojure.pprint :as pp])\n\n      (defn artifacts [h]\n        (apply concat (keys h) (map artifacts (vals h))))\n\n      (let [hierarchy (cp/managed-dependency-hierarchy :dependencies\n                                                       :managed-dependencies\n                                                       (project/read))]\n        (-> (into (sorted-map-by (fn [x y]\n                                   (compare (str x) (str y))))\n                  (for [[a v] (artifacts hierarchy)]\n                    [a v]))\n            ;; Unhelpful to warn on these:\n            (dissoc 'org.clojure/clojure)\n            (dissoc 'leiningen-core)\n            (pp/pprint))))\n{clj-commons/pomegranate \"1.2.24\",\n com.hypirion/io \"0.3.1\",\n com.jcraft/jsch \"0.1.55\",\n com.jcraft/jsch.agentproxy.connector-factory \"0.0.9\",\n com.jcraft/jsch.agentproxy.core \"0.0.9\",\n com.jcraft/jsch.agentproxy.jsch \"0.0.9\",\n com.jcraft/jsch.agentproxy.pageant \"0.0.9\",\n com.jcraft/jsch.agentproxy.sshagent \"0.0.9\",\n com.jcraft/jsch.agentproxy.usocket-jna \"0.0.9\",\n com.jcraft/jsch.agentproxy.usocket-nc \"0.0.9\",\n commons-codec \"1.15\",\n commons-io \"2.8.0\",\n commons-lang \"2.6\",\n javax.inject \"1\",\n net.cgrand/parsley \"0.9.3\",\n net.cgrand/regex \"1.1.0\",\n net.java.dev.jna/jna \"4.1.0\",\n net.java.dev.jna/jna-platform \"4.1.0\",\n nrepl \"1.3.0\",\n org.apache.commons/commons-lang3 \"3.12.0\",\n org.apache.httpcomponents/httpclient \"4.5.14\",\n org.apache.httpcomponents/httpcore \"4.4.16\",\n org.apache.maven.resolver/maven-resolver-api \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-connector-basic \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-impl \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-named-locks \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-spi \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-transport-file \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-transport-http \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-transport-wagon \"1.9.4\",\n org.apache.maven.resolver/maven-resolver-util \"1.9.4\",\n org.apache.maven.wagon/wagon-http \"3.5.3\",\n org.apache.maven.wagon/wagon-http-shared \"3.5.3\",\n org.apache.maven.wagon/wagon-provider-api \"3.5.3\",\n org.apache.maven.wagon/wagon-ssh \"3.5.3\",\n org.apache.maven.wagon/wagon-ssh-common \"3.5.3\",\n org.apache.maven/maven-artifact \"3.8.7\",\n org.apache.maven/maven-builder-support \"3.8.7\",\n org.apache.maven/maven-model \"3.8.7\",\n org.apache.maven/maven-model-builder \"3.8.7\",\n org.apache.maven/maven-repository-metadata \"3.8.7\",\n org.apache.maven/maven-resolver-provider \"3.8.7\",\n org.clojars.trptcolin/sjacket \"0.1.1.1\",\n org.clojure/core.specs.alpha \"0.2.62\",\n org.clojure/data.codec \"0.1.0\",\n org.clojure/data.xml \"0.2.0-alpha6\",\n org.clojure/spec.alpha \"0.3.218\",\n org.clojure/tools.macro \"0.1.5\",\n org.codehaus.plexus/plexus-interactivity-api \"1.1\",\n org.codehaus.plexus/plexus-interpolation \"1.26\",\n org.codehaus.plexus/plexus-utils \"3.3.1\",\n org.eclipse.sisu/org.eclipse.sisu.inject \"0.3.5\",\n org.flatland/classlojure \"0.7.1\",\n org.nrepl/incomplete \"0.1.0\",\n org.slf4j/jcl-over-slf4j \"1.7.36\",\n org.slf4j/slf4j-api \"1.7.25\",\n org.slf4j/slf4j-nop \"1.7.25\",\n org.tcrawley/dynapath \"1.1.0\",\n quoin \"0.1.2\",\n robert/hooke \"1.3.0\",\n scout \"0.1.1\",\n stencil \"0.5.0\",\n timofreiberg/bultitude \"0.3.0\"}\n"
  },
  {
    "path": "resources/leiningen/new/app/CHANGELOG.md",
    "content": "# Change Log\nAll notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](https://keepachangelog.com/).\n\n## [Unreleased]\n### Changed\n- Add a new arity to `make-widget-async` to provide a different widget shape.\n\n## [0.1.1] - {{date}}\n### Changed\n- Documentation on how to make the widgets.\n\n### Removed\n- `make-widget-sync` - we're all async, all the time.\n\n### Fixed\n- Fixed widget maker to keep working when daylight savings switches over.\n\n## 0.1.0 - {{date}}\n### Added\n- Files from the new template.\n- Widget maker public API - `make-widget-sync`.\n\n[Unreleased]: https://sourcehost.site/your-name/{{name}}/compare/0.1.1...HEAD\n[0.1.1]: https://sourcehost.site/your-name/{{name}}/compare/0.1.0...0.1.1\n"
  },
  {
    "path": "resources/leiningen/new/app/LICENSE",
    "content": "Eclipse Public License - v 2.0\n\n    THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE\n    PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION\n    OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\n  a) in the case of the initial Contributor, the initial content\n     Distributed under this Agreement, and\n\n  b) in the case of each subsequent Contributor:\n     i) changes to the Program, and\n     ii) additions to the Program;\n  where such changes and/or additions to the Program originate from\n  and are Distributed by that particular Contributor. A Contribution\n  \"originates\" from a Contributor if it was added to the Program by\n  such Contributor itself or anyone acting on such Contributor's behalf.\n  Contributions do not include changes or additions to the Program that\n  are not Modified Works.\n\n\"Contributor\" means any person or entity that Distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which\nare necessarily infringed by the use or sale of its Contribution alone\nor when combined with the Program.\n\n\"Program\" means the Contributions Distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement\nor any Secondary License (as applicable), including Contributors.\n\n\"Derivative Works\" shall mean any work, whether in Source Code or other\nform, that is based on (or derived from) the Program and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship.\n\n\"Modified Works\" shall mean any work in Source Code or other form that\nresults from an addition to, deletion from, or modification of the\ncontents of the Program, including, for purposes of clarity any new file\nin Source Code form that contains any contents of the Program. Modified\nWorks shall not include works that contain only declarations,\ninterfaces, types, classes, structures, or files of the Program solely\nin each case in order to link to, bind by name, or subclass the Program\nor Modified Works thereof.\n\n\"Distribute\" means the acts of a) distributing or b) making available\nin any manner that enables the transfer of a copy.\n\n\"Source Code\" means the form of a Program preferred for making\nmodifications, including but not limited to software source code,\ndocumentation source, and configuration files.\n\n\"Secondary License\" means either the GNU General Public License,\nVersion 2.0, or any later versions of that license, including any\nexceptions or additional permissions as identified by the initial\nContributor.\n\n2. GRANT OF RIGHTS\n\n  a) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free copyright\n  license to reproduce, prepare Derivative Works of, publicly display,\n  publicly perform, Distribute and sublicense the Contribution of such\n  Contributor, if any, and such Derivative Works.\n\n  b) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free patent\n  license under Licensed Patents to make, use, sell, offer to sell,\n  import and otherwise transfer the Contribution of such Contributor,\n  if any, in Source Code or other form. This patent license shall\n  apply to the combination of the Contribution and the Program if, at\n  the time the Contribution is added by the Contributor, such addition\n  of the Contribution causes such combination to be covered by the\n  Licensed Patents. The patent license shall not apply to any other\n  combinations which include the Contribution. No hardware per se is\n  licensed hereunder.\n\n  c) Recipient understands that although each Contributor grants the\n  licenses to its Contributions set forth herein, no assurances are\n  provided by any Contributor that the Program does not infringe the\n  patent or other intellectual property rights of any other entity.\n  Each Contributor disclaims any liability to Recipient for claims\n  brought by any other entity based on infringement of intellectual\n  property rights or otherwise. As a condition to exercising the\n  rights and licenses granted hereunder, each Recipient hereby\n  assumes sole responsibility to secure any other intellectual\n  property rights needed, if any. For example, if a third party\n  patent license is required to allow Recipient to Distribute the\n  Program, it is Recipient's responsibility to acquire that license\n  before distributing the Program.\n\n  d) Each Contributor represents that to its knowledge it has\n  sufficient copyright rights in its Contribution, if any, to grant\n  the copyright license set forth in this Agreement.\n\n  e) Notwithstanding the terms of any Secondary License, no\n  Contributor makes additional grants to any Recipient (other than\n  those set forth in this Agreement) as a result of such Recipient's\n  receipt of the Program under the terms of a Secondary License\n  (if permitted under the terms of Section 3).\n\n3. REQUIREMENTS\n\n3.1 If a Contributor Distributes the Program in any form, then:\n\n  a) the Program must also be made available as Source Code, in\n  accordance with section 3.2, and the Contributor must accompany\n  the Program with a statement that the Source Code for the Program\n  is available under this Agreement, and informs Recipients how to\n  obtain it in a reasonable manner on or through a medium customarily\n  used for software exchange; and\n\n  b) the Contributor may Distribute the Program under a license\n  different than this Agreement, provided that such license:\n     i) effectively disclaims on behalf of all other Contributors all\n     warranties and conditions, express and implied, including\n     warranties or conditions of title and non-infringement, and\n     implied warranties or conditions of merchantability and fitness\n     for a particular purpose;\n\n     ii) effectively excludes on behalf of all other Contributors all\n     liability for damages, including direct, indirect, special,\n     incidental and consequential damages, such as lost profits;\n\n     iii) does not attempt to limit or alter the recipients' rights\n     in the Source Code under section 3.2; and\n\n     iv) requires any subsequent distribution of the Program by any\n     party to be under a license that satisfies the requirements\n     of this section 3.\n\n3.2 When the Program is Distributed as Source Code:\n\n  a) it must be made available under this Agreement, or if the\n  Program (i) is combined with other material in a separate file or\n  files made available under a Secondary License, and (ii) the initial\n  Contributor attached to the Source Code the notice described in\n  Exhibit A of this Agreement, then the Program may be made available\n  under the terms of such Secondary Licenses, and\n\n  b) a copy of this Agreement must be included with each copy of\n  the Program.\n\n3.3 Contributors may not remove or alter any copyright, patent,\ntrademark, attribution notices, disclaimers of warranty, or limitations\nof liability (\"notices\") contained within the Program from any copy of\nthe Program which they Distribute, provided that Contributors may add\ntheir own appropriate notices.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities\nwith respect to end users, business partners and the like. While this\nlicense is intended to facilitate the commercial use of the Program,\nthe Contributor who includes the Program in a commercial product\noffering should do so in a manner which does not create potential\nliability for other Contributors. Therefore, if a Contributor includes\nthe Program in a commercial product offering, such Contributor\n(\"Commercial Contributor\") hereby agrees to defend and indemnify every\nother Contributor (\"Indemnified Contributor\") against any losses,\ndamages and costs (collectively \"Losses\") arising from claims, lawsuits\nand other legal actions brought by a third party against the Indemnified\nContributor to the extent caused by the acts or omissions of such\nCommercial Contributor in connection with its distribution of the Program\nin a commercial product offering. The obligations in this section do not\napply to any claims or Losses relating to any actual or alleged\nintellectual property infringement. In order to qualify, an Indemnified\nContributor must: a) promptly notify the Commercial Contributor in\nwriting of such claim, and b) allow the Commercial Contributor to control,\nand cooperate with the Commercial Contributor in, the defense and any\nrelated settlement negotiations. The Indemnified Contributor may\nparticipate in any such claim at its own expense.\n\nFor example, a Contributor might include the Program in a commercial\nproduct offering, Product X. That Contributor is then a Commercial\nContributor. If that Commercial Contributor then makes performance\nclaims, or offers warranties related to Product X, those performance\nclaims and warranties are such Commercial Contributor's responsibility\nalone. Under this section, the Commercial Contributor would have to\ndefend claims against the other Contributors related to those performance\nclaims and warranties, and if a court requires any other Contributor to\npay any damages as a result, the Commercial Contributor must pay\nthose damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN \"AS IS\"\nBASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR\nIMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF\nTITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR\nPURPOSE. Each Recipient is solely responsible for determining the\nappropriateness of using and distributing the Program and assumes all\nrisks associated with its exercise of rights under this Agreement,\nincluding but not limited to the risks and costs of program errors,\ncompliance with applicable laws, damage to or loss of data, programs\nor equipment, and unavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS\nSHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST\nPROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of\nthe remainder of the terms of this Agreement, and without further\naction by the parties hereto, such provision shall be reformed to the\nminimum extent necessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity\n(including a cross-claim or counterclaim in a lawsuit) alleging that the\nProgram itself (excluding combinations of the Program with other software\nor hardware) infringes such Recipient's patent(s), then such Recipient's\nrights granted under Section 2(b) shall terminate as of the date such\nlitigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it\nfails to comply with any of the material terms or conditions of this\nAgreement and does not cure such failure in a reasonable period of\ntime after becoming aware of such noncompliance. If all Recipient's\nrights under this Agreement terminate, Recipient agrees to cease use\nand distribution of the Program as soon as reasonably practicable.\nHowever, Recipient's obligations under this Agreement and any licenses\ngranted by Recipient relating to the Program shall continue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement,\nbut in order to avoid inconsistency the Agreement is copyrighted and\nmay only be modified in the following manner. The Agreement Steward\nreserves the right to publish new versions (including revisions) of\nthis Agreement from time to time. No one other than the Agreement\nSteward has the right to modify this Agreement. The Eclipse Foundation\nis the initial Agreement Steward. The Eclipse Foundation may assign the\nresponsibility to serve as the Agreement Steward to a suitable separate\nentity. Each new version of the Agreement will be given a distinguishing\nversion number. The Program (including Contributions) may always be\nDistributed subject to the version of the Agreement under which it was\nreceived. In addition, after a new version of the Agreement is published,\nContributor may elect to Distribute the Program (including its\nContributions) under the new version.\n\nExcept as expressly stated in Sections 2(a) and 2(b) above, Recipient\nreceives no rights or licenses to the intellectual property of any\nContributor under this Agreement, whether expressly, by implication,\nestoppel or otherwise. All rights in the Program not expressly granted\nunder this Agreement are reserved. Nothing in this Agreement is intended\nto be enforceable by any entity that is not a Contributor or Recipient.\nNo third-party beneficiary rights are created under this Agreement.\n\nExhibit A - Form of Secondary Licenses Notice\n\n\"This Source Code may also be made available under the following\nSecondary Licenses when the conditions for such availability set forth\nin the Eclipse Public License, v. 2.0 are satisfied: GNU General Public\nLicense as published by the Free Software Foundation, either version 2\nof the License, or (at your option) any later version, with the GNU\nClasspath Exception which is available at\nhttps://www.gnu.org/software/classpath/license.html.\"\n\n  Simply including a copy of this Agreement, including this Exhibit A\n  is not sufficient to license the Source Code under Secondary Licenses.\n\n  If it is not possible or desirable to put the notice in a particular\n  file, then You may include the notice in a location (such as a LICENSE\n  file in a relevant directory) where a recipient would be likely to\n  look for such a notice.\n\n  You may add additional accurate notices of copyright ownership."
  },
  {
    "path": "resources/leiningen/new/app/README.md",
    "content": "# {{name}}\n\nFIXME: description\n\n## Installation\n\nDownload from https://example.com/FIXME.\n\n## Usage\n\nFIXME: explanation\n\n    $ java -jar {{name}}-0.1.0-standalone.jar [args]\n\n## Options\n\nFIXME: listing of options this app accepts.\n\n## Examples\n\n...\n\n### Bugs\n\n...\n\n### Any Other Sections\n### That You Think\n### Might be Useful\n\n## License\n\nCopyright © {{year}} FIXME\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\nhttps://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat https://www.gnu.org/software/classpath/license.html.\n"
  },
  {
    "path": "resources/leiningen/new/app/core.clj",
    "content": "(ns {{namespace}}\n  (:gen-class))\n\n(defn -main\n  \"I don't do a whole lot ... yet.\"\n  [& args]\n  (println \"Hello, World!\"))\n"
  },
  {
    "path": "resources/leiningen/new/app/gitignore",
    "content": "/target\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.hgignore\n.hg/\n"
  },
  {
    "path": "resources/leiningen/new/app/hgignore",
    "content": "syntax: glob\npom.xml\npom.xml.asc\n*.jar\n*.class\n.gitignore\n.git/**\n\nsyntax: regexp\n^.nrepl-port\n^.prepl-port\n^.lein-.*\n^target/\n^classes/\n^checkouts/\nprofiles.clj\n"
  },
  {
    "path": "resources/leiningen/new/app/intro.md",
    "content": "# Introduction to {{name}}\n\nTODO: write [great documentation](https://jacobian.org/writing/what-to-write/)\n"
  },
  {
    "path": "resources/leiningen/new/app/project.clj",
    "content": "(defproject {{raw-name}} \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0\"\n            :url \"https://www.eclipse.org/legal/epl-2.0/\"}\n  :dependencies [[org.clojure/clojure \"1.12.2\"]]\n  :main ^:skip-aot {{namespace}}\n  :target-path \"target/%s\"\n  :profiles {:uberjar {:aot :all\n                       :jvm-opts [\"-Dclojure.compiler.direct-linking=true\"]}})\n"
  },
  {
    "path": "resources/leiningen/new/app/test.clj",
    "content": "(ns {{namespace}}-test\n  (:require [clojure.test :refer :all]\n            [{{namespace}} :refer :all]))\n\n(deftest a-test\n  (testing \"FIXME, I fail.\"\n    (is (= 0 1))))\n"
  },
  {
    "path": "resources/leiningen/new/default/CHANGELOG.md",
    "content": "# Change Log\nAll notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](https://keepachangelog.com/).\n\n## [Unreleased]\n### Changed\n- Add a new arity to `make-widget-async` to provide a different widget shape.\n\n## [0.1.1] - {{date}}\n### Changed\n- Documentation on how to make the widgets.\n\n### Removed\n- `make-widget-sync` - we're all async, all the time.\n\n### Fixed\n- Fixed widget maker to keep working when daylight savings switches over.\n\n## 0.1.0 - {{date}}\n### Added\n- Files from the new template.\n- Widget maker public API - `make-widget-sync`.\n\n[Unreleased]: https://sourcehost.site/your-name/{{name}}/compare/0.1.1...HEAD\n[0.1.1]: https://sourcehost.site/your-name/{{name}}/compare/0.1.0...0.1.1\n"
  },
  {
    "path": "resources/leiningen/new/default/LICENSE",
    "content": "Eclipse Public License - v 2.0\n\n    THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE\n    PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION\n    OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\n  a) in the case of the initial Contributor, the initial content\n     Distributed under this Agreement, and\n\n  b) in the case of each subsequent Contributor:\n     i) changes to the Program, and\n     ii) additions to the Program;\n  where such changes and/or additions to the Program originate from\n  and are Distributed by that particular Contributor. A Contribution\n  \"originates\" from a Contributor if it was added to the Program by\n  such Contributor itself or anyone acting on such Contributor's behalf.\n  Contributions do not include changes or additions to the Program that\n  are not Modified Works.\n\n\"Contributor\" means any person or entity that Distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which\nare necessarily infringed by the use or sale of its Contribution alone\nor when combined with the Program.\n\n\"Program\" means the Contributions Distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement\nor any Secondary License (as applicable), including Contributors.\n\n\"Derivative Works\" shall mean any work, whether in Source Code or other\nform, that is based on (or derived from) the Program and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship.\n\n\"Modified Works\" shall mean any work in Source Code or other form that\nresults from an addition to, deletion from, or modification of the\ncontents of the Program, including, for purposes of clarity any new file\nin Source Code form that contains any contents of the Program. Modified\nWorks shall not include works that contain only declarations,\ninterfaces, types, classes, structures, or files of the Program solely\nin each case in order to link to, bind by name, or subclass the Program\nor Modified Works thereof.\n\n\"Distribute\" means the acts of a) distributing or b) making available\nin any manner that enables the transfer of a copy.\n\n\"Source Code\" means the form of a Program preferred for making\nmodifications, including but not limited to software source code,\ndocumentation source, and configuration files.\n\n\"Secondary License\" means either the GNU General Public License,\nVersion 2.0, or any later versions of that license, including any\nexceptions or additional permissions as identified by the initial\nContributor.\n\n2. GRANT OF RIGHTS\n\n  a) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free copyright\n  license to reproduce, prepare Derivative Works of, publicly display,\n  publicly perform, Distribute and sublicense the Contribution of such\n  Contributor, if any, and such Derivative Works.\n\n  b) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free patent\n  license under Licensed Patents to make, use, sell, offer to sell,\n  import and otherwise transfer the Contribution of such Contributor,\n  if any, in Source Code or other form. This patent license shall\n  apply to the combination of the Contribution and the Program if, at\n  the time the Contribution is added by the Contributor, such addition\n  of the Contribution causes such combination to be covered by the\n  Licensed Patents. The patent license shall not apply to any other\n  combinations which include the Contribution. No hardware per se is\n  licensed hereunder.\n\n  c) Recipient understands that although each Contributor grants the\n  licenses to its Contributions set forth herein, no assurances are\n  provided by any Contributor that the Program does not infringe the\n  patent or other intellectual property rights of any other entity.\n  Each Contributor disclaims any liability to Recipient for claims\n  brought by any other entity based on infringement of intellectual\n  property rights or otherwise. As a condition to exercising the\n  rights and licenses granted hereunder, each Recipient hereby\n  assumes sole responsibility to secure any other intellectual\n  property rights needed, if any. For example, if a third party\n  patent license is required to allow Recipient to Distribute the\n  Program, it is Recipient's responsibility to acquire that license\n  before distributing the Program.\n\n  d) Each Contributor represents that to its knowledge it has\n  sufficient copyright rights in its Contribution, if any, to grant\n  the copyright license set forth in this Agreement.\n\n  e) Notwithstanding the terms of any Secondary License, no\n  Contributor makes additional grants to any Recipient (other than\n  those set forth in this Agreement) as a result of such Recipient's\n  receipt of the Program under the terms of a Secondary License\n  (if permitted under the terms of Section 3).\n\n3. REQUIREMENTS\n\n3.1 If a Contributor Distributes the Program in any form, then:\n\n  a) the Program must also be made available as Source Code, in\n  accordance with section 3.2, and the Contributor must accompany\n  the Program with a statement that the Source Code for the Program\n  is available under this Agreement, and informs Recipients how to\n  obtain it in a reasonable manner on or through a medium customarily\n  used for software exchange; and\n\n  b) the Contributor may Distribute the Program under a license\n  different than this Agreement, provided that such license:\n     i) effectively disclaims on behalf of all other Contributors all\n     warranties and conditions, express and implied, including\n     warranties or conditions of title and non-infringement, and\n     implied warranties or conditions of merchantability and fitness\n     for a particular purpose;\n\n     ii) effectively excludes on behalf of all other Contributors all\n     liability for damages, including direct, indirect, special,\n     incidental and consequential damages, such as lost profits;\n\n     iii) does not attempt to limit or alter the recipients' rights\n     in the Source Code under section 3.2; and\n\n     iv) requires any subsequent distribution of the Program by any\n     party to be under a license that satisfies the requirements\n     of this section 3.\n\n3.2 When the Program is Distributed as Source Code:\n\n  a) it must be made available under this Agreement, or if the\n  Program (i) is combined with other material in a separate file or\n  files made available under a Secondary License, and (ii) the initial\n  Contributor attached to the Source Code the notice described in\n  Exhibit A of this Agreement, then the Program may be made available\n  under the terms of such Secondary Licenses, and\n\n  b) a copy of this Agreement must be included with each copy of\n  the Program.\n\n3.3 Contributors may not remove or alter any copyright, patent,\ntrademark, attribution notices, disclaimers of warranty, or limitations\nof liability (\"notices\") contained within the Program from any copy of\nthe Program which they Distribute, provided that Contributors may add\ntheir own appropriate notices.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities\nwith respect to end users, business partners and the like. While this\nlicense is intended to facilitate the commercial use of the Program,\nthe Contributor who includes the Program in a commercial product\noffering should do so in a manner which does not create potential\nliability for other Contributors. Therefore, if a Contributor includes\nthe Program in a commercial product offering, such Contributor\n(\"Commercial Contributor\") hereby agrees to defend and indemnify every\nother Contributor (\"Indemnified Contributor\") against any losses,\ndamages and costs (collectively \"Losses\") arising from claims, lawsuits\nand other legal actions brought by a third party against the Indemnified\nContributor to the extent caused by the acts or omissions of such\nCommercial Contributor in connection with its distribution of the Program\nin a commercial product offering. The obligations in this section do not\napply to any claims or Losses relating to any actual or alleged\nintellectual property infringement. In order to qualify, an Indemnified\nContributor must: a) promptly notify the Commercial Contributor in\nwriting of such claim, and b) allow the Commercial Contributor to control,\nand cooperate with the Commercial Contributor in, the defense and any\nrelated settlement negotiations. The Indemnified Contributor may\nparticipate in any such claim at its own expense.\n\nFor example, a Contributor might include the Program in a commercial\nproduct offering, Product X. That Contributor is then a Commercial\nContributor. If that Commercial Contributor then makes performance\nclaims, or offers warranties related to Product X, those performance\nclaims and warranties are such Commercial Contributor's responsibility\nalone. Under this section, the Commercial Contributor would have to\ndefend claims against the other Contributors related to those performance\nclaims and warranties, and if a court requires any other Contributor to\npay any damages as a result, the Commercial Contributor must pay\nthose damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN \"AS IS\"\nBASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR\nIMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF\nTITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR\nPURPOSE. Each Recipient is solely responsible for determining the\nappropriateness of using and distributing the Program and assumes all\nrisks associated with its exercise of rights under this Agreement,\nincluding but not limited to the risks and costs of program errors,\ncompliance with applicable laws, damage to or loss of data, programs\nor equipment, and unavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS\nSHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST\nPROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of\nthe remainder of the terms of this Agreement, and without further\naction by the parties hereto, such provision shall be reformed to the\nminimum extent necessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity\n(including a cross-claim or counterclaim in a lawsuit) alleging that the\nProgram itself (excluding combinations of the Program with other software\nor hardware) infringes such Recipient's patent(s), then such Recipient's\nrights granted under Section 2(b) shall terminate as of the date such\nlitigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it\nfails to comply with any of the material terms or conditions of this\nAgreement and does not cure such failure in a reasonable period of\ntime after becoming aware of such noncompliance. If all Recipient's\nrights under this Agreement terminate, Recipient agrees to cease use\nand distribution of the Program as soon as reasonably practicable.\nHowever, Recipient's obligations under this Agreement and any licenses\ngranted by Recipient relating to the Program shall continue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement,\nbut in order to avoid inconsistency the Agreement is copyrighted and\nmay only be modified in the following manner. The Agreement Steward\nreserves the right to publish new versions (including revisions) of\nthis Agreement from time to time. No one other than the Agreement\nSteward has the right to modify this Agreement. The Eclipse Foundation\nis the initial Agreement Steward. The Eclipse Foundation may assign the\nresponsibility to serve as the Agreement Steward to a suitable separate\nentity. Each new version of the Agreement will be given a distinguishing\nversion number. The Program (including Contributions) may always be\nDistributed subject to the version of the Agreement under which it was\nreceived. In addition, after a new version of the Agreement is published,\nContributor may elect to Distribute the Program (including its\nContributions) under the new version.\n\nExcept as expressly stated in Sections 2(a) and 2(b) above, Recipient\nreceives no rights or licenses to the intellectual property of any\nContributor under this Agreement, whether expressly, by implication,\nestoppel or otherwise. All rights in the Program not expressly granted\nunder this Agreement are reserved. Nothing in this Agreement is intended\nto be enforceable by any entity that is not a Contributor or Recipient.\nNo third-party beneficiary rights are created under this Agreement.\n\nExhibit A - Form of Secondary Licenses Notice\n\n\"This Source Code may also be made available under the following\nSecondary Licenses when the conditions for such availability set forth\nin the Eclipse Public License, v. 2.0 are satisfied: GNU General Public\nLicense as published by the Free Software Foundation, either version 2\nof the License, or (at your option) any later version, with the GNU\nClasspath Exception which is available at\nhttps://www.gnu.org/software/classpath/license.html.\"\n\n  Simply including a copy of this Agreement, including this Exhibit A\n  is not sufficient to license the Source Code under Secondary Licenses.\n\n  If it is not possible or desirable to put the notice in a particular\n  file, then You may include the notice in a location (such as a LICENSE\n  file in a relevant directory) where a recipient would be likely to\n  look for such a notice.\n\n  You may add additional accurate notices of copyright ownership."
  },
  {
    "path": "resources/leiningen/new/default/README.md",
    "content": "# {{name}}\n\nA Clojure library designed to ... well, that part is up to you.\n\n## Usage\n\nFIXME\n\n## License\n\nCopyright © {{year}} FIXME\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\nhttps://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat https://www.gnu.org/software/classpath/license.html.\n"
  },
  {
    "path": "resources/leiningen/new/default/core.clj",
    "content": "(ns {{namespace}})\n\n(defn foo\n  \"I don't do a whole lot.\"\n  [x]\n  (println x \"Hello, World!\"))\n"
  },
  {
    "path": "resources/leiningen/new/default/gitignore",
    "content": "/target\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.hgignore\n.hg/\n"
  },
  {
    "path": "resources/leiningen/new/default/hgignore",
    "content": "syntax: glob\ntarget/**\nclasses/**\ncheckouts/**\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.gitignore\n.git/**\n"
  },
  {
    "path": "resources/leiningen/new/default/intro.md",
    "content": "# Introduction to {{name}}\n\nTODO: write [great documentation](https://jacobian.org/writing/what-to-write/)\n"
  },
  {
    "path": "resources/leiningen/new/default/project.clj",
    "content": "(defproject {{raw-name}} \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0\"\n            :url \"https://www.eclipse.org/legal/epl-2.0/\"}\n  :dependencies [[org.clojure/clojure \"1.12.2\"]]\n  :repl-options {:init-ns {{namespace}}})\n"
  },
  {
    "path": "resources/leiningen/new/default/test.clj",
    "content": "(ns {{namespace}}-test\n  (:require [clojure.test :refer :all]\n            [{{namespace}} :refer :all]))\n\n(deftest a-test\n  (testing \"FIXME, I fail.\"\n    (is (= 0 1))))\n"
  },
  {
    "path": "resources/leiningen/new/plugin/CHANGELOG.md",
    "content": "# Change Log\nAll notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](https://keepachangelog.com/).\n\n## [Unreleased]\n### Changed\n- Add a new arity to `make-widget-async` to provide a different widget shape.\n\n## [0.1.1] - {{date}}\n### Changed\n- Documentation on how to make the widgets.\n\n### Removed\n- `make-widget-sync` - we're all async, all the time.\n\n### Fixed\n- Fixed widget maker to keep working when daylight savings switches over.\n\n## 0.1.0 - {{date}}\n### Added\n- Files from the new template.\n- Widget maker public API - `make-widget-sync`.\n\n[Unreleased]: https://sourcehost.site/your-name/{{name}}/compare/0.1.1...HEAD\n[0.1.1]: https://sourcehost.site/your-name/{{name}}/compare/0.1.0...0.1.1\n"
  },
  {
    "path": "resources/leiningen/new/plugin/LICENSE",
    "content": "Eclipse Public License - v 2.0\n\n    THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE\n    PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION\n    OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\n  a) in the case of the initial Contributor, the initial content\n     Distributed under this Agreement, and\n\n  b) in the case of each subsequent Contributor:\n     i) changes to the Program, and\n     ii) additions to the Program;\n  where such changes and/or additions to the Program originate from\n  and are Distributed by that particular Contributor. A Contribution\n  \"originates\" from a Contributor if it was added to the Program by\n  such Contributor itself or anyone acting on such Contributor's behalf.\n  Contributions do not include changes or additions to the Program that\n  are not Modified Works.\n\n\"Contributor\" means any person or entity that Distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which\nare necessarily infringed by the use or sale of its Contribution alone\nor when combined with the Program.\n\n\"Program\" means the Contributions Distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement\nor any Secondary License (as applicable), including Contributors.\n\n\"Derivative Works\" shall mean any work, whether in Source Code or other\nform, that is based on (or derived from) the Program and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship.\n\n\"Modified Works\" shall mean any work in Source Code or other form that\nresults from an addition to, deletion from, or modification of the\ncontents of the Program, including, for purposes of clarity any new file\nin Source Code form that contains any contents of the Program. Modified\nWorks shall not include works that contain only declarations,\ninterfaces, types, classes, structures, or files of the Program solely\nin each case in order to link to, bind by name, or subclass the Program\nor Modified Works thereof.\n\n\"Distribute\" means the acts of a) distributing or b) making available\nin any manner that enables the transfer of a copy.\n\n\"Source Code\" means the form of a Program preferred for making\nmodifications, including but not limited to software source code,\ndocumentation source, and configuration files.\n\n\"Secondary License\" means either the GNU General Public License,\nVersion 2.0, or any later versions of that license, including any\nexceptions or additional permissions as identified by the initial\nContributor.\n\n2. GRANT OF RIGHTS\n\n  a) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free copyright\n  license to reproduce, prepare Derivative Works of, publicly display,\n  publicly perform, Distribute and sublicense the Contribution of such\n  Contributor, if any, and such Derivative Works.\n\n  b) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free patent\n  license under Licensed Patents to make, use, sell, offer to sell,\n  import and otherwise transfer the Contribution of such Contributor,\n  if any, in Source Code or other form. This patent license shall\n  apply to the combination of the Contribution and the Program if, at\n  the time the Contribution is added by the Contributor, such addition\n  of the Contribution causes such combination to be covered by the\n  Licensed Patents. The patent license shall not apply to any other\n  combinations which include the Contribution. No hardware per se is\n  licensed hereunder.\n\n  c) Recipient understands that although each Contributor grants the\n  licenses to its Contributions set forth herein, no assurances are\n  provided by any Contributor that the Program does not infringe the\n  patent or other intellectual property rights of any other entity.\n  Each Contributor disclaims any liability to Recipient for claims\n  brought by any other entity based on infringement of intellectual\n  property rights or otherwise. As a condition to exercising the\n  rights and licenses granted hereunder, each Recipient hereby\n  assumes sole responsibility to secure any other intellectual\n  property rights needed, if any. For example, if a third party\n  patent license is required to allow Recipient to Distribute the\n  Program, it is Recipient's responsibility to acquire that license\n  before distributing the Program.\n\n  d) Each Contributor represents that to its knowledge it has\n  sufficient copyright rights in its Contribution, if any, to grant\n  the copyright license set forth in this Agreement.\n\n  e) Notwithstanding the terms of any Secondary License, no\n  Contributor makes additional grants to any Recipient (other than\n  those set forth in this Agreement) as a result of such Recipient's\n  receipt of the Program under the terms of a Secondary License\n  (if permitted under the terms of Section 3).\n\n3. REQUIREMENTS\n\n3.1 If a Contributor Distributes the Program in any form, then:\n\n  a) the Program must also be made available as Source Code, in\n  accordance with section 3.2, and the Contributor must accompany\n  the Program with a statement that the Source Code for the Program\n  is available under this Agreement, and informs Recipients how to\n  obtain it in a reasonable manner on or through a medium customarily\n  used for software exchange; and\n\n  b) the Contributor may Distribute the Program under a license\n  different than this Agreement, provided that such license:\n     i) effectively disclaims on behalf of all other Contributors all\n     warranties and conditions, express and implied, including\n     warranties or conditions of title and non-infringement, and\n     implied warranties or conditions of merchantability and fitness\n     for a particular purpose;\n\n     ii) effectively excludes on behalf of all other Contributors all\n     liability for damages, including direct, indirect, special,\n     incidental and consequential damages, such as lost profits;\n\n     iii) does not attempt to limit or alter the recipients' rights\n     in the Source Code under section 3.2; and\n\n     iv) requires any subsequent distribution of the Program by any\n     party to be under a license that satisfies the requirements\n     of this section 3.\n\n3.2 When the Program is Distributed as Source Code:\n\n  a) it must be made available under this Agreement, or if the\n  Program (i) is combined with other material in a separate file or\n  files made available under a Secondary License, and (ii) the initial\n  Contributor attached to the Source Code the notice described in\n  Exhibit A of this Agreement, then the Program may be made available\n  under the terms of such Secondary Licenses, and\n\n  b) a copy of this Agreement must be included with each copy of\n  the Program.\n\n3.3 Contributors may not remove or alter any copyright, patent,\ntrademark, attribution notices, disclaimers of warranty, or limitations\nof liability (\"notices\") contained within the Program from any copy of\nthe Program which they Distribute, provided that Contributors may add\ntheir own appropriate notices.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities\nwith respect to end users, business partners and the like. While this\nlicense is intended to facilitate the commercial use of the Program,\nthe Contributor who includes the Program in a commercial product\noffering should do so in a manner which does not create potential\nliability for other Contributors. Therefore, if a Contributor includes\nthe Program in a commercial product offering, such Contributor\n(\"Commercial Contributor\") hereby agrees to defend and indemnify every\nother Contributor (\"Indemnified Contributor\") against any losses,\ndamages and costs (collectively \"Losses\") arising from claims, lawsuits\nand other legal actions brought by a third party against the Indemnified\nContributor to the extent caused by the acts or omissions of such\nCommercial Contributor in connection with its distribution of the Program\nin a commercial product offering. The obligations in this section do not\napply to any claims or Losses relating to any actual or alleged\nintellectual property infringement. In order to qualify, an Indemnified\nContributor must: a) promptly notify the Commercial Contributor in\nwriting of such claim, and b) allow the Commercial Contributor to control,\nand cooperate with the Commercial Contributor in, the defense and any\nrelated settlement negotiations. The Indemnified Contributor may\nparticipate in any such claim at its own expense.\n\nFor example, a Contributor might include the Program in a commercial\nproduct offering, Product X. That Contributor is then a Commercial\nContributor. If that Commercial Contributor then makes performance\nclaims, or offers warranties related to Product X, those performance\nclaims and warranties are such Commercial Contributor's responsibility\nalone. Under this section, the Commercial Contributor would have to\ndefend claims against the other Contributors related to those performance\nclaims and warranties, and if a court requires any other Contributor to\npay any damages as a result, the Commercial Contributor must pay\nthose damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN \"AS IS\"\nBASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR\nIMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF\nTITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR\nPURPOSE. Each Recipient is solely responsible for determining the\nappropriateness of using and distributing the Program and assumes all\nrisks associated with its exercise of rights under this Agreement,\nincluding but not limited to the risks and costs of program errors,\ncompliance with applicable laws, damage to or loss of data, programs\nor equipment, and unavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS\nSHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST\nPROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of\nthe remainder of the terms of this Agreement, and without further\naction by the parties hereto, such provision shall be reformed to the\nminimum extent necessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity\n(including a cross-claim or counterclaim in a lawsuit) alleging that the\nProgram itself (excluding combinations of the Program with other software\nor hardware) infringes such Recipient's patent(s), then such Recipient's\nrights granted under Section 2(b) shall terminate as of the date such\nlitigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it\nfails to comply with any of the material terms or conditions of this\nAgreement and does not cure such failure in a reasonable period of\ntime after becoming aware of such noncompliance. If all Recipient's\nrights under this Agreement terminate, Recipient agrees to cease use\nand distribution of the Program as soon as reasonably practicable.\nHowever, Recipient's obligations under this Agreement and any licenses\ngranted by Recipient relating to the Program shall continue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement,\nbut in order to avoid inconsistency the Agreement is copyrighted and\nmay only be modified in the following manner. The Agreement Steward\nreserves the right to publish new versions (including revisions) of\nthis Agreement from time to time. No one other than the Agreement\nSteward has the right to modify this Agreement. The Eclipse Foundation\nis the initial Agreement Steward. The Eclipse Foundation may assign the\nresponsibility to serve as the Agreement Steward to a suitable separate\nentity. Each new version of the Agreement will be given a distinguishing\nversion number. The Program (including Contributions) may always be\nDistributed subject to the version of the Agreement under which it was\nreceived. In addition, after a new version of the Agreement is published,\nContributor may elect to Distribute the Program (including its\nContributions) under the new version.\n\nExcept as expressly stated in Sections 2(a) and 2(b) above, Recipient\nreceives no rights or licenses to the intellectual property of any\nContributor under this Agreement, whether expressly, by implication,\nestoppel or otherwise. All rights in the Program not expressly granted\nunder this Agreement are reserved. Nothing in this Agreement is intended\nto be enforceable by any entity that is not a Contributor or Recipient.\nNo third-party beneficiary rights are created under this Agreement.\n\nExhibit A - Form of Secondary Licenses Notice\n\n\"This Source Code may also be made available under the following\nSecondary Licenses when the conditions for such availability set forth\nin the Eclipse Public License, v. 2.0 are satisfied: GNU General Public\nLicense as published by the Free Software Foundation, either version 2\nof the License, or (at your option) any later version, with the GNU\nClasspath Exception which is available at\nhttps://www.gnu.org/software/classpath/license.html.\"\n\n  Simply including a copy of this Agreement, including this Exhibit A\n  is not sufficient to license the Source Code under Secondary Licenses.\n\n  If it is not possible or desirable to put the notice in a particular\n  file, then You may include the notice in a location (such as a LICENSE\n  file in a relevant directory) where a recipient would be likely to\n  look for such a notice.\n\n  You may add additional accurate notices of copyright ownership."
  },
  {
    "path": "resources/leiningen/new/plugin/README.md",
    "content": "# {{name}}\n\nA Leiningen plugin to do many wonderful things.\n\n## Usage\n\nFIXME: Use this for user-level plugins:\n\nPut `[{{name}} \"0.1.0-SNAPSHOT\"]` into the `:plugins` vector of your `:user`\nprofile.\n\nFIXME: Use this for project-level plugins:\n\nPut `[{{name}} \"0.1.0-SNAPSHOT\"]` into the `:plugins` vector of your project.clj.\n\nFIXME: and add an example usage that actually makes sense:\n\n    $ lein {{unprefixed-name}}\n\n## License\n\nCopyright © {{year}} FIXME\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\nhttps://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat https://www.gnu.org/software/classpath/license.html.\n"
  },
  {
    "path": "resources/leiningen/new/plugin/gitignore",
    "content": "/target\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.hgignore\n.hg/\n"
  },
  {
    "path": "resources/leiningen/new/plugin/hgignore",
    "content": "syntax: glob\ntarget/**\nclasses/**\ncheckouts/**\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.gitignore\n.git/**\n"
  },
  {
    "path": "resources/leiningen/new/plugin/name.clj",
    "content": "(ns leiningen.{{unprefixed-name}})\n\n(defn {{unprefixed-name}}\n  \"I don't do a lot.\"\n  [project & args]\n  (println \"Hi!\"))\n"
  },
  {
    "path": "resources/leiningen/new/plugin/project.clj",
    "content": "(defproject {{name}} \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0\"\n            :url \"https://www.eclipse.org/legal/epl-2.0/\"}\n  :eval-in-leiningen true)\n"
  },
  {
    "path": "resources/leiningen/new/template/CHANGELOG.md",
    "content": "# Change Log\nAll notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](https://keepachangelog.com/).\n\n## [Unreleased]\n### Changed\n- Add a new arity to `make-widget-async` to provide a different widget shape.\n\n## [0.1.1] - {{date}}\n### Changed\n- Documentation on how to make the widgets.\n\n### Removed\n- `make-widget-sync` - we're all async, all the time.\n\n### Fixed\n- Fixed widget maker to keep working when daylight savings switches over.\n\n## 0.1.0 - {{date}}\n### Added\n- Files from the new template.\n- Widget maker public API - `make-widget-sync`.\n\n[Unreleased]: https://source-host.site/your-name/{{name}}/compare/0.1.1...HEAD\n[0.1.1]: https://source-host.site/your-name/{{name}}/compare/0.1.0...0.1.1\n"
  },
  {
    "path": "resources/leiningen/new/template/LICENSE",
    "content": "Eclipse Public License - v 2.0\n\n    THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE\n    PUBLIC LICENSE (\"AGREEMENT\"). ANY USE, REPRODUCTION OR DISTRIBUTION\n    OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.\n\n1. DEFINITIONS\n\n\"Contribution\" means:\n\n  a) in the case of the initial Contributor, the initial content\n     Distributed under this Agreement, and\n\n  b) in the case of each subsequent Contributor:\n     i) changes to the Program, and\n     ii) additions to the Program;\n  where such changes and/or additions to the Program originate from\n  and are Distributed by that particular Contributor. A Contribution\n  \"originates\" from a Contributor if it was added to the Program by\n  such Contributor itself or anyone acting on such Contributor's behalf.\n  Contributions do not include changes or additions to the Program that\n  are not Modified Works.\n\n\"Contributor\" means any person or entity that Distributes the Program.\n\n\"Licensed Patents\" mean patent claims licensable by a Contributor which\nare necessarily infringed by the use or sale of its Contribution alone\nor when combined with the Program.\n\n\"Program\" means the Contributions Distributed in accordance with this\nAgreement.\n\n\"Recipient\" means anyone who receives the Program under this Agreement\nor any Secondary License (as applicable), including Contributors.\n\n\"Derivative Works\" shall mean any work, whether in Source Code or other\nform, that is based on (or derived from) the Program and for which the\neditorial revisions, annotations, elaborations, or other modifications\nrepresent, as a whole, an original work of authorship.\n\n\"Modified Works\" shall mean any work in Source Code or other form that\nresults from an addition to, deletion from, or modification of the\ncontents of the Program, including, for purposes of clarity any new file\nin Source Code form that contains any contents of the Program. Modified\nWorks shall not include works that contain only declarations,\ninterfaces, types, classes, structures, or files of the Program solely\nin each case in order to link to, bind by name, or subclass the Program\nor Modified Works thereof.\n\n\"Distribute\" means the acts of a) distributing or b) making available\nin any manner that enables the transfer of a copy.\n\n\"Source Code\" means the form of a Program preferred for making\nmodifications, including but not limited to software source code,\ndocumentation source, and configuration files.\n\n\"Secondary License\" means either the GNU General Public License,\nVersion 2.0, or any later versions of that license, including any\nexceptions or additional permissions as identified by the initial\nContributor.\n\n2. GRANT OF RIGHTS\n\n  a) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free copyright\n  license to reproduce, prepare Derivative Works of, publicly display,\n  publicly perform, Distribute and sublicense the Contribution of such\n  Contributor, if any, and such Derivative Works.\n\n  b) Subject to the terms of this Agreement, each Contributor hereby\n  grants Recipient a non-exclusive, worldwide, royalty-free patent\n  license under Licensed Patents to make, use, sell, offer to sell,\n  import and otherwise transfer the Contribution of such Contributor,\n  if any, in Source Code or other form. This patent license shall\n  apply to the combination of the Contribution and the Program if, at\n  the time the Contribution is added by the Contributor, such addition\n  of the Contribution causes such combination to be covered by the\n  Licensed Patents. The patent license shall not apply to any other\n  combinations which include the Contribution. No hardware per se is\n  licensed hereunder.\n\n  c) Recipient understands that although each Contributor grants the\n  licenses to its Contributions set forth herein, no assurances are\n  provided by any Contributor that the Program does not infringe the\n  patent or other intellectual property rights of any other entity.\n  Each Contributor disclaims any liability to Recipient for claims\n  brought by any other entity based on infringement of intellectual\n  property rights or otherwise. As a condition to exercising the\n  rights and licenses granted hereunder, each Recipient hereby\n  assumes sole responsibility to secure any other intellectual\n  property rights needed, if any. For example, if a third party\n  patent license is required to allow Recipient to Distribute the\n  Program, it is Recipient's responsibility to acquire that license\n  before distributing the Program.\n\n  d) Each Contributor represents that to its knowledge it has\n  sufficient copyright rights in its Contribution, if any, to grant\n  the copyright license set forth in this Agreement.\n\n  e) Notwithstanding the terms of any Secondary License, no\n  Contributor makes additional grants to any Recipient (other than\n  those set forth in this Agreement) as a result of such Recipient's\n  receipt of the Program under the terms of a Secondary License\n  (if permitted under the terms of Section 3).\n\n3. REQUIREMENTS\n\n3.1 If a Contributor Distributes the Program in any form, then:\n\n  a) the Program must also be made available as Source Code, in\n  accordance with section 3.2, and the Contributor must accompany\n  the Program with a statement that the Source Code for the Program\n  is available under this Agreement, and informs Recipients how to\n  obtain it in a reasonable manner on or through a medium customarily\n  used for software exchange; and\n\n  b) the Contributor may Distribute the Program under a license\n  different than this Agreement, provided that such license:\n     i) effectively disclaims on behalf of all other Contributors all\n     warranties and conditions, express and implied, including\n     warranties or conditions of title and non-infringement, and\n     implied warranties or conditions of merchantability and fitness\n     for a particular purpose;\n\n     ii) effectively excludes on behalf of all other Contributors all\n     liability for damages, including direct, indirect, special,\n     incidental and consequential damages, such as lost profits;\n\n     iii) does not attempt to limit or alter the recipients' rights\n     in the Source Code under section 3.2; and\n\n     iv) requires any subsequent distribution of the Program by any\n     party to be under a license that satisfies the requirements\n     of this section 3.\n\n3.2 When the Program is Distributed as Source Code:\n\n  a) it must be made available under this Agreement, or if the\n  Program (i) is combined with other material in a separate file or\n  files made available under a Secondary License, and (ii) the initial\n  Contributor attached to the Source Code the notice described in\n  Exhibit A of this Agreement, then the Program may be made available\n  under the terms of such Secondary Licenses, and\n\n  b) a copy of this Agreement must be included with each copy of\n  the Program.\n\n3.3 Contributors may not remove or alter any copyright, patent,\ntrademark, attribution notices, disclaimers of warranty, or limitations\nof liability (\"notices\") contained within the Program from any copy of\nthe Program which they Distribute, provided that Contributors may add\ntheir own appropriate notices.\n\n4. COMMERCIAL DISTRIBUTION\n\nCommercial distributors of software may accept certain responsibilities\nwith respect to end users, business partners and the like. While this\nlicense is intended to facilitate the commercial use of the Program,\nthe Contributor who includes the Program in a commercial product\noffering should do so in a manner which does not create potential\nliability for other Contributors. Therefore, if a Contributor includes\nthe Program in a commercial product offering, such Contributor\n(\"Commercial Contributor\") hereby agrees to defend and indemnify every\nother Contributor (\"Indemnified Contributor\") against any losses,\ndamages and costs (collectively \"Losses\") arising from claims, lawsuits\nand other legal actions brought by a third party against the Indemnified\nContributor to the extent caused by the acts or omissions of such\nCommercial Contributor in connection with its distribution of the Program\nin a commercial product offering. The obligations in this section do not\napply to any claims or Losses relating to any actual or alleged\nintellectual property infringement. In order to qualify, an Indemnified\nContributor must: a) promptly notify the Commercial Contributor in\nwriting of such claim, and b) allow the Commercial Contributor to control,\nand cooperate with the Commercial Contributor in, the defense and any\nrelated settlement negotiations. The Indemnified Contributor may\nparticipate in any such claim at its own expense.\n\nFor example, a Contributor might include the Program in a commercial\nproduct offering, Product X. That Contributor is then a Commercial\nContributor. If that Commercial Contributor then makes performance\nclaims, or offers warranties related to Product X, those performance\nclaims and warranties are such Commercial Contributor's responsibility\nalone. Under this section, the Commercial Contributor would have to\ndefend claims against the other Contributors related to those performance\nclaims and warranties, and if a court requires any other Contributor to\npay any damages as a result, the Commercial Contributor must pay\nthose damages.\n\n5. NO WARRANTY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN \"AS IS\"\nBASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR\nIMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF\nTITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR\nPURPOSE. Each Recipient is solely responsible for determining the\nappropriateness of using and distributing the Program and assumes all\nrisks associated with its exercise of rights under this Agreement,\nincluding but not limited to the risks and costs of program errors,\ncompliance with applicable laws, damage to or loss of data, programs\nor equipment, and unavailability or interruption of operations.\n\n6. DISCLAIMER OF LIABILITY\n\nEXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT\nPERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS\nSHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST\nPROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE\nEXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n7. GENERAL\n\nIf any provision of this Agreement is invalid or unenforceable under\napplicable law, it shall not affect the validity or enforceability of\nthe remainder of the terms of this Agreement, and without further\naction by the parties hereto, such provision shall be reformed to the\nminimum extent necessary to make such provision valid and enforceable.\n\nIf Recipient institutes patent litigation against any entity\n(including a cross-claim or counterclaim in a lawsuit) alleging that the\nProgram itself (excluding combinations of the Program with other software\nor hardware) infringes such Recipient's patent(s), then such Recipient's\nrights granted under Section 2(b) shall terminate as of the date such\nlitigation is filed.\n\nAll Recipient's rights under this Agreement shall terminate if it\nfails to comply with any of the material terms or conditions of this\nAgreement and does not cure such failure in a reasonable period of\ntime after becoming aware of such noncompliance. If all Recipient's\nrights under this Agreement terminate, Recipient agrees to cease use\nand distribution of the Program as soon as reasonably practicable.\nHowever, Recipient's obligations under this Agreement and any licenses\ngranted by Recipient relating to the Program shall continue and survive.\n\nEveryone is permitted to copy and distribute copies of this Agreement,\nbut in order to avoid inconsistency the Agreement is copyrighted and\nmay only be modified in the following manner. The Agreement Steward\nreserves the right to publish new versions (including revisions) of\nthis Agreement from time to time. No one other than the Agreement\nSteward has the right to modify this Agreement. The Eclipse Foundation\nis the initial Agreement Steward. The Eclipse Foundation may assign the\nresponsibility to serve as the Agreement Steward to a suitable separate\nentity. Each new version of the Agreement will be given a distinguishing\nversion number. The Program (including Contributions) may always be\nDistributed subject to the version of the Agreement under which it was\nreceived. In addition, after a new version of the Agreement is published,\nContributor may elect to Distribute the Program (including its\nContributions) under the new version.\n\nExcept as expressly stated in Sections 2(a) and 2(b) above, Recipient\nreceives no rights or licenses to the intellectual property of any\nContributor under this Agreement, whether expressly, by implication,\nestoppel or otherwise. All rights in the Program not expressly granted\nunder this Agreement are reserved. Nothing in this Agreement is intended\nto be enforceable by any entity that is not a Contributor or Recipient.\nNo third-party beneficiary rights are created under this Agreement.\n\nExhibit A - Form of Secondary Licenses Notice\n\n\"This Source Code may also be made available under the following\nSecondary Licenses when the conditions for such availability set forth\nin the Eclipse Public License, v. 2.0 are satisfied: GNU General Public\nLicense as published by the Free Software Foundation, either version 2\nof the License, or (at your option) any later version, with the GNU\nClasspath Exception which is available at\nhttps://www.gnu.org/software/classpath/license.html.\"\n\n  Simply including a copy of this Agreement, including this Exhibit A\n  is not sufficient to license the Source Code under Secondary Licenses.\n\n  If it is not possible or desirable to put the notice in a particular\n  file, then You may include the notice in a location (such as a LICENSE\n  file in a relevant directory) where a recipient would be likely to\n  look for such a notice.\n\n  You may add additional accurate notices of copyright ownership."
  },
  {
    "path": "resources/leiningen/new/template/README.md",
    "content": "# {{name}}\n\nA Leiningen template for FIXME.\n\n## Usage\n\nFIXME\n\n## License\n\nCopyright © {{year}} FIXME\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\nhttps://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat https://www.gnu.org/software/classpath/license.html.\n"
  },
  {
    "path": "resources/leiningen/new/template/foo.clj",
    "content": "(def {{name}} :foo)\n"
  },
  {
    "path": "resources/leiningen/new/template/gitignore",
    "content": "/target\n/classes\n/checkouts\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.hgignore\n.hg/\n"
  },
  {
    "path": "resources/leiningen/new/template/hgignore",
    "content": "syntax: glob\ntarget/**\nclasses/**\ncheckouts/**\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.gitignore\n.git/**\n"
  },
  {
    "path": "resources/leiningen/new/template/project.clj",
    "content": "(defproject {{group-prefix}}lein-template.{{artifact-id}} \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0\"\n            :url \"https://www.eclipse.org/legal/epl-2.0/\"}\n  :eval-in-leiningen true)\n"
  },
  {
    "path": "resources/leiningen/new/template/temp.clj",
    "content": "(ns leiningen.new.{{artifact-id}}\n  (:require [leiningen.new.templates :as tmpl]\n            [leiningen.core.main :as main]))\n\n(def render (tmpl/renderer \"{{sanitized}}\"))\n\n(defn {{artifact-id}}\n  \"FIXME: write documentation\"\n  [name]\n  (let [data {:name name\n              :sanitized (tmpl/name-to-path name)}]\n    (main/info \"Generating fresh 'lein new' {{name}} project.\")\n    (tmpl/->files data\n                  [\"src/{{placeholder}}/foo.clj\" (render \"foo.clj\" data)])))\n"
  },
  {
    "path": "resources/repl-welcome",
    "content": "    Docs: (doc function-name-here)\n          (find-doc \"part-of-name-here\")\n  Source: (source function-name-here)\n Javadoc: (javadoc java-object-or-class-here)\n    Exit: Control+D or (exit) or (quit)\n Results: Stored in vars *1, *2, *3, an exception in *e\n"
  },
  {
    "path": "sample.project.clj",
    "content": ";; This is an annotated reference of the options that may be set in a\n;; project.clj file. It is fairly contrived in order to cover lots of\n;; different options; it shouldn't be considered a representative\n;; configuration. For a more detailed explanation of some of the terms\n;; run `lein help tutorial`.\n\n;; These options apply to Leiningen 2.x. See the 1.x branch for older versions:\n;; https://github.com/technomancy/leiningen/blob/1.x/sample.project.clj\n\n;; The project is named \"sample\", and its group-id is \"org.example\".\n(defproject org.example/sample \"1.0.0-SNAPSHOT\" ; version \"1.0.0-SNAPSHOT\"\n  ;; Beyond this point you may prepend a form with unquote, or ~, to eval it.\n\n;;; Project Metadata\n  ;; The description text is searchable from repositories like Clojars.\n  :description \"A sample project\"\n  :url \"https://example.org/sample-clojure-project\"\n  ;; The mailing list of the project. If the project has multiple mailing\n  ;; lists, use the :mailing-lists key (bound to a seq of mailing list\n  ;; descriptions as below).\n  :mailing-list {:name \"sample mailing list\"\n                 :archive \"https://example.org/sample-mailing-list-archives\"\n                 :other-archives [\"https://example.org/sample-list-archive2\"\n                                  \"https://example.org/sample-list-archive3\"]\n                 :post \"list@example.org\"\n                 :subscribe \"list-subscribe@example.org\"\n                 :unsubscribe \"list-unsubscribe@example.org\"}\n  ;; The project's license. :distribution should be :repo or :manual;\n  ;; :repo means it is OK for public repositories to host this project's\n  ;; artifacts. A seq of :licenses is also supported.\n  :license {:name \"Eclipse Public License - v 1.0\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"\n            :distribution :repo\n            :comments \"same as Clojure\"}\n  ;; Warns users of earlier versions of Leiningen. Set this if your project\n  ;; relies on features only found in newer Leiningen versions.\n  :min-lein-version \"2.0.0\"\n\n  ;; You can require a specific version of Leiningen. In case of mismatch\n  ;; execution will abort. When versions are compared, suffixes such as\n  ;; \"-SNAPSHOT\" are dropped.\n  ;; :exact-lein-version \"2.8.2\"\n\n;;; Dependencies, Plugins, and Repositories\n  ;; Dependencies are listed as [group-id/name version]; in addition\n  ;; to keywords supported by Pomegranate, you can use :native-prefix\n  ;; to specify a prefix. This prefix is used to extract natives in\n  ;; jars that don't adhere to the default \"<os>/<arch>/\" layout that\n  ;; Leiningen expects.\n  ;; You can also use strings like [\"group-id/name\" version] for instances\n  ;; where the dependency name isn't a valid symbol literal.\n  :dependencies [[org.clojure/clojure \"1.3.0\"]\n                 [org.jclouds/jclouds \"1.0\" :classifier \"jdk15\"]\n                 [net.sf.ehcache/ehcache \"2.3.1\" :extension \"pom\"]\n                 [log4j \"1.2.15\" :exclusions [[javax.mail/mail :extension \"jar\"]\n                                              [javax.jms/jms :classifier \"*\"]\n                                              com.sun.jdmk/jmxtools\n                                              com.sun.jmx/jmxri]]\n                 [\"net.3scale/3scale-api\" \"3.0.2\"]\n                 [org.lwjgl.lwjgl/lwjgl \"2.8.5\"]\n                 [org.lwjgl.lwjgl/lwjgl-platform \"2.8.5\"\n                  :classifier \"natives-osx\"\n                  ;; LWJGL stores natives in the root of the jar; this\n                  ;; :native-prefix will extract them.\n                  :native-prefix \"\"]]\n  ;; \"Managed Dependencies\" are a concept borrowed from maven pom files; see\n  ;;  https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management\n  ;; Managed dependencies allow you to specify a desired version number for a dependency\n  ;;  *if* the dependency exists (often transitively), but a managed dependency\n  ;;  will not actually cause the described artifact to be a dependency on its own.\n  ;; This feature is most useful in combination with some other mechanism for\n  ;;  defining a \"parent project\"; e.g. you can have a \"parent project\" that specifies\n  ;;  managed dependencies for common libraries that you use frequently in your other\n  ;;  projects, and then the downstream/child projects can specify a normal dependency on\n  ;;  those libraries *without specifying a version number*, and thus will inherit\n  ;;  the version number from the parent.  This provides a simpler means of keeping\n  ;;  common dependency versions in sync across a large number of clojure libraries.\n  ;; For more info see ./doc/MANAGED_DEPS.md and https://github.com/achin/lein-parent\n  :managed-dependencies [[clj-time \"0.12.0\"]\n                         [me.raynes/fs \"1.4.6\"]]\n\n  ;; What to do in the case of version conflicts. Defaults to :ranges, which\n  ;; warns when version ranges are present anywhere in the dependency tree,\n  ;; but can be set to true to warn for both ranges and overrides, or :abort\n  ;; to exit in the case of ranges or overrides. Setting this to :warn or\n  ;; :abort will also warn you when plugins or their dependencies\n  ;; conflict with libraries used by Leiningen itself.\n  :pedantic? :abort\n  ;; Global exclusions are applied across the board, as an alternative\n  ;; to duplication for multiple dependencies with the same excluded libraries.\n  :exclusions [org.apache.poi/poi\n               org.apache.poi/poi-ooxml]\n  ;; Plugins are code that runs in Leiningen itself and usually\n  ;; provide new tasks or hooks.\n  :plugins [[lein-pprint \"1.1.1\"]\n            [lein-assoc \"0.1.0\"]\n            [s3-wagon-private \"1.1.1\"]\n            [lein-foo \"0.0.1\" :hooks false]\n            [lein-bar \"0.0.1\" :middleware false]]\n  ;; These repositories will be searched for :dependencies and\n  ;; :plugins and will also be available to deploy to.\n  ;; Add ^:replace (:repositories ^:replace [...]) to only use repositories you\n  ;; list below.\n  :repositories [[\"java.net\" \"https://download.java.net/maven/2\"]\n                 [\"sonatype\" {:url \"https://oss.sonatype.org/content/repositories/releases\"\n                              ;; If a repository contains releases only setting\n                              ;; :snapshots to false will speed up dependencies.\n                              :snapshots false\n                              ;; Disable signing releases deployed to this repo.\n                              ;; (Not recommended.)\n                              :sign-releases false\n                              ;; You can also set the policies for how to handle\n                              ;; :checksum failures to :fail, :warn, or :ignore.\n                              :checksum :fail\n                              ;; How often should this repository be checked for\n                              ;; snapshot updates? (:daily, :always, or :never)\n                              :update :always\n                              ;; You can also apply them to releases only:\n                              :releases {:checksum :fail :update :always}}]\n                 ;; Repositories named \"snapshots\" and \"releases\" automatically\n                 ;; have their :snapshots and :releases disabled as appropriate.\n                 ;; Credentials for repositories should *not* be stored\n                 ;; in project.clj but in ~/.lein/credentials.clj.gpg instead,\n                 ;; see `lein help deploying` under \"Authentication\".\n                 [\"snapshots\" \"https://blueant.com/archiva/snapshots\"]\n                 [\"releases\" {:url \"https://blueant.com/archiva/internal\"\n                              ;; Using :env as a value here will cause an\n                              ;; environment variable to be used based on\n                              ;; the key; in this case LEIN_PASSWORD.\n                              :username \"milgrim\" :password :env}]]\n  ;; These repositories will be included with :repositories when loading plugins.\n  ;; This would normally be set in a profile for non-public repositories.\n  ;; All the options are the same as in the :repositories map.\n  :plugin-repositories [[\"internal-plugin-repo\" \"https://example.org/repo\"]]\n  ;; Fetch dependencies from mirrors. Mirrors override repositories when the key\n  ;; in the :mirrors map matches either the name or URL of a specified\n  ;; repository. All settings supported in :repositories may be set here too.\n  ;; The :name should match the name of the mirrored repository.\n  :mirrors {\"central\" {:name \"central\"\n                       :url \"https://mirrors.ibiblio.org/pub/mirrors/maven2\"}\n            #\"clojars\" {:name \"Internal nexus\"\n                        :url \"https://mvn.local/nexus/releases\"\n                        :repo-manager true}}\n  ;; Override location of the local maven repository. Relative to project root.\n  :local-repo \"local-m2\"\n  ;; You can set :update and :checksum policies here to have them\n  ;; apply for all :repositories. Usually you will not set :update\n  ;; directly but apply the \"update\" profile instead.\n  :update :always\n  :checksum :fail\n  ;; Prevent Leiningen from checking the network for dependencies.\n  ;; This wouldn't normally be set in project.clj; it would come from a profile.\n  :offline? true\n  ;; the deploy task will give preference to repositories specified in\n  ;; :deploy-repositories, and repos listed there will not be used for\n  ;; dependency resolution.\n  :deploy-repositories [[\"releases\" {:url \"https://blueant.com/archiva/internal/releases\"\n                                     ;; Select a GPG private key to use for\n                                     ;; signing. (See \"How to specify a user\n                                     ;; ID\" in GPG's manual.) GPG will\n                                     ;; otherwise pick the first private key\n                                     ;; it finds in your keyring.\n                                     ;; Currently only works in :deploy-repositories\n                                     ;; or as a top-level (global) setting.\n                                     :signing {:gpg-key \"0xAB123456\"}}]\n                        [\"snapshots\" \"https://blueant.com/archiva/internal/snapshots\"]]\n  ;; Defaults for signing options. Defers to per-repository settings.\n  ;; You can set this in the :user profile in ~/.lein/profiles.clj too.\n  :signing {;; specify which key to use for signing; set to false to disable.\n            ;; defaults to using whatever key GPG is configured to use.\n            :gpg-key \"root@eruditorum.org\"\n            ;; specify which SSH key to use for signing; defaults to not signing\n            ;; with SSH.\n            :ssh-key \"~/.ssh/id_rsa\"}\n  ;; If you configure a custom repository with a self-signed SSL\n  ;; certificate, you will need to add it here. Paths should either\n  ;; be on Leiningen's classpath or relative to the project root.\n  :certificates [\"blueant.pem\"]\n\n;;; Profiles\n  ;; Each active profile gets merged into the project map. The :dev\n  ;; and :user profiles are active by default, but the latter should be\n  ;; looked up in ~/.lein/profiles.clj rather than set in project.clj.\n  ;; Use the with-profiles higher-order task to run a task with a\n  ;; different set of active profiles.\n  ;; See `lein help profiles` for a detailed explanation.\n  :profiles {:debug {:debug true\n                     :injections [(prn (into {} (System/getProperties)))]}\n             :1.4 {:dependencies [[org.clojure/clojure \"1.4.0\"]]}\n             :1.5 {:dependencies [[org.clojure/clojure \"1.5.0\"]]}\n             ;; activated by default\n             :dev {:resource-paths [\"dummy-data\"]\n                   :dependencies [[clj-stacktrace \"0.2.4\"]]}\n             ;; activated automatically during uberjar\n             :uberjar {:aot [entry.point.ns]}\n             ;; activated automatically in repl task\n             :repl {:plugins [[cider/cider-nrepl \"0.7.1\"]]}}\n  ;; Load these namespaces from within Leiningen to pick up hooks from them.\n  :hooks [leiningen.hooks.difftest]\n  ;; Apply these middleware functions from plugins to your project\n  ;; when it loads. Both hooks and middleware can be loaded implicitly\n  ;; or by being listed here.\n  :middleware [lein-xml.plugin/middleware]\n  ;; By default, middleware gets memoized; you can disable it with this setting.\n  ;; For bootstrapping reasons, this is only supported in the top level of\n  ;; defproject or the :user profile.\n  :memoize-middleware? false\n  ;; These settings disable the implicit loading of middleware and\n  ;; hooks, respectively. You can disable both with :implicits false.\n  :implicit-middleware false\n  :implicit-hooks false\n\n;;; Entry Point\n  ;; The -main function in this namespace will be run at launch\n  ;; (either via `lein run` or from an uberjar). It should be variadic:\n  ;;\n  ;; (ns my.service.runner\n  ;;   (:gen-class))\n  ;;\n  ;; (defn -main\n  ;;   \"Application entry point\"\n  ;;   [& args]\n  ;;   (comment Do app initialization here))\n  ;;\n  ;; This will be AOT compiled by default; to disable this, attach ^:skip-aot\n  ;; metadata to the namespace symbol. ^:skip-aot will not disable AOT\n  ;; compilation of :main when :aot is :all or contains the main class. It's\n  ;; best to be explicit with the :aot key rather than relying on\n  ;; auto-compilation of :main. Setting :main to nil is useful when a\n  ;; project contains several main functions. nil will produce a jar\n  ;; with manifest.mf that lacks `Main-Class' property.\n  :main my.service.runner\n  ;; Support project-specific task aliases. These are interpreted in\n  ;; the same way as command-line arguments to the lein command. If\n  ;; the alias points to a vector, it uses partial application. For\n  ;; example, \"lein with-magic run -m hi.core\" would be equivalent to\n  ;; \"lein assoc :magic true run -m hi.core\". Remember, commas are not\n  ;; considered to be special by argument parsers, they're just part\n  ;; of the preceding argument.\n  :aliases {\"launch\" [\"run\" \"-m\" \"myproject.main\"]\n            ;; Values from the project map can be spliced into the arguments\n            ;; using :project/key keywords.\n            \"launch-version\" [\"run\" \"-m\" \"myproject.main\" :project/version]\n            \"dumbrepl\" [\"trampoline\" \"run\" \"-m\" \"clojure.main/main\"]\n            ;; :pass-through-help ensures `lein my-alias help` is not converted\n            ;; into `lein help my-alias`.\n            \"go\" ^:pass-through-help [\"run\" \"-m\"]\n            ;; For complex aliases, a docstring may be attached. The docstring\n            ;; will be printed instead of the expansion when running `lein help`.\n            \"deploy!\" ^{:doc \"Recompile sources, then deploy if tests succeed.\"}\n            ;; Nested vectors are supported for the \"do\" task\n            [\"do\" \"clean\" [\"test\" \":integration\"] [\"deploy\" \"clojars\"]]}\n\n;;; Custom Release Tasks\n  ;; By default `lein release` performs a series of tasks typical of the release\n  ;; process for many Leiningen-managed projects. These tasks can be overridden\n  ;; using `:release-tasks` as follows:\n  :release-tasks [[\"vcs\" \"assert-committed\"]\n                  [\"change\" \"version\"\n                   \"leiningen.release/bump-version\" \"release\"]\n                  [\"vcs\" \"commit\"]\n                  [\"vcs\" \"tag\"]\n                  [\"deploy\"]]\n  ;; This differs from the default `:release-tasks` behavior in that it doesn't\n  ;; go on to perform another `change version` or `vcs` task, instead leaving\n  ;; that up to the developer to do manually.\n\n;;; Running Project Code\n  ;; Normally Leiningen runs the javac and compile tasks before\n  ;; calling any eval-in-project code, but you can override this with\n  ;; the :prep-tasks key to do other things like compile protocol buffers.\n  :prep-tasks [[\"protobuf\" \"compile\"] \"javac\" \"compile\"]\n  ;; These namespaces will be AOT-compiled. Needed for gen-class and\n  ;; other Java interop functionality. Put a regex here to compile all\n  ;; namespaces whose names match. If you only need AOT for an uberjar\n  ;; gen-class, put `:aot [entry.point.ns]` in the :uberjar profile and see\n  ;; :target-path for how to enable profile-based target isolation.\n  ;; Putting :all here will AOT-compile everything, but this can cause issues\n  ;; with certain uses of protocols and records.\n  :aot [org.example.sample]\n  ;; Forms to prepend to every form that is evaluated inside your project.\n  ;; Allows working around the Gilardi Scenario: https://technomancy.us/143\n  ;; Note: This code is not executed in jars or uberjars.\n  :injections [(require 'clojure.pprint)]\n  ;; Java agents can instrument and intercept certain VM features. Include\n  ;; :bootclasspath true to place the agent jar on the bootstrap classpath.\n  :java-agents [[nodisassemble \"0.1.1\" :options \"extra\"]]\n  ;; Options to pass to java compiler for java source,\n  ;; exactly the same as command line arguments to javac.\n  :javac-options [\"-target\" \"1.6\" \"-source\" \"1.6\" \"-Xlint:-options\"]\n  ;; Emit warnings on all reflection calls. - DEPRECATED (see below)\n  :warn-on-reflection true\n  ;; Sets the values of global vars within Clojure. This example\n  ;; disables all pre- and post-conditions and emits warnings on\n  ;; reflective calls. See the Clojure documentation for the list of\n  ;; valid global variables to set (and their meaningful values).\n  :global-vars {*warn-on-reflection* true\n                *assert* false}\n  ;; Preserve metadata when evaluating project code. This can remove reflection\n  ;; warnings but can also cause incompatibilities with certain plugins.\n  :preserve-eval-meta true\n  ;; Use a different `java` executable for project JVMs. Leiningen's own JVM is\n  ;; set with the LEIN_JAVA_CMD environment variable.\n  :java-cmd \"/home/phil/bin/java1.7\"\n  ;; You can set JVM-level options here. The :java-opts key is an alias for this.\n  :jvm-opts [\"-Xmx1g\"]\n  ;; Set the context in which your project code is evaluated. Defaults\n  ;; to :subprocess, but can also be :leiningen (for plugins) or :nrepl\n  ;; to connect to an existing project process over nREPL. A project nREPL\n  ;; server can be started simply by invoking `lein repl`. If no connection\n  ;; can be established, :nrepl falls back to :subprocess.\n  :eval-in :leiningen\n  ;; Enable bootclasspath optimization. This improves boot time but interferes\n  ;; with certain libraries like Jetty that make assumptions about classloaders.\n  :bootclasspath true\n\n;;; Filesystem Paths\n  ;; If you'd rather use a different directory structure, you can set these.\n  ;; Paths that contain \"inputs\" are string vectors, \"outputs\" are strings.\n  :source-paths [\"src\" \"src/main/clojure\"]\n  :java-source-paths [\"src/main/java\"]  ; Java source is stored separately.\n  :test-paths [\"test\" \"src/test/clojure\"]\n  :resource-paths [\"src/main/resource\"] ; Non-code files included in classpath/jar.\n  ;; All generated files will be placed in :target-path. In order to avoid\n  ;; cross-profile contamination (for instance, uberjar classes interfering\n  ;; with development), it's recommended to include %s in in your custom\n  ;; :target-path, which will splice in names of the currently active profiles.\n  :target-path \"target/%s/\"\n  ;; Directory in which to place AOT-compiled files. Including %s will\n  ;; splice the :target-path into this value.\n  :compile-path \"%s/classy-files\"\n  ;; Directory in which to extract native components from inside dependencies.\n  ;; Including %s will splice the :target-path into this value. Note that this\n  ;; is not where to *look* for existing native libraries; use :jvm-opts with\n  ;; -Djava.library.path=... instead for that.\n  :native-path \"%s/bits-n-stuff\"\n  ;; Directories under which `lein clean` removes files.\n  ;; Specified by keyword or keyword-chain to get-in path in this defproject.\n  ;; Both a single path and a collection of paths are accepted as each.\n  ;; For example, if the other parts of project are like:\n  ;;   :target-path \"target\"\n  ;;   :compile-path \"classes\"\n  ;;   :foobar-paths [\"foo\" \"bar\"]\n  ;;   :baz-config {:qux-path \"qux\"}\n  ;; :clean-targets below lets `lein clean` remove files under \"target\",\n  ;; \"classes\", \"foo\", \"bar\", \"qux\", and \"out\".\n  ;; By default, will protect paths outside the project root and within standard\n  ;; lein source directories (\"src\", \"test\", \"resources\", \"doc\", \"project.clj\").\n  ;; However, this protection can be overridden with metadata on the :clean-targets\n  ;; vector - ^{:protect false}\n  :clean-targets [:target-path :compile-path :foobar-paths\n                  [:baz-config :qux-path] \"out\"]\n  ;; Workaround for https://dev.clojure.org/jira/browse/CLJ-322 by deleting\n  ;; compilation artifacts for namespaces that come from dependencies.\n  :clean-non-project-classes true\n  ;; Paths to include on the classpath from each project in the\n  ;; checkouts/ directory. (See the tutorial for more details about\n  ;; checkout dependencies.) Set this to be a vector of functions that\n  ;; take the target project as argument. Defaults to [:source-paths\n  ;; :compile-path :resource-paths], but you could use the following\n  ;; to share code from the test suite:\n  :checkout-deps-shares [:source-paths :test-paths\n                         ~(fn [p] (str (:root p) \"/lib/dev/*\"))]\n\n;;; Testing\n  ;; Predicates to determine whether to run a test or not, take test metadata\n  ;; as argument. See `lein help test` for more information.\n  :test-selectors {:default (fn [m] (not (or (:integration m) (:regression m))))\n                   :integration :integration\n                   :regression :regression}\n  ;; In order to support the `retest` task, Leiningen must monkeypatch the\n  ;; clojure.test library. This disables that feature and breaks `lein retest`.\n  :monkeypatch-clojure-test false\n\n;;; Repl\n  ;; Options to change the way the REPL behaves.\n  :repl-options { ;; Specify the string to print when prompting for input.\n                 ;; defaults to something like (fn [ns] (str *ns* \"=> \"))\n                 :prompt (fn [ns] (str \"your command for <\" ns \">? \" ))\n                 ;; What to print when the repl session starts.\n                 :welcome (println \"Welcome to the magical world of the repl!\")\n                 ;; Specify the ns to start the REPL in (overrides :main in\n                 ;; this case only)\n                 :init-ns foo.bar\n                 ;; This expression will run when first opening a REPL, in the\n                 ;; namespace from :init-ns or :main if specified.\n                 :init (println \"here we are in\" *ns*)\n                 ;; Print stack traces on exceptions (highly recommended, but\n                 ;; currently overwrites *1, *2, etc).\n                 :caught clj-stacktrace.repl/pst+\n                 ;; Skip's the default requires and printed help message.\n                 :skip-default-init false\n                 ;; Customize the socket the repl task listens on and\n                 ;; attaches to.  Specify either a filesystem :socket\n                 ;; (where the parent directory should be used to\n                 ;; control access since POSIX doesn't require\n                 ;; respecting the socket permissions):\n                 :socket \"/path/to/the/socket\"\n                 ;; or a network :host and/or :port\n                 ;;   :host \"0.0.0.0\"\n                 ;;   :port 4001\n                 ;; File name to use as history: user input will be stored there\n                 ;; over sessions. Defaults to .lein-repl-history inside a\n                 ;; project or to repl-history in the Leiningen home directory\n                 ;; outside of a project.  Use nil (or file name like\n                 ;; \"/dev/null\") to disable REPL history completely.\n                 :history-file \"/tmp/my-project-repl-history\"\n                 ;; If nREPL takes too long to load it may timeout,\n                 ;; increase this to wait longer before timing out.\n                 ;; Defaults to 30000 (30 seconds)\n                 :timeout 40000\n                 ;; nREPL server customization\n                 ;; Only one of #{:nrepl-handler :nrepl-middleware}\n                 ;; may be used at a time.\n                 ;; Use a different server-side nREPL handler.\n                 :nrepl-handler (nrepl.server/default-handler)\n                 ;; Add server-side middleware to nREPL stack.\n                 :nrepl-middleware [my.nrepl.thing/wrap-amazingness\n                                    ;; TODO: link to more detailed documentation.\n                                    ;; Middleware without appropriate metadata\n                                    ;; (see nrepl.middleware/set-descriptor!\n                                    ;; for details) will simply be appended to the stack\n                                    ;; of middleware (rather than ordered based on its\n                                    ;; expectations and requirements).\n                                    (fn [handler]\n                                      (fn [& args]\n                                        (prn :middle args)\n                                        (apply handler args)))]}\n\n;;; Jar Output\n  ;; Name of the jar file produced. Will be placed inside :target-path.\n  ;; Including %s will splice the project version into the filename.\n  :jar-name \"sample.jar\"\n  ;; As above, but for uberjar.\n  :uberjar-name \"sample-standalone.jar\"\n  ;; Leave the contents of :source-paths out of jars (for AOT projects).\n  :omit-source true\n  ;; Files with names matching any of these patterns will be excluded from jars.\n  :jar-exclusions [#\"(?:^|/).svn/\"]\n  ;; Files with names matching any of these patterns will included in the jar\n  ;; even if they'd be skipped otherwise.\n  :jar-inclusions [#\"^\\.ebextensions\"]\n  ;; Same as :jar-exclusions, but for uberjars.\n  :uberjar-exclusions [#\"META-INF/DUMMY.SF\"]\n  ;; By default Leiningen will run a clean before creating jars to prevent\n  ;; undeclared AOT from leaking to downstream consumers; this disables\n  ;; that behaviour.\n  :auto-clean false\n  ;; Files to merge programmatically in uberjars when multiple same-named files\n  ;; exist across project and dependencies.  Should be a map of filename strings\n  ;; or regular expressions to a sequence of three functions:\n  ;; 1. Takes an input stream; returns a parsed datum.\n  ;; 2. Takes a new datum and the current result datum; returns a merged datum.\n  ;; 3. Takes an output stream and a datum; writes the datum to the stream.\n  ;; Resolved in reverse dependency order, starting with project.\n  :uberjar-merge-with {#\"\\.properties$\" [slurp str spit]}\n  ;; Add arbitrary jar entries. Supports :path, :paths, :bytes, and :fn types.\n  :filespecs [{:type :path :path \"config/base.clj\"}\n              ;; Files within other jars can be added\n              {:type :path :path \"some-dependency-1.0.0.jar!/resources/file.txt\"}\n              ;; Directory paths are included recursively.\n              {:type :paths :paths [\"config/web\" \"config/cli\"]}\n              ;; Programmatically-generated content can use :bytes.\n              {:type :bytes :path \"project.clj\"\n               ;; Strings or byte arrays are accepted.\n               :bytes ~(slurp \"project.clj\")}\n              ;; :fn filespecs take the project as an argument and\n              ;; should return a filespec map of one of the other types.\n              {:type :fn :fn (fn [p]\n                               {:type :bytes :path \"git-log\"\n                                :bytes (:out (clojure.java.shell/sh\n                                              \"git\" \"log\" \"-n\" \"1\"))})}]\n  ;; Set arbitrary key/value pairs for the jar's manifest. Any\n  ;; vector or sequence of pairs is supported as well.\n  :manifest {\"Project-awesome-level\" \"super-great\"\n             ;; Function values will be called with the project as an argument.\n             \"Class-Path\" ~#(clojure.string/join\n                             \\space\n                             (leiningen.core.classpath/get-classpath %))\n             ;; If a value is a collection, a manifest section is built for it and\n             ;; the name of the key is used as the section name.\n             :my-section-1 [[\"MyKey1\" \"MyValue1\"] [\"MyKey2\" \"MyValue2\"]]\n             :my-section-2 {\"MyKey3\" \"MyValue3\" \"MyKey4\" \"MyValue4\"}\n             ;; Symbol values will be resolved to find a function to call.\n             \"Grunge-level\" my.plugin/calculate-grunginess}\n\n;;; Pom Output\n  ;; Where the pom.xml is written. If not set, the project root.\n  :pom-location \"target/\"\n  ;; Set parent for working within a multi-module maven project.\n  :parent [org.example/parent \"0.0.1\" :relative-path \"../parent/pom.xml\"]\n  ;; Extensions here will be propagated to the pom but not used by Leiningen.\n  :extensions [[org.apache.maven.wagon/wagon-webdav \"1.0-beta-2\"]\n               [foo/bar-baz \"1.0\"]]\n  ;; Plugins here will be propagated to the pom but not used by Leiningen.\n  :pom-plugins [[com.theoryinpractise/clojure-maven-plugin \"1.3.13\"\n                 ;; this section is optional, values have the same syntax as pom-addition\n                 {:configuration [:sourceDirectories [:sourceDirectory \"src\"]]\n                  :extensions \"true\"\n                  :executions ([:execution [:id \"echodir\"]\n                                [:goals ([:goal \"run\"])]\n                                [:phase \"verify\"]])}]\n                [org.apache.tomcat.maven/tomcat7-maven-plugin \"2.1\"]\n                [com.google.appengine/appengine-maven-plugin \"1.9.68\"\n                 ;; Use a list to pass any structure unaltered\n                 (:configuration\n                  [:project \"foo\"]\n                  [:version \"bar\"])]]\n  ;; Include <scm> tag in generated pom.xml file. All key/value pairs\n  ;; appear exactly as configured. If absent, Leiningen will try to\n  ;; use information from a .git directory.\n  :scm {:name \"git\"\n        :tag \"098afd745bcd\"\n        :url \"http://127.0.0.1/git/my-project\"\n        ;; Allows you to use a repository in a different directory than the\n        ;; project's root, for instance, if you had multiple projects in a\n        ;; single git repository.\n        :dir \"..\"}\n  ;; Include xml in generated pom.xml file, as parsed by\n  ;; clojure.data.xml/sexp-as-element. Resulting pom still needs to\n  ;; validate according to the pom XML schema.\n  :pom-addition ([:developers [:developer\n                               [:id \"technomancy\"]\n                               [:name \"Phil Hagelberg\"]\n                               [:url \"https://technomancy.us\"]\n                               [:roles\n                                [:role \"developer\"]\n                                [:role \"maintainer\"]]]]\n                 [:contributors [:contributor\n                                 [:name \"Ben Bitdiddle\"]\n                                 [:url \"https://www.example.com/benjamin\"]\n                                 [:properties [:id \"benbit\"]]]])\n\n;;; Safety flags\n  ;; Indicate whether or not `lein install` should abort when trying to install\n  ;; releases. When false, trying to run `lein install` in a project with a version\n  ;; that isn't a snapshot will cause Leiningen to abort with a descriptive error\n  ;; message.\n  :install-releases? false\n  ;; Dictate which git branches deploys should be allowed from. When set,\n  ;; `lein deploy` will only work from the git branches included and will\n  ;; abort otherwise.\n  :deploy-branches [\"main\"]\n\n;;; Artifact Classifers Installation\n  ;; Option to install classified maven artifacts. A map where keys\n  ;; indicate the classifier name.\n  :classifiers {;; If the value is a map it is merged like a profile\n                :tests {:source-paths ^:replace [\"test\"]}\n                ;; If a keyword it is looked up from :profiles\n                :classy :my-profile})\n\n;;; Environment Variables used by Leiningen\n\n;; JAVA_CMD - executable to use for java(1)\n;; JVM_OPTS - extra options to pass to the java command\n;; DEBUG - increased verbosity\n;; LEIN_SILENT - suppress info-level output\n;; LEIN_HOME - directory in which to look for user settings\n;; LEIN_SNAPSHOTS_IN_RELEASE - allow releases to depend on snapshots\n;; LEIN_JVM_OPTS - tweak speed of plugins or fix compatibility with old Java versions\n;; LEIN_USE_BOOTCLASSPATH - speed up boot time on JVMs older than 9\n;; LEIN_REPL_HOST - interface on which to connect to nREPL server\n;; LEIN_REPL_PORT - port on which to start or connect to nREPL server\n;; LEIN_OFFLINE - equivalent of :offline? true but works for plugins\n;; LEIN_GPG - gpg executable to use for encryption/signing\n;; LEIN_NEW_UNIX_NEWLINES - ensure that `lein new` emits '\\n' as newlines\n;; LEIN_SUPPRESS_USER_LEVEL_REPO_WARNINGS - suppress \"repository in user profile\" warnings\n;; LEIN_FAST_TRAMPOLINE - memoize `java` invocation command to speed up subsequent trampoline launches\n;; LEIN_NO_USER_PROFILES - suppress loading of user and system profiles\n;; http_proxy - host and port to proxy HTTP connections through\n;; http_no_proxy - pipe-separated list of hosts which may be accessed directly\n"
  },
  {
    "path": "src/leiningen/change.clj",
    "content": "(ns leiningen.change\n  \"Rewrite project.clj by applying a function.\"\n  (:require [clojure.string :as str]\n            [clojure.zip :as zip]\n            [clojure.java.io :as io]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.main :as main]\n            [net.cgrand.sjacket :as sj]\n            [net.cgrand.sjacket.parser :as parser]))\n\n;;; Helpers\n\n(defn- fail-argument! [msg]\n  (throw (IllegalArgumentException. msg)))\n\n;; NOTE: The metadata will be printed out differently. E.g. ^:replace will be\n;; printed as ^{:replace true} -- but at least it is preserved.\n(defn- clj->sjacket [value]\n  (binding [*print-meta* true]\n    (-> value pr-str parser/parser :content first)))\n\n;; NOTE: this destroy comments, formatting, etc.\n(defn- sjacket->clj [value]\n  (if-not (or (#{:comment :whitespace :newline} (:tag value))\n              (#{\"]\" \"}\"} value))\n    (-> value sj/str-pt read-string)))\n\n(defn ^:internal normalize-path [value]\n  (if (coll? value)\n    value\n    (map keyword (remove empty? (str/split value #\":\")))))\n\n(defn ^:internal collapse-fn [f args]\n  (let [f (cond (ifn? f) f\n                (= \"set\" f) (constantly (first args))\n                (string? f) (or (utils/require-resolve (symbol f))\n                                (fail-argument! (str \"Unable to resolve \" f)))\n                :else (fail-argument! (str f \" is not a function.\")))]\n    #(apply f % args)))\n\n;;; Maven convention helpers\n\n(defn- split-name [name]\n  (str/split name #\"/\" 2))\n\n(defn- get-group-id [name]\n  (let [[group artifact] (split-name name)]\n    group))\n\n(defn- get-artifact-id [name]\n  (let [[group artifact] (split-name name)]\n    (or artifact group)))\n\n(defn- set-group-id [new-id name]\n  (let [[group artifact] (split-name name)]\n    (str new-id \"/\" (or artifact group))))\n\n(defn- set-artifact-id [new-id name]\n  (let [[group artifact] (split-name name)]\n    (if artifact\n      (str group \"/\" new-id)\n      new-id)))\n\n;;; Traversal\n\n(defn- defproject? [loc]\n  (let [{:keys [tag content]} (zip/node loc)]\n    (and (= :name tag)\n         (= [\"defproject\"] content))))\n\n(defn- insignificant? [loc]\n  (let [{:keys [tag]} (zip/node loc)]\n    (parser/space-nodes tag)))\n\n(defn- find-defproject [loc]\n  (->> loc\n       (iterate zip/next)\n       (take-while (comp not zip/end?))\n       (filter defproject?)\n       first))\n\n(defn- find-right [loc pred]\n  (->> loc\n      (iterate zip/right)\n      (take-while (comp not nil?))\n      (filter (comp pred zip/node))\n      first))\n\n(defn- find-dependency-version [loc groupid-artifactid]\n  \"Find the entry in a vector of dependencies or managed dependencies \n   whose first element matches the symbol bound to groupid-artifactid.  \n   Return the loc of the first string in that entry, which we assume\n   to be a version number.\"\n  (if-let [dependency (->> loc\n                           (iterate zip/right)\n                           (take-while (comp not nil?))\n                           (remove insignificant?)\n                           (filter (comp #{groupid-artifactid} \n                                         first\n                                         sjacket->clj\n                                         first))\n                           first)]\n    (-> dependency zip/down (find-right (comp #{:string} :tag)))\n    nil))\n\n(defn- find-key [loc key]\n  (->> loc\n       (iterate zip/right)\n       (take-while (comp not nil?))\n       (remove insignificant?)\n       (partition 2)\n       (map first)\n       (filter (comp #{key} sjacket->clj zip/node))\n       first))\n\n(defn- next-value [loc]\n  (->> loc\n       (iterate zip/right)\n       (take-while (comp not nil?))\n       (drop 1)\n       (remove insignificant?)\n       first))\n\n(defn- get-datatype [loc]\n  \"Get the datatype (e.g., :vector, :map) of the object at loc\"\n  (let [node (->> loc \n                  (iterate zip/right)\n                  (take-while (comp not nil?))\n                  (remove insignificant?)\n                  (filter (comp #{:string :map :vector} :tag zip/node))\n                  first\n                  zip/node)]\n    (:tag node)))\n\n(defn- parse-project [project-str]\n  (-> (parser/parser project-str)\n      zip/xml-zip\n      find-defproject\n      (or (fail-argument! \"Project definition not found\"))\n      zip/up))\n\n;;; Modifiers\n\n(defn- insert-entry [loc val]\n  (-> (if-not (= \"{\" (zip/node (zip/left loc)))\n        (zip/insert-left loc \" \")\n        loc)\n      (zip/insert-left (clj->sjacket val))))\n\n(defn- update-version [proj fn]\n  (-> proj\n      (find-right (comp #{:string} :tag))\n      (or (fail-argument! \"Project version not found\"))\n      (zip/edit (comp clj->sjacket fn sjacket->clj))\n      zip/root))\n\n\n(defn- update-name [proj fn]\n  (-> proj\n      zip/right\n      (find-right (comp #{:symbol} :tag))\n      (or (fail-argument! \"Project name not found\"))\n      (zip/edit (comp clj->sjacket symbol fn str sjacket->clj ))\n      zip/root))\n\n(defmulti ^:private get-loc-for-key \n  \"Given a node in the sjacket DOM with a known datatype (:map, :vector), \n   return the next node in the traversal with key p.\"\n  (fn [node datatype p] datatype))\n\n(defmethod get-loc-for-key :map [node datatype p]\n  (or (-> node \n          (find-key p)\n          next-value)\n      (-> node\n          zip/rightmost\n          (insert-entry p)\n          (insert-entry {})\n          zip/left)))\n\n(defmethod get-loc-for-key :vector [node datatype p]\n  (or (find-dependency-version node (symbol (namespace p) (name p)))\n      (-> node\n          zip/rightmost\n          (insert-entry [(symbol (namespace p) (name p)) \"\"])\n          zip/left\n          zip/down\n          zip/right\n          zip/right\n          zip/right)))\n\n\n(defn- update-setting [proj datatype [p & ath] fn]\n  (let [loc (get-loc-for-key proj datatype p)]\n    (if-not (empty? ath)\n      (recur (-> loc zip/down zip/right) (get-datatype loc) ath fn)\n      (zip/root\n       (zip/edit loc (comp clj->sjacket fn sjacket->clj))))))\n\n;;; Public API\n\n(defn change-string\n  \"Programmatic functional access to project.clj-rewriting.\n\nSee the `change` task function which handles reading and writing from disk as\nwell as turning string args into Clojure data; this function handles the rest.\"\n  [project-str key-or-path f & args]\n  (let [f (collapse-fn f args)\n        path (normalize-path key-or-path)\n        proj (parse-project project-str)]\n    (sj/str-pt\n     (condp = path\n       [:version] (update-version proj f)\n       [:name] (update-name proj f)\n       [:group-id] (update-name proj #(set-group-id (f (get-group-id %)) %))\n       [:artifact-id] (update-name proj #(set-artifact-id\n                                          (f (get-artifact-id %)) %))\n       ;; moving to the right to move past defproject to get nice key-value\n       ;; pairs whitespaces and project name and version are filtered out later\n       (update-setting (zip/right proj) :map path f)))))\n\n(defn change\n  \"Rewrite project.clj with f applied to the value at key-or-path.\n\nThe first argument should be a keyword,  or mashed-together keywords for\nnested values indicating which value to change). The second argument\nshould name a function var which will be called with the current value\nas its first argument and the remaining task arguments as the rest.\n\nThis will append \\\"-SNAPSHOT\\\" to the current version:\n\n    $ lein change version str '\\\"-SNAPSHOT\\\"'\n\nWhen called programmatically, you may pass a coll of keywords for the\nfirst arg or an actual function for the second.\n\nUsing set as the function argument will set the key directly, rather than\napplying a function to the original value:\n\n    $ lein change version set '\\\"1.0.0\\\"'\n\nTo update the version of a dependency in a :dependencies or\n:managed-dependencies vector, use this:\n\n    $ lein change :dependencies:org.clojure/clojure set '\\\"1.10.1\\\"'\n\nAll the arguments to f are passed through the reader, so double quoting is\nnecessary to use strings. Note that this task reads the project.clj file\nfrom disk rather than honoring the project map, so profile merging or\n`update-in` invocations will not affect it.\"\n  [project key-or-path f & args]\n  ;; cannot work with project map, want to preserve formatting, comments, etc\n  (when-not (and (every? string? args)\n                 (try (mapv read-string args) (catch Exception _)))\n    (main/abort \"Each argument to change task must be a readable string:\"\n                (pr-str args)))\n  (let [project-file (io/file (:root project) \"project.clj\")\n        source (slurp project-file)\n        args (map read-string args)]\n    (spit project-file (apply change-string source key-or-path f args))))\n"
  },
  {
    "path": "src/leiningen/check.clj",
    "content": "(ns leiningen.check\n  \"Check syntax and warn on reflection.\"\n  (:require [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [bultitude.core :as b]\n            [clojure.java.io :as io]))\n\n(defn check\n  \"Check syntax and warn on reflection.\"\n  ([project]\n     (let [source-files (map io/file (:source-paths project))\n           nses (sort (b/namespaces-on-classpath :classpath source-files\n                                                 :ignore-unreadable? false))\n           action `(let [failures# (atom 0)]\n                     (doseq [ns# '~nses]\n                       ;; load will add the .clj, so can't use ns/path-for.\n                       (let [ns-file# (-> (str ns#)\n                                          (.replace \\- \\_)\n                                          (.replace \\. \\/))]\n                         (binding [*out* *err*]\n                           (println \"Checking namespace\" ns#))\n                         (try\n                           (binding [*warn-on-reflection* true]\n                             (load ns-file#))\n                           (catch ExceptionInInitializerError e#\n                             (swap! failures# inc)\n                             (.printStackTrace e#)))))\n                     (if-not (zero? @failures#)\n                       (System/exit @failures#)))\n           project (assoc-in project [:global-vars '*warn-on-reflection*] true)\n           project (assoc project :target-path\n                          (str (:target-path project) \"/check\"))]\n       (try\n         (binding [eval/*pump-in* false]\n           (eval/eval-in-project project action))\n         (catch clojure.lang.ExceptionInfo e\n           (main/abort \"Failed.\"))))))\n"
  },
  {
    "path": "src/leiningen/classpath.clj",
    "content": "(ns leiningen.classpath\n  \"Print the classpath of the current project.\"\n  (:require [leiningen.core.classpath :as classpath]\n            [leiningen.core.main :as main]\n            [clojure.string :as str]))\n\n(defn get-classpath-string [project]\n  (try\n    (str/join java.io.File/pathSeparatorChar (classpath/get-classpath project))\n    (catch Exception e\n      (main/abort (.getMessage e)))))\n\n(defn classpath\n  \"Write the classpath of the current project to output-file.\n\nWith no arguments, print the classpath to stdout.\n\nSuitable for java's -cp option.\"\n  ([project]\n     (println (get-classpath-string project)))\n  ([project output-file]\n     (spit output-file (get-classpath-string project))))\n"
  },
  {
    "path": "src/leiningen/clean.clj",
    "content": "(ns leiningen.clean\n  \"Remove all files from project's target-path.\"\n  (:require [clojure.java.io :as io]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.main :as main])\n  (:import [java.io IOException]))\n\n(defn real-directory?\n  \"Returns true if this file is a real directory, false if it is a symlink or a\n  normal file.\"\n  [f]\n  (if (= :windows (utils/get-os))\n    (.isDirectory f)\n    (and (.isDirectory f)\n         (not (utils/symlink? f)))))\n\n(defn delete-file-recursively\n  \"Delete file f. If it's a directory, recursively delete all its contents.\n  Raise an exception if any deletion fails unless silently is true.\"\n  [f & [silently]]\n  (let [f (io/file f)]\n    (when (real-directory? f)\n      (doseq [child (.listFiles f)]\n        (delete-file-recursively child silently)))\n    (.setWritable f true)\n    (io/delete-file f silently)))\n\n(defn- protected-paths\n  \"Returns a set of leiningen project source directories and important files.\"\n  [project]\n  (let [root-dir (:root project)]\n    (->> [:source-paths :java-source-paths :test-paths :resource-paths]\n         (select-keys project)\n         (mapcat val)\n         (list* (io/file root-dir \"doc\")\n                (io/file root-dir \"project.clj\"))\n         (map io/file)\n         (map #(.getCanonicalPath %))\n         set)))\n\n(defn- protected-path?\n  \"Is path one of the leiningen project files or directories (which we expect to\n  be version controlled), or a descendant?\"\n  [project path]\n  (let [protected-paths (protected-paths project)]\n    (or (protected-paths (.getCanonicalPath (io/file path)))\n        (some #(utils/ancestor? % path) protected-paths))))\n\n(defn- protect-clean-targets?\n  \"Returns the value of :protect in the metadata map for the :clean-targets\n  value.\"\n  [project]\n  (-> project :clean-targets meta (get :protect true)))\n\n(defn- error-msg [& args]\n  (apply str (concat args\n                     \"\\nCheck :clean-targets\"\n                     \" or override this behavior by adding metadata ->\"\n                     \"\\n  :clean-targets ^{:protect false} [...targets...]\")))\n\n(defn- sanity-check\n  \"Ensure that a clean-target string refers to a directory that is sensible to\n  delete.\"\n  [project clean-target]\n  (when (and (string? clean-target)\n             (protect-clean-targets? project))\n    (cond (not (utils/ancestor? (:root project) clean-target))\n          (main/abort (error-msg \"Deleting path outside of the project root [\\\"\"\n                                 clean-target \"\\\"] is not allowed.\"))\n          (protected-path? project clean-target)\n          (main/abort (error-msg \"Deleting non-target project paths [\\\"\"\n                                 clean-target \"\\\"] is not allowed.\")))))\n\n(defn- with-parent-target-path\n  \"Assoc the :target-path sans the profile suffix, if any format\n  specifier is detected in the raw :target-path\"\n  [project]\n  (if-let [tp (->> project meta :without-profiles :target-path (re-find #\"(.*?)/[^/]*%\") second)]\n    (assoc project :target-path (if (.isAbsolute (io/file tp))\n                                  tp\n                                  (str (io/file (:root project) tp))))\n    project))\n\n(defn clean\n  \"Removes all files from paths in clean-targets for a project\"\n  [project]\n  (let [project (with-parent-target-path project)]\n    (doseq [target-key (:clean-targets project)]\n      (when-let [target (cond (vector? target-key)  (get-in project target-key)\n                          (keyword? target-key) (target-key project)\n                          (string? target-key)  target-key)]\n        (doseq [f (flatten [target])]\n          (sanity-check project f)\n          (delete-file-recursively f :silently))))))\n"
  },
  {
    "path": "src/leiningen/compile.clj",
    "content": "(ns leiningen.compile\n  \"Compile Clojure source into .class files.\"\n  (:require [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [bultitude.core :as b]\n            [clojure.java.io :as io])\n  (:refer-clojure :exclude [compile])\n  (:import (java.io PushbackReader File)))\n\n(defn regex? [str-or-re]\n  (instance? java.util.regex.Pattern str-or-re))\n\n(defn- matching-nses [re-or-sym namespaces]\n  (if (regex? re-or-sym)\n    (filter #(re-find re-or-sym (name %)) namespaces)\n    [re-or-sym]))\n\n(defn- find-namespaces-by-regex [project nses]\n  (let [avail-nses (->> (:source-paths project)\n                        (map io/file)\n                        (b/namespaces-on-classpath :classpath)\n                        (sort))]\n    (mapcat #(matching-nses % avail-nses) nses)))\n\n(defn compilable-namespaces\n  \"Returns a seq of the namespaces that are compilable, regardless of whether\n  their class files are present and up-to-date.\"\n  [{:keys [aot source-paths] :as project}]\n  (if (or (= :all aot) (= [:all] aot))\n    (sort (b/namespaces-on-classpath :classpath (map io/file source-paths)))\n    (find-namespaces-by-regex project aot)))\n\n(defn stale-namespaces\n  \"Return a seq of namespaces that are both compilable and that have missing or\n  out-of-date class files.\"\n  [project]\n  (for [namespace (compilable-namespaces project)\n        :let [[rel-source source]\n              (or (first (for [source-path (:source-paths project)\n                               rel-source (map (partial b/path-for namespace) [\"clj\" \"cljc\"])\n                               :let [file (io/file source-path rel-source)]\n                               :when (.exists ^File file)]\n                           [rel-source file]))\n                  (let [rel-source (b/path-for namespace)]\n                    ;; always return a source file location (#1205)\n                    [rel-source (io/file (first (:source-paths project)) rel-source)]))]\n        :when source\n        :let [rel-compiled (.replaceFirst rel-source \"\\\\.cljc?$\" \"__init.class\")\n              compiled (io/file (:compile-path project) rel-compiled)]\n        :when (>= (.lastModified source) (.lastModified compiled))]\n    namespace))\n\n;; .class file cleanup\n\n(defn- package-in-project?\n  \"Tests if the package found in the compile path exists as a directory in the\n  source path.\"\n  [found-path compile-path source-path]\n  (.isDirectory (io/file (.replace found-path compile-path source-path))))\n\n(defn- has-source-package?\n  \"Test if the class file's package exists as a directory in source-paths.\"\n  [project f source-paths]\n  (and source-paths\n       (let [[[parent] [_ _ proxy-mod-parent]]\n             (->> f, (iterate #(.getParentFile %)),\n                  (take-while identity), rest,\n                  (split-with #(not (re-find #\"^proxy\\$\" (.getName %)))))\n             found-path (.getPath (or proxy-mod-parent parent))\n             compile-path (:compile-path project)]\n         (some #(package-in-project? found-path compile-path %) source-paths))))\n\n(defn- source-in-project?\n  \"Tests if a file found in the compile path exists in the source path.\"\n  [parent compile-path source-path]\n  (let [path (.replace parent compile-path source-path)]\n    (or (.exists (io/file (str path \".clj\")))\n        (.exists (io/file (str path \".cljc\"))))))\n\n(defn- class-in-project? [project f]\n  (or (has-source-package? project f (:source-paths project))\n      (has-source-package? project f (:java-source-paths project))\n      (let [parent (.getParent f)\n            compile-path (:compile-path project)]\n        (some #(source-in-project? parent compile-path %) (:source-paths project)))))\n\n(defn- relative-path [project f]\n  (let [root-length (if (= \\/ (last (:compile-path project)))\n                      (count (:compile-path project))\n                      (inc (count (:compile-path project))))]\n    (subs (.getAbsolutePath f) root-length)))\n\n(defn- blacklisted-class? [project f]\n  ;; true indicates all non-project classes are blacklisted\n  (or (true? (:clean-non-project-classes project))\n      (some #(re-find % (relative-path project f))\n            (:clean-non-project-classes project))))\n\n(defn- whitelisted-class? [project f]\n  (or (class-in-project? project f)\n      (and (:class-file-whitelist project)\n           (re-find (:class-file-whitelist project)\n                    (relative-path project f)))))\n\n(defn clean-non-project-classes [project]\n  (when (:clean-non-project-classes project)\n    (doseq [f (file-seq (io/file (:compile-path project)))\n            :when (and (.isFile f)\n                       (not (whitelisted-class? project f))\n                       (blacklisted-class? project f))]\n      (.delete f))))\n\n(defn compilation-specs [cli-args]\n  (if (contains? #{[:all] [\":all\"]} cli-args)\n    [:all]\n    (->> cli-args\n         (map #(if (string? %) (read-string %) %))\n         (sort-by (comp not regex?)))))\n\n(def ^:private thread-factory-form\n  `(let [counter# (atom 0)]\n     (proxy [java.util.concurrent.ThreadFactory] []\n      (newThread [r#]\n        (let [thread-factory# (java.util.concurrent.Executors/defaultThreadFactory)]\n          (doto (.newThread thread-factory# r#)\n            (.setName (str \"leiningen-send-off-pool-\" (swap! counter# inc)))))))))\n\n(def ^:private set-agent-threadpool-form\n  ;; set-agent-send-off-executor! was introduced in Clojure 1.5\n  `(when-let [set-executor!# (resolve 'clojure.core/set-agent-send-off-executor!)]\n     (set-executor!#\n      (doto ^java.util.concurrent.ThreadPoolExecutor\n          (java.util.concurrent.Executors/newCachedThreadPool ~thread-factory-form)\n        (.setKeepAliveTime 100 java.util.concurrent.TimeUnit/MILLISECONDS)))))\n\n(defn compile\n  \"Compile Clojure source into .class files.\n\nUses the namespaces specified under :aot in project.clj or those given\nas command-line arguments. Use :all argument to compile everything. Pass\n#\\\"regular expressions\\\" to compile any matching namespaces. You may need\nto escape punctuation for your shell.\n\nThis should automatically happen when required if it's configured correctly; it\nshouldn't need to be manually invoked. See the javac task as well.\n\nCompiling code loads the namespace, so keep side-effects out of the top level.\nCode that should run on startup belongs in a -main defn.\"\n  ([project]\n   (if-let [namespaces (seq (stale-namespaces project))]\n     (let [ns-sym (gensym \"namespace\")\n           form `(do\n                   ~set-agent-threadpool-form\n                   (doseq [~ns-sym '~namespaces]\n                     ~(when main/*info*\n                        `(binding [*out* *err*]\n                           (println \"Compiling\" ~ns-sym)))\n                     (try\n                       (clojure.core/compile ~ns-sym)\n                       (catch Throwable t#\n                         (binding [*out* *err*]\n                           (println (.getMessage t#)))\n                         (throw t#)))))\n           project (update-in project [:prep-tasks]\n                              (partial remove #{\"compile\"}))]\n       (try (binding [eval/*eval-print-dup* true]\n              (eval/eval-in-project project form))\n            (catch Exception e\n              (main/abort \"Compilation failed:\" (.getMessage e)))\n            (finally (clean-non-project-classes project))))\n     (main/debug \"All namespaces already AOT compiled.\")))\n  ([project & args]\n   (compile (assoc project :aot (compilation-specs args)))))\n"
  },
  {
    "path": "src/leiningen/deploy.clj",
    "content": "(ns leiningen.deploy\n  \"Build and deploy jar to remote repository.\"\n  (:require [cemerick.pomegranate.aether :as aether]\n            [leiningen.core.classpath :as classpath]\n            [leiningen.core.main :as main]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.user :as user]\n            [leiningen.core.utils :as utils]\n            [clojure.java.io :as io]\n            [leiningen.pom :as pom]\n            [leiningen.jar :as jar]\n            [clojure.java.shell :as sh]\n            [clojure.string :as string]))\n\n(defn- abort-message [message]\n  (cond (re-find #\"Return code is 405\" message)\n        (str message \"\\n\" \"Ensure you are deploying over SSL.\")\n        (re-find #\"Return code is 401\" message)\n        (str message \"\\n\" \"See `lein help deploying` for an explanation of how\"\n             \" to specify credentials.\")\n        :else message))\n\n(defn add-auth-from-url\n  [[id settings]]\n  (let [url (utils/build-url id)\n        user-info (and url (.getUserInfo url))\n        [username password] (and user-info (.split user-info \":\"))]\n    (if username\n      [id (assoc settings :username username :password password)]\n      [id settings])))\n\n;; for some reason they nerfed Console so you can't use proxy with it,\n;; so we gotta do this the dipshit way to make it testable.\n(defn read-password-fn []\n  (if (System/console)\n    #(.readPassword (System/console) \"%s\" (into-array [%]))))\n\n(defn add-auth-interactively [[id settings]]\n  (if (or (and (:username settings) (some settings [:password :passphrase\n                                                    :private-key-file]))\n          (:no-auth settings)\n          (re-find #\"(file|scp|scpexe)://\" (str (:url settings))))\n    [id settings]\n    (do\n      (when @utils/rebound-io?\n        (main/abort \"No credentials found for \" id \"(did you mean `lein deploy\"\n                    \"clojars`?)\\nPassword prompts are not supported when ran\"\n                    \"after other (potentially)\\ninteractive tasks.\\nSee `lein\"\n                    \"help deploy` for an explanation of how to specify\"\n                    \"credentials.\"))\n      (print \"No credentials found for\" id)\n      (when (not= \"clojars\" id)\n        (print \"(did you mean `lein deploy clojars`?)\"))\n      (println \"\\nSee `lein help deploying` for how to configure credentials\"\n               \"to avoid prompts.\")\n      (print \"Username: \") (flush)\n      (let [username (read-line)\n            read-password (read-password-fn)\n            password (if read-password\n                       (apply str (read-password \"Password: \"))\n                       (do\n                         (println \"LEIN IS UNABLE TO TURN OFF ECHOING, SO\"\n                                  \"THE PASSWORD IS PRINTED TO THE CONSOLE\")\n                         (print \"Password: \")\n                         (flush)\n                         (read-line)))]\n        [id (assoc settings :username username :password password)]))))\n\n;; repo names must not contain path delimiters because they're used by\n;; aether for form filenames\n(defn- sanitize-repo-name [name]\n  (last (.split name \"/\")))\n\n(defn repo-for [project name]\n  (let [settings (merge (get (into {} (:repositories project)) name)\n                        (get (into {} (:deploy-repositories project)) name))]\n    (-> [(sanitize-repo-name name) (or settings {:url name})]\n        (classpath/add-repo-auth)\n        (add-auth-from-url)\n        (add-auth-interactively))))\n\n(defn signing-args\n  \"Produce GPG arguments for signing a file.\"\n  [file opts]\n  (let [key-spec (if-let [key (:gpg-key opts)]\n                   [\"--default-key\" key])]\n    `[\"--yes\" \"-ab\" ~@key-spec \"--\" ~file]))\n\n(defn sign\n  \"Create a detached signature and return the signature file name.\"\n  [file opts]\n  (let [{:keys [err exit]} (apply user/gpg (signing-args file opts))]\n    (when-not (zero? exit)\n      (main/abort \"Could not sign\"\n                  (str file \"\\n\" err (if err \"\\n\")\n                       \"\\nSee `lein help gpg` for how to set up gpg.\\n\"\n                       \"If you don't expect people to need to verify the \"\n                       \"authorship of your jar, you\\ncan add `:sign-releases \"\n                       \"false` to the relevant `:deploy-repositories` entry.\")))\n    (str file \".asc\")))\n\n(defn- ssh-keygen-cmd [file opts]\n  [\"ssh-keygen\" \"-Y\" \"sign\" \"-f\" (:ssh-key opts) \"-n\" \"file\" file])\n\n(defn- sign-ssh [file opts]\n  (when-not (zero? (apply eval/sh (ssh-keygen-cmd file opts)))\n    (main/abort \"Could not sign\" file))\n  (str file \".sig\"))\n\n(defn- signature-filename [coords extension]\n  (apply concat (update-in (apply hash-map coords) [:extension]\n                           #(str (or % \"jar\") extension))))\n\n(defn- gpg-signature-for-artifact [[coords artifact-file] opts]\n  (if (not= false (:gpg-key opts))\n    {(signature-filename coords \".asc\") (sign artifact-file opts)}))\n\n(defn- ssh-signature-for-artifact [[coords artifact-file] opts]\n  (if (:ssh-key opts)\n    {(signature-filename coords \".sig\") (sign-ssh artifact-file opts)}))\n\n(defn signature-for-artifact [artifact opts]\n  (merge (gpg-signature-for-artifact artifact opts)\n         (ssh-signature-for-artifact artifact opts)))\n\n(defn signatures-for-artifacts\n  \"Creates and returns the list of signatures for the artifacts needed to be\n  signed.\"\n  [artifacts sig-opts]\n  (let [total (count artifacts)]\n    (println \"Need to sign\" total \"files\")\n    (doall\n     (map-indexed\n      (fn [idx [coords artifact-file :as artifact]]\n        (printf \"[%d/%d] Signing %s\\n\" (inc idx) total artifact-file)\n        (flush)\n        (signature-for-artifact artifact sig-opts))\n      artifacts))))\n\n(defn sign-for-repo?\n  \"Generally sign artifacts for this repo?\"\n  [repo]\n  (:sign-releases (second repo) true))\n\n(defn signing-opts\n  \"Extract signing options map from a project.\"\n  [project repo]\n  (merge (:signing project) (:signing (second repo))))\n\n(defn files-for [project repo]\n  (let [signed? (sign-for-repo? repo)\n        ;; If pom is put in \"target/\", :auto-clean true will remove it if the\n        ;; jar is created afterwards. So make jar first, then pom.\n        artifacts (merge (jar/jar project)\n                         {[:extension \"pom\"] (pom/pom project)})\n        sig-opts (signing-opts project repo)]\n    (if (and signed? (not (.endsWith (:version project) \"-SNAPSHOT\")))\n      (reduce merge artifacts (signatures-for-artifacts artifacts sig-opts))\n      artifacts)))\n\n(defn warn-missing-metadata [project]\n  (doseq [key [:description :license :url]]\n    (when (or (nil? (project key)) (re-find #\"FIXME\" (str (project key))))\n      (main/warn \";; WARNING: please set\" key \"in project.clj.\"))))\n\n(defn- in-branches [branches]\n  (-> (sh/sh \"git\" \"rev-parse\" \"--abbrev-ref\" \"HEAD\")\n      :out\n      butlast\n      string/join\n      branches\n      not))\n\n(defn- extension [f]\n  (if-let [[_ signed-extension] (re-find #\"\\.([a-z]+\\.asc)$\" f)]\n    signed-extension\n    (if (= \"pom.xml\" (.getName (io/file f)))\n      \"pom\"\n      (last (.split f \"\\\\.\")))))\n\n(defn classifier\n  \"The classifier is be located between the version and extension name of the artifact.\n\n  See https://maven.apache.org/plugins/maven-deploy-plugin/examples/deploying-with-classifiers.html \"\n  [version f]\n  (let [pattern (re-pattern (format \"%s-(\\\\p{Alnum}*)\\\\.%s\" version (extension f)))\n        [_ classifier-of] (re-find pattern f)]\n    (if-not (empty? classifier-of)\n      classifier-of)))\n\n(defn- fail-on-empty-project [project]\n  (when-not (:root project)\n    (main/abort \"Couldn't find project.clj, which is needed for deploy task\")))\n\n(defn ^:no-project-needed deploy\n  \"Deploy jar and pom to remote repository.\n\nThe target repository will be looked up in :repositories in project.clj:\n\n  :repositories [[\\\"snapshots\\\" \\\"https://internal.repo/snapshots\\\"]\n                 [\\\"releases\\\" \\\"https://internal.repo/releases\\\"]\n                 [\\\"alternate\\\" \\\"https://other.server/repo\\\"]]\n\nIf you don't provide a repository name to deploy to, either \\\"snapshots\\\" or\n\\\"releases\\\" will be used depending on your project's current version. You may\nprovide a repository URL instead of a name.\n\nSee `lein help deploying` under \\\"Authentication\\\" for instructions on\nhow to configure your credentials so you are not prompted on each\ndeploy.\n\nYou can also deploy arbitrary artifacts from disk:\n\n    $ lein deploy myrepo com.blueant/fancypants 1.0.1 fancypants.jar pom.xml\n\nThe repository can be defined in defproject or a profile, or it can be a URL.\nUse file://$HOME/.m2/repository to install in the local repo.\n\nWhile this works with any arbitrary files on disk, downstream projects will not\nbe able to depend on jars that are deployed without a pom.\"\n  ([project]\n     (deploy project (if (pom/snapshot? project)\n                       \"snapshots\"\n                       \"releases\")))\n  ([project repository]\n     (fail-on-empty-project project)\n     (let [branches (set (:deploy-branches project))]\n       (when (and (seq branches)\n                  (in-branches branches))\n         (apply main/abort \"Can only deploy from branches listed in\"\n                \":deploy-branches:\" branches)))\n     (warn-missing-metadata project)\n     (let [repo (repo-for project repository)\n           files (files-for project repo)]\n       (try\n         (java.lang.System/setProperty \"aether.checksums.forSignature\" \"true\")\n         (main/debug \"Deploying\" files \"to\" repo)\n         (aether/deploy\n          :coordinates [(symbol (:group project) (:name project))\n                        (:version project)]\n          :artifact-map files\n          :transfer-listener :stdout\n          :repository [repo]\n          :proxy (classpath/get-proxy-settings))\n         (catch org.eclipse.aether.deployment.DeploymentException e\n           (when main/*debug* (.printStackTrace e))\n           (main/abort (abort-message (.getMessage e)))))))\n  ([project repository identifier version & files]\n     (let [identifier (symbol identifier)\n           artifact-id (name identifier)\n           group-id (namespace identifier)\n           repo (repo-for project repository)\n           artifacts (for [f files]\n                       [[:extension (extension f)\n                         :classifier (classifier version f)] f])]\n       (java.lang.System/setProperty \"aether.checksums.forSignature\" \"true\")\n       (main/debug \"Deploying\" files \"to\" repo)\n       (aether/deploy\n        :coordinates [(symbol group-id artifact-id) version]\n        :artifact-map (into {} artifacts)\n        :transfer-listener :stdout\n        :repository [repo]\n        :local-repo (:local-repo project)\n        :proxy (classpath/get-proxy-settings)))))\n"
  },
  {
    "path": "src/leiningen/deps.clj",
    "content": "(ns leiningen.deps\n  \"Download and examine dependencies.\"\n  (:require [leiningen.core.classpath :as classpath]\n            [leiningen.core.main :as main]\n            [leiningen.core.project :as project]\n            [leiningen.core.user :as user]\n            [clojure.pprint :as pprint]\n            [leiningen.core.utils :as utils]\n            [cemerick.pomegranate.aether :as aether])\n  (:import (org.eclipse.aether.resolution DependencyResolutionException)))\n\n(defn- walk-deps\n  ([deps f level]\n     (doseq [[dep subdeps] deps]\n       (f dep level)\n       (when subdeps\n         (walk-deps subdeps f (inc level)))))\n  ([deps f]\n     (walk-deps deps f 0)))\n\n(defn- print-dep [dep level]\n  (println (apply str (repeat (* 2 level) \\space)) (pr-str dep)))\n\n(defn- print-path [steps]\n  (doseq [[dep version level] steps]\n    (print-dep [dep version] level)))\n\n(defn- why-deps\n  ([deps target path]\n   (doseq [[[dep version] subdeps] deps]\n     (when (= target dep)\n       (doall (map-indexed #(println (apply str (repeat %1 \"  \")) %2)\n                           (conj path [dep version]))))\n     (when subdeps\n       (why-deps subdeps target (conj path [dep version])))))\n  ([deps target]\n   (why-deps deps target [])))\n\n\f\n\n(declare check-signature)\n\n(defn- fetch-key [signature err]\n  (if (or (re-find #\"Can't check signature: public key not found\" err)\n          (re-find #\"Can't check signature: No public key\" err))\n    (let [key (second (re-find #\"using \\w+ key(?: ID)? (.+)\" err))\n          {:keys [err exit]} (user/gpg \"--recv-keys\" \"--\" key)]\n      (if (and (zero? exit)\n               (not (re-find #\"new key but contains no user ID - skipped\" err)))\n        (check-signature signature)\n        :no-key))\n    :bad-signature))\n\n(defn- check-signature [signature]\n  (let [{:keys [err exit]} (user/gpg \"--verify\" \"--\" (str signature))]\n    (if (zero? exit)\n      :signed ; TODO distinguish between signed and trusted\n      (fetch-key signature err))))\n\n(defn- get-signature [project dep]\n  (let [dep-map (assoc (apply hash-map (drop 2 dep))\n                  ;; TODO: check pom signature too\n                  :extension \"jar.asc\")\n        dep (into (vec (take 2 dep)) (apply concat dep-map))]\n    (try (->> (apply aether/resolve-dependencies\n                (apply concat\n                  (assoc (classpath/default-aether-args project) :coordinates [dep])))\n              (aether/dependency-files)\n              (filter #(.endsWith (.getName %) \".asc\"))\n              (first))\n         (catch DependencyResolutionException _))))\n\n(defn- verify [project dep _]\n  (let [signature (get-signature project dep)\n        status (if signature\n                 (check-signature signature)\n                 :unsigned)]\n    ;; TODO: support successful exit code only on fully-signed deps\n    (println status (pr-str dep))))\n\f\n\n(def tree-command\n  \"A mapping from the tree-command to the dependency key it should print a tree\n  for.\"\n  {\":tree\" [:dependencies :managed-dependencies]\n   \":tree-data\" [:dependencies :managed-dependencies]\n   \":plugin-tree\" [:plugins nil]\n   \":plugin-tree-data\" [:plugins nil]})\n\n\f\n\n(defn print-implicits [project type]\n  (when-let [implicits (seq (filter utils/require-resolve\n                                    (project/plugin-vars project type)))]\n    (println (str \"Implicit \" (name type) \":\"))\n    (doseq [i implicits] (println \" \" i))))\n\n\f\n\n(defn query [project artifact version-string]\n  (let [artifact (symbol artifact)]\n    (->> (assoc project :query [[artifact version-string]])\n         (classpath/get-dependencies :query nil)\n         keys\n         (filter #(= artifact (first %)))\n         first second println)))\n\n\f\n\n(defn deps\n  \"Download and examine dependencies.\n\n    lein deps :tree\n\nShow the full dependency tree for the current project. Each dependency is only\nshown once within a tree.\n\n    lein deps :tree-data\n\nShow the full dependency tree as above, but in EDN format.\n\n    lein deps :plugin-tree\n\nShow the full dependency tree for the plugins in the current project.\n\n    lein deps :plugin-tree-data\n\nShow the full dependency tree for the plugins in the current project as above, but in EDN format.\n\n    lein deps :verify\n\nCheck signatures of each dependency. ALPHA: subject to change.\n\n    lein deps :implicits\n\nList the implicit middleware and hooks that will be activated by the current\nset of plugins. Useful for debugging unexplained behaviour.\n\n    lein deps :why org.clojure/core.logic\n\nShow just the path in the dependency tree directly relating to why a\nspecific dependency has been included.\n\n    lein deps :query circleci/circleci.test 0.3.0-SNAPSHOT\n\nLook up the version number for a dependency in the remote repositories and\nprint a resolved version. If omitted, the version defaults to \\\"RELEASE\\\". Can\nresolve SNAPSHOT versions to timestamps.\n\n    lein deps\n\nForce Leiningen to download the dependencies it needs. This usage is\ndeprecated as it should happen automatically on demand.\n\nNormally snapshot dependencies will be checked once every 24 hours; to\nforce them to be updated, use `lein -U $TASK`.\"\n  ([project]\n     (deps project nil))\n  ([project command]\n     (try\n       (cond (= \":implicits\" command)\n             (do (print-implicits project :middleware)\n                 (print-implicits project :hooks))\n             (tree-command command)\n             (let [project (project/merge-profiles\n                            project\n                            [{:pedantic? (quote ^:displace warn)}])\n                   [dependencies-key managed-dependencies-key] (tree-command command)\n                   hierarchy (classpath/managed-dependency-hierarchy\n                              dependencies-key\n                              managed-dependencies-key\n                              project)]\n               (case command\n                 \":tree\" (walk-deps hierarchy print-dep)\n                 \":plugin-tree\" (walk-deps hierarchy print-dep)\n                 \":tree-data\"  (binding [*print-length* 10000 *print-level* 10000]\n                                 (pprint/pprint hierarchy))\n                 \":plugin-tree-data\" (binding [*print-length* 10000 *print-level* 10000]\n                                       (pprint/pprint hierarchy))))\n             (= command \":verify\")\n             (if (user/gpg-available?)\n               (walk-deps (classpath/managed-dependency-hierarchy\n                           :dependencies\n                           :managed-dependencies\n                           project)\n                          (partial verify project))\n               (main/abort (str \"Could not verify - gpg not available.\\n\"\n                                \"See `lein help gpg` for how to setup gpg.\")))\n             (empty? command) (classpath/resolve-managed-dependencies\n                               :dependencies :managed-dependencies project)\n             :else (main/abort \"Unknown deps command\" command))\n       (catch DependencyResolutionException e\n         (main/abort (.getMessage e)))))\n  ([project command target]\n   (cond (= command \":query\")\n         (deps project command target \"RELEASE\")\n         (re-find #\"^:why+$\" command)\n         (why-deps (classpath/managed-dependency-hierarchy :dependencies\n                                                           :managed-dependencies\n                                                           project)\n                   (symbol target))\n         :else (main/abort \"Unknown deps command\" command)))\n  ([project command artifact version-string]\n   (when (not= \":query\" command)\n     (main/abort \"Unknown deps command\" command))\n   (query project artifact version-string)))\n"
  },
  {
    "path": "src/leiningen/do.clj",
    "content": "(ns leiningen.do\n  \"Higher-order task to perform other tasks in succession.\"\n  (:refer-clojure :exclude [do])\n  (:require [leiningen.core.main :as main]))\n\n(defn- conj-to-last [coll x]\n  (update-in coll [(dec (count coll))] conj x))\n\n(defn- butlast-char\n  \"Removes the last character in the string.\"\n  [s]\n  (subs s 0 (dec (count s))))\n\n(defn- pop-if-last\n  \"Pops the collection if (pred (peek coll)) is truthy.\"\n  [coll pred]\n  (if (pred (peek coll))\n    (pop coll)\n    coll))\n\n(defn ^:internal group-args\n  ([args]  (-> (reduce group-args [[]] args)\n               (pop-if-last empty?)))\n  ([groups arg]\n     (cond (coll? arg) (-> (pop-if-last groups empty?)\n                           (conj arg []))\n           (.endsWith arg \",\") (-> groups\n                                   (conj-to-last (butlast-char arg))\n                                   (conj []))\n           :else (conj-to-last groups arg))))\n\n(defn ^:no-project-needed ^:higher-order do\n  \"Higher-order task to perform other tasks in succession.\n\nEach comma-separated group should be a task name followed by optional arguments.\n\nUSAGE: lein do test, compile :all, deploy private-repo\"\n  [project & args]\n  (doseq [arg-group (group-args args)]\n    (main/resolve-and-apply project arg-group)))\n"
  },
  {
    "path": "src/leiningen/help.clj",
    "content": "(ns leiningen.help\n  \"Display a list of tasks or help for a given task.\"\n  (:require [clojure.string :as string]\n            [clojure.java.io :as io]\n            [leiningen.core.main :as main]\n            [bultitude.core :as b]))\n\n(def docstrings\n  (memoize\n   (fn []\n     (apply hash-map\n            (mapcat (juxt second b/doc-from-ns-form)\n                    (b/namespace-forms-on-classpath :prefix \"leiningen\"))))))\n\n(def ^{:private true\n       :doc \"Width of task name column in list of tasks produced by help task.\"}\n  task-name-column-width 20)\n\n(defn- get-arglists [task]\n  (for [args (or (:help-arglists (meta task)) (:arglists (meta task)))]\n    (vec (remove #(= 'project %) args))))\n\n(def ^:private help-padding 3)\n\n(defn- formatted-docstring [command docstring padding]\n  (apply str\n         (replace\n          {\\newline\n           (apply str\n                  (cons \\newline (repeat (+ padding (count command)) \\space)))}\n          docstring)))\n\n(defn- formatted-help [command docstring longest-key-length]\n  (let [padding (+ longest-key-length help-padding (- (count command)))]\n    (format (str \"%1s\" (apply str (repeat padding \\space)) \"%2s\")\n            command\n            (formatted-docstring command docstring padding))))\n\n(defn- get-subtasks-and-docstrings-for [task]\n  (into {}\n        (map (fn [subtask]\n               (let [m (meta subtask)]\n                 [(str (:name m)) (first (.split (:doc m \"\") \"\\n\"))]))\n             (:subtasks (meta task)))))\n\n(defn subtask-help-for\n  [task-ns task]\n  (if-let [subtasks (seq (get-subtasks-and-docstrings-for task))]\n    (let [longest-key-length (apply max (map count (keys subtasks)))]\n      (string/join \"\\n\" (concat [\"\\n\\nSubtasks available:\"]\n                                (for [[subtask doc] subtasks]\n                                  (formatted-help subtask doc\n                                                  longest-key-length))\n                                [(str \"\\nRun `lein help \" (:name (meta task))\n                                      \" $SUBTASK` for subtask details.\")])))))\n\n(defn- resolve-task [task-name]\n  (try (let [task-ns (doto (symbol (str \"leiningen.\" task-name)) require)\n             task (ns-resolve task-ns (symbol task-name))]\n         [task-ns task])\n       (catch java.io.FileNotFoundException e\n         [nil nil])))\n\n(defn- resolve-subtask [task-name subtask-name]\n  (let [[_ task] (resolve-task task-name)]\n    (some #(if (= (symbol subtask-name) (:name (meta %))) %)\n          (:subtasks (meta task)))))\n\n(defn- clean-static-help\n  \"Returns a string containing help content. Removes doctoc comments if they\n  are present.\"\n  [help-text]\n   (let [doctoc-text \"<!-- END doctoc generated TOC please keep comment here to allow auto update -->\"]\n     (if (string/includes? help-text doctoc-text)\n       (string/triml (second (string/split help-text (re-pattern doctoc-text))))\n       help-text)))\n\n(defn- static-help [name]\n  (if-let [resource (io/resource (format \"leiningen/help/%s\" name))]\n    (clean-static-help (slurp resource))))\n\n(declare help-for)\n\n(defn- alias-help\n  \"Returns a string containing help for an alias, or nil if the string is not an\n  alias.\"\n  [aliases task-name]\n  (if (aliases task-name)\n    (let [alias-expansion (aliases task-name)\n          explanation (-> alias-expansion meta :doc)]\n      (cond explanation (str task-name \": \" explanation)\n            (string? alias-expansion) (str\n                                       (format\n                                        (str \"'%s' is an alias for '%s',\"\n                                             \" which has following help doc:\\n\")\n                                        task-name alias-expansion)\n                                       (help-for alias-expansion))\n            :no-explanation-or-string (str task-name \" is an alias, expands to \"\n                                           alias-expansion)))))\n\n(defn help-for\n  \"Returns a string containing help for a task.\n  Looks for a function named 'help' in the subtask's namespace, then a docstring\n  on the task, then a docstring on the task ns.\"\n  ([task-name]\n     (let [[task-ns task] (resolve-task task-name)]\n       (if task\n         (let [help-fn (ns-resolve task-ns 'help)]\n           (str (or (and (not= task-ns 'leiningen.help) help-fn (help-fn))\n                    (:doc (meta task))\n                    (:doc (meta (find-ns task-ns))))\n                (subtask-help-for task-ns task)\n                (if (some seq (get-arglists task))\n                  (str \"\\n\\nArguments: \" (pr-str (get-arglists task))))))\n         (main/abort (format \"Task: '%s' not found\" task-name)))))\n  ([project task-name]\n     (let [aliases (merge main/aliases (:aliases project))]\n       (or (alias-help aliases task-name)\n           (help-for task-name)))))\n\n(defn help-for-subtask\n  \"Returns a string containing help for a subtask.\n  Looks for a function named 'help-<subtask>' in the subtask's namespace,\n  using the subtask's docstring if the help function is not found.\"\n  ([task-name subtask-name]\n     (if-let [subtask (resolve-subtask task-name subtask-name)]\n       (let [subtask-meta (meta subtask)\n             help-fn (ns-resolve (:ns subtask-meta)\n                                 (symbol (str \"help-\" subtask-name)))\n             arglists (get-arglists subtask)]\n         (str (or (and help-fn (help-fn)) (:doc subtask-meta))\n              (if (some seq arglists)\n                (str \"\\n\\nArguments: \" (pr-str arglists)))))\n       (main/abort (format \"Subtask: '%s %s' not found\" task-name subtask-name))))\n  ([project task-name subtask-name]\n     (let [aliases (merge main/aliases (:aliases project))]\n       (help-for-subtask (aliases task-name task-name) subtask-name))))\n\n(defn help-summary-for [task-ns]\n  (try (let [task-name (last (.split (name task-ns) \"\\\\.\"))]\n         ;; Use first line of task docstring if ns metadata isn't present\n         (str task-name (apply str (repeat (- task-name-column-width\n                                              (count task-name)) \" \"))\n              (or (task-ns (docstrings))\n                  (first (.split (help-for {} task-name) \"\\n\")))))\n       (catch Throwable e\n         (binding [*out* *err*]\n           (str task-ns \"  Problem loading: \" (.getMessage e))))))\n\n(defn ^:no-project-needed ^:higher-order help\n  \"Display a list of tasks or help for a given task or subtask.\n\nAlso provides readme, faq, tutorial, news, sample, profiles,\ndeploying, mixed-source, templates, and copying info.\"\n  ([project task subtask] (println (or (static-help (str task \"-\" subtask))\n                                       (help-for-subtask project task subtask))))\n  ([project task] (println (or (static-help task) (help-for project task))))\n  ([project]\n     (println \"Leiningen is a tool for working with Clojure projects.\\n\")\n     (println \"Several tasks are available:\")\n     (doseq [task-ns (main/tasks)]\n       (println (help-summary-for task-ns)))\n     (println \"\\nRun `lein help $TASK` for details.\")\n     (println \"\\nGlobal Options:\")\n     (println \"  -o             Run a task offline.\")\n     (println \"  -U             Run a task after forcing update of snapshots.\")\n     (println \"  -h, --help     Print this help or help for a specific task.\")\n     (println \"  -v, --version  Print Leiningen's version.\")\n     (when-let [aliases (:aliases project)]\n       (println \"\\nThese aliases are available:\")\n       (doseq [[k v] aliases]\n         (if-let [explanation (-> v meta :doc)]\n           (println (str k \": \" explanation))\n           (println (str k  \", expands to \" v)))))\n     (println \"\\nSee also: readme, faq, tutorial, news, sample, profiles,\"\n              \"deploying, gpg,\\nmixed-source, templates, and copying.\")))\n"
  },
  {
    "path": "src/leiningen/install.clj",
    "content": "(ns leiningen.install\n  \"Install the current project to the local repository.\"\n  (:require [cemerick.pomegranate.aether :as aether]\n            [leiningen.core.project :as project]\n            [leiningen.core.main :as main]\n            [leiningen.jar :as jar]\n            [leiningen.pom :as pom]\n            [clojure.java.io :as io])\n  (:import (java.util.jar JarFile)\n           (java.util UUID)))\n\n(defn install\n  \"Install jar and pom to the local repository; typically ~/.m2.\n\nIn order to install arbitrary files into a repository see the deploy task.\"\n  [project]\n  (when (not (or (:install-releases? project true)\n                 (pom/snapshot? project)))\n    (main/abort \"Can't install release artifacts when :install-releases?\"\n                \"is set to false.\"))\n  (let [jarfiles (jar/jar project)\n        pomfile (pom/pom project)\n        local-repo (:local-repo project)]\n    (aether/install\n     :coordinates [(symbol (:group project) (:name project))\n                   (:version project)]\n     :artifact-map jarfiles\n     :pom-file (io/file pomfile)\n     :local-repo local-repo)\n    (main/info (str \"Installed jar and pom into \" (if local-repo\n                                                    local-repo \"local repo\") \".\"))))\n"
  },
  {
    "path": "src/leiningen/jar.clj",
    "content": "(ns leiningen.jar\n  \"Package up all the project's files into a jar file.\"\n  (:require [leiningen.pom :as pom]\n            [leiningen.clean :as clean]\n            [leiningen.compile :as compile]\n            [leiningen.core.project :as project]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]\n            [bultitude.core :as b]\n            [clojure.set :as set]\n            [clojure.string :as string]\n            [clojure.java.io :as io])\n  (:import (java.util.jar Manifest JarEntry JarOutputStream)\n           (java.io BufferedOutputStream FileOutputStream\n                    ByteArrayInputStream)))\n\n(def ^:deprecated whitelist-keys\n  \"Deprecated: use leiningen.core.project/whitelist-keys instead\"\n  project/whitelist-keys)\n\n(defn- unix-path [path]\n  (.replace path \"\\\\\" \"/\"))\n\n(defn- default-manifest [project]\n  {\"Created-By\" (str \"Leiningen \" (main/leiningen-version))\n   \"Built-By\" (System/getProperty \"user.name\")\n   \"Build-Jdk\" (System/getProperty \"java.version\")\n   \"Leiningen-Project-ArtifactId\" (:name project)\n   \"Leiningen-Project-GroupId\" (:group project)\n   \"Leiningen-Project-Version\" (:version project)})\n\n(declare ^:private manifest-entry)\n\n(defn- manifest-entries [project manifest-seq]\n  (map (partial manifest-entry project) manifest-seq))\n\n(defn- manifest-entry [project [k v]]\n  (cond (symbol? v) (manifest-entry project [k (resolve v)])\n        (fn? v) (manifest-entry project [k (v project)])\n        (coll? v) (->> v ;; Sub-manifest = manifest section\n                       (manifest-entries project)\n                       (cons (str \"\\nName: \" (name k) \"\\n\"))\n                       (string/join))\n        :else (->> (str (name k) \": \" v)\n                   (partition-all 70)  ;; Manifest spec says lines <= 72 chars\n                   (map (partial apply str))\n                   (string/join \"\\n \")  ;; Manifest spec says join with \"\\n \"\n                   (format \"%s\\n\"))))\n\n(defn- place-sections-last\n  \"Places sections at the end of the manifest seq, as specified by the\n  Manifest spec. Retains ordering otherwise (if mf is ordered).\"\n  [mf]\n  (sort-by val (fn [v1 v2]\n                 (and (not (coll? v1)) (coll? v2)))\n           (seq mf)))\n\n(defn ^:internal make-manifest [project]\n  (let [project-manifest (into {} (:manifest project))\n        default-manifest' (cond-> (default-manifest project)\n                            ;; Add default \"Main-Class\" only if :main is not\n                            ;; explicitly set to nil\n                            (:main project :not-found)\n                            (assoc \"Main-Class\"\n                                   (munge (str (:main project 'clojure.main)))))]\n    (->> (merge default-manifest' project-manifest)\n         ;; manifest's \"Main-Class\" always overrides default \"Main-Class\"\n         place-sections-last\n         (manifest-entries project)\n         (cons \"Manifest-Version: 1.0\\n\") ;; Manifest-Version line must be first\n         (string/join \"\")\n         .getBytes\n         ByteArrayInputStream.\n         Manifest.)))\n\n(defn ^:internal manifest-map [manifest]\n  (let [attrs (.getMainAttributes manifest)]\n    (zipmap (map str (keys attrs)) (vals attrs))))\n\n(defn- added-file?\n  \"Returns true if the file is already added to the jar, false otherwise. Prints\n  a warning if the file is not a directory.\"\n  [file relative-path added-paths]\n  ;; Path may be blank if it is the root path\n  (if (or (string/blank? relative-path) (added-paths relative-path))\n    (do\n      (when-not (.isDirectory file)\n        (main/info \"Warning: skipped duplicate file:\" relative-path))\n      true)))\n\n(defn- skip-file?\n  \"Skips the file if it doesn't exist. If the file is not the\n  root-file (specified by :path), will also skip it if it is a dotfile, emacs\n  backup file or matches an exclusion pattern.\"\n  [file relative-path root-file exclusion-patterns inclusion-patterns]\n  (or (not (.exists file))\n      (and\n       (not= file root-file)\n       (not (some #(re-find % relative-path) inclusion-patterns))\n       (or\n        (re-find #\"^\\.?#\" (.getName file))\n        (re-find #\"~$\" (.getName file))\n        (some #(re-find % relative-path) exclusion-patterns)))))\n\n(defmulti ^:private copy-to-jar (fn [project jar-os acc spec] (:type spec)))\n\n(defn- relativize-path\n  \"Relativizes a path: Removes the root-path of a path if not already removed.\"\n  [path root-path]\n  (if (.startsWith path root-path)\n    (.substring path (.length root-path))\n    path))\n\n(defn- full-path ;; Q: is this a good name for this action?\n  \"Appends the path string with a '/' if the file is a directory.\"\n  [file path]\n  (if (.isDirectory file)\n    (str path \"/\")\n    path))\n\n(defn- dir-string\n  \"Returns the file's directory as a string, or the string representation of the\n  file itself if it is a directory.\"\n  [file]\n  (if-not (.isDirectory file)\n    (str (.getParent file) \"/\")\n    (str file \"/\")))\n\n(defn- put-jar-entry!\n  \"Adds a jar entry to the Jar output stream.\"\n  [jar-os file path]\n  (.putNextEntry jar-os (doto (JarEntry. path)\n                       (.setTime (.lastModified file))))\n  (when-not (.isDirectory file)\n    (io/copy file jar-os)))\n\n(defmethod copy-to-jar :path [project jar-os acc spec]\n  (let [root-file (io/file (:path spec))\n        root-dir-path (unix-path (dir-string root-file))\n        paths (for [child (file-seq root-file)\n                    :let [path (relativize-path\n                                 (full-path child (unix-path (str child)))\n                                 root-dir-path)]]\n                (when-not (or (skip-file? child path root-file\n                                          (:jar-exclusions project)\n                                          (:jar-inclusions project))\n                              (added-file? child path acc))\n                  (put-jar-entry! jar-os child path)\n                  path))]\n    (into acc paths)))\n\n(defmethod copy-to-jar :paths [project jar-os acc spec]\n  (reduce (partial copy-to-jar project jar-os) acc\n          (for [path (:paths spec)]\n            {:type :path :path path})))\n\n(defmethod copy-to-jar :bytes [project jar-os acc spec]\n  (let [path (unix-path (:path spec))]\n    (when-not (some #(re-find % path) (:jar-exclusions project))\n      (.putNextEntry jar-os (JarEntry. path))\n      (let [bytes (if (string? (:bytes spec))\n                    (.getBytes (:bytes spec))\n                    (:bytes spec))]\n        (io/copy (ByteArrayInputStream. bytes) jar-os)))\n    (conj acc path)))\n\n(defmethod copy-to-jar :fn [project jar-os acc spec]\n  (let [f (eval (:fn spec))\n        dynamic-spec (f project)]\n    (copy-to-jar project jar-os acc dynamic-spec)))\n\n(defn write-jar [project out-file filespecs]\n  (with-open [jar-os (-> out-file\n                         (FileOutputStream.)\n                         (BufferedOutputStream.)\n                         (JarOutputStream. (make-manifest project)))]\n    (let [jar-paths (reduce (partial copy-to-jar project jar-os)\n                            #{}\n                            filespecs)]\n      (if (:main project)\n        (let [main-path (str (-> (string/replace (:main project) \".\" \"/\")\n                                 (string/replace \"-\" \"_\"))\n                              \".class\")]\n          (when-not (some #{main-path} jar-paths)\n            (main/info \"Warning: The Main-Class specified does not exist\"\n                       \"within the jar. It may not be executable as expected.\"\n                       \"A gen-class directive may be missing in the namespace\"\n                       \"which contains the main method, or the namespace has not\"\n                       \"been AOT-compiled.\"))))\n      jar-paths)))\n\n;; TODO: change in 3.0; this is hideous\n(defn- filespecs [project]\n  (let [root-files (.list (io/file (:root project)))\n        readmes (filter (partial re-find #\"^(?i)readme\") root-files)\n        licenses (filter (partial re-find #\"^(?i)license\") root-files)\n        scope (partial format \"META-INF/leiningen/%s/%s/%s\"\n                       (:group project) (:name project))]\n    (concat [{:type :bytes\n              :path (format \"META-INF/maven/%s/%s/pom.xml\"\n                            (:group project) (:name project))\n              :bytes (.getBytes (pom/make-pom project))}\n             {:type :bytes :path (scope \"project.clj\")\n              :bytes (.getBytes (slurp (str (:root project) \"/project.clj\")))}]\n            (for [doc (map (partial io/file (:root project))\n                        (concat readmes licenses))\n                  :when (.isFile doc)]\n              {:type :bytes :path (scope (.getName doc))\n               :bytes (.getBytes (slurp doc))})\n            [{:type :path :path (:compile-path project)}\n             {:type :paths :paths (distinct (:resource-paths project))}]\n            (if-not (:omit-source project)\n              [{:type :paths\n                :paths (distinct (concat (:source-paths project)\n                                         (:java-source-paths project)))}])\n            (:filespecs project))))\n\n;; Split out backwards-compatibility. Collapse into get-jar-filename for 3.0\n(defn get-classified-jar-filename [project classifier]\n  (let [target (doto (io/file (:target-path project)) utils/mkdirs)\n        suffix (if classifier (str \"-\" (name classifier) \".jar\") \".jar\")\n        name-kw (if (= classifier :standalone) :uberjar-name :jar-name)\n        jar-name (or (project name-kw) (str (:name project) \"-%s\" suffix))\n        jar-name (format jar-name (:version project))]\n    (str (io/file target jar-name))))\n\n(defn- compile-main? [{:keys [main source-paths] :as project}]\n  (and main (not (:skip-aot (meta main)))\n       (some #(or (.exists (io/file % (b/path-for main \"clj\")))\n                  (.exists (io/file % (b/path-for main \"cljc\")))) source-paths)))\n\n(def ^:private implicit-aot-warning\n  (delay\n   (main/info \"Warning: specified :main without including it in :aot.\"\n              \"\\nImplicit AOT of :main will be removed in Leiningen 3.0.0.\"\n              \"\\nIf you only need AOT for your uberjar, consider adding\"\n              \":aot :all into your\\n:uberjar profile instead.\")))\n\n(defn warn-implicit-aot [project]\n  (when (and (:main project) (not (:skip-aot (meta (:main project))))\n             (not= :all (:aot project))\n             (not= [:all] (:aot project))\n             (not (some #{(:main project)} (:aot project)))\n             (not (some #(re-matches % (str (:main project)))\n                        (filter compile/regex? (:aot project)))))\n    (force implicit-aot-warning)))\n\n;; TODO: remove for 3.0\n(defn- add-main [project given-main]\n  (warn-implicit-aot project)\n  (let [project (if given-main\n                  (assoc project :main (symbol given-main))\n                  project)]\n    (if (and (compile-main? project)\n             (not= :all (:aot project))\n             (not= [:all] (:aot project))\n             (not (some #(= % (:main project)) (:aot project))))\n      (update-in project [:aot] conj (:main project))\n      project)))\n\n(defn- process-project\n  \"Like update-in, but for preparing projects for (uber)jaring. f is a function\n  that will take the old project and any supplied args and return the new\n  project, but with whitelisted keys retained and with the main argument\n  inserted if provided.\"\n  [project main f & args]\n  (-> (apply f project args)\n      (project/retain-whitelisted-keys project)\n      (add-main main)\n      ;; Ensure test paths can't affect jar compilation\n      ;; https://github.com/technomancy/leiningen/issues/2808\n      (assoc :test-paths [])))\n\n(defn- preprocess-project [project & [main]]\n  (process-project project main project/unmerge-profiles\n                   (project/non-leaky-profiles project)))\n\n(defn- get-jar-filename*\n  [project uberjar?]\n  (get-classified-jar-filename project (if uberjar? :standalone)))\n\n(defn get-jar-filename [project & [uberjar?]]\n  (get-jar-filename* (preprocess-project project) uberjar?))\n\n(defn build-jar\n  \"Build a jar for the given project and jar-file.\"\n  [project jar-file]\n  (eval/prep project)\n  (write-jar project jar-file (filespecs project))\n  (main/info \"Created\" (str jar-file))\n  jar-file)\n\n(defn main-jar\n  [project provided-profiles main]\n  (let [project (process-project project main project/merge-profiles\n                                 provided-profiles)]\n    {[:extension \"jar\"] (build-jar project (get-jar-filename* project nil))}))\n\n(defn classifier-jar\n  \"Package up all the project's classified files into a jar file.\n\nCreate a $PROJECT-$VERSION-$CLASSIFIER.jar file containing project's source\nfiles as well as .class files if applicable. The classifier is looked up in the\nproject`s :classifiers map. If it's a map, it's merged like a profile. If it's a\nkeyword, it's looked up in :profiles before being merged.\"\n  [{:keys [target-path] :as project} provided-profiles classifier spec]\n  (when (:dependencies spec)\n    (main/warn\n     \";; WARNING: Classifier specifies :dependencies which will be ignored.\"))\n  (let [profiles (concat provided-profiles [::target ::classifier])\n        target-profile {:target-path\n                        (.getPath (io/file target-path (name classifier)))}\n        project (-> project\n                    (vary-meta assoc-in [:profiles ::classifier] spec)\n                    (vary-meta assoc-in [:profiles ::target] target-profile)\n                    (process-project nil project/merge-profiles profiles))]\n\n    [[:classifier (name classifier) :extension \"jar\"]\n     (build-jar project (get-classified-jar-filename project classifier))]))\n\n(defn classifier-jars\n  \"Package up all the project's classified files into jar files.\n\nCreate a $PROJECT-$VERSION-$CLASSIFIER.jar file for each entry in the project's\n:classifiers. Returns a map of :classifier/:extension coordinates to files.\"\n  [{:keys [classifiers] :as project} provided-profiles]\n  (into {}\n        (map #(apply classifier-jar project provided-profiles %) classifiers)))\n\n(defn jar\n  \"Package up all the project's files into a jar file.\n\nCreate a $PROJECT-$VERSION.jar file containing project's source files as well\nas .class files if applicable. If project.clj contains a :main key, the -main\nfunction in that namespace will be used as the main-class for executable jar.\n\nWith an argument, the jar will be built with an alternate main.\"\n  ([project main]\n     (utils/with-write-permissions (:root project)\n       (when (:auto-clean project true)\n         (clean/clean project))\n       (let [scoped-profiles (set (project/pom-scope-profiles project :provided))\n             default-profiles (set (project/expand-profile project :default))\n             provided-profiles (remove\n                                (set/difference default-profiles scoped-profiles)\n                                (->> project meta :included-profiles\n                                     (project/expand-profiles project)))\n             project (preprocess-project project main)]\n         (merge (main-jar project provided-profiles main)\n                (classifier-jars project provided-profiles)))))\n  ([project] (jar project nil)))\n"
  },
  {
    "path": "src/leiningen/javac.clj",
    "content": "(ns leiningen.javac\n  \"Compile Java source files.\"\n  (:require [leiningen.classpath :as classpath]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.project :as project]\n            [clojure.java.io :as io]\n            [clojure.string :as string])\n  (:import java.io.File))\n\n(defn- stale-java-sources\n  \"Returns a lazy seq of file paths: every Java source file within dirs modified\n  since it was most recently compiled into compile-path.\"\n  [dirs compile-path]\n  (for [dir dirs\n        ^File source (filter #(-> ^File % (.getName) (.endsWith \".java\"))\n                             (file-seq (io/file dir)))\n        :let [rel-source (.substring (.getPath source) (inc (count dir)))\n              rel-compiled (.replaceFirst rel-source \"\\\\.java$\" \".class\")\n              compiled (io/file compile-path rel-compiled)]\n        :when (>= (.lastModified source) (.lastModified compiled))]\n    (.getPath source)))\n\n(def ^:private special-ant-javac-keys\n  \"Legacy (Lein1/Ant task) javac options that do not translate to the new (JDK's\n  javac) format as key-value pairs. For example, :debug \\\"off\\\" needs to be\n  translated to -g:none.\"\n  [:destdir :debug :debugLevel])\n\n(defn- normalize-specials\n  \"Handles legacy (Lein1/Ant task) javac options that do not translate to the\n  new (JDK's javac) format as key-value pairs.\"\n  [{:keys [debug debugLevel]}]\n  ;; debug \"off\"               => -g:none\n  ;; debugLevel \"source,lines\" => -g:source-lines\n  (if (or (= \"off\" debug) (false? debug))\n    [\"-g:none\"]\n    (if debugLevel\n      [(str \"-g:\" debugLevel)]\n      [])))\n\n(defn normalize-javac-options\n  \"Converts :javac-opts in Leiningen 1 format (passed as a map) into Leiningen 2\n  format (a vector). Options in Leiningen 2 format are returned unmodified.\"\n  [opts]\n  (if (map? opts)\n    (let [special-opts (select-keys opts special-ant-javac-keys)\n          other-opts   (apply dissoc opts special-ant-javac-keys)\n          specials     (normalize-specials special-opts)\n          others       (mapcat (fn [[k v]] [(str \"-\" (name k)) v]) other-opts)]\n      (vec (map (comp name str) (concat specials others))))\n    opts))\n\n(defn- safe-quote [s]\n  (str \"\\\"\" (string/replace s \"\\\\\" \"\\\\\\\\\") \"\\\"\"))\n\n;; Tool's .run method expects the last argument to be an array of\n;; strings, so that's what we'll return here.\n(defn- javac-options\n  \"Compile all sources of possible options and add important defaults.\n  Result is a String java array of options.\"\n  [project files args]\n  (let [options-file (File/createTempFile \".leiningen-cmdline\" nil)]\n    (.deleteOnExit options-file)\n    (with-open [options-file (io/writer options-file)]\n      (doto options-file\n        (.write (format \"-cp %s\\n\" (safe-quote (classpath/get-classpath-string project))))\n        (.write (format \"-d %s\\n\" (safe-quote (:compile-path project))))\n        (.write (string/join \"\\n\" (map safe-quote files)))))\n    (into-array String\n                (concat (normalize-javac-options (:javac-options project))\n                        args\n                        [(str \"@\" options-file)]))))\n\n;; Pure java projects will not have Clojure on the classpath. As such, we need\n;; to add it if it's not already there.\n(def subprocess-profile\n  {:dependencies [^:displace ['org.clojure/clojure (clojure-version)]]\n   :eval-in :subprocess})\n\n(defn- subprocess-form\n  \"Creates a form for running javac in a subprocess.\"\n  [compile-path files javac-opts]\n  (main/debug \"Running javac with\" javac-opts)\n  `(let [abort# (fn [& msg#]\n                  (.println java.lang.System/err (apply str msg#))\n                  (java.lang.System/exit 1))]\n     (if-let [compiler# (javax.tools.ToolProvider/getSystemJavaCompiler)]\n       (do\n         ~(when main/*info*\n            `(binding [*out* *err*]\n               (println \"Compiling\" ~(count files) \"source files to\" ~compile-path)))\n         (.mkdirs (clojure.java.io/file ~compile-path))\n         (when-not (zero?\n                    (.run compiler# nil nil nil\n                          (into-array java.lang.String ~javac-opts)))\n           (abort# \"Compilation of Java sources(lein javac) failed.\")))\n       (abort# \"Java compiler not found; Be sure to use java from a JDK\\n\"\n               \"rather than a JRE by modifying PATH or setting JAVA_CMD.\"))))\n\n(defn javac-project-for-subprocess\n  \"Merge profiles to create project appropriate for javac subprocess.  This\n  function is mostly extracted to simplify testing, to validate that settings\n  like `:local-repo` and `:mirrors` are respected.\"\n  [project subprocess-profile]\n  (-> (project/merge-profiles project [subprocess-profile])\n      (project/retain-whitelisted-keys project)))\n\n;; We can't really control what is printed here. We're just going to\n;; allow `.run` to attach in, out, and err to the standard streams. This\n;; should have the effect of compile errors being printed. javac doesn't\n;; actually output any compilation info unless it has to (for an error)\n;; or you make it do so with `-verbose`.\n(defn- run-javac-subprocess\n  \"Run javac to compile all source files in the project. The compilation is run\n  in a subprocess to avoid it from adding the leiningen standalone to the\n  classpath, as leiningen adds itself to the classpath through the\n  bootclasspath.\"\n  [project args]\n  (let [compile-path (:compile-path project)\n        files (stale-java-sources (:java-source-paths project) compile-path)\n        javac-opts (vec (javac-options project files args))\n        form (subprocess-form compile-path files javac-opts)]\n    (when (seq files)\n      (try\n        (binding [eval/*pump-in* false]\n          (eval/eval-in\n           (javac-project-for-subprocess project subprocess-profile)\n           form))\n        (catch Exception e\n          (if-let [exit-code (:exit-code (ex-data e))]\n            (main/exit exit-code)\n            (throw e)))))))\n\n(defn javac\n  \"Compile Java source files.\n\nAdd a :java-source-paths key to project.clj to specify where to find them.\nOptions passed in on the command line as well as options from the :javac-options\nvector in project.clj will be given to the compiler; e.g. `lein javac -verbose`.\n\nLike the compile and deps tasks, this should be invoked automatically when\nneeded and shouldn't ever need to be run by hand. By default it is called before\ncompilation of Clojure source; change :prep-tasks to alter this.\"\n  [project & args]\n  (run-javac-subprocess project args))\n"
  },
  {
    "path": "src/leiningen/new/app.clj",
    "content": "(ns leiningen.new.app\n  \"Generate a basic application project.\"\n  (:require [leiningen.new.templates :refer [renderer year date project-name\n                                             ->files sanitize-ns name-to-path\n                                             multi-segment]]\n            [leiningen.core.main :as main]))\n\n(defn app\n  \"An application project template.\"\n  [name]\n  (let [render (renderer \"app\")\n        main-ns (multi-segment (sanitize-ns name))\n        data {:raw-name name\n              :name (project-name name)\n              :namespace main-ns\n              :nested-dirs (name-to-path main-ns)\n              :year (year)\n              :date (date)}]\n    (main/info \"Generating a project called\" name \"based on the 'app' template.\")\n    (->files data\n             [\"project.clj\" (render \"project.clj\" data)]\n             [\"README.md\" (render \"README.md\" data)]\n             [\"doc/intro.md\" (render \"intro.md\" data)]\n             [\".gitignore\" (render \"gitignore\" data)]\n             [\".hgignore\" (render \"hgignore\" data)]\n             [\"src/{{nested-dirs}}.clj\" (render \"core.clj\" data)]\n             [\"test/{{nested-dirs}}_test.clj\" (render \"test.clj\" data)]\n             [\"LICENSE\" (render \"LICENSE\" data)]\n             [\"CHANGELOG.md\" (render \"CHANGELOG.md\" data)]\n             \"resources\")))\n"
  },
  {
    "path": "src/leiningen/new/default.clj",
    "content": "(ns leiningen.new.default\n  \"Generate a library project.\"\n  (:require [leiningen.new.templates :refer [renderer year date project-name\n                                             ->files sanitize-ns name-to-path\n                                             multi-segment]]\n            [leiningen.core.main :as main]))\n\n(defn default\n  \"A general project template for libraries.\n\nAccepts a group id in the project name: `lein new foo.bar/baz`\"\n  [name]\n  (let [render (renderer \"default\")\n        main-ns (multi-segment (sanitize-ns name))\n        data {:raw-name name\n              :name (project-name name)\n              :namespace main-ns\n              :nested-dirs (name-to-path main-ns)\n              :year (year)\n              :date (date)}]\n    (main/info \"Generating a project called\" name \"based on the 'default' template.\")\n    (main/info \"The default template is intended for library projects, not applications.\")\n    (main/info \"To see other templates (app, plugin, etc), try `lein help new`.\")\n    (->files data\n             [\"project.clj\" (render \"project.clj\" data)]\n             [\"README.md\" (render \"README.md\" data)]\n             [\"doc/intro.md\" (render \"intro.md\" data)]\n             [\".gitignore\" (render \"gitignore\" data)]\n             [\".hgignore\" (render \"hgignore\" data)]\n             [\"src/{{nested-dirs}}.clj\" (render \"core.clj\" data)]\n             [\"test/{{nested-dirs}}_test.clj\" (render \"test.clj\" data)]\n             [\"LICENSE\" (render \"LICENSE\" data)]\n             [\"CHANGELOG.md\" (render \"CHANGELOG.md\" data)]\n             \"resources\")))\n"
  },
  {
    "path": "src/leiningen/new/plugin.clj",
    "content": "(ns leiningen.new.plugin\n  (:require [leiningen.new.templates :refer [renderer sanitize year date ->files]]\n            [leiningen.core.main :as main]))\n\n(defn plugin\n  \"A leiningen plugin project template.\"\n  [^String name]\n  (let [render (renderer \"plugin\")\n        unprefixed (if (.startsWith name \"lein-\")\n                     (subs name 5)\n                     name)\n        data {:name name\n              :unprefixed-name unprefixed\n              :sanitized (sanitize unprefixed)\n              :year (year)\n              :date (date)}]\n    (main/info (str \"Generating a fresh Leiningen plugin called \" name \".\"))\n    (->files data\n             [\"project.clj\" (render \"project.clj\" data)]\n             [\"README.md\" (render \"README.md\" data)]\n             [\".gitignore\" (render \"gitignore\" data)]\n             [\".hgignore\" (render \"hgignore\" data)]\n             [\"src/leiningen/{{sanitized}}.clj\" (render \"name.clj\" data)]\n             [\"LICENSE\" (render \"LICENSE\" data)]\n             [\"CHANGELOG.md\" (render \"CHANGELOG.md\" data)])))\n"
  },
  {
    "path": "src/leiningen/new/template.clj",
    "content": "(ns leiningen.new.template\n  (:require [clojure.string :as str]\n            [leiningen.new.templates :as t]\n            [leiningen.core.main :as main]))\n\n(defn template\n  \"A meta-template for 'lein new' templates.\"\n  [template-name]\n  (when-not (namespace (symbol template-name))\n    (main/warn (str \";; Template names must use a group-id to conform with new\"\n                    \" Clojars security policy:\\n\"\n                    \";; https://github.com/clojars/clojars-web/wiki/Verified-Group-Names\"\n                    \"\\n\\n;; You may generate this template but you may not be\"\n                    \" able to publish it on Clojars.\")))\n  (let [render (t/renderer \"template\")\n        sym (symbol template-name)\n        data {:name template-name\n              :artifact-id (name sym)\n              ;; if there's no group-id we need to leave out the slash\n              :group-prefix (if-let [group-id (namespace sym)]\n                              (str group-id \"/\"))\n              :sanitized (t/name-to-path (name sym))\n              :placeholder \"{{sanitized}}\"\n              :year (t/year)\n              :date (t/date)}]\n    (main/info \"Generating fresh 'lein new' template project.\")\n    (t/->files data\n               [\"README.md\" (render \"README.md\" data)]\n               [\"project.clj\" (render \"project.clj\" data)]\n               [\".gitignore\" (render \"gitignore\" data)]\n               [\".hgignore\" (render \"hgignore\" data)]\n               [\"src/leiningen/new/{{sanitized}}.clj\" (render \"temp.clj\" data)]\n               [\"resources/leiningen/new/{{sanitized}}/foo.clj\" (render \"foo.clj\")]\n               [\"LICENSE\" (render \"LICENSE\" data)]\n               [\"CHANGELOG.md\" (render \"CHANGELOG.md\" data)])))\n"
  },
  {
    "path": "src/leiningen/new/templates.clj",
    "content": ";; You can write a 'new' task yourself without any extra plugins like\n;; lein-newnew. What makes lein-new so useful is the `templates` task for\n;; listing templates and this file. The primary problem with writing your\n;; own project scaffolding tools that are domain-specific is you\n;; generally have to reimplement the same things every single time. With\n;; lein-new, you have this little library that your templates can use.\n;; It has all the things a template is likely to need:\n;; * an easy way to generate files and namespaces\n;; * a way to render files written with a flexible template language\n;; * a way to get those files off of the classpath transparently\n(ns leiningen.new.templates\n  (:require [clojure.java.io :as io]\n            [clojure.string :as string]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.user :as user]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.main :as main]\n            [stencil.core :as stencil])\n  (:import (java.util Calendar)))\n\n(defn project-name\n  \"Returns project name from (possibly group-qualified) name:\n\n  mygroup/myproj => myproj\n  myproj         => myproj\"\n  [s]\n  (last (string/split s #\"/\")))\n\n(defn fix-line-separators\n  \"Replace all \\\\n with system specific line separators.\"\n  [s]\n  (let [line-sep (if (user/getenv \"LEIN_NEW_UNIX_NEWLINES\") \"\\n\"\n                     (user/getprop \"line.separator\"))]\n    (string/replace s \"\\n\" line-sep)))\n\n(defn slurp-to-lf\n  \"Returns the entire contents of the given reader as a single string. Converts\n  all line endings to \\\\n.\"\n  [r]\n  (let [sb (StringBuilder.)]\n    (loop [s (.readLine r)]\n      (if (nil? s)\n        (str sb)\n        (do\n          (.append sb s)\n          (.append sb \"\\n\")\n          (recur (.readLine r)))))))\n\n(defn slurp-resource\n  \"Reads the contents of a resource. Temporarily converts line endings in the\n  resource to \\\\n before converting them into system specific line separators\n  using fix-line-separators.\"\n  [resource]\n  (if (string? resource) ; for 2.0.0 compatibility, can break in 3.0.0\n    (-> resource io/resource io/reader slurp-to-lf fix-line-separators)\n    (-> resource io/reader slurp-to-lf fix-line-separators)))\n\n(defn sanitize\n  \"Replace hyphens with underscores.\"\n  [s]\n  (string/replace s \"-\" \"_\"))\n\n(defn multi-segment\n  \"Make a namespace multi-segmented by adding another segment if necessary.\n  The additional segment defaults to \\\"core\\\".\"\n  ([s] (multi-segment s \"core\"))\n  ([s final-segment]\n     (if (.contains s \".\")\n       s\n       (format \"%s.%s\" s final-segment))))\n\n(defn name-to-path\n  \"Constructs directory structure from fully qualified artifact name:\n\n  \\\"foo-bar.baz\\\" becomes \\\"foo_bar/baz\\\"\n\n  and so on. Uses platform-specific file separators.\"\n  [s]\n  (-> s sanitize (string/replace \".\" java.io.File/separator)))\n\n(defn sanitize-ns\n  \"Returns project namespace name from (possibly group-qualified) project name:\n\n  mygroup/myproj  => mygroup.myproj\n  myproj          => myproj\n  mygroup/my_proj => mygroup.my-proj\"\n  [s]\n  (-> s\n      (string/replace \"/\" \".\")\n      (string/replace \"_\" \"-\")))\n\n(defn group-name\n  \"Returns group name from (a possibly unqualified) name:\n\n  my.long.group/myproj => my.long.group\n  mygroup/myproj       => mygroup\n  myproj               => nil\"\n  [s]\n  (let [grpseq (butlast (string/split (sanitize-ns s) #\"\\.\"))]\n    (if (seq grpseq)\n      (->> grpseq (interpose \".\") (apply str)))))\n\n(defn year\n  \"Get the current year. Useful for setting copyright years and such.\"\n  [] (.get (Calendar/getInstance) Calendar/YEAR))\n\n(defn date\n  \"Get the current date as a string in ISO8601 format.\"\n  []\n  (let [df (java.text.SimpleDateFormat. \"yyyy-MM-dd\")]\n    (.format df (java.util.Date.))))\n\n;; It'd be silly to expect people to pull in stencil just to render a mustache\n;; string. We can just provide this function instead. In doing so, it is much\n;; less likely that template authors will have to pull in any external\n;; libraries. Though they are welcome to if they need.\n(def render-text stencil/render-string)\n\n;; Templates are expected to store their mustache template files in\n;; `leiningen/new/<template>/`. We have our convention of where templates\n;; will be on the classpath but we still have to know what the template's\n;; name is in order to know where this directory is and thus where to look\n;; for mustache template files. Since we're likely to be rendering a number\n;; of templates, we don't want to have to pass the name of the template every\n;; single time. We've also avoided magic so far, so a dynamic var and accompanying\n;; macro to set it is not in our game plan. Instead, our function for rendering\n;; templates on the classpath will be a function returned from this higher-order\n;; function. This way, we can say the name of our template just once and our\n;; render function will always know.\n(defn renderer\n  \"Create a renderer function that looks for mustache templates in the\n  right place given the name of your template. If no data is passed, the\n  file is simply slurped and the content returned unchanged.\n\n  render-fn - Optional rendering function that will be used in place of the\n              default renderer. This allows rendering templates that contain\n              tags that conflic with the Stencil renderer such as {{..}}.\"\n  [name & [render-fn]]\n  (let [render (or render-fn render-text)]\n    (fn [template & [data]]\n      (let [path (string/join \"/\" [\"leiningen\" \"new\" (sanitize name) template])]\n        (if-let [resource (io/resource path)]\n          (if data\n            (render (slurp-resource resource) data)\n            (io/reader resource))\n          (main/abort (format \"Template resource '%s' not found.\" path)))))))\n\n;; We  provide a hier order function which returns  a function to generate\n;; binary resources such as images placed in `leiningen/new/<template>/`\n(defn raw-resourcer\n  \"Create a renderer function that looks for raw files in the\n  right place given the name of your template.\"\n  [name]\n  (fn [file]\n    (let [path (string/join \"/\" [\"leiningen\" \"new\" (sanitize name) file])]\n      (if-let [resource (io/resource path)]\n        (io/input-stream resource)\n        (main/abort (format \"File '%s' not found.\" path))))))\n\n;; Our file-generating function, `->files` is very simple. We'd like\n;; to keep it that way. Sometimes you need your file paths to be\n;; templates as well. This function just renders a string that is the\n;; path to where a file is supposed to be placed by a template.\n;; It is private because you shouldn't have to call it yourself, since\n;; `->files` does it for you.\n(defn- template-path [name path data]\n  (io/file name (render-text path data)))\n\n(def ^{:dynamic true} *dir* nil)\n(def ^{:dynamic true} *force?* false)\n\n;; A template, at its core, is meant to generate files and directories that\n;; represent a project. This is our way of doing that. `->files` is basically\n;; a mini-DSL for generating files. It takes your mustache template data and\n;; any number of vectors or strings. It iterates through those arguments and\n;; when it sees a vector, it treats the first element as the path to spit to\n;; and the second element as the contents to put there. If it encounters a\n;; string, it treats it as an empty directory that should be created. Any parent\n;; directories for any of our generated files and directories are created\n;; automatically. All paths are considered mustache templates and are rendered\n;; with our data. Of course, this doesn't effect paths that don't have templates\n;; in them, so it is all transparent unless you need it.\n(defn ->files\n  \"Generate a file with content. path can be a java.io.File or string.\n  It will be turned into a File regardless. Any parent directories will be\n  created automatically. Data should include a key for :name so that the project\n  is created in the correct directory.\"\n  [{:keys [name] :as data} & paths]\n  (let [dir (or *dir*\n                (-> (System/getProperty \"leiningen.original.pwd\")\n                    (io/file name) (.getPath)))]\n    (if (or (= \".\" dir) (.mkdir (io/file dir)) *force?*)\n      (doseq [path paths]\n        (if (string? path)\n          (utils/mkdirs (template-path dir path data))\n          (let [[path content & options] path\n                path (template-path dir path data)\n                options (apply hash-map options)]\n            (utils/mkdirs (.getParentFile path))\n            (io/copy content (io/file path))\n            (when (:executable options)\n              (.setExecutable path true)))))\n      (main/info (str \"Could not create directory \" dir\n                      \". Maybe it already exists?\"\n                      \"  See also :force or --force\")))))\n"
  },
  {
    "path": "src/leiningen/new.clj",
    "content": "(ns leiningen.new\n  \"Generate project scaffolding based on a template.\"\n  (:refer-clojure :exclude [new])\n  (:require [clojure.string :as str]\n            [leiningen.core.classpath :as cp]\n            [leiningen.core.project :as project]\n            [leiningen.core.user :as user]\n            [leiningen.core.main :refer [abort parse-options option-arg debug]]\n            [leiningen.new.templates :refer [*dir* *force?*]]\n            leiningen.new.template\n            leiningen.new.plugin\n            leiningen.new.default\n            leiningen.new.app)\n  (:import java.io.FileNotFoundException))\n\n(def ^:dynamic *use-snapshots?* false)\n(def ^:dynamic *template-version* nil)\n\n(defn- template-symbol\n  \"The old style of template artifacts was $FOO/lein-template where\n  the short name of the template was used as the group-id within\n  Clojars, but Clojars will not allow new templates in this style to\n  be created going forward. The new style is $GROUP/lein-template.$ARTIFACT\n  so `lein new us.technomancy/my-stuff would look up\n  us.technomancy/lein-template.my-stuff in the remote repository.\"\n  [template-name]\n  (if (re-find #\"/\" template-name)\n    (let [[group-id artifact-id] ((juxt namespace name) (symbol template-name))]\n      (symbol group-id (str \"lein-template.\" artifact-id)))\n    (symbol template-name \"lein-template\")))\n\n(defn- fake-project [name]\n  (let [template-version (cond *template-version* *template-version*\n                               *use-snapshots?*   \"(0.0.0,)\"\n                               :else              \"RELEASE\")\n        user-profiles (:user (user/profiles))\n        repositories (reduce\n                       (:reduce (meta project/default-repositories))\n                       project/default-repositories\n                       (:plugin-repositories user-profiles))]\n    (merge {:templates [[(template-symbol name) template-version]]\n            :repositories repositories\n            :update :always}\n           (select-keys user-profiles [:mirrors]))))\n\n(defn resolve-remote-template [name ns-sym]\n  (try (cp/resolve-dependencies :templates (fake-project name)\n                                :add-classpath? true)\n       (require ns-sym)\n       true\n       (catch clojure.lang.Compiler$CompilerException e\n         (abort (str \"Could not load template, failed with: \" (.getMessage e))))\n       (catch Exception e\n         (debug (str e)))))\n\n(defn resolve-template [template-name]\n  (let [ns-sym (symbol (str \"leiningen.new.\" (name (symbol template-name))))]\n    (if (try (require (symbol (str \"leiningen.new.\" template-name)))\n             true\n             (catch FileNotFoundException _\n               (resolve-remote-template template-name ns-sym)))\n      (resolve (symbol (name ns-sym) (name (symbol template-name))))\n      (abort \"Could not find template for\" template-name\n             \"on the classpath: \" ns-sym))))\n\n;; A lein-newnew template is actually just a function that generates files and\n;; directories. We have a bit of convention: we expect that each template is on\n;; the classpath and is based in a .clj file at `leiningen/new/`. Making this\n;; assumption, users can simply give us the name of the template they wish to\n;; use and we can `require` it without searching the classpath for it or doing\n;; other time consuming things. If this namespace isn't found and we are\n;; running Leiningen 2, we can resolve it via pomegranate first.\n;;\n;; Since our templates are just function calls just like Leiningen tasks, we can\n;; also expect that a template generation function also be named the same as the\n;; last segment of its namespace. This is what we call to generate the project.\n(defn create\n  [template name & args]\n  (cond\n   (and (re-find #\"(?i)(?<!(clo|compo))jure\" name)\n        (not (System/getenv \"LEIN_IRONIC_JURE\")))\n   (abort \"Sorry, names such as clojure or *jure are not allowed.\"\n          \"\\nIf you intend to use this name ironically, please set the\"\n          \"\\nLEIN_IRONIC_JURE environment variable and try again.\")\n   (and (re-find #\"(?i)(?<!(cl|comp))eauxure\" name)\n        (not (System/getenv \"LEIN_IRONIC_EAUXURE\")))\n   (abort \"Sorry, names such as cleauxure or *eauxure are not allowed.\"\n          \"\\nIf you intend to use this name ironically, please set the\"\n          \"\\nLEIN_IRONIC_EAUXURE environment variable and try again.\")\n   (or (= name \"clojure\") (= name \"cljs\"))\n   (abort \"Sorry, clojure and cljs can't be used as project names.\"\n          \"\\nIt will confuse the compiler and cause obscure issues.\")\n   (and (re-find #\"[A-Z]\" name)\n        (not (System/getenv \"LEIN_BREAK_CONVENTION\")))\n   (abort \"Project names containing uppercase letters are not recommended\"\n          \"\\nand will be rejected by repositories like Clojars and Central.\"\n          \"\\nIf you're truly unable to use a lowercase name, please set the\"\n          \"\\nLEIN_BREAK_CONVENTION environment variable and try again.\")\n   (not (symbol? (try (read-string name) (catch Exception _))))\n   (abort \"Project names must be valid Clojure symbols.\")\n   :else (apply (resolve-template template) name args)))\n\n;; Since we have our convention of templates always being at\n;; `leiningen.new.<template>`, we can easily search the classpath\n;; to find templates in the same way that Leiningen can search to\n;; find tasks. Furthermore, since our templates will always have a\n;; function named after the template that is the entry-point, we can\n;; also expect that it has the documentation for the template. We can\n;; just look up these templates on the classpath, require them, and then\n;; get the metadata off of that function to list the names and docs\n;; for all of the available templates.\n\n(defn show\n  \"Show details for a given template.\"\n  [name]\n  (let [resolved (meta (resolve-template name))]\n    (println (:doc resolved \"No documentation available.\"))\n    (println)\n    (println \"Argument list:\" (or (:help-arglists resolved)\n                                  (:arglists resolved)))))\n\n(def ^{:dynamic true :doc \"Bound to project map at runtime\"} *project* nil)\n\n(defn- project-name-specified? [[first-arg & _]]\n  (and first-arg (not (option-arg first-arg))))\n\n(defn- template-specified? [[_ second-arg & _]]\n  (and second-arg (not (option-arg second-arg))))\n\n(defn- parse-args [[first-arg second-arg & opts :as args]]\n  (if (project-name-specified? args)\n    (let [template-name (if (template-specified? args) first-arg nil)\n          new-project-name (if (template-specified? args) second-arg first-arg)\n          options (parse-options (if (template-specified? args)\n                                   opts\n                                   (if second-arg\n                                     (cons second-arg opts) opts)))]\n      [template-name new-project-name options])\n    [nil nil (parse-options args)]))\n\n(defn- print-help []\n  (require 'leiningen.help)\n  ((ns-resolve 'leiningen.help 'help) nil \"new\"))\n\n(defn ^{:no-project-needed true\n        :help-arglists '[[project project-name]\n                         [project template project-name [-- & args]]]\n        :subtasks [#'leiningen.new.template/template\n                   #'leiningen.new.plugin/plugin\n                   #'leiningen.new.default/default\n                   #'leiningen.new.app/app]}\n  new\n  \"Generate scaffolding for a new project based on a template.\n\nIf only one argument is passed to the \\\"new\\\" task, the default template\nis used and the argument is used as the name of the project.\n\nIf two arguments are passed, the first should be the name of a template,\nand the second is used as the name of the project, for example:\n\n    lein new $TEMPLATE_NAME $PROJECT_NAME\n\nTo generate to a directory different than your project's name use --to-dir:\n\n    lein new $TEMPLATE_NAME $PROJECT_NAME --to-dir $DIR\n\nBy default, the \\\"new\\\" task will not write to an existing directory.\nSupply the --force option to override this behavior:\n\n    lein new $TEMPLATE_NAME $PROJECT_NAME --force\n    lein new $TEMPLATE_NAME $PROJECT_NAME --to-dir $DIR --force\n\nArguments can be passed to templates by adding them after \\\"new\\\"'s options. Use\n`--` to separate arguments to lein new and the actual template you are using:\n\n    lein new $TEMPLATE_NAME $PROJECT_NAME --to-dir $DIR -- template-arg-1 template-arg-2\n\nIf you'd like to use an unreleased (ie, SNAPSHOT) template, pass in --snapshot:\n\n    lein new $TEMPLATE_NAME $PROJECT_NAME --snapshot\n\nIf you'd rather like to use a specific version of template, specify the version\nwith --template-version option:\n\n    lein new $TEMPLATE_NAME $PROJECT_NAME --template-version $TEMPLATE_VERSION\n\nIf you use the `--snapshot` or `--template-version` argument with template args\nyou may need to use `--` to prevent template args from being interpreted as\narguments to `lein new`:\n\n    lein new $TEMPLATE_NAME $PROJECT_NAME --snapshot -- template-arg-1 template-arg-2\n\nThird-party templates can be found at by searching on Clojars:\n  https://clojars.org/search?q=artifact-id:lein-template*\n\nNote that there's no need to \\\"install\\\" a given third- party template; lein\nwill automatically fetch it for you.\n\nUse `lein new :show $TEMPLATE` to see details about a given template.\n\nTo create a new template of your own, run `lein help templates`.\"\n  [project & args]\n  (binding [*project* project]\n    (let [[template-name new-project-name\n           [options template-args]] (parse-args args)]\n      (if (or (:--help options) (empty? args))\n        (print-help)\n        (if-let [show-template (or (and (true? (:show options))\n                                        new-project-name)\n                                   (:show options) (:--show options))]\n          (show show-template)\n          (binding [*dir* (or (:to-dir options) (:--to-dir options))\n                    *use-snapshots?* (or (:snapshot options)\n                                         (:--snapshot options))\n                    *template-version* (or (:template-version options)\n                                           (:--template-version options))\n                    *force?* (or (:force options) (:--force options))]\n            (apply create (or template-name \"default\")\n                   new-project-name template-args)))))))\n"
  },
  {
    "path": "src/leiningen/plugin.clj",
    "content": "(ns leiningen.plugin\n  \"DEPRECATED. Please use the :user profile instead.\"\n  (:require [leiningen.core.main :as main]))\n\n(defn ^:no-project-needed plugin\n  \"DEPRECATED. Please use the :user profile instead.\"\n  [& args]\n  (main/abort \"The plugin task from Leiningen 1.x has been removed.\"))\n"
  },
  {
    "path": "src/leiningen/pom.clj",
    "content": "(ns leiningen.pom\n  \"Write a pom.xml file to disk for Maven interoperability.\"\n  (:import java.io.IOException)\n  (:require [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.project :as project]\n            [clojure.java.io :as io]\n            [clojure.set :as set]\n            [clojure.string :as s]\n            [clojure.java.shell :as sh]\n            [clojure.data.xml :as xml]\n            [clojure.data.xml.name :as name]\n            [leiningen.core.classpath :as classpath]))\n\n(def pom-uri \"https://maven.apache.org/POM/4.0.0\")\n\n(def ^:private xsi-uri \"http://www.w3.org/2001/XMLSchema-instance\")\n\n(xml/alias-uri 'pom pom-uri\n               'xsi xsi-uri)\n\n(defn- relativize [project]\n  (let [root (str (:root project) (System/getProperty \"file.separator\"))]\n    (reduce #(update-in %1 [%2]\n                        (fn [xs]\n                          (if (sequential? xs)\n                            (vec (for [x xs]\n                                   (.replace x root \"\")))\n                            (and xs (.replace xs root \"\")))))\n            project\n            [:target-path :compile-path :source-paths :test-paths\n             :resource-paths :java-source-paths])))\n\n;; git scm\n\n(defn- resolve-git-dir [project]\n  (let [alternate-git-root (io/file (get-in project [:scm :dir]))\n        git-dir-file (io/file (or alternate-git-root (:root project)) \".git\")]\n    (if (.isFile git-dir-file)\n      (io/file (second (re-find #\"gitdir: (\\S+)\" (slurp (str git-dir-file)))))\n      git-dir-file)))\n\n(defn- read-git-ref\n  \"Reads the commit SHA1 for a git ref path, or nil if no commit exist.\"\n  [git-dir ref-path]\n  (let [ref (io/file git-dir ref-path)]\n    (if (.exists ref)\n      (.trim (slurp ref))\n      nil)))\n\n(defn- read-git-head-file\n  \"Reads the current value of HEAD by attempting to read .git/HEAD, returning\n  the SHA1 or nil if none exists.\"\n  [git-dir]\n  (let [head (.trim (slurp (str (io/file git-dir \"HEAD\"))))]\n                           (if-let [ref-path (second (re-find #\"ref: (\\S+)\" head))]\n                             (read-git-ref git-dir ref-path))))\n\n(defn- read-git-head\n  \"Reads the value of HEAD and returns a commit SHA1, or nil if no commit\n  exist.\"\n  [git-dir]\n  (try\n    (let [git-ref (sh/sh \"git\" \"rev-parse\" \"HEAD\" :dir git-dir)]\n      (if (= (:exit git-ref) 0)\n        (.trim (:out git-ref))\n        (read-git-head-file git-dir)))\n    (catch IOException e (read-git-head-file git-dir))))\n\n(defn- read-git-origin\n  \"Reads the URL for the remote origin repository.\"\n  [git-dir]\n  (with-open [rdr (io/reader (io/file git-dir \"config\"))]\n    (->> (map #(.trim %) (line-seq rdr))\n         (drop-while #(not= \"[remote \\\"origin\\\"]\" %))\n         (next)\n         (take-while #(not (.startsWith % \"[\")))\n         (map #(re-matches #\"url\\s*=\\s*(\\S*)\\s*\" %))\n         (filter identity)\n         (first)\n         (second))))\n\n(defn- parse-github-url\n  \"Parses a GitHub URL returning a [username repo] pair.\"\n  [url]\n  (if url\n    (next\n     (or (re-matches #\"(?:[A-Za-z-]{2,}@)?github.com:([^/]+)/([^/]+).git\" url)\n         (re-matches #\"[^:]+://(?:[A-Za-z-]{2,}@)?github.com/([^/]+)/([^/]+?)(?:.git)?\" url)))))\n\n(defn- github-urls [url]\n  (if-let [[user repo] (parse-github-url url)]\n    {:public-clone (str \"git://github.com/\" user \"/\" repo \".git\")\n     :dev-clone (str \"ssh://git@github.com/\" user \"/\" repo \".git\")\n     :browse (str \"https://github.com/\" user \"/\" repo)}))\n\n(defn- make-git-scm-map [git-dir]\n  (try\n    (let [origin (read-git-origin git-dir)\n          head (read-git-head git-dir)\n          urls (github-urls origin)]\n      (cond-> {:url (:browse urls)}\n        (:public-clone urls) (assoc :connection (str \"scm:git:\" (:public-clone urls)))\n        (:dev-clone urls)    (assoc :developerConnection (str \"scm:git:\" (:dev-clone urls)))\n        head                 (assoc :tag head)))\n    (catch java.io.FileNotFoundException _)))\n\n(def disclaimer\n  \"A notice to place at the bottom of generated files.\"\n  \"\\n<!-- This file was autogenerated by Leiningen.\n  Please do not edit it directly; instead edit project.clj and regenerate it.\n  It should not be considered canonical data. For more information see\n  https://codeberg.org/leiningen/leiningen -->\\n\")\n\n(defn- camelize [string]\n  (s/replace string #\"[-_](\\w)\" (comp s/upper-case second)))\n\n(defn- pomify [key]\n  (->> key name camelize (xml/qname pom-uri)))\n\n(defn- pomify-sexp [x]\n  (cond\n    (vector? x) (let [[tag & [attrs & content :as all-content]] x\n                      tag (cond-> tag (not (name/namespaced? tag)) pomify)]\n                  (if (map? attrs)\n                    (into [tag attrs] (map pomify-sexp) content)\n                    (into [tag] (map pomify-sexp) all-content)))\n    (seq? x) (map pomify-sexp x)\n    :else x))\n\n(defmulti ^:private xml-tags\n  (fn [tag value] (keyword \"leiningen.pom\" (name tag))))\n\n(defn- guess-scm\n  \"Returns the name of the SCM used in project.clj or \\\"auto\\\" if nonexistant.\n  Example: :scm {:name \\\"git\\\" :tag \\\"deadbeef\\\"}\"\n  [project]\n  (or (-> project :scm :name) \"auto\"))\n\n(defn- xmlify\n  \"Converts the map identified by :scm\"\n  [scm]\n  (map #(xml-tags (first %) (second %)) scm))\n\n(defn- make-project-scm-map [project]\n  (select-keys (:scm project) [:url :connection\n                               :tag :developerConnection]))\n\n(defn- write-scm-tag\n  \"Write the <scm> tag for pom.xml.\n  Retains backwards compatibility without an :scm map.\"\n  [scm project]\n  (->> (case scm\n         \"auto\" (make-git-scm-map (resolve-git-dir project))\n         \"git\" (merge (make-git-scm-map (resolve-git-dir project))\n                      (make-project-scm-map project))\n         ; else\n         (make-project-scm-map project))\n       xmlify\n       (xml-tags :scm)))\n\n(defmethod xml-tags :default\n  ([tag value]\n     (and value [(pomify tag) value])))\n\n(defmethod xml-tags ::list\n  ([tag values]\n     [(pomify tag) (map (partial xml-tags\n                                 (-> tag name (s/replace #\"ies$\" \"y\") keyword))\n                        values)]))\n\n(doseq [c [::dependencies ::repositories]]\n  (derive c ::list))\n\n(defmethod xml-tags ::exclusions\n  [tag values]\n  (and (seq values)\n       [::pom/exclusions\n        (for [exclusion-spec values\n              :let [[dep & {:keys [classifier extension]}]\n                    (if (symbol? exclusion-spec)\n                      [exclusion-spec]\n                      exclusion-spec)]]\n          [::pom/exclusion (map (partial apply xml-tags)\n                                (merge (project/artifact-map dep)\n                                       {:classifier classifier\n                                        :type extension}))])]))\n\n(defmethod xml-tags ::dependency\n  ([_ [dep version & {:keys [optional classifier\n                             exclusions scope\n                             extension]}]]\n     [::pom/dependency\n      (map (partial apply xml-tags)\n           {:group-id (or (namespace dep) (name dep))\n            :artifact-id (name dep)\n            :version version\n            :optional optional\n            :classifier classifier\n            :type extension\n            :exclusions exclusions\n            :scope scope})]))\n\n(defn- policy-tags [type opts]\n  (seq (keep (partial apply xml-tags)\n             {:enabled (str (if (nil? (type opts))\n                              true\n                              (boolean\n                               (type opts))))\n              :update-policy (or (some-> opts type :update name)\n                                 (some-> opts :update name))\n              :checksum-policy (or (some-> opts type :checksum name)\n                                   (some-> opts :checksum name))})))\n\n(defmethod xml-tags ::repository\n  ([_ [id opts]]\n     [::pom/repository\n      (map (partial apply xml-tags)\n           {:id id\n            :url (:url opts)\n            :snapshots (policy-tags :snapshots opts)\n            :releases (policy-tags :releases opts)})]))\n\n(defmethod xml-tags ::license\n  ([_ opts]\n     (and opts\n          (if-let [tags (if (string? opts)\n                          [::pom/name opts]\n                          (seq (for [key [:name :url :distribution :comments]\n                                     :let [val (opts key)] :when val]\n                                 [(pomify key) (name val)])))]\n            [::pom/license tags]))))\n\n(defn- license-tags [project]\n  (seq (concat (for [k [:license :licence]\n                     :let [l (xml-tags :license (get project k))]\n                     :when l]\n                 l)\n               (keep (partial xml-tags :license) (:licenses project))\n               (keep (partial xml-tags :license) (:licences project)))))\n\n(defn- resource-tags [project type]\n  (if-let [resources (seq (:resource-paths project))]\n    (let [types (pomify (str (name type) \"s\"))]\n      (vec (concat [types]\n                   (for [resource resources]\n                     [(pomify type) [::pom/directory resource]]))))))\n\n(defmethod xml-tags ::build\n  ([_ [project test-project]]\n     (let [[src & extra-src] (concat (:source-paths project)\n                                     (:java-source-paths project))\n           [test & extra-test] (:test-paths test-project)]\n       [::pom/build\n        [::pom/sourceDirectory src]\n        (xml-tags :testSourceDirectory test)\n        (resource-tags project :resource)\n        (resource-tags test-project :testResource)\n        (if-let [extensions (seq (:extensions project))]\n          (vec (concat [::pom/extensions]\n                       (for [[dep version] extensions]\n                         [::pom/extension\n                          [::pom/artifactId (name dep)]\n                          [::pom/groupId (or (namespace dep) (name dep))]\n                          [::pom/version version]]))))\n        [::pom/directory (:target-path project)]\n        [::pom/outputDirectory (:compile-path project)]\n        [::pom/plugins\n            (if-let [plugins (seq (:pom-plugins project))]\n                           (for [[dep version plugin-addition] plugins]\n                             [::pom/plugin\n                              [::pom/groupId (or (namespace dep) (name dep))]\n                              [::pom/artifactId (name dep)]\n                              [::pom/version version]\n                              (pomify-sexp\n                                (cond\n                                  (map? plugin-addition) (seq plugin-addition)\n                                  (vector? plugin-addition) (seq (apply hash-map plugin-addition))\n                                  (list? plugin-addition) (vec plugin-addition)))\n                           ]\n                          ))\n        (if (or (seq extra-src) (seq extra-test))\n           [::pom/plugin\n            [::pom/groupId \"org.codehaus.mojo\"]\n            [::pom/artifactId \"build-helper-maven-plugin\"]\n            [::pom/version \"1.7\"]\n            [::pom/executions\n             (if (seq extra-src)\n               [::pom/execution\n                [::pom/id \"add-source\"]\n                [::pom/phase \"generate-sources\"]\n                [::pom/goals [::pom/goal \"add-source\"]]\n                [::pom/configuration\n                 (vec (concat [::pom/sources]\n                              (map (fn [x] [::pom/source x]) extra-src)))]])\n             (if (seq extra-test)\n               [::pom/execution\n                [::pom/id \"add-test-source\"]\n                [::pom/phase \"generate-test-sources\"]\n                [::pom/goals [::pom/goal \"add-test-source\"]]\n                [::pom/configuration\n                 (vec (concat [::pom/sources]\n                              (map (fn [x] [::pom/source x]) extra-test)))]])]])]])))\n\n(defmethod xml-tags ::parent\n  ([_ [dep version & opts]]\n     (let [opts (apply hash-map opts)]\n       [::pom/parent\n        [::pom/artifactId (name dep)]\n        [::pom/groupId (or (namespace dep) (name dep))]\n        [::pom/version version]\n        [::pom/relativePath (:relative-path opts)]])))\n\n(defmethod xml-tags ::mailing-list\n  ([_ opts]\n     (if opts\n       [::pom/mailingLists\n        [::pom/mailingList\n         [::pom/name (:name opts)]\n         [::pom/subscribe (:subscribe opts)]\n         [::pom/unsubscribe (:unsubscribe opts)]\n         [::pom/post (:post opts)]\n         [::pom/archive (:archive opts)]\n         (if-let [other-archives (:other-archives opts)]\n           (vec (concat [::pom/otherArchives]\n                        (for [other other-archives]\n                          [::pom/otherArchive other]))))]])))\n\n(defn- distinct-key [k xs]\n  ((fn step [seen xs]\n     (lazy-seq\n      (if (seq xs)\n        (let [x (first xs), key (k x)]\n          (if (seen key)\n            (step seen (rest xs))\n            (cons x (step (conj seen key) (rest xs))))))))\n   #{} (seq xs)))\n\n(defn- make-scope [scope [dep version & opts]]\n  (list* dep version (apply concat (assoc (apply hash-map opts) :scope scope))))\n\n(defn- dep-key [dep]\n  (select-keys (project/dependency-map dep) [:group-id :artifact-id :classifier\n                                             :extension :scope]))\n\n(defmethod xml-tags ::project\n  ([_ project]\n     (let [original-project (-> project meta ::original-project)\n           profile-kws (concat\n                        (set/difference\n                         (set (project/non-leaky-profiles original-project))\n                         (set (project/pom-scope-profiles\n                               original-project :provided))\n                         (set (project/pom-scope-profiles\n                               original-project :test))))\n           test-project (-> original-project\n                            (project/unmerge-profiles profile-kws)\n                            (project/merge-profiles [:test])\n                            relativize)\n           managed-deps (:managed-dependencies test-project)\n           deps (:dependencies test-project)]\n       (list\n        [::pom/project {:xmlns pom-uri\n                        :xmlns/xsi xsi-uri\n                        ::xsi/schemaLocation\n                        (str pom-uri \" https://maven.apache.org/xsd/maven-4.0.0.xsd\")}\n         [::pom/modelVersion \"4.0.0\"]\n         (and (:parent project) (xml-tags :parent (:parent project)))\n         [::pom/groupId (:group project)]\n         [::pom/artifactId (:name project)]\n         [::pom/packaging (:packaging project \"jar\")]\n         [::pom/version (:version project)]\n         (and (:classifier project) [::pom/classifier (:classifier project)])\n         [::pom/name (:name project)]\n         [::pom/description (:description project)]\n         (xml-tags :url (:url project))\n         (if-let [licenses (license-tags project)]\n           [::pom/licenses licenses])\n         (xml-tags :mailing-list (:mailing-list project))\n         (write-scm-tag (guess-scm project) project)\n         ;; TODO: this results in lots of duplicate entries\n         (xml-tags :build [project test-project])\n         (xml-tags :repositories (:repositories project))\n         (xml-tags :dependencyManagement\n                   (xml-tags :dependencies (distinct-key dep-key managed-deps)))\n         (xml-tags :dependencies (distinct-key dep-key deps))\n         (and (:pom-addition project) (pomify-sexp (:pom-addition project)))]))))\n\n(defn snapshot? [project]\n  (and (:version project)\n       (re-find #\"SNAPSHOT\" (:version project))))\n\n(defn check-for-snapshot-deps [project]\n  (when (and (not (snapshot? project))\n             (not (System/getenv \"LEIN_SNAPSHOTS_IN_RELEASE\")))\n    (let [merged-deps (classpath/merge-versions-from-managed-coords\n                       (:dependencies project)\n                       (:managed-dependencies project))]\n      (when (some #(re-find #\"SNAPSHOT\" (second %)) merged-deps)\n        (main/abort \"Release versions may not depend upon snapshots.\"\n                    \"\\nFreeze snapshots to dated versions or set the\"\n                    \"LEIN_SNAPSHOTS_IN_RELEASE environment variable to override.\")))))\n\n(defn make-pom\n  ([project] (make-pom project false))\n  ([project disclaimer?]\n     (let [profile-kws (project/non-leaky-profiles project)\n           project (-> project\n                       (project/unmerge-profiles profile-kws)\n                       (vary-meta assoc ::original-project project))]\n       (check-for-snapshot-deps project)\n       (str\n        (xml/indent-str\n         (xml/sexp-as-element\n          (xml-tags :project (relativize project))))\n        (if disclaimer? disclaimer)))))\n\n(defn ^{:help-arglists '([])} pom\n  \"Write a pom.xml file to disk for Maven interoperability.\"\n  ([project pom-location-or-properties]\n     (let [pom (make-pom project true)\n           pom-file (io/file (:root project) pom-location-or-properties)]\n       (utils/mkdirs (.getParentFile pom-file))\n       (with-open [pom-writer (io/writer pom-file)]\n         (.write pom-writer pom))\n       (main/info \"Wrote\" (str pom-file))\n       (.getAbsolutePath pom-file)))\n  ([project] (pom project (io/file (:pom-location project) \"pom.xml\"))))\n"
  },
  {
    "path": "src/leiningen/release.clj",
    "content": "(ns leiningen.release\n  \"Perform :release-tasks.\"\n  (:require [clojure.java.io :as io]\n            [leiningen.core.main :as main]\n            [leiningen.core.project :as project]))\n\n(def ^:dynamic *level* nil)\n\n(defn string->semantic-version [version-string]\n  \"Create map representing the given version string. Returns nil if the\n  string does not follow guidelines setforth by Semantic Versioning 2.0.0,\n  https://semver.org/\"\n  ;; <MajorVersion>.<MinorVersion>.<PatchVersion>[-<Qualifier>][-SNAPSHOT]\n  (if-let [[_ major minor patch qualifier snapshot]\n           (re-matches\n            #\"(\\d+)\\.(\\d+)\\.(\\d+)(?:-(?!SNAPSHOT)([^\\-]+))?(?:-(SNAPSHOT))?\"\n            version-string)]\n    (->> [major minor patch]\n         (map #(Integer/parseInt %))\n         (zipmap [:major :minor :patch])\n         (merge {:qualifier qualifier\n                 :snapshot snapshot}))))\n\n(defn parse-semantic-version [version-string]\n  \"Create map representing the given version string. Aborts with exit code 1\n  if the string does not follow guidelines setforth by Semantic Versioning 2.0.0,\n  https://semver.org/\"\n  (or (string->semantic-version version-string)\n      (main/abort \"Unrecognized version string:\" version-string)))\n\n(defn version-map->string\n  \"Given a version-map, return a string representing the version.\"\n  [version-map]\n  (let [{:keys [major minor patch qualifier snapshot]} version-map]\n    (cond-> (str major \".\" minor \".\" patch)\n            qualifier (str \"-\" qualifier)\n            snapshot (str \"-\" snapshot))))\n\n(defn next-qualifier\n  \"Increments and returns the qualifier.  If an explicit `sublevel`\n  is provided, then, if the original qualifier was using that sublevel,\n  increments it, else returns that sublevel with \\\"1\\\" appended.\n  Supports empty strings for sublevel, in which case the return value\n  is effectively a BuildNumber.\"\n  ([qualifier]\n   (if-let [[_ sublevel] (re-matches #\"([^\\d]+)?(?:\\d+)?\"\n                                         (or qualifier \"\"))]\n     (next-qualifier sublevel qualifier)\n     \"1\"))\n  ([sublevel qualifier]\n   (let [pattern (re-pattern (str sublevel \"([0-9]+)\"))\n         [_ n] (and qualifier (re-find pattern qualifier))]\n     (str sublevel (inc (Integer. (or n 0)))))))\n\n(defn bump-version-map\n  \"Given version as a map of the sort returned by parse-semantic-version, return\n  a map of the version incremented in the level argument.  Always returns a\n  SNAPSHOT version, unless the level is :release.  For :release, removes SNAPSHOT\n  if the input is a SNAPSHOT, removes qualifier if the input is not a SNAPSHOT.\"\n  [{:keys [major minor patch qualifier snapshot]} level]\n  (let [level (or level\n                  (if qualifier :qualifier)\n                  :patch)]\n    (case (keyword (name level))\n      :major {:major (inc major) :minor 0 :patch 0 :qualifier nil :snapshot \"SNAPSHOT\"}\n      :minor {:major major :minor (inc minor) :patch 0 :qualifier nil :snapshot \"SNAPSHOT\"}\n      :patch {:major major :minor minor :patch (inc patch) :qualifier nil :snapshot \"SNAPSHOT\"}\n      :alpha {:major major :minor minor :patch patch\n              :qualifier (next-qualifier \"alpha\" qualifier)\n              :snapshot \"SNAPSHOT\"}\n      :beta {:major major :minor minor :patch patch\n             :qualifier (next-qualifier \"beta\" qualifier)\n             :snapshot \"SNAPSHOT\"}\n      :rc {:major major :minor minor :patch patch\n           :qualifier (next-qualifier \"RC\" qualifier)\n           :snapshot \"SNAPSHOT\"}\n      :qualifier {:major major :minor minor :patch patch\n                  :qualifier (next-qualifier qualifier)\n                  :snapshot \"SNAPSHOT\"}\n      :release (merge {:major major :minor minor :patch patch}\n                      (if snapshot\n                        {:qualifier qualifier :snapshot nil}\n                        {:qualifier nil :snapshot nil})))))\n\n(defn bump-version\n  \"Given a version string, return the bumped version string -\n   incremented at the indicated level. Add qualifier unless releasing\n   non-snapshot. Level defaults to *level*.\"\n  [version-str & [level]]\n  (-> version-str\n      (parse-semantic-version)\n      (bump-version-map (or level *level*))\n      (version-map->string)))\n\n\f\n\n(defn ^{:subtasks []} release\n  \"Perform release tasks.\n\nThe default list of release tasks is as follows:\n\n  :release-tasks [[\\\"vcs\\\" \\\"assert-committed\\\"]\n                  [\\\"change\\\" \\\"version\\\"\n                   \\\"leiningen.release/bump-version\\\" \\\"release\\\"]\n                  [\\\"vcs\\\" \\\"commit\\\"]\n                  [\\\"vcs\\\" \\\"tag\\\"]\n                  [\\\"deploy\\\"]\n                  [\\\"change\\\" \\\"version\\\" \\\"leiningen.release/bump-version\\\"]\n                  [\\\"vcs\\\" \\\"commit\\\"]\n                  [\\\"vcs\\\" \\\"push\\\"]]\n\nFirst change the version stored in project.clj, then commit that change, tag\nthis commit to with the release version indicated, deploy to the Maven release\nrepository, then change to the next snapshot version in project.clj, commit\nthat change, and push to the default remote version control repository.\n\nA key point to note is that this default set of :release-tasks requires a clean\nworking directory as far as the current version control system is concerned.\nThis ensures that the `vcs commit` tasks will only save changes made to\nproject.clj made by the `change version` tasks.\n\nThis behavior can be overridden by setting :release-tasks a vector in which\nevery element is either a task name or a collection in which the first element\nis a task name and the rest are arguments to that task.\n\nThe release task takes a single argument which should be one of :major,\n:minor, :patch, :alpha, :beta, or :rc to indicate which version level to\nbump. If none is given, it defaults to :patch.\"\n  ([project] (release project *level*))\n  ([project level]\n     (binding [*level* (if level (read-string level))]\n       (let [release-tasks (:release-tasks project)\n             task-count (count release-tasks)]\n         (doseq [[i task] (map vector (range 1 (inc task-count)) release-tasks)]\n           (apply main/info \"[\" i \"/\" task-count \"] Running lein\" task)\n           (let [current-project (project/init-project (project/read))]\n             (main/resolve-and-apply current-project task)))))))\n\n;; support existing release plugin:\n;; https://github.com/technomancy/leiningen/issues/1544\n(when-let [[resource] (-> (.getContextClassLoader (Thread/currentThread))\n                          (.getResources \"leiningen/release.clj\")\n                          (enumeration-seq) (distinct) (rest) (seq))]\n  (let [release-str (slurp resource)]\n    (when-not (re-find #\"support existing release plugin\" release-str)\n      (clojure.lang.Compiler/load (io/reader resource)\n                                  \"leiningen/release.clj\" release-str))))\n"
  },
  {
    "path": "src/leiningen/repl.clj",
    "content": "(ns leiningen.repl\n  \"Start a repl session either with the current project or standalone.\"\n  (:require [clojure.set]\n            [clojure.main]\n            [clojure.string :as s]\n            [clojure.java.io :as io]\n            nrepl.ack\n            nrepl.config\n            nrepl.server\n            [nrepl.transport :as transport]\n            [cemerick.pomegranate :as pomegranate]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.user :as user]\n            [leiningen.core.project :as project]\n            [leiningen.core.classpath :as classpath]\n            [leiningen.trampoline :as trampoline])\n  (:import\n   (java.io File)\n   (java.net URI)))\n\n(defn- repl-port-file-vector\n  \"Returns the repl port file for this project as a vector.\"\n  [project]\n  (if-let [root (:root project)]\n    [root \".nrepl-port\"]\n    [(user/leiningen-home) \"repl-port\"]))\n\n(defn- repl-port-file-path\n  \"Returns the repl port file path for this project.\"\n  [project]\n  (.getPath (apply io/file (repl-port-file-vector project))))\n\n(defn lookup-opt [opt-key opts]\n  (second (drop-while #(not= % opt-key) opts)))\n\n(defn opt-host [opts]\n  (lookup-opt \":host\" opts))\n\n(defn opt-port [opts]\n  (if-let [port (lookup-opt \":port\" opts)]\n    (Integer/valueOf port)))\n\n(defn opt-socket [opts]\n  (lookup-opt \":socket\" opts))\n\n(defn opt-transport [opts]\n  (if-let [transport (lookup-opt \":transport\" opts)]\n    (utils/require-resolve transport)))\n\n(defn opt-greeting-fn [opts]\n  (if-let [greeting-fn (lookup-opt \":greeting-fn\" opts)]\n    (utils/require-resolve greeting-fn)))\n\n(defn ack-port [project]\n  (if-let [p (or (user/getenv \"LEIN_REPL_ACK_PORT\")\n                 (-> project :repl-options :ack-port)\n                 (:ack-port nrepl.config/config))]\n    (Integer/valueOf p)))\n\n(defn configured-repl-connection [project opts]\n  (let [opt-host (lookup-opt \":host\" opts)\n        opt-port (lookup-opt \":port\" opts)\n        opt-sock (lookup-opt \":socket\" opts)\n        env-host (user/getenv \"LEIN_REPL_HOST\")\n        env-port (user/getenv \"LEIN_REPL_PORT\")\n        env-sock (user/getenv \"LEIN_REPL_SOCKET\")\n        prj-host (-> project :repl-options :host)\n        prj-port (-> project :repl-options :port)\n        prj-sock (-> project :repl-options :socket)\n        nrepl-bind (nrepl.config/config :bind)\n        nrepl-host (nrepl.config/config :host)\n        nrepl-port (nrepl.config/config :port)\n        nrepl-sock (nrepl.config/config :socket)]\n\n    (when (and opt-sock (or opt-host opt-port))\n      (main/abort \":socket argument conflicts with :host and :port\"))\n    (when (and env-sock (or env-host env-port))\n      (main/abort \"LEIN_REPL_HOST conflicts with LEIN_REPL_HOST and LEIN_REPL_PORT\"))\n    (when (and prj-sock (or prj-host prj-port))\n      (main/abort \"project :repl-options :socket conflicts with :host and :port\"))\n    (when (and nrepl-sock (or nrepl-bind nrepl-host nrepl-port))\n      (main/abort \"nREPL config :socket conflicts with :bind, :host, and :port\"))\n\n    (if-let [sock (or opt-sock env-sock prj-sock nrepl-sock)]\n      {:socket sock}\n      {:host (or opt-host env-host prj-host nrepl-host nrepl-bind \"127.0.0.1\")\n       :port (Integer/valueOf (or opt-port env-port prj-port nrepl-port 0))})))\n\n(defn repl-transport [project]\n  (if-let [transport (or (user/getenv \"LEIN_REPL_TRANSPORT\")\n                         (-> project :repl-options :transport)\n                         (:transport nrepl.config/config))]\n    (utils/require-resolve transport)))\n\n(defn repl-greeting-fn [project]\n  (if-let [greeting-fn (or (user/getenv \"LEIN_REPL_GREETING_FN\")\n                           (-> project :repl-options :greeting-fn)\n                           (:greeting-fn nrepl.config/config))]\n    (utils/require-resolve greeting-fn)))\n\n(defn client-repl-port [project configured-port]\n  (let [port configured-port]\n    (if (zero? configured-port)\n      (try\n        (-> (io/file (:root project) \".nrepl-port\")\n            slurp\n            s/trim)\n        (catch Exception _))\n      configured-port)))\n\n(defn ensure-port [s]\n  (if (re-find #\":\\d+($|/.*$)\" s)\n    s\n    (main/abort \"Port is required. See `lein help repl`\")))\n\n(defn is-uri? [s]\n  (boolean (and (string? s) (re-find #\"^https?://\" s))))\n\n(defn string-from-file [arg]\n  (if-let [filename-tmp (and (seq arg) (= \"@\" (subs arg 0 1)) (seq (subs arg 1)))]\n    (let [filename (apply str filename-tmp)\n          errmsg (str \"The file '\" filename \"' can't be read.\")]\n      (if-let [content (try (slurp filename)\n                            (catch Exception e\n                            (main/abort errmsg)))]\n        (s/trim content)\n        (main/abort errmsg)))\n      false))\n\n(defn connect-string [project opts]\n  ;; REVIEW: ignores command line :host ;port :socket, depending on the first arg?\n  (let [opt (str (first opts))]\n    (if-let [sx (string-from-file opt)]\n      (connect-string project [sx])\n      (if (is-uri? opt)\n        opt\n        ;; TODO: perhaps use URI/toASCIIString (like nrepl, and server-forms)\n        (let [{:keys [host port socket]} (configured-repl-connection project opts)]\n          (when socket\n            (main/abort \"Cannot connect to filesystem sockets yet\"))\n          (as-> (s/split opt #\":\") x\n            (remove s/blank? x)\n            (-> (drop-last (count x) [host (client-repl-port project port)])\n                (concat x))\n            (s/join \":\" x)\n            (ensure-port x)))))))\n\n(defn options-for-reply [project & {:keys [attach port scheme]}]\n  (as-> (:repl-options project) opts\n        (merge {:history-file (->> (if-let [root (:root project)]\n                                     [root \".lein-repl-history\"]\n                                     [(user/leiningen-home) \"repl-history\"])\n                                   (apply io/file)\n                                   str)\n                :input-stream System/in\n                ;; TODO: once reply/#114 is fixed; add (user/help) back in and\n                ;; move other source/javadoc/etc references into longer help.\n                :welcome (list 'println (slurp (io/resource \"repl-welcome\")))}\n               opts)\n        (apply dissoc opts :init (if attach [:host :port]))\n        (merge opts (cond attach {:attach (str attach)}\n                          port {:port port}\n                          :else {}))\n        (clojure.set/rename-keys opts {:prompt :custom-prompt\n                                       :welcome :custom-help})\n        (if (:port opts) (update-in opts [:port] str) opts)\n        (if scheme (assoc opts :scheme scheme) opts)))\n\n(defn init-ns [{{:keys [init-ns]} :repl-options, :keys [main]}]\n  (or init-ns (if main (if (namespace main)\n                         (symbol (namespace main))\n                         main))))\n\n(defn- wrap-init-ns [project]\n  (if-let [init-ns (init-ns project)]\n    ;; set-descriptor! currently nREPL only accepts a var\n    `(with-local-vars\n         [wrap-init-ns#\n          (fn [h#]\n            ;; this needs to be a var, since it's in the nREPL session\n            (with-local-vars [init-ns-sentinel# nil]\n              (fn [{:keys [~'session] :as msg#}]\n                (when-not (@~'session init-ns-sentinel#)\n                  (swap! ~'session assoc\n                         (var *ns*)\n                         (try (require '~init-ns) (create-ns '~init-ns)\n                              (catch Throwable t# (create-ns '~'user)))\n                         init-ns-sentinel# true))\n                (h# msg#))))]\n       (doto wrap-init-ns#\n         (nrepl.middleware/set-descriptor!\n          {:requires #{(var nrepl.middleware.session/session)}\n           :expects #{\"eval\"}})\n         (alter-var-root (constantly @wrap-init-ns#))))))\n\n(defn- handler-for [{{:keys [nrepl-middleware nrepl-handler]} :repl-options,\n                     :as project}]\n  (when (and nrepl-middleware nrepl-handler)\n    (main/abort \"Can only use one of\" :nrepl-handler \"or\" :nrepl-middleware))\n  (let [nrepl-middleware (remove nil? (concat [(wrap-init-ns project)]\n                                              (or nrepl-middleware\n                                                  (:middleware nrepl.config/config))))]\n    (or nrepl-handler\n        (:handler nrepl.config/config)\n        `(nrepl.server/default-handler\n           ~@(map #(if (symbol? %) (list 'var %) %) nrepl-middleware)))))\n\n(defn- init-requires [{{:keys [nrepl-middleware nrepl-handler caught]}\n                       :repl-options :as project} & nses]\n  (let [defaults '[nrepl.server incomplete.core]\n        nrepl-syms (->> (cons nrepl-handler nrepl-middleware)\n                        (filter symbol?)\n                        (map namespace)\n                        (remove nil?)\n                        (map symbol))\n        caught (and caught (namespace caught) [(symbol (namespace caught))])]\n    (for [n (concat defaults nrepl-syms nses caught)]\n      (list 'quote n))))\n\n(defn- ignore-sigint-form []\n  `(when (try (Class/forName \"sun.misc.Signal\")\n              (catch ClassNotFoundException e#))\n     (try\n       (sun.misc.Signal/handle\n         (sun.misc.Signal. \"INT\")\n         (proxy [sun.misc.SignalHandler] [] (handle [signal#])))\n       (catch Throwable e#))))\n\n(defn- cfg->transport-uri-scheme\n  [cfg]\n  (transport/uri-scheme (or (:transport cfg) #'transport/bencode)))\n\n(defn- server-forms [project cfg ack-port start-msg?]\n  [`(do (if ~(some-> (:transport cfg) meta :ns str)\n          (require (symbol ~(-> (:transport cfg) meta :ns str))))\n        (let [socket# ~(:socket cfg)\n              server# (nrepl.server/start-server\n                       :bind ~(:host cfg)\n                       :port ~(:port cfg)\n                       :socket socket#\n                       :transport-fn ~(:transport cfg)\n                       :greeting-fn ~(:greeting-fn cfg)\n                       :ack-port ~ack-port\n                       :handler ~(handler-for project))]\n          (if socket#\n            (when ~start-msg?\n              (println \"nREPL server listening on \"\n                       (-> (URI. \"nrepl+unix\" socket# nil) .toASCIIString)))\n            (let [port# (:port server#)\n                  repl-port-file# (apply io/file ~(repl-port-file-vector project))\n                  ;; TODO 3.0: remove legacy repl port support.\n                  legacy-repl-port# (if (.exists (io/file ~(:target-path project \"\")))\n                                      (io/file ~(:target-path project) \"repl-port\"))]\n              (when ~start-msg?\n                (println \"nREPL server started on port\" port# \"on host\" ~(:host cfg)\n                         (str \"- \"\n                              (transport/uri-scheme ~(or (:transport cfg) #'transport/bencode))\n                              \"://\" ~(:host cfg) \":\" port#)))\n              (spit (doto ^File repl-port-file# io/make-parents .deleteOnExit)\n                    port#)\n              (when legacy-repl-port#\n                (spit (doto ^File legacy-repl-port# .deleteOnExit) port#))))\n          @(promise)))\n   ;; TODO: remove in favour of :injections in the :repl profile\n   `(do ~(when-let [init-ns (init-ns project)]\n           `(try (doto '~init-ns require in-ns)\n                 (catch Exception e#\n                   (when-not (= '~init-ns '~'user)\n                     (println e#))\n                   (ns ~init-ns))))\n        (when-not (resolve 'when-some)\n          (binding [*out* *err*]\n            (println \"As of 2.8.2, the repl task is incompatible with\"\n                     \"Clojure versions older than 1.7.0.\"\n                     \"\\nYou can downgrade to 2.8.1 or use `lein trampoline run\"\n                     \"-m clojure.main` for a simpler fallback repl.\"))\n          (System/exit 1))\n        ~@(for [n (init-requires project)]\n            `(try (require ~n)\n                  (catch Throwable t#\n                    (println \"Error loading\" (str ~n \":\")\n                             (or (.getMessage t#) (type t#))))))\n        ~(-> project :repl-options :init))])\n\n(def reply-profile\n  {:dependencies\n   '[^:displace [reply \"0.5.1\" :exclusions [org.clojure/clojure ring/ring-core]]\n     ^:displace [net.cgrand/parsley \"0.9.3\" :exclusions [org.clojure/clojure]]\n     [org.nrepl/incomplete \"0.1.0\"]]})\n\n(defn- trampoline-repl [project port]\n  (let [init-option (get-in project [:repl-options :init])\n        init-code `(do\n                     ~(if-let [ns# (init-ns project)] `(in-ns '~ns#))\n                     ~init-option)\n        options (-> (options-for-reply project :port port)\n                    (assoc :custom-eval init-code)\n                    (dissoc :input-stream))\n        profile (:leiningen/trampoline-repl (:profiles project)\n                                            reply-profile)]\n    (eval/eval-in-project\n     (project/merge-profiles project [profile])\n     `(do (reply.main/launch '~options) (System/exit 0))\n     `(do (try (require '~(init-ns project)) (catch Exception t#))\n          (require ~@(init-requires project 'reply.main))))))\n\n(defn- ack-server\n  \"The server which handles ack replies.\"\n  [transport]\n  (nrepl.server/start-server\n   :bind (:nost (configured-repl-connection nil nil))\n   :handler (nrepl.ack/handle-ack nrepl.server/unknown-op)\n   :transport-fn transport))\n\n(defn nrepl-dependency? [{:keys [dependencies]}]\n  (some (fn [[d]] (re-find #\"nrepl\" (str d))) dependencies))\n\n;; NB: This function cannot happen in parallel (or be recursive) because of race\n;; conditions in nrepl.ack.\n(defn server [project cfg headless?]\n  (nrepl.ack/reset-ack-port!)\n  (when-not (nrepl-dependency? project)\n    (main/info \"Warning: no nREPL dependency detected.\")\n    (main/info \"Be sure to include nrepl/nrepl in :dependencies\"\n               \"of your profile.\"))\n  (let [prep-blocker @eval/prep-blocker\n        ack-port (:port (ack-server (or (:transport cfg) #'transport/bencode)))]\n    (-> (bound-fn []\n          (binding [eval/*pump-in* false]\n            (let [[evals requires]\n                  (server-forms project cfg ack-port (and headless? main/*info*))]\n              (try\n                (eval/eval-in-project project\n                                      `(do ~(ignore-sigint-form) ~evals)\n                                      requires)\n                (catch Exception e\n                  (when main/*debug* (throw e))\n                  (main/warn (.getMessage e)))))))\n        (Thread.) (.start))\n    (when project @prep-blocker)\n    (when headless? @(promise))\n    (if-let [repl-port (nrepl.ack/wait-for-ack\n                        (get-in project [:repl-options :timeout] 60000))]\n      (do (main/info \"nREPL server started on port\"\n                     repl-port \"on host\" (:host cfg)\n                     (str \"- \"\n                          (cfg->transport-uri-scheme cfg)\n                          \"://\" (:host cfg) \":\" repl-port))\n          repl-port)\n      (main/abort \"REPL server launch timed out.\"))))\n\n(defn resolve-reply-launch-nrepl\n  []\n  (utils/require-resolve 'reply.main/launch-nrepl))\n\n(defn client\n  ([project attach]\n   (client project attach {}))\n  ([project attach cfg]\n   (when (is-uri? attach)\n     (require 'drawbridge.client))\n   (pomegranate/add-dependencies :coordinates (:dependencies reply-profile)\n                                 :repositories (map classpath/add-repo-auth\n                                                    (:repositories project)))\n   (let [launch (resolve-reply-launch-nrepl)]\n     (launch (options-for-reply project\n                                :attach attach\n                                :scheme (cfg->transport-uri-scheme cfg))))))\n\n(defn ^:no-project-needed repl\n  \"Start a repl session either with the current project or standalone.\n\nSubcommands:\n\n<none> -> :start\n\n:start [:host host] [:port port]\n  This will launch an nREPL server and connect a client to it.\n  If the :host key is given, LEIN_REPL_HOST is set, or :host is present\n  under :repl-options, that host will be attached to, defaulting to\n  localhost otherwise, which will block remote connections. If the :port\n  key is given, LEIN_REPL_PORT is set, or :port is present under\n  :repl-options in the project map, that port will be used for\n  the server, otherwise it is chosen randomly. When starting outside\n  of a project, the nREPL server will run internally to Leiningen. When\n  run under trampoline, the client/server step is skipped entirely; use\n  the :headless command to start a trampolined server.\n\n:headless [[:host host] [:port port] | [:socket path]]\n  This will launch an nREPL server and wait (as per :start), without\n  connecting a client to it.  If the :socket key is given,\n  LEIN_REPL_SOCKET is set, or :socket is present under :repl-options\n  in the project map, the server will listen on the filesystem socket\n  specified by the path. Note that POSIX does not specify the\n  effect (if any) of the socket file's permissions (and some systems\n  have ignored them), so any access control should be arranged via\n  parent directories. You may not specify both a socket and a\n  host/port.\n\n:connect [dest]\n  Connects to an already running nREPL server. Dest can be:\n  - host:port -- connects to the specified host and port;\n  - port -- resolves host from the LEIN_REPL_HOST environment\n      variable or :repl-options, in that order, and defaults to\n      localhost.\n  If no dest is given, resolves the host resolved as described above\n  and the port from LEIN_REPL_PORT, :repl-options, or .nrepl-port in\n  the project root, in that order. Providing an argument that begins\n  with @ and points to a filename containing a connect string will read\n  that file and use its contents, allowing sensitive credentials to be\n  kept out of the process table and shell history.\n\n:transport [transport]\n  Start nREPL using the transport referenced here, instead of using the\n  default bencode transport. Useful is you want to leverage a client\n  that can't handle bencode.\n  If no transport is given then it will be inferred by checking\n  LEIN_REPL_TRANSPORT, :repl-options, or .nrepl.edn (global one or in\n  the project root), in that order.\n\n:greeting-fn [greeting-fn]\n  Function used to generate the greeting message in the REPL after the\n  nREPL server has started. Useful for \\\"dumb\\\" transports like TTY, or\n  when you want to send some custom message to clients on connect.\n  If no greeting-fn is given then it will be inferred by checking\n  LEIN_REPL_GREETING_FN, :repl-options, or .nrepl.edn (global one or in\n  the project root), in that order.\n\nFor connecting to HTTPS repl servers add [nrepl/drawbridge \\\"0.2.1\\\"]\nto your :plugins list.\n\nNote: the :repl profile is implicitly activated for this task. It cannot be\ndeactivated, but it can be overridden.\"\n\n  ([project] (repl project \":start\"))\n  ([project subcommand & opts]\n   (let [repl-profiles (project/profiles-with-matching-meta project :repl)\n         project (project/merge-profiles project repl-profiles)]\n     (if (= subcommand \":connect\")\n       (client project (doto (connect-string project opts)\n                         (->> (main/info \"Connecting to nREPL at\"))))\n       (let [cfg (assoc (configured-repl-connection project opts)\n                        :transport (or (opt-transport opts) (repl-transport project))\n                        :greeting-fn (or (opt-greeting-fn opts) (repl-greeting-fn project)))\n             socket (:socket cfg)\n             run #(binding [eval/*eval-print-dup* true]\n                    (case subcommand\n                      \":start\" (if trampoline/*trampoline?*\n                                 (trampoline-repl project (:port cfg))\n                                 (client project (server project cfg false) cfg))\n                      \":headless\" (apply eval/eval-in-project project\n                                         (server-forms project cfg\n                                                       (when-not socket (ack-port project))\n                                                       true))\n                      (main/abort (str \"Unknown subcommand \" subcommand))))]\n         (if socket\n           (run)\n           (utils/with-write-permissions (repl-port-file-path project)\n             (run))))))))\n\n;; A note on testing the repl task: it has a number of modes of operation\n;; which need to be tested individually:\n;; * :start (normal operation)\n;; * :headless (server-only)\n;; * :connect (client-only)\n\n;; These three modes should really each be tested in each of these contexts:\n;; * :eval-in :subprocess (default)\n;; * :eval-in :trampoline\n;; * :eval-in :leiningen (:connect prolly doesn't need separate testing here)\n\n;; Visualizing a 3x3 graph with checkboxes is an exercise left to the reader.\n\n;; Possibly worth testing in TERM=dumb (no completion) as well as a regular\n;; terminal, but that doesn't need to happen separately for each\n;; subcommand. This is more about testing reply than the repl task itself.\n"
  },
  {
    "path": "src/leiningen/retest.clj",
    "content": "(ns leiningen.retest\n  \"Run only the test namespaces which failed last time around.\"\n  (:require [leiningen.test :as test]\n            [leiningen.core.main :as main]))\n\n(defn retest\n  \"Run only the test namespaces which failed last time around.\"\n  [project & selectors]\n  (if (:monkeypatch-clojure-test project true)\n    (apply test/test project\n           (concat (if (.exists (java.io.File. \".lein-failures\"))\n                     (->> (slurp \".lein-failures\")\n                          read-string keys sort))\n                   selectors))\n    (main/abort \"Cannot retest when :monkeypatch-clojure-test is disabled.\")))\n"
  },
  {
    "path": "src/leiningen/run.clj",
    "content": "(ns leiningen.run\n  \"Run a -main function with optional command-line arguments.\"\n  (:require [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main])\n  (:import (java.io FileNotFoundException)\n           (clojure.lang Reflector)))\n\n(defn- normalize-main [given]\n  (when-not (or (symbol? given)\n                (and (string? given) (symbol? (read-string given))))\n    (main/abort (str \"Option -m requires a valid namespace argument, not \"\n                     given \".\")))\n  (if (namespace (symbol given))\n    (symbol given)\n    (symbol (name given) \"-main\")))\n\n(defn- prep-arg\n  \"Prepares an argument with the given preparation method.\"\n  [prep-method arg]\n  (case prep-method\n    :stringify (if (string? arg) arg\n                   (pr-str arg)) ;; print-dup/print-meta seems overkill\n    :quote (list 'quote arg)\n    (throw (ex-info \"Unknown preparation method\"\n                    {:prep-method prep-method}))))\n\n;; TODO: get rid of this in 3.0\n(defn run-form\n  \"Construct a form to run the given main defn or class with arguments.\"\n  [given args]\n  `(binding [*command-line-args* '~args]\n     ;;\n     ;; Some complicated error-handling logic here to support main\n     ;; being either a namespace or a class.\n     ;;\n     ;; The use case that prompted this complexity is that if we\n     ;; have a namespace such as:\n     ;;\n     ;;   (ns foo.main\n     ;;     (:require does.not.exist))\n     ;;\n     ;; and we do a `lein run -m foo.main`, we will get a\n     ;; FileNotFoundException, but NOT because foo.main doesn't\n     ;; exist. So we want to make sure that error propogates\n     ;; up in the event that the class doesn't exist as well.\n     ;; But we still have to try the class first because it's\n     ;; not easy to distinguish the above case from the case\n     ;; when foo.main is a class and not a namespace at all.\n     ;;\n     ;; This would be a lot simpler if we weren't trying to\n     ;; transparently support both namespaces and classes specified in\n     ;; the same way.\n     ;;\n\n     ;; Try to require the namespace and run the appropriate var,\n     ;; noting what happened.\n     (let [[ns-flag# data#]\n           (try (require '~(symbol (namespace\n                                    (normalize-main given))))\n                (let [v# (resolve '~(normalize-main given))]\n                  (if (ifn? v#)\n                    [:var v#]\n                    [:not-found]))\n                (catch FileNotFoundException e#\n                  [:threw e#]))\n\n           ;; If we didn't succeed above, check if a class exists for\n           ;; the given name\n           ^Class class#\n           (when-not (= :var ns-flag#)\n             (try (Class/forName ~(name given))\n                  (catch ClassNotFoundException _#)))]\n       (cond\n         (= :var ns-flag#)\n         (data# ~@args)\n\n         ;; If the class exists, run its main method.\n         class#\n         ;; NOTE: this prints a reflection warning, unless project has `:preserve-eval-meta true`\n         ;;       https://github.com/technomancy/leiningen/issues/2695\n         ;;       https://github.com/technomancy/leiningen/issues/2328\n         ;        https://github.com/technomancy/leiningen/issues/2814\n         (Reflector/invokeStaticMethod\n          class# \"main\" ^\"[Ljava.lang.Object;\" (into-array [(into-array String '~args)]))\n\n         ;; If the symbol didn't resolve, give a reasonable message\n         (= :not-found ns-flag#)\n         (throw (Exception. ~(str \"Cannot find anything to run for: \" (name given))))\n\n         ;; If we got an exception earlier and nothing else worked,\n         ;; rethrow that.\n         (= :threw ns-flag#)\n         (do (binding [*out* *err*]\n               (println (str \"Can't find '\" '~given \"' as .class or .clj for \"\n                             \"lein run: please check the spelling.\")))\n             (throw data#))))))\n\n(defn- parse-args\n  \"Parses the arguments passed in to run, and returns a map with the results. If\n  an argument is given more than once, it is assumed to be an argument to the\n  main function.\"\n  ([args] (parse-args args {}))\n  ([[f & rest-args :as args] cur-args]\n   (if-not (seq args)\n     (merge {:arg-conversion :stringify\n             :args args} cur-args)\n     (cond (= \"--\" f)\n           (merge {:arg-conversion :stringify\n                   :args rest-args}\n                  cur-args)\n           (and (or (= \"-m\" f)\n                    (= \":main\" f))\n                (not (contains? cur-args :main)))\n           (if (first rest-args)\n             (->> (assoc cur-args :main (first rest-args))\n                  (parse-args (rest rest-args)))\n             (main/abort \"Option -m requires a namespace argument.\"))\n           (and (= \"--quote-args\" f)\n                (not (contains? cur-args :arg-conversion)))\n           (->> (assoc cur-args :arg-conversion :quote)\n                (parse-args rest-args))\n           :else\n           (merge {:arg-conversion :stringify\n                   :args args}\n                  cur-args)))))\n\n(defn- run-main\n  \"Loads the project namespaces as well as all its dependencies and then calls\n  ns/f, passing it the args.\"\n  [project given prep-type args]\n  ;; must convert lazy-seq to list(issue #2091)\n  ;; eval can't handle well a form that contains an evaluated empty lazy-seq\n  (let [prepped-args (apply list (map #(prep-arg prep-type %) args))]\n    (try (eval/eval-in-project project (run-form given prepped-args))\n         (catch clojure.lang.ExceptionInfo e\n           (main/exit (:exit-code (ex-data e) 1))))))\n\n(defn ^{:help-arglists '([]) :no-project-needed true} run\n  \"Run the project's -main function.\n\nUSAGE: lein run [--] [ARGS...]\nCalls the -main function in the namespace specified as :main in project.clj.\nYou may use -- to escape the first argument in case it begins with `-' or `:'.\nIf your main function is not called \\\"-main\\\", you may use a namespaced symbol\nlike clojure.main/main.\n\nUSAGE: lein run -m NAMESPACE[/MAIN_FUNCTION] [--] [ARGS...]\nCalls the main function in the specified namespace. You may have to use -- to\nescape the first argument in case it begins with `-' or `:'.\n\nThe `--quote-args' flag quotes the arguments passed in, instead of converting\nthem to strings. Arguments coming from the command line will always be strings,\nso this is only useful when invoked from :aliases.\n\nSee also \\\"lein help trampoline\\\" for a way to save memory using this task.\"\n  [project & raw-args]\n  (let [arg-map (parse-args raw-args)]\n    (if (and (not (:main arg-map))\n             (not (:main project)))\n      (main/abort \"No :main namespace specified in project.clj.\")\n      (run-main project (or (:main arg-map) (:main project))\n                (:arg-conversion arg-map) (:args arg-map)))))\n"
  },
  {
    "path": "src/leiningen/search.clj",
    "content": "(ns leiningen.search\n  \"Search Central and Clojars for published artifacts.\"\n  (:require [clojure.string :as string]\n            [clojure.xml :as xml]\n            [leiningen.core.project :as project]\n            [leiningen.core.main :as main])\n  (:import (java.net URLEncoder)\n           (javax.xml.parsers SAXParser)\n           (org.xml.sax.helpers DefaultHandler)))\n\n(defn- decruft-central-xml [content]\n  (zipmap (map #(get-in % [:attrs :name]) content)\n          (map #(get-in % [:content 0]) content)))\n\n;; replace clojure.xml version with one that doesn't do illegal access\n(defn- startparse [^String url ^DefaultHandler ch]\n  (let [^SAXParser p (xml/disable-external-entities (xml/sax-parser))]\n    (.parse p url ch)))\n\n(defn parse [url]\n  (try (xml/parse url startparse)\n       (catch Exception e\n         (main/warn \";; Could not retrieve search results from\"\n                    (str url \":\")\n                    (if (re-find #\"HTTP response code: (400|505)\" (str e))\n                      \"Query syntax unsupported.\"\n                      (.getMessage e)))\n         (when main/*debug*\n           (.printStackTrace e)))))\n\n(defn search-central [query]\n  (let [url (str \"https://search.maven.org/solrsearch/select?wt=xml&q=\" query)]\n    (doseq [doc (get-in (parse url) [:content 1 :content])]\n      (let [result (decruft-central-xml (:content doc))\n            dep (if (= (result \"a\") (result \"g\"))\n                  (result \"a\")\n                  (str (result \"g\") \"/\" (result \"a\")))]\n        (println (format \"[%s \\\"%s\\\"]\" dep (result \"latestVersion\")))))))\n\n(defn search-clojars [query]\n  (let [url (str \"https://clojars.org/search?format=xml&q=\" query)]\n    (doseq [{result :attrs} (:content (parse url))]\n      (let [dep (if (= (result :jar_name) (result :group_name))\n                  (result :jar_name)\n                  (str (result :group_name) \"/\" (result :jar_name)))]\n        (println (format \"[%s \\\"%s\\\"]\" dep (result :version)))\n        (when-let [desc (and (not= (string/trim (result :description \"\")) \"\")\n                             (result :description))]\n          (println \" \" (string/trim (first (string/split desc #\"\\n\")))))))))\n\n(defn ^:no-project-needed search\n  \"Search Central and Clojars for published artifacts.\"\n  [project ^String query]\n  (let [project (or project (project/make {}))\n        repos (into {} (:repositories project))]\n    (doseq [[repo searcher] [[\"central\" search-central]\n                             [\"clojars\" search-clojars]]]\n      (when (repos repo)\n        (try (println \"Searching\" repo \"...\")\n             (searcher (URLEncoder/encode query \"UTF-8\"))\n             (catch java.io.IOException e\n               (binding [*out* *err*]\n                 (println \"Query failed with message\" (.getMessage e)))))))))\n"
  },
  {
    "path": "src/leiningen/show_profiles.clj",
    "content": "(ns leiningen.show-profiles\n  \"List all available profiles or display one if given an argument.\"\n  (:require [clojure.string]\n            [clojure.pprint :as pprint]\n            [leiningen.core.project :as project]))\n\n(defn ^:no-project-needed show-profiles\n  \"List all available profiles or display one if given an argument.\"\n  ([project]\n     (->> (project/read-profiles project)\n          (keys)\n          (map (comp #(subs % 1) str))\n          (sort)\n          (clojure.string/join \"\\n\")\n          (println)))\n  ([project profile]\n     (-> (project/read-profiles project)\n         (get (keyword profile))\n         (pprint/pprint))\n     (flush)))\n"
  },
  {
    "path": "src/leiningen/static_classpath.clj",
    "content": "(ns leiningen.static-classpath\n  \"Print the classpath of the current project without loading code.\"\n  (:require [leiningen.classpath :as classpath]\n            [leiningen.core.project :as project]\n            [clojure.java.io :as io])\n  (:import (java.io PushbackReader)))\n\n(def unsafe-keys [:plugins :hooks :middleware :certificates :mirrors :local-repo\n                  :implicits :implicit-hooks :implicit-middleware])\n\n(def profile-names [:base :system :provided :dev])\n\n(defn- safely-read-project [{:keys [root]}]\n  (with-open [rdr (PushbackReader. (io/reader (io/file root \"project.clj\")))]\n    (let [items (repeatedly #(read {:eof ::eof} rdr))\n          items (take-while #(not= ::eof %) items)\n          [_defproject project-name version & rest] (last items)\n          project (merge {:name (name project-name)\n                          :group (or (namespace project-name)\n                                     (name project-name))\n                          :version version\n                          :root root}\n                         project/defaults\n                         (apply hash-map rest)\n                         {:repositories project/default-repositories\n                          :plugin-repositories project/default-repositories})\n          project (apply dissoc project unsafe-keys)]\n      (project/merge-profiles (project/init-project project profile-names)\n                              profile-names))))\n\n(defn ^:no-project-needed static-classpath\n  \"Write the classpath of the current project to output-file or stdout.\n\nDoes not load any plugins or other project code; should be safe to run on\nuntrusted projects; however, may be less accurate than `classpath`.\nSuitable for use in static analysis.\"\n  ([project]\n   (classpath/classpath (safely-read-project project)))\n  ([project output-file]\n   (classpath/classpath (safely-read-project project) output-file)))\n"
  },
  {
    "path": "src/leiningen/test.clj",
    "content": "(ns leiningen.test\n  \"Run the project's tests.\"\n  (:refer-clojure :exclude [test])\n  (:require [clojure.java.io :as io]\n            [bultitude.core :as b]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [leiningen.core.project :as project])\n  (:import (java.io File PushbackReader)))\n\n(def ^:dynamic *exit-after-tests* true)\n\n;; This is a massive and terrible monkeypatch to work around the fact\n;; that the built-in clojure.test library does not accept patches from\n;; outside the core team. At this point the monkeypatching code below\n;; should be considered legacy, and rather than trying to improve it,\n;; all efforts should be instead directed towards improving external\n;; libraries such as https://github.com/lambdaisland/kaocha, which\n;; has a superset of these features and also doesn't require you to\n;; stop using clojure.test to write your tests.\n\n;; We recommend that projects override the test task with an alias\n;; that calls out to a third-party testing library instead.\n\n(def form-for-suppressing-unselected-tests\n  \"A function that figures out which vars need to be suppressed based on the\n  given selectors, moves their :test metadata to :leiningen/skipped-test (so\n  that clojure.test won't think they are tests), runs the given function, and\n  then sets the metadata back.\"\n  `(fn [namespaces# selectors# func#]\n     (let [copy-meta# (fn [var# from-key# to-key#]\n                        (if-let [x# (get (meta var#) from-key#)]\n                          (alter-meta! var# #(-> % (assoc to-key# x#) (dissoc from-key#)))))\n           vars# (if (seq selectors#)\n                   (->> namespaces#\n                        (mapcat (comp vals ns-interns))\n                        (remove (fn [var#]\n                                  (some (fn [[selector# args#]]\n                                          (let [sfn# (if (vector? selector#)\n                                                       (second selector#)\n                                                       selector#)]\n                                            (apply sfn#\n                                                   (merge (-> var# meta :ns meta)\n                                                          (assoc (meta var#) ::var var#))\n                                                   args#)))\n                                        selectors#)))))\n           copy# #(doseq [v# vars#] (copy-meta# v# %1 %2))]\n       (copy# :test :leiningen/skipped-test)\n       (try (func#)\n            (finally\n              (copy# :leiningen/skipped-test :test))))))\n\n(defn- form-for-select-namespaces [namespaces selectors]\n  `(reduce (fn [acc# [f# args#]]\n             (if (vector? f#)\n               (filter #(apply (first f#) % args#) acc#)\n               acc#))\n           '~namespaces ~selectors))\n\n(defn- form-for-nses-selectors-match [selectors ns-sym]\n  `(distinct\n    (for [ns# ~ns-sym\n          [_# var#] (ns-publics ns#)\n          :when (and (-> var# meta :test)\n                     (some (fn [[selector# args#]]\n\n                             (apply (if (vector? selector#)\n                                      (second selector#)\n                                      selector#)\n                                    (merge (-> var# meta :ns meta)\n                                           (assoc (meta var#) ::var var#))\n                                    args#))\n                           ~selectors))]\n      ns#)))\n\n;; TODO: make this an option to form-for-testing-namespaces in 3.0.\n(def ^:private ^:dynamic *monkeypatch?* true)\n\n(defn form-for-testing-namespaces\n  \"Return a form that when eval'd in the context of the project will test each\n  namespace and print an overall summary.\n\n  Options:\n  - :reloading-require  if true, use :reload option for clojure.core/require calls\"\n  ([namespaces opt & [selectors]]\n     (let [ns-sym (gensym \"namespaces\")]\n       `(let [~ns-sym ~(form-for-select-namespaces namespaces selectors)]\n          (when (seq ~ns-sym)\n            (apply require\n                   ~@(if (:reloading-require opt)\n                       [:reload])\n                   ~ns-sym))\n          (let [failures# (atom {})\n                selected-namespaces# ~(form-for-nses-selectors-match selectors ns-sym)\n                _# (when ~*monkeypatch?*\n                     (leiningen.core.injected/add-hook\n                      #'clojure.test/test-ns\n                      (fn [test-ns# ns#]\n                        (try\n                          (test-ns# ns#)\n                          (catch Throwable t#\n                            (binding [clojure.test/*report-counters*\n                                      (ref clojure.test/*initial-report-counters*)\n                                      clojure.test/*testing-vars*\n                                      (list (with-meta 'test\n                                              {:name ns#\n                                               :ns ns#}))]\n                              (clojure.test/do-report {:type :error\n                                                       :message \"Uncaught exception in test fixture\"\n                                                       :expected nil\n                                                       :actual t#})\n                              (clojure.test/do-report {:type :end-test-ns\n                                                       :ns (the-ns ns#)})\n                              @clojure.test/*report-counters*)))))\n                     (leiningen.core.injected/add-hook\n                      #'clojure.test/report\n                      (fn [report# m# & args#]\n                        (when (#{:error :fail} (:type m#))\n                          (when-let [first-var# (-> clojure.test/*testing-vars* first meta)]\n                            (let [ns-name# (-> first-var# :ns ns-name name)\n                                  test-name# (-> first-var# :name name)]\n                              (swap! failures# update-in [ns-name#] (fnil conj []) test-name#)\n                              (newline)\n                              (println \"lein test :only\" (str ns-name# \"/\" test-name#)))))\n                        (if (= :begin-test-ns (:type m#))\n                          (clojure.test/with-test-out\n                            (newline)\n                            (println \"lein test\" (ns-name (:ns m#))))\n                          (apply report# m# args#)))))\n                summary# (binding [clojure.test/*test-out* *out*]\n                           (~form-for-suppressing-unselected-tests\n                            selected-namespaces# ~selectors\n                            #(apply ~'clojure.test/run-tests selected-namespaces#)))]\n            (spit \".lein-failures\" (if ~*monkeypatch?*\n                                     (pr-str @failures#)\n                                     \"#<disabled :monkeypatch-clojure-test>\"))\n            (let [exit-code# (min 1\n                                  (+ (int (:error summary#))\n                                     (int (:fail summary#))))]\n              (if ~*exit-after-tests*\n                (System/exit exit-code#)\n                exit-code#)))))))\n\n(defn- split-selectors [args]\n  (let [[nses selectors] (split-with (complement keyword?) args)]\n    [nses\n     (loop [acc {} [selector & selectors] selectors]\n       (if (seq selectors)\n         (let [[args next] (split-with (complement keyword?) selectors)]\n           (recur (assoc acc selector (list 'quote args))\n                  next))\n         (if selector\n           (assoc acc selector ())\n           acc)))]))\n\n(defn- partial-selectors [project-selectors selectors]\n  (for [[k v] selectors\n        :let [selector-form (k project-selectors)]\n        :when selector-form]\n    [selector-form v]))\n\n(def ^:private only-form\n  ['(fn [ns & vars]\n      ((set (for [v vars]\n              (-> (str v)\n                  (.split \"/\")\n                  (first)\n                  (symbol))))\n       ns))\n   '(fn [m & vars]\n      (some #(let [var (str \"#'\" %)]\n               (if (some #{\\/} var)\n                 (= var (-> m ::var str))\n                 (= % (ns-name (:ns m)))))\n            vars))])\n\n(defn- convert-to-ns [possible-file]\n  (if (and (re-matches #\".*\\.cljc?\" possible-file) (.exists (io/file possible-file)))\n    (str (second (b/ns-form-for-file possible-file)))\n    possible-file))\n\n(defn ^:internal read-args [args project]\n  (let [args (->> args (map convert-to-ns) (map read-string))\n        [nses given-selectors] (split-selectors args)\n        nses (or (seq nses)\n                 (sort (b/namespaces-on-classpath\n                        :classpath (map io/file (distinct (:test-paths project)))\n                        :ignore-unreadable? false)))\n        selectors (partial-selectors (merge {:all '(constantly true)}\n                                            {:only only-form}\n                                            (:test-selectors project))\n                                     given-selectors)\n        selectors-or-default (if (and (empty? selectors)\n                                      (:default (:test-selectors project)))\n                               [[(:default (:test-selectors project)) ()]]\n                               selectors)]\n    (when (and (empty? selectors)\n               (seq given-selectors))\n      (main/abort \"Please specify :test-selectors in project.clj\"))\n    [nses selectors-or-default]))\n\n(defn test\n  \"Run the project's tests.\n\nMarking deftest or ns forms with metadata allows you to pick selectors to\nspecify a subset of your test suite to run:\n\n    (deftest ^:integration network-heavy-test\n      (is (= [1 2 3] (:numbers (network-operation)))))\n\nWrite the selectors in project.clj:\n\n    :test-selectors {:default (complement :integration)\n                     :integration :integration}\n\nArguments to this task will be considered test selectors if they are keywords,\notherwise arguments must be test namespaces or files to run. With no\narguments the :default test selector is used if present, otherwise all\ntests are run. Test selector arguments must come after the list of namespaces.\n\nA default :only test-selector is available to run select tests. For example,\n`lein test :only leiningen.test.test/test-default-selector` only runs the\nspecified test. A default :all test-selector is available to run all tests.\n\nIf :eval-in :nrepl is specified in the project, test namespaces may reload\nout-of-order. However, all test namespaces will be (re)loaded at least\nonce (in *some* order).\n\nIf you are looking for more control over your tests, consider 3rd-party\nrunners like Kaocha.\n\nThis task uses the following exit codes:\n- 0 if all tests pass successfully\n- 1 otherwise\"\n  [project & tests]\n  (binding [main/*exit-process?* (if (= :leiningen (:eval-in project))\n                                   false\n                                   main/*exit-process?*)\n            *exit-after-tests* (if (= :leiningen (:eval-in project))\n                                 false\n                                 *exit-after-tests*)\n            *monkeypatch?* (:monkeypatch-clojure-test project true)]\n    (let [project (project/merge-profiles project [:leiningen/test :test])\n          [nses selectors] (read-args tests project)\n          _ (eval/prep project)\n          form (form-for-testing-namespaces\n                 nses\n                 {;; people running `lein test` with :eval-in :nrepl presumably\n                  ;; want the nrepl server to reevaluate code on each run.\n                  ;; while it's known to be buggy to use :reload, let's just\n                  ;; use it for now, because the alternative would be somewhat\n                  ;; underwhelming for users of :eval-in :nrepl (tests would\n                  ;; never reload).\n                  :reloading-require (= :nrepl (:eval-in project))}\n                 (vec selectors))]\n      (try (let [exit (eval/eval-in-project project form '(require 'clojure.test))]\n             (when (and (number? exit) (pos? exit))\n               (throw (ex-info \"Tests Failed\" {:exit-code exit}))))\n           (catch clojure.lang.ExceptionInfo e\n             (main/abort (.getMessage e)))))))\n"
  },
  {
    "path": "src/leiningen/trampoline.clj",
    "content": "(ns leiningen.trampoline\n  \"Run a task without nesting the project's JVM inside Leiningen's.\"\n  (:refer-clojure :exclude [trampoline])\n  (:require [clojure.string :as string]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.project :as project]\n            [clojure.java.io :as io]\n            [clojure.pprint :as pprint]))\n\n(def ^:dynamic *trampoline?* false)\n\n(defn- trampoline-file []\n  (System/getenv \"TRAMPOLINE_FILE\"))\n\n(defn- win-batch? []\n  (if-let [t (trampoline-file)]\n    (.endsWith t \".bat\")))\n\n(defn- quote-arg [arg]\n  (if (win-batch?)\n    (format \"\\\"%s\\\"\" arg)\n    (format \"'%s'\" arg)))\n\n(defn trampoline-command-string [project forms profiles]\n  ;; each form is (do init & body)\n  (let [forms (map rest forms) ;; strip off do\n        inits (map first forms)\n        rests (mapcat rest forms)\n        command (eval/shell-command project (concat '(do) inits rests))]\n    (string/join \" \" (map quote-arg command))))\n\n(defn write-trampoline [project forms profiles]\n  (let [command (trampoline-command-string project forms profiles)\n        trampoline (trampoline-file)]\n    (main/debug \"Trampoline command:\" command)\n    (utils/mkdirs (.getParentFile (io/file trampoline)))\n    (spit trampoline command)))\n\n(defn ^:higher-order trampoline\n  \"Run a task without nesting the project's JVM inside Leiningen's.\n\nCalculates the Clojure code to run in the project's process for the\ngiven task and allows Leiningen's own JVM process to exit before\nrunning it rather than launching a subprocess of Leiningen's JVM.\n\nUse this to save memory or to work around stdin issues.\n\nNote that this can be unpredictable on account of collapsing all\neval-in-project calls into one run. For example, tasks chained\ntogether under different profiles end up all running together.\"\n\n  [project task-name & args]\n  (when (= :leiningen (:eval-in project))\n    (main/info \"Warning: trampoline has no effect with :eval-in-leiningen.\"))\n  (binding [*trampoline?* true]\n    (main/apply-task (main/lookup-alias task-name project)\n                     (-> (assoc project :eval-in :trampoline)\n                         (vary-meta update-in [:without-profiles] assoc\n                                    :eval-in :trampoline))\n                     args))\n  (if (seq @eval/trampoline-forms)\n    (write-trampoline @eval/trampoline-project\n                      @eval/trampoline-forms\n                      @eval/trampoline-profiles)\n    (main/abort task-name \"did not run any project code for trampolining.\")))\n"
  },
  {
    "path": "src/leiningen/uberjar.clj",
    "content": "(ns leiningen.uberjar\n  \"Package up the project files and dependencies into a jar file.\"\n  (:require [clojure.xml :as xml]\n            [clojure.zip :as zip]\n            [clojure.java.io :as io]\n            [leiningen.core.classpath :as classpath]\n            [leiningen.core.project :as project]\n            [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]\n            [leiningen.jar :as jar]\n            [leiningen.pom :as pom]\n            [clojure.set :as set])\n  (:import (java.io File FileOutputStream PrintWriter InputStream)\n           (java.util.regex Pattern)\n           (java.util.zip ZipFile ZipOutputStream ZipEntry)\n           (javax.xml.parsers SAXParser)\n           (org.xml.sax.helpers DefaultHandler)\n           (org.apache.commons.io.output CloseShieldOutputStream)\n           (org.apache.commons.lang StringEscapeUtils)))\n\n(defn- check-for-snapshot-deps [project]\n  (->> (project/non-leaky-profiles project)\n       (project/unmerge-profiles project)\n       pom/check-for-snapshot-deps))\n\n(defn- tree-edit\n  \"Walk the componment xml dom looking for description tag\"\n  [zipper editor]\n  (loop [loc zipper]\n    (if (zip/end? loc)\n      (zip/root loc)\n      (if (= :description (:tag (zip/node loc)))\n        (let [new-loc (zip/edit loc editor)]\n          (recur (zip/next new-loc)))\n        (recur (zip/next loc))))))\n\n(defn- html-escape-editor\n  \"Escape <,>,& from content\"\n  [node]\n  (let [content (get (:content node) 0)]\n    (if-not (nil? content)\n      (assoc-in node [:content 0] (StringEscapeUtils/escapeXml content))\n      node)))\n\n;; replace clojure.xml version with one that doesn't do illegal access\n(defn- startparse [^InputStream ins ^DefaultHandler ch]\n  (let [^SAXParser p (xml/disable-external-entities (xml/sax-parser))]\n    (.parse p ins ch)))\n\n(defn- components-read [ins]\n  (let [zipper (-> ins (xml/parse startparse) zip/xml-zip)]\n    (->> (tree-edit zipper html-escape-editor) zip/xml-zip zip/children\n         (filter #(= (:tag %) :components))\n         first :content)))\n\n(defn- components-write [out components]\n  (binding [*out* (PrintWriter. out)]\n    (xml/emit {:tag :component-set\n               :content\n               [{:tag :components\n                 :content components}]})\n    (.flush *out*)))\n\n(def components-merger\n  \"Project `:uberjar-merge-with` merger for components.xml files.\"\n  [components-read into components-write])\n\n(def clj-map-merger\n  \"Project `:uberjar-merge-with` for files containing a single map\n  read with `clojure.core/read`, such as data_readers.clj.\"\n  [(comp read-string slurp) merge #(spit %1 (pr-str %2))])\n\n(defn- merger-match? [[pattern] filename]\n  (boolean\n   (condp instance? pattern\n     String (= pattern filename)\n     Pattern (re-find pattern filename))))\n\n(def ^:private skip-merger\n  [(constantly ::skip)\n   (constantly nil)])\n\n(def ^:private default-merger\n  [(fn [in out file prev]\n     (when-not prev\n       (.setCompressedSize file -1)\n       (.putNextEntry out file)\n       (io/copy (.getInputStream in file) out)\n       (.closeEntry out))\n     ::skip)\n   (constantly nil)])\n\n(defn- make-merger [fns]\n  {:pre [(sequential? fns) (= 3 (count fns)) (every? ifn? fns)]}\n  (let [[read-fn merge-fn write-fn] fns]\n    [(fn [in out file prev]\n       (with-open [ins (.getInputStream in file)]\n         (let [new (read-fn ins)]\n           (if-not prev\n             new\n             (merge-fn new prev)))))\n     (fn [out filename result]\n       (.putNextEntry out (ZipEntry. filename))\n       (write-fn (CloseShieldOutputStream. out) result)\n       (.closeEntry out))]))\n\n(defn- make-mergers [project]\n  (into (utils/map-vals (:uberjar-merge-with project)\n                        (comp make-merger eval))\n        (map #(vector % skip-merger)\n             (:uberjar-exclusions project))))\n\n(defn- select-merger [mergers filename]\n  (or (->> mergers (filter #(merger-match? % filename)) first second)\n      default-merger))\n\n(defn- warn-on-drop [filename]\n  (let [non-code #\".*/|project\\.clj|META-INF/(MANIFEST\\.MF|(NOTICE|LICENSE)(.*\\.txt)?|DEPENDENCIES)\"]\n    (if-not (re-matches non-code filename)\n      (main/debug \"  Dropping\" filename))))\n\n;; TODO: unify with copy-to-jar functionality in jar.clj (for 3.0?)\n(defn- copy-entries\n  \"Read entries of ZipFile `in` and apply the filename-determined entry-merging\n  logic captured in `mergers`. The default merger copies entry contents directly\n  to the ZipOutputStream `out` and skips subsequent same-named files. Returns\n  new `merged-map` merged entry map.\"\n  [in out mergers merged-map]\n  (reduce (fn [merged-map file]\n            (let [filename (.getName file), prev (get merged-map filename)]\n              (if (identical? ::skip prev)\n                (do (warn-on-drop filename)\n                  merged-map)\n                (let [[read-merge] (select-merger mergers filename)]\n                  (assoc merged-map\n                    filename (read-merge in out file prev))))))\n          merged-map (enumeration-seq (.entries in))))\n\n(defn- include-dep [out mergers merged-map dep]\n  (main/debug \"Including\" (.getName dep))\n  (with-open [zipfile (ZipFile. dep)]\n    (copy-entries zipfile out mergers merged-map)))\n\n(defn write-components\n  \"Given a list of jarfiles, writes contents to a stream\"\n  [project jars out]\n  (let [mergers (make-mergers project)\n        include-dep (partial include-dep out mergers)\n        merged-map (reduce include-dep {} jars)]\n    (doseq [[filename result] merged-map\n            :when (not (identical? ::skip result))\n            :let [[_ write] (select-merger mergers filename)]]\n      (write out filename result))))\n\n(defn uberjar\n  \"Package up the project files and all dependencies into a jar file.\n\nIncludes the contents of each of the dependency jars. Suitable for standalone\ndistribution.\n\nWith an argument, the uberjar will be built with an alternate main.\n\nThe namespace you choose as main should have :gen-class in its ns form\nas well as defining a -main function.\n\nNote: The :uberjar profile is implicitly activated for this task, and cannot\nbe deactivated.\"\n\n  ([project main]\n   (let [scoped-profiles (set (project/pom-scope-profiles project :provided))\n         default-profiles (set (project/expand-profile project :default))\n         provided-profiles (remove\n                            (set/difference default-profiles scoped-profiles)\n                            (-> project meta :included-profiles))\n         project (->> (into [:uberjar] provided-profiles)\n                      (project/merge-profiles project))\n         _ (check-for-snapshot-deps project)\n         project (update-in project [:jar-inclusions]\n                            concat (:uberjar-inclusions project))\n         [_ jar] (try (first (jar/jar project main))\n                      (catch Exception e\n                        (when main/*debug*\n                          (.printStackTrace e))\n                        (main/abort \"Uberjar aborting because jar failed:\"\n                                    (.getMessage e))))\n         standalone-filename (jar/get-jar-filename project :standalone)]\n     (with-open [out (-> standalone-filename\n                         (FileOutputStream.)\n                         (ZipOutputStream.))]\n       (let [whitelisted (select-keys project project/whitelist-keys)\n             project (-> (project/unmerge-profiles project [:default])\n                         (merge whitelisted))\n             deps (->> (classpath/resolve-managed-dependencies\n                        :dependencies :managed-dependencies project)\n                       (filter #(.endsWith (.getName %) \".jar\")))\n             jars (cons (io/file jar) deps)]\n         (write-components project jars out)))\n     (main/info \"Created\" standalone-filename)\n     standalone-filename))\n  ([project] (uberjar project nil)))\n"
  },
  {
    "path": "src/leiningen/update_in.clj",
    "content": "(ns leiningen.update-in\n  \"Perform arbitrary transformations on your project map.\"\n  (:refer-clojure :exclude [update-in])\n  (:require [leiningen.core.main :as main]\n            [leiningen.core.project :as project]\n            [leiningen.core.utils :as utils]\n            [clojure.core :as clj]))\n\n(defn ^:internal parse-args [key-path f args]\n  (let [[f-args [_ & task+args]] (split-with #(not= \"--\" %) args)]\n    [(mapv keyword (rest (.split key-path \":\")))\n     (utils/require-resolve (read-string f))\n     (mapv read-string f-args)\n     task+args]))\n\n(defn ^:internal update-project [project keys-vec f args]\n  (let [f #(if (seq keys-vec)\n             (apply clj/update-in % keys-vec f args)\n             (apply f % args))]\n    (-> (vary-meta (f project) clj/update-in [:without-profiles] f)\n        (project/load-plugins)\n        (project/activate-middleware))))\n\n(defn ^:higher-order ^:no-project-needed update-in\n  \"Perform arbitrary transformations on your project map.\n\nActs a lot like calling `clojure.core/update-in` on your project map\nand then invoking a task on it, but with a few differences. Instead of\na vector of keys for reaching into nested maps, just mash keywords\ntogether like \\\":repl-options:port\\\". A single \\\":\\\" refers to the map\nroot. Provide the arguments to f (which must be a resolvable var)\nfollowed by \\\"--\\\", and then the task name and arguments to the task:\n\n    $ lein update-in :dependencies conj \\\"[slamhound \\\\\\\"1.1.3\\\\\\\"]\\\" -- repl\"\n  [project key-path f & args]\n  (let [[keys-vec f f-args task+args] (parse-args key-path f args)]\n    (main/resolve-and-apply (update-project project keys-vec f f-args)\n                            task+args)))\n"
  },
  {
    "path": "src/leiningen/upgrade.clj",
    "content": "(ns leiningen.upgrade\n  \"Upgrade Leiningen to specified version or latest stable.\"\n  (:require [leiningen.core.main :as main]))\n\n;; This file is only a placeholder. The real upgrade\n;; implementation can be found in the 'lein' script.\n\n(defn ^:no-project-needed upgrade\n  \"Upgrade Leiningen to specified version or latest stable.\"\n  [project & args]\n  (main/abort \"Upgrade is either disabled, or you have tried to call it from a\"\n              \"higher order\\ntask. If you've installed lein through a package\"\n              \"manager, upgrade lein through\\nthe package manager's upgrade\"\n              \"commands.\"))\n"
  },
  {
    "path": "src/leiningen/vcs.clj",
    "content": "(ns leiningen.vcs\n  \"Interact with the version control system.\"\n  (:require [clojure.java.io :as io]\n            [bultitude.core :as b]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]))\n\n;; TODO: make pom task use this ns by adding a few more methods\n\n(def supported-systems (atom [:git]))\n\n(defn uses-vcs [project vcs]\n  (let [vcs-dir (io/file (:root project)\n                         (get-in project [:scm :dir] \"\")\n                         (str \".\" (name vcs)))]\n    (and (.exists vcs-dir) vcs)))\n\n(defn which-vcs [project & _]\n  (or (:vcs project) (some (partial uses-vcs project) @supported-systems)))\n\n(defn parse-tag-args [args]\n  (loop [parsed-args {:sign? true :annotate? true}\n         args args]\n    (case (first args)\n      (\"--sign\" \"-s\") (recur (assoc parsed-args :sign? true) (rest args))\n      \"--no-sign\" (recur (assoc parsed-args :sign? false) (rest args))\n      \"--annotate\" (recur (assoc parsed-args :annotate? true) (rest args))\n      \"--no-annotate\" (recur (assoc parsed-args :annotate? false) (rest args))\n      nil parsed-args                                       ;; We're finished and can exit\n      (recur (assoc parsed-args :prefix (first args)) (rest args)))))\n\n(def default-commit-message \"Version %s\")\n\n;;; Methods\n\n(defmulti push \"Push to your remote repository.\"\n  which-vcs :default :none)\n\n(defmulti commit\n  \"Commit changes to current repository. Takes an optional format\n  string for the commit message that will be provided the version.\"\n  which-vcs :default :none)\n\n(defmulti tag\n  \"Apply a version control tag. Takes an optional tag prefix.\n  Pass --no-sign option to skip signing, or --no-annotate to create\n  non-release tags.\"\n  which-vcs :default :none)\n\n(defmulti assert-committed \"Abort if uncommitted changes exist.\"\n  which-vcs :default :none)\n\n\n;;; VCS not found\n\n(defn- unknown-vcs [task]\n  (binding [*out* *err*]\n    (println (str \"VCS not found for 'vcs \" task \"'\"))\n    (println \"Maybe add :scm {:dir \\\"..\\\"} to project.clj?\"))\n  (System/exit 1))\n\n(defmethod push :none [project & [args]] (unknown-vcs \"push\"))\n\n(defmethod commit :none [project & _] (unknown-vcs \"commit\"))\n\n(defmethod tag :none [project] (unknown-vcs \"tag\"))\n\n(defmethod assert-committed :none [project] (unknown-vcs \"assert-committed\"))\n\n\n;;; Git\n\n(defmethod push :git [project & args]\n  (binding [eval/*dir* (:root project)]\n    (apply eval/sh-with-exit-code \"Couldn't push to the remote\" \"git\" \"push\" \"--follow-tags\" args)))\n\n(defmethod commit :git\n  ([project]\n   (commit project default-commit-message))\n  ([project message-template]\n   (binding [eval/*dir* (:root project)]\n     (let [message (format message-template (:version project))]\n       (eval/sh-with-exit-code \"Couldn't commit\" \"git\" \"commit\" \"-a\" \"-m\" message)))))\n\n(defmethod tag :git [{:keys [root version]} & args]\n  (binding [eval/*dir* root]\n    (let [{:keys [annotate? sign? prefix]} (parse-tag-args args)\n          tag (if prefix\n                (str prefix version)\n                version)\n          cmd (->> [\"git\" \"tag\" (if sign? \"--sign\") tag (if annotate? \"-a\") \"-m\" (str \"Release \" version)]\n                   (filter some?))]\n      (apply eval/sh-with-exit-code \"Couldn't tag\" cmd))))\n\n(defmethod assert-committed :git [project]\n  (binding [eval/*dir* (:root project)]\n    (when (re-find #\"Changes (not staged for commit|to be committed)\"\n                   (utils/with-system-out-str (eval/sh-with-exit-code \"Couldn't get status\" \"git\" \"status\")))\n       (main/abort \"Uncommitted changes in\" (:root project) \"directory.\"))))\n\n(defn- not-found [subtask]\n  (partial #'main/task-not-found (str \"vcs \" subtask)))\n\n(defn- load-methods []\n  (doseq [n (b/namespaces-on-classpath :prefix \"leiningen.vcs.\")]\n    (swap! supported-systems conj (keyword (last (.split (name n) \"\\\\.\"))))\n    (require n)))\n\n(defn ^{:subtasks [#'push #'commit #'tag #'assert-committed]} vcs\n  \"Interact with the version control system.\"\n  [project subtask & args]\n  (load-methods)\n  (let [subtasks (:subtasks (meta #'vcs) {})\n        [subtask-var] (filter #(= subtask (name (:name (meta %)))) subtasks)]\n    (apply (or subtask-var (not-found subtask)) project args)))\n"
  },
  {
    "path": "src/leiningen/version.clj",
    "content": "(ns leiningen.version\n  \"Print version for Leiningen and the current JVM.\"\n  (:require [leiningen.core.main :as main]))\n\n(defn ^:no-project-needed version\n  \"Print version for Leiningen and the current JVM.\"\n  [project]\n  (println \"Leiningen\" (main/leiningen-version)\n           \"on Java\" (System/getProperty \"java.version\")\n           (System/getProperty \"java.vm.name\")))\n"
  },
  {
    "path": "src/leiningen/with_profile.clj",
    "content": "(ns leiningen.with-profile\n  \"Apply the given task with the profile(s) specified.\"\n  (:require [clojure.string :as string]\n            [leiningen.core.main :as main]\n            [leiningen.core.project :as project]\n            [robert.hooke :as hooke]))\n\n(defn ^:internal with-profiles*\n  \"Apply the given task with a comma-separated profile list.\"\n  [project profiles task-name args]\n  (hooke/with-scope\n    (let [project (and project (project/set-profiles project profiles))\n          task-name (main/lookup-alias task-name project)]\n      (main/apply-task task-name project args))))\n\n(defn profiles-in-group\n  [project profile-group]\n  (let [profiles (.split profile-group \",\")\n        prefixes (map first profiles)]\n    (cond\n     (every? #{\\+ \\-} prefixes)\n     (distinct\n      (reduce (fn [result profile]\n                (let [pm (first profile), profile (keyword (subs profile 1))\n                      profiles (project/expand-profile project profile)]\n                  (if (= \\+ pm)\n                    (concat result profiles)\n                    (remove (set profiles) result))))\n              (mapcat (partial project/expand-profile project)\n                      (:active-profiles (meta project)))\n              profiles))\n\n     (not-any? #{\\+ \\-} prefixes)\n     (distinct\n      (mapcat (comp #(project/expand-profile project %) keyword)\n              profiles))\n\n     :else\n     (throw\n      (ex-info\n       \"Profiles in with-profile must either all be qualified, or none qualified\"\n       {:exit-code 1})))))\n\n\n(defn- apply-task-with-profiles\n  [project profiles task-name args failures multi-group]\n  (when multi-group\n    (main/info (format \"Performing task '%s' with profile(s): '%s'\"\n                       task-name\n                       (string/join \",\" (map name profiles)))))\n  (binding [main/*exit-process?* false]\n    (try\n      (with-profiles* project profiles task-name args)\n      (catch Exception e\n        (main/info\n         (format \"Error encountered performing task '%s' with profile(s): '%s'\"\n                 task-name (string/join \",\" (map name profiles))))\n        (if (and (:exit-code (ex-data e)) (not main/*debug*))\n          (main/info (.getMessage e))\n          (.printStackTrace e))\n        (swap! failures inc)))))\n\n(defn ^:no-project-needed ^:higher-order with-profile\n  \"Apply the given task with the profile(s) specified.\n\nComma-separated profiles may be given to merge profiles and perform the task.\nColon-separated profiles may be given for sequential profile task application.\n\nA profile list may either be a list of profiles to use, or may specify the\nprofiles to add or remove from the active profile list using + or - prefixes.\n\nFor example:\n\n     lein with-profile user,dev test\n     lein with-profile -dev test\n     lein with-profile +1.4:+1.4,-dev:base,user test\n\nTo list all profiles or show a single one, see the show-profiles task.\nFor a detailed description of profiles, see `lein help profiles`.\"\n  [project profiles task-name & args]\n  (let [profile-groups (seq (.split profiles \":\"))\n        failures (atom 0)\n        result (->> profile-groups\n                    (map (partial profiles-in-group project))\n                    (mapv #(apply-task-with-profiles\n                            project % task-name args failures\n                            (> (count profile-groups) 1))))]\n    (when (pos? @failures)\n      (main/abort))\n    result))\n"
  },
  {
    "path": "test/.gnupg/gpg.conf",
    "content": "keyserver keys.openpgp.org"
  },
  {
    "path": "test/leiningen/echo.clj",
    "content": "(ns leiningen.echo)\n\n(defn ^:no-project-needed echo [project & args]\n  (apply println args))\n"
  },
  {
    "path": "test/leiningen/project.clj",
    "content": "(ns leiningen.project)\n\n(defn ^:no-project-needed project [project & args]\n  (if (seq args)\n    (get-in project (mapv keyword args))\n    project))\n"
  },
  {
    "path": "test/leiningen/test/change.clj",
    "content": "(ns leiningen.test.change\n  (:require [clojure.string :as str]\n            [clojure.test :refer :all]\n            [leiningen.change :refer :all]))\n\n(deftest test-set-version\n  (testing \"project definition not found\"\n    (is (thrown-with-msg?\n         IllegalArgumentException #\"Project definition not found\"\n         (change-string \";;(defproject stealth.library \\\"0.0.0\\\")\"\n                        [:version] \"set\" \"0.0.1\"))))\n\n  (testing \"project version not found\"\n    (is (thrown-with-msg?\n         IllegalArgumentException #\"Project version not found\"\n         (change-string \"(defproject com.someproject :dependencies [[\\\"some.thing\\\" \\\"2.3.1\\\"]])\"\n                        [:version] \"set\" \"1.2.3\"))))\n\n  (testing \"simplest possible case\"\n    (is (= \"(defproject leingingen.change \\\"0.0.2-SNAPSHOT\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\")\"\n                          [:version] \"set\" \"0.0.2-SNAPSHOT\"))))\n\n  (testing \"the largest project.clj in the repo\"\n    (let [before (slurp (clojure.java.io/resource \"leiningen/help/project.clj\"))\n          after  (change-string before [:version] \"set\" \"6.4.1\")]\n      ;; check the key portion\n      (is (= \"(defproject org.example/sample \\\"6.4.1\\\" \" (.substring after 529 568)))\n      ;; check a random dependency for changes\n      (is (re-find #\"log4j \\\"1.2.15\\\"\" after)))))\n\n(deftest test-set-group-id\n  (testing \"renaming an existing group-id\"\n    (is (= \"(defproject core/library \\\"0.0.1\\\" :license {})\"\n           (change-string \"(defproject contrib/library \\\"0.0.1\\\" :license {})\"\n                          [:group-id] \"set\" \"core\"))))\n  (testing \"where group-id was previously implicit\"\n    (is (= \"(defproject core/library \\\"0.0.1\\\" :license {})\"\n           (change-string \"(defproject library \\\"0.0.1\\\" :license {})\"\n                          [:group-id] \"set\" \"core\")))))\n\n(deftest test-set-artifact-id\n  (testing \"where group-id is implicit\"\n    (is (= \"(defproject reagent \\\"0.0.1\\\" :license {})\"\n           (change-string \"(defproject cloact \\\"0.0.1\\\" :license {})\"\n                          [:artifact-id] \"set\" \"reagent\"))))\n  (testing \"where group-id is explicit\"\n    (is (= \"(defproject tonsky/datascript \\\"0.0.1\\\" :license {})\"\n           (change-string \"(defproject tonsky/datalogscript \\\"0.0.1\\\" :license {})\"\n                          [:artifact-id] \"set\" \"datascript\")))))\n\n(deftest test-external-function\n  (testing \"regular function by string identifier\"\n    (is (= \"(defproject leingingen.change \\\"1.9.52\\\")\"\n           (change-string \"(defproject leingingen.change \\\"1.9.52-QUALIFIED\\\")\"\n                          [:version] \"leiningen.release/bump-version\" :release))))\n\n  ;; NOTE: order is important here, previous test cases leiningen.relase to be loaded\n  (testing \"regular function by actual reference\"\n    (is (= \"(defproject leingingen.change \\\"1.9.53-SNAPSHOT\\\")\"\n           (change-string \"(defproject leingingen.change \\\"1.9.52\\\")\"\n                          [:version] (find-var 'leiningen.release/bump-version)\n                          :patch)))))\n\n(deftest test-set-map-value\n  (testing \"can set a key\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\" :description \\\"a static description\\\")\"\n                          [:description] \"set\" \"a dynamic description\"))))\n\n  (testing \"can set a key with newlines in place\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :description \\\"a dynamic description\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :description \\\"a static description\\\")\"\n                          [:description] \"set\" \"a dynamic description\"))))\n\n  (testing \"can set a key with empty line in place\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\"\\n\\n  :description \\\"a dynamic description\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\"\\n\\n  :description \\\"a static description\\\")\"\n                          [:description] \"set\" \"a dynamic description\"))))\n\n  (testing \"can set a key with newlines and comments in place\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :description \\\"a static description\\\"\\n ; whatever \\n  :url  \\\"https://test.com\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :description \\\"a static description\\\"\\n ; whatever \\n  :url  \\\"https://old.com\\\")\"\n                          [:url] \"set\" \"https://test.com\"))))\n\n  (testing \"can create a new key\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\")\"\n                          [:description] \"set\" \"a dynamic description\"))))\n\n  (testing \"can create a new key with newlines in place\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\"\\n :description \\\"a dynamic description\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\"\\n)\"\n                          [:description] \"set\" \"a dynamic description\"))))\n\n  (testing \"can create a new key instead of replacing a nested one with the same name\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :description \\\"a dynamic description\\\"\\n  :license {:name \\\"Test\\\"\\n  :url \\\"https://test.com\\\"}\\n :url \\\"https://new.com\\\")\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :description \\\"a dynamic description\\\"\\n  :license {:name \\\"Test\\\"\\n  :url \\\"https://test.com\\\"}\\n)\"\n                          [:url] \"set\" \"https://new.com\"))))\n\n  (testing \"can set a nested key\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\" :license {:url \\\"https://example.com\\\"})\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\" :license {:url \\\"https://old.com\\\"})\"\n                          [:license :url] \"set\" \"https://example.com\"))))\n\n  (testing \"can set a nested key with newlines in place\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :license {:url \\\"https://example.com\\\"})\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\"\\n  :license {:url \\\"https://old.com\\\"})\"\n                          [:license :url] \"set\" \"https://example.com\"))))\n\n  (testing \"can create a nested value\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\" :a {:b {:c 1}})\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\")\"\n                          [:a :b :c] \"set\" 1))))\n\n  (testing \"can understand cli short form\"\n    (is (= \"(defproject leingingen.change \\\"0.0.1\\\" :license {:url \\\"https://example.com\\\"})\"\n           (change-string \"(defproject leingingen.change \\\"0.0.1\\\")\"\n                          \":license:url\" \"set\" \"https://example.com\")))))\n\n(deftest test-set-dependency-value\n  (testing \"can set dependency version\"\n    (is (= \"(defproject leiningen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\" :dependencies [[org.clojure/clojure \\\"1.10.1\\\"]])\"\n           (change-string \"(defproject leiningen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\" :dependencies [[org.clojure/clojure \\\"1.8.0\\\"]])\"\n                          \":dependencies:org.clojure/clojure\"  \"set\" \"1.10.1\"))))\n  (testing \"can alter version without impacting the rest of a dependency vector\"\n    (is (= \"(defproject leiningen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\" :dependencies [[org.clojure/clojure \\\"1.10.1\\\" :exclusions [group/artifact \\\"1.0.0\\\"]]])\"\n          (change-string \"(defproject leiningen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\" :dependencies [[org.clojure/clojure \\\"1.8.0\\\" :exclusions [group/artifact \\\"1.0.0\\\"]]])\"\n                         \":dependencies:org.clojure/clojure\"  \"set\" \"1.10.1\"))))\n  (testing \"can append dependency version\"\n    (is (= \"(defproject leiningen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\" :dependencies [[org.clojure/clojure \\\"1.8.0\\\"] [org.clojure/core.cache \\\"1.0.207\\\"]])\"\n           (change-string \"(defproject leiningen.change \\\"0.0.1\\\" :description \\\"a dynamic description\\\" :dependencies [[org.clojure/clojure \\\"1.8.0\\\"]])\"\n                          \":dependencies:org.clojure/core.cache\"  \"set\" \"1.0.207\")))))\n\n(deftest test-normalize-path\n  (is (= [:a]\n         (normalize-path \"a\")\n         (normalize-path \":a\")))\n  (is (= [:a :b]\n         (normalize-path \"a:b\")\n         (normalize-path \":a:b\")\n         (normalize-path [:a :b])))\n  (is (= [:dependencies :org.clojure/clojure]\n         (normalize-path \":dependencies:org.clojure/clojure\")\n         )))\n\n(def div-dinc (comp inc inc /))\n\n(deftest test-collapse-fn\n  ;; right-partial application\n  (is (= 10 ((collapse-fn div-dinc [2 3 4]) 192)))\n  ;; return leading constant\n  (is (= 10 ((collapse-fn \"set\" [10]) :ignored)))\n  (is (= 10 ((collapse-fn \"set\" [10 :ignored :stuff]) nil)))\n  ;; right-partial application + method lookup\n  (is (= 10 ((collapse-fn #'leiningen.test.change/div-dinc [3]) 24))))\n"
  },
  {
    "path": "test/leiningen/test/check.clj",
    "content": "(ns leiningen.test.check\n  (:require [clojure.test :refer :all]\n            [clojure.java.io :as io]\n            [leiningen.check :as check]\n            [leiningen.clean :as clean]\n            [leiningen.core.main :as main]\n            [leiningen.test.helper :as h])\n  (:import (java.io ByteArrayOutputStream PrintStream)))\n\n(deftest works-with-aot\n  (binding [main/*exit-process?* false]\n    (let [project (doto (h/read-test-project \"reflector\") clean/clean)\n          old-err System/err\n          out (ByteArrayOutputStream.)]\n      (System/setErr (PrintStream. out))\n      (try (binding [*err* (io/writer out)]\n             (check/check project))\n           (catch clojure.lang.ExceptionInfo e\n             (when-not (is (= 1 (:exit-code (ex-data e))))\n               (throw e)))\n           (finally (System/setErr old-err)))\n      (let [out-str (.toString out \"UTF-8\")]\n        (is (re-find #\"field getBytes can't be resolved\" out-str))\n        (is (not (re-find #\"ClassNotFoundException\" out-str)))))))\n"
  },
  {
    "path": "test/leiningen/test/clean.clj",
    "content": "(ns leiningen.test.clean\n  (:use [clojure.test]\n        [clojure.java.io :only [file make-parents writer]]\n        [leiningen.clean :only [clean]]\n        [leiningen.test.helper :only [sample-project noerr-fixture]])\n  (:require [leiningen.core.project :as project]))\n\n(def target-1 (:target-path sample-project))\n(def target-2 (str (file (:root sample-project) \"target-2\")))\n(def target-3 (str (file (:root sample-project) \"target-3\")))\n\n(def target-dirs (map file [target-1 target-2 target-3]))\n\n(def delete-calls (atom '()))\n\n(defn mock-delete-files\n  \"This implementation of delete-files-recursively will simply track the parameters passed in a state atom.\"\n  [& params]\n  (swap! delete-calls #(cons params %)))\n\n(use-fixtures :each\n  (fn [f]\n    ;; start each test with empty state.\n    (swap! delete-calls empty)\n\n    ;; The original delete-file-recursively is potentially destructive, so let's mock it.\n    (with-redefs [leiningen.clean/delete-file-recursively mock-delete-files]\n      (f)))\n  noerr-fixture)\n\n(defn assert-cleaned\n  \"Asserts that the mock was called for the given target path.\"\n  [path]\n  (is (some (comp #(.startsWith path %) first) @delete-calls)\n      (format \"delete-files-recursively was not called for %s\" path)))\n\n(defn relative-to-absolute-project-path\n  \"Converts a relative path to an absolute path within the sample project\"\n  [path]\n  (str (file (:root sample-project) path)))\n\n(deftest test-default-clean-target\n  (clean sample-project)\n  (is (= target-1 (ffirst @delete-calls))))\n\n(deftest test-explicit-clean-targets-with-keywords\n  (let [modified-project\n        (assoc sample-project\n          :target-path-2 target-2\n          :clean-targets [:target-path :target-path-2])]\n    (clean modified-project)\n    (assert-cleaned target-1)\n    (assert-cleaned target-2)))\n\n(deftest test-explicit-clean-targets-with-vector-of-keywords\n  (testing \"clean targets that are deeply nested in the project map\"\n   (let [modified-project\n         (assoc sample-project\n           :nest-1 {:nest-2 {:target-path-3 target-3}}\n           :clean-targets [[:nest-1 :nest-2 :target-path-3]])]\n     (clean modified-project)\n     (assert-cleaned target-3))))\n\n(deftest test-explicit-clean-targets-with-valid-string-paths\n  (let [modified-project\n        (assoc sample-project\n          :clean-targets [target-2 target-3])]\n    (clean modified-project)\n    (assert-cleaned target-2)\n    (assert-cleaned target-3)))\n\n(deftest test-explicit-clean-targets-with-invalid-string-paths\n  ;; These are non-existent paths outside the project root -\n  ;; used in case someone tries to execute them with out the\n  ;; fixture. Deleting \"/\" might be bad for your mental health.\n  (testing \"should not delete ancestor paths of the project root\"\n    (doseq [test-dir [\"../../xyz\" \"/xyz\"]]\n      (let [modified-project\n            (assoc sample-project\n              :clean-targets [test-dir])]\n        (is (thrown-with-msg? clojure.lang.ExceptionInfo #\"project root\"\n                              (clean modified-project))))))\n\n  (testing \"should not delete protected project paths\"\n    (doseq [path-key [:test-paths :resource-paths :source-paths :java-source-paths]]\n      (let [test-path (relative-to-absolute-project-path \"test-path\")\n            modified-project\n            (assoc sample-project\n              path-key [test-path]\n              :clean-targets [test-path])]\n        (is (thrown-with-msg? clojure.lang.ExceptionInfo #\"non-target\"\n                              (clean modified-project))))))\n\n  (testing \"should not delete project.clj\"\n    (let [modified-project\n          (assoc sample-project\n            :clean-targets [(relative-to-absolute-project-path \"project.clj\")])]\n      (is (thrown-with-msg? clojure.lang.ExceptionInfo #\"non-target\"\n                            (clean modified-project)))))\n\n  (testing \"should not delete docs\"\n    (let [modified-project\n          (assoc sample-project\n            :clean-targets [(relative-to-absolute-project-path \"doc/stuff.doc\")])]\n      (is (thrown-with-msg? clojure.lang.ExceptionInfo #\"non-target\"\n                            (clean modified-project))))))\n\n(deftest test-protect-metadata-override\n  ;; This will override the sanity check by adding :protect false to\n  ;; the metadata for :clean-targets. Again, this could be destructive\n  ;; so I'm using a non-existent protected directory. The result will\n  ;; be that our mock delete-file-recursively will get called, and\n  ;; no exceptions should be thrown.\n  (testing \"override protected path sanity checking\"\n    (doseq [test-dir\n            (concat [\"../../xyz\" \"/xyz\"]\n                    (map relative-to-absolute-project-path\n                         [\"xsrc\" \"xtest\" \"xresources\"\n                          \"doc/foo\" \"project.clj\"]))]\n      (let [modified-project\n            (assoc sample-project\n              :test-paths [(relative-to-absolute-project-path \"xtest\")]\n              :resource-paths [(relative-to-absolute-project-path \"xresources\")]\n              :source-paths [(relative-to-absolute-project-path \"xsrc\")]\n              :clean-targets ^{:protect false} [test-dir])]\n        (clean modified-project)\n        (assert-cleaned test-dir)))))\n\n(deftest spliced-target-paths\n  (let [p (-> (project/make {:root \"/a/b/c\" :target-path \"foo/bar/%s\"})\n            (project/set-profiles [:dev]))]\n    (is (= \"/a/b/c/foo/bar/dev\" (:target-path p)))\n    (clean p)\n    (assert-cleaned \"/a/b/c/foo/bar/dev\")))\n\n(deftest absolute-spliced-target-path\n  (let [p (-> (project/make {:root \"/a/b/c\"\n                             :target-path \"/foo/bar/%s\"\n                             :clean-targets ^{:protect false} [:target-path]})\n            (project/set-profiles [:dev]))]\n    (is (= \"/foo/bar/dev\" (:target-path p)))\n    (clean p)\n    (assert-cleaned \"/foo/bar/dev\")))\n"
  },
  {
    "path": "test/leiningen/test/compile.clj",
    "content": "(ns leiningen.test.compile\n  (:refer-clojure :exclude [compile])\n  (:require [clojure.test :refer :all]\n            [clojure.java.io :as io]\n            [clojure.java.shell :refer [with-sh-dir]]\n            [leiningen.compile :refer :all]\n            [leiningen.test.helper :refer [sample-project\n                                           delete-file-recursively\n                                           sample-ordered-aot-project\n                                           sample-failing-project\n                                           sample-reader-cond-project\n                                           tricky-name-project\n                                           more-gen-classes-project\n                                           with-system-err-str\n                                           with-system-out-str]]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]))\n\n(use-fixtures :each (fn [f]\n                      (delete-file-recursively\n                       (io/file \"test_projects\" \"sample\" \"target\") true)\n                      (delete-file-recursively\n                       (io/file \"test_projects\" \"sample-failing\" \"target\") true)\n                      (binding [main/*info* false]\n                        (f))))\n\n(deftest ^:online test-compile\n  (with-out-str\n    (compile sample-project \"nom.nom.nom\"))\n  (is (.exists (io/file \"test_projects\" \"sample\" \"target\"\n                     \"classes\" \"nom\" \"nom\" \"nom.class\")))\n  (with-system-err-str\n    (is (thrown? Exception (binding [*err* (java.io.StringWriter.)]\n                             (compile sample-failing-project))))))\n\n(deftest ^:online test-compile-all\n  (compile sample-project \":all\")\n  (is (.exists (io/file \"test_projects\" \"sample\" \"target\"\n                        \"classes\" \"nom\" \"nom\" \"nom.class\"))))\n\n(deftest test-compile-order-sorted\n  (is (= 0\n    (compare\n      (vec (compilable-namespaces sample-ordered-aot-project))\n      (vec (sort (compilable-namespaces sample-ordered-aot-project)))))))\n\n(deftest test-compile-regex\n  (compile more-gen-classes-project \"#\\\"\\\\.ba.$\\\"\")\n  (is (.exists (io/file \"test_projects\" \"more-gen-classes\" \"target\"\n                        \"classes\" \"more_gen_classes\" \"bar.class\")))\n  (is (.exists (io/file \"test_projects\" \"more-gen-classes\" \"target\"\n                        \"classes\" \"more_gen_classes\" \"baz.class\")))\n  (is (not (.exists (io/file \"test_projects\" \"more-gen-classes\" \"target\"\n                             \"classes\" \"more_gen_classes\" \"foo.class\")))))\n\n(deftest test-compile-cljc\n  (compile sample-reader-cond-project)\n  (is (.exists (io/file \"test_projects\" \"sample-reader-cond\" \"target\"\n                        \"classes\" \"nom\" \"nom\" \"clj__init.class\")))\n  (is (.exists (io/file \"test_projects\" \"sample-reader-cond\" \"target\"\n                        \"classes\" \"nom\" \"nom\" \"cljc__init.class\"))))\n\n(def eip-check (atom false))\n\n(deftest ^:online test-plugin\n  (reset! eip-check false)\n  (eval/eval-in-project (assoc sample-project\n                          :eval-in :leiningen\n                          :skip-shutdown-agents true\n                          :main nil)\n                        `(reset! eip-check true))\n  (is @eip-check))\n\n(deftest ^:online test-cleared-transitive-aot\n  (compile (assoc sample-project :clean-non-project-classes true) \"nom.nom.nom\")\n  (eval/eval-in-project sample-project '(require 'nom.nom.nom))\n  (let [classes (seq (.list (io/file \"test_projects\" \"sample\" \"target\"\n                                     \"classes\" \"nom\" \"nom\")))]\n    (doseq [r [#\"nom\\$fn__\\d+.class\" #\"nom\\$loading__\\d+__auto__.class\"\n               #\"nom\\$_main.class\" #\"nom.class\" #\"nom__init.class\"]]\n      (is (some (partial re-find r) classes) (format \"missing %s\" r))))\n  (is (not (.exists (io/file \"test_projects\" \"sample\" \"target\"\n                             \"classes\" \"sample2\" \"core.class\"))))\n  (is (not (.exists (io/file \"test_projects\" \"sample\" \"target\"\n                             \"classes\" \"sample2\" \"alt.class\")))))\n\n(deftest ^:online test-cleared-transitive-aot-by-regexes\n  (compile (assoc sample-project :clean-non-project-classes [#\"core\"])\n           \"nom.nom.check\")\n  (let [classes (seq (.list (io/file \"test_projects\" \"sample\" \"target\"\n                                     \"classes\" \"nom\" \"nom\")))]\n    (doseq [r [#\"check\\$loading__\\d+__auto__.class\"\n               #\"check\\$_main.class\" #\"check.class\" #\"check__init.class\"]]\n      (is (some (partial re-find r) classes) (format \"missing %s\" r))))\n  (is (not (.exists (io/file \"test_projects\" \"sample\" \"target\"\n                             \"classes\" \"sample2\" \"core.class\"))))\n  (is (.exists (io/file \"test_projects\" \"sample\" \"target\" \"classes\"\n                        \"sample2\" \"alt__init.class\"))))\n\n(deftest ^:online test-injection\n  (eval/eval-in-project (assoc sample-project\n                          :injections ['(do (ns inject.stuff)\n                                            (def beef :hot))])\n                        '#'inject.stuff/beef))\n\n;; (deftest test-compile-java-main\n;;   (compile dev-deps-project))\n\n(deftest bad-aot-test\n  (is (re-find #\"does\\.not\\.exist|does\\/not\\/exist\"\n               (with-system-err-str\n                 (try\n                   (binding [*err* (java.io.StringWriter.)]\n                     (compile (assoc sample-project :aot '[does.not.exist])))\n                   (catch clojure.lang.ExceptionInfo _))))))\n\n(deftest compilation-specs-tests\n  (is (= '[foo bar] (compilation-specs [\"foo\" \"bar\"])))\n  (is (= [:all] (compilation-specs [\":all\"]) (compilation-specs [:all])))\n  (is (every? #'leiningen.compile/regex?\n              (compilation-specs [\"#\\\"foo\\\"\" #\"bar\" \"#\\\"baz\\\"\"])))\n  (testing \"that regexes are compiled first\"\n    (let [spec (compilation-specs '[foo #\"baz\" bar #\"quux\"])]\n      (is (every? symbol? (drop-while #'leiningen.compile/regex? spec))))))\n"
  },
  {
    "path": "test/leiningen/test/deploy.clj",
    "content": "(ns leiningen.test.deploy\n  (:require [clojure.java.io :as io]\n            [clojure.test :refer :all]\n            [leiningen.deploy :refer :all]\n            [leiningen.core.main :as main]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.utils :as utils]\n            [leiningen.test.helper :as help]))\n\n(use-fixtures :once (fn [f] (binding [main/*info* false] (f))))\n\n(defn- repo-path\n  [relative-repo-path]\n  (clojure.string/replace\n    (format \"%s/%s\" help/tmp-dir relative-repo-path)\n    \"\\\\\" \"/\")) ;make path delimiters look the same / even under Windows\n\n(defn- repo-url\n  [absolute-repo-path]\n  (str \"file://\" absolute-repo-path))\n\n(defn- deploy-snapshots\n  [project relative-repo-path & [explicit-deploy-repo?]]\n  (let [repo-path (repo-path relative-repo-path)\n        repo-url (repo-url repo-path)]\n    (help/delete-file-recursively repo-path :silently)\n    (with-out-str\n      (deploy project (if explicit-deploy-repo?\n                        repo-url\n                        \"snapshots\")))\n    (let [dir (io/file repo-path \"nomnomnom/nomnomnom/0.5.0-SNAPSHOT/\")\n          files (.list dir)]\n      (is (seq files))\n      ;; TODO: this is vulnerable to the y3k bug!\n      (is (seq (filter #(re-find #\"nomnomnom-0.5.0-2\\d{7}\\.\" %) files))))))\n\n(deftest ^:online test-deploy\n  (testing \"simple deployment to `snapshots` already defined in project.clj\"\n    (deploy-snapshots help/sample-project \"lein-repo\")))\n\n(deftest ^:online test-deploy-password\n  (with-redefs [read-password-fn (constantly (constantly\n                                              (char-array \"stupidhorse\")))\n                read-line (constantly \"leiningen-test-fail-expected-sorry\")]\n    (reset! utils/rebound-io? false)\n    (binding [main/*exit-process?* false\n              *err* (java.io.StringWriter.)]\n      (testing \"provides password in a way pomegranate accepts\"\n        (let [result (try\n                       (with-out-str\n                         (help/with-system-err-str\n                           (deploy help/sample-project \"clojars\")))\n                       (catch Exception e\n                         (.getMessage e)))]\n          (is (re-find #\"401 Unauthorized\" result)))))))\n\n(deftest ^:online test-deploy-custom-url\n  (testing \"deployment to a repo specified as a URL argument to `deploy`\"\n    (deploy-snapshots help/sample-project \"lein-custom-repo\" true)))\n\n(deftest ^:online test-deploy-repositories-key\n  (testing \"preferring repository in :deploy-repositories over :repositories\"\n    (deploy-snapshots (assoc help/sample-project\n                        :deploy-repositories\n                        {\"snapshots\" {:url (-> \"deploy-only-repo\"\n                                               repo-path repo-url)}})\n                      \"deploy-only-repo\")))\n\n(deftest ^:online test-deploy-classifier\n  (testing \"deployment with explicit file names uploads classifiers to repo\"\n    (let [deploy-dir (repo-path \"deploy-classifier\")\n          project    (assoc help/sample-deploy-project\n                            :deploy-repositories\n                            {\"snapshots\" {:url (repo-url deploy-dir)}})]\n      (help/delete-file-recursively deploy-dir :silently)\n      (with-out-str\n        (deploy project \"snapshots\"\n                \"deploy-me/deploy-me\"\n                (:version project)\n                (str (:root project) \"/deploy-me-0.1.0-SNAPSHOT-fat.jarr\")))\n      (let [dir (io/file deploy-dir \"deploy-me/deploy-me/0.1.0-SNAPSHOT/\")\n            files (.list dir)]\n        (is (seq (filter #(re-find #\"deploy-me-0.1.0-[\\d.]+-\\d+-fat.jarr$\" %) files)))))))\n\n(deftest signing\n  (testing \"GPG invocation\"\n    (is (= (signing-args \"foo.jar\" nil)\n           [\"--yes\" \"-ab\" \"--\" \"foo.jar\"]))\n    (is (= (signing-args \"foo.jar\" {:gpg-key \"123456\"})\n           [\"--yes\" \"-ab\" \"--default-key\" \"123456\" \"--\" \"foo.jar\"])))\n  (testing \"Key selection\"\n    (is (= (:gpg-key (signing-opts {:signing {:gpg-key \"key-project\"}}\n                                   [\"repo\" {:signing {:gpg-key \"key-repo\"}}]))\n           \"key-repo\"))\n    (is (= (:gpg-key (signing-opts {:signing {:gpg-key \"key-project\"}}\n                                   [\"repo\" {}]))\n           \"key-project\")))\n  (testing \"Whether to sign\"\n    (is (= (sign-for-repo? [\"foo\" {:sign-releases true}]) true))\n    (is (= (sign-for-repo? [\"foo\" {:sign-releases false}]) false))\n    (is (= (sign-for-repo? [\"foo\" {}]) true))))\n\n(deftest ssh-signing\n  (let [file (str (:root help/sample-project) \"/project.clj\")\n        artifacts {[:extension \"clj\"] file}]\n    (io/delete-file (str file \".sig\") :silently)\n    ;; git won't store file permissions so we need to set this manually\n    (binding [*out* (java.io.PrintWriter. (java.io.StringWriter.))]\n      (eval/sh \"chmod\" \"600\" \"test_projects/.ssh/id_rsa\"))\n    (binding [main/*exit-process?* false\n              eval/*sh-silent?* true]\n      (is (= [{[:extension \"clj.sig\"] (str file \".sig\")}]\n             (binding [*out* (java.io.PrintWriter. (java.io.StringWriter.))]\n               (signatures-for-artifacts artifacts\n                                         {:ssh-key \"test_projects/.ssh/id_rsa\"\n                                          :gpg-key false}))))\n      (is (= 0 (binding [*out* (java.io.PrintWriter. (java.io.StringWriter.))]\n                 (eval/sh \"test_projects/.ssh/verify\")))))))\n\n(deftest validate-input\n  (testing \"Fail if project data is missing\"\n    (is (thrown? clojure.lang.ExceptionInfo (binding [*err* (java.io.StringWriter.)]\n                                              (deploy nil)))))\n  (testing \"Fail if project data is missing\"\n    (is (thrown? clojure.lang.ExceptionInfo (binding [*err* (java.io.StringWriter.)]\n                                              (deploy nil \"snapshots\"))))))\n\n(deftest classifiying\n  (are [expected version file] (= expected (classifier version file))\n      \"fat\" \"1.2.3\"          \"some-project-1.2.3-fat.jar\"\n      \"fat\" \"1.2.3-alpha6\"   \"some-project-1.2.3-alpha6-fat.jar\"\n      \"fat\" \"1.2.3-SNAPSHOT\" \"some-project-1.2.3-SNAPSHOT-fat.jar\"\n      nil   \"1.2.3\"          \"some-project-1.2.3-.jar\"\n      nil   \"1.2.3\"          \"some-project-1.2.3.jar\"\n      nil   \"0.1.0\"          \"/opt/workspace/mylib-0.1.0-builddir/target/mylib-0.1.0.jar\"\n      \"RC2\" \"0.1.0\"          \"\\\\opt\\\\workspace\\\\mylib-0.1.0-builddir\\\\target\\\\mylib-0.1.0-RC2.jar\"))\n"
  },
  {
    "path": "test/leiningen/test/deps.clj",
    "content": "(ns leiningen.test.deps\n  (:require [clojure.test :refer :all]\n            [leiningen.deps :refer :all]\n            [leiningen.test.helper :refer [sample-project m2-dir\n                                           m2-file\n                                           native-project\n                                           managed-deps-project\n                                           with-system-out-str\n                                           with-system-err-str\n                                           delete-file-recursively]]\n            [clojure.java.io :as io]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.user :as user]\n            [leiningen.core.eval :as eval]\n            [leiningen.core.main :as main]\n            [leiningen.core.classpath :as classpath]\n            [cemerick.pomegranate.aether :as aether]\n            [leiningen.core.project :as project]))\n\n(defn- set-gpg-home [f]\n  (binding [user/*gpg-home* \"test/.gnupg\"\n            main/*info* false]\n    (f)))\n\n(use-fixtures :once set-gpg-home)\n\n(deftest ^:online test-deps\n  (let [sample-deps [[\"rome\" \"0.9\"] [\"jdom\" \"1.0\"]]]\n    (doseq [[n v] sample-deps]\n      (delete-file-recursively (m2-dir n v) :silently))\n    ;; For some reason running deps on a project that includes ring\n    ;; fails, but only when done right here. https://p.hagelb.org/mystery.gif\n    (deps (update-in sample-project [:dependencies] rest))\n    (doseq [[n v] sample-deps]\n      (is (.exists (m2-dir n v)) (str n \" was not downloaded.\")))))\n\n(deftest ^:online test-dependency-hierarchy\n  (let [sample-deps [[\"ring\" \"1.0.0\"] [\"rome\" \"0.9\"] [\"jdom\" \"1.0\"]]]\n    (doseq [[n v] sample-deps]\n      (delete-file-recursively (m2-dir n v) :silently))\n    (let [out (with-out-str (deps sample-project \":tree\"))]\n      (doseq [dep '[[org.clojure/clojure \"1.3.0\"]\n                    [ring \"1.0.0\"]\n                    [ring/ring-core \"1.0.0\"]\n                    [commons-codec \"1.4\"]\n                    [commons-fileupload \"1.2.1\"]\n                    [commons-io \"1.4\"]\n                    [javax.servlet/servlet-api \"2.5\"]\n                    [ring/ring-devel \"1.0.0\"]\n                    [clj-stacktrace \"0.2.2\"]\n                    [hiccup \"0.3.7\"]\n                    [ns-tracker \"0.1.1\"]\n                    [org.clojure/tools.namespace \"0.1.0\"]\n                    [org.clojure/java.classpath \"0.1.0\"]\n                    [ring/ring-jetty-adapter \"1.0.0\"]\n                    [org.mortbay.jetty/jetty-util \"6.1.25\"]\n                    [org.mortbay.jetty/jetty \"6.1.25\"]\n                    [org.mortbay.jetty/servlet-api \"2.5-20081211\"]\n                    [ring/ring-servlet \"1.0.0\"]\n                    [rome \"0.9\"]\n                    [jdom \"1.0\"]]]\n        (is (.contains out (pr-str dep)))))))\n\n(deftest ^:online test-plugin-dependency-hierarchy\n  (let [sample-plugin-deps [[\"codox\" \"0.6.4\"]]]\n    (doseq [[n v] sample-plugin-deps]\n      (delete-file-recursively (m2-dir n v) :silently))\n    (let [out (with-out-str (deps sample-project \":plugin-tree\"))]\n      (doseq [plugin-dep '[[codox \"0.6.4\"]\n                           [codox/codox.leiningen \"0.6.4\"]\n                           [leinjacker \"0.4.1\"]\n                           [org.clojure/core.contracts \"0.0.1\"]\n                           [org.clojure/clojure \"1.4.0\"]\n                           [org.clojure/core.unify \"0.5.3\"]]]\n        (is (.contains out (pr-str plugin-dep)))))))\n\n(deftest ^:online test-plugin-dependency-hierarchy-as-edn\n  (let [sample-plugin-deps [[\"codox\" \"0.6.4\"]]]\n    (doseq [[n v] sample-plugin-deps]\n      (delete-file-recursively (m2-dir n v) :silently))\n    (let [out (with-out-str (deps sample-project \":plugin-tree-data\"))]\n      (is (= '{[codox \"0.6.4\"]\n               {[codox/codox.leiningen \"0.6.4\"]\n                {[leinjacker \"0.4.1\"]\n                 {[org.clojure/core.contracts \"0.0.1\"]\n                  {[org.clojure/clojure \"1.4.0\"] nil\n                   [org.clojure/core.unify \"0.5.3\"] nil}}}}}\n             (read-string out))))))\n\n(deftest ^:online test-snapshots-releases\n  (let [pr (assoc sample-project\n                  :repositories ^:replace {\"clojars\" {:url \"https://repo.clojars.org/\"\n                                            :snapshots false}})\n        ps (assoc sample-project\n                  :repositories ^:replace {\"clojars\" {:url \"https://repo.clojars.org/\"\n                                            :releases false}})\n        slamhound ['slamhound \"1.1.0-SNAPSHOT\"]\n        hooke ['robert/hooke \"1.0.1\"]\n        deps (fn [project]\n               (delete-file-recursively (apply m2-dir slamhound) :quiet)\n               (delete-file-recursively (apply m2-dir hooke) :quiet)\n               (leiningen.deps/deps project))]\n    (deps (assoc pr :dependencies [hooke]))\n    (is (.exists (m2-dir :robert/hooke \"1.0.1\")))\n    (deps (assoc ps :dependencies [slamhound]))\n    (is (.exists (m2-dir \"slamhound\" \"1.1.0-SNAPSHOT\")))\n    (let [snaps-repo-rel-dep (assoc ps :dependencies [hooke])]\n      (is (thrown? Exception (deps snaps-repo-rel-dep)))\n      (is (not (.exists (m2-dir :robert/hooke \"1.0.1\")))))\n    (let [rel-repo-snaps-dep (assoc pr :dependencies [slamhound])]\n      (is (thrown? Exception (deps rel-repo-snaps-dep)))\n      (is (not (.exists (m2-dir \"slamhound\" \"1.1.0-SNAPSHOT\"))))) ))\n\n(def native-lib-files-map\n  {:linux {:x86 #{\"libjri.so\" \"libjinput-linux.so\" \"liblwjgl.so\" \"libopenal.so\"\n                  \"librxtxSerial.so\" \"libjtokyocabinet.so\"\n                  \"libjtokyocabinet.so.1\" \"libjtokyocabinet.so.1.1.0\"\n                  \"libtokyocabinet.a\" \"libtokyocabinet.so\"\n                  \"libtokyocabinet.so.9\" \"libtokyocabinet.so.9.10.0\"\n                  \"libtokyocabinet.so.9.8.0\"}\n           :x86_64 #{\"libjri.so\" \"libjinput-linux64.so\" \"liblwjgl64.so\"\n                     \"libopenal64.so\" \"librxtxSerial.so\" \"libjtokyocabinet.so\"\n                     \"libjtokyocabinet.so.1\" \"libjtokyocabinet.so.1.1.0\"\n                     \"libtokyocabinet.a\" \"libtokyocabinet.so\"\n                     \"libtokyocabinet.so.9\" \"libtokyocabinet.so.9.10.0\"\n                     \"libtokyocabinet.so.9.8.0\"}}\n   :macosx {:x86 #{\"libjri.jnilib\" \"libjinput-osx.jnilib\" \"liblwjgl.jnilib\"\n                   \"openal.dylib\" \"librxtxSerial.jnilib\"\n                   \"libjtokyocabinet.1.1.0.dylib\" \"libjtokyocabinet.1.dylib\"\n                   \"libjtokyocabinet.dylib\" \"libjtokyocabinet.jnilib\"\n                   \"libtokyocabinet.9.10.0.dylib\"\n                   \"libtokyocabinet.9.8.0.dylib\" \"libtokyocabinet.9.dylib\"\n                   \"libtokyocabinet.a\" \"libtokyocabinet.dylib\"}\n            :x86_64 #{\"libjri.jnilib\" \"libjinput-osx.jnilib\"\n                      \"liblwjgl.jnilib\"\n                      \"openal.dylib\" \"librxtxSerial.jnilib\"\n                      \"libjtokyocabinet.1.1.0.dylib\"\n                      \"libjtokyocabinet.1.dylib\"\n                      \"libjtokyocabinet.dylib\" \"libjtokyocabinet.jnilib\"\n                      \"libtokyocabinet.9.10.0.dylib\"\n                      \"libtokyocabinet.9.8.0.dylib\" \"libtokyocabinet.9.dylib\"\n                      \"libtokyocabinet.a\" \"libtokyocabinet.dylib\"}}\n   :windows {:x86 #{\"jri.dll\" \"rJava.dll\" \"jinput-dx8.dll\" \"jinput-raw.dll\"\n                    \"lwjgl.dll\" \"OpenAL32.dll\" \"rxtxSerial.dll\"}\n             :x86_64 #{\"jri.dll\" \"rJava.dll\" \"jinput-dx8_64.dll\"\n                       \"jinput-raw_64.dll\" \"lwjgl64.dll\" \"OpenAL64.dll\"\n                       \"rxtxSerial.dll\"}}\n   :solaris {:x86 #{\"liblwjgl.so\" \"libopenal.so\"}\n             :x86_64 #{\"liblwjgl64.so\" \"libopenal.so\"}}})\n\n(deftest test-native-deps\n  (delete-file-recursively (:target-path native-project) true)\n  (deps native-project)\n  (is (= (conj (get-in native-lib-files-map [(utils/get-os) (utils/get-arch)])\n               \".gitkeep\")\n         (set (for [f (rest (file-seq (io/file (first (eval/native-arch-paths\n                                                       native-project)))))]\n                (.getName f))))))\n\n(defn coordinates-match?\n  [dep1 dep2]\n  ;; NOTE: there is a new function in the 0.3.1 release of pomegranate that\n  ;;  is useful here, but it is private.  Calling it via the symbol dereference\n  ;;  for now, but might consider making it public upstream.  Haven't done so\n  ;;  yet since it is only used for tests.\n  (#'aether/coordinates-match? dep1 dep2))\n\n(deftest ^:online test-managed-deps\n  (let [is-clojure-dep? #(#{'org.clojure/clojure\n                            'nrepl/nrepl}\n                          (first %))\n        remove-clojure-deps #(remove is-clojure-dep? %)\n        managed-deps (remove-clojure-deps (:managed-dependencies managed-deps-project))\n        ;; find deps from normal \"deps\" section which explicitly specify their\n        ;; version number rather than inheriting it from managed-deps\n        versioned-unmanaged-deps (filter\n                                  (fn [dep]\n                                    (and (> (count dep) 1)\n                                         (string? (nth dep 1))\n                                         (not (is-clojure-dep? dep))))\n                                  (:dependencies managed-deps-project))\n        ;; the list of final, used deps w/versions\n        merged-deps (remove-clojure-deps\n                     (classpath/merge-versions-from-managed-coords\n                      (:dependencies managed-deps-project)\n                      (:managed-dependencies managed-deps-project)))\n        ;; the list of deps from the managed deps section that aren't used\n        unused-managed-deps (-> (remove\n                                 (fn [dep]\n                                   (or (some (partial coordinates-match? dep) merged-deps)\n                                       ;; special-casing to remove tools.reader, which is a common transitive dep\n                                       ;; of two of our normal dependencies\n                                       (= 'org.clojure/tools.reader (first dep))))\n                                 managed-deps))\n        ;; deps that have classifiers\n        classified-deps (filter\n                         #(some #{:classifier} %)\n                         merged-deps)]\n    ;; make sure the sample data has some unmanaged deps, some unused managed deps,\n    ;; and some classified deps, for completeness\n    (is (seq versioned-unmanaged-deps))\n    (is (seq unused-managed-deps))\n    (is (seq classified-deps))\n    ;; delete all of the existing artifacts for merged deps\n    (doseq [[n v] merged-deps]\n        (delete-file-recursively (m2-dir n v) :silently))\n    ;; delete all of the artifacts for the managed deps too\n    (doseq [[n v] managed-deps]\n      (delete-file-recursively (m2-dir n v) :silently))\n    ;; delete all copies of tools.reader so we know that the managed dependency\n    ;; for it is taking precedence\n    (delete-file-recursively (m2-dir 'org.clojure/tools.reader) :silently)\n    (deps managed-deps-project)\n    ;; artifacts should be available for all merged deps\n    (doseq [[n v] merged-deps]\n      (is (.exists (m2-dir n v)) (str n \" was not downloaded (missing dir '\" (m2-dir n v) \"').\")))\n    ;; artifacts should *not* have been downloaded for unused managed deps\n    (doseq [[n v] unused-managed-deps]\n      (is (not (.exists (m2-dir n v))) (str n \" was unexpectedly downloaded (found unexpected dir '\" (m2-dir n v) \"').\")))\n    ;; artifacts with classifiers should be available\n    (doseq [[n v _ classifier] classified-deps]\n      (let [f (m2-file n v classifier)]\n        (is (.exists f) (str f \" was not downloaded.\"))))\n    ;; check tools.reader explicitly, since it is our special transitive dependency\n    (let [tools-reader-versions (into [] (.listFiles (m2-dir 'org.clojure/tools.reader)))]\n      (is (= 1 (count tools-reader-versions)))\n      (is (= (first tools-reader-versions) (m2-dir 'org.clojure/tools.reader\n                                                   (->> managed-deps\n                                                        (filter\n                                                         (fn [dep] (= 'org.clojure/tools.reader (first dep))))\n                                                        first\n                                                        second)))))))\n\n(deftest test-managed-deps-with-profiles\n  (testing \"Able to resolve deps when profile omits versions in deps\"\n    (deps (project/set-profiles managed-deps-project [:add-deps])))\n  (testing \"Able to resolve deps when profile with ^:replace omits versions in deps\"\n    (deps (project/set-profiles managed-deps-project [:replace-deps]))))\n\n(deftest ^:online test-verify\n  (let [project (-> sample-project\n                    (update :repositories (fn [repos]\n                                            (remove #(= \"other\" (first %)) repos)))\n                    (assoc :dependencies '[[org.clojure/clojure \"1.10.3\"]\n                                           [rome \"0.9\"]\n                                           [ring \"1.0.0\"]])\n                    (assoc :key-server \"hkps://keyserver.ubuntu.com\")\n                    (assoc :checksum :ignore))\n        _ (deps project)\n        out (with-out-str\n              (with-system-err-str\n                (deps project \":verify\")))]\n    (doseq [[dep signed] '{[org.clojure/clojure \"1.10.3\"] :signed\n                           [rome \"0.9\"] :unsigned\n                           [jdom \"1.0\"] :unsigned}]\n      (is (.contains out (pr-str signed dep))\n          (str \"missing \" dep)))))\n"
  },
  {
    "path": "test/leiningen/test/do.clj",
    "content": "(ns leiningen.test.do\n  (:refer-clojure :exclude [do])\n  (:use [clojure.test]\n        [leiningen.do]))\n\n(deftest test-group-args-empty-args\n  (is (= [] (group-args []))))\n\n(deftest test-group-args-single-task\n  (is (= [[\"pom\"]] (group-args [\"pom\"]))))\n\n(deftest test-group-args-without-args\n  (is (= [[\"clean\"] [\"deps\"] [\"test\"]]\n         (group-args [\"clean,\" \"deps,\" \"test\"]))))\n\n(deftest test-group-args-with-args\n  (is (= [[\"test\" \"test-core\"] [\"version\"]]\n         (group-args [\"test\" \"test-core,\" \"version\"]))))\n\n(deftest test-group-args-with-long-chain\n  (is (= [[\"help\" \"help\"] [\"help\" \"version\"] [\"version\"]\n          [\"test\" \"test-compile\"]]\n         (group-args '(\"help\" \"help,\" \"help\" \"version,\" \"version,\"\n                       \"test\" \"test-compile\")))))\n\n(deftest test-group-existing-collections\n  (is (= [[\"clean\"] [\"test\" \":integration\"] '(\"deploy\" \"clojars\")]\n         (group-args [\"clean\" [\"test\" \":integration\"]\n                      '(\"deploy\" \"clojars\")])))\n  (is (= [[\"foo\" \"bar\"] [\"baz\" \"quux\"]]\n         (group-args [[\"foo\" \"bar\"] [\"baz\" \"quux\"]])))\n  (is (= [[\"foo\" \"bar\"] [\"baz\"]]\n         (group-args [[\"foo\" \"bar\"] \"baz\"])))\n  (is (= [[\"combinations\"] [\"work\"] [\"as\" \"well\"]]\n         (group-args [\"combinations,\" \"work\" [\"as\" \"well\"]]))))\n"
  },
  {
    "path": "test/leiningen/test/help.clj",
    "content": "(ns leiningen.test.help\n  (:use [leiningen.help]\n        [clojure.test])\n  (:require [leiningen.test.helper :as helper]))\n\n(def formatted-docstring @#'leiningen.help/formatted-docstring)\n(def get-subtasks-and-docstrings-for\n  @#'leiningen.help/get-subtasks-and-docstrings-for)\n(def formatted-help @#'leiningen.help/formatted-help)\n(def resolve-task @#'leiningen.help/resolve-task)\n\n(deftest blank-subtask-help-for-pom\n  (let [subtask-pom (apply subtask-help-for (resolve-task \"pom\"))]\n    (is (= nil subtask-pom))))\n\n(deftest subtask-help-for-new\n  (let [subtask-help (apply subtask-help-for (resolve-task \"new\"))]\n    (is (re-find #\"Subtasks available\" subtask-help))\n    (is (re-find #\"default\\s+A general project template.\" subtask-help))\n    (is (re-find #\"plugin\\s+A leiningen plugin project template.\" subtask-help))\n    (is (re-find #\"template\\s+A meta-template for 'lein new' templates.\"\n                 subtask-help))))\n\n(deftest subtask-help-for-new-default\n  (let [subtask-help (help-for-subtask \"new\" \"default\")]\n    (is (re-find #\"^A general project template.\" subtask-help))\n    (is (re-find #\"Arguments: \\(\\[name\\]\\)\" subtask-help))))\n\n(deftest test-docstring-formatting\n  (is (= \"This is an\n              AWESOME command\n            For real!\"\n      (formatted-docstring\n        \"install\"\n        \"This is an\\n  AWESOME command\\nFor real!\" 5))))\n\n(deftest test-formatted-help\n  (is (= \"install           This is an\n                  AWESOME command\n                  For real!\"\n      (formatted-help \"install\" \"This is an\\nAWESOME command\\nFor real!\" 15))))\n\n(deftest ^:disabled test-get-subtasks\n  (let [m (get-subtasks-and-docstrings-for (second (resolve-task \"plugin\")))]\n    (is (= [\"install\" \"uninstall\"]\n           (sort (keys m))))))\n\n(deftest test-alias-docstrings\n  (testing \"default alias docstrings\"\n    (is (re-find #\"is an alias for\" (help-for {} \"--version\")))\n    (is (re-find #\"is an alias\" (help-for {} \"-o\")))\n    (is (re-find #\"not found\"\n                 (helper/abort-msg help-for {} \"not-a-task\"))))\n  (testing \"own alias docstrings\"\n    (let [custom-aliases {:aliases {\"foobar\" ^{:doc \"Foos the bar.\"}\n                                              [\"foo\" \"bar\"],\n                                    \"vsn\" \"version\"\n                                    \"multipart\" [\"multi\" \"part\"]}}]\n      (is (re-find #\"is an alias for\" (help-for custom-aliases \"vsn\")))\n      (is (re-find #\"is an alias\" (help-for custom-aliases \"multipart\")))\n      (is (re-find #\"Foos the bar\\.\" (help-for custom-aliases \"foobar\")))\n      (is (re-find #\"not found\"\n                   (helper/abort-msg help-for custom-aliases \"not-a-task\"))))))\n"
  },
  {
    "path": "test/leiningen/test/helper.clj",
    "content": "(ns leiningen.test.helper\n  (:require [leiningen.core.project :as project]\n            [leiningen.core.user :as user]\n            [leiningen.core.utils :as utils]\n            [leiningen.core.main :as main]\n            [leiningen.core.test.helper :as helper]\n            [clojure.java.io :as io]\n            [clojure.string :as str]))\n\n;; TODO: fix\n(def local-repo (io/file (System/getProperty \"user.home\") \".m2\" \"repository\"))\n\n(def tmp-dir (System/getProperty \"java.io.tmpdir\"))\n\n(defn m2-dir\n  ([n]\n   (let [group (-> (if (string? n) n (or (namespace n) (name n)))\n                   (str/replace \".\" \"/\"))]\n     (io/file local-repo group (name n))))\n  ([n v]\n   (io/file (m2-dir n) v)))\n\n(defn m2-file [n v classifier]\n  (io/file (m2-dir n v) (str (name n) \"-\" v \"-\" classifier \".jar\")))\n\n(defn read-test-project-with-user-profiles [name user-profiles]\n  (with-redefs [user/profiles (constantly user-profiles)]\n    (let [project (project/read (format \"test_projects/%s/project.clj\" name))]\n      (project/init-project\n       (project/project-with-profiles-meta\n        project (merge @project/default-profiles (:profiles project)))))))\n\n(defn read-test-project [name]\n  (read-test-project-with-user-profiles name {}))\n\n(def with-resources-project (read-test-project \"with-resources\"))\n\n(def with-aliases-project (read-test-project \"with-aliases\"))\n\n(def with-aliases2-project (binding [main/*info* false]\n                             (read-test-project \"with-aliases2\")))\n\n(def sample-project (read-test-project \"sample\"))\n\n(def sample-failing-project (read-test-project \"sample-failing\"))\n\n(def sample-no-aot-project (read-test-project \"sample-no-aot\"))\n\n(def sample-ordered-aot-project (read-test-project \"sample-ordered-aot\"))\n\n(def sample-profile-meta-project (read-test-project \"sample-profile-meta\"))\n\n(def sample-reader-cond-project (read-test-project \"sample-reader-cond\"))\n\n(def sample-fixture-error-project (read-test-project \"sample-fixture-error\"))\n\n(def sample-deploy-project (read-test-project \"sample-deploy\"))\n\n(def tricky-name-project (read-test-project \"tricky-name\"))\n\n(def native-project (read-test-project \"native\"))\n\n(def provided-project (read-test-project \"provided\"))\n\n(def uberjar-merging-project (read-test-project \"uberjar-merging\"))\n\n(def data-readers-backwards-compatibility-project (read-test-project \"data-readers-backwards-compatibility\"))\n\n(def overlapped-sourcepaths-project (read-test-project \"overlapped-sourcepaths\"))\n\n(def more-gen-classes-project (read-test-project \"more-gen-classes\"))\n\n(def bad-require-project (read-test-project \"bad-require\"))\n\n(def java-main-project (read-test-project \"java-main\"))\n\n(def file-not-found-thrower-project (read-test-project \"file-not-found-thrower\"))\n\n(def jvm-opts-project (read-test-project \"jvm-opts\"))\n\n(def with-classifiers-project (read-test-project \"with-classifiers\"))\n\n(def managed-deps-project (read-test-project \"managed-deps\"))\n\n(def managed-deps-snapshot-project (read-test-project \"managed-deps-snapshot\"))\n\n(def with-pom-plugins-project (read-test-project \"with-pom-plugins\"))\n\n(def lein-test-reload-bug-project (read-test-project \"lein-test-reload-bug\"))\n\n(def lein-test-exit-code-project (read-test-project \"lein-test-exit-code\"))\n\n(def leaky-composite-project (read-test-project \"leaky-composite\"))\n\n(def preserve-eval-meta-project (read-test-project \"preserve-eval-meta\"))\n\n(defn abort-msg\n  \"Catches main/abort thrown by calling f on its args and returns its error\n  message.\"\n  [f & args]\n  (apply helper/abort-msg f args))\n\n;; grumble, grumble; why didn't this make it into clojure.java.io?\n(defn delete-file-recursively\n  \"Delete file f. If it's a directory, recursively delete all its contents.\n  Raise an exception if any deletion fails unless silently is true.\"\n  [f & [silently]]\n  (System/gc) ; This sometimes helps release files for deletion on windows.\n  (let [f (io/file f)]\n    (if (.isDirectory f)\n      (doseq [child (.listFiles f)]\n        (delete-file-recursively child silently)))\n    (io/delete-file f silently)))\n\n\n(defn fix-path-delimiters [input-str]\n  (clojure.string/replace input-str \"/\" java.io.File/separator))\n\n;; So paths would work under Windows too, which adds a drive letter and changes\n;; the path separator.\n(defn pathify\n  \"Converts paths to absolute paths. Will throw if not, because if the path is\n  not absolute, then .getAbsolutePath will resolve them relative to current\n  directory.\" [in-str-or-file]\n  (cond (or\n          (nil? in-str-or-file)\n          (not (or\n                 (.startsWith in-str-or-file \"/\")\n                 (and\n                   (>= (.length in-str-or-file) 3)\n                   (= \":\\\\\" (.substring in-str-or-file 1 3))))))\n    (throw (RuntimeException. (str \"Bad usage, passed: `\" in-str-or-file \"`.\")))\n    :else\n    (.getAbsolutePath (io/as-file in-str-or-file))))\n\n(defn entries\n  \"Returns a lazy seq of all the entries in a zipfile.\"\n  [zipfile]\n  (enumeration-seq (.entries zipfile)))\n\n(defn walkzip\n  \"Applies f to all ZipEntries in the ZipFile filename and returns the result as\n  a vector.\"\n  [filename f]\n  (with-open [z (java.util.zip.ZipFile. filename)]\n    (reduce #(conj %1 (f %2)) [] (entries z))))\n\n(defn noerr-fixture [f]\n  (binding [*err* (java.io.StringWriter.)]\n    (f)))\n\n(def #^{:macro true} with-system-out-str #'utils/with-system-out-str)\n\n(def #^{:macro true} with-system-err-str #'utils/with-system-err-str)\n\n(defn unmemoize [v underlying]\n  (alter-var-root v (constantly underlying)))\n"
  },
  {
    "path": "test/leiningen/test/install.clj",
    "content": "(ns leiningen.test.install\n  (:require [leiningen.core.user :as user]\n            [leiningen.core.main :as main]\n            [clojure.test :refer :all]\n            [leiningen.install :refer :all]\n            [leiningen.test.helper :as helper]\n            [clojure.java.io :as io]))\n\n(deftest ^:online test-install\n  (helper/unmemoize #'leiningen.core.classpath/get-dependencies-memoized\n                    #'leiningen.core.classpath/get-dependencies*)\n  (helper/delete-file-recursively (helper/m2-dir \"nomnomnom\" \"0.5.0-SNAPSHOT\") true)\n  (with-out-str\n    (binding [main/*info* false]\n      (install helper/sample-project)))\n  (is (not (empty? (.listFiles (helper/m2-dir \"nomnomnom\" \"0.5.0-SNAPSHOT\"))))))\n\n(def tricky-m2-dir (io/file helper/local-repo \"org\" \"domain\" \"tricky-name\" \"1.0\"))\n\n(deftest ^:online test-tricky-name-install\n  (helper/delete-file-recursively tricky-m2-dir true)\n  (with-out-str\n    (install helper/tricky-name-project))\n  (is (not (empty? (.listFiles tricky-m2-dir)))))\n"
  },
  {
    "path": "test/leiningen/test/jar.clj",
    "content": "(ns leiningen.test.jar\n  (:require [clojure.test :refer :all]\n            [leiningen.jar :refer :all]\n            [clojure.java.io :as io]\n            [leiningen.core.main :as main]\n            [leiningen.core.project :as project]\n            [leiningen.core.utils :refer [platform-nullsink]]\n            [leiningen.test.helper :as helper]\n            [robert.hooke :as hooke]\n            [leiningen.javac :as javac]\n            [leiningen.test.helper :refer [unmemoize\n                                           with-system-out-str\n                                           with-system-err-str]]))\n\n(def long-line\n  (apply str (repeat 10000 \"a\")))\n\n(def mock-project-1\n  {:name \"mock-project\"\n   :group \"mock-group\"\n   :version \"1.0\"\n   :main 'foo.one-two.three-four.bar\n   :manifest [[\"hello\" \"world\"]\n              [:my-section-1 {\"C\" \"D\" \"S\" \"T\"}]\n              [\"A\" \"B\"]\n              [:my-section-2 [[\"E\" \"F\"] [\"X\" \"Y\"]] ]\n              [\"G\" \"H\"]\n              [\"long-line\" long-line]]})\n\n(def mock-project-2\n  {:name \"mock-project\"\n   :group \"mock-group\"\n   :version \"1.0\"\n   :main 'foo.one-two.three-four.bar\n   :manifest {\"hello\" \"world\"\n              :my-section-1 {\"C\" \"D\" \"S\" \"T\"}\n              \"A\" \"B\"\n              :my-section-2 [[\"E\" \"F\"] [\"X\" \"Y\"]]\n              \"G\" \"H\"\n              \"long-line\" long-line}})\n\n(deftest has-whitelist\n  (is (= whitelist-keys project/whitelist-keys)))\n\n(deftest test-manifest\n  (doseq [mock-project [mock-project-1 mock-project-2]]\n    (let [mm (-> mock-project\n                 make-manifest\n                 manifest-map)]\n      (is (= {\"Main-Class\" \"foo.one_two.three_four.bar\", \"hello\" \"world\"}\n             (select-keys mm [\"hello\" \"Main-Class\"])))\n      (is (= #{\"A\" \"Build-Jdk\" \"Built-By\" \"Created-By\" \"G\"\n               \"Leiningen-Project-ArtifactId\" \"Leiningen-Project-GroupId\"\n               \"Leiningen-Project-Version\" \"Main-Class\" \"Manifest-Version\"\n               \"hello\" \"long-line\"}\n             (-> mm keys set)))\n      (is (= (get mm \"Leiningen-Project-ArtifactId\") \"mock-project\"))\n      (is (= (get mm \"Leiningen-Project-GroupId\") \"mock-group\"))\n      (is (= (get mm \"Leiningen-Project-Version\") \"1.0\"))\n      (is (= (get mm \"long-line\") long-line))\n      (is (=  #{\"my-section-1\" \"my-section-2\"}\n             (-> mock-project\n                 make-manifest\n                 .getEntries\n                 keys\n                 set))))))\n\n(deftest test-jar-fails\n  (binding [*err* (java.io.StringWriter.)]\n    (with-system-out-str\n      (with-system-err-str\n        (is (thrown? Exception (jar helper/sample-failing-project)))))))\n\n(deftest test-directory-entries-added-to-jar\n  (with-out-str\n    (let [jar (first (vals (jar helper/with-resources-project)))\n          entry-names (set (helper/walkzip jar #(.getName %)))]\n      (is (entry-names \"nested/dir/\"))\n      (is (not (some #(.startsWith % \"/\") entry-names))))))\n\n(deftest test-profile-added-to-jar\n  (with-out-str\n    (let [project (-> helper/with-resources-project\n                      (project/add-profiles\n                       {:test-jar {:resource-paths ^:replace []}})\n                      (project/merge-profiles [:test-jar]))\n          jar (first (vals (jar project)))\n          entry-names (set (helper/walkzip jar #(.getName %)))]\n      (is (not (entry-names \"nested/dir/sample.txt\"))))))\n\n(deftest test-no-aot-jar-succeeds\n  (with-out-str\n    (let [project (helper/read-test-project \"sample-no-aot\")\n          jar (first (vals (jar project)))\n          entry-names (set (helper/walkzip jar #(.getName %)))]\n      (is (not (entry-names \"dev.clj\"))))))\n\n(deftest test-classifier-jar-succeeds\n  (is (= 1 (count (:classifiers helper/with-classifiers-project)))\n      \"test project has a classifier\")\n  (with-out-str\n    (is (= 1 (count (classifier-jars helper/with-classifiers-project nil)))\n        \"test project produces a classifier jar\"))\n  (with-out-str\n    (is (jar helper/with-classifiers-project)\n        \"jar runs correctly\")\n    (is (= 2 (count (jar helper/with-classifiers-project)))\n        \"jar produces two jar files\")))\n\n(deftest ^:online test-no-deps-jar\n  (unmemoize #'leiningen.core.classpath/get-dependencies-memoized\n             #'leiningen.core.classpath/get-dependencies*)\n  (binding [main/*info* false]\n    (let [project (helper/read-test-project \"sample-bad-user\")\n          [coord jar-file] (first (jar (dissoc project :dependencies :main)))]\n      (is (.exists (io/file jar-file)))\n      (is (= coord [:extension \"jar\"])))))\n\n(deftest overlapped-paths\n  (let [info-logs (atom [])]\n    (with-redefs [main/info (fn [& args] (swap! info-logs conj args))]\n      (let [result (jar helper/overlapped-sourcepaths-project)]\n        (is result)\n        (is (not-any? #(re-find #\"Warning\" %) (mapcat identity @info-logs)))))))\n\n(def mock-project mock-project-1)\n\n(deftest test-write-jar\n  (testing (str \"Confirm that a warning is output when the Main-Class is not \"\n                \"part of the output jar file\")\n    (let [out-str (with-out-str\n                    (write-jar mock-project\n                               \"/dev/null\"\n                               [{:type :bytes\n                                 :path \"foo/one_two.class\"\n                                 :bytes \"\"}\n                                {:type :bytes\n                                 :path \"foo/one_two_too.class\"\n                                 :bytes \"\"}]))]\n      (is (.contains out-str\n                     \"Warning: The Main-Class specified does not exist\"))))\n\n  (testing (str \"Confirm that a warning is NOT output when the Main-Class is \"\n                \"not part of the output jar file\")\n    (let [out-str (with-out-str\n                    (write-jar mock-project\n                               \"/dev/null\"\n                               [{:type :bytes\n                                 :path \"foo/one_two.class\"\n                                 :bytes \"\"}\n                                {:type :bytes\n                                 :path \"foo/one_two_too.class\"\n                                 :bytes \"\"}\n                                {:type :bytes\n                                 :path \"foo/one_two/three_four/bar.class\"\n                                 :bytes \"\"}]))]\n      (is (not (.contains out-str\n                          \"Warning: The Main-Class specified does not exist\"))))))\n\n(deftest javac-launched-with-whitelisted-settings\n  (let [user-profile {:local-repo \"test_projects/jar/foo/bar\"\n                      :mirrors {\"central\" {:name \"central\"\n                                           :url \"https://maven-central.storage-download.googleapis.com/repos/central/data/\"}}}\n        orig-project (-> (helper/read-test-project-with-user-profiles\n                          \"java-main\"\n                          {:user user-profile}))\n        javac-project (atom {})\n        javac-project-hook (fn [f proj profile]\n                             (let [new-project (f proj profile)]\n                               (reset! javac-project new-project)\n                               new-project))]\n    (hooke/with-scope\n      (hooke/add-hook #'javac/javac-project-for-subprocess javac-project-hook)\n      (with-out-str\n        (binding [main/*info* false]\n          (jar orig-project)))\n      (is (= (:local-repo orig-project)\n             (:local-repo @javac-project)))\n      (is (= (:mirrors orig-project)\n             (:mirrors @javac-project))))))\n"
  },
  {
    "path": "test/leiningen/test/javac.clj",
    "content": "(ns leiningen.test.javac\n  (:use [clojure.test]\n        [clojure.java.io :only [file]]\n        [leiningen.javac :only [javac normalize-javac-options]]\n        [leiningen.test.helper :only [delete-file-recursively\n                                      #_dev-deps-project]]))\n\n(deftest test-javac-options-normalization\n  (testing \"that Leiningen 2 style options are returned unmodified\"\n    (are [arg] (= arg (normalize-javac-options arg))\n      [\"-target\" \"1.6\" \"-source\" \"1.6\"]\n      [\"-deprecation\" \"-g\"]))\n  (testing \"conversion of Leiningen 1 style options that are supported\"\n    (are [old new] (= new (normalize-javac-options old))\n         {:debug false}                [\"-g:none\"]\n         {:debug \"off\"}                [\"-g:none\"]\n         ;; overriden by :compile-path\n         {:destdir \"clazzez\"}          []\n         {:encoding \"utf8\"}            [\"-encoding\" \"utf8\"]\n         {:debugLevel \"source,lines\"}  [\"-g:source,lines\"]))\n  (testing \"conversion of multiple Leiningen 1 style options\"\n    ;; Cannot assume argument order from hash maps\n    (are [old new] (= new\n                      (apply hash-map (normalize-javac-options old)))\n         {:source \"1.5\" :target \"1.5\"} {\"-target\" \"1.5\" \"-source\" \"1.5\"}\n         {:source 1.5   \"target\" 1.5}  {\"-target\" \"1.5\" \"-source\" \"1.5\"})))\n\n(deftest ^:disabled ; not really; need to fix this\n  test-javac\n  #_(delete-file-recursively (:compile-path dev-deps-project) true)\n  #_(javac dev-deps-project)\n  (is (.exists (file \"test_projects/dev-deps-only/classes\"\n                     \"dev_deps_only\" \"Junk.class\")))\n  (is (.exists (file \"test_projects/dev-deps-only/classes\"\n                     \"dev_deps_only\" \"Junk2.class\"))))\n"
  },
  {
    "path": "test/leiningen/test/jvm_opts.clj",
    "content": "(ns leiningen.test.jvm-opts\n  (:require [leiningen.with-profile :refer [with-profile]]\n            [leiningen.test.helper :refer [jvm-opts-project\n                                           with-system-out-str]])\n  (:use clojure.test))\n\n;; This is a regression test for technomancy/leiningen#1676 (make sure\n;; that file.encoding can be overriden by profiles.)\n(deftest file-encoding-conveyed\n  (let [exec '(println \"system encoding\" (System/getProperty \"file.encoding\"))\n        run-with #(with-system-out-str\n                    (with-profile jvm-opts-project % \"run\"\n                      \"-m\" \"clojure.main\"\n                      \"-e\" (pr-str exec)))]\n    (testing \"baseline sane\"\n      (is (.contains (run-with \"+no-op\") \"system encoding UTF-8\")))\n    (testing \"accepts alternative\"\n      (is (.contains (run-with \"+ascii\") \"system encoding ASCII\")))))\n"
  },
  {
    "path": "test/leiningen/test/new/templates.clj",
    "content": "(ns leiningen.test.new.templates\n  (:use clojure.test\n        leiningen.new.templates)\n  (:require [leiningen.test.helper :refer [abort-msg] :as lthelper]\n            [leiningen.core.user :as user]\n            [clojure.java.io :as io])\n  (:import [java.io File]))\n\n(defn- getenv [s]\n  (System/getenv s))\n\n(deftest line-separators\n  (testing \"that nothing changes when we're on unix systems\"\n    (with-redefs [user/getprop (constantly \"\\n\")]\n      (is (= (fix-line-separators \"foo\") \"foo\"))\n      (is (= (fix-line-separators \"bar\\nbaz\") \"bar\\nbaz\"))\n      (is (= (fix-line-separators \"quux\\n\\n\\nsycorax\") \"quux\\n\\n\\nsycorax\"))))\n\n  (testing \"that newlines are correctly converted on '\\\\r\\\\n' systems\"\n    (with-redefs [user/getprop (constantly \"\\r\\n\")]\n      (is (= (fix-line-separators \"foo\") \"foo\"))\n      (is (= (fix-line-separators \"bar\\nbaz\") \"bar\\r\\nbaz\"))\n      (is (= (fix-line-separators \"quux\\n\\n\\nsycorax\")\n             \"quux\\r\\n\\r\\n\\r\\nsycorax\"))))\n\n  (testing \"that other bizarre systems get same treatment\"\n    (with-redefs [user/getprop (constantly \"\\t\\t\")]\n      (is (= (fix-line-separators \"foo\") \"foo\"))\n      (is (= (fix-line-separators \"bar\\nbaz\") \"bar\\t\\tbaz\"))\n      (is (= (fix-line-separators \"quux\\n\\n\\nsycorax\")\n             \"quux\\t\\t\\t\\t\\t\\tsycorax\"))))\n\n  (testing \"that one can override the normal system newline\"\n    (with-redefs [user/getprop (constantly \"\\r\\n\")\n                  user/getenv (fn [s] (if (= s \"LEIN_NEW_UNIX_NEWLINES\")\n                                      \"y\"\n                                      (getenv s)))]\n      (is (= (fix-line-separators \"foo\") \"foo\"))\n      (is (= (fix-line-separators \"bar\\nbaz\") \"bar\\nbaz\"))\n      (is (= (fix-line-separators \"quux\\n\\n\\nsycorax\") \"quux\\n\\n\\nsycorax\")))))\n\n(deftest project-names\n  (is (= (project-name \"org.example/foo.bar\") \"foo.bar\"))\n  (is (= (project-name \"example\") \"example\"))\n  (is (= (sanitize-ns \"org.example/foo-bar\") \"org.example.foo-bar\"))\n  (is (= (sanitize-ns \"foo-bar\") \"foo-bar\"))\n  (is (= (sanitize-ns \"foo_bar\") \"foo-bar\")))\n\n(deftest namespaces\n  (is (= (multi-segment \"foo\") \"foo.core\"))\n  (is (= (multi-segment \"foo\" \"api\") \"foo.api\"))\n  (is (= (multi-segment \"multi.segment\" \"last\") \"multi.segment\")))\n\n(deftest paths\n  (is (= (name-to-path \"foo-bar.baz\") (lthelper/fix-path-delimiters \"foo_bar/baz\"))))\n\n(deftest renderers\n  (is (.contains (abort-msg (renderer \"my-template\") \"boom\" {})\n                 \"Template resource 'leiningen/new/my_template/boom' not found.\"))\n  (is (.contains (abort-msg (renderer \"my-template\") \"boom\")\n                 \"Template resource 'leiningen/new/my_template/boom' not found.\")))\n\n(deftest slurp-resource-compatibility ; can be removed in 3.0.0\n  (is (= (slurp-resource \"leiningen/new/template/temp.clj\")\n         (slurp-resource (io/resource \"leiningen/new/template/temp.clj\")))))\n\n\n(deftest files\n  (testing \"that files marked as executable are set executable\"\n    (let [file (File/createTempFile \"lein\" \"template\")\n          path [(.getName file) (.getAbsolutePath file) :executable true]]\n      (binding [*dir* (.getParentFile file)\n                *force?* true]\n        (.deleteOnExit file)\n        (->files {} path)\n        (is (.canExecute file))))))\n"
  },
  {
    "path": "test/leiningen/test/new.clj",
    "content": "(ns leiningen.test.new\n  (:require [leiningen.new :as new]\n            [clojure.test :refer :all]\n            [clojure.java.io :refer [file]]\n            [leiningen.test.helper :refer [delete-file-recursively abort-msg]]\n            [leiningen.new :as new]\n            [leiningen.core.main :as main]))\n\n(use-fixtures :once (fn [f] (binding [main/*info* false] (f))))\n\n(deftest test-new-with-just-project-name\n  (new/new nil \"test-new-proj\")\n  (is (= #{\"README.md\" \"project.clj\" \"resources\" \"src\" \"core.clj\" \"test\"\n           \"doc\" \"intro.md\" \"test_new_proj\" \"core_test.clj\" \".gitignore\"\n           \".hgignore\" \"LICENSE\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"test-new-proj\")))))))\n  (delete-file-recursively (file \"test-new-proj\") :silently))\n\n(deftest test-new-with-group-and-project-name\n  (new/new nil \"orgname/a-project\")\n  (is (= #{\"src\" \"a_project_test.clj\" \"project.clj\" \"a_project.clj\" \"orgname\"\n           \"resources\" \"test\" \".gitignore\" \"README.md\" \"doc\" \"intro.md\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName)\n                   (rest (file-seq (file \"a-project\")))))))\n  (delete-file-recursively (file \"a-project\") :silently))\n\n(deftest test-new-with-explicit-default-template\n  (new/new nil \"default\" \"test-new-proj\")\n  (is (= #{\"README.md\" \"project.clj\" \"src\" \"core.clj\" \"test\" \"resources\"\n           \"doc\" \"intro.md\" \"test_new_proj\" \"core_test.clj\" \".gitignore\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"test-new-proj\")))))))\n  (delete-file-recursively (file \"test-new-proj\") :silently))\n\n(deftest test-new-with-app-template\n  (new/new nil \"app\" \"test-new-app\")\n  (is (= #{\"README.md\" \"project.clj\" \"src\" \"core.clj\" \"test\" \"resources\"\n           \"doc\" \"intro.md\" \"test_new_app\" \"core_test.clj\" \".gitignore\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"test-new-app\")))))))\n  (delete-file-recursively (file \"test-new-app\") :silently))\n\n(deftest test-new-with-plugin-template\n  (new/new nil \"plugin\" \"test-new-plugin\")\n  (is (= #{\"README.md\" \"project.clj\" \"src\" \"leiningen\"\n           \"test_new_plugin.clj\" \".gitignore\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"test-new-plugin\")))))))\n  (delete-file-recursively (file \"test-new-plugin\") :silently))\n\n(deftest test-new-with-template-template\n  (new/new nil \"template\" \"test-new-template\")\n  (is (= #{\"README.md\" \"project.clj\" \"src\" \"leiningen\" \"new\" \"resources\"\n           \"test_new_template.clj\" \"test_new_template\" \"foo.clj\" \".gitignore\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"test-new-template\")))))))\n  (delete-file-recursively (file \"test-new-template\") :silently))\n\n(deftest test-new-with-nonexistent-template\n  (is (re-find\n       #\"Could not find template for zzz\"\n       (with-redefs [leiningen.new/resolve-remote-template (constantly false)]\n         (abort-msg new/new nil \"zzz\" \"my-zzz\")))))\n\n(deftest test-new-with-nonexistent-template-in-mirrors\n  (is (nil?\n       (with-redefs\n         [leiningen.core.user/profiles\n          (constantly {:user\n                        {:mirrors\n                          {\"clojars\" \"https://clojars.example.com\"\n                           \"central\" \"https://central.exmaple.com\"}}})]\n         (let [name \"luminus\"\n               sym (symbol (str \"leiningen.new.\" name))]\n           (leiningen.new/resolve-remote-template name sym))))))\n\n(deftest ^:online test-group-id-template\n  (is (fn? @(new/resolve-template \"us.technomancy/liquid-cool\")))\n  (is (fn? @(new/resolve-template \"net.ofnir/default\"))))\n\n(deftest test-new-with-*-jure-project-name\n  (is (re-find\n       #\"names such as clojure .* are not allowed\"\n       (with-redefs [leiningen.new/resolve-remote-template (constantly false)]\n         (abort-msg new/new nil \"awesomejure\")))))\n\n(deftest test-new-with-clojure-project-name\n  (is (re-find\n       #\"clojure.*can't be used as project name\"\n       (with-redefs [leiningen.new/resolve-remote-template (constantly false)]\n         (abort-msg new/new nil \"clojure\")))))\n\n(deftest test-new-with-show-describes-a-template\n  (is (re-find\n       #\"^A general project template for libraries\"\n       (with-out-str\n         (new/new nil \":show\" \"default\"))))\n  (is (re-find\n       #\"^A general project template for libraries\"\n       (with-out-str\n         (new/new nil \"default\" \":show\")))))\n\n(deftest test-new-with-to-dir-option\n  (new/new nil \"test-new-proj\" \"--to-dir\" \"my-proj\")\n  (is (= #{\"README.md\" \"project.clj\" \"src\" \"core.clj\" \"test\" \"resources\"\n           \"doc\" \"intro.md\" \"test_new_proj\" \"core_test.clj\" \".gitignore\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"my-proj\")))))))\n  (delete-file-recursively (file \"my-proj\") :silently))\n\n(deftest test-new-with-force-option\n  (.mkdir (file \"test-new-proj\"))\n  (new/new nil \"test-new-proj\" \"--force\")\n  (is (= #{\"README.md\" \"project.clj\" \"src\" \"core.clj\" \"test\" \"resources\"\n           \"doc\" \"intro.md\" \"test_new_proj\" \"core_test.clj\" \".gitignore\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"test-new-proj\")))))))\n  (delete-file-recursively (file \"test-new-proj\") :silently))\n\n(deftest test-new-with-to-dir-and-force-option\n  (.mkdir (file \"my-proj\"))\n  (new/new nil \"test-new-proj\" \"--to-dir\" \"my-proj\" \"--force\")\n  (is (= #{\"README.md\" \"project.clj\" \"src\" \"core.clj\" \"test\" \"resources\"\n           \"doc\" \"intro.md\" \"test_new_proj\" \"core_test.clj\" \".gitignore\"\n           \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n         (set (map (memfn getName) (rest (file-seq (file \"my-proj\")))))))\n  (delete-file-recursively (file \"my-proj\") :silently))\n\n(deftest test-new-generates-in-the-current-directory\n  (let [original-pwd (System/getProperty \"leiningen.original.pwd\")\n        new-pwd (file original-pwd \"subdir\") ;; TODO: make rand temp dir instead\n        _ (.mkdir new-pwd)\n        new-pwd (str new-pwd)]\n    ;; Simulate being in a directory other than the project's top-level dir\n    (System/setProperty \"leiningen.original.pwd\" new-pwd)\n\n    (new/new nil \"test-new-proj\")\n    (is (= #{\"README.md\" \"project.clj\" \"src\" \"core.clj\" \"test\" \"resources\"\n             \"doc\" \"intro.md\" \"test_new_proj\" \"core_test.clj\" \".gitignore\"\n             \"LICENSE\" \".hgignore\" \"CHANGELOG.md\"}\n           (set (map (memfn getName)\n                     (rest (file-seq (file new-pwd \"test-new-proj\")))))))\n    (System/setProperty \"leiningen.original.pwd\" original-pwd)\n    (delete-file-recursively (file new-pwd) :silently)))\n"
  },
  {
    "path": "test/leiningen/test/pom.clj",
    "content": "(ns leiningen.test.pom\n  (:require [clojure.data.xml :as xml]\n            [leiningen.core.project :as project]\n            [leiningen.core.main :as main]\n            [clojure.test :refer :all]\n            [clojure.java.io :as io]\n            [leiningen.pom :as lein-pom :refer [make-pom pom pom-uri snapshot?]]\n            [leiningen.core.user :as user]\n            [leiningen.test.helper\n             :refer [sample-project sample-profile-meta-project\n                     managed-deps-project managed-deps-snapshot-project\n                     with-pom-plugins-project leaky-composite-project]\n             :as lthelper]))\n\n(use-fixtures :once (fn [f]\n                      (with-redefs [user/profiles (constantly {})]\n                        (f))))\n\n(xml/alias-uri 'pom pom-uri)\n\n(deftest test-pom-file-is-created\n  (let [pom-file (io/file (:root sample-project) \"pom.xml\")]\n    (io/delete-file pom-file true)\n    (binding [main/*info* false]\n      (pom sample-project))\n    (is (.exists pom-file))))\n\n(defn parse-xml [s]\n  (xml/parse-str s :skip-whitespace true))\n\n(defn deep-content [xml tags]\n  (reduce #(->> %1\n               (filter (fn [xml] (= (:tag xml) %2)))\n               first\n               :content)\n          (if (seq? xml)\n            xml\n            [xml])\n          tags))\n\n(def first-in (comp first deep-content))\n\n(defn with-profile [project name profile]\n  (let [profile (#'project/apply-profile-meta\n                 (project/default-profile-metadata name)\n                 profile)]\n    (-> project\n        (vary-meta update-in [:without-profiles :profiles]\n                   assoc name profile)\n        (vary-meta update-in [:profiles]\n                   assoc name profile))))\n\n(defn with-profile-merged\n  ([project profile]\n     (with-profile-merged project :testy profile))\n  ([project name profile]\n      (project/merge-profiles (with-profile project name profile) [name])))\n\n(deftest test-pom-scm-auto\n  (with-redefs [lein-pom/parse-github-url (constantly [\"techno\" \"lein\"])\n                lein-pom/read-git-head (constantly \"the git head\")]\n    (let [project (with-profile-merged sample-project\n                  ^:leaky {:scm {:name \"auto\"\n                                 :dir \".\" ;; so resolve-git-dir looks for lein project .git dir, not the sample\n                                 :connection \"https://example.org/ignored-url\"\n                                 :url \"https://github.com/this-is/ignored\"}})\n        pom (make-pom project)\n        xml (parse-xml pom)]\n      (is (= \"scm:git:git://github.com/techno/lein.git\" (first-in xml [::pom/project ::pom/scm ::pom/connection])))\n      (is (= \"scm:git:ssh://git@github.com/techno/lein.git\" (first-in xml [::pom/project ::pom/scm ::pom/developerConnection])))\n      (is (= \"https://github.com/techno/lein\" (first-in xml [::pom/project ::pom/scm ::pom/url])))\n      (is (= \"the git head\" (first-in xml [::pom/project ::pom/scm ::pom/tag]))))))\n\n(deftest test-pom-scm-git\n  (with-redefs [lein-pom/read-git-origin (constantly \"git@github.com:techno/lein.git\")\n                lein-pom/read-git-head (constantly \"the git head\")]\n    (let [project (with-profile-merged sample-project\n                  ^:leaky {:scm {:name \"git\"\n                                 :dir \".\" ;; so resolve-git-dir looks for lein project .git dir, not the sample\n                                 :connection \":connection is not ignored in :scm :git\"\n                                 :url \"https://github.com/this-is-not/ignored\"}})\n        pom (make-pom project)\n        xml (parse-xml pom)]\n      (is (= \":connection is not ignored in :scm :git\" (first-in xml [::pom/project ::pom/scm ::pom/connection])))\n      (is (= \"scm:git:ssh://git@github.com/techno/lein.git\" (first-in xml [::pom/project ::pom/scm ::pom/developerConnection])))\n      (is (= \"https://github.com/this-is-not/ignored\" (first-in xml [::pom/project ::pom/scm ::pom/url])))\n      (is (= \"the git head\" (first-in xml [::pom/project ::pom/scm ::pom/tag]))))))\n\n(deftest test-pom-scm-git-with-empty-values\n  (with-redefs [lein-pom/parse-github-url (constantly [\"techno\" \"lein\"])\n                lein-pom/read-git-head (constantly \"the git head\")]\n    (let [project (with-profile-merged sample-project\n                  ^:leaky {:scm {:name \"git\"\n                                 :dir \".\" ;; so resolve-git-dir looks for lein project .git dir, not the sample\n                                 :connection \"\"\n                                 :developerConnection nil\n                                 :url \"https://github.com/this-is-not/ignored\"}})\n        pom (make-pom project)\n        xml (parse-xml pom)]\n      (is (nil? (first-in xml [::pom/project ::pom/scm ::pom/connection]))\n          \":connection is not present because the project defines an empty value for it\")\n      (is (nil? (first-in xml [::pom/project ::pom/scm ::pom/developerConnection]))\n          \":developerConnection is not present because the project defines an empty value for it\")\n      (is (= \"https://github.com/this-is-not/ignored\" (first-in xml [::pom/project ::pom/scm ::pom/url])))\n      (is (= \"the git head\" (first-in xml [::pom/project ::pom/scm ::pom/tag]))))))\n\n(deftest test-pom-scm-git-with-https-url\n  (with-redefs [lein-pom/read-git-origin (constantly \"https://github.com/techno/lein.git\")\n                lein-pom/read-git-head (constantly \"the git head\")]\n    (let [project (with-profile-merged sample-project\n                  ^:leaky {:scm {:name \"git\"\n                                 :dir \".\" ;; so resolve-git-dir looks for lein project .git dir, not the sample\n                                 :connection \":connection is not ignored in :scm :git\"\n                                 :url \"https://github.com/this-is-not/ignored\"}})\n        pom (make-pom project)\n        xml (parse-xml pom)]\n      (is (= \":connection is not ignored in :scm :git\" (first-in xml [::pom/project ::pom/scm ::pom/connection])))\n      (is (= \"scm:git:ssh://git@github.com/techno/lein.git\" (first-in xml [::pom/project ::pom/scm ::pom/developerConnection])))\n      (is (= \"https://github.com/this-is-not/ignored\" (first-in xml [::pom/project ::pom/scm ::pom/url])))\n      (is (= \"the git head\" (first-in xml [::pom/project ::pom/scm ::pom/tag]))))))\n\n(deftest test-pom-scm-git-with-non-git-url\n  (with-redefs [lein-pom/read-git-origin (constantly \"https://github.com/techno/lein\")\n                lein-pom/read-git-head (constantly \"the git head\")]\n    (let [project (with-profile-merged sample-project\n                  ^:leaky {:scm {:name \"git\"\n                                 :dir \".\" ;; so resolve-git-dir looks for lein project .git dir, not the sample\n                                 :connection \":connection is not ignored in :scm :git\"\n                                 :url \"https://github.com/this-is-not/ignored\"}})\n        pom (make-pom project)\n        xml (parse-xml pom)]\n      (is (= \":connection is not ignored in :scm :git\" (first-in xml [::pom/project ::pom/scm ::pom/connection])))\n      (is (= \"scm:git:ssh://git@github.com/techno/lein.git\" (first-in xml [::pom/project ::pom/scm ::pom/developerConnection])))\n      (is (= \"https://github.com/this-is-not/ignored\" (first-in xml [::pom/project ::pom/scm ::pom/url])))\n      (is (= \"the git head\" (first-in xml [::pom/project ::pom/scm ::pom/tag]))))))\n\n(deftest test-pom-default-values\n  (let [xml (parse-xml (make-pom sample-project))]\n    (is (= \"nomnomnom\" (first-in xml [::pom/project ::pom/groupId]))\n        \"group is correct\")\n    (is (= \"nomnomnom\" (first-in xml [::pom/project ::pom/artifactId]))\n        \"artifact is correct\")\n    (is (= \"nomnomnom\" (first-in xml [::pom/project ::pom/name]))\n        \"name is correct\")\n    (is (= \"0.5.0-SNAPSHOT\" (first-in xml [::pom/project ::pom/version]))\n        \"version is correct\")\n    (is (nil? (first-in xml [::pom/project ::pom/parent]))\n        \"no parent\")\n    (is (= \"https://leiningen.org\" (first-in xml [::pom/project ::pom/url]))\n        \"url is correct\")\n    (is (= [\"Eclipse Public License\" \"https://www.eclipse.org/legal/epl-v10.html\"]\n           (->> (deep-content xml [::pom/project ::pom/licenses])\n                (map :content) first (map :content) (map first)))\n        \"no license\")\n    (is (= \"A test project\" (first-in xml [::pom/project ::pom/description]))\n        \"description is included\")\n    (is (= nil (first-in xml [::pom/project ::pom/mailingLists]))\n        \"no mailing list\")\n    (is (= [\"central\" \"clojars\" \"other\"]\n           (map #(first-in % [::pom/repository ::pom/id])\n                (deep-content xml [::pom/project ::pom/repositories])))\n        \"repositories are named\")\n    (is (= [\"https://repo1.maven.org/maven2/\" \"https://repo.clojars.org/\"\n            \"https://example.com/repo\"]\n           (map #(first-in % [::pom/repository ::pom/url])\n                (deep-content xml [::pom/project ::pom/repositories])))\n        \"repositories have correct location\")\n    (is (= [\"false\" \"true\" \"true\"]\n           (map #(first-in % [::pom/repository ::pom/snapshots ::pom/enabled])\n                (deep-content xml [::pom/project ::pom/repositories])))\n        \"some snapshots are enabled\")\n    (is (= [\"true\" \"true\" \"true\"]\n           (map #(first-in % [::pom/repository ::pom/releases ::pom/enabled])\n                (deep-content xml [::pom/project ::pom/repositories])))\n        \"releases are enabled\")\n    (is (= [nil nil \"always\"]\n           (map #(first-in % [::pom/repository ::pom/snapshots ::pom/updatePolicy])\n                (deep-content xml [::pom/project ::pom/repositories])))\n        \"snapshots update policy is included\")\n    (is (= [nil nil \"warn\"]\n           (map #(first-in % [::pom/repository ::pom/releases ::pom/checksumPolicy])\n                (deep-content xml [::pom/project ::pom/repositories])))\n        \"releases checksum policy is included\")\n    (is (= \"src\" (first-in xml [::pom/project ::pom/build ::pom/sourceDirectory]))\n        \"source directory is included\")\n    (is (= \"test\" (first-in xml [::pom/project ::pom/build ::pom/testSourceDirectory]))\n        \"test directory is included\")\n    (is (= [\"resources\"]\n           (map #(first-in % [::pom/resource ::pom/directory])\n                (deep-content xml [::pom/project ::pom/build ::pom/resources])))\n        \"resource directories use project without :default or :dev profile\")\n    (is (= [\"resources\"]\n           (map #(first-in % [::pom/testResource ::pom/directory])\n                (deep-content xml [::pom/project ::pom/build ::pom/testResources])))\n        \"test resource directories use :dev :default and :test profiles\")\n    (is (= \"target\" (first-in xml [::pom/project ::pom/build ::pom/directory]))\n        \"target directory is included\")\n    (is (= nil (first-in xml [::pom/project ::pom/build ::pom/extensions]))\n        \"no extensions\")\n    (is (= (lthelper/fix-path-delimiters \"target/classes\")\n           (first-in xml [::pom/project ::pom/build ::pom/outputDirectory]))\n        \"classes directory is included\")\n    (is (= [\"org.clojure\" \"rome\" \"ring\"]\n           (map #(first-in % [::pom/dependency ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"clojure\" \"rome\" \"ring\"]\n           (map #(first-in % [::pom/dependency ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"1.3.0\" \"0.9\" \"1.0.0\"]\n           (map #(first-in % [::pom/dependency ::pom/version])\n                (deep-content xml [::pom/project ::pom/dependencies]))))))\n\n(deftest test-dependencies-are-test-scoped\n  (let [xml (parse-xml\n             (make-pom (with-profile-merged\n                         sample-project\n                         :test {:dependencies '[[peridot \"0.0.5\"]]})))]\n    (is (= [\"org.clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"1.3.0\" \"0.9\" \"1.0.0\" \"0.0.5\"]\n           (map #(first-in % [::pom/dependency ::pom/version])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"test\"]\n           (map #(first-in % [::pom/dependency ::pom/scope])\n                (deep-content xml [::pom/project ::pom/dependencies]))))))\n\n(deftest dev-dependencies-are-test-scoped\n  (let [xml (parse-xml\n             (make-pom (with-profile-merged\n                         sample-project\n                         :dev\n                         {:dependencies '[[peridot \"0.0.5\"]]})))]\n    (is (= [\"org.clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"1.3.0\" \"0.9\" \"1.0.0\" \"0.0.5\"]\n           (map #(first-in % [::pom/dependency ::pom/version])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"test\"]\n           (map #(first-in % [::pom/dependency ::pom/scope])\n                (deep-content xml [::pom/project ::pom/dependencies]))))))\n\n(deftest provided-dependencies-are-provided-scoped\n  (let [xml (parse-xml\n             (make-pom (with-profile-merged\n                         sample-project\n                         :provided\n                         {:dependencies '[[peridot \"0.0.5\"]]})))]\n    (is (= [\"org.clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"1.3.0\" \"0.9\" \"1.0.0\" \"0.0.5\"]\n           (map #(first-in % [::pom/dependency ::pom/version])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"provided\"]\n           (map #(first-in % [::pom/dependency ::pom/scope])\n                (deep-content xml [::pom/project ::pom/dependencies]))))))\n\n(deftest dependency-options\n  (let [xml (parse-xml\n             (make-pom (with-profile-merged\n                         sample-project\n                         ^:leaky {:dependencies '[[peridot \"0.0.5\"\n                                                   :scope \"provided\"\n                                                   :optional true\n                                                   :classifier \"sources\"\n                                                   :extension \"pom\"\n                                                   :exclusions\n                                                   [[ring-mock\n                                                     :classifier \"cla\"\n                                                     :extension \"dom\"]]]]})))]\n    (is (= [\"org.clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"1.3.0\" \"0.9\" \"1.0.0\" \"0.0.5\"]\n           (map #(first-in % [::pom/dependency ::pom/version])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"provided\"]\n           (map #(first-in % [::pom/dependency ::pom/scope])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"true\"]\n           (map #(first-in % [::pom/dependency ::pom/optional])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"sources\"]\n           (map #(first-in % [::pom/dependency ::pom/classifier])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"pom\"]\n           (map #(first-in % [::pom/dependency ::pom/type])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"ring-mock\"]\n           (map #(first-in % [::pom/dependency ::pom/exclusions ::pom/exclusion ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"ring-mock\"]\n           (map #(first-in % [::pom/dependency ::pom/exclusions ::pom/exclusion ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"cla\"]\n           (map #(first-in % [::pom/dependency ::pom/exclusions ::pom/exclusion ::pom/classifier])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"dom\"]\n           (map #(first-in % [::pom/dependency ::pom/exclusions ::pom/exclusion ::pom/type])\n                (deep-content xml [::pom/project ::pom/dependencies])))))\n  (let [xml (parse-xml\n             (make-pom (with-profile-merged\n                         sample-project\n                         ^:leaky {:dependencies '[[peridot \"0.0.5\"\n                                                   :scope \"provided\"\n                                                   :exclusions\n                                                   [ring-mock]]]})))]\n    (is (= [\"org.clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"clojure\" \"rome\" \"ring\" \"peridot\"]\n           (map #(first-in % [::pom/dependency ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"1.3.0\" \"0.9\" \"1.0.0\" \"0.0.5\"]\n           (map #(first-in % [::pom/dependency ::pom/version])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"provided\"]\n           (map #(first-in % [::pom/dependency ::pom/scope])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil \"ring-mock\"]\n           (map #(first-in % [::pom/dependency ::pom/exclusions ::pom/exclusion ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil nil]\n           (map #(first-in % [::pom/dependency ::pom/exclusions ::pom/exclusion ::pom/classifier])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil nil nil  nil]\n           (map #(first-in % [::pom/dependency ::pom/exclusions ::pom/exclusion ::pom/type])\n                (deep-content xml [::pom/project ::pom/dependencies]))))))\n\n(deftest dependencies-are-required-when-overlapped-by-builtin-profiles\n  (let [xml (parse-xml\n             (make-pom (with-profile-merged\n                         sample-project\n                         :dev {:dependencies '[[rome \"0.8\"]]})))]\n    (is (= [\"org.clojure\" \"rome\" \"ring\"]\n           (map #(first-in % [::pom/dependency ::pom/groupId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"clojure\" \"rome\" \"ring\"]\n           (map #(first-in % [::pom/dependency ::pom/artifactId])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [\"1.3.0\" \"0.8\" \"1.0.0\"]\n           (map #(first-in % [::pom/dependency ::pom/version])\n                (deep-content xml [::pom/project ::pom/dependencies]))))\n    (is (= [nil \"test\" nil]\n           (map #(first-in % [::pom/dependency ::pom/scope])\n                (deep-content xml [::pom/project ::pom/dependencies]))))))\n\n(deftest test-pom-has-classifier-when-defined\n  (is (not (re-find #\"classifier\"\n                    (make-pom sample-project))))\n  (is (= \"stuff\"\n         (-> (make-pom (with-profile-merged\n                         sample-project\n                         ^:leaky {:classifier \"stuff\"}))\n              parse-xml\n              (first-in [::pom/project ::pom/classifier])))))\n\n(deftest test-pom-adds-java-source-paths\n  (is (= (vec (map lthelper/fix-path-delimiters [\"java/src\" \"java/another\"]))\n         (-> (make-pom (with-profile-merged sample-project\n                         ^:leaky\n                         {:java-source-paths [\"java/src\" \"java/another\"]}))\n             parse-xml\n             (deep-content [::pom/project ::pom/build ::pom/plugins ::pom/plugin ::pom/executions\n                            ::pom/execution ::pom/configuration ::pom/sources])\n             ((partial mapcat :content))))))\n\n(deftest test-pom-handles-global-exclusions\n  (is (= [[\"clojure\"] [\"clojure\"]]\n         (-> (make-pom (with-profile-merged sample-project\n                         ^:leaky {:exclusions '[org.clojure/clojure]}))\n             parse-xml\n             (deep-content [::pom/project ::pom/dependencies])\n             ((partial map #(deep-content % [::pom/dependency ::pom/exclusions])))\n             ((partial map\n                       (partial map\n                                #(first-in % [::pom/exclusion ::pom/artifactId]))))))))\n\n(deftest test-pom-tries-to-pprint\n  (is (re-find #\"(?m)^\\s+<groupId>nomnomnom</groupId>$\"\n               (make-pom sample-project))))\n\n(deftest test-snapshot-checking\n  (binding [main/*exit-process?* false]\n    (let [project (vary-meta sample-project update-in [:without-profiles] assoc\n                             :version \"1.0\"\n                             :dependencies [['clojure \"1.0.0-SNAPSHOT\"]])]\n      (is (thrown? Exception (binding [*err* (java.io.StringWriter.)]\n                               (pom project)))))))\n\n(deftest test-classifier-kept\n  (let [xml (parse-xml (make-pom lthelper/native-project))]\n    (is (= [[\"gdx-platform\" nil] [\"gdx-platform\" \"natives-desktop\"]]\n           (for [dep (deep-content xml [::pom/project ::pom/dependencies])\n                 :let [artifact (first-in dep [::pom/dependency ::pom/artifactId])]\n                 :when (= \"gdx-platform\" artifact)]\n             [artifact (first-in dep [::pom/dependency ::pom/classifier])])))))\n\n(deftest test-override-base-profile\n  (testing \"leaky explicit profile\"\n    (let [p (make-pom (with-profile-merged sample-project\n                        ^:leaky\n                        {:dependencies [['nrepl/nrepl \"0.4.5\"]]}))\n          deps (deep-content (parse-xml p) [::pom/project ::pom/dependencies])\n          nrepls (filter #(re-find #\"nrepl\" (pr-str %)) deps)\n          versions (map #(deep-content % [::pom/dependency ::pom/version]) nrepls)]\n      (is (= [[\"0.4.5\"]] versions))))\n  (testing \"pom-scope\"\n    (let [p (make-pom (with-profile-merged sample-project\n                        ^{:pom-scope :test}\n                        {:dependencies [['nrepl/nrepl \"0.4.5\"]]}))\n          deps (deep-content (parse-xml p) [::pom/project ::pom/dependencies])\n          nrepls (filter #(re-find #\"nrepl\" (pr-str %)) deps)\n          versions (map #(deep-content % [::pom/dependency ::pom/version]) nrepls)]\n      (is (= [[\"0.4.5\"]] versions)))))\n\n(deftest test-leaky-profile\n  (let [p (binding [main/*info* false]\n            (make-pom sample-profile-meta-project))\n        deps (deep-content (parse-xml p) [::pom/project ::pom/dependencies])\n        t-m (filter #(re-find #\"tools.macro\" (pr-str %)) deps)\n        j-c (filter #(re-find #\"java.classpath\" (pr-str %)) deps)\n        t-n (filter #(re-find #\"tools.namespace\" (pr-str %)) deps)]\n    (is (= [[\"0.1.2\"]] (map #(deep-content % [::pom/dependency ::pom/version]) t-m)))\n    (is (= [[\"0.2.2\"]] (map #(deep-content % [::pom/dependency ::pom/version]) j-c)))\n    (is (= [[\"0.2.6\"]] (map #(deep-content % [::pom/dependency ::pom/version]) t-n)))\n    (is (= [nil] (map #(deep-content % [::pom/dependency ::pom/scope]) t-m)))\n    (is (= [[\"test\"]] (map #(deep-content % [::pom/dependency ::pom/scope]) j-c)))\n    (is (= [[\"provided\"]] (map #(deep-content % [::pom/dependency ::pom/scope]) t-n)))))\n\n(deftest test-determine-release-type\n  (testing \"Version containing SNAPSHOT is treated as snapshot\"\n    (is (snapshot? {:version \"SNAPSHOT\"}))\n    (is (snapshot? {:version \"fooSNAPSHOTbar\"})))\n  (testing \"Version containing anything else is not a snapshot \"\n    (is (not (snapshot? {:version \"foo\"})))\n    (is (not (snapshot? nil)))))\n\n(deftest test-managed-dependencies\n  (doseq [proj [managed-deps-snapshot-project\n                managed-deps-project]]\n    (let [xml (parse-xml\n               (make-pom proj))]\n      (testing \"normal dependencies are written to pom properly\"\n        (is (= [\"org.clojure\" \"rome\" \"ring\" \"ring\" \"ring\" \"commons-codec\"\n                \"commons-math\" \"org.apache.commons\" \"org.clojure\" \"org.clojure\"]\n               (map #(first-in % [::pom/dependency ::pom/groupId])\n                    (deep-content xml [::pom/project ::pom/dependencies]))))\n        (is (= [\"clojure\" \"rome\" \"ring\" \"ring-codec\" \"ring-headers\"\n                \"commons-codec\" \"commons-math\" \"commons-csv\"\n                \"tools.emitter.jvm\" \"tools.namespace\"]\n               (map #(first-in % [::pom/dependency ::pom/artifactId])\n                    (deep-content xml [::pom/project ::pom/dependencies]))))\n        (is (= [nil nil nil nil nil \"1.6\" nil nil \"0.1.0-beta5\" \"0.3.0-alpha3\"]\n               (map #(first-in % [::pom/dependency ::pom/version])\n                    (deep-content xml [::pom/project ::pom/dependencies])))))\n      (testing \"managed dependencies are written to pom properly\"\n        (is (= [\"org.clojure\" \"rome\" \"ring\" \"ring\" \"ring\" \"commons-math\"\n                \"org.apache.commons\" \"ring\" \"org.clojure\"]\n               (map #(first-in % [::pom/dependency ::pom/groupId])\n                    (deep-content xml [::pom/project ::pom/dependencyManagement ::pom/dependencies]))))\n        (is (= [\"clojure\" \"rome\" \"ring\" \"ring-codec\" \"ring-headers\"\n                \"commons-math\" \"commons-csv\" \"ring-defaults\" \"tools.reader\"]\n               (map #(first-in % [::pom/dependency ::pom/artifactId])\n                    (deep-content xml [::pom/project ::pom/dependencyManagement ::pom/dependencies]))))\n        (is (= [\"1.3.0\" \"0.9\" \"1.0.0\" \"1.0.1\" \"0.2.0\" \"1.2\" \"1.4\" \"0.2.1\" \"1.0.0-beta3\"]\n               (map #(first-in % [::pom/dependency ::pom/version])\n                    (deep-content xml [::pom/project ::pom/dependencyManagement ::pom/dependencies]))))\n        (is (= [nil nil nil nil nil \"sources\" \"sources\" nil nil]\n               (map #(first-in % [::pom/dependency ::pom/classifier])\n                    (deep-content xml [::pom/project ::pom/dependencyManagement ::pom/dependencies]))))))))\n\n(deftest test-pom-plugins\n  (let [xml              (parse-xml (make-pom with-pom-plugins-project))\n        plugins          (deep-content xml [::pom/project ::pom/build ::pom/plugins])\n        get-plugin       (fn [re]\n                           (first (filter #(re-find re (pr-str %)) plugins)))\n        simple-plugin    (get-plugin #\"simple-plugin\")\n        plugin-with-vec  (get-plugin #\"with-vec\")\n        plugin-with-map  (get-plugin #\"with-map\")\n        plugin-with-list (get-plugin #\"with-list\")]\n    (testing \"two-parameter version adds maven plugin\"\n      (is (= simple-plugin\n             (xml/sexp-as-element\n               [::pom/plugin\n                [::pom/groupId \"two.parameter\"]\n                [::pom/artifactId \"simple-plugin\"]\n                [::pom/version \"1.0.0\"]]))))\n    (testing \"vector as third parameter is interpreted as a mapping\"\n      (is (= plugin-with-vec\n             (xml/sexp-as-element\n               [::pom/plugin\n                [::pom/groupId \"three.parameter\"]\n                [::pom/artifactId \"with-vec\"]\n                [::pom/version \"1.0.1\"]\n                [::pom/a 3]]))))\n    (testing \"hashmap as third parameter is converted to tags\"\n      (is (= plugin-with-map\n             (xml/sexp-as-element\n               [::pom/plugin\n                [::pom/groupId \"three.parameter\"]\n                [::pom/artifactId \"with-map\"]\n                [::pom/version \"1.0.2\"]\n                [::pom/a 1]\n                [::pom/b 2]\n                [::pom/c 3]]))))\n    (testing \"list as third parameter keeps structure\"\n      (is (= plugin-with-list\n             (xml/sexp-as-element\n               [::pom/plugin\n                [::pom/groupId \"three.parameter\"]\n                [::pom/artifactId \"with-list\"]\n                [::pom/version \"1.0.3\"]\n                [::pom/root\n                 [::pom/a 1]\n                 [::pom/b\n                  [::pom/c 2]\n                  [::pom/d 3]]]]))))))\n\n(deftest composite-dev-profile-sets-scope\n  (let [xml (binding [main/*info* false]\n              (parse-xml (make-pom leaky-composite-project)))\n        scopes (map #(first-in % [::pom/dependency ::pom/scope])\n                    (deep-content xml [::pom/project\n                                       ::pom/dependencies]))]\n    (is (= [nil \"test\" \"test\"] scopes))))\n"
  },
  {
    "path": "test/leiningen/test/release.clj",
    "content": "(ns leiningen.test.release\n  (:require [clojure.test :refer :all]\n            [clojure.pprint :as pprint]\n            [leiningen.release :refer :all]))\n\n(def invalid-semver-version-values\n  [[\"1.0\" \"1.0\"]\n    [\"derpin\" \"derpin\"]])\n\n(def valid-semver-version-values\n  [[\"1.0.0\"\n   {:major 1\n    :minor 0\n    :patch 0\n    :qualifier nil\n    :snapshot nil}\n   {:major \"2.0.0-SNAPSHOT\"\n    :minor \"1.1.0-SNAPSHOT\"\n    :patch \"1.0.1-SNAPSHOT\"\n    :release \"1.0.0\"\n    :alpha \"1.0.0-alpha1-SNAPSHOT\"\n    :beta \"1.0.0-beta1-SNAPSHOT\"\n    :rc \"1.0.0-RC1-SNAPSHOT\"\n    :qualifier \"1.0.0-1-SNAPSHOT\"}]\n\n   [\"1.2.3\"\n   {:major 1\n    :minor 2\n    :patch 3\n    :qualifier nil\n    :snapshot nil}\n   {:major \"2.0.0-SNAPSHOT\"\n    :minor \"1.3.0-SNAPSHOT\"\n    :patch \"1.2.4-SNAPSHOT\"\n    :release \"1.2.3\"\n    :alpha \"1.2.3-alpha1-SNAPSHOT\"\n    :beta \"1.2.3-beta1-SNAPSHOT\"\n    :rc \"1.2.3-RC1-SNAPSHOT\"\n    :qualifier \"1.2.3-1-SNAPSHOT\"}]\n\n   [\"1.2.3-herp\"\n   {:major 1\n    :minor 2\n    :patch 3\n    :qualifier \"herp\"\n    :snapshot nil}\n   {:major \"2.0.0-SNAPSHOT\"\n    :minor \"1.3.0-SNAPSHOT\"\n    :patch \"1.2.4-SNAPSHOT\"\n    :release \"1.2.3\"\n    :alpha \"1.2.3-alpha1-SNAPSHOT\"\n    :beta \"1.2.3-beta1-SNAPSHOT\"\n    :rc \"1.2.3-RC1-SNAPSHOT\"\n    :qualifier \"1.2.3-herp1-SNAPSHOT\"}]\n\n   [\"1.0.0-SNAPSHOT\"\n   {:major 1\n    :minor 0\n    :patch 0\n    :qualifier nil\n    :snapshot \"SNAPSHOT\"}\n   {:major \"2.0.0-SNAPSHOT\"\n    :minor \"1.1.0-SNAPSHOT\"\n    :patch \"1.0.1-SNAPSHOT\"\n    :release \"1.0.0\"\n    :alpha \"1.0.0-alpha1-SNAPSHOT\"\n    :beta \"1.0.0-beta1-SNAPSHOT\"\n    :rc \"1.0.0-RC1-SNAPSHOT\"\n    :qualifier \"1.0.0-1-SNAPSHOT\"}]\n\n   [\"1.0.0-alpha1\"\n   {:major 1\n    :minor 0\n    :patch 0\n    :qualifier \"alpha1\"\n    :snapshot nil}\n   {:major \"2.0.0-SNAPSHOT\"\n    :minor \"1.1.0-SNAPSHOT\"\n    :patch \"1.0.1-SNAPSHOT\"\n    :release \"1.0.0\"\n    :alpha \"1.0.0-alpha2-SNAPSHOT\"\n    :beta \"1.0.0-beta1-SNAPSHOT\"\n    :rc \"1.0.0-RC1-SNAPSHOT\"\n    :qualifier \"1.0.0-alpha2-SNAPSHOT\"}]\n\n   [\"1.0.0-alpha1-SNAPSHOT\"\n    {:major 1\n     :minor 0\n     :patch 0\n     :qualifier \"alpha1\"\n     :snapshot \"SNAPSHOT\"}\n    {:major \"2.0.0-SNAPSHOT\"\n     :minor \"1.1.0-SNAPSHOT\"\n     :patch \"1.0.1-SNAPSHOT\"\n     :release \"1.0.0-alpha1\"\n     :alpha \"1.0.0-alpha2-SNAPSHOT\"\n     :beta \"1.0.0-beta1-SNAPSHOT\"\n     :rc \"1.0.0-RC1-SNAPSHOT\"\n     :qualifier \"1.0.0-alpha2-SNAPSHOT\"}]\n\n   [\"1.0.0-beta1\"\n    {:major 1\n     :minor 0\n     :patch 0\n     :qualifier \"beta1\"\n     :snapshot nil}\n    {:major \"2.0.0-SNAPSHOT\"\n     :minor \"1.1.0-SNAPSHOT\"\n     :patch \"1.0.1-SNAPSHOT\"\n     :release \"1.0.0\"\n     :alpha \"1.0.0-alpha1-SNAPSHOT\"\n     :beta \"1.0.0-beta2-SNAPSHOT\"\n     :rc \"1.0.0-RC1-SNAPSHOT\"\n     :qualifier \"1.0.0-beta2-SNAPSHOT\"}]\n\n   [\"1.0.0-RC2-SNAPSHOT\"\n    {:major 1\n     :minor 0\n     :patch 0\n     :qualifier \"RC2\"\n     :snapshot \"SNAPSHOT\"}\n    {:major \"2.0.0-SNAPSHOT\"\n     :minor \"1.1.0-SNAPSHOT\"\n     :patch \"1.0.1-SNAPSHOT\"\n     :release \"1.0.0-RC2\"\n     :alpha \"1.0.0-alpha1-SNAPSHOT\"\n     :beta \"1.0.0-beta1-SNAPSHOT\"\n     :rc \"1.0.0-RC3-SNAPSHOT\"\n     :qualifier \"1.0.0-RC3-SNAPSHOT\"}]\n\n   [\"1.2.3-herp2\"\n    {:major 1\n     :minor 2\n     :patch 3\n     :qualifier \"herp2\"\n     :snapshot nil}\n    {:major \"2.0.0-SNAPSHOT\"\n     :minor \"1.3.0-SNAPSHOT\"\n     :patch \"1.2.4-SNAPSHOT\"\n     :release \"1.2.3\"\n     :alpha \"1.2.3-alpha1-SNAPSHOT\"\n     :beta \"1.2.3-beta1-SNAPSHOT\"\n     :rc \"1.2.3-RC1-SNAPSHOT\"\n     :qualifier \"1.2.3-herp3-SNAPSHOT\"}]\n\n   [\"1.2.3-25\"\n    {:major 1\n     :minor 2\n     :patch 3\n     :qualifier \"25\"\n     :snapshot nil}\n    {:major \"2.0.0-SNAPSHOT\"\n     :minor \"1.3.0-SNAPSHOT\"\n     :patch \"1.2.4-SNAPSHOT\"\n     :release \"1.2.3\"\n     :alpha \"1.2.3-alpha1-SNAPSHOT\"\n     :beta \"1.2.3-beta1-SNAPSHOT\"\n     :rc \"1.2.3-RC1-SNAPSHOT\"\n     :qualifier \"1.2.3-26-SNAPSHOT\"}]])\n\n(deftest test-string->semantic-version\n  (testing \"Testing semantic version string parsing\"\n    (doseq [[args expected] valid-semver-version-values]\n      (testing (format \"with valid version strings: %s\" args)\n        (is (= (string->semantic-version args) expected))))\n\n    (testing \"with invalid version strings.\"\n      (doseq [[semver-test-data] invalid-semver-version-values]\n        (is (nil? (string->semantic-version semver-test-data)))))))\n\n(deftest test-parse-semver-version\n  (testing \"Testing semantic version string parsing\"\n    (doseq [[args expected] valid-semver-version-values]\n      (testing (format \"with valid version strings: %s\" args)\n        (is (= (parse-semantic-version args) expected))))\n\n    (testing \"with invalid version strings.\"\n      (doseq [[semver-test-data] invalid-semver-version-values]\n        (is (thrown-with-msg? Exception #\"Unrecognized version string\"\n                              (binding [leiningen.core.main/*exit-process?* false\n                                        *err* (java.io.StringWriter.)]\n                                (parse-semantic-version semver-test-data))))))))\n\n(deftest version-map->string-valid\n  (doseq [[string parsed bumps] valid-semver-version-values]\n    (is (= string (version-map->string parsed)))\n    (doseq [[level expected-bumped-string] bumps]\n      (let [bumped (bump-version-map parsed level)]\n        (is (= bumped (parse-semantic-version expected-bumped-string)))\n        (is (= expected-bumped-string (version-map->string bumped)))))))"
  },
  {
    "path": "test/leiningen/test/repl.clj",
    "content": "(ns leiningen.test.repl\n  (:require [clojure.java.io :as io]\n            [clojure.test :refer :all]\n            [leiningen.repl :refer :all]\n            [leiningen.test.helper :as helper]\n            [leiningen.core.user :as user]\n            [leiningen.core.project :as project]\n            [leiningen.core.main :as main]\n            [leiningen.core.utils :as utils]\n            [nrepl.ack :as ack]\n            [nrepl.core :as nrepl]\n            [nrepl.config])\n  (:import\n   (java.io File)\n   (java.nio.file Files)))\n\n(deftest test-merge-repl-profile\n  (is (= (-> {:repl-options {:ack-port 4}}\n             (with-meta\n               {:without-profiles {:repl-options {:ack-port 3}}\n                :profiles {:repl {:repl-options {:ack-port 2}}\n                           :user {:repl-options {:ack-port 1}}}\n                :active-profiles [:default]})\n             (project/merge-profiles [:repl])\n             :repl-options :ack-port)\n         2)))\n\n(deftest test-opt-host\n  (are [in exp] (= exp (opt-host in))\n       [\":host\" \"0.0.0.0\"]        \"0.0.0.0\"\n       [\":host\" \"1.1.1.1\"]        \"1.1.1.1\"\n       [\":foo\" \":host\" \"0.0.0.0\"] \"0.0.0.0\"\n       [\":host\" \"0.0.0.0\" \":foo\"] \"0.0.0.0\"\n       [\"0.0.0.0\"]                nil\n       [\":host\"]                  nil\n       [\":port\" \"0.0.0.0\"]        nil\n       []                         nil\n       nil                        nil))\n\n(deftest test-opt-port\n  (are [in exp] (= exp (opt-port in))\n       [\":port\" \"1\"]        1\n       [\":foo\" \":port\" \"1\"] 1\n       [\":port\" \"1\" \":foo\"] 1\n       [\"1\"]                nil\n       []                   nil))\n\n(deftest test-ack-port\n  (let [env \"5\"\n        prj {:repl-options {:ack-port 4}}]\n    (are [env proj exp]\n         (= exp (with-redefs [user/getenv {\"LEIN_REPL_ACK_PORT\" env}]\n                  (ack-port proj)))\n         env prj 5\n         nil prj 4\n         nil nil nil)))\n\n(deftest test-configured-repl-connection\n  (let [vhost \"LEIN_REPL_HOST\"\n        vport \"LEIN_REPL_PORT\"\n        vsock \"LEIN_REPL_SOCKET\"]\n    (are [context exp]\n        (= exp (let [[opts env proj nrepl] context]\n                 (with-redefs [nrepl.config/config (or nrepl {})\n                               user/getenv (or env {})]\n                   (configured-repl-connection proj opts))))\n\n        [nil nil nil nil]\n        {:host \"127.0.0.1\" :port 0}\n\n        ;; port precedence\n        [[\":port\" \"1\"] {vport \"2\"} {:repl-options {:port 3}} {:port 4}]\n        {:host \"127.0.0.1\" :port 1}\n        [nil {vport \"2\"} {:repl-options {:port 3}} {:port 4}]\n        {:host \"127.0.0.1\" :port 2}\n        [nil nil {:repl-options {:port 3}} {:port 4}]\n        {:host \"127.0.0.1\" :port 3}\n        [nil nil nil {:port 4}]\n        {:host \"127.0.0.1\" :port 4}\n\n        ;; host precedence\n        [[\":host\" \"opt\"] {vhost \"env\"} {:repl-options {:host \"proj\"}} {:host \"nrepl\"}]\n        {:host \"opt\" :port 0}\n        [nil {vhost \"env\"} {:repl-options {:host \"proj\"}} {:host \"nrepl\"}]\n        {:host \"env\" :port 0}\n        [nil nil {:repl-options {:host \"proj\"}} {:host \"nrepl\"}]\n        {:host \"proj\" :port 0}\n        [nil nil nil {:host \"nrepl\"}]\n        {:host \"nrepl\" :port 0}\n        [nil nil nil {:bind \"nrepl\"}]\n        {:host \"nrepl\" :port 0}\n        ;; REVIEW: appropriate to allow duplicates?\n        [nil nil nil {:host \"host\" :bind \"bind\"}]\n        {:host \"host\" :port 0}\n\n        ;; socket precedence\n        [[\":socket\" \"opt\"] {vsock \"env\"} {:repl-options {:socket \"proj\"}} {:socket \"nrepl\"}]\n        {:socket \"opt\"}\n        [nil {vsock \"env\"} {:repl-options {:socket \"proj\"}} {:socket \"nrepl\"}]\n        {:socket \"env\"}\n        [nil nil {:repl-options {:socket \"proj\"}} {:socket \"nrepl\"}]\n        {:socket \"proj\"}\n        [nil nil nil {:socket \"nrepl\"}]\n        {:socket \"nrepl\"})))\n\n(defmacro with-captured-abort [& body]\n  `(let [args# (atom nil)]\n     (with-redefs [main/abort #(reset! args# %&)]\n       (do ~@body)\n       (let [result# @args#]\n         (when-not (seq result#)\n           (throw (ex-info \"Expected abort, none found\" {})))\n         @args#))))\n\n(deftest test-configured-repl-connection-errors\n  (testing \"conflicting arguments\"\n    (is (= [\":socket argument conflicts with :host and :port\"]\n           (with-captured-abort\n             (configured-repl-connection nil [\":socket\" \"foo\" \":host\" \"bar\"]))))\n    (is (= [\":socket argument conflicts with :host and :port\"]\n           (with-captured-abort\n             (configured-repl-connection nil [\":socket\" \"foo\" \":port\" \"bar\"])))))\n  (testing \"conflicting environment vars\"\n    (is (= [\"LEIN_REPL_HOST conflicts with LEIN_REPL_HOST and LEIN_REPL_PORT\"]\n           (with-captured-abort\n             (with-redefs [user/getenv {\"LEIN_REPL_SOCKET\" \"foo\" \"LEIN_REPL_HOST\" \"bar\"}]\n               (configured-repl-connection nil nil)))))\n    (is (= [\"LEIN_REPL_HOST conflicts with LEIN_REPL_HOST and LEIN_REPL_PORT\"]\n           (with-captured-abort\n             (with-redefs [user/getenv {\"LEIN_REPL_SOCKET\" \"foo\" \"LEIN_REPL_PORT\" \"1\"}]\n               (configured-repl-connection nil nil))))))\n  (testing \"conflicting project settings\"\n    (is (= [\"project :repl-options :socket conflicts with :host and :port\"]\n           (with-captured-abort\n             (configured-repl-connection {:repl-options {:socket \"foo\" :host \"bar\"}} nil))))\n    (is (= [\"project :repl-options :socket conflicts with :host and :port\"]\n           (with-captured-abort\n             (configured-repl-connection {:repl-options {:socket \"foo\" :port \"bar\"}} nil)))))\n  (testing \"conflicticting nrepl settings\"\n    (is (= [\"nREPL config :socket conflicts with :bind, :host, and :port\"]\n           (with-captured-abort\n             (with-redefs [nrepl.config/config {:socket \"foo\" :bind \"bar\"}]\n               (configured-repl-connection nil nil)))))\n    (is (= [\"nREPL config :socket conflicts with :bind, :host, and :port\"]\n           (with-captured-abort\n             (with-redefs [nrepl.config/config {:socket \"foo\" :host \"bar\"}]\n               (configured-repl-connection nil nil)))))\n    (is (= [\"nREPL config :socket conflicts with :bind, :host, and :port\"]\n           (with-captured-abort\n             (with-redefs [nrepl.config/config {:socket \"foo\" :port \"bar\"}]\n               (configured-repl-connection nil nil)))))))\n\n(deftest test-is-uri\n  (is (= true  (is-uri? \"http://example.org\")))\n  (is (= true  (is-uri? \"https://example.org\")))\n  (is (= true  (is-uri? \"http://example.org:20/repl\")))\n  (is (= true  (is-uri? \"https://example.org:20/repl\")))\n  (is (= false (is-uri? \"\")))\n  (is (= false (is-uri? \"7\")))\n  (is (= false (is-uri? \"myhost:9\")))\n  (is (= false (is-uri? \"localhost:20\")))\n  (is (= false (is-uri? \"localhost:\"))))\n\n(deftest test-connect-string\n  (are [in exp]\n      (= exp (with-redefs [configured-repl-connection (constantly {:host \"repl-host\"\n                                                                   :port 5})]\n                (connect-string {} [in])))\n       \"\"                         \"repl-host:5\"\n       \"7\"                        \"repl-host:7\"\n       \"myhost:9\"                 \"myhost:9\"\n       \"http://localhost\"         \"http://localhost\"\n       \"http://localhost/ham\"     \"http://localhost/ham\"\n       \"http://localhost:20\"      \"http://localhost:20\"\n       \"http://localhost:20/ham\"  \"http://localhost:20/ham\"\n       \"https://localhost\"        \"https://localhost\"\n       \"https://localhost/ham\"    \"https://localhost/ham\"\n       \"https://localhost:20\"     \"https://localhost:20\"\n       \"https://localhost:20/ham\" \"https://localhost:20/ham\")\n  (with-redefs [configured-repl-connection (constantly {:host \"repl-host\"\n                                                        :port 0})]\n    (is (= \"repl-host:1\" (connect-string {} [\"1\"])))\n    (is (= \"repl-host:123\" (connect-string {} [\"123\"])))\n    (are [in proj]\n         (is (re-find\n              #\"Port is required\"\n              (helper/abort-msg connect-string proj in)))\n         [\"foo1234\"]               {:root \"/tmp\"}\n         []                        {:root \"/tmp\"}\n         []                        helper/with-resources-project)\n    (are [in proj]\n         (is (re-find\n              #\"The file '.+' can't be read.\"\n              (helper/abort-msg connect-string proj in)))\n         [\"@/tmp/please-do-not-create-this-file-it-will-break-my-test\"] {}))\n  (is (= \"myhost:23\" (connect-string helper/sample-project [\"@test/sample-connect-string\"])))\n  (is (= \"http://localhost:23/repl\" (connect-string helper/sample-project [\"@test/sample-connect-string-http\"])))\n\n  (is (= \"127.0.0.1:4242\" (connect-string helper/sample-project [])))\n  (is (= \"127.0.0.1:4343\" (connect-string helper/sample-project [\"4343\"])))\n  (is (= \"127.0.0.1:4242\" (connect-string helper/with-resources-project [\"4242\"]))))\n\n(deftest test-options-for-reply\n  (is (= (helper/fix-path-delimiters \"/home/user/.lein-repl-history\")\n         (:history-file (options-for-reply {:root \"/home/user\"}))))\n  (let [prompt-fn (fn [ns] \"hi \")]\n    (are\n     [in exp]\n     (= (merge\n         {:history-file (helper/pathify\n                          (str (user/leiningen-home) \"/repl-history\"))\n          :custom-help (list 'println (slurp (clojure.java.io/resource\n                                               \"repl-welcome\")))\n          :input-stream System/in}\n         exp)\n        (let [[prj-k prj-v arg-k arg-v] in]\n          (apply options-for-reply\n                 {:repl-options (into {} (and prj-k {prj-k prj-v}))}\n                 (into [] (and arg-k [arg-k arg-v])))))\n     [:standalone true]              {:standalone true}\n     [:prompt prompt-fn]             {:custom-prompt prompt-fn}\n     [:host \"prj-host\"]              {:host \"prj-host\"}\n     [:host \"prj-host\" :port 1]      {:host \"prj-host\" :port \"1\"}\n     [nil nil :port 1]               {:port \"1\"}\n     [:port 2]                       {:port \"2\"}\n     [:port 2 :port 1]               {:port \"1\"}\n     [:host \"prj-host\" :attach \"xy\"] {:attach \"xy\"}\n     [:port 3 :attach \"xy\"]          {:attach \"xy\"}\n     [:attach \"xy\" :scheme \"nrepl\"]  {:attach \"xy\" :scheme \"nrepl\"}\n     [:scheme \"nrepl+edn\"]           {:scheme \"nrepl+edn\"})))\n\n(deftest test-init-ns\n  (let [main {:main 'some.ns/main}\n        repl-opts (merge main {:repl-options {:init-ns 'init-ns}})]\n    (are [in exp] (= exp (init-ns in))\n         main 'some.ns\n         repl-opts 'init-ns)))\n\n(defn- mocked-repl [& args]\n  (with-redefs [ack/wait-for-ack (constantly 9999)\n                resolve-reply-launch-nrepl (constantly identity)]\n    (binding [main/*info* false]\n      (apply repl args))))\n\n(deftest test-scheme\n  (let [project helper/sample-ordered-aot-project]\n    (is (= {:attach \"9999\" :scheme \"nrepl\"}\n           (-> (mocked-repl project)\n               (select-keys [:attach :scheme]))))\n    (is (= {:attach \"9999\" :scheme \"nrepl\"}\n           (-> (mocked-repl project \":start\"\n                            \":transport\" 'nrepl.transport/bencode)\n               (select-keys [:attach :scheme]))))\n    (is (= {:attach \"9999\" :scheme \"nrepl+edn\"}\n           (-> (mocked-repl project \":start\"\n                            \":transport\" 'nrepl.transport/edn)\n               (select-keys [:attach :scheme]))))))\n\n(deftest ^:disabled test-headless-socket\n  (let [tmpdir (utils/create-tmpdir (-> \"target\" File. .getAbsoluteFile)\n                                    \"socket-test-\" \"rwx------\")\n        sock-path (str tmpdir \"/socket\")\n        sock-file (io/as-file sock-path)]\n    (try\n      (let [server (future (repl helper/sample-ordered-aot-project\n                                 \":headless\" \":socket\" sock-path))]\n        (while (not (.exists sock-file))\n          (Thread/sleep 100))\n        (is (= [42] (with-open [conn (nrepl/connect :socket sock-path)]\n                      (-> (nrepl/client conn 3000)\n                          (nrepl/message {:op \"eval\" :code \"(+ 21 21)\"})\n                          nrepl/response-values)))))\n      (finally\n        (.delete sock-file)\n        (Files/delete tmpdir)))))\n"
  },
  {
    "path": "test/leiningen/test/run.clj",
    "content": "(ns leiningen.test.run\n  (:require [leiningen.core.project :as project]\n            [leiningen.javac]\n            [clojure.java.io :as io]\n            [leiningen.test.helper :as helper\n             :refer [bad-require-project tmp-dir tricky-name-project\n                     java-main-project file-not-found-thrower-project\n                     with-system-out-str with-system-err-str\n                     preserve-eval-meta-project]]\n            [clojure.test :refer :all]\n            [leiningen.run :refer :all]))\n\n(def out-file (format \"%s/lein-test\" tmp-dir))\n\n(deftest test-arg-map\n  (let [parse-args #'leiningen.run/parse-args]\n    (is (= (:main (parse-args [\"-m\" \"my-main\"]))\n           \"my-main\"))\n    (is (= ((juxt :main :args) (parse-args [\"-m\" \"my-main\" \"-m\" \"foo\"]))\n           [\"my-main\" [\"-m\" \"foo\"]]))\n    (is (= (:arg-conversion (parse-args [\"-m\" \"my-main\"]))\n           :stringify))\n    (is (= (:arg-conversion (parse-args [\"-m\" \"my-main\" \"--quote-args\"]))\n           :quote))\n    (is (= (:arg-conversion (parse-args [\"--quote-args\" \"-m\" \"my-main\"]))\n           :quote))\n    (is (= (:args (parse-args [\"--\" \"--quote-args\" \"-m\" \"my-main\"]))\n           [\"--quote-args\" \"-m\" \"my-main\"]))\n    (is (= (:args (parse-args [\"--\" \"--\" \"-m\" \"my-main\"]))\n           [\"--\" \"-m\" \"my-main\"]))))\n\n(use-fixtures :each (fn [f]\n                      (f)\n                      (io/delete-file out-file :silently)))\n\n(deftest test-basic\n  (run tricky-name-project \"/unreadable\")\n  (is (= \"nom:/unreadable\" (slurp out-file))))\n\n(deftest test-alt-main\n  (run tricky-name-project \"-m\" \"org.domain.tricky-name.munch\" \"/unreadable\")\n  (is (= \":munched (\\\"/unreadable\\\")\" (slurp out-file))))\n\n(deftest test-valid-namespace-argument\n  (is (re-find #\"Option -m requires a valid namespace argument, not -1\\.\"\n               (helper/abort-msg run tricky-name-project \"-m\" \"-1\"))))\n\n(deftest test-nonexistant-ns-error-message\n  (is (re-find #\"Can't find 'nonexistant.ns' as \\.class or \\.clj for lein run\"\n               (with-system-err-str\n                 (try (run tricky-name-project \"-m\" \"nonexistant.ns\")\n                      (catch Exception _))))))\n\n(deftest test-escape-args\n  (run tricky-name-project \"--\" \":bbb\")\n  (is (= \"nom::bbb\" (slurp out-file)))\n  (run tricky-name-project \"--\" \"-m\")\n  (is (= \"nom:-m\" (slurp out-file))))\n\n(deftest test-bad-require-error-msg\n  (let [e-msg (with-system-err-str\n                (try (run bad-require-project)\n                     (catch clojure.lang.ExceptionInfo e nil)))]\n    ;; Don't throw the old ClassNotFoundException\n    (is (not (re-find #\"ClassNotFoundException: bad-require.core\" e-msg)))\n    ;; Do show a relevant error message\n    (is (re-find #\"FileNotFoundException\" e-msg))\n    (is (re-find #\"this/namespace/does/not/exist.clj\" e-msg))))\n\n(deftest test-run-java-main\n  (leiningen.javac/javac java-main-project)\n  (let [out-result (with-system-out-str (run java-main-project))]\n    (is (= (.trim out-result) ;; To avoid os-specific newline handling\n            \"Hello from Java!\"))))\n\n;; Regression test for https://github.com/technomancy/leiningen/issues/1469\n(deftest file-not-found-exception-test\n  (let [s (with-system-err-str\n            (try (run file-not-found-thrower-project\n                   \"-m\" \"file-not-found-thrower.core\")\n                 (catch clojure.lang.ExceptionInfo e nil)))]\n    ;; testing that the true exception is printed immediately and\n    ;; the inappropriate error message \"Can't find\n    ;; 'file-not-found-thrower.core' as .class or .clj for lein run:\n    ;; please check the spelling.\" is not\n    (is (.contains s \"Exception in thread \\\"main\\\" java.io.FileNotFoundException\"))))\n\n(deftest test-preserve-eval-meta\n  ;; By default, metadata (including type hints) is not preserved when dumping the code\n  ;; to be evaluated in the project. That's the case because some plugins include objects\n  ;; with metadata that can't be read (i.e. #object tags, referring to functions or vars).\n  ;; See https://github.com/technomancy/leiningen/issues/2814\n  (let [err (with-system-err-str (run tricky-name-project \"/unreadable\"))]\n    (is (re-find #\"Reflection warning.*call to.*can't be resolved\" err)))\n\n  ;; One consequence of not including type hints in the code to be evaluated is that\n  ;; `lein run` will print a reflection warning in projects with\n  ;; `:global-vars {*warn-on-reflection* true}`, because the code injected to run the\n  ;; main function needs type hints to avoid reflection. Including metadata is available\n  ;; as opt-in, using the :preserve-eval-meta project key. When that is set to true, no\n  ;; reflection warning should happen, but some plugins can't be loaded.\n  ;; See https://github.com/technomancy/leiningen/issues/2695\n  (let [err (with-system-err-str (run preserve-eval-meta-project))]\n    (is (not (re-find #\"Reflection warning.*call to.*can't be resolved\" err)))))\n"
  },
  {
    "path": "test/leiningen/test/search.clj",
    "content": "(ns leiningen.test.search\n  (:import (com.sun.net.httpserver HttpExchange HttpHandler HttpServer)\n           (java.net InetSocketAddress))\n  (:require [clojure.data.xml :as xml]\n            [clojure.string :as str]\n            [clojure.test :refer :all]\n            [leiningen.search :as search]))\n\n;;; Setting up a mock server for querying\n\n(def server (atom nil))\n\n(defn start-server! [^InetSocketAddress sock]\n  (let [mock-element  (xml/element \"error\"\n                                   {:message \"Invalid search syntax query\"\n                                    :id \"24c1c717-98dd-4312-9fa8-8d63dab5ce74\"})\n        mock-error    (xml/emit-str mock-element)\n        handle-search (reify HttpHandler\n                        (^void handle [this ^HttpExchange exchange]\n                         (with-open [response (.getResponseBody exchange)]\n                           (.sendResponseHeaders exchange 400 (count mock-error))\n                           (.write response (.getBytes ^String mock-error)))))]\n    (reset! server (doto (HttpServer/create sock 0)\n                     (.createContext \"/search\" handle-search)\n                     (.start)))))\n\n(defn stop-server! []\n  (.stop ^HttpServer @server 0)\n  (reset! server nil))\n\n;;; Actual testing code\n\n(use-fixtures :once\n  (fn [f]\n    (let [sock (InetSocketAddress. 50000)]\n      (start-server! sock)\n      (f)\n      (stop-server!))))\n\n(deftest parse-error-handling\n  (testing \"parse reports helpful errors\"\n    (let [url    \"http://localhost:50000/search?q=foobar\"\n          result (with-out-str\n                   ;; direct stderr to stdout so we can get a string and\n                   ;; inspect it\n                   (binding [*err* *out*]\n                     (search/parse url)))]\n      (is (str/includes? result \"syntax unsupported\")))))\n"
  },
  {
    "path": "test/leiningen/test/static_classpath.clj",
    "content": "(ns leiningen.test.static-classpath\n  (:require [clojure.test :refer :all]\n            [clojure.string :as str]\n            [leiningen.core.main :as main]\n            [leiningen.test.helper :as helper])\n  (:import (java.io File)))\n\n(defn- relativize [paths-str root]\n  (for [path (str/split paths-str #\":\")]\n    (-> path\n        (str/replace root \"\")\n        (str/replace (System/getenv \"HOME\") \"~\")\n        (str/replace \"~/.m2/repository/\" \"$REPO/\"))))\n\n(deftest test-static-classpath\n  (let [tmp (File/createTempFile \"lein\" \"static-cp\")\n        {:keys [root]} helper/leaky-composite-project]\n    (try\n      ;; static protections will wipe out these things; with-redefs can restore\n      ;; them back to their root values for us\n      (with-redefs [*read-eval* false\n                    eval eval\n                    load-file load-file]\n        (try (binding [main/*cwd* root]\n               (main/-main \"static-classpath\" (str tmp)))\n             (catch Exception e\n               ;; suppressed exit\n               (is (zero? (:exit-code (ex-data e)))))))\n      (is (= #{\"$REPO/clj-stacktrace/clj-stacktrace/0.2.8/clj-stacktrace-0.2.8.jar\"\n               \"$REPO/commons-codec/commons-codec/1.11/commons-codec-1.11.jar\"\n               \"$REPO/commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4.jar\"\n               \"$REPO/commons-io/commons-io/2.6/commons-io-2.6.jar\"\n               \"$REPO/crypto-equality/crypto-equality/1.0.0/crypto-equality-1.0.0.jar\"\n               \"$REPO/crypto-random/crypto-random/1.2.0/crypto-random-1.2.0.jar\"\n               \"$REPO/hiccup/hiccup/1.0.5/hiccup-1.0.5.jar\"\n               \"$REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar\"\n               \"$REPO/nrepl/nrepl/1.0.0/nrepl-1.0.0.jar\"\n               \"$REPO/ns-tracker/ns-tracker/0.4.0/ns-tracker-0.4.0.jar\"\n               \"$REPO/org/clojure/clojure/1.10.1/clojure-1.10.1.jar\"\n               \"$REPO/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar\"\n               \"$REPO/org/clojure/java.classpath/0.3.0/java.classpath-0.3.0.jar\"\n               \"$REPO/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar\"\n               \"$REPO/org/clojure/tools.namespace/0.2.11/tools.namespace-0.2.11.jar\"\n               \"$REPO/org/eclipse/jetty/jetty-http/9.4.31.v20200723/jetty-http-9.4.31.v20200723.jar\"\n               \"$REPO/org/eclipse/jetty/jetty-io/9.4.31.v20200723/jetty-io-9.4.31.v20200723.jar\"\n               \"$REPO/org/eclipse/jetty/jetty-server/9.4.31.v20200723/jetty-server-9.4.31.v20200723.jar\"\n               \"$REPO/org/eclipse/jetty/jetty-util/9.4.31.v20200723/jetty-util-9.4.31.v20200723.jar\"\n               \"$REPO/org/nrepl/incomplete/0.1.0/incomplete-0.1.0.jar\"\n               \"$REPO/ring/ring-codec/1.1.2/ring-codec-1.1.2.jar\"\n               \"$REPO/ring/ring-core/1.8.2/ring-core-1.8.2.jar\"\n               \"$REPO/ring/ring-devel/1.8.2/ring-devel-1.8.2.jar\"\n               \"$REPO/ring/ring-jetty-adapter/1.8.2/ring-jetty-adapter-1.8.2.jar\"\n               \"$REPO/ring/ring-servlet/1.8.2/ring-servlet-1.8.2.jar\"\n               \"$REPO/ring/ring/1.8.2/ring-1.8.2.jar\"\n               \"/dev-resources\"\n               \"/src\"\n               \"/target/classes\"\n               \"/test\"}\n             (set (relativize (slurp tmp) root))))\n      (finally\n        (.delete tmp)))))\n"
  },
  {
    "path": "test/leiningen/test/test.clj",
    "content": "(ns leiningen.test.test\n  (:refer-clojure :exclude [test])\n  (:require [clojure.test :refer :all]\n            [leiningen.test :refer :all]\n            [leiningen.test.helper :refer [tmp-dir sample-no-aot-project\n                                           lein-test-exit-code-project\n                                           lein-test-reload-bug-project\n                                           sample-reader-cond-project\n                                           sample-failing-project\n                                           sample-fixture-error-project\n                                           with-system-err-str\n                                           with-system-out-str]]\n            [clojure.java.io :as io]\n            [leiningen.core.main :as main]\n            [leiningen.core.project :as project]))\n\n(use-fixtures :each\n              (fn [f]\n                (f)\n                (.delete (java.io.File. tmp-dir \"lein-test-ran\"))))\n\n(defn runs []\n  (let [ran-file (io/file tmp-dir \"lein-test-ran\")]\n    (and (.exists ran-file)\n         (-> ran-file\n             (slurp)\n             (.split \"\\n\")\n             (->> (map read-string)\n                  (frequencies))))))\n\n(defn ran? [] (-> (runs) keys set))\n\n(deftest test-project-selectors\n  (is (= #{:default :integration :int2 :no-custom}\n         (set (keys (:test-selectors sample-no-aot-project)))))\n  (is (every? ifn? (map eval (vals (:test-selectors sample-no-aot-project))))))\n\n(deftest test-default-selector\n  (test sample-no-aot-project \":default\")\n  (is (= (ran?) #{:regular :int2 :not-custom :fixture})))\n\n(deftest fixture-runs-appropriate-number-of-times\n  ;; Issue #1269\n  (test sample-no-aot-project)\n  ;; Because three tests ran\n  (is (= 3 ((runs) :fixture))))\n\n(deftest test-no-args-defaults-to-default-selector\n  (test sample-no-aot-project)\n  (is (= (ran?) #{:regular :int2 :not-custom :fixture})))\n\n(deftest test-basic-selector\n  (test sample-no-aot-project \":integration\")\n  (is (= (ran?) #{:integration :integration-ns :fixture})))\n\n(deftest test-complex-selector\n  (test sample-no-aot-project \":no-custom\")\n  (is (= (ran?) #{:integration :integration-ns :regular :int2 :fixture})))\n\n(deftest test-two-selectors\n  (test sample-no-aot-project \":integration\" \":int2\")\n  (is (= (ran?) #{:integration :integration-ns :int2 :fixture})))\n\n(deftest test-override-namespace-selector\n  (test sample-no-aot-project \":int2\")\n  (is (= (ran?) #{:integration-ns :int2 :fixture})))\n\n(deftest test-only-selector\n  (test sample-no-aot-project \":only\" \"selectors/regular\")\n  (is (= (ran?) #{:regular :fixture})))\n\n(deftest test-namespace-argument\n  (test sample-no-aot-project \"selectors\")\n  (is (= (ran?) #{:regular :not-custom :int2 :fixture})))\n\n(deftest test-reader-conditional-tests\n  (test sample-reader-cond-project)\n  (is (= (ran?) #{:clj-test :cljc-test})))\n\n(deftest test-namespaces-load-in-order\n  ;; Issue #2715\n  (test lein-test-reload-bug-project))\n\n(deftest test-failure-exit-code\n  (is (= 1 (try\n             ;; suppress output; there's a lot of bad-looking stuff here\n             (with-out-str\n               (test lein-test-exit-code-project))\n             (catch clojure.lang.ExceptionInfo e\n               (:exit-code (ex-data e)))))))\n\n(deftest test-invalid-namespace-argument\n  (is (.contains\n       (with-system-err-str\n         (try\n           (test sample-no-aot-project \"boom\")\n           (catch clojure.lang.ExceptionInfo e\n             (when-not (:exit-code (ex-data e))\n               (throw e)))))\n       \"java.io.FileNotFoundException: Could not locate\")))\n\n(deftest test-file-argument\n  (let [file (io/file (first (:test-paths sample-no-aot-project)) \"selectors.clj\")]\n    (test sample-no-aot-project (.getPath file)))\n  (is (= (ran?) #{:regular :not-custom :int2 :fixture})))\n\n(deftest test-unreadable-test-fails\n  (let [project (project/merge-profiles sample-failing-project\n                                        [{:aot ^:replace []\n                                          :dependencies ^:replace\n                                          [['org.clojure/clojure (clojure-version)]]}])]\n    (binding [main/*exit-process?* false]\n      (is (= \"EOF while reading\" (try (test project) false\n                                      (catch Exception e\n                                        (.getMessage e))))))))\n\n(deftest test-catch-fixture-errors\n  (with-system-out-str\n    (test sample-fixture-error-project))\n  (is (= (ran?) #{:test-a :test-c})))\n"
  },
  {
    "path": "test/leiningen/test/uberjar.clj",
    "content": "(ns leiningen.test.uberjar\n  (:require [leiningen.uberjar :refer :all]\n            [clojure.test :refer :all]\n            [clojure.java.io :as io]\n            [clojure.java.shell :refer [sh]]\n            [clojure.xml :as xml]\n            [leiningen.test.helper :refer [unmemoize\n                                           sample-no-aot-project\n                                           uberjar-merging-project\n                                           data-readers-backwards-compatibility-project\n                                           provided-project\n                                           managed-deps-project\n                                           managed-deps-snapshot-project] :as h])\n  (:import (java.io File FileOutputStream)\n           (java.util.zip ZipFile)))\n\n(deftest test-uberjar\n  (let [project (h/read-test-project \"sample-no-aot\")\n        _ (with-out-str\n            (uberjar sample-no-aot-project))\n        filename (str \"test_projects/sample-no-aot/target/\"\n                      \"nomnomnom-0.5.0-SNAPSHOT-standalone.jar\")\n        uberjar-file (File. filename)]\n    (is (= true (.exists uberjar-file)))\n    (when (.exists uberjar-file)\n      (let [entries (->> (ZipFile. uberjar-file)\n                         .entries\n                         enumeration-seq\n                         (map (memfn getName))\n                         set)]\n        (.deleteOnExit uberjar-file)\n        (is (entries \"nom/nom/nom.clj\"))\n        (is (entries \"org/codehaus/janino/Compiler$1.class\"))\n        (is (not (entries \"dev.clj\")))\n        (is (not (entries \"module-info.class\")))))))\n\n(deftest test-uberjar-merge-with\n  (with-out-str\n    (uberjar uberjar-merging-project))\n  (let [filename (str \"test_projects/uberjar-merging/target/\"\n                      \"nomnomnom-0.5.0-SNAPSHOT-standalone.jar\")\n        uberjar-file (File. filename)]\n    (is (= true (.exists uberjar-file)))\n    (when (.exists uberjar-file)\n      (.deleteOnExit uberjar-file)\n      (with-open [zf (ZipFile. uberjar-file)]\n        (is (= '{nomnomnom/identity clojure.core/identity\n                 mf/i nomnomnom/override\n                 mf/s method.fn/static\n                 ordered/set flatland.ordered.set/into-ordered-set\n                 ordered/map flatland.ordered.map/ordered-map}\n               (->> (.getEntry zf \"data_readers.clj\")\n                    (.getInputStream zf)\n                    slurp read-string)))))))\n\n(deftest test-uberjar-data-readers-backwards-compatibility\n  (with-out-str\n    (uberjar data-readers-backwards-compatibility-project))\n  (let [filename (str \"test_projects/data-readers-backwards-compatibility/\"\n                      \"target/bug-bug-standalone.jar\")\n        uberjar-file (File. filename)]\n    (is (= true (.exists uberjar-file)))\n    (when (.exists uberjar-file)\n      (.deleteOnExit uberjar-file)\n      (with-open [zf (ZipFile. uberjar-file)]\n        (let [contents (->> (.getEntry zf \"data_readers.clj\")\n                            (.getInputStream zf)\n                            slurp)]\n          (is (.startsWith contents \"{\")) ;; not a namespaced map\n          (is (= '{ordered/set flatland.ordered.set/into-ordered-set\n                   ordered/map flatland.ordered.map/ordered-map}\n                 (read-string contents))))))))\n\n(deftest test-components-merger\n  (let [file1 (io/input-stream \"test_projects/uberjar-components-merging/components1.xml\")\n        file2 (io/input-stream \"test_projects/uberjar-components-merging/components2.xml\")\n        [read-xml combine write-xml] components-merger\n        combined-xml (combine (read-xml file1) (read-xml file2))\n        expected-xml (xml/parse (io/input-stream\n                                 \"test_projects/uberjar-components-merging/expected-components.xml\")\n                                #'leiningen.uberjar/startparse)\n        result-file \"test_projects/uberjar-components-merging/result-components.xml\"\n        out-file (FileOutputStream. (File. result-file))]\n      (write-xml out-file combined-xml)\n      (is (= expected-xml (xml/parse (io/input-stream result-file)\n                                     #'leiningen.uberjar/startparse)))\n      (io/delete-file result-file true)))\n\n;; TODO: this breaks on Java 6\n(deftest ^:disabled test-uberjar-provided\n  (let [bootclasspath \"-Xbootclasspath/a:leiningen-core/lib/clojure-1.4.0.jar\"\n        filename \"test_projects/provided/target/provided-0-standalone.jar\"]\n    (with-out-str\n      (uberjar provided-project))\n    (is (= 1 (:exit (sh \"java\" \"-jar\" filename))))\n    (is (= 0 (:exit (sh \"java\" bootclasspath \"-jar\" filename))))))\n\n(deftest test-uberjar-managed-dependencies\n  (unmemoize #'leiningen.core.classpath/get-dependencies-memoized\n             #'leiningen.core.classpath/get-dependencies*)\n  (doseq [[proj jarfile] [[managed-deps-snapshot-project\n                           (str \"test_projects/managed-deps-snapshot/target/\"\n                                \"mgmt-0.99.0-SNAPSHOT-standalone.jar\")]\n                          [managed-deps-project\n                           (str \"test_projects/managed-deps/target/\"\n                                \"mgmt-0.99.0-standalone.jar\")]]]\n    (with-out-str\n      (uberjar proj))\n    (let [uberjar-file (File. jarfile)]\n      (is (= true (.exists uberjar-file))\n          (format \"File '%s' does not exist!\" uberjar-file)))))\n"
  },
  {
    "path": "test/leiningen/test/update_in.clj",
    "content": "(ns leiningen.test.update-in\n  (:refer-clojure :exclude [update-in])\n  (:use clojure.test leiningen.update-in))\n\n(defn- prj-map [p] (with-meta p {:without-profiles p}))\n\n(deftest test-update-in\n  (doseq\n      [[in-args task-form]\n       (->> [[(prj-map {:version \"1.0.0\"})\n              \":\" \"assoc\" \":version\" \"\\\"2.0.0\\\"\" \"--\" \"jar\"]\n             [\"jar\" (prj-map {:version \"2.0.0\"})]\n\n             [(prj-map {:repl-options {:port 1}})\n              \":repl-options:port\" \"inc\" \"--\" \"repl\" \":headless\"]\n             [\"repl\" (prj-map {:repl-options {:port 2}}) \":headless\"]\n\n             [(prj-map {:dependencies [['clojure.core (clojure-version)]]})\n              \":dependencies\" \"conj\" \"[slamhound \\\"1.1.3\\\"]\" \"--\" \"repl\"]\n             [\"repl\" (prj-map {:dependencies [['clojure.core (clojure-version)]\n                                             ['slamhound \"1.1.3\"]]})]]\n            (partition 2))]\n    (let [[in-prj key-path f & args] in-args\n          [keys-vec f f-args [task-name & task-args]]\n          (parse-args key-path f args)\n          out-prj (update-project in-prj keys-vec f f-args)]\n      (is (= task-form (concat [task-name out-prj] task-args)))\n      (is (= (meta (second task-form)) (meta out-prj))))))\n"
  },
  {
    "path": "test/leiningen/test/vcs.clj",
    "content": "(ns leiningen.test.vcs\n  (:require [clojure.test :refer :all]\n            [leiningen.vcs :as vcs]))\n\n(deftest parsed-args\n  (testing \"VCS tag argument parsing\"\n    (are [args parsed-args] (= (vcs/parse-tag-args args) parsed-args)\n      [] {:sign? true :annotate? true}\n      [\"v\"] {:prefix \"v\" :sign? true :annotate? true}\n      [\"v\" \"--sign\"] {:prefix \"v\" :sign? true :annotate? true}\n      [\"--sign\"] {:sign? true :annotate? true}\n      [\"--no-sign\"] {:sign? false :annotate? true}\n      [\"--no-sign\" \"v\"] {:prefix \"v\" :sign? false :annotate? true}\n      [\"--no-annotate\"] {:sign? true :annotate? false}\n      [\"--annotate\"] {:sign? true :annotate? true}\n      [\"--no-sign\" \"--no-annotate\" \"v\"] {:sign? false :annotate? false :prefix \"v\"}\n      [\"-s\"] {:sign? true :annotate? true}\n      [\"v\" \"r\"] {:prefix \"r\" :sign? true :annotate? true})))\n"
  },
  {
    "path": "test/leiningen/test/with_profile.clj",
    "content": "(ns leiningen.test.with-profile\n  (:require [clojure.test :refer :all]\n            [leiningen.core.main :as main]\n            [leiningen.test.helper\n             :refer [with-aliases-project\n                     with-aliases2-project]\n             :as lthelper]\n            [leiningen.with-profile :refer :all]))\n\n(defn- prj-map\n  ([p] (prj-map p [:default]))\n  ([p a]\n     (let [p {:profiles p}\n           m {:without-profiles p, :active-profiles a\n              :profiles (:profiles p)}]\n       (with-meta p m))))\n\n(deftest test-profiles-in-group\n  (doseq [[project pgroup expected]\n          [[(prj-map {}) \"+foo\" [:base :system :user :provided :dev :foo]]\n           [(prj-map {:default [:base :dev]}) \"+foo\" [:base, :dev, :foo]]\n           [(prj-map {:default [:base :dev]}) \"-dev\" [:base]]\n           [(prj-map {:default [:base :dev]}) \"-dev,+foo\" [:base, :foo]]\n           [(prj-map {:default [:base :dev]}) \"-default,+foo\" [:foo]]\n           [(prj-map {:default [:base :dev], :foo [:bar :baz]})\n            \"-default,+foo\" [:bar :baz]]\n           [(prj-map {:default [:base :dev], :dev [:foo]\n                      :foo [:bar :baz], :baz [:zap]})\n            \"-default,+foo\" [:bar :zap]]\n           ;; TODO: drop support for partially-composite profiles in 3.0\n           [(prj-map {:default [:base :dev], :foo [:bar {:gross true}]})\n            \"-default,+foo\" [:foo]]]]\n    (is (= expected (profiles-in-group project pgroup))))\n  (testing \"no +/- prefixes in arg\"\n    (let [project (prj-map {:default [:base :dev] :foo [:bar :baz]\n                            :bar [:one :two] :baz [:three :four]})]\n      (doseq [[pgroup expected]\n              [[\"foo\" [:one :two :three :four]]\n               [\"bar\" [:one :two]]\n               [\"baz\" [:three :four]]\n               [\"bar,baz\" [:one :two :three :four]]\n               [\"baz,bar\" [:three :four :one :two]]]]\n        (is (= expected (profiles-in-group project pgroup)))))))\n\n(deftest default-project-with-profiles\n  (testing \"outside project directory\"\n    (let [project (main/default-project)]\n      (is (= nil (main/resolve-and-apply project [\"project\" \"a\"]))\n          \"base project\")\n      (testing \"with a profile\"\n        (let [project (vary-meta project assoc-in [:profiles :a2] {:a 2})]\n          (is (= [2]\n                 (main/resolve-and-apply project\n                                         [\"with-profile\" \"+a2\" \"project\" \"a\"]))\n              \"applies profile\"))))))\n\n(deftest with-profiles-aliases-test\n  (testing \"recursive aliases\"\n    (testing \"no with-profile\"\n      (is (= 1 (main/resolve-and-apply with-aliases-project [\"project\" \"a\"]))\n          \"recursive alias\")\n      (is (= 1 (main/resolve-and-apply with-aliases-project [\"projecta\"]))\n          \"two level alias\"))\n\n    (testing \"with-profile added profile\"\n      (is (= [2] (main/resolve-and-apply\n                  with-aliases-project [\"with-profile\" \"+a2\" \"project\" \"a\"]))\n          \"recursive partial alias\")\n      (is (= [2] (main/resolve-and-apply\n                  with-aliases-project [\"with-profile\" \"+a2\" \"projecta\"]))\n          \"recursive full alias\"))\n\n    (testing \"with-profile set profile\"\n      (is (= [2] (main/resolve-and-apply\n                  with-aliases-project [\"with-profile\" \"a2\" \"project\" \"a\"]))\n          \"recursive partial alias\")\n      (is (= [2] (main/resolve-and-apply\n                  with-aliases-project [\"with-profile\" \"a2\" \"projecta\"]))\n          \"recursive full alias\"))\n\n\n    (testing \"with-profile added in alias\"\n      (is (= [2]\n             (main/resolve-and-apply with-aliases-project [\"pa2project\" \"a\"]))\n          \"recursive partial alias\")\n      (is (= [2]\n             (main/resolve-and-apply with-aliases-project [\"pa2projecta\"]))\n          \"recursive full alias\"))\n\n    (testing \"with-profile set in alias\"\n      (is (= [2] (main/resolve-and-apply\n                  with-aliases-project [\"a2project\" \"a\"]))\n          \"recursive partial alias\")\n      (is (= [2] (main/resolve-and-apply with-aliases-project [\"a2projecta\"]))\n          \"recursive full alias\"))\n\n\n    (testing \"with alias in profile\"\n      (is (= [2] (main/resolve-and-apply\n                  with-aliases-project [\"with-profile\" \"+a2\" \"inp-projecta\"]))\n          \"with profile added\")\n      (is (= [2] (main/resolve-and-apply\n                  with-aliases-project [\"with-profile\" \"a2\" \"inp-projecta\"]))\n          \"with profile set\")))\n\n  (testing \"recursive across profiles\"\n    (is (= [2] (main/resolve-and-apply with-aliases2-project [\"project\" \"a\"]))\n        \"partial alias from user profile\")\n    (is (= [[2]] (main/resolve-and-apply with-aliases2-project [\"projecta\"]))\n        \"full alias from user profile\")\n    (is (= [2] (main/resolve-and-apply\n                with-aliases2-project [\"project-set\" \"a\"]))\n        \"partial alias from user profile\")\n    ;; this should probably be [[2]]\n    (is (= [2] (main/resolve-and-apply with-aliases2-project [\"projecta-set\"]))\n        \"full alias from user profile\")))\n"
  },
  {
    "path": "test/sample-connect-string",
    "content": "myhost:23\n"
  },
  {
    "path": "test/sample-connect-string-http",
    "content": "http://localhost:23/repl\n"
  },
  {
    "path": "test_projects/.ssh/allowed_signers",
    "content": "phil@hagelb.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCl/xWvwO2cw7yuHnv1spMGIBBFB5pFXduh3P8RD2dOqAv4CM9mrQ2BjSMbz0WePHvKYDNecrpG/vGHZHs5Anflj8nLRKjeihpQ5NpkQd51ICrR8u6dtjqIvXFMJZc3mW8IycUOb63+FNRxnNychc/RBPTJ8Gm1f0FBNpiSBZ8GpW1SjDuTM6bBPSmpQ6cLkrwCPMVPgKkUeXou7at13lKN7BZbW4KNhJVpHXpcxUTYVyvrZIochEVKlub+o0TWyzASQQFzNXU89nUjto51qAG4deYWKPOQYETpqgK7H4j8YqO6FUXwiHmnUPdRo22tuMlm9vDQubAXQ8of9ZOQQdiIsTRAemqgbU+e8cegxNqGtlabVNV9P36ATm2XAL8ovgrRAN0Q2Ict2MPKxG0ZH/9ct5GH/PWrSnWaYEcdjfQkJiJdSPL9omwzLWUnMAtTkGtxGkT81SPwbuOPzjQ4xMIK05sayWJtWx9kSPuX912798UjAk5kuHSR2olA9MPmtN0= phil@whirlwind\n"
  },
  {
    "path": "test_projects/.ssh/id_rsa",
    "content": "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAYEApf8Vr8DtnMO8rh579bKTBiAQRQeaRV3bodz/EQ9nTqgL+AjPZq0N\ngY0jG89Fnjx7ymAzXnK6Rv7xh2R7OQJ35Y/Jy0So3ooaUOTaZEHedSAq0fLunbY6iL1xTC\nWXN5lvCMnFDm+t/hTUcZzcnIXP0QT0yfBptX9BQTaYkgWfBqVtUow7kzOmwT0pqUOnC5K8\nAjzFT4CpFHl6Lu2rdd5SjewWW1uCjYSVaR16XMVE2Fcr62SKHIRFSpbm/qNE1sswEkEBcz\nV1PPZ1I7aOdagBuHXmFijzkGBE6aoCux+I/GKjuhVF8Ih5p1D3UaNtrbjJZvbw0LmwF0PK\nH/WTkEHYiLE0QHpqoG1PnvHHoMTahrZWm1TVfT9+gE5tlwC/KL4K0QDdENiHLdjDysRtGR\n//XLeRh/z1q0p1mmBHHY30JCYiXUjy/aJsMy1lJzALU5BrcRpE/NUj8G7jj840OMTCCtOb\nGslibVsfZEj7l/ddu/fFIwJOZLh0kdqJQPTD5rTdAAAFiODHXAPgx1wDAAAAB3NzaC1yc2\nEAAAGBAKX/Fa/A7ZzDvK4ee/WykwYgEEUHmkVd26Hc/xEPZ06oC/gIz2atDYGNIxvPRZ48\ne8pgM15yukb+8YdkezkCd+WPyctEqN6KGlDk2mRB3nUgKtHy7p22Ooi9cUwllzeZbwjJxQ\n5vrf4U1HGc3JyFz9EE9MnwabV/QUE2mJIFnwalbVKMO5MzpsE9KalDpwuSvAI8xU+AqRR5\nei7tq3XeUo3sFltbgo2ElWkdelzFRNhXK+tkihyERUqW5v6jRNbLMBJBAXM1dTz2dSO2jn\nWoAbh15hYo85BgROmqArsfiPxio7oVRfCIeadQ91Gjba24yWb28NC5sBdDyh/1k5BB2Iix\nNEB6aqBtT57xx6DE2oa2VptU1X0/foBObZcAvyi+CtEA3RDYhy3Yw8rEbRkf/1y3kYf89a\ntKdZpgRx2N9CQmIl1I8v2ibDMtZScwC1OQa3EaRPzVI/Bu44/ONDjEwgrTmxrJYm1bH2RI\n+5f3Xbv3xSMCTmS4dJHaiUD0w+a03QAAAAMBAAEAAAGAHpeKOZ/GqrNwHG7FzZwheGmEVh\nR2m/4WMhh2cYBzO43A1u9YucV+zbdjFwb1/5mJ/twH24otRlRJ0vfztaf8zLPZLrrynEC7\nZNkoXn29L7zD53lr/GjPFNBFBxGOctK2Idp9lJGEcWUJWf7csYP/rrfJHUZPVQGk1w3mxF\nKA4kqugR4TBKfqPYa2HNm4+WsLdyYX/vTpNDrHB8sJZGmasUknPaL5xnb+yiaCnIJGk9BM\n6c7XnTXLR1nULG2OjD9ZyqU+M/D2vOaP0FFUyeLD16RIxZWdxDVmR9oPK6X54m9m9TgVG7\nQQaPZwAfP4bZHuq+CYhgUPq3YKYgrc9vNhKBobtwUarDjkquKUI8yArhwVXuopW9/pRbky\nXf+D98YSoexrnpSFmJeH3Z8r5Gdd8SQgoeP4NBhVwJT1soU1hvszTzWkQCfbfi3BmFBZxt\nWp8eJK5DH6edBkpwnIUmH26CuNkREfb/PE/jy6Tlg9WP2ST45NRg85EZ4HYbyPwbPBAAAA\nwH5ogY8+kkbhqpHn2qmfTjdLkaUJuIHLEAlAy3CKGp1jZ8sJNjl0ZIzn5GV5aRbhmVTGoE\nhw+ta0x6b10KF49i8/eHE0bpgtNOkX1ufTDw6IHY50vePGkyCi4TMwMUGLW+9bCz3CyIgP\neiQJ+fLb3oDSqiqsq2ZAFRRlabN/KcVuzft5MsgZbdIu/VKgCm6i2k2QYSf7+zGvKr6ceK\nHgQ3autVKYW47/pqPxyqGrQ9a+1FG9O9VEVRYjjSZ0u3ZCfgAAAMEA0Y4/mmFKWAaEskUq\nAPJPeem0qB/z/PT4BGM7/VMONl7rH/ayJv6evtYBw1fSZ3VNt45HHzZPktR6aLjp7KZmR6\nZyorze+Van2vAfAs0/GolZOCPp83lsXSKmgTq62a4aZ17F4rKKO+H/x20oi0I33PByaOiY\neap5c+5JpO1nx/8p2bHCCMNmlNB3xPhGYVZobe6Fuwj9yfPL1X1JB+1uuTw+fABLIMqaMD\n1zPtTSRpgNDXN0hsIQ4Erkxap+f7GpAAAAwQDKyWBHqCazT+XIyWpSjU2kPcK/13/QDl5g\nalz7U4wwAelA/cJ25LJnIISzz9vYjDigYCI9n+mvFh+vU2fEaSAyIsvEISD38ASmOLP4Sg\nFcOHJH8YofYzDAY8ZBGYcvcAf7b7J66my/1W/B6M6L2OWg4kG2UX1zvmH0SA8zozfJH9fH\nhf3sAldZEcXJ8ziQZlYby4uSaC0xD2jKq3rO9DV49n45KMyq/INLqa6wfdHCYQxKnmQYyn\nLEXAgFW/V9UhUAAAAOcGhpbEB3aGlybHdpbmQBAgMEBQ==\n-----END OPENSSH PRIVATE KEY-----\n"
  },
  {
    "path": "test_projects/.ssh/id_rsa.pub",
    "content": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCl/xWvwO2cw7yuHnv1spMGIBBFB5pFXduh3P8RD2dOqAv4CM9mrQ2BjSMbz0WePHvKYDNecrpG/vGHZHs5Anflj8nLRKjeihpQ5NpkQd51ICrR8u6dtjqIvXFMJZc3mW8IycUOb63+FNRxnNychc/RBPTJ8Gm1f0FBNpiSBZ8GpW1SjDuTM6bBPSmpQ6cLkrwCPMVPgKkUeXou7at13lKN7BZbW4KNhJVpHXpcxUTYVyvrZIochEVKlub+o0TWyzASQQFzNXU89nUjto51qAG4deYWKPOQYETpqgK7H4j8YqO6FUXwiHmnUPdRo22tuMlm9vDQubAXQ8of9ZOQQdiIsTRAemqgbU+e8cegxNqGtlabVNV9P36ATm2XAL8ovgrRAN0Q2Ict2MPKxG0ZH/9ct5GH/PWrSnWaYEcdjfQkJiJdSPL9omwzLWUnMAtTkGtxGkT81SPwbuOPzjQ4xMIK05sayWJtWx9kSPuX912798UjAk5kuHSR2olA9MPmtN0= phil@whirlwind\n"
  },
  {
    "path": "test_projects/.ssh/verify",
    "content": "#!/bin/bash\n\nssh-keygen -Y verify -f test_projects/.ssh/allowed_signers -I phil@hagelb.org -n file -s test_projects/sample/project.clj.sig < test_projects/sample/project.clj > /dev/null\n"
  },
  {
    "path": "test_projects/README.txt",
    "content": "These projects are used for leiningen's test suite, so don't change\nany of these values without updating the relevant tests. If you\njust want a basic project to work from, generate a new one with\n\"lein new\".\n"
  },
  {
    "path": "test_projects/bad-require/.gitignore",
    "content": "/target\n/lib\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n.lein-deps-sum\n.lein-failures\n.lein-plugins\n.lein-repl-history\n"
  },
  {
    "path": "test_projects/bad-require/project.clj",
    "content": "(defproject bad-require \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]]\n  :main bad-require.core)\n"
  },
  {
    "path": "test_projects/bad-require/src/bad_require/core.clj",
    "content": "(ns bad-require.core\n  (:require [this.namespace.does.not.exist]))\n\n(defn -main [])\n"
  },
  {
    "path": "test_projects/data-readers-backwards-compatibility/project.clj",
    "content": "(defproject bug \"bug\"\n  :dependencies [[org.clojure/clojure \"1.8.0\"]\n                 [org.flatland/ordered \"1.5.6\"]])\n"
  },
  {
    "path": "test_projects/file-not-found-thrower/.gitignore",
    "content": "/target\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n"
  },
  {
    "path": "test_projects/file-not-found-thrower/project.clj",
    "content": "(defproject file-not-found-thrower \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]])\n"
  },
  {
    "path": "test_projects/file-not-found-thrower/src/file_not_found_thrower/core.clj",
    "content": "(ns file-not-found-thrower.core)\n\n(defn -main\n  \"I don't do a whole lot.\"\n  []\n  (slurp \"haha this file does NOT EXIST\"))\n"
  },
  {
    "path": "test_projects/java-main/.gitignore",
    "content": "/target\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n"
  },
  {
    "path": "test_projects/java-main/project.clj",
    "content": "(defproject java-main \"0.1.0-SNAPSHOT\"\n  :java-source-paths [\"src/java\"]\n  :dependencies [[org.clojure/clojure \"1.8.0\"]] ;; lein run errors if not there.\n  :main my.java.Main)\n"
  },
  {
    "path": "test_projects/java-main/src/java/my/java/Main.java",
    "content": "package my.java;\n\npublic class Main {\n    public static void main(String[] args) {\n        System.out.println(\"Hello from Java!\");\n    }\n}\n"
  },
  {
    "path": "test_projects/jvm-opts/project.clj",
    "content": "(defproject custom/args \"0.0.1-SNAPSHOT\"\n  :description \"A test project\"\n  :dependencies [[org.clojure/clojure \"1.8.0\"]]\n  :profiles {:no-op {}\n             :ascii {:jvm-opts [\"-Dfile.encoding=ASCII\"]}})\n"
  },
  {
    "path": "test_projects/leaky-composite/project.clj",
    "content": ";; https://github.com/technomancy/leiningen/issues/2721\n(defproject leaky-composite \"0.1.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.10.1\"]]\n  :profiles {:ring {:dependencies [[ring \"1.8.2\"]]}\n             :dev  [:ring]\n             :test {:dependencies [[clucy \"1.0.0\"]]}})\n"
  },
  {
    "path": "test_projects/lein-test-exit-code/project.clj",
    "content": "(defproject lein-test-exit-code \"0.1.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.10.3\"]]\n  :eval-in :leiningen)\n"
  },
  {
    "path": "test_projects/lein-test-exit-code/test/lein_test_exit_code/core_test.clj",
    "content": "(ns lein-test-exit-code.core-test\n  (:require [clojure.test :refer [deftest is]]))\n\n(defmacro gen-failing-deftests [n]\n  `(do\n     ~@(for [i (range n)]\n         `(deftest ~(symbol (str \"expected-failure-\" i))\n            (is false \"Expected failure.\")))))\n\n(gen-failing-deftests 256)\n"
  },
  {
    "path": "test_projects/lein-test-reload-bug/project.clj",
    "content": "(defproject lein-test-reload-bug \"0.1.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.10.1\"]])\n"
  },
  {
    "path": "test_projects/lein-test-reload-bug/test/lein_test_reload_bug/a_deftype.clj",
    "content": "(ns lein-test-reload-bug.a-deftype\n  (:require [lein-test-reload-bug.b-protocol\n             :refer [B]]))\n\n(deftype A []\n  B\n  (b [this] :ok))\n"
  },
  {
    "path": "test_projects/lein-test-reload-bug/test/lein_test_reload_bug/b_protocol.clj",
    "content": "(ns lein-test-reload-bug.b-protocol)\n\n(defprotocol B\n  (b [this]))\n"
  },
  {
    "path": "test_projects/lein-test-reload-bug/test/lein_test_reload_bug/core_test.clj",
    "content": "(ns lein-test-reload-bug.core-test\n  (:require [clojure.test :refer [deftest is]]\n            [lein-test-reload-bug.a-deftype :refer [->A]]\n            [lein-test-reload-bug.b-protocol :refer [b]]))\n\n(deftest a-test\n  (let [a (->A)]\n    (is (= :ok (b a)))))\n"
  },
  {
    "path": "test_projects/managed-deps/project.clj",
    "content": "(def clj-version \"1.3.0\")\n\n(defproject mgmt \"0.99.0\"\n  :description \"A test project\"\n\n  :managed-dependencies [[~(symbol \"org.clojure\" \"clojure\") ~clj-version]\n                 [rome ~(str \"0.\" \"9\")]\n                 [ring/ring \"1.0.0\"]\n                 [ring/ring-codec \"1.0.1\"]\n                 [ring/ring-headers \"0.2.0\"]\n                 [commons-math/commons-math \"1.2\" :classifier \"sources\"]\n                 [org.apache.commons/commons-csv \"1.4\" :classifier \"sources\"]\n                 [ring/ring-defaults \"0.2.1\"]\n                 [org.clojure/tools.reader \"1.0.0-beta3\"]]\n\n  :dependencies [[org.clojure/clojure]\n                 [rome/rome nil]\n                 [ring]\n                 [ring/ring-codec nil :exclusions [commons-codec]]\n                 [ring/ring-headers :exclusions [ring/ring-core]]\n                 [commons-codec \"1.6\"]\n                 [commons-math nil :classifier \"sources\"]\n                 [org.apache.commons/commons-csv :classifier \"sources\"]\n                 [org.clojure/tools.emitter.jvm \"0.1.0-beta5\"] ; depends on tools.reader 0.8.5\n                 [org.clojure/tools.namespace \"0.3.0-alpha3\"] ; depends on tools.reader 0.10.0\n                 ]\n\n  :profiles {:add-deps {:dependencies [[org.clojure/clojure]]}\n             :replace-deps {:dependencies ^:replace [[org.clojure/clojure]]}})\n"
  },
  {
    "path": "test_projects/managed-deps-snapshot/project.clj",
    "content": "(def clj-version \"1.3.0\")\n\n(defproject mgmt \"0.99.0-SNAPSHOT\"\n  :description \"A test project\"\n\n  :managed-dependencies [[~(symbol \"org.clojure\" \"clojure\") ~clj-version]\n                 [rome ~(str \"0.\" \"9\")]\n                 [ring/ring \"1.0.0\"]\n                 [ring/ring-codec \"1.0.1\"]\n                 [ring/ring-headers \"0.2.0\"]\n                 [commons-math/commons-math \"1.2\" :classifier \"sources\"]\n                 [org.apache.commons/commons-csv \"1.4\" :classifier \"sources\"]\n                 [ring/ring-defaults \"0.2.1\"]\n                 [org.clojure/tools.reader \"1.0.0-beta3\"]]\n\n  :dependencies [[org.clojure/clojure]\n                 [rome/rome nil]\n                 [ring]\n                 [ring/ring-codec nil :exclusions [commons-codec]]\n                 [ring/ring-headers :exclusions [ring/ring-core]]\n                 [commons-codec \"1.6\"]\n                 [commons-math nil :classifier \"sources\"]\n                 [org.apache.commons/commons-csv :classifier \"sources\"]\n                 [org.clojure/tools.emitter.jvm \"0.1.0-beta5\"] ; depends on tools.reader 0.8.5\n                 [org.clojure/tools.namespace \"0.3.0-alpha3\"] ; depends on tools.reader 0.10.0\n                 ])\n"
  },
  {
    "path": "test_projects/more-gen-classes/.gitignore",
    "content": "/target\n/lib\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n.lein-deps-sum\n.lein-failures\n.lein-plugins\n.lein-repl-history\n"
  },
  {
    "path": "test_projects/more-gen-classes/README.md",
    "content": "# more-gen-classes\n\nA Clojure library designed to ... well, that part is up to you.\n\n## Usage\n\nFIXME\n\n## License\n\nCopyright © 2013 FIXME\n\nDistributed under the Eclipse Public License, the same as Clojure.\n"
  },
  {
    "path": "test_projects/more-gen-classes/doc/intro.md",
    "content": "# Introduction to more-gen-classes\n\nTODO: write [great documentation](https://jacobian.org/writing/what-to-write/)\n"
  },
  {
    "path": "test_projects/more-gen-classes/project.clj",
    "content": "(defproject more-gen-classes \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]])\n"
  },
  {
    "path": "test_projects/more-gen-classes/src/more_gen_classes/bar.clj",
    "content": "(ns more-gen-classes.bar\n  (:gen-class))\n"
  },
  {
    "path": "test_projects/more-gen-classes/src/more_gen_classes/baz.clj",
    "content": "(ns more-gen-classes.baz\n  (:gen-class))\n"
  },
  {
    "path": "test_projects/more-gen-classes/src/more_gen_classes/foo.clj",
    "content": "(ns more-gen-classes.foo\n  (:gen-class))\n"
  },
  {
    "path": "test_projects/native/.gitignore",
    "content": "pom.xml\n*jar\n/lib\n/nnnative\n/classes\n.lein-failures\n.lein-deps-sum\n"
  },
  {
    "path": "test_projects/native/project.clj",
    "content": "(defproject project-name \"1.0.0-SNAPSHOT\"\n  :description \"Test support for transitive native dependencies\"\n  :native-path \"nnnative\"\n  :dependencies [[org.clojure/clojure \"1.4.0\"]\n                 [serial-port \"1.0.7\"]\n                 [penumbra/lwjgl \"2.4.2\"]\n                 [com.badlogicgames.gdx/gdx-platform \"0.9.9\"]\n                 [com.badlogicgames.gdx/gdx-platform \"0.9.9\" :classifier \"natives-desktop\"]\n                 [org.clojars.samaaron/rxtx \"2.2.0\"]\n                 [jriengine \"0.8.4\"]\n                 [tokyocabinet \"1.24.0\"]])\n"
  },
  {
    "path": "test_projects/overlapped-sourcepaths/project.clj",
    "content": "(defproject overlapped-sourcepaths \"0.1.0\"\n  :dependencies [[org.clojure/clojure \"1.3.0\"]]\n  :java-source-paths [\"src\"])\n"
  },
  {
    "path": "test_projects/overlapped-sourcepaths/src/foo",
    "content": ""
  },
  {
    "path": "test_projects/preserve-eval-meta/.gitignore",
    "content": "pom.xml\n*jar\nlib\nclasses\n"
  },
  {
    "path": "test_projects/preserve-eval-meta/project.clj",
    "content": "(defproject preserve-eval-meta \"1.0\"\n  :description \"Basic project with main invoked via lein run without reflection warnings\"\n  :dependencies [[org.clojure/clojure \"1.11.1\"]]\n  :global-vars {*warn-on-reflection* true}\n  :preserve-eval-meta true\n  :main ^{:skip-aot true} preserve-eval-meta.core)\n"
  },
  {
    "path": "test_projects/preserve-eval-meta/src/preserve_eval_meta/core.clj",
    "content": "(ns preserve-eval-meta.core)\n\n(defn -main [& args]\n  (System/exit 0))\n"
  },
  {
    "path": "test_projects/provided/project.clj",
    "content": "(defproject provided \"0\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies []\n  :java-source-paths [\"src\"]\n  :main provided.core.Example\n  :profiles {:provided {:dependencies [[org.clojure/clojure \"1.4.0\"]]}})\n"
  },
  {
    "path": "test_projects/provided/src/provided/core/Example.java",
    "content": "package provided.core;\n\nimport clojure.lang.RT;\n\npublic class Example {\n\npublic static void\nmain(String... args) {\n    System.exit(\n        RT.intCast(\n            RT.var(\"clojure.core\", \"read-string\").invoke(\"0\")));\n}\n\n}\n"
  },
  {
    "path": "test_projects/reflector/.gitignore",
    "content": "/target\n/classes\n/checkouts\nprofiles.clj\npom.xml\npom.xml.asc\n*.jar\n*.class\n/.lein-*\n/.nrepl-port\n/.prepl-port\n.hgignore\n.hg/\n"
  },
  {
    "path": "test_projects/reflector/project.clj",
    "content": "(defproject reflector \"0.1.0-SNAPSHOT\"\n  :description \"a sample project involving AOT\"\n  :url \"https://leiningen.org\"\n  :license {:name \"EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0\"\n            :url \"https://www.eclipse.org/legal/epl-2.0/\"}\n  :dependencies [[org.clojure/clojure \"1.11.1\"]]\n  :aot [reflector.classy])\n"
  },
  {
    "path": "test_projects/reflector/src/reflector/classy.clj",
    "content": "(ns reflector.classy\n  (:gen-class :extends java.lang.RuntimeException))\n\n(defn init [xyz] (.getBytes xyz))\n\n"
  },
  {
    "path": "test_projects/reflector/src/reflector/main.clj",
    "content": "(ns reflector.main\n  (:require [reflector.classy])\n  (:import reflector.classy))\n\n(defn -main [& args]\n  (prn (classy.)))\n"
  },
  {
    "path": "test_projects/sample/.nrepl-port",
    "content": "4242"
  },
  {
    "path": "test_projects/sample/checkouts/sample2/.gitignore",
    "content": "pom.xml\n*jar\nlib\nclasses"
  },
  {
    "path": "test_projects/sample/checkouts/sample2/README",
    "content": "# sample2\n\nFIXME: write description\n\n## Usage\n\nFIXME: write\n\n## Installation\n\nFIXME: write\n\n## License\n\nFIXME: write\n"
  },
  {
    "path": "test_projects/sample/checkouts/sample2/project.clj",
    "content": "(defproject sample2 \"1.0.0-SNAPSHOT\"\n  :description \"FIXME: write\"\n  :dependencies [[org.clojure/clojure \"1.1.0\"]\n                 [org.clojure/clojure-contrib \"1.1.0\"]])"
  },
  {
    "path": "test_projects/sample/checkouts/sample2/src/sample2/alt.clj",
    "content": "(ns sample2.alt)\n"
  },
  {
    "path": "test_projects/sample/checkouts/sample2/src/sample2/core.clj",
    "content": "(ns sample2.core\n  (:require sample2.alt)\n  (:gen-class))\n"
  },
  {
    "path": "test_projects/sample/checkouts/sample2/test/sample2/core_test.clj",
    "content": "(ns sample2.core-test\n  (:use [sample2.core] :reload-all)\n  (:use [clojure.test]))\n\n(deftest replace-me ;; FIXME: write\n  (is false))\n"
  },
  {
    "path": "test_projects/sample/project.clj",
    "content": "(def clj-version \"1.3.0\")\n\n(defproject nomnomnom \"0.5.0-SNAPSHOT\"\n  :description \"A test project\"\n  :url \"https://leiningen.org\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[~(symbol \"org.clojure\" \"clojure\") ~clj-version]\n                 [rome ~(str \"0.\" \"9\")]\n                 [ring \"1.0.0\"]]\n  :plugins [[codox \"0.6.4\"]]\n  :main nom.nom.nom\n  :global-vars {*warn-on-reflection* true}\n  :jar-exclusions [#\"^META-INF\"]\n  :filespecs [{:type :fn :fn (fn [p] {:type :bytes :path \"bytes.clj\"\n                                     :bytes (str \"[:bytes \\\"are\\\" \"\n                                                 (:name p) \"]\")})}]\n  :test-selectors {:integration :integration\n                   :default (complement :integration)\n                   :random (fn [_] (> (rand) ~(float 1/2)))}\n  :repositories [[\"other\" {:url \"https://example.com/repo\"\n                           :update :always\n                           :releases {:checksum :warn}}]]\n  :deploy-repositories {\"snapshots\" ~(format \"file://%s/lein-repo\"\n                                             (System/getProperty \"java.io.tmpdir\"))})\n"
  },
  {
    "path": "test_projects/sample/src/nom/nom/check.clj",
    "content": "(ns nom.nom.check\n  (:require [sample2.core])\n  (:gen-class))\n\n(defn -main [])\n"
  },
  {
    "path": "test_projects/sample/src/nom/nom/nom.clj",
    "content": "(ns nom.nom.nom\n  (:import [org.jdom.adapters CrimsonDOMAdapter])\n  (:gen-class))\n\n(when-not (= \"1.3.0\" (clojure-version))\n  (throw (Exception. (str \"Not running Clojure 1.3.0: \"\n                          (clojure-version)))))\n\n(def unused-proxy (proxy [Object] [] (toString [] \"unused\")))\n\n(defn -main [& args]\n  (when-not (empty? args)\n    (println \"NOM! Munched\" (first args))\n    (recur (rest args))))\n"
  },
  {
    "path": "test_projects/sample/test/test_nom_nom_nom.clj",
    "content": "(ns test-nom-nom-nom\n  (:use [nom.nom.nom]\n        [clojure.test]))\n\n(defn test-ns-hook\n  []\n  (is false))\n\n(defn f [x]\n  (.list x))\n\n(deftest should-use-1.1.0\n  (is (= \"1.1.0\" (clojure-version)))\n  (f (java.io.File. \"/tmp\")))\n"
  },
  {
    "path": "test_projects/sample-bad-user/project.clj",
    "content": "(def clj-version \"1.3.0\")\n\n(defproject nomnomnom \"0.5.0-SNAPSHOT\"\n  :description \"A test project\"\n  :url \"https://leiningen.org\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[~(symbol \"org.clojure\" \"clojure\") ~clj-version]\n                 [rome ~(str \"0.\" \"9\")]\n                 [ring \"1.0.0\"]]\n  :plugins [[codox \"0.6.4\"]]\n  :main nom.nom.nom\n  :global-vars {*warn-on-reflection* true}\n  :jar-exclusions [#\"^META-INF\"]\n  :filespecs [{:type :fn :fn (fn [p] {:type :bytes :path \"bytes.clj\"\n                                     :bytes (str \"[:bytes \\\"are\\\" \"\n                                                 (:name p) \"]\")})}]\n  :test-selectors {:integration :integration\n                   :default (complement :integration)\n                   :random (fn [_] (> (rand) ~(float 1/2)))}\n  :repositories [[\"other\" {:url \"https://example.com/repo\"\n                           :update :always\n                           :releases {:checksum :warn}}]]\n  :deploy-repositories {\"snapshots\" ~(format \"file://%s/lein-repo\"\n                                             (System/getProperty \"java.io.tmpdir\"))})\n"
  },
  {
    "path": "test_projects/sample-bad-user/src/nom/nom/check.clj",
    "content": "(ns nom.nom.check\n  (:require [sample2.core])\n  (:gen-class))\n\n(defn -main [])\n"
  },
  {
    "path": "test_projects/sample-bad-user/src/nom/nom/nom.clj",
    "content": "(ns nom.nom.nom\n  (:import [org.jdom.adapters CrimsonDOMAdapter])\n  (:gen-class))\n\n(when-not (= \"1.3.0\" (clojure-version))\n  (throw (Exception. (str \"Not running Clojure 1.3.0: \"\n                          (clojure-version)))))\n\n(def unused-proxy (proxy [Object] [] (toString [] \"unused\")))\n\n(defn -main [& args]\n  (when-not (empty? args)\n    (println \"NOM! Munched\" (first args))\n    (recur (rest args))))\n"
  },
  {
    "path": "test_projects/sample-bad-user/test/user.clj",
    "content": "(ns user)\n\n(throw (Exception. \"loaded user!\"))\n"
  },
  {
    "path": "test_projects/sample-deploy/deploy-me-0.1.0-SNAPSHOT-fat.jarr",
    "content": "I am a teapot!\n"
  },
  {
    "path": "test_projects/sample-deploy/project.clj",
    "content": "(defproject deploy-me \"0.1.0-SNAPSHOT\"\n  :description \"FIXME: write description\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]])\n"
  },
  {
    "path": "test_projects/sample-failing/project.clj",
    "content": "(defproject nomnomnom \"0.5.0-SNAPSHOT\"\n  :dependencies [[~(symbol \"org.clojure\" \"clojure\") ~\"1.2.0\"]]\n  :aot [nom.nom.nom])\n"
  },
  {
    "path": "test_projects/sample-failing/src/nom/nom/nom.clj",
    "content": "(ns nom.nom.nom\n  (:gen-class))\n\nfailure-expected-here-dont-freak-out\n\nThis noming squirrel will cause compilation of this file to fail.\n\n ,;;:;,\n   ;;;;;\n  ,:;;:;    ,'=.\n  ;:;:;' .=\" ,'_\\\n  ':;:;,/  ,__:=@\n   ';;:;  =./)_\n     `\"=\\_  )_\"`\n          ``'\"\n"
  },
  {
    "path": "test_projects/sample-failing/test/sample/unreadable.clj",
    "content": "(ns sample.unreadable\n\n"
  },
  {
    "path": "test_projects/sample-fixture-error/project.clj",
    "content": "(defproject sample-fixture-error \"0.1.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.8.0\"]])\n"
  },
  {
    "path": "test_projects/sample-fixture-error/test/test_a.clj",
    "content": "(ns test-a\n  (:require [clojure.test :refer :all]\n            [clojure.java.io :refer [writer]]))\n\n(defn record-ran [t]\n  (let [file-name (format \"%s/lein-test-ran\"\n                          (System/getProperty \"java.io.tmpdir\"))]\n    (with-open [w (writer file-name :append true)]\n      (.write w (str t \"\\n\")))))\n\n(deftest test-a\n  (record-ran :test-a)\n  (is (= 1 1)))\n"
  },
  {
    "path": "test_projects/sample-fixture-error/test/test_b.clj",
    "content": "(ns test-b\n  (:require [clojure.test :refer :all]\n            [test-a :refer [record-ran]]))\n\n(use-fixtures :once\n  (fn [& _]\n    (throw (Exception. \"Don't panic. This is an expected exception.\"))))\n\n(deftest test-b\n  (record-ran :test-b)\n  (is (= 1 1)))\n"
  },
  {
    "path": "test_projects/sample-fixture-error/test/test_c.clj",
    "content": "(ns test-c\n  (:require [clojure.test :refer :all]\n            [test-a :refer (record-ran)]))\n\n(deftest test-c\n  (record-ran :test-c)\n  (is (= 1 1)))\n"
  },
  {
    "path": "test_projects/sample-no-aot/dev-resources/dev.clj",
    "content": "\"don't include me in the uberjar!\"\n"
  },
  {
    "path": "test_projects/sample-no-aot/project.clj",
    "content": "(defproject nomnomnom \"0.5.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.3.0\"]\n                 [janino \"2.5.15\"]]\n  :uberjar-exclusions [#\"DUMMY\"]\n  :test-selectors {:default (fn [m] (not (:integration m)))\n                   :integration :integration\n                   :int2 :int2\n                   :no-custom (fn [m] (not (false? (:custom m))))})\n"
  },
  {
    "path": "test_projects/sample-no-aot/src/nom/nom/nom.clj",
    "content": "(ns nom.nom.nom)\n;; This file is not AOT compiled!\n"
  },
  {
    "path": "test_projects/sample-no-aot/test/namespace.clj",
    "content": "(ns ^:integration namespace\n  (:use [clojure.test]\n        [selectors :only [record-ran]]))\n\n(deftest integration-test\n  (record-ran :integration-ns)\n  (is true))\n\n(deftest ^:int2 int2-integration-test\n  (record-ran :integration-ns)\n  (is true))\n"
  },
  {
    "path": "test_projects/sample-no-aot/test/selectors.clj",
    "content": "(ns selectors\n  (:use [clojure.test]\n        [clojure.java.io]))\n\n(defn record-ran [t]\n  (let [file-name (format \"%s/lein-test-ran\"\n                          (System/getProperty \"java.io.tmpdir\"))]\n    (with-open [w (writer file-name :append true)]\n      (.write w (str t \"\\n\")))))\n\n(use-fixtures :each (fn [t] (record-ran :fixture) (t)))\n\n(deftest ^{:integration true} integration-test\n  (record-ran :integration)\n  (is true))\n\n(deftest regular\n  (record-ran :regular)\n  (is true))\n\n(deftest ^{:custom false} not-custom\n  (record-ran :not-custom)\n  (is true))\n\n(deftest ^{:int2 true} integration-2\n  (record-ran :int2)\n  (is true))\n"
  },
  {
    "path": "test_projects/sample-ordered-aot/project.clj",
    "content": "(defproject sample-ordered-aot \"0.1.0-SNAPSHOT\"\n  :description \"This project is to drive testing of ordered aot compilation.\"\n  :url \"https://example.com/FIXME\"\n  :license {:name \"Eclipse Public License\"\n            :url \"https://www.eclipse.org/legal/epl-v10.html\"}\n  :dependencies [[org.clojure/clojure \"1.8.0\"]]\n  :aot :all)\n"
  },
  {
    "path": "test_projects/sample-ordered-aot/src/sample_ordered_aot/baz.clj",
    "content": "(ns sample-ordered-aot.baz)\n\n(defn baz\n  \"I don't do a whole lot.\"\n  [x]\n  (println x \"Hello, World!\"))\n"
  },
  {
    "path": "test_projects/sample-ordered-aot/src/sample_ordered_aot/foo.clj",
    "content": "(ns sample-ordered-aot.foo)\n\n(defn foo\n  \"I don't do a whole lot.\"\n  [x]\n  (println x \"Hello, World!\"))\n"
  },
  {
    "path": "test_projects/sample-profile-meta/project.clj",
    "content": "(defproject nomnomnom \"0.5.0-SNAPSHOT\"\n  :dependencies []\n  :profiles {:default [:leiningen/default :my-leaky :my-provided :my-test]\n             :my-leaky ^:leaky {:dependencies\n                                [[org.clojure/tools.macro \"0.1.2\"]]}\n             :my-test\n             ^{:pom-scope :test} {:dependencies\n                                  [[org.clojure/java.classpath \"0.2.2\"]]}\n             :my-provided\n             ^{:pom-scope :provided} {:dependencies\n                                      [[org.clojure/tools.namespace \"0.2.6\"]]}})\n"
  },
  {
    "path": "test_projects/sample-reader-cond/project.clj",
    "content": "(defproject nomnomnom \"0.5.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.8.0\"]\n                 [janino \"2.5.15\"]]\n  :aot :all\n  :uberjar-exclusions [#\"DUMMY\"])\n"
  },
  {
    "path": "test_projects/sample-reader-cond/src/nom/nom/clj.clj",
    "content": "(ns nom.nom.clj)\n"
  },
  {
    "path": "test_projects/sample-reader-cond/src/nom/nom/cljc.cljc",
    "content": "(ns nom.nom.cljc)\n"
  },
  {
    "path": "test_projects/sample-reader-cond/test/clj_test.clj",
    "content": "(ns clj-test\n  (:use [clojure.test]\n        [selectors :only [record-ran]]))\n\n(deftest clojure-test\n  (record-ran :clj-test)\n  (is true))\n"
  },
  {
    "path": "test_projects/sample-reader-cond/test/cljc_test.cljc",
    "content": "(ns cljc-test\n  (:use #?(:clj  [clojure.test]\n           :cljs [cljs.test])\n        [selectors :only [record-ran]]))\n\n(deftest conditional-test\n  (record-ran :cljc-test)\n  (is true))\n"
  },
  {
    "path": "test_projects/sample-reader-cond/test/selectors.clj",
    "content": "(ns selectors\n  (:use [clojure.test]\n        [clojure.java.io]))\n\n(defn record-ran [t]\n  (let [file-name (format \"%s/lein-test-ran\"\n                          (System/getProperty \"java.io.tmpdir\"))]\n    (with-open [w (writer file-name :append true)]\n      (.write w (str t \"\\n\")))))\n\n"
  },
  {
    "path": "test_projects/tricky-name/.gitignore",
    "content": "pom.xml\n*jar\nlib\nclasses\n"
  },
  {
    "path": "test_projects/tricky-name/project.clj",
    "content": "(defproject org.domain/tricky-name \"1.0\"\n  :description \"One with a tricky group and project name\"\n  :dependencies [[org.clojure/clojure \"1.3.0\"]]\n  :global-vars {*warn-on-reflection* true}\n  :main ^{:skip-aot true} org.domain.tricky-name.core)\n"
  },
  {
    "path": "test_projects/tricky-name/src/org/domain/tricky_name/brunch.clj",
    "content": "(ns org.domain.tricky-name.brunch)\n\n(defn -main [& args]\n  (spit (format \"%s/lein-test\" (System/getProperty \"java.io.tmpdir\")) \"BRUNCH\"))\n"
  },
  {
    "path": "test_projects/tricky-name/src/org/domain/tricky_name/core.clj",
    "content": "(ns org.domain.tricky-name.core)\n\n(defn -main [& args]\n  (when-not (empty? args)\n    (spit (format \"%s/lein-test\" (System/getProperty \"java.io.tmpdir\"))\n          (str \"nom:\" (first args)))\n    (recur (rest args))))\n"
  },
  {
    "path": "test_projects/tricky-name/src/org/domain/tricky_name/munch.clj",
    "content": "(ns org.domain.tricky-name.munch)\n\n(defn -main [& args]\n  (spit (format \"%s/lein-test\" (System/getProperty \"java.io.tmpdir\"))\n        (pr-str :munched args)))\n"
  },
  {
    "path": "test_projects/uberjar-components-merging/components1.xml",
    "content": "<component-set>\n  <components>\n    <component>\n      <role>org.apache.maven.doxia.Doxia</role>\n      <implementation>org.apache.maven.doxia.DefaultDoxia</implementation>\n      <description>Simple implementation of the Doxia interface:\nuses a ParserManager to lookup a parser.</description>\n      <requirements>\n        <requirement>\n          <role>org.apache.maven.doxia.parser.manager.ParserManager</role>\n          <field-name>parserManager</field-name>\n        </requirement>\n      </requirements>\n    </component>\n    <component>\n      <role>org.apache.maven.doxia.macro.Macro</role>\n      <role-hint>echo</role-hint>\n      <implementation>org.apache.maven.doxia.macro.EchoMacro</implementation>\n      <description>A simple macro that prints out the key and value of some supplied parameters.</description>\n    </component>\n    <component>\n      <role>org.apache.maven.doxia.macro.manager.MacroManager</role>\n      <implementation>org.apache.maven.doxia.macro.manager.DefaultMacroManager</implementation>\n      <description>Default implementation of &lt;code&gt;MacroManager&lt;/code&gt;</description>\n      <requirements>\n        <requirement>\n          <role>org.apache.maven.doxia.macro.Macro</role>\n          <field-name>macros</field-name>\n        </requirement>\n      </requirements>\n    </component>\n    <component>\n      <role>org.apache.maven.doxia.macro.Macro</role>\n      <role-hint>snippet</role-hint>\n      <implementation>org.apache.maven.doxia.macro.snippet.SnippetMacro</implementation>\n      <description>A macro that prints out the content of a file or a URL.</description>\n    </component>\n    <component>\n      <role>org.apache.maven.doxia.macro.Macro</role>\n      <role-hint>swf</role-hint>\n      <implementation>org.apache.maven.doxia.macro.SwfMacro</implementation>\n      <description>Macro for embedding Flash (SWF) within Maven documentation.</description>\n    </component>\n    <component>\n      <role>org.apache.maven.doxia.macro.Macro</role>\n      <role-hint>toc</role-hint>\n      <implementation>org.apache.maven.doxia.macro.toc.TocMacro</implementation>\n      <description>Macro to display a &lt;code&gt;Table Of Content&lt;/code&gt; in a given &lt;code&gt;Sink&lt;/code&gt;.</description>\n    </component>\n    <component>\n      <role>org.apache.maven.doxia.module.site.manager.SiteModuleManager</role>\n      <implementation>org.apache.maven.doxia.module.site.manager.DefaultSiteModuleManager</implementation>\n      <description>Simple implementation of the SiteModuleManager interface.</description>\n      <requirements>\n        <requirement>\n          <role>org.apache.maven.doxia.module.site.SiteModule</role>\n          <field-name>siteModules</field-name>\n        </requirement>\n      </requirements>\n    </component>\n    <component>\n      <role>org.apache.maven.doxia.parser.manager.ParserManager</role>\n      <implementation>org.apache.maven.doxia.parser.manager.DefaultParserManager</implementation>\n      <description>Simple implementation of the &lt;code&gt;ParserManager&lt;/code&gt; interface.</description>\n      <requirements>\n        <requirement>\n          <role>org.apache.maven.doxia.parser.Parser</role>\n          <field-name>parsers</field-name>\n        </requirement>\n      </requirements>\n    </component>\n  </components>\n</component-set>\r\n"
  },
  {
    "path": "test_projects/uberjar-components-merging/components2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n\r\n<!--\r\n  Licensed to the Apache Software Foundation (ASF) under one\r\n  or more contributor license agreements.  See the NOTICE file\r\n  distributed with this work for additional information\r\n  regarding copyright ownership.  The ASF licenses this file\r\n  to you under the Apache License, Version 2.0 (the\r\n  \"License\"); you may not use this file except in compliance\r\n  with the License.  You may obtain a copy of the License at\r\n\r\n  https://www.apache.org/licenses/LICENSE-2.0\r\n\r\n  Unless required by applicable law or agreed to in writing,\r\n  software distributed under the License is distributed on an\r\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\n  KIND, either express or implied.  See the License for the\r\n  specific language governing permissions and limitations\r\n  under the License.\r\n-->\r\n\r\n<component-set>\r\n  <!-- Doxia core -->\r\n  <components>\r\n    <component>\r\n      <role>org.apache.maven.doxia.macro.Macro</role>\r\n      <role-hint>echo</role-hint>\r\n      <implementation>org.apache.maven.doxia.macro.EchoMacro</implementation>\r\n      <description>A simple macro that prints out the key and value of some supplied\r\n      parameters.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.macro.manager.MacroManager</role>\r\n      <implementation>org.apache.maven.doxia.macro.manager.DefaultMacroManager</implementation>\r\n      <description>Default implementation of &lt;code&gt;MacroManager&lt;/code&gt;</description>\r\n      <requirements>\r\n        <requirement>\r\n          <role>org.apache.maven.doxia.macro.Macro</role>\r\n          <field-name>macros</field-name>\r\n        </requirement>\r\n      </requirements>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.macro.Macro</role>\r\n      <role-hint>snippet</role-hint>\r\n      <implementation>org.apache.maven.doxia.macro.snippet.SnippetMacro</implementation>\r\n      <description>A macro that prints out the content of a file or a URL.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.macro.Macro</role>\r\n      <role-hint>swf</role-hint>\r\n      <implementation>org.apache.maven.doxia.macro.SwfMacro</implementation>\r\n      <description>Macro for embedding Flash (SWF) within Maven documentation.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.macro.Macro</role>\r\n      <role-hint>toc</role-hint>\r\n      <implementation>org.apache.maven.doxia.macro.toc.TocMacro</implementation>\r\n      <description>Macro to display a &lt;code&gt;Table Of Content&lt;/code&gt; in a\r\n        given &lt;code&gt;Sink&lt;/code&gt;.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.manager.ParserManager</role>\r\n      <implementation>org.apache.maven.doxia.parser.manager.DefaultParserManager</implementation>\r\n      <description>Simple implementation of the\r\n        &lt;code&gt;ParserManager&lt;/code&gt; interface.</description>\r\n      <requirements>\r\n        <requirement>\r\n          <role>org.apache.maven.doxia.parser.Parser</role>\r\n          <field-name>parsers</field-name>\r\n        </requirement>\r\n      </requirements>\r\n    </component>\r\n\r\n    <!-- Doxia apt -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.Parser</role>\r\n      <role-hint>apt</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.apt.AptParser</implementation>\r\n      <description>The APT parser.</description>\r\n      <requirements>\r\n        <requirement>\r\n          <role>org.apache.maven.doxia.macro.manager.MacroManager</role>\r\n          <field-name>macroManager</field-name>\r\n        </requirement>\r\n      </requirements>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>apt</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.apt.AptSinkFactory</implementation>\r\n      <description>APT implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia confluence -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.Parser</role>\r\n      <role-hint>confluence</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.confluence.ConfluenceParser</implementation>\r\n      <description>Parse the &lt;a href=&quot;http://www.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>confluence</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.confluence.ConfluenceSinkFactory</implementation>\r\n      <description>Confluence implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia docbook -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.Parser</role>\r\n      <role-hint>docbook</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.docbook.DocBookParser</implementation>\r\n      <description>Parse a &lt;code&gt;Docbook&lt;/code&gt; document and emit events\r\n        into the specified doxia Sink.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>docbook</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.docbook.DocbookSinkFactory</implementation>\r\n      <description>Docbook implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia fml -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.Parser</role>\r\n      <role-hint>fml</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.fml.FmlParser</implementation>\r\n      <description>Parse a fml model and emit events into the specified doxia Sink.</description>\r\n      <requirements>\r\n        <requirement>\r\n          <role>org.apache.maven.doxia.macro.manager.MacroManager</role>\r\n          <field-name>macroManager</field-name>\r\n        </requirement>\r\n      </requirements>\r\n    </component>\r\n\r\n    <!-- Doxia fo -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>fo</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.fo.FoSinkFactory</implementation>\r\n      <description>FO implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia itext -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>itext</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.itext.ITextSinkFactory</implementation>\r\n      <description>IText implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia latex -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>latex</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.latex.LatexSinkFactory</implementation>\r\n      <description>Latex implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia rtf -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>rtf</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.rtf.RtfSinkFactory</implementation>\r\n      <description>APT implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia twiki -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.Parser</role>\r\n      <role-hint>twiki</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.twiki.TWikiParser</implementation>\r\n      <description>Parse the &lt;a href=&quot;http://twiki.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>twiki</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.twiki.TWikiSinkFactory</implementation>\r\n      <description>TWiki implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia xdoc -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.Parser</role>\r\n      <role-hint>xdoc</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.xdoc.XdocParser</implementation>\r\n      <description>Parse an xdoc model and emit events into the specified doxia Sink.</description>\r\n      <requirements>\r\n        <requirement>\r\n          <role>org.apache.maven.doxia.macro.manager.MacroManager</role>\r\n          <field-name>macroManager</field-name>\r\n        </requirement>\r\n      </requirements>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>xdoc</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.xdoc.XdocSinkFactory</implementation>\r\n      <description>Xdoc implementation of the Sink factory.</description>\r\n    </component>\r\n\r\n    <!-- Doxia xhtml -->\r\n    <component>\r\n      <role>org.apache.maven.doxia.parser.Parser</role>\r\n      <role-hint>xhtml</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.xhtml.XhtmlParser</implementation>\r\n      <description>Parse an xhtml model and emit events into a Doxia Sink.</description>\r\n    </component>\r\n    <component>\r\n      <role>org.apache.maven.doxia.sink.SinkFactory</role>\r\n      <role-hint>xhtml</role-hint>\r\n      <implementation>org.apache.maven.doxia.module.xhtml.XhtmlSinkFactory</implementation>\r\n      <description>Xhtml implementation of the Sink factory.</description>\r\n    </component>\r\n  </components>\r\n</component-set>\r\n"
  },
  {
    "path": "test_projects/uberjar-components-merging/expected-components.xml",
    "content": "<?xml version='1.0' encoding='UTF-8'?>\n<component-set>\n<components>\n<component>\n<role>\norg.apache.maven.doxia.Doxia\n</role>\n<implementation>\norg.apache.maven.doxia.DefaultDoxia\n</implementation>\n<description>\nSimple implementation of the Doxia interface:\nuses a ParserManager to lookup a parser.\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.parser.manager.ParserManager\n</role>\n<field-name>\nparserManager\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\necho\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.EchoMacro\n</implementation>\n<description>\nA simple macro that prints out the key and value of some supplied parameters.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.manager.MacroManager\n</role>\n<implementation>\norg.apache.maven.doxia.macro.manager.DefaultMacroManager\n</implementation>\n<description>\nDefault implementation of &lt;code&gt;MacroManager&lt;/code&gt;\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<field-name>\nmacros\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\nsnippet\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.snippet.SnippetMacro\n</implementation>\n<description>\nA macro that prints out the content of a file or a URL.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\nswf\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.SwfMacro\n</implementation>\n<description>\nMacro for embedding Flash (SWF) within Maven documentation.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\ntoc\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.toc.TocMacro\n</implementation>\n<description>\nMacro to display a &lt;code&gt;Table Of Content&lt;/code&gt; in a given &lt;code&gt;Sink&lt;/code&gt;.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.module.site.manager.SiteModuleManager\n</role>\n<implementation>\norg.apache.maven.doxia.module.site.manager.DefaultSiteModuleManager\n</implementation>\n<description>\nSimple implementation of the SiteModuleManager interface.\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.module.site.SiteModule\n</role>\n<field-name>\nsiteModules\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.manager.ParserManager\n</role>\n<implementation>\norg.apache.maven.doxia.parser.manager.DefaultParserManager\n</implementation>\n<description>\nSimple implementation of the &lt;code&gt;ParserManager&lt;/code&gt; interface.\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<field-name>\nparsers\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\necho\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.EchoMacro\n</implementation>\n<description>\nA simple macro that prints out the key and value of some supplied\n      parameters.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.manager.MacroManager\n</role>\n<implementation>\norg.apache.maven.doxia.macro.manager.DefaultMacroManager\n</implementation>\n<description>\nDefault implementation of &lt;code&gt;MacroManager&lt;/code&gt;\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<field-name>\nmacros\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\nsnippet\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.snippet.SnippetMacro\n</implementation>\n<description>\nA macro that prints out the content of a file or a URL.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\nswf\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.SwfMacro\n</implementation>\n<description>\nMacro for embedding Flash (SWF) within Maven documentation.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.macro.Macro\n</role>\n<role-hint>\ntoc\n</role-hint>\n<implementation>\norg.apache.maven.doxia.macro.toc.TocMacro\n</implementation>\n<description>\nMacro to display a &lt;code&gt;Table Of Content&lt;/code&gt; in a\n        given &lt;code&gt;Sink&lt;/code&gt;.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.manager.ParserManager\n</role>\n<implementation>\norg.apache.maven.doxia.parser.manager.DefaultParserManager\n</implementation>\n<description>\nSimple implementation of the\n        &lt;code&gt;ParserManager&lt;/code&gt; interface.\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<field-name>\nparsers\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<role-hint>\napt\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.apt.AptParser\n</implementation>\n<description>\nThe APT parser.\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.macro.manager.MacroManager\n</role>\n<field-name>\nmacroManager\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\napt\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.apt.AptSinkFactory\n</implementation>\n<description>\nAPT implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<role-hint>\nconfluence\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.confluence.ConfluenceParser\n</implementation>\n<description>\nParse the &lt;a href=&quot;http://www.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\nconfluence\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.confluence.ConfluenceSinkFactory\n</implementation>\n<description>\nConfluence implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<role-hint>\ndocbook\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.docbook.DocBookParser\n</implementation>\n<description>\nParse a &lt;code&gt;Docbook&lt;/code&gt; document and emit events\n        into the specified doxia Sink.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\ndocbook\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.docbook.DocbookSinkFactory\n</implementation>\n<description>\nDocbook implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<role-hint>\nfml\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.fml.FmlParser\n</implementation>\n<description>\nParse a fml model and emit events into the specified doxia Sink.\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.macro.manager.MacroManager\n</role>\n<field-name>\nmacroManager\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\nfo\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.fo.FoSinkFactory\n</implementation>\n<description>\nFO implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\nitext\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.itext.ITextSinkFactory\n</implementation>\n<description>\nIText implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\nlatex\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.latex.LatexSinkFactory\n</implementation>\n<description>\nLatex implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\nrtf\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.rtf.RtfSinkFactory\n</implementation>\n<description>\nAPT implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<role-hint>\ntwiki\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.twiki.TWikiParser\n</implementation>\n<description>\nParse the &lt;a href=&quot;http://twiki.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\ntwiki\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.twiki.TWikiSinkFactory\n</implementation>\n<description>\nTWiki implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<role-hint>\nxdoc\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.xdoc.XdocParser\n</implementation>\n<description>\nParse an xdoc model and emit events into the specified doxia Sink.\n</description>\n<requirements>\n<requirement>\n<role>\norg.apache.maven.doxia.macro.manager.MacroManager\n</role>\n<field-name>\nmacroManager\n</field-name>\n</requirement>\n</requirements>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\nxdoc\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.xdoc.XdocSinkFactory\n</implementation>\n<description>\nXdoc implementation of the Sink factory.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.parser.Parser\n</role>\n<role-hint>\nxhtml\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.xhtml.XhtmlParser\n</implementation>\n<description>\nParse an xhtml model and emit events into a Doxia Sink.\n</description>\n</component>\n<component>\n<role>\norg.apache.maven.doxia.sink.SinkFactory\n</role>\n<role-hint>\nxhtml\n</role-hint>\n<implementation>\norg.apache.maven.doxia.module.xhtml.XhtmlSinkFactory\n</implementation>\n<description>\nXhtml implementation of the Sink factory.\n</description>\n</component>\n</components>\n</component-set>\n"
  },
  {
    "path": "test_projects/uberjar-merging/project.clj",
    "content": "(defproject nomnomnom \"0.5.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.8.0\"]\n                 [janino \"2.5.15\"]\n                 [org.platypope/method-fn \"0.1.0\"]\n                 [porcupine \"0.0.4\"]]\n  :uberjar-exclusions [#\"DUMMY\"]\n  :uberjar-merge-with {#\"\\.properties$\" [slurp str spit]}\n  :test-selectors {:default (fn [m] (not (:integration m)))\n                   :integration :integration\n                   :int2 :int2\n                   :no-custom (fn [m] (not (false? (:custom m))))})\n"
  },
  {
    "path": "test_projects/uberjar-merging/resources/data_readers.clj",
    "content": "{nomnomnom/identity clojure.core/identity,\n mf/i nomnomnom/override,\n }\n"
  },
  {
    "path": "test_projects/with-aliases/project.clj",
    "content": "(defproject project-with-aliases \"0.1.0-SNAPSHOT\"\n  :aliases {\"p\" [\"echo\" \"p\"]\n            \"a2p\" [\"with-profile\" \"+a2\" \"p\"]\n            \"pp\" [\"with-profile\" \"+a2\" \"echo\" \"pp\"]\n            \"ppp\" [\"with-profile\" \"+a2\" \"echo\" \"ppp\"]\n            \"echo\" [\"echo\" \"hello\"]\n\n            \"project\" [\"project\"]\n            \"projecta\" [\"project\" \"a\"]\n\n            \"pa2project\" [\"with-profile\" \"+a2\" \"project\"]\n            \"pa2projecta\" [\"with-profile\" \"+a2\" \"project\" \"a\"]\n\n            \"a2project\" [\"with-profile\" \"a2\" \"project\"]\n            \"a2projecta\" [\"with-profile\" \"a2\" \"project\" \"a\"]}\n  :a 1\n  :profiles {:a2 {:aliases {\"q\" [\"echo\" \"q\"]\n                            \"inp-projecta\" [\"project\" \"a\"]}\n                  :a 2}})\n"
  },
  {
    "path": "test_projects/with-aliases2/project.clj",
    "content": "(defproject project-with-aliases \"0.1.0-SNAPSHOT\"\n  :a 1\n  :profiles {:a2 {:a 2}})\n"
  },
  {
    "path": "test_projects/with-classifiers/project.clj",
    "content": "(defproject with-classifiers \"0.1.0-SNAPSHOT\"\n  :classifiers {:tests {:source-paths ^:replace [\"test\"]\n                        :resource-paths ^:replace []}})\n"
  },
  {
    "path": "test_projects/with-pom-plugins/project.clj",
    "content": "(defproject project-with-pom-plugins \"0.1.0-SNAPSHOT\"\n  :pom-plugins [[two.parameter/simple-plugin \"1.0.0\"]\n                [three.parameter/with-vec \"1.0.1\"\n                 [:a 1 :a 2 :a 3]]\n                [three.parameter/with-map \"1.0.2\"\n                 {:a 1\n                  :b 2\n                  :c 3}]\n                [three.parameter/with-list \"1.0.3\"\n                 (:root\n                   [:a 1]\n                   [:b\n                    [:c 2]\n                    [:d 3]])]])\n"
  },
  {
    "path": "test_projects/with-resources/project.clj",
    "content": "(defproject project-with-resources \"0.5.0-SNAPSHOT\"\n  :dependencies [[org.clojure/clojure \"1.3.0\"]\n                 [janino \"2.5.15\"]]\n\n  :resource-paths [\"resources\"])\n"
  },
  {
    "path": "test_projects/with-resources/resources/nested/dir/sample.txt",
    "content": "Do not remove me!\n"
  },
  {
    "path": "web/.htaccess",
    "content": "Options +MultiViews -ExecCGI\nRewriteEngine on\n\n# HTTPS\nRewriteCond %{HTTPS} !=on\nRewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]\n\nHeader set Strict-Transport-Security \"max-age=31536000\" env=HTTPS\nHeader always set Permissions-Policy: interest-cohort=()\n\nErrorDocument 404 /404.html\nAddDefaultCharset UTF-8\nFileETag MTime Size\n"
  },
  {
    "path": "web/404.html",
    "content": "<!DOCTYPE html>\n<head>\n    <meta charset=\"utf-8\">\n    <title>Leiningen: not found</title>\n\n    <meta name=\"viewport\"\n          content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n    <link rel=\"stylesheet\" href=\"/stylesheets/base.css\">\n    <link rel=\"stylesheet\" href=\"/stylesheets/skeleton.css\">\n    <link rel=\"stylesheet\" href=\"/stylesheets/layout.css\">\n\n    <link rel=\"shortcut icon\" href=\"images/favicon.ico\">\n</head>\n<body>\n\n  <div class=\"container\">\n    <div class=\"three columns offset-by-one\">\n      <img src=\"img/leiningen.jpg\" title=\"logo\" id=\"logo\">\n    </div>\n    <div class=\"eight columns offset-by-two\" id=\"title\">\n      <h1 style=\"margin-top: 40px\">Leiningen</h1>\n      <p>Sorry. Couldn't Find That Page! You probably want\n        to <a href=\"/\">go home</a>?</p>\n    </div>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/Makefile",
    "content": "DOCS=tutorial.html faq.html plugins.html profiles.html deploy.html\n\nupload: html\n\trsync -r ./ leiningen.org:leiningen.org/\n\nhtml: $(DOCS)\n\n# we can't set the prerequisite properly because we used uppercase\n# filenames for some reason in the markdown\n%.html:\n\tpandoc --template template.html --to html -o $@ \\\n\t\t--metadata title=\"Leiningen $*\" \\\n\t\t../doc/$(shell echo $* | tr '[:lower:]' '[:upper:]').md\n\nclean: ; rm $(DOCS)\n\n# TODO: css for code styles\n\n.PHONY: upload html\n"
  },
  {
    "path": "web/_foot.html",
    "content": "    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"sixteen columns\" id=\"footer\">\n        <p>&copy; 2012-2022 Phil Hagelberg\n        and contributors. Licensed under\n        the <a href=\"https://codeberg.org/leiningen/leiningen/src/stable/COPYING\">EPL\n        1.0</a>. See the code\n        for <a href=\"https://codeberg.org/leiningen/leiningen/src/main/web\">this\n        site</a>.</p>\n    </div>\n    </div><!-- container -->\n"
  },
  {
    "path": "web/grench.html",
    "content": "<!DOCTYPE html>\n<head>\n\n    <!-- Basic Page Needs\n  ================================================== -->\n    <meta charset=\"utf-8\">\n    <title>Grenchman</title>\n    <meta name=\"description\" content=\"Grenchman: quick invocation of code over nREPL.\">\n    <meta name=\"author\" content=\"Phil Hagelberg and contributors\">\n\n    <!-- Mobile Specific Metas\n  ================================================== -->\n    <meta name=\"viewport\"\n          content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n\n    <!-- CSS\n  ================================================== -->\n    <link rel=\"stylesheet\" href=\"stylesheets/base.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/skeleton.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/layout.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/htmlize.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/grench.css\">\n</head>\n<body>\n\n  <div class=\"container\">\n    <div class=\"eight columns offset-by-two\" id=\"title\">\n      <h1 class=\"remove-bottom\">Grenchman</h1>\n      <h6>fast invocation of code over nREPL</h6>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"two-thirds column\">\n      <p id=\"pitch\">Grenchman lets you run\n      <a href=\"https://clojure.org\">Clojure</a>\n      code <strong>quickly</strong>. By connecting to a\n      running <a href=\"https://github.com/clojure/tools.nrepl\">nREPL</a>\n      server you avoid JVM startup time, streamlining your development\n      workflow. It includes its own repl client implementation\n      featuring full <a href=\"https://www.gnu.org/s/readline\">GNU\n      Readline</a> support as well as the ability to\n      invoke <a href=\"https://leiningen.org\">Leiningen</a> tasks.</p>\n\n      <p>Just launch an nREPL server in the background with <kbd>lein\n          trampoline repl :headless</kbd> or\n          by <a href=\"https://github.com/clojure/tools.nrepl/blob/master/README.md#embedding-nrepl-starting-a-server\">embedding\n          nREPL in your codebase</a>, and <kbd>grench</kbd> will\n          connect to it and run your code there.</p>\n\n      <p>Please report\n      issues <a href=\"https://gitlab.com/technomancy/grenchman/issues\">on\n      GitLab</a> or on IRC.</p>\n    </div>\n\n    <div class=\"one-third column\">\n    <pre class=\"htmlize\" id=\"sample\"><span class=\"prompt\">$</span> time grench eval '(prn \"Hello!\")'\n<span class=\"stdout\">\"Hello!\"</span>\n\n<span class=\"timing\">real    0m0.117s\nuser    0m0.024s\nsys     0m0.024s</span></pre>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"one-third column\" id=\"download\">\n      <h3 class=\"offset-by-one\">Download</h3></div>\n    <div class=\"two-thirds column\">\n\n      <p>The latest version of Grenchman is 0.3.0, but it claims to be\n        Distributed native binaries are about 10MB but have no\n        dependencies required besides <kbd>libffi</kbd>\n        and <kbd>libreadline-dev</kbd>. All programs are 64-bit.</p>\n\n      <ul class=\"download\">\n        <li><a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-debian-7\">Debian Wheezy</a>\n          <span class=\"etc\">[ <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-debian-7.sha1\">sha1</a> |\n            <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-debian-7.asc\">sig</a> ]</span></li>\n        <li><a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-ubuntu\">Debian Jessie, Ubuntu 12.04, 12.10, and 13.04</a>\n          <span class=\"etc\">[ <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-ubuntu.sha1\">sha1</a> |\n            <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-ubuntu.asc\">sig</a> ]</span></li>\n        <li><a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-fedora\">Fedora (tested on 19)</a>\n          <span class=\"etc\">[ <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-fedora.sha1\">sha1</a> |\n            <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-fedora.asc\">sig</a> ]</span></li>\n        <li><a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-mac\">Mac OS X</a>\n          <span class=\"etc\">[ <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-mac.sha1\">sha1</a> |\n            <a href=\"https://technomancy.github.io/grenchman/downloads/grench-0.2.0-mac.asc\">sig</a> ]</span></li>\n      </ul>\n\n      <p>Download the appropriate binary for your platform, set the\n        executable bit with <kbd>chmod</kbd>, and place it on\n        your <kbd>$PATH</kbd> as <kbd>grench</kbd> to install. You can\n        check the signatures by pulling in the key with <kbd>gpg\n        --recv-keys 77E77DDC</kbd> and running <kbd>gpg --verify\n        $ASC_FILE</kbd>.</p>\n\n      <p>Source\n      and <a href=\"https://gitlab.com/technomancy/grenchman/issues\">issues</a>\n      are\n      tracked <a href=\"https://gitlab.com/technomancy/grenchman\">on\n      GitLab</a>.</p>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"sixteen columns\" id=\"footer\">\n        <p>&copy; 2013, 2019 Phil Hagelberg\n        and <a href=\"https://gitlab.com/technomancy/grenchman/contributors\">contributors</a>.\n        Licensed under\n        the <a href=\"https://gitlab.com/technomancy/grenchman/blob/master/COPYING\">GNU\n        General Public License version 3.0</a> or later.</p>\n    </div>\n    </div><!-- container -->\n\n<!-- End Document\n================================================== -->\n</body>\n</html>\n"
  },
  {
    "path": "web/img/favicon/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <square150x150logo src=\"/img/favicon/mstile-150x150.png\"/>\n            <TileColor>#ffffff</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "web/img/favicon/manifest.json",
    "content": "{\n    \"name\": \"Leiningen\",\n    \"icons\": [\n        {\n            \"src\": \"/img/favicon/android-chrome-192x192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/img/favicon/android-chrome-256x256.png\",\n            \"sizes\": \"256x256\",\n            \"type\": \"image/png\"\n        }\n    ],\n    \"theme_color\": \"#ffffff\",\n    \"background_color\": \"#ffffff\",\n    \"display\": \"standalone\"\n}"
  },
  {
    "path": "web/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Leiningen</title>\n    <meta name=\"description\" content=\"Leiningen: automating Clojure projects\">\n    <meta name=\"author\" content=\"Phil Hagelberg and contributors\">\n\n    <!-- Mobile Specific Metas\n  ================================================== -->\n    <meta name=\"viewport\"\n          content=\"width=device-width, initial-scale=1\">\n\n    <!-- Favicons + Manifest\n  ================================================== -->\n  <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/img/favicon/apple-touch-icon.png\">\n  <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/img/favicon/favicon-32x32.png\">\n  <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/img/favicon/favicon-16x16.png\">\n  <link rel=\"manifest\" href=\"/img/favicon/manifest.json\">\n  <link rel=\"mask-icon\" href=\"/img/favicon/safari-pinned-tab.svg\" color=\"#000000\">\n  <link rel=\"shortcut icon\" href=\"/img/favicon/favicon.ico\">\n  <meta name=\"msapplication-config\" content=\"/img/favicon/browserconfig.xml\">\n  <meta name=\"theme-color\" content=\"#ffffff\">\n\n    <!-- CSS\n  ================================================== -->\n    <link rel=\"stylesheet\" href=\"stylesheets/base.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/skeleton.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/layout.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/htmlize.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/lein.css\">\n</head>\n<body>\n\n  <div class=\"container\">\n    <div class=\"three columns offset-by-one\">\n      <img src=\"img/leiningen.jpg\" title=\"logo\" id=\"logo\">\n    </div>\n    <div class=\"eight columns offset-by-two\" id=\"title\">\n      <h1 class=\"remove-bottom\" style=\"margin-top: 40px\">Leiningen</h1>\n      <p id=\"tagline\">for automating Clojure projects without setting\n        your hair on fire</p>\n      <nav id=\"links\" class=\"offset-by-three\">\n        <a href=\"#install\">install</a> |\n        <a href=\"#docs\">docs</a> |\n        <a href=\"#community\">community</a> |\n        <a href=\"https://codeberg.org/leiningen/leiningen\">source</a>\n      </nav>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"one-third column\">\n      <p id=\"pitch\">Leiningen is <strong>the easiest way to use\n      <a href=\"https://clojure.org\">Clojure</a></strong>. With a focus\n      on project automation and declarative configuration, it gets out\n      of your way and lets you focus on your code.</p>\n    </div>\n    <div class=\"two-thirds column\">\n    <pre class=\"htmlize\" id=\"sample-project\"><span class=\"esk-paren\">(</span>defproject leiningen.org <span class=\"string\">\"1.0.0\"</span>\n  <span class=\"constant\">:description</span> <span class=\"string\">\"Generate static HTML for https://leiningen.org\"</span>\n  <span class=\"constant\">:dependencies</span> [[enlive <span class=\"string\">\"1.0.1\"</span>]\n                 [cheshire <span class=\"string\">\"4.0.0\"</span>]\n                 [org.markdownj/markdownj <span class=\"string\">\"0.3.0-1.0.2b4\"</span>]]\n  <span class=\"constant\">:main</span> leiningen.web<span class=\"esk-paren\">)</span></pre>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"one-third column\"><h3 class=\"offset-by-one\">Install</h3></div>\n    <div class=\"two-thirds column\" id=\"install\">\n      <p>First check\n      your <a href=\"https://wiki.leiningen.org/Packaging\">package\n      manager</a> to see whether it includes Leiningen. If not, don't\n      worry; a manual install is easy.</p>\n\n      <p>Leiningen and Clojure require Java; ideally\n        <a href=\"https://adoptium.net\">OpenJDK</a>. Get this from\n        your package manager, or download manually if you have to.</p>\n      <ol>\n        <li>Download the <a href=\"https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein\"><kbd>lein</kbd>\n        script</a> (or on\n          Windows <a href=\"https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat\"><kbd>lein.bat</kbd></a>\n          if you don't use WSL)</li>\n        <li>Place it on your <kbd>$PATH</kbd> where your shell can find it (eg. <kbd>/usr/local/bin/</kbd>)</li>\n        <li>Set it to be executable (<kbd>sudo chmod a+x /usr/local/bin/lein</kbd>)</li>\n        <li>Run it (<kbd>lein</kbd>) and it will download the self-install package</li>\n      </ol>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"one-third column\" style=\"float: right\">\n      <h3 class=\"offset-by-one\">Documentation</h3></div>\n\n    <div class=\"two-thirds column\" id=\"docs\">\n      <p>The <a href=\"/tutorial.html\">tutorial</a>\n        is the best place to start. If you have Leiningen installed,\n        you can read the tutorial by running <kbd>lein help\n        tutorial</kbd>. It does not cover learning the\n        language itself;\n        good <a href=\"https://clojure-doc.org\">Clojure\n        documentation</a> can be found elsewhere.</p>\n\n\n      <p>Running <kbd>lein help faq</kbd> will get you the\n        <a href=\"/faq.html\">FAQ</a>.\n        Documentation for each individual task is available\n        via <kbd>lein help $TASK</kbd>. You can also\n        see <a href=\"https://codeberg.org/leiningen/leiningen/src/stable/sample.project.clj\">the\n        sample <kbd>project.clj</kbd> file</a> containing a reference of most\n        project settings by running <kbd>lein help sample</kbd>.</p>\n\n      <p>More:\n        <a href=\"/profiles.html\">profiles</a> |\n        <a href=\"/deploy.html\">deploying libraries</a> |\n        <a href=\"/plugins.html\">writing plugins</a> |\n        <a href=\"https://wiki.leiningen.org/Plugins\">plugin list</a>\n      </p>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"one-third column\"><h3 class=\"offset-by-one\">Community</h3></div>\n    <div class=\"two-thirds column\" id=\"community\">\n      <p>At the time of this writing Leiningen is the most\n        widely-contributed-to Clojure project. We welcome potential\n        contributors and do our best to make it easy to help out.</p>\n\n      <p>Discussion occurs primarily <a href=\"irc://irc.libera.chat#leiningen\">in\n          the <kbd>#leiningen</kbd> channel</a>\n        on <a href=\"https://libera.chat\">Libera.Chat</a>.</p>\n\n      <p>Issues should\n        be <a href=\"https://codeberg.org/leiningen/leiningen/issues\">reported\n        on the issue tracker</a>.</p>\n\n      <p>The <a href=\"https://codeberg.org/leiningen/leiningen/issues\">canonical\n          repository is on Codeberg</a> but a mirror will be left up\n        <a href=\"https://github.com/technomancy/leiningen\">on\n        Github</a> for a while for people who have not yet created a\n        Codeberg account.</p>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"sixteen columns\" id=\"footer\">\n        <p>&copy; 2012-2025 Phil Hagelberg\n        and contributors. Licensed under\n        the <a href=\"https://codeberg.org/leiningen/leiningen/src/stable/COPYING\">EPL\n        1.0</a>. See the code\n        for <a href=\"https://codeberg.org/leiningen/leiningen/src/main/web\">this\n        site</a>.</p>\n    </div>\n    </div><!-- container -->\n\n</body>\n</html>\n"
  },
  {
    "path": "web/robots.txt",
    "content": "# www.robotstxt.org/\n# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449\n\nUser-agent: *\n\n"
  },
  {
    "path": "web/stylesheets/base.css",
    "content": "/*\n* Skeleton V1.1\n* Copyright 2011, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://www.opensource.org/licenses/mit-license.php\n* 8/17/2011\n*/\n\n\n/* Table of Content\n==================================================\n\t#Reset & Basics\n\t#Basic Styles\n\t#Site Styles\n\t#Typography\n\t#Links\n\t#Lists\n\t#Images\n\t#Buttons\n\t#Tabs\n\t#Forms\n\t#Misc */\n\n\n/* #Reset & Basics (Inspired by E. Meyers)\n================================================== */\n\thtml, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t\tborder: 0;\n\t\tfont-size: 100%;\n\t\tfont: inherit;\n\t\tvertical-align: baseline; }\n\tarticle, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {\n\t\tdisplay: block; }\n\tbody {\n\t\tline-height: 1; }\n\tblockquote, q {\n\t\tquotes: none; }\n\tblockquote:before, blockquote:after,\n\tq:before, q:after {\n\t\tcontent: '';\n\t\tcontent: none; }\n\ttable {\n\t\tborder-collapse: collapse;\n\t\tborder-spacing: 0; }\n\n\n/* #Basic Styles\n================================================== */\n\tbody {\n\t\tbackground: #fff;\n\t\tfont: 14px/21px \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\t\tcolor: #444;\n\t\t-webkit-font-smoothing: antialiased; /* Fix for webkit rendering */\n\t\t-webkit-text-size-adjust: 100%;\n }\n\n\n/* #Typography\n================================================== */\n\th1, h2, h3, h4, h5, h6 {\n\t\tcolor: #181818;\n\t\tfont-family: \"Georgia\", \"Times New Roman\", serif;\n\t\tfont-weight: normal; }\n\th1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }\n\th1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;}\n\th2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; }\n\th3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; }\n\th4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; }\n\th5 { font-size: 17px; line-height: 24px; }\n\th6 { font-size: 14px; line-height: 21px; }\n\t.subheader { color: #777; }\n\n\tp { margin: 0 0 20px 0; }\n\tp img { margin: 0; }\n\tp.lead { font-size: 21px; line-height: 27px; color: #777;  }\n\n\tem { font-style: italic; }\n\tstrong { font-weight: bold; color: #333; }\n\tsmall { font-size: 80%; }\n\n/*\tBlockquotes  */\n\tblockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }\n\tblockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }\n\tblockquote cite { display: block; font-size: 12px; color: #555; }\n\tblockquote cite:before { content: \"\\2014 \\0020\"; }\n\tblockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }\n\n\thr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; }\n\n\n/* #Links\n================================================== */\n\ta, a:visited { color: #555; text-decoration: underline; outline: 0; }\n\ta:hover, a:focus { color: #000; }\n\tp a, p a:visited { line-height: inherit; }\n\n\n/* #Lists\n================================================== */\n\tul, ol { margin-bottom: 20px; margin-left: 30px; }\n\tul.square { list-style: square outside; }\n\tul.circle { list-style: circle outside; }\n\tul.disc { list-style: disc outside; }\n\tul ul, ul ol,\n\tol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%;  }\n\tul ul li, ul ol li,\n\tol ol li, ol ul li { margin-bottom: 6px; }\n\tli { line-height: 18px; margin-bottom: 12px; }\n\tul.large li { line-height: 21px; }\n\tli p { line-height: 21px; }\n\n/* #Images\n================================================== */\n\n\timg.scale-with-grid {\n\t\tmax-width: 100%;\n\t\theight: auto; }\n\n\n/* #Buttons\n================================================== */\n\n\t.button,\n\tbutton,\n\tinput[type=\"submit\"],\n\tinput[type=\"reset\"],\n\tinput[type=\"button\"] {\n\t\tbackground: #eee; /* Old browsers */\n\t\tbackground: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */\n\t\tbackground: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */\n\t\tbackground: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */\n\t\tbackground: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */\n\t\tbackground: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */\n\t\tbackground: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */\n\t  border: 1px solid #aaa;\n\t  border-top: 1px solid #ccc;\n\t  border-left: 1px solid #ccc;\n\t  -moz-border-radius: 3px;\n\t  -webkit-border-radius: 3px;\n\t  border-radius: 3px;\n\t  color: #444;\n\t  display: inline-block;\n\t  font-size: 11px;\n\t  font-weight: bold;\n\t  text-decoration: none;\n\t  text-shadow: 0 1px rgba(255, 255, 255, .75);\n\t  cursor: pointer;\n\t  margin-bottom: 20px;\n\t  line-height: normal;\n\t  padding: 8px 10px;\n\t  font-family: \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif; }\n\n\t.button:hover,\n\tbutton:hover,\n\tinput[type=\"submit\"]:hover,\n\tinput[type=\"reset\"]:hover,\n\tinput[type=\"button\"]:hover {\n\t\tcolor: #222;\n\t\tbackground: #ddd; /* Old browsers */\n\t\tbackground: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */\n\t\tbackground: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */\n\t\tbackground: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */\n\t\tbackground: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */\n\t\tbackground: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */\n\t\tbackground: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */\n\t  border: 1px solid #888;\n\t  border-top: 1px solid #aaa;\n\t  border-left: 1px solid #aaa; }\n\n\t.button:active,\n\tbutton:active,\n\tinput[type=\"submit\"]:active,\n\tinput[type=\"reset\"]:active,\n\tinput[type=\"button\"]:active {\n\t\tborder: 1px solid #666;\n\t\tbackground: #ccc; /* Old browsers */\n\t\tbackground: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */\n\t\tbackground: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */\n\t\tbackground: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */\n\t\tbackground: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */\n\t\tbackground: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */\n\t\tbackground: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }\n\n\t.button.full-width,\n\tbutton.full-width,\n\tinput[type=\"submit\"].full-width,\n\tinput[type=\"reset\"].full-width,\n\tinput[type=\"button\"].full-width {\n\t\twidth: 100%;\n\t\tpadding-left: 0 !important;\n\t\tpadding-right: 0 !important;\n\t\ttext-align: center; }\n\n\t/* Fix for odd Mozilla border & padding issues */\n\tbutton::-moz-focus-inner,\n\tinput::-moz-focus-inner {\n    border: 0;\n    padding: 0;\n\t}\n\n\n/* #Tabs (activate in tabs.js)\n================================================== */\n\tul.tabs {\n\t\tdisplay: block;\n\t\tmargin: 0 0 20px 0;\n\t\tpadding: 0;\n\t\tborder-bottom: solid 1px #ddd; }\n\tul.tabs li {\n\t\tdisplay: block;\n\t\twidth: auto;\n\t\theight: 30px;\n\t\tpadding: 0;\n\t\tfloat: left;\n\t\tmargin-bottom: 0; }\n\tul.tabs li a {\n\t\tdisplay: block;\n\t\ttext-decoration: none;\n\t\twidth: auto;\n\t\theight: 29px;\n\t\tpadding: 0px 20px;\n\t\tline-height: 30px;\n\t\tborder: solid 1px #ddd;\n\t\tborder-width: 1px 1px 0 0;\n\t\tmargin: 0;\n\t\tbackground: #f5f5f5;\n\t\tfont-size: 13px; }\n\tul.tabs li a.active {\n\t\tbackground: #fff;\n\t\theight: 30px;\n\t\tposition: relative;\n\t\ttop: -4px;\n\t\tpadding-top: 4px;\n\t\tborder-left-width: 1px;\n\t\tmargin: 0 0 0 -1px;\n\t\tcolor: #111;\n\t\t-moz-border-radius-topleft: 2px;\n\t\t-webkit-border-top-left-radius: 2px;\n\t\tborder-top-left-radius: 2px;\n\t\t-moz-border-radius-topright: 2px;\n\t\t-webkit-border-top-right-radius: 2px;\n\t\tborder-top-right-radius: 2px; }\n\tul.tabs li:first-child a.active {\n\t\tmargin-left: 0; }\n\tul.tabs li:first-child a {\n\t\tborder-width: 1px 1px 0 1px;\n\t\t-moz-border-radius-topleft: 2px;\n\t\t-webkit-border-top-left-radius: 2px;\n\t\tborder-top-left-radius: 2px; }\n\tul.tabs li:last-child a {\n\t\t-moz-border-radius-topright: 2px;\n\t\t-webkit-border-top-right-radius: 2px;\n\t\tborder-top-right-radius: 2px; }\n\n\tul.tabs-content { margin: 0; display: block; }\n\tul.tabs-content > li { display:none; }\n\tul.tabs-content > li.active { display: block; }\n\n\t/* Clearfixing tabs for beautiful stacking */\n\tul.tabs:before,\n\tul.tabs:after {\n\t  content: '\\0020';\n\t  display: block;\n\t  overflow: hidden;\n\t  visibility: hidden;\n\t  width: 0;\n\t  height: 0; }\n\tul.tabs:after {\n\t  clear: both; }\n\tul.tabs {\n\t  zoom: 1; }\n\n\n/* #Forms\n================================================== */\n\n\tform {\n\t\tmargin-bottom: 20px; }\n\tfieldset {\n\t\tmargin-bottom: 20px; }\n\tinput[type=\"text\"],\n\tinput[type=\"password\"],\n\tinput[type=\"email\"],\n\ttextarea,\n\tselect {\n\t\tborder: 1px solid #ccc;\n\t\tpadding: 6px 4px;\n\t\toutline: none;\n\t\t-moz-border-radius: 2px;\n\t\t-webkit-border-radius: 2px;\n\t\tborder-radius: 2px;\n\t\tfont: 13px \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\t\tcolor: #777;\n\t\tmargin: 0;\n\t\twidth: 210px;\n\t\tmax-width: 100%;\n\t\tdisplay: block;\n\t\tmargin-bottom: 20px;\n\t\tbackground: #fff; }\n\tselect {\n\t\tpadding: 0; }\n\tinput[type=\"text\"]:focus,\n\tinput[type=\"password\"]:focus,\n\tinput[type=\"email\"]:focus,\n\ttextarea:focus {\n\t\tborder: 1px solid #aaa;\n \t\tcolor: #444;\n \t\t-moz-box-shadow: 0 0 3px rgba(0,0,0,.2);\n\t\t-webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);\n\t\tbox-shadow:  0 0 3px rgba(0,0,0,.2); }\n\ttextarea {\n\t\tmin-height: 60px; }\n\tlabel,\n\tlegend {\n\t\tdisplay: block;\n\t\tfont-weight: bold;\n\t\tfont-size: 13px;  }\n\tselect {\n\t\twidth: 220px; }\n\tinput[type=\"checkbox\"] {\n\t\tdisplay: inline; }\n\tlabel span,\n\tlegend span {\n\t\tfont-weight: normal;\n\t\tfont-size: 13px;\n\t\tcolor: #444; }\n\n/* #Misc\n================================================== */\n\t.remove-bottom { margin-bottom: 0 !important; }\n\t.half-bottom { margin-bottom: 10px !important; }\n\t.add-bottom { margin-bottom: 20px !important; }\n\n\n"
  },
  {
    "path": "web/stylesheets/grench.css",
    "content": "body {\n    padding: 50px 0 200px 0;\n}\n\nh1, h2, h3, h4, h5, h6 {\n    font-family: \"Bitter\", serif;\n    font-weight: 400;\n}\n\nnav#links {\n    margin-top: 149px;\n}\n\n/* nav#links > a { float: left; }  */\n/* nav#links > a + a:before { display: block; float: left; content: ' | '; } */\n\n.constant {\n color: #25536D;\n}\n\na, a:visited {\n  color: #25536D;\n  text-decoration: none;\n  border-bottom: 1px solid;\n}\n\na:hover, a:focus {\n color: black;\n}\n\n\np {\n    text-align: justify;\n    -webkit-hyphens: auto;\n    -moz-hyphens: auto;\n}\n\np#pitch {\n    text-align: left;\n}\n\npre, tt, kbd, code {\n    font-family: 'Inconsolata', 'Consolas', mono;\n}\n\n#sample {\n    font-size: 16px;\n}\n\nhr {\n    margin: 35px 0;\n}\n\nh3 {\n    margin: 21px 0;\n}\n\n#footer p {\n    text-align: center;\n}\n\n.etc {\n    font-size: 90%;\n}\n\npre#sample {\n    padding: 0.5em;\n    color: white;\n    background-color: #3F3F3F;\n    border-style: solid;\n    border-width: 3px;\n    border-color: #ddd;\n    border-radius: 5px;\n}\n\npre .prompt {\n    font-weight: bold;\n}\n\npre .stdout {\n    color: #cc9393;\n}\n\npre .timing {\n    color: #bfebbf;\n}\n\nul.download {\n    list-style-position: inside;\n    list-style-type: disc;\n}\n\n@font-face {\n  font-family: 'Inconsolata';\n  font-style: normal;\n  font-weight: 400;\n  font-stretch: normal;\n  src: url(/inconsolata.ttf) format('truetype');\n}\n\n@font-face {\n  font-family: 'Bitter';\n  font-style: normal;\n  font-weight: 400;\n  src: url(/bitter.ttf) format('truetype');\n}\n"
  },
  {
    "path": "web/stylesheets/htmlize.css",
    "content": "body {\n    color: #000000;\n    background-color: #ffffff;\n}\n.constant {\n    /* font-lock-constant-face */\n    color: #008b8b;\n}\n.esk-paren {\n    /* esk-paren-face */\n    color: #8c8c8c;\n}\n.hl-line {\n    /* hl-line */\n    background-color: #b4eeb4;\n}\n.string {\n    /* font-lock-string-face */\n    color: #8b2252;\n}\n"
  },
  {
    "path": "web/stylesheets/layout.css",
    "content": "/*\n* Skeleton V1.1\n* Copyright 2011, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://www.opensource.org/licenses/mit-license.php\n* 8/17/2011\n*/\n\n/* Table of Content\n==================================================\n\t#Site Styles\n\t#Page Styles\n\t#Media Queries\n\t#Font-Face */\n\n/* #Site Styles\n================================================== */\n\n/* #Page Styles\n================================================== */\n\n/* #Media Queries\n================================================== */\n\n\t/* Smaller than standard 960 (devices and browsers) */\n\t@media only screen and (max-width: 959px) {}\n\n\t/* Tablet Portrait size to standard 960 (devices and browsers) */\n\t@media only screen and (min-width: 768px) and (max-width: 959px) {}\n\n\t/* All Mobile Sizes (devices and browser) */\n\t@media only screen and (max-width: 767px) {}\n\n\t/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */\n\t@media only screen and (min-width: 480px) and (max-width: 767px) {}\n\n\t/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */\n\t@media only screen and (max-width: 479px) {}\n\n\n/* #Font-Face\n================================================== */\n/* \tThis is the proper syntax for an @font-face file\n\t\tJust create a \"fonts\" folder at the root,\n\t\tcopy your FontName into code below and remove\n\t\tcomment brackets */\n\n/*\t@font-face {\n\t    font-family: 'FontName';\n\t    src: url('../fonts/FontName.eot');\n\t    src: url('../fonts/FontName.eot?iefix') format('eot'),\n\t         url('../fonts/FontName.woff') format('woff'),\n\t         url('../fonts/FontName.ttf') format('truetype'),\n\t         url('../fonts/FontName.svg#webfontZam02nTh') format('svg');\n\t    font-weight: normal;\n\t    font-style: normal; }\n*/"
  },
  {
    "path": "web/stylesheets/lein.css",
    "content": "body {\n    padding: 50px 0 200px 0;\n}\n\nh1, h2, h3, h4, h5, h6 {\n    font-family: \"Bitter\", serif;\n    font-weight: 400;\n}\n\nnav#links {\n    margin-top: 149px;\n}\n\n/* nav#links > a { float: left; }  */\n/* nav#links > a + a:before { display: block; float: left; content: ' | '; } */\n\n.constant {\n color: #25536D;\n}\n\na, a:visited {\n  color: #25536D;\n  text-decoration: none;\n  border-bottom: 1px solid;\n}\n\na:hover, a:focus {\n color: black;\n}\n\na.anchor {\n  text-decoration: none;\n  border-bottom: unset;\n}\n\np {\n    text-align: justify;\n    -webkit-hyphens: auto;\n    -moz-hyphens: auto;\n}\n\np#pitch {\n    text-align: left;\n}\n\npre, tt, kbd, code {\n  font-family: 'Inconsolata', 'Consolas', monospace;\n}\n\n#sample-project {\n    font-size: 16px;\n}\n\nhr {\n    margin: 35px 0;\n}\n\nh3 {\n    margin: 21px 0;\n}\n\n#footer p {\n    text-align: center;\n}\n\n@font-face {\n  font-family: 'Inconsolata';\n  font-style: normal;\n  font-weight: 400;\n  font-stretch: normal;\n  src: url(/inconsolata.ttf) format('truetype');\n}\n\n@font-face {\n  font-family: 'Bitter';\n  font-style: normal;\n  font-weight: 400;\n  src: url(/bitter.ttf) format('truetype');\n}\n"
  },
  {
    "path": "web/stylesheets/skeleton.css",
    "content": "/*\n* Skeleton V1.1\n* Copyright 2011, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://www.opensource.org/licenses/mit-license.php\n* 8/17/2011\n*/\n\n\n/* Table of Contents\n==================================================\n    #Base 960 Grid\n    #Tablet (Portrait)\n    #Mobile (Portrait)\n    #Mobile (Landscape)\n    #Clearing */\n\n\n\n/* #Base 960 Grid\n================================================== */\n\n    .container                                  { position: relative; width: 960px; margin: 0 auto; padding: 0; }\n    .container .column,\n    .container .columns                         { float: left; display: inline; margin-left: 10px; margin-right: 10px; }\n    .row                                        { margin-bottom: 20px; }\n\n    /* Nested Column Classes */\n    .column.alpha, .columns.alpha               { margin-left: 0; }\n    .column.omega, .columns.omega               { margin-right: 0; }\n\n    /* Base Grid */\n    .container .one.column,\n    .container .one.columns                     { width: 40px;  }\n    .container .two.columns                     { width: 100px; }\n    .container .three.columns                   { width: 160px; }\n    .container .four.columns                    { width: 220px; }\n    .container .five.columns                    { width: 280px; }\n    .container .six.columns                     { width: 340px; }\n    .container .seven.columns                   { width: 400px; }\n    .container .eight.columns                   { width: 460px; }\n    .container .nine.columns                    { width: 520px; }\n    .container .ten.columns                     { width: 580px; }\n    .container .eleven.columns                  { width: 640px; }\n    .container .twelve.columns                  { width: 700px; }\n    .container .thirteen.columns                { width: 760px; }\n    .container .fourteen.columns                { width: 820px; }\n    .container .fifteen.columns                 { width: 880px; }\n    .container .sixteen.columns                 { width: 940px; }\n\n    .container .one-third.column                { width: 300px; }\n    .container .two-thirds.column               { width: 620px; }\n\n    /* Offsets */\n    .container .offset-by-one                   { padding-left: 60px;  }\n    .container .offset-by-two                   { padding-left: 120px; }\n    .container .offset-by-three                 { padding-left: 180px; }\n    .container .offset-by-four                  { padding-left: 240px; }\n    .container .offset-by-five                  { padding-left: 300px; }\n    .container .offset-by-six                   { padding-left: 360px; }\n    .container .offset-by-seven                 { padding-left: 420px; }\n    .container .offset-by-eight                 { padding-left: 480px; }\n    .container .offset-by-nine                  { padding-left: 540px; }\n    .container .offset-by-ten                   { padding-left: 600px; }\n    .container .offset-by-eleven                { padding-left: 660px; }\n    .container .offset-by-twelve                { padding-left: 720px; }\n    .container .offset-by-thirteen              { padding-left: 780px; }\n    .container .offset-by-fourteen              { padding-left: 840px; }\n    .container .offset-by-fifteen               { padding-left: 900px; }\n\n\n\n/* #Tablet (Portrait)\n================================================== */\n\n    /* Note: Design for a width of 768px */\n\n    @media only screen and (min-width: 768px) and (max-width: 959px) {\n        .container                                  { width: 768px; }\n        .container .column,\n        .container .columns                         { margin-left: 10px; margin-right: 10px;  }\n        .column.alpha, .columns.alpha               { margin-left: 0; margin-right: 10px; }\n        .column.omega, .columns.omega               { margin-right: 0; margin-left: 10px; }\n        .alpha.omega                                { margin-left: 0; margin-right: 0; }\n\n        .container .one.column,\n        .container .one.columns                     { width: 28px; }\n        .container .two.columns                     { width: 76px; }\n        .container .three.columns                   { width: 124px; }\n        .container .four.columns                    { width: 172px; }\n        .container .five.columns                    { width: 220px; }\n        .container .six.columns                     { width: 268px; }\n        .container .seven.columns                   { width: 316px; }\n        .container .eight.columns                   { width: 364px; }\n        .container .nine.columns                    { width: 412px; }\n        .container .ten.columns                     { width: 460px; }\n        .container .eleven.columns                  { width: 508px; }\n        .container .twelve.columns                  { width: 556px; }\n        .container .thirteen.columns                { width: 604px; }\n        .container .fourteen.columns                { width: 652px; }\n        .container .fifteen.columns                 { width: 700px; }\n        .container .sixteen.columns                 { width: 748px; }\n\n        .container .one-third.column                { width: 236px; }\n        .container .two-thirds.column               { width: 492px; }\n\n        /* Offsets */\n        .container .offset-by-one                   { padding-left: 48px; }\n        .container .offset-by-two                   { padding-left: 96px; }\n        .container .offset-by-three                 { padding-left: 144px; }\n        .container .offset-by-four                  { padding-left: 192px; }\n        .container .offset-by-five                  { padding-left: 240px; }\n        .container .offset-by-six                   { padding-left: 288px; }\n        .container .offset-by-seven                 { padding-left: 336px; }\n        .container .offset-by-eight                 { padding-left: 384px; }\n        .container .offset-by-nine                  { padding-left: 432px; }\n        .container .offset-by-ten                   { padding-left: 480px; }\n        .container .offset-by-eleven                { padding-left: 528px; }\n        .container .offset-by-twelve                { padding-left: 576px; }\n        .container .offset-by-thirteen              { padding-left: 624px; }\n        .container .offset-by-fourteen              { padding-left: 672px; }\n        .container .offset-by-fifteen               { padding-left: 720px; }\n    }\n\n\n/*  #Mobile (Portrait)\n================================================== */\n\n    /* Note: Design for a width of 320px */\n\n    @media only screen and (max-width: 767px) {\n        .container { width: 300px; }\n        .container .columns,\n        .container .column { margin: 0; }\n\n        .container .one.column,\n        .container .one.columns,\n        .container .two.columns,\n        .container .three.columns,\n        .container .four.columns,\n        .container .five.columns,\n        .container .six.columns,\n        .container .seven.columns,\n        .container .eight.columns,\n        .container .nine.columns,\n        .container .ten.columns,\n        .container .eleven.columns,\n        .container .twelve.columns,\n        .container .thirteen.columns,\n        .container .fourteen.columns,\n        .container .fifteen.columns,\n        .container .sixteen.columns,\n        .container .one-third.column,\n        .container .two-thirds.column  { width: 300px; }\n\n        /* Offsets */\n        .container .offset-by-one,\n        .container .offset-by-two,\n        .container .offset-by-three,\n        .container .offset-by-four,\n        .container .offset-by-five,\n        .container .offset-by-six,\n        .container .offset-by-seven,\n        .container .offset-by-eight,\n        .container .offset-by-nine,\n        .container .offset-by-ten,\n        .container .offset-by-eleven,\n        .container .offset-by-twelve,\n        .container .offset-by-thirteen,\n        .container .offset-by-fourteen,\n        .container .offset-by-fifteen { padding-left: 0; }\n\n    }\n\n\n/* #Mobile (Landscape)\n================================================== */\n\n    /* Note: Design for a width of 480px */\n\n    @media only screen and (min-width: 480px) and (max-width: 767px) {\n        .container { width: 420px; }\n        .container .columns,\n        .container .column { margin: 0; }\n\n        .container .one.column,\n        .container .one.columns,\n        .container .two.columns,\n        .container .three.columns,\n        .container .four.columns,\n        .container .five.columns,\n        .container .six.columns,\n        .container .seven.columns,\n        .container .eight.columns,\n        .container .nine.columns,\n        .container .ten.columns,\n        .container .eleven.columns,\n        .container .twelve.columns,\n        .container .thirteen.columns,\n        .container .fourteen.columns,\n        .container .fifteen.columns,\n        .container .sixteen.columns,\n        .container .one-third.column,\n        .container .two-thirds.column { width: 420px; }\n    }\n\n\n/* #Clearing\n================================================== */\n\n    /* Self Clearing Goodness */\n    .container:after { content: \"\\0020\"; display: block; height: 0; clear: both; visibility: hidden; }\n\n    /* Use clearfix class on parent to clear nested columns,\n    or wrap each row of columns in a <div class=\"row\"> */\n    .clearfix:before,\n    .clearfix:after,\n    .row:before,\n    .row:after {\n      content: '\\0020';\n      display: block;\n      overflow: hidden;\n      visibility: hidden;\n      width: 0;\n      height: 0; }\n    .row:after,\n    .clearfix:after {\n      clear: both; }\n    .row,\n    .clearfix {\n      zoom: 1; }\n\n    /* You can also use a <br class=\"clear\" /> to clear columns */\n    .clear {\n      clear: both;\n      display: block;\n      overflow: hidden;\n      visibility: hidden;\n      width: 0;\n      height: 0;\n    }\n"
  },
  {
    "path": "web/template.html",
    "content": "<!DOCTYPE html>\n<head lang=\"en\">\n    <meta charset=\"utf-8\">\n    <title>$title$</title>\n    <meta name=\"description\" content=\"Leiningen: automating Clojure projects\">\n    <meta name=\"author\" content=\"Phil Hagelberg and contributors\">\n\n    <!-- Mobile Specific Metas\n  ================================================== -->\n    <meta name=\"viewport\"\n          content=\"width=device-width, initial-scale=1\">\n\n    <!-- Favicons + Manifest\n  ================================================== -->\n  <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/img/favicon/apple-touch-icon.png\">\n  <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/img/favicon/favicon-32x32.png\">\n  <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/img/favicon/favicon-16x16.png\">\n  <link rel=\"manifest\" href=\"/img/favicon/manifest.json\">\n  <link rel=\"mask-icon\" href=\"/img/favicon/safari-pinned-tab.svg\" color=\"#000000\">\n  <link rel=\"shortcut icon\" href=\"/img/favicon/favicon.ico\">\n  <meta name=\"msapplication-config\" content=\"/img/favicon/browserconfig.xml\">\n  <meta name=\"theme-color\" content=\"#ffffff\">\n\n    <!-- CSS\n  ================================================== -->\n    <link rel=\"stylesheet\" href=\"stylesheets/base.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/skeleton.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/layout.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/htmlize.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/lein.css\">\n</head>\n<body>\n\n  <div class=\"container\">\n    <div class=\"three columns offset-by-one\">\n      <img src=\"img/leiningen.jpg\" title=\"logo\" id=\"logo\">\n    </div>\n    <div class=\"eight columns offset-by-two\" id=\"title\">\n      <h1 class=\"remove-bottom\" style=\"margin-top: 40px\">Leiningen</h1>\n      <p>for automating Clojure projects without setting your hair on fire</p>\n      <nav id=\"links\" class=\"offset-by-three\">\n        <a href=\"/#install\">install</a> |\n        <a href=\"/#docs\">docs</a> |\n        <a href=\"/#community\">community</a> |\n        <a href=\"https://codeberg.org/leiningen/leiningen\">source</a>\n      </nav>\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"sixteen columns\">\n      ${body}\n    </div>\n\n    <div class=\"sixteen columns\"><hr /></div>\n\n    <div class=\"sixteen columns\" id=\"footer\">\n        <p>&copy; 2012-2024 Phil Hagelberg\n        and contributors. Licensed under\n        the <a href=\"https://codeberg.org/leiningen/leiningen/src/stable/COPYING\">EPL\n        1.0</a>. See the code\n        for <a href=\"https://codeberg.org/leiningen/leiningen/src/main/web\">this\n        site</a>.</p>\n    </div>\n    </div><!-- container -->\n\n</body>\n</html>\n"
  },
  {
    "path": "web/wiki/.gitignore",
    "content": "/index.cgi\n"
  },
  {
    "path": "web/wiki/.htaccess",
    "content": "Options -ExecCGI\n\nHeader set Strict-Transport-Security \"max-age=31536000\"\nHeader set X-Frame-Options \"DENY\"\nHeader set X-XSS-Protection \"1; mode=block\"\n\nRewriteRule \"^([-A-Za-z/]*)$\" \"https://codeberg.org/leiningen/leiningen/wiki/$1\"\n\nErrorDocument 404 /404.html\n"
  },
  {
    "path": "web/wiki/Makefile",
    "content": "upload: .htaccess\n\trsync -rAv $^ leiningen@wiki.leiningen.org:wiki.leiningen.org/\n"
  },
  {
    "path": "zsh_completion.zsh",
    "content": "#compdef lein\n\n# Lein ZSH completion function\n# Drop this somewhere in your $fpath (like /usr/share/zsh/site-functions)\n# and rename it _lein\n\n_lein() {\n  if (( CURRENT > 2 )); then\n    # shift words so _arguments doesn't have to be concerned with second command\n    (( CURRENT-- ))\n    shift words\n    # use _call_function here in case it doesn't exist\n    _call_function 1 _lein_${words[1]}\n  else\n    _values \"lein command\" \\\n      \"change[Rewrite project.clj by applying a function.]\" \\\n      \"check[Check syntax and warn on reflection.]\" \\\n      \"classpath[Print the classpath of the current project.]\" \\\n      \"clean[Remove all files from project's target-path.]\" \\\n      \"compile[Compile Clojure source into .class files.]\" \\\n      \"deploy[Build and deploy jar to remote repository.]\" \\\n      \"deps[Download all dependencies.]\" \\\n      \"do[Higher-order task to perform other tasks in succession.]\" \\\n      \"help[Display a list of tasks or help for a given task.]\" \\\n      \"install[Install the current project to the local repository.]\" \\\n      \"jar[Package up all the project's files into a jar file.]\" \\\n      \"javac[Compile Java source files.]\" \\\n      \"new[Generate project scaffolding based on a template.]\" \\\n      \"plugin[DEPRECATED. Please use the :user profile instead.]\" \\\n      \"pom[Write a pom.xml file to disk for Maven interoperability.]\" \\\n      \"release[Perform :release-tasks.]\" \\\n      \"repl[Start a repl session either with the current project or standalone.]\" \\\n      \"retest[Run only the test namespaces which failed last time around.]\" \\\n      \"run[Run a -main function with optional command-line arguments.]\" \\\n      \"search[Search remote maven repositories for matching jars.]\" \\\n      \"show-profiles[List all available profiles or display one if given an argument.]\" \\\n      \"test[Run the project's tests.]\" \\\n      \"trampoline[Run a task without nesting the project's JVM inside Leiningen's.]\" \\\n      \"uberjar[Package up the project files and dependencies into a jar file.]\" \\\n      \"update-in[Perform arbitrary transformations on your project map.]\" \\\n      \"upgrade[Upgrade Leiningen to specified version or latest stable.]\" \\\n      \"vcs[Interact with the version control system.]\" \\\n      \"version[Print version for Leiningen and the current JVM.]\" \\\n      \"with-profile[Apply the given task with the profile(s) specified.]\"\n  fi\n}\n\n_lein_plugin() {\n  _values \"lein plugin commands\" \\\n    \"install[Download, package, and install plugin jarfile into ~/.lein/plugins]\" \\\n    \"uninstall[Delete the plugin jarfile: \\[GROUP/\\]ARTIFACT-ID VERSION]\"\n}\n\n\n_lein_namespaces() {\n  if [ -f \"./project.clj\" -a -d \"$1\" ]; then\n    _values \"lein valid namespaces\" \\\n      $(find \"$1\" -type f -name \"*.clj\" -exec awk '/^\\(ns */ {gsub(\"\\\\)\", \"\", $2); print $2}' '{}' '+')\n  fi\n}\n\n\n_lein_run() {\n  _lein_namespaces \"src/\"\n}\n\n_lein_test() {\n  _lein_namespaces \"test/\"\n}\n\n"
  }
]