Boot: How to run with the clojure version declared in the :dependencies?

254 views
Skip to first unread message

Tassilo Horn

unread,
Jun 12, 2015, 8:08:17 PM6/12/15
to clo...@googlegroups.com
Hi all,

I'm toying around with boot and try to get my leiningen config converted
to it.

My build.boot contains

--8<---------------cut here---------------start------------->8---
(set-env!
:resource-paths #{"src" "resources"}
:dependencies '[[org.clojure/clojure "1.7.0-RC1"]
...])
--8<---------------cut here---------------end--------------->8---

but "boot repl" or `M-x cider-jack-in RET` in emacs still give me a REPL
running 1.6.0. I know I can call

$ BOOT_CLOJURE_VERSION="1.7.0-RC1" boot repl

or define the BOOT_CLOJURE_VERSION in a boot.properties file, but do I
really need to duplicate the clojure version?

Bye,
Tassilo

Dylan Butman

unread,
Jun 13, 2015, 8:37:16 PM6/13/15
to clo...@googlegroups.com
Yes you need to duplicate the version in a properties file or env variable. It's important to differentiate between runtime and compiled dependencies vs the environment that actually does the compiling. There could be instances where different versions may be needed.

Juho Teperi

unread,
Jun 14, 2015, 4:12:33 PM6/14/15
to clo...@googlegroups.com
I have tried to describe how to set Clojure version with Boot here: https://github.com/boot-clj/boot/wiki/Setting-Clojure-version

It should also explain why the duplication is required.

Tassilo Horn

unread,
Jun 15, 2015, 4:05:52 AM6/15/15
to Juho Teperi, clo...@googlegroups.com
Juho Teperi <juho....@iki.fi> writes:

> I have tried to describe how to set Clojure version with Boot
> here: https://github.com/boot-clj/boot/wiki/Setting-Clojure-version

Yes, I'm using that now, i.e., I set BOOT_CLOJURE_VERSION in
boot.properties. Is there a way to access that from my build.boot so
that I can do something like

:dependencies `[[org.clojure/clojure
~(System/getenv "BOOT_CLOJURE_VERSION")]
...]

Apparently, that returns nil and so does System/getProperty for
"BOOT_CLOJURE_VERSION" or "boot.clojure.version".

> It should also explain why the duplication is required.

Well, it explains why I have to have it in my :dependencies but not why
I also need to have BOOT_CLOJURE_VERSION. Of course, there's a
technical reason in that build.boot's evaluation already requires
clojure to be up and running but it wouldn't be overly complicated to
check if there's a declared clojure dep with just some shell processing.

While we are at it: why do I also need to pin the boot version when
using a boot.properties?

And what's the thing with :scope "provided"? IIUC, this means that apps
depending on my lib won't incorporate my lib's clojure dep transitively.
But is that really what I want? I mean, I use transducers so some
flavor of clojure 1.7.0 is a strict requirement. I don't really want to
dictate a specific version, i.e., 1.7.0-beta* or later would be fine.
But with :scope "provided" any app depending on my lib would just use
1.6.0 by default if I understand correctly, and that will simply not
work. With the explicit (non-provided scope) declarations, users are
still able to use whatever clojure 1.7 version they want using
:exclusions, no?

Bye,
Tassilo

Juho Teperi

unread,
Jun 15, 2015, 4:21:05 AM6/15/15
to clo...@googlegroups.com, juho....@iki.fi
Hi,


On Monday, June 15, 2015 at 11:05:52 AM UTC+3, Tassilo Horn wrote:
Juho Teperi <juho....@iki.fi> writes:

> I have tried to describe how to set Clojure version with Boot
> here: https://github.com/boot-clj/boot/wiki/Setting-Clojure-version

Yes, I'm using that now, i.e., I set BOOT_CLOJURE_VERSION in
boot.properties.  Is there a way to access that from my build.boot so
that I can do something like

  :dependencies `[[org.clojure/clojure
                   ~(System/getenv "BOOT_CLOJURE_VERSION")]
                  ...] 

Apparently, that returns nil and so does System/getProperty for
"BOOT_CLOJURE_VERSION" or "boot.clojure.version".

Boot might do this automatically in future. https://github.com/boot-clj/boot/issues/230
 

> It should also explain why the duplication is required.

Well, it explains why I have to have it in my :dependencies but not why
I also need to have BOOT_CLOJURE_VERSION.  Of course, there's a
technical reason in that build.boot's evaluation already requires
clojure to be up and running but it wouldn't be overly complicated to
check if there's a declared clojure dep with just some shell processing.

While we are at it: why do I also need to pin the boot version when
using a boot.properties?

Technical reasons. Micha is thinking about fixing the implementation so that it allows other Boot env variables and allows leaving out variables you don't want to set. https://github.com/boot-clj/boot/issues/229
 

And what's the thing with :scope "provided"?  IIUC, this means that apps
depending on my lib won't incorporate my lib's clojure dep transitively.
But is that really what I want?  I mean, I use transducers so some
flavor of clojure 1.7.0 is a strict requirement.  I don't really want to
dictate a specific version, i.e., 1.7.0-beta* or later would be fine.
But with :scope "provided" any app depending on my lib would just use
1.6.0 by default if I understand correctly, and that will simply not
work.  With the explicit (non-provided scope) declarations, users are
still able to use whatever clojure 1.7 version they want using
:exclusions, no?

Even if your library has direct dependency to Clojure, there is no assurance that that version will be used. If your lib has Clj 1.7 depenency and the app has  dependency to 1.6.0, the app's dependency will be used. It the application doesn't have Clojure dependency first transitive Clojure dependency will be used and there is no knowing what that is (might be e.g. 1.4.0 depending on what library the app has first in dependencies).

This page should describe how dependencies are resolved: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
Especially the dependency mediation part under transitive dependencies header.
 

Bye,
Tassilo

Tassilo Horn

unread,
Jun 15, 2015, 6:30:38 AM6/15/15
to Juho Teperi, clo...@googlegroups.com
Juho Teperi <juho....@iki.fi> writes:

Hi!

>> :dependencies `[[org.clojure/clojure
>> ~(System/getenv "BOOT_CLOJURE_VERSION")]
>> ...]
>
>
>> Apparently, that returns nil and so does System/getProperty for
>> "BOOT_CLOJURE_VERSION" or "boot.clojure.version".
>>
>
> Boot might do this automatically in
> future. https://github.com/boot-clj/boot/issues/230

Subscribed!

>> > It should also explain why the duplication is required.
>>
>> Well, it explains why I have to have it in my :dependencies but not
>> why I also need to have BOOT_CLOJURE_VERSION. Of course, there's a
>> technical reason in that build.boot's evaluation already requires
>> clojure to be up and running but it wouldn't be overly complicated to
>> check if there's a declared clojure dep with just some shell
>> processing.
>>
>> While we are at it: why do I also need to pin the boot version when
>> using a boot.properties?
>>
>
> Technical reasons. Micha is thinking about fixing the implementation so
> that it allows other Boot env variables and allows leaving out variables
> you don't want to set. https://github.com/boot-clj/boot/issues/229

Ok, thanks for the pointer.

>> And what's the thing with :scope "provided"? IIUC, this means that
>> apps depending on my lib won't incorporate my lib's clojure dep
>> transitively. But is that really what I want? I mean, I use
>> transducers so some flavor of clojure 1.7.0 is a strict requirement.
>> I don't really want to dictate a specific version, i.e., 1.7.0-beta*
>> or later would be fine. But with :scope "provided" any app depending
>> on my lib would just use 1.6.0 by default if I understand correctly,
>> and that will simply not work. With the explicit (non-provided
>> scope) declarations, users are still able to use whatever clojure 1.7
>> version they want using :exclusions, no?
>
> Even if your library has direct dependency to Clojure, there is no
> assurance that that version will be used. If your lib has Clj 1.7 depenency
> and the app has dependency to 1.6.0, the app's dependency will be used. It
> the application doesn't have Clojure dependency first transitive Clojure
> dependency will be used and there is no knowing what that is (might be e.g.
> 1.4.0 depending on what library the app has first in dependencies).
>
> This page should describe how dependencies are
> resolved:
> https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
> Especially the dependency mediation part under transitive dependencies
> header.

Ok, thanks. But still, without :scope "provided" chances are higher
that the "correct" clojure version will be used because it'll do the
right thing when the app has no clojure dependency declared on its own
and my lib is on top of the :dependencies. The :scope "provided" is a
good idea for libs that aren't frequenty updated because without that,
it could force a very outdated clojure version on lib-users.

Well, it seems like this is just another instance of "it would be great
if Maven version ranges were working and widely used". ;-)

Bye,
Tassilo
Reply all
Reply to author
Forward
0 new messages