<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions in tools.build</title>
<link>https://ask.clojure.org/index.php/questions/contrib-libs/tools-build</link>
<description></description>
<item>
<title>tools.build compile-clj capture out/err</title>
<link>https://ask.clojure.org/index.php/14648/tools-build-compile-clj-capture-out-err</link>
<description>&lt;p&gt;When calling &lt;code&gt;compile-clj&lt;/code&gt;, a user can pass in &lt;code&gt;:out&lt;/code&gt; and &lt;code&gt;:err&lt;/code&gt; to capture the output of the compilation call. However, if for some reason the sub-process exits with a non-0, &lt;code&gt;compile-clj&lt;/code&gt; throws without returning that output, making it hard to know what went wrong. (see here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/tools.build/blob/2d2f1b05fd84c3cc756221c17fcfb98034b4d65c/src/main/clojure/clojure/tools/build/tasks/compile_clj.clj#L120&quot;&gt;https://github.com/clojure/tools.build/blob/2d2f1b05fd84c3cc756221c17fcfb98034b4d65c/src/main/clojure/clojure/tools/build/tasks/compile_clj.clj#L120&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;I would find it helpful if the ex-data of the thrown exception included the &lt;code&gt;:out&lt;/code&gt; (variable &lt;code&gt;ps-out&lt;/code&gt; and &lt;code&gt;:err&lt;/code&gt; (variable &lt;code&gt;ps-err&lt;/code&gt;) from the &lt;code&gt;process/process&lt;/code&gt; call. Then I could have further insight into what went wrong.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14648/tools-build-compile-clj-capture-out-err</guid>
<pubDate>Mon, 28 Jul 2025 19:41:29 +0000</pubDate>
</item>
<item>
<title>tools.build fails with http_proxy/https_proxy set</title>
<link>https://ask.clojure.org/index.php/14602/tools-build-fails-with-httpproxy-httpsproxy-set</link>
<description>&lt;p&gt;The autopkgtest of the tools.build package fails with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Running tests in #{&quot;src/test/clojure&quot;}

Testing clojure.tools.build.tasks.test-basis
Warning: failed to load the S3TransporterFactory class
Jul 01, 2025 8:15:38 AM org.apache.http.impl.execchain.RetryExec execute
INFO: I/O exception (java.net.SocketException) caught when processing request to {s}-&amp;gt;https://repo1.maven.org:443: Network is unreachable
[...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The autopkgtest script debian/tests/source:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

set -ueo pipefail

cp=($(&amp;lt; debian/libtools-build-clojure.classpath))
test &quot;${cp[0]}&quot; = usr/share/java/tools.build.jar
unset cp[0] # drop it

test_cp=(src/main/clojure
         src/test/clojure
         /usr/share/java/test-runner.jar
         /usr/share/java/maven-resolver-named-locks.jar
         /usr/share/java/maven-repository-metadata-3.x.jar
         &quot;${cp[@]}&quot;)

test_cp=&quot;$(IFS=:; echo &quot;${test_cp[*]}&quot;)&quot;

# Derived from ./deps.edn, and avoids a circular dep on clojure-cli
java -XX:-OmitStackTraceInFastThrow -cp &quot;$test_cp&quot; clojure.main \
     -m cognitect.test-runner cognitect.test-runner.api/test \
     --dir src/test/clojure --namespace-regex '.*'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Ubuntu autopkgtest infrastructure restrict the Internet access and sets http_proxy/https_proxy.&lt;/p&gt;
&lt;p&gt;Please support those proxy settings.&lt;/p&gt;
&lt;p&gt;Bug-Ubuntu: &lt;a rel=&quot;nofollow&quot; href=&quot;https://launchpad.net/bugs/2115740&quot;&gt;https://launchpad.net/bugs/2115740&lt;/a&gt;&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14602/tools-build-fails-with-httpproxy-httpsproxy-set</guid>
<pubDate>Wed, 02 Jul 2025 11:56:53 +0000</pubDate>
</item>
<item>
<title>Please consider making tools.build pom.properties reproducible (e.g. the &quot;Generated by&quot; date)</title>
<link>https://ask.clojure.org/index.php/14389/please-consider-making-properties-reproducible-generated</link>
<description>&lt;p&gt;At the moment (in 1.2.24) the pom.properties includes the current date in a comment, making the resulting jars differ.  For now, in Debian we're deferring to SOURCE_DATE_EPOCH whenever it's set: &lt;a rel=&quot;nofollow&quot; href=&quot;https://salsa.debian.org/clojure-team/tools-build-clojure/-/blob/5739183ec76c39453ff267c6ba19c0605eb406b7/debian/patches/0002-write-pom-make-pom.properties-generated-date-reproducible.patch&quot;&gt;https://salsa.debian.org/clojure-team/tools-build-clojure/-/blob/5739183ec76c39453ff267c6ba19c0605eb406b7/debian/patches/0002-write-pom-make-pom.properties-generated-date-reproducible.patch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;See also:&lt;br&gt;
- &lt;a rel=&quot;nofollow&quot; href=&quot;https://bugs.debian.org/1095578&quot;&gt;https://bugs.debian.org/1095578&lt;/a&gt; &lt;br&gt;
- &lt;a rel=&quot;nofollow&quot; href=&quot;https://reproducible-builds.org/docs/&quot;&gt;https://reproducible-builds.org/docs/&lt;/a&gt;&lt;br&gt;
- &lt;a rel=&quot;nofollow&quot; href=&quot;https://tests.reproducible-builds.org/debian/pomegranate-clojure&quot;&gt;https://tests.reproducible-builds.org/debian/pomegranate-clojure&lt;/a&gt;&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14389/please-consider-making-properties-reproducible-generated</guid>
<pubDate>Sun, 16 Feb 2025 18:43:21 +0000</pubDate>
</item>
<item>
<title>How to ignore :src-pom default for clojure.tools.build.api/write-pom if ./pom.xml exists?</title>
<link>https://ask.clojure.org/index.php/13802/ignore-pom-default-for-clojure-tools-build-api-write-exists</link>
<description>&lt;p&gt;I have a project that generates more than one jar artifact. For project A, I have &lt;code&gt;./pom.xml&lt;/code&gt; that is used as a template and everything works fine.&lt;/p&gt;
&lt;p&gt;For project B, I want to generate a pom.xml that's completely separate from project A which does not use ./pom.xml as a template. I generate the pom as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(require '[clojure.tools.build.api :as b])
(b/write-pom {:class-dir class-dir
                  :pom-data pom-data
                  :lib coord
                  :version version
                  :basis basis})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, since &lt;code&gt;./pom.xml&lt;/code&gt; exists, it is used as a template. Explicitly passing &lt;code&gt;nil&lt;/code&gt; for &lt;code&gt;:src-pom&lt;/code&gt; doesn't help. The only workaround I could find was to pass in a bogus path for &lt;code&gt;:src-pom&lt;/code&gt;.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13802/ignore-pom-default-for-clojure-tools-build-api-write-exists</guid>
<pubDate>Sun, 31 Mar 2024 20:50:22 +0000</pubDate>
</item>
<item>
<title>Warn about user.clj during build compilation</title>
<link>https://ask.clojure.org/index.php/13770/warn-about-user-clj-during-build-compilation</link>
<description>&lt;p&gt;We’ve had a few cases where people encountered issues due to the existence of user.clj during uberjar building with tools.build. &lt;/p&gt;
&lt;p&gt;Because user loads early, anything it loads is not (typically) reloaded during compilation, which can lead to some namespaces not being compiled.&lt;/p&gt;
&lt;p&gt;Should maybe warn if user is on classpath or even actively recompile with something like &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(binding [*compile-files* true] (require 'user :reload-all))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13770/warn-about-user-clj-during-build-compilation</guid>
<pubDate>Wed, 28 Feb 2024 13:20:46 +0000</pubDate>
</item>
<item>
<title>switch tools.build to pull from jars rather than exploding onto disk</title>
<link>https://ask.clojure.org/index.php/13231/switch-tools-build-pull-from-jars-rather-than-exploding-onto</link>
<description>&lt;p&gt;Following on from &lt;a rel=&quot;nofollow&quot; href=&quot;https://ask.clojure.org/index.php/10854/getting-an-error-with-tools-build-uberjar?show=10854#q10854&quot;&gt;https://ask.clojure.org/index.php/10854/getting-an-error-with-tools-build-uberjar?show=10854#q10854&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jars are case-sensitive. This means that an uberjar can have a file named &lt;code&gt;license&lt;/code&gt; and &lt;code&gt;LICENSE/epl.txt&lt;/code&gt; simultaneously inside them. But if you explode these to disk when building an uberjar in a file system that is case-sensitive (in particular, OSX), you can an error along the lines of&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Execution error (ExceptionInfo) at clojure.tools.build.tasks.uber/explode1 (uber.clj:166).&lt;br&gt;
Cannot write META-INF/license/LICENSE.aix-netbsd.txt from io.grpc/grpc-netty-shaded as parent dir is a file from another lib. One of them must be excluded.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The solution to this is to track down the conflicting files and add them to exclusions. But often this can be tedious if the single file you want ot exclude &lt;code&gt;license&lt;/code&gt; exists and the error message is about one of several files that conflicts &lt;code&gt;LICENSE/epl.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The error is annoying also because these files can sit together just fine in an uberjar, but not in their temporary location on disk. It would be nice if the uberjar could just pull files from each jar rather than copy them onto disk in an intermediate step.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13231/switch-tools-build-pull-from-jars-rather-than-exploding-onto</guid>
<pubDate>Tue, 29 Aug 2023 20:49:38 +0000</pubDate>
</item>
<item>
<title>Can 'write-pom' in tools.build support providing additional dependencies in the pom.xml with scope 'provided'?</title>
<link>https://ask.clojure.org/index.php/12817/tools-support-providing-additional-dependencies-provided</link>
<description>&lt;p&gt;To work appropriately in the Java ecosystem, optional dependencies for libraries can be included with scope 'provided' within a pom.xml file. &lt;/p&gt;
&lt;p&gt;deps.edn explicitly does not support including dependencies with a scope of 'provided', in favour of using aliases. &lt;/p&gt;
&lt;p&gt;In order to work well as a library within a wider Java ecosystem, it would be very helpful to be able to write out a library jar file with a pom.xml file with additional dependencies that are not included in deps.edn, but with a scope of 'provided' for Java build tools.&lt;/p&gt;
&lt;p&gt;An example is cljdoc, which cannot build documentation when a library is built and all dependencies are not included appropriately.&lt;/p&gt;
&lt;p&gt;'write-pom' already has an option to include a template 'source' pom.xml, but the dependencies are overwritten with information from the deps.edn file. &lt;/p&gt;
&lt;p&gt;There are workarounds - e.g. see thread &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurians.slack.com/archives/C8V0BQ0M6/p1680090647156119&quot;&gt;https://clojurians.slack.com/archives/C8V0BQ0M6/p1680090647156119&lt;/a&gt;   which patch the process to include deps with a 'provided' scope - but they are not ideal. &lt;/p&gt;
&lt;p&gt;Options.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;do nothing - we monkey patch tools.build as per Slack thread example, or otherwise alter the generated pom.xml to include additional 'provided' scope deps.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;merge existing dependencies from the source (template) pom.xml instead of overwriting [but perhaps a breaking change]&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provide an additional parameter to 'write-pom' to include arbitrary deps, a sequence of maps that are converted to XML including :scope which would be :provided for these optional dependencies.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;work with cljdoc to support aliases so that documentation builds can be customised by library authors so builds such as this do not fail. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12817/tools-support-providing-additional-dependencies-provided</guid>
<pubDate>Wed, 29 Mar 2023 16:55:52 +0000</pubDate>
</item>
<item>
<title>tools.build.api/uber uses EDN for data_readers.cljc -- it should support reader conditionals</title>
<link>https://ask.clojure.org/index.php/12733/tools-build-datareaders-should-support-reader-conditionals</link>
<description>&lt;p&gt;The conflict handler for &lt;code&gt;data_readers.clj*&lt;/code&gt; treats the files as EDN when it reads them to merge them. This fails for &lt;code&gt;.cljc&lt;/code&gt; files containing reader conditionals:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RuntimeException No dispatch macro for: ?
	clojure.lang.Util.runtimeException (Util.java:221)
	clojure.lang.EdnReader$DispatchReader.invoke (EdnReader.java:552)
	clojure.lang.EdnReader.readDelimitedList (EdnReader.java:757)
	clojure.lang.EdnReader$MapReader.invoke (EdnReader.java:680)
	clojure.lang.EdnReader.read (EdnReader.java:145)
	clojure.lang.EdnReader.read (EdnReader.java:111)
	clojure.lang.EdnReader.readString (EdnReader.java:67)
	clojure.edn/read-string (edn.clj:46)
	clojure.edn/read-string (edn.clj:37)
	clojure.edn/read-string (edn.clj:37)
	clojure.tools.build.tasks.uber/conflict-data-readers (uber.clj:89)
	clojure.tools.build.tasks.uber/conflict-data-readers (uber.clj:86)
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12733/tools-build-datareaders-should-support-reader-conditionals</guid>
<pubDate>Tue, 07 Mar 2023 19:36:03 +0000</pubDate>
</item>
<item>
<title>Ability to customise java-cmd in tools.build</title>
<link>https://ask.clojure.org/index.php/12134/ability-to-customise-java-cmd-in-tools-build</link>
<description>&lt;p&gt;Moving the original &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurians.slack.com/archives/C02B5GHQWP4/p1661625386101119&quot;&gt;question&lt;/a&gt; from Clojurians Slack:&lt;/p&gt;
&lt;p&gt;When moving one of my projects to JDK 19 I was pointing clojure to the jdk using the &lt;strong&gt;JAVA_CMD&lt;/strong&gt; env var. Everything was fine til I hit the uber jar step in the CI, where it simply refused to recognise the jdk 19 functions.&lt;/p&gt;
&lt;p&gt;Took me a while and including reading the tools.build source to realise why it wasn't propagating the &lt;strong&gt;JAVA_CMD&lt;/strong&gt; var and turns out I had to read env and send the &lt;strong&gt;:java_cmd&lt;/strong&gt; in the &lt;strong&gt;b/compile-clj&lt;/strong&gt; call.&lt;/p&gt;
&lt;p&gt;I can see why the behaviour is like this, but would &lt;strong&gt;:java_cmd&lt;/strong&gt; defaulting to the value of &lt;strong&gt;JAVA_CMD&lt;/strong&gt; something that could be considered? Feels a bit more intuitive for me, as mostly the invocations of tools.build fns would be from the shell.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12134/ability-to-customise-java-cmd-in-tools-build</guid>
<pubDate>Sat, 27 Aug 2022 20:54:32 +0000</pubDate>
</item>
<item>
<title>Exception in EdnReader$DispatchReader</title>
<link>https://ask.clojure.org/index.php/12017/exception-in-ednreaderdispatchreader</link>
<description>&lt;p&gt;(from &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurians.slack.com/archives/C02B5GHQWP4/p1656165951371179&quot;&gt;https://clojurians.slack.com/archives/C02B5GHQWP4/p1656165951371179&lt;/a&gt;)&lt;br&gt;
When I include tick/tick {:mvn/version &quot;0.5.0-RC6&quot;} as a dep, I get the exception below.  I cannot reproduce in an deps.edn that only contains this library so I believe there is some kind of conflict with another library.  &lt;/p&gt;
&lt;p&gt;{:clojure.main/message&lt;br&gt;
 &quot;Execution error at clojure.tools.build.tasks.uber/conflict-data-readers (uber.clj:90).\nNo dispatch macro for: ?\n&quot;,&lt;br&gt;
 :clojure.main/triage&lt;br&gt;
 {:clojure.error/class java.lang.RuntimeException,&lt;br&gt;
  :clojure.error/line 90,&lt;br&gt;
  :clojure.error/cause &quot;No dispatch macro for: ?&quot;,&lt;br&gt;
  :clojure.error/symbol&lt;br&gt;
  clojure.tools.build.tasks.uber/conflict-data-readers,&lt;br&gt;
  :clojure.error/source &quot;uber.clj&quot;,&lt;br&gt;
  :clojure.error/phase :execution},&lt;br&gt;
 :clojure.main/trace&lt;br&gt;
 {:via&lt;br&gt;
  [{:type java.lang.RuntimeException,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:message &quot;No dispatch macro for: ?&quot;,
:at [clojure.lang.Util runtimeException &quot;Util.java&quot; 221]}],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  :trace&lt;br&gt;
  [[clojure.lang.Util runtimeException &quot;Util.java&quot; 221]&lt;br&gt;
   [clojure.lang.EdnReader$DispatchReader invoke &quot;EdnReader.java&quot; 552]&lt;br&gt;
   [clojure.lang.EdnReader readDelimitedList &quot;EdnReader.java&quot; 757]&lt;br&gt;
   [clojure.lang.EdnReader$MapReader invoke &quot;EdnReader.java&quot; 680]&lt;br&gt;
   [clojure.lang.EdnReader read &quot;EdnReader.java&quot; 145]&lt;br&gt;
   [clojure.lang.EdnReader read &quot;EdnReader.java&quot; 111]&lt;br&gt;
   [clojure.lang.EdnReader readString &quot;EdnReader.java&quot; 67]&lt;br&gt;
   [clojure.edn$read_string invokeStatic &quot;edn.clj&quot; 46]&lt;br&gt;
   [clojure.edn$read_string invokeStatic &quot;edn.clj&quot; 37]&lt;br&gt;
   [clojure.edn$read_string invoke &quot;edn.clj&quot; 37]&lt;br&gt;
   [clojure.tools.build.tasks.uber$conflict_data_readers&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;invokeStatic
&quot;uber.clj&quot;
90]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   [clojure.tools.build.tasks.uber$conflict_data_readers&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;invoke
&quot;uber.clj&quot;
86]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   [clojure.tools.build.tasks.uber$handle_conflict&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;invokeStatic
&quot;uber.clj&quot;
120]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   [clojure.tools.build.tasks.uber$handle_conflict&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;invoke
&quot;uber.clj&quot;
111]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   [clojure.tools.build.tasks.uber$explode invokeStatic &quot;uber.clj&quot; 157]&lt;br&gt;
   [clojure.tools.build.tasks.uber$explode invoke &quot;uber.clj&quot; 137]&lt;br&gt;
   [clojure.tools.build.tasks.uber$uber$fn&lt;strong&gt;3537$fn&lt;/strong&gt;3541&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;invoke
&quot;uber.clj&quot;
253]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   [clojure.lang.PersistentVector reduce &quot;PersistentVector.java&quot; 343]&lt;br&gt;
   [clojure.core$reduce invokeStatic &quot;core.clj&quot; 6885]&lt;br&gt;
   [clojure.core$reduce invoke &quot;core.clj&quot; 6868]&lt;br&gt;
   [clojure.tools.build.tasks.uber$uber$fn__3537 invoke &quot;uber.clj&quot; 252]&lt;br&gt;
   [clojure.core.protocols$iter_reduce invokeStatic &quot;protocols.clj&quot; 49]&lt;br&gt;
   [clojure.core.protocols$fn__8230 invokeStatic &quot;protocols.clj&quot; 75]&lt;br&gt;
   [clojure.core.protocols$fn__8230 invoke &quot;protocols.clj&quot; 75]&lt;br&gt;
   [clojure.core.protocols$fn&lt;strong&gt;8178$G&lt;/strong&gt;8173__8191&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;invoke
&quot;protocols.clj&quot;
13]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   [clojure.core$reduce invokeStatic &quot;core.clj&quot; 6886]&lt;br&gt;
   [clojure.core$reduce invoke &quot;core.clj&quot; 6868]&lt;br&gt;
   [clojure.tools.build.tasks.uber$uber invokeStatic &quot;uber.clj&quot; 250]&lt;br&gt;
   [clojure.tools.build.tasks.uber$uber invoke &quot;uber.clj&quot; 237]&lt;br&gt;
   [clojure.lang.Var invoke &quot;Var.java&quot; 384]&lt;br&gt;
   [clojure.tools.build.api$uber invokeStatic &quot;api.clj&quot; 480]&lt;br&gt;
   [clojure.tools.build.api$uber invoke &quot;api.clj&quot; 408]&lt;br&gt;
   [org.corfield.build$uber invokeStatic &quot;build.clj&quot; 250]&lt;br&gt;
   [org.corfield.build$uber invoke &quot;build.clj&quot; 208]&lt;br&gt;
   [build$uber invokeStatic &quot;build.clj&quot; 14]&lt;br&gt;
   [build$uber invoke &quot;build.clj&quot; 12]&lt;br&gt;
   [clojure.lang.AFn applyToHelper &quot;AFn.java&quot; 154]&lt;br&gt;
   [clojure.lang.AFn applyTo &quot;AFn.java&quot; 144]&lt;br&gt;
   [clojure.lang.Var applyTo &quot;Var.java&quot; 705]&lt;br&gt;
   [clojure.core$apply invokeStatic &quot;core.clj&quot; 667]&lt;br&gt;
   [clojure.core$apply invoke &quot;core.clj&quot; 662]&lt;br&gt;
   [clojure.run.exec$exec invokeStatic &quot;exec.clj&quot; 48]&lt;br&gt;
   [clojure.run.exec$exec doInvoke &quot;exec.clj&quot; 39]&lt;br&gt;
   [clojure.lang.RestFn invoke &quot;RestFn.java&quot; 423]&lt;br&gt;
   [clojure.run.exec$_main$fn__205 invoke &quot;exec.clj&quot; 180]&lt;br&gt;
   [clojure.run.exec$_main invokeStatic &quot;exec.clj&quot; 176]&lt;br&gt;
   [clojure.run.exec$_main doInvoke &quot;exec.clj&quot; 139]&lt;br&gt;
   [clojure.lang.RestFn applyTo &quot;RestFn.java&quot; 137]&lt;br&gt;
   [clojure.lang.Var applyTo &quot;Var.java&quot; 705]&lt;br&gt;
   [clojure.core$apply invokeStatic &quot;core.clj&quot; 667]&lt;br&gt;
   [clojure.main$main_opt invokeStatic &quot;main.clj&quot; 514]&lt;br&gt;
   [clojure.main$main_opt invoke &quot;main.clj&quot; 510]&lt;br&gt;
   [clojure.main$main invokeStatic &quot;main.clj&quot; 664]&lt;br&gt;
   [clojure.main$main doInvoke &quot;main.clj&quot; 616]&lt;br&gt;
   [clojure.lang.RestFn applyTo &quot;RestFn.java&quot; 137]&lt;br&gt;
   [clojure.lang.Var applyTo &quot;Var.java&quot; 705]&lt;br&gt;
   [clojure.main main &quot;main.java&quot; 40]],&lt;br&gt;
  :cause &quot;No dispatch macro for: ?&quot;}}&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12017/exception-in-ednreaderdispatchreader</guid>
<pubDate>Sat, 25 Jun 2022 16:32:02 +0000</pubDate>
</item>
<item>
<title>relative directories in classpath-roots</title>
<link>https://ask.clojure.org/index.php/11982/relative-directories-in-classpath-roots</link>
<description>&lt;p&gt;In the context of a monorepo containing several modules I have noticed an issue with &lt;code&gt;clojure.tools.build.api/compile-clj&lt;/code&gt; which is making difficult to compile files when the basis project root is not in the current directory.&lt;/p&gt;
&lt;p&gt;Here is a minimal scenario demonstrating the problem.&lt;/p&gt;
&lt;p&gt;I have a top-level monorepo &lt;code&gt;deps.edn&lt;/code&gt; using tools.build to prepare/package its modules&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; {:deps {monorepo/module-a {:local/root &quot;modules/a&quot;}}
 :aliases {:build {:deps {io.github.clojure/tools.build {:git/tag &quot;v0.8.2&quot;
                                                         :git/sha &quot;ba1a2bf&quot;}}
                   :ns-default build}}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Module A contains some clojure source files. Here is &lt;code&gt;modules/a/deps.edn&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{:paths [&quot;src&quot;]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those files require a compilation step. Here is the top-level &lt;code&gt;build.clj&lt;/code&gt; file expected to proccess those files.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(ns build
  (:require [clojure.tools.build.api :as b]))

(def module-a (binding [b/*project-root* &quot;modules/a&quot;]
                (b/create-basis {:project &quot;deps.edn&quot;})))

(defn compile-a [_]
  (b/compile-clj
   {:basis module-a
    :src-dirs [&quot;modules/a/src&quot;]
    :class-dir &quot;target/module-a/classes&quot;}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However when invoking &lt;code&gt;clojure -T:build compile-a&lt;/code&gt; from top-level directory I encounter the following error &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Execution error (FileNotFoundException) at user/eval136$fn (compile.clj:5).
Could not locate monorepo/module/a__init.class, monorepo/module/a.clj or monorepo/module/a.cljc on classpath.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem is that the  &quot;src&quot; relative directory is not expanded in the &lt;code&gt;:classpath-roots&lt;/code&gt; which lead &lt;code&gt;compile-clj&lt;/code&gt; to search source files in the wrong location. It is possible to work around the issue by  binding the &lt;code&gt;*project-root*&lt;/code&gt; again and adapting &lt;code&gt;:src-dirs&lt;/code&gt; and &lt;code&gt;class-dir&lt;/code&gt; relative to module A root directory like this&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn compile-a [_]
  (binding [b/*project-root* &quot;modules/a&quot;]
    (b/compile-clj
     {:basis module-a
      :src-dirs [&quot;src&quot;]
      :class-dir &quot;../../target/module-a/classes&quot;})))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However IMO it would be better if the computed classpath in the basis was fully expanded by transforming relative paths into absolute ones to avoid this extra ceremony.&lt;/p&gt;
&lt;p&gt;What do you think?&lt;br&gt;
Is there a reason why relative source path directories are currently kept relative ?&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11982/relative-directories-in-classpath-roots</guid>
<pubDate>Sun, 19 Jun 2022 16:50:53 +0000</pubDate>
</item>
<item>
<title>Files in deps :local/root :git/url will directly copy into uberjar without go through conflict-handlers</title>
<link>https://ask.clojure.org/index.php/11788/local-directly-uberjar-without-through-conflict-handlers</link>
<description>&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/tools.build/blob/1309f935b098123eb807c972a053eeab77f6f4cd/src/main/clojure/clojure/tools/build/tasks/uber.clj#L172&quot;&gt;https://github.com/clojure/tools.build/blob/1309f935b098123eb807c972a053eeab77f6f4cd/src/main/clojure/clojure/tools/build/tasks/uber.clj#L172&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The handling between jar and lib folders like git deps or local root are completely different. In my case, I have some config files in edn format (duct's duct_hierarchy.edn) exists in both jar deps and git deps. My additional conflict handler is never receiving the edn file that exists in git deps.&lt;/p&gt;
&lt;p&gt;Is it the expected behaviour? I can imagine that even &lt;strong&gt;LICENSE&lt;/strong&gt; or &lt;strong&gt;data_readers.clj&lt;/strong&gt; would suffer the same issue. e.g. being overrided by files in git deps.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11788/local-directly-uberjar-without-through-conflict-handlers</guid>
<pubDate>Fri, 22 Apr 2022 10:58:50 +0000</pubDate>
</item>
<item>
<title>Is it possible to set a var during compilation in tools.build?</title>
<link>https://ask.clojure.org/index.php/11610/is-it-possible-to-set-a-var-during-compilation-in-tools-build</link>
<description>&lt;p&gt;Specifically I'd like to set &lt;code&gt;clojure.test/*load-tests*&lt;/code&gt; to false, so that test code is excluded by the &lt;code&gt;clojure.test/deftest&lt;/code&gt;,&lt;code&gt;with-test&lt;/code&gt; etc. macro's. Lein provided injections as an escape hatch, tools.build doesn't seem to have an equivalent.&lt;/p&gt;
&lt;p&gt;Looking at the code, tools.build seems to compile code from a separate generated script in a temp file, which seems to make injections or wrappers impossible. Also couldn't find options to pass other than compiler options.&lt;/p&gt;
&lt;p&gt;A more in-depth description of this use case can be found on clojureverse: &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojureverse.org/t/require-import-inside-deftest/8644/3&quot;&gt;https://clojureverse.org/t/require-import-inside-deftest/8644/3&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Is there a solution or suggested workaround available?&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11610/is-it-possible-to-set-a-var-during-compilation-in-tools-build</guid>
<pubDate>Mon, 28 Feb 2022 20:50:43 +0000</pubDate>
</item>
<item>
<title>clojure.tools.build.api/process + ignore hangs when process has large output</title>
<link>https://ask.clojure.org/index.php/11510/clojure-tools-build-process-ignore-hangs-process-large-output</link>
<description>&lt;p&gt;Similar to &lt;a rel=&quot;nofollow&quot; href=&quot;https://ask.clojure.org/index.php/11509/clojure-launch-doesnt-consume-inputstream-process-terminating&quot;&gt;https://ask.clojure.org/index.php/11509/clojure-launch-doesnt-consume-inputstream-process-terminating&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;tools.build.api/process hangs when ignoring output and the process has large output. Here is curl downloading and printing 1mb of text:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clj -Sdeps '{:deps {io.github.clojure/tools.build {:git/tag &quot;v0.7.5&quot; :git/sha &quot;34727f7&quot;}}}'
Clojure 1.11.0-alpha3
user=&amp;gt; (require '[clojure.tools.build.api :as tb])

user=&amp;gt; (tb/process {:command-args [&quot;curl&quot; &quot;https://gist.githubusercontent.com/khaykov/a6105154becce4c0530da38e723c2330/raw/41ab415ac41c93a198f7da5b47d604956157c5c3/gistfile1.txt&quot;] :out :ignore})
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think instead of using PIPE, the ignore option should be using DISCARD:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/ProcessBuilder.Redirect.html#DISCARD&quot;&gt;https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/ProcessBuilder.Redirect.html#DISCARD&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One caveat: DISCARD is only available on Java 9 and newer. We could do resolve in a try/catch on the top level to see if DISCARD is available and then use that, if available and fall back on PIPE if it isn't. Alternatively, use a thread to consume output while the process is running or redirect to a temporary file.&lt;/p&gt;
&lt;p&gt;I'll provide a patch, if desired, and when agreed upon the direction of the solution.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11510/clojure-tools-build-process-ignore-hangs-process-large-output</guid>
<pubDate>Tue, 25 Jan 2022 09:56:37 +0000</pubDate>
</item>
<item>
<title>Will tools.build be released as a jar?</title>
<link>https://ask.clojure.org/index.php/11433/will-tools-build-be-released-as-a-jar</link>
<description>&lt;p&gt;I am developing a library with a dependency on tools.build and I would like to publish it as a jar.  Whilst tools.build is only available as a git dep, I cannot include it as a dependency in my pom file.  A wider discussion on this topic was held on this &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurians.slack.com/archives/C6QH853H8/p1641381677207800&quot;&gt;slack thread&lt;/a&gt;, where @alexmiller requested that I raise this topic here.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11433/will-tools-build-be-released-as-a-jar</guid>
<pubDate>Wed, 05 Jan 2022 15:02:43 +0000</pubDate>
</item>
<item>
<title>Allow specifying the output pom path</title>
<link>https://ask.clojure.org/index.php/11370/allow-specifying-the-output-pom-path</link>
<description>&lt;p&gt;My initial use for tools.build is to update the pom.xml in the project with the appropriate version.  It would be great if I could specify that write-pom should be output  to pom.xml, rather than the folder layout that is imposed on me by the current function.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11370/allow-specifying-the-output-pom-path</guid>
<pubDate>Tue, 07 Dec 2021 21:25:13 +0000</pubDate>
</item>
<item>
<title>tools.build/jar doesn't support &quot;sections&quot; in manifest</title>
<link>https://ask.clojure.org/index.php/11358/tools-build-jar-doesnt-support-sections-in-manifest</link>
<description>&lt;p&gt;Sections are groups which start with &lt;code&gt;Name: &lt;/code&gt; and have section-specific entries in them.&lt;/p&gt;
&lt;p&gt;Capsule uses this for having platform-specific information about how to start.&lt;/p&gt;
&lt;p&gt;Here's an example of using the API to get section information:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Main-Class: clojure.main

Name: Frank
Main-Class: frank.clojure.main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ clj       
Clojure 1.10.3
user=&amp;gt; (require '[clojure.java.io :as io])
nil
user=&amp;gt; (io/input-stream &quot;/tmp/MANIFEST.MF&quot;)
#object[java.io.BufferedInputStream 0x69ce2f62 &quot;java.io.BufferedInputStream@69ce2f62&quot;]
user=&amp;gt; (def mf (java.util.jar.Manifest. (io/input-stream &quot;/tmp/MANIFEST.MF&quot;)))
#'user/mf
user=&amp;gt; (.getAttributes mf &quot;Frank&quot;)
{#object[java.util.jar.Attributes$Name 0x2e3a5237 &quot;Main-Class&quot;] &quot;frank.clojure.main&quot;}
user=&amp;gt; (.getMainAttributes mf)
{#object[java.util.jar.Attributes$Name 0x2e3a5237 &quot;Main-Class&quot;] &quot;clojure.main&quot;}
user=&amp;gt; (.getEntries mf)
{&quot;Frank&quot; {#object[java.util.jar.Attributes$Name 0x2e3a5237 &quot;Main-Class&quot;] &quot;frank.clojure.main&quot;}}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11358/tools-build-jar-doesnt-support-sections-in-manifest</guid>
<pubDate>Sun, 05 Dec 2021 14:52:52 +0000</pubDate>
</item>
<item>
<title>tools.build copy-dir with replace loses file permissions</title>
<link>https://ask.clojure.org/index.php/11349/tools-build-copy-dir-with-replace-loses-file-permissions</link>
<description>&lt;p&gt;When you use &lt;code&gt;clojure.tools.build.api/copy-dir&lt;/code&gt; with &lt;code&gt;:replace&lt;/code&gt; it reads the source file and then writes a new target file -- it doesn't &quot;copy&quot; the file so the target file is created with default permissions.&lt;/p&gt;
&lt;p&gt;This is a problem if you are copying executable shell scripts and trying to replace text in them because the target file created &lt;em&gt;won't&lt;/em&gt; have executable permissions.&lt;/p&gt;
&lt;p&gt;This cropped up with &lt;code&gt;deps-new&lt;/code&gt; in this issue: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/seancorfield/deps-new/issues/22&quot;&gt;https://github.com/seancorfield/deps-new/issues/22&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I think that if you source file is executable, the target file should also be executable -- and that works fine without &lt;code&gt;:replace&lt;/code&gt;.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11349/tools-build-copy-dir-with-replace-loses-file-permissions</guid>
<pubDate>Fri, 03 Dec 2021 06:29:30 +0000</pubDate>
</item>
<item>
<title>Is it possible to build an uberwar using deps.edn using tools.build or other tool?</title>
<link>https://ask.clojure.org/index.php/11341/possible-build-uberwar-using-deps-using-tools-build-other-tool</link>
<description>&lt;p&gt;We have a small Clojure &amp;amp; ClojureScript web app running in Tomcat. The project managed to end up with a deps.edn for use with Shadow-cljs &amp;amp; lein for the backend to essentially build an uberwar. Is there a way to build an uberwar with tools-build or in some other way using deps.edn?&lt;/p&gt;
&lt;p&gt;Thanks for any pointers&lt;/p&gt;
&lt;p&gt;Cheers&lt;br&gt;
Daniel Sunnerek&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11341/possible-build-uberwar-using-deps-using-tools-build-other-tool</guid>
<pubDate>Thu, 02 Dec 2021 13:22:01 +0000</pubDate>
</item>
<item>
<title>tools.build uber's default conflict handlers don't append to META-INF/services properly</title>
<link>https://ask.clojure.org/index.php/11316/tools-default-conflict-handlers-append-services-properly</link>
<description>&lt;p&gt;Our project has some dependencies that register parsers for various file formats via the java services framework.&lt;/p&gt;
&lt;p&gt;We’re using &lt;code&gt;b/uber&lt;/code&gt; and are finding some &lt;code&gt;META-INF/services/&lt;/code&gt; definitions are not correctly being appended.  &lt;/p&gt;
&lt;p&gt;I’ve chased this down to the regex in the default-handlers being &lt;code&gt;^META-INF/services/&lt;/code&gt; instead of something more like &lt;code&gt;^META-INF/services/.*&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The current regex would match under &lt;code&gt;re-find&lt;/code&gt;, but not under &lt;code&gt;re-matches&lt;/code&gt; which the implementation uses.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11316/tools-default-conflict-handlers-append-services-properly</guid>
<pubDate>Fri, 26 Nov 2021 17:29:12 +0000</pubDate>
</item>
<item>
<title>tools.build uber task fails when the dependency tree contains a dep which has no jar</title>
<link>https://ask.clojure.org/index.php/11156/tools-build-uber-task-fails-when-dependency-contains-which</link>
<description>&lt;p&gt;The &lt;code&gt;clojure.tools.build.api/uber&lt;/code&gt; task fails when the dependency tree contains a dep which has no jar.  &lt;/p&gt;
&lt;p&gt;A relatively minimal failing test case is the following tools.build task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(ns build 
  (:require [clojure.tools.build.api :as b]))

(defn failing-uber [_]
    (b/uber {:class-dir &quot;classes&quot;
     :uber-file &quot;foo.jar&quot;
     :basis (b/create-basis {:project {:deps {'org.apache.jena/apache-jena-libs {:mvn/version &quot;4.2.0&quot; :extension &quot;pom&quot;} }}})})

(comment 
   (failing-uber {})
 )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Evaluating the above function results in the following exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. Unhandled clojure.lang.ExceptionInfo
   Unexpected lib file:
   /Users/rick/.m2/repository/org/apache/jena/apache-jena-libs/4.2.0/apache-jena-libs-4.2.0.pom
   {}
                  uber.clj:  182  clojure.tools.build.tasks.uber/explode
                  uber.clj:  141  clojure.tools.build.tasks.uber/explode
                  uber.clj:  257  clojure.tools.build.tasks.uber/uber/fn/fn
     PersistentVector.java:  343  clojure.lang.PersistentVector/reduce
                  core.clj: 6829  clojure.core/reduce
                  core.clj: 6812  clojure.core/reduce
                  uber.clj:  256  clojure.tools.build.tasks.uber/uber/fn
             protocols.clj:   49  clojure.core.protocols/iter-reduce
             protocols.clj:   75  clojure.core.protocols/fn
             protocols.clj:   75  clojure.core.protocols/fn
             protocols.clj:   13  clojure.core.protocols/fn/G
                  core.clj: 6830  clojure.core/reduce
                  core.clj: 6812  clojure.core/reduce
                  uber.clj:  254  clojure.tools.build.tasks.uber/uber
                  uber.clj:  241  clojure.tools.build.tasks.uber/uber
                  Var.java:  384  clojure.lang.Var/invoke
                   api.clj:  394  clojure.tools.build.api/uber
                   api.clj:  339  clojure.tools.build.api/uber
                      REPL:   21  build/eval25043
                      REPL:   21  build/eval25043
             Compiler.java: 7181  clojure.lang.Compiler/eval
             Compiler.java: 7136  clojure.lang.Compiler/eval
                  core.clj: 3202  clojure.core/eval
                  core.clj: 3198  clojure.core/eval
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 1977  clojure.core/with-bindings*
                  core.clj: 1977  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
               RestFn.java:  137  clojure.lang.RestFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj:  662  clojure.core/apply
                regrow.clj:   20  refactor-nrepl.ns.slam.hound.regrow/wrap-clojure-repl/fn
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   84  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  152  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  202  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  201  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  825  java.lang.Thread/run
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I believe this is because the above dependency has no corresponding jar file, and only contains a pom.xml which groups up a set of dependencies.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11156/tools-build-uber-task-fails-when-dependency-contains-which</guid>
<pubDate>Tue, 12 Oct 2021 14:00:42 +0000</pubDate>
</item>
<item>
<title>tools.build.api/copy-dir corrupts binary files if :replace is used</title>
<link>https://ask.clojure.org/index.php/11147/tools-build-api-copy-dir-corrupts-binary-files-replace-used</link>
<description>&lt;p&gt;Without a &lt;code&gt;:replace&lt;/code&gt; parameter, &lt;code&gt;b/copy-dir&lt;/code&gt; faithfully copies over any binary (and text) files in from the source directories.&lt;/p&gt;
&lt;p&gt;However, if a &lt;code&gt;:replace&lt;/code&gt; parameter is provided, then it corrupts any binary files when copying.  It does the replacement properly for any text files in the directories.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repro:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a source dir &lt;code&gt;mysrc&lt;/code&gt;.  In that dir, place the file&lt;br&gt;
&lt;code&gt;cryogen.png&lt;/code&gt; from&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://raw.githubusercontent.com/cryogen-project/cryogen/master/src/leiningen/new/cryogen/img/cryogen.png&quot;&gt;https://raw.githubusercontent.com/cryogen-project/cryogen/master/src/leiningen/new/cryogen/img/cryogen.png&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Then run &lt;code&gt;(b/copy-dir :src-dirs [&quot;mysrc&quot;] :target-dir &quot;newdir&quot; :replace {&quot;&amp;lt;&amp;lt;name&amp;gt;&amp;gt;&quot; &quot;me&quot;})&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;cryogen.png&lt;/code&gt; in &lt;code&gt;newdir&lt;/code&gt; will be corrupted.&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11147/tools-build-api-copy-dir-corrupts-binary-files-replace-used</guid>
<pubDate>Sun, 10 Oct 2021 01:32:33 +0000</pubDate>
</item>
<item>
<title>Add git-hash function</title>
<link>https://ask.clojure.org/index.php/11093/add-git-hash-function</link>
<description>&lt;p&gt;I want api to get git hash to find the exact version.&lt;br&gt;
Thank you.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn git-hash
  &quot;Shells out to git and returns hash of commits on this branch:
    git rev-parse HEAD

  Options:
    :dir - dir to invoke this command from, by default current directory
    :short? - shorten hash to 7 length characters&quot;
  [{:keys [dir short?] :or {dir &quot;.&quot;} :as params}]
  (assert-specs &quot;git-hash&quot; params
                :dir ::specs/path
                :short? ::specs/boolean)
  (-&amp;gt; {:command-args (cond-&amp;gt; [&quot;git&quot; &quot;rev-parse&quot;]
                       short? (conj &quot;--short&quot;)
                       :default (conj &quot;HEAD&quot;))
       :dir (.getPath (resolve-path dir))
       :out :capture}
      process
      :out
      str/trim))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11093/add-git-hash-function</guid>
<pubDate>Thu, 23 Sep 2021 14:30:27 +0000</pubDate>
</item>
<item>
<title>tools.build's compile-clj does not allow setting jvm options</title>
<link>https://ask.clojure.org/index.php/11078/tools-builds-compile-clj-does-not-allow-setting-jvm-options</link>
<description>&lt;p&gt;I've a project that uses Malli with a custom default registry, a feature which requires the code be compiled with a certain jvm opt set &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/metosin/malli#changing-the-default-registry&quot;&gt;as is detailed in its documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It was suggested to me in &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/seancorfield/build-clj/issues/7#issuecomment-924524367&quot;&gt;this issue&lt;/a&gt; that this is currently not supported in tools.build's &lt;code&gt;compile-clj&lt;/code&gt; function. I'm posting here in the hopes this can be filed as a feature request so that I can eventually move this project to tools.build.&lt;/p&gt;
&lt;p&gt;Thanks.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11078/tools-builds-compile-clj-does-not-allow-setting-jvm-options</guid>
<pubDate>Wed, 22 Sep 2021 14:03:32 +0000</pubDate>
</item>
<item>
<title>Add git-branch function</title>
<link>https://ask.clojure.org/index.php/11072/add-git-branch-function</link>
<description>&lt;p&gt;This is useful for deciding whether to issue a SNAPSHOT release or not.&lt;/p&gt;
&lt;p&gt;Here's a working implementation if anyone wants it for their project now:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(ns build
  (:require [clojure.string :as str]
            [clojure.tools.build.api :as b]
            [clojure.tools.build.api.specs :as specs]))

(defn git-branch
  &quot;Shells out to git and returns the current branch
    git branch --show-current
  Options:
    :dir - dir to invoke this command from, by default current directory&quot;
  [{:keys [dir] :or {dir &quot;.&quot;} :as params}]
  (@#'b/assert-specs &quot;git-branch&quot; params :dir ::specs/path)
  (-&amp;gt; {:command-args [&quot;git&quot; &quot;branch&quot; &quot;--show-current&quot;]
       :dir (.getPath (b/resolve-path dir))
       :out :capture}
    b/process
    :out
    str/trim))

(def lib 'my-group/my-lib)

(def version
  (if (= &quot;master&quot; (git-branch nil))
    (format &quot;1.0.%s&quot; (b/git-count-revs nil))
    (format &quot;1.0.%s-SNAPSHOT&quot; (b/git-count-revs nil))))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11072/add-git-branch-function</guid>
<pubDate>Mon, 20 Sep 2021 22:31:14 +0000</pubDate>
</item>
<item>
<title>Should tools.build functions respect with-dir (from tools.deps.alpha)?</title>
<link>https://ask.clojure.org/index.php/11027/should-tools-build-functions-respect-with-from-tools-alpha</link>
<description>&lt;p&gt;I ran across this issue with &lt;code&gt;depstar&lt;/code&gt; but observed that &lt;code&gt;tools.build&lt;/code&gt; behaves the same, possibly incorrect, way.&lt;/p&gt;
&lt;p&gt;See &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/seancorfield/with-dir-repro&quot;&gt;https://github.com/seancorfield/with-dir-repro&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you wrap &lt;code&gt;(b/create-basis ..)&lt;/code&gt; in &lt;code&gt;with-dir&lt;/code&gt; from &lt;code&gt;tools.deps.alpha&lt;/code&gt;, it calculates the basis from the &lt;code&gt;deps.edn&lt;/code&gt; file in the context of the &lt;code&gt;with-dir&lt;/code&gt; location.&lt;/p&gt;
&lt;p&gt;However, if you use that basis with &lt;code&gt;tools.build&lt;/code&gt; functions, they do not behave correctly -- even if they are also wrapped in the same &lt;code&gt;with-dir&lt;/code&gt; context.&lt;/p&gt;
&lt;p&gt;The dependencies come from the project &lt;code&gt;deps.edn&lt;/code&gt; (Clojure 1.9.0 in this example) but the &lt;code&gt;src&lt;/code&gt; used is from the root of the repo, not from the project folder.&lt;/p&gt;
&lt;p&gt;This is counter-intuitive (and took me a while to track down with &lt;code&gt;depstar&lt;/code&gt; -- where I definitely consider it to be a bug).&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11027/should-tools-build-functions-respect-with-from-tools-alpha</guid>
<pubDate>Wed, 08 Sep 2021 22:02:10 +0000</pubDate>
</item>
<item>
<title>How to control the transient deps that get compiled/assembled into an uberjar?</title>
<link>https://ask.clojure.org/index.php/10905/control-transient-deps-that-compiled-assembled-into-uberjar</link>
<description>&lt;p&gt;I am having trouble understanding how to control the contents of an uberjar using &lt;code&gt;tools.build&lt;/code&gt;. In this scenario, the runtime environment (a Spark cluster) provides some deps and thus those deps should not be in the uberjar. Let's say I have 2 classpaths (represented as aliases):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:compile&lt;/code&gt; The classpath with all deps/classes that are required for compilation. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;:uber&lt;/code&gt; The classpath with only the deps/classes that should be in the final jar. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In theory, if you take the &lt;code&gt;:compile&lt;/code&gt; classpath and subtract the &lt;code&gt;:uber&lt;/code&gt; classpath, we should get the set of classes that are provided by the runtime environment. &lt;/p&gt;
&lt;p&gt;Consider the following simplified dependency graph:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggTFJcbiAgICBwcm9qW215LnByb2plY3QvYXBwXSAtLT4gc3FsXG4gICAgcHJvaltteS5wcm9qZWN0L2FwcF0gLS0-IGNvcmVcbiAgICBwcm9qW215LnByb2plY3QvYXBwXSAtLT4gc2NhbGFcbiAgICBwcm9qW215LnByb2plY3QvYXBwXSAtLT4gb3RoZXJbc29tZS5vdGhlci9kZXBdXG4gICAgb3RoZXIgLS0-IHRyYW5zW3NvbWUudHJhbnNpZW50L2RlcF1cbiAgICBzcWxbb3JnLmFwYWNoZS5zcGFyay9zcWxdIC0tPiBjb3JlXG4gICAgY29yZVtvcmcuYXBhY2hlLnNwYXJrL2NvcmVdIC0tPiBhcGFjaGVbb3JnLmFwYWNoZS5jb21tb25zLypdXG4gICAgY29yZVtvcmcuYXBhY2hlLnNwYXJrL2NvcmVdIC0tPiBzY2FsYVtvcmcuc2NhbGEtbGFuZy9zY2FsYS1saWJyYXJ5XVxuICAgXG4gICAgc3R5bGUgc3FsIGZpbGw6I0ZGRlxuICAgIHN0eWxlIGNvcmUgZmlsbDojRkZGXG4gICAgc3R5bGUgc2NhbGEgZmlsbDojRkZGXG4gICAgc3R5bGUgYXBhY2hlIGZpbGw6I0ZGRiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In0sInVwZGF0ZUVkaXRvciI6ZmFsc2UsImF1dG9TeW5jIjp0cnVlLCJ1cGRhdGVEaWFncmFtIjpmYWxzZX0&quot; alt=&quot;dep graph&quot;&gt;&lt;/p&gt;
&lt;p&gt;We only need the blue deps to be in the jar. The white &quot;provided&quot; deps need to be used during compilation but should not be in the final uberjar. &lt;/p&gt;
&lt;p&gt;I looked into using the &lt;code&gt;:filter-nses&lt;/code&gt; option of &lt;code&gt;compile-clj&lt;/code&gt; but it creates problems with transient deps.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If we filter to only &lt;code&gt;my.project&lt;/code&gt; we will lose the important deps of &lt;code&gt;some.other/dep&lt;/code&gt; and &lt;code&gt;some.transient/dep&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If we filter to exclude &lt;code&gt;org.apache&lt;/code&gt; (not possible with &lt;code&gt;:filter-nses&lt;/code&gt;, but in theory it could be done) we would still have &lt;code&gt;org.scala-lang/scala-library&lt;/code&gt; hanging around.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also experimented using different calls to &lt;code&gt;create-basis&lt;/code&gt; during compile and jar building. I'm not sure if that makes any sense.&lt;/p&gt;
&lt;p&gt;Is it possible to leverage the dependency graph to control either 1) what gets compiled or 2) which classes get put into an uberjar? Any advice would be much appreciated.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10905/control-transient-deps-that-compiled-assembled-into-uberjar</guid>
<pubDate>Thu, 05 Aug 2021 16:36:31 +0000</pubDate>
</item>
<item>
<title>getting an error with tools.build uberjar</title>
<link>https://ask.clojure.org/index.php/10854/getting-an-error-with-tools-build-uberjar</link>
<description>&lt;p&gt;I'm creating an uberjar with &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;build=&amp;gt; (b/uber {:class-dir class-dir
                 :uber-file &quot;uberjar.jar&quot;
                 :basis     basis})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This throws an error&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;build=&amp;gt; (b/uber {:class-dir class-dir
                 :uber-file &quot;uberjar.jar&quot;
                 :basis     basis})
Execution error (FileNotFoundException) at java.io.FileOutputStream/open0 (FileOutputStream.java:-2).
/var/folders/_h/3fpgc8pj4fb2_w3mfqfl59fr0000gn/T/uber8421760143696109740/license/LICENSE (Not a directory)
build=&amp;gt; *e
#error {
 :cause &quot;/var/folders/_h/3fpgc8pj4fb2_w3mfqfl59fr0000gn/T/uber8421760143696109740/license/LICENSE (Not a directory)&quot;
 :via
 [{:type java.io.FileNotFoundException
   :message &quot;/var/folders/_h/3fpgc8pj4fb2_w3mfqfl59fr0000gn/T/uber8421760143696109740/license/LICENSE (Not a directory)&quot;
   :at [java.io.FileOutputStream open0 &quot;FileOutputStream.java&quot; -2]}]
 :trace
 [[java.io.FileOutputStream open0 &quot;FileOutputStream.java&quot; -2]
  [java.io.FileOutputStream open &quot;FileOutputStream.java&quot; 298]
  [java.io.FileOutputStream &amp;lt;init&amp;gt; &quot;FileOutputStream.java&quot; 237]
  [java.io.FileOutputStream &amp;lt;init&amp;gt; &quot;FileOutputStream.java&quot; 187]
  [clojure.tools.build.tasks.uber$explode invokeStatic &quot;uber.clj&quot; 66]
  [clojure.tools.build.tasks.uber$explode invoke &quot;uber.clj&quot; 53]
  [clojure.tools.build.tasks.uber$uber$fn__16290 invoke &quot;uber.clj&quot; 114]
  [clojure.core$run_BANG_$fn__8813 invoke &quot;core.clj&quot; 7717]
  [clojure.core.protocols$naive_seq_reduce invokeStatic &quot;protocols.clj&quot; 62]
  [clojure.core.protocols$interface_or_naive_reduce invokeStatic &quot;protocols.clj&quot; 72]
  [clojure.core.protocols$fn__8181 invokeStatic &quot;protocols.clj&quot; 169]
  [clojure.core.protocols$fn__8181 invoke &quot;protocols.clj&quot; 124]
  [clojure.core.protocols$fn__8136$G__8131__8145 invoke &quot;protocols.clj&quot; 19]
  [clojure.core.protocols$seq_reduce invokeStatic &quot;protocols.clj&quot; 31]
  [clojure.core.protocols$fn__8166 invokeStatic &quot;protocols.clj&quot; 75]
  [clojure.core.protocols$fn__8166 invoke &quot;protocols.clj&quot; 75]
  [clojure.core.protocols$fn__8110$G__8105__8123 invoke &quot;protocols.clj&quot; 13]
  [clojure.core$reduce invokeStatic &quot;core.clj&quot; 6830]
  [clojure.core$run_BANG_ invokeStatic &quot;core.clj&quot; 7712]
  [clojure.core$run_BANG_ invoke &quot;core.clj&quot; 7712]
  [clojure.tools.build.tasks.uber$uber invokeStatic &quot;uber.clj&quot; 114]
  [clojure.tools.build.tasks.uber$uber invoke &quot;uber.clj&quot; 104]
  [clojure.lang.Var invoke &quot;Var.java&quot; 384]
  [clojure.tools.build.api$uber invokeStatic &quot;api.clj&quot; 277]
  [clojure.tools.build.api$uber invoke &quot;api.clj&quot; 266]
  [build$eval16234 invokeStatic &quot;NO_SOURCE_FILE&quot; 11]
  [build$eval16234 invoke &quot;NO_SOURCE_FILE&quot; 11]
  [clojure.lang.Compiler eval &quot;Compiler.java&quot; 7181]
  [clojure.lang.Compiler eval &quot;Compiler.java&quot; 7136]
  [clojure.core$eval invokeStatic &quot;core.clj&quot; 3202]
  [clojure.core$eval invoke &quot;core.clj&quot; 3198]
  [clojure.main$repl$read_eval_print__9110$fn__9113 invoke &quot;main.clj&quot; 437]
  [clojure.main$repl$read_eval_print__9110 invoke &quot;main.clj&quot; 437]
  [clojure.main$repl$fn__9119 invoke &quot;main.clj&quot; 458]
  [clojure.main$repl invokeStatic &quot;main.clj&quot; 458]
  [clojure.core.server$repl invokeStatic &quot;server.clj&quot; 180]
  [clojure.core.server$repl invoke &quot;server.clj&quot; 180]
  [clojure.lang.AFn applyToHelper &quot;AFn.java&quot; 152]
  [clojure.lang.AFn applyTo &quot;AFn.java&quot; 144]
  [clojure.lang.Var applyTo &quot;Var.java&quot; 705]
  [clojure.core$apply invokeStatic &quot;core.clj&quot; 667]
  [clojure.core.server$accept_connection invokeStatic &quot;server.clj&quot; 73]
  [clojure.core.server$start_server$fn__8902$fn__8903$fn__8905 invoke &quot;server.clj&quot; 117]
  [clojure.lang.AFn run &quot;AFn.java&quot; 22]
  [java.lang.Thread run &quot;Thread.java&quot; 829]]}
build=&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This error is actually thrown from two libs on our classpath:&lt;br&gt;
- .m2/repository/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar&lt;br&gt;
- .m2/repository/xml-apis/xml-apis-ext/1.3.04/xml-apis-ext-1.3.04.jar&lt;/p&gt;
&lt;p&gt;Each of these has an entry &lt;code&gt;license/LICENSE&lt;/code&gt;. The problem seems to arise that I am on osx which uses a case insensitive but case-preserving filesystem and there is already a top-level &lt;code&gt;LICENSE&lt;/code&gt; file from another jar. So it cannot create a &lt;code&gt;license/LICENSE&lt;/code&gt; entry in addition to a &lt;code&gt;LICENSE&lt;/code&gt; file that already exists.&lt;/p&gt;
&lt;p&gt;I repod this with the following code that creates a few jars:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(ns build
  (:require [clojure.tools.build.api :as b]))

;; create a jar with just a single namespace and a license/LICENSE file
(b/write-file {:path &quot;target/liba/a.clj&quot;
               :content (symbol &quot;(ns a)&quot;)})
(b/write-file {:path &quot;target/liba/license/LICENSE&quot;
               :content (symbol &quot;this is the license from a&quot;)})
(b/write-file {:path &quot;target/liba/deps.edn&quot;
               :content '{:paths [&quot;.&quot;]}})
(b/write-pom {:basis (b/create-basis {:project &quot;target/liba/deps.edn&quot;})
              :class-dir &quot;target/liba&quot;
              :lib 'liba/liba
              :version &quot;1.0.0&quot;
              :src-dirs [&quot;target/liba&quot;]})
(b/jar {:class-dir &quot;target/liba&quot;
        :jar-file &quot;target/jars/liba.jar&quot;})

;; create another jar libb with just a single ns and a license file
(b/write-file {:path &quot;target/libb/b.clj&quot;
               :content (symbol &quot;(ns b)&quot;)})
(b/write-file {:path &quot;target/libb/license&quot;
               :content (symbol &quot;this is the license from b&quot;)})
(b/write-file {:path &quot;target/libb/deps.edn&quot;
               :content '{:paths [&quot;.&quot;]}})
(b/write-pom {:basis (b/create-basis {:project &quot;target/libb/deps.edn&quot;})
              :class-dir &quot;target/libb&quot;
              :lib 'libb/libb
              :version &quot;1.0.0&quot;
              :src-dirs [&quot;target/libb&quot;]})
(b/jar {:class-dir &quot;target/libb&quot;
        :jar-file &quot;target/jars/libb.jar&quot;})

;; create a consumer of these
(b/write-file {:path &quot;target/libc/license&quot;
               :content (symbol &quot;this is the license from c&quot;)})
(b/write-file {:path &quot;target/libc/deps.edn&quot;
               :content '{:deps {liba/liba {:local/root &quot;../jars/liba.jar&quot;}
                                 libb/libb {:local/root &quot;../jars/libb.jar&quot;}}}})

(def old-project-root b/*project-root*)
(b/set-project-root! &quot;target/libc&quot;)
#_(b/set-project-root! old-project-root)

(b/uber {:class-dir &quot;.&quot;
         :uber-file &quot;uberjar.jar&quot;
         :basis (b/create-basis {:project &quot;deps.edn&quot;})
         :main 'clojure.main})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But the basic error happens when trying to explode the jars and creating a folder &lt;code&gt;license&lt;/code&gt; when a file &lt;code&gt;LICENSE&lt;/code&gt; already exists.&lt;/p&gt;
&lt;p&gt;EDIT&lt;br&gt;
Sean mentioned that depstar has an api-compatible &lt;code&gt;uber&lt;/code&gt; function and that has worked for me. Since the contents of the jars never hit the filesystem this constraint is avoided.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10854/getting-an-error-with-tools-build-uberjar</guid>
<pubDate>Tue, 27 Jul 2021 15:48:45 +0000</pubDate>
</item>
<item>
<title>tools.build create-basis cannot use alias that includes tools.deps.alpha</title>
<link>https://ask.clojure.org/index.php/10852/tools-build-create-basis-cannot-alias-includes-tools-alpha</link>
<description>&lt;p&gt;If you try to call &lt;code&gt;create-basis&lt;/code&gt; with an alias that involves &lt;code&gt;tools.deps.alpha&lt;/code&gt;, you get the following exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Execution error (ExceptionInfo) at clojure.tools.deps.alpha.extensions.maven/get-artifact (maven.clj:133).
Could not find artifact org.clojure:tools.deps.alpha:jar:${project.version} in central (https://repo1.maven.org/maven2/)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is because &lt;code&gt;tools.build&lt;/code&gt; includes a source version of &lt;code&gt;deps.edn&lt;/code&gt; with that string, instead of a version number:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./tools.build/src/main/resources/clojure/tools/deps/deps.edn
    :deps {:extra-deps {org.clojure/tools.deps.alpha {:mvn/version &quot;${project.version}&quot;}}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here's the minimal repro: in an otherwise empty directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;; deps.edn 
{:aliases
 {:build
  {:deps {io.github.clojure/tools.build {:git/tag &quot;v0.1.6&quot; :git/sha &quot;5636e61&quot;}}
   :ns-default build}}}

;; build.clj 
(ns build
  (:require [clojure.tools.build.api :as b]))

(defn bug [_]
  (b/create-basis {:aliases [:deps]}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;clojure -T:build bug
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given that &lt;code&gt;tools.build&lt;/code&gt; already explicitly depends on t.d.a as follows, I don't understand why it also needs a copy of t.d.a's &lt;code&gt;deps.edn&lt;/code&gt; source in in the &lt;code&gt;resources&lt;/code&gt; tree?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;org.clojure/tools.deps.alpha {:mvn/version &quot;0.12.1003&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Removing that file from the checked out &lt;code&gt;tools.build&lt;/code&gt; (under &lt;code&gt;~/.gitlibs/libs&lt;/code&gt;) seems to solve the problem and doesn't &lt;em&gt;appear&lt;/em&gt; to break anything else...&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10852/tools-build-create-basis-cannot-alias-includes-tools-alpha</guid>
<pubDate>Mon, 26 Jul 2021 23:38:47 +0000</pubDate>
</item>
<item>
<title>What does &quot;Manifest type :jar not loaded when finding deps ...&quot; mean?</title>
<link>https://ask.clojure.org/index.php/10831/what-does-manifest-type-jar-not-loaded-when-finding-deps-mean</link>
<description>&lt;p&gt;I have a jar that I created from one of my projects using &lt;code&gt;tools.build&lt;/code&gt;. I have included it has a &lt;code&gt;:local/root&lt;/code&gt; dep in a different project but get the following error whenever I invoke &lt;code&gt;clj&lt;/code&gt; with the jar on the classpath.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Error building classpath. Manifest type :jar not loaded when finding deps for io.github.erp12/clark-scala in coordinate {:local/root &quot;/Users/eddie/Projects/Software/clark/clark-scala/target/clark-scala-2.12.13.1.jar&quot;, :deps/manifest :jar, :deps/root &quot;/Users/eddie/Projects/Software/clark/clark-scala/target/clark-scala-2.12.13.1.jar&quot;, :parents #{[]}, :paths [&quot;/Users/eddie/Projects/Software/clark/clark-scala/target/clark-scala-2.12.13.1.jar&quot;]}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This error message helps identify which dep (and in this case, which exact jar file) is causing the problem, but I don't know if there is any information in there that could help identify the cause problem. Am I missing the way to interpret this exception? Are there any common causes of this?&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10831/what-does-manifest-type-jar-not-loaded-when-finding-deps-mean</guid>
<pubDate>Sun, 18 Jul 2021 06:16:17 +0000</pubDate>
</item>
<item>
<title>Add ability to customize JAR manifest created by clojure.tools.build.api/uber</title>
<link>https://ask.clojure.org/index.php/10827/ability-customize-manifest-created-clojure-tools-build-uber</link>
<description>&lt;p&gt;There are several reasons we need to customize the META-INF/MANIFEST.MF file created by &lt;code&gt;clojure.tools.build.api/uber&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A Java library we use, Liquibase, &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.liquibase.com/tools-integrations/extensions/extension-upgrade-guides/lb-2.0-upgrade-guide.html&quot;&gt;requires a &lt;code&gt;Liquibase-Package&lt;/code&gt; entry in the manifest file to be used inside uberjars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;We'd like to exclude &lt;code&gt;Multi-Release: true&lt;/code&gt; from the built uberjar even tho some of our libs our multi-release. Log4j is an order of magnitude slower in a multi-release JAR and until we figure out how to fix that issue we've just been creating single-release JARs&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With Leiningen you can specify the contents of the manifest by including a &lt;code&gt;:manifest&lt;/code&gt; key in &lt;code&gt;project.clj&lt;/code&gt;... adding an option like that to &lt;code&gt;tools.build&lt;/code&gt; would be extremely helpful.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10827/ability-customize-manifest-created-clojure-tools-build-uber</guid>
<pubDate>Fri, 16 Jul 2021 19:53:16 +0000</pubDate>
</item>
<item>
<title>Exclude existing META-INF/MANIFEST.MF when invoking clojure.tools.build.api/uber</title>
<link>https://ask.clojure.org/index.php/10760/exclude-existing-meta-manifest-invoking-clojure-tools-build</link>
<description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;I have been trying to build an uberjar using tools.deps and I encountered the following exception:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Execution error (ZipException) at java.util.zip.ZipOutputStream/putNextEntry (ZipOutputStream.java:233).
duplicate entry: META-INF/MANIFEST.MF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is because one library appears to provides a META-INF/MANIFEST.MF that conflicts with the one &lt;code&gt;clojure.tools.build.api/uber&lt;/code&gt; is trying to add in the uberjar.&lt;/p&gt;
&lt;p&gt;I guess such file should be ignored by default for example by defining &lt;code&gt;clojure.tools.build.tasks.uber/uber-exclusions&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def ^:private uber-exclusions
  [#&quot;project.clj&quot;
   #&quot;META-INF/.*\.(?:SF|RSA|DSA|MF)&quot;])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don't have access to Clojure JIRA but If somebody give me access I am willing to provide a trivial patch containing this fix and a test case for the specific MANIFEST.MF exclusion.&lt;/p&gt;
</description>
<category>tools.build</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10760/exclude-existing-meta-manifest-invoking-clojure-tools-build</guid>
<pubDate>Sat, 10 Jul 2021 19:24:16 +0000</pubDate>
</item>
</channel>
</rss>