Fork me on GitHub
#boot
<
2017-02-05
>
moxaj00:02:11

@alandipert thanks i'll take a look

richiardiandrea00:02:50

@micha I was finally able to give a shot to my idea of declarative declaration of tasks: https://gist.github.com/arichiardi/7e4c430ff4ead706392f22e77c85b16a

richiardiandrea00:02:50

Any opinion is more than welcome, there is a custom macro behind of course 馃檪

richiardiandrea00:02:14

One thing is that defedntask does not declare parameters for now

richiardiandrea00:02:13

but everything is data, which makes everything really flexible

richiardiandrea00:02:01

the macro require the namespaces, resolves vars and composes the tasks

richiardiandrea01:02:17

Can the pom task generate poms for maven plugins? I see an issue already, it does not have a parent

richiardiandrea04:02:47

Uhm, working on the task above I wanted to add an option:

a parent SYM:VER=PATH       [sym str str]
but it throws a:
java.lang.Thread.run              Thread.java:  745
java.util.concurrent.ThreadPoolExecutor$Worker.run  ThreadPoolExecutor.java:  617
 java.util.concurrent.ThreadPoolExecutor.runWorker  ThreadPoolExecutor.java: 1142
               java.util.concurrent.FutureTask.run          FutureTask.java:  266
                                               ...                               
               clojure.core/binding-conveyor-fn/fn                 core.clj: 2020
                                 boot.core/boot/fn                 core.clj: 1030
                                               ...                               
                         boot.core/construct-tasks                 core.clj:  986
                                               ...                               
            boot.from.clojure.tools.cli/parse-opts                  cli.clj:  500
   boot.from.clojure.tools.cli/parse-option-tokens                  cli.clj:  350
                               clojure.core/reduce                 core.clj: 6703
                                               ...                               
boot.from.clojure.tools.cli/parse-option-tokens/fn                  cli.clj:  347
                              boot.cli/assoc-fn/fn                  cli.clj:   79
                               boot.cli/parse-type                  cli.clj:   62
                               clojure.core/symbol                 core.clj:  579
java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.String
  clojure.lang.ExceptionInfo: clojure.lang.PersistentVector cannot be cast to java.lang.String

qqq05:02:54

when using the (uber :as-jars true) task, how do I tell it to put jars in WEB-INF/lib/ while the classes in WEB-INF/classes ? right now, it's putting my *.jar files in WEB-INF/classes/ ... which I believe is causing problems

juhoteperi16:02:07

Boot-reload seems to have separate Slack webhook, I disabled that one now

mobileink20:02:49

@qqq: sift. or you could just use boot-gae/libs. 馃槈

qqq20:02:48

@mobileink : I could not imagine missing out on the fun of working things out from scratch

mobileink21:02:20

maybe, or rather most likely, you'll come with better ways to do things.

mobileink21:02:15

i'm still far from having solid intuitions about how best to write boot tasks.

mobileink21:02:19

i tend to hack at them until they more or less behave.

qqq21:02:55

@mobileink: I do have to give you props for one thing: the way you're using uber :as-jars + moving to lib/ results in FAR FAR FAR fewer class files than anything I've done in the past, and as a result, has resulted in FAR FAR FAR faster app_cfg.sh update .

mobileink21:02:28

ah, the creds there go to the boot devs, who seem to have thought about nearly everything, one way or another.

qqq21:02:27

something else I'm trying at the moment is only having clojure, javax.servlet, and com.google.appengine/appengine-api as dependencies (so no ring, no compojure) and seeing how far this works

qqq21:02:53

in theory it should be enough since: (1) all static files are handled by web.xml servlet, and (2) for all "REST" ish apis, I really only need one endpoint and have the request query encode everything

mobileink21:02:29

sure, you can get along fine w/out ring, etc., as long as you don't mind implementing the nitty-gritty stuff like dealing directly with the native request/response apis.

mobileink21:02:58

just defn -service.

qqq21:02:27

if we throw out all of routing, all I need are just /static -- web.xml handles it, serves static stuff /api -- takes EDN as input, produces EDN as output

mobileink21:02:50

yeah, if you do not need routing in your app there's no point in using a routing lib. just put defn -service or defn -doGet or whatever in your clojure delegate ns.

mobileink21:02:31

you'll have to use java interop in your handler, but that's easy. once it's debugged you can aot the whole thing to get a little more speed.

mobileink21:02:43

a demo showing this in boot-gae-examples is on my backlist, maybe you'll contrib one? 馃槈

qqq21:02:26

yeah (1) I think all I need are doGet, doPost, and doPut

qqq21:02:33

and (2) as a result, my war only has 3 JAR dependencies

mobileink21:02:51

we should probably move this to a different channel, like #web or #google-cloud . i don't know how to do this automagically.

mobileink21:02:26

in any case, if your processing is simple enough you might be better off dropping clojure altogether in your backend app, just use java.

mobileink21:02:01

then you can lose the clojure jar and startup cost .

anmonteiro22:02:26

hrm, boot-cljs-test is adding a 2nd CLJS to my dependencies which causes warnings like:

Classpath conflict: org.clojure/google-closure-library version 0.0-20160609-f42b4a24 already loaded, ALSO loading version 0.0-20151016-61277aea
Classpath conflict: org.clojure/clojurescript version 1.9.456 already loaded, ALSO loading version 1.7.228
Classpath conflict: org.clojure/google-closure-library-third-party version 0.0-20160609-f42b4a24 already loaded, ALSO loading version 0.0-20151016-61277aea
Classpath conflict: org.clojure/tools.reader version 1.0.0-beta3 already loaded, ALSO loading version 1.0.0-alpha1

anmonteiro22:02:05

any idea to prevent it from injecting a second dep?

richiardiandrea22:02:36

@anmonteiro I would check if boot show -d shows the one that it is including it and then use :exclusions

juhoteperi22:02:55

@anmonteiro Are you using version 0.3.0 I think it should only add deps if you don't already have them

anmonteiro22:02:07

I'm using 0.3.0

anmonteiro22:02:11

but I definitely have the deps

juhoteperi22:02:27

It should also log a message when it is adding new deps

anmonteiro22:02:42

Adding: ([org.clojure/clojurescript "1.7.228"] [doo "0.1.7"]) to :dependencies

anmonteiro22:02:49

but I have ClojureScript 1.4.456 馃檪

juhoteperi22:02:09

That is strange, it should be checking current deps and not add deps that already exist

juhoteperi22:02:31

Are you dynamically adding deps in some tasks or something?

anmonteiro22:02:26

I don't believe so

richiardiandrea22:02:05

that Adding clause, I have never seen it anywhere...looks like tasks are injecting something (maybe)

anmonteiro22:02:13

@juhoteperi the problem is that u/filter-deps is checking for the exact version to be loaded

anmonteiro22:02:17

but maybe I'm misunderstanding, I don't know how pod/dependency-loaded? works

anmonteiro22:02:48

OK turns out this may be a bug in Boot

anmonteiro22:02:57

found the problem

anmonteiro22:02:23

this is how I'm including CLJS:

[org.clojure/clojurescript   "1.9.456" :classifier "aot"]

anmonteiro22:02:33

if I remove the "aot" classifier, everything works as expected

richiardiandrea22:02:51

maybe the comparison is by vector and it should be by symbol only ?

juhoteperi22:02:03

Probably dependency-loaded? breaks because the pom file is in different path

anmonteiro22:02:30

dependency-loaded? returns nil with AOTed CLJS

juhoteperi22:02:24

aoted jar doesn't contain pom.properties at all

juhoteperi22:02:10

Also, with aoted clojurescript, some packages are trying to load cljs 0.0-3165...

anmonteiro22:02:25

that's probably Doo

juhoteperi22:02:05

No, it is before I even gets to boot-cljs-test

juhoteperi22:02:24

It is piggieback

juhoteperi22:02:08

How do the classifiers work? Looks like the dependency with classifier doesn't replace normal one currently

juhoteperi22:02:17

Perhaps a bug in Boot?

anmonteiro22:02:02

edge case that didn't come up until now? 馃檪

richiardiandrea22:02:03

but boot probably just forwards to aether

juhoteperi22:02:04

Is the aot dependency supposed to be used alone or together with the normal dep?

anmonteiro22:02:31

yeah, definitely alone

juhoteperi22:02:28

after 5 exclusions I managed to get normal version exlucded

juhoteperi22:02:37

and reproduced the problem

anmonteiro22:02:52

right. this project has a bunch of exclusions

juhoteperi22:02:26

dependecy-loaded? is at least broken, and there is also something strange going on with normal version getting included even if there is aot version

juhoteperi22:02:53

Well, it is same with Lein, if I depend on aoted cljs, Reagent will bring on transitive dependency on normal dep

juhoteperi22:02:12

So I guess that is how Aether/maven is supposed to work

juhoteperi22:02:05

I think in java side they are often used for additional parts, and don't replace the main dependency, like sources or javadoc

qqq22:02:39

in boot, is it possible for one "watch" to trigger two different compiles? I want to say: if this src directory cahnges, compile (:optimizations :none :source-map true) to THIS DIR compile (:optimizations :advanced :source-map false) to OTHER DIR

richiardiandrea22:02:09

@juhoteperi Maven rules are weird indeed

richiardiandrea22:02:42

I have this bookmarked for checking every now and then 馃槃

richiardiandrea22:02:18

> NOTE: In two of these dependency references, we had to specify the <type/> element. This is because the minimal set of information for matching a dependency reference against a dependencyManagement section is actually {groupId, artifactId, type, classifier}. In many cases, these dependencies will refer to jar artifacts with no classifier. This allows us to shorthand the identity set to {groupId, artifactId}, since the default for the type field is jar, and the default classifier is null.

richiardiandrea22:02:53

so classifier is actually part of the resolution process and I would not be surprised it took precedence when specified

juhoteperi22:02:54

@anmonteiro I think it is safe to depend on both normal and aot dependency

richiardiandrea22:02:59

@qqq try to explore boot watch -h

juhoteperi22:02:16

You'll get the sources from both dependencies, but Clojure will anyway first use compiled classes

anmonteiro22:02:22

ah interesting

juhoteperi22:02:44

Aot contains all the same files as normal jar AND java classes

anmonteiro22:02:45

trying that now

qqq22:02:16

@richiardiandrea : does that provide more info than (doc watch)? as (doc watch) only gives me options :help :quiet :verbose :manual :debounce :include :ezclude

qqq22:02:29

from which it's not clear how to setup "one src directory, compile two times"

juhoteperi22:02:55

@qqq You could use multiple cljs tasks or one cljs task with multiple .cljs.edn

richiardiandrea22:02:58

@qqq no more info than that, I would play with include, exclude and the compile tasks, but I have never tried myself

qqq22:02:16

so here's the issue:

qqq22:02:30

(1) I know how ot setup the unoptimized compile (2) I know how to setup the optimized compile (3) I can solve this via two boot sessions

anmonteiro22:02:35

@juhoteperi that definitely works, but still feels like a hack

anmonteiro22:02:38

thanks! 馃檪

qqq22:02:43

my issue is: "is there some "parallel task" which taks two tasks ad makes one task out of it

qqq22:02:47

this doesn't seem like . 'watch' issue

qqq22:02:56

it seems like a different primitive for 'run two tasks in parallel'

micha22:02:17

running tasks in parallel introduces some tricky situations

juhoteperi22:02:50

@qqq Boot-cljs supports parallel compilation of multiple cljs.edn files

micha22:02:13

since the purpose of tasks is generally to manipulate the classpath, and the classpath is generally related to the filesystem, and the filesystem is globally shared

micha22:02:52

boot-cljs can do that because each cljs application is compiling files that will go in different places

qqq22:02:15

@micha: two different questions then: (1) should I just acept one boot one task, and avoid trying to "parallel" stuff in a single boot? (2) if I want to gen a optimized and unoptimized version -- do I run two separate boots, or do I use something else?

micha22:02:58

what is the objective?

micha22:02:28

if you make an optimized version that one will always take way longer than the unoptimized version i'm sure

qqq22:02:49

for dev, I want the unoptimized version; occasionally I want to test on the optimized version too, without having to wait for a boot jvm startup

micha22:02:50

so doing them in parallel will only save you like 100ms out of 10000 or more

juhoteperi22:02:08

@anmonteiro I wonder if Cljs is using classifiers like they are supposed to be used

micha22:02:13

even jvm startup is small compared to cljs compilation with advanced optimizations

juhoteperi22:02:31

I don't think dependency-loaded? can changed to take classified dependency into account

micha22:02:33

i mean clojure startup

qqq22:02:02

okay, so you're saying "just fire up a new boot every time you need an optimized version" because the optimized compile process is so slow

anmonteiro22:02:20

@juhoteperi I think ClojureScript is using classifiers as they are meant, but I could be wrong. The problem with dependency-loaded? is that the AOTed artifact doesn't have a properties.xml or whatever

juhoteperi22:02:57

With Java libraries, they often have classifiers javadoc and sources, but those jars only contain docs or sources, so the normal dependency is also required

anmonteiro22:02:38

CLJS AOT doesn't seem to have .clj files, only cljs

micha22:02:42

@qqq i do all my development stuff without optimizations, and then test that optimizations don't break anything (like i forgot to include externs, whatever) before deploying to the staging environment

juhoteperi22:02:17

If it was enough for dependency-loaded? that there was any dependency with the id, adding only javadoc dependency would say that dependency is already provided though there are no classes

anmonteiro22:02:40

that makes sense

qqq22:02:43

@micha: yeah, that soudns more reasonable

juhoteperi22:02:43

Based on my understanding, it seems to be reasonable to add normal dependency in addition to aoted one. Then one doesn't need exclude normal one from all the other deps that have transitive dependency on that.

juhoteperi22:02:32

Also, cold cljs compiles times seem about the same for me with normal and aoted cljs 馃槥

anmonteiro22:02:14

@juhoteperi right, AOT is not about making compile times better

anmonteiro22:02:29

it's about loading speed of Clojure namespaces

anmonteiro22:02:41

it would make e.g. entering a REPL faster

juhoteperi22:02:41

Yeah, but is should make loading Cljs namespaces faster which should make build faster

anmonteiro22:02:57

not by a significant margin I would say

juhoteperi22:02:25

So what is the usecase?

anmonteiro22:02:10

@juhoteperi I think ClojureScript started having AOTed artifacts when David was messing with REPL startup

mobileink22:02:44

is it just me, or are maven scopes insane? e.g. :scope "compile" does not mean scope is :compile, it means scope is :all. even worse, maven scopes conflate (classpath) scope and transitivity, and the official docs fail to say explicitly how scopes work in most cases. and even worster, they make no distinction between dev, test, and prod execution environments.

juhoteperi22:02:24

maven doesn't have dev test or prod environments

juhoteperi22:02:21

But yeah, they feel quite lacking as they are hardcoded and the names don't describe their uses very clearly

mobileink22:02:37

but in at least some cases we have limited control over execution envs (i'm looking at you, gae), so what is "provided" in prod may not be provided in dev.

mobileink22:02:10

i would like to propose that boot remedy this.

juhoteperi22:02:28

I don't think solution to this can be tied to one build tool

micha23:02:15

the thing with maven scopes is that they're designed for use with maven the build tool

micha23:02:35

maven was very successful and the dependency package stuff has been coopted in various ways

micha23:02:03

in clojure we use the maven repos without actually using maven (aether, the dependency resolution library was factored out)

mobileink23:02:30

@juhoteperi i would not even try to solve it everywhere, just thinking about boot. e.g. instead of :scope "compile", sth like :scope [:compile :test :runtime]

micha23:02:46

i haven't found "provided" or "runtime" scopes to be useful with clojure projects

micha23:02:58

but "compile" and "test" seem to provide all the functionality i need

micha23:02:12

like i use "test" if there is a dependency that i don't want to be transitive

juhoteperi23:02:15

"provided" can be used in libraries to depend on clojure core non transitively

micha23:02:37

@juhoteperi yeah i have experimented with that

micha23:02:42

but i don't think it's a good idea imo

micha23:02:03

because when you declare a dependency as "provided" it doesn't show up in the dependency tree

juhoteperi23:02:45

Hmm, interesting

micha23:02:45

so my final thoughts we that if there is a contentious dependency, like org.clojure/clojure, that every library depends on, or the cljs compiler, etc

micha23:02:01

in that case the only sane thing is for the user to specify a version in their :dependencies

mobileink23:02:02

right but my bitch (let's be honest) is that a) the names are all wrong, and b) there's a big diif. between scope and transitivity. imho it would be better to make it all explict.

micha23:02:26

at least the user can use boot show -p for example to help decide which version might be the best

juhoteperi23:02:46

Well, we could probably provide something like Lein profiles to better control what dependencies use in what cases

juhoteperi23:02:08

But for the transitivity stuff, we can do nothing because that is implemented in aether

micha23:02:30

@mobileink the scope stuff is a maven thing, part of the POM spec

mobileink23:02:04

well, the issue i'm getting at is not just dependencies. it's more like dependency dependencies. ;)

micha23:02:23

also it's good to use the POM as correctly as possible because a maven user might want to use your clojure library

mobileink23:02:09

@micha: understood, my point is that does not impose requirements on the boot "api", so to speak.

micha23:02:22

@mobileink there is a thing called apache ivy, which might be interesting to look at

micha23:02:58

i haven't really used it, but i remember looking at it -- it has a more programmable resolution framework

mobileink23:02:39

maven says "provided". which is opaque if not inane. nothing stops us fron supporting sth less nutty, and translating it into maven-speak.

micha23:02:20

yeah i think "provided" is more for use with application containers, like tomcat etc

micha23:02:20

if you deploy uberjars (the usual thing) you don't need to worry about any of that

micha23:02:30

because there is no need for dependency resolution at runtime

micha23:02:13

the problem the tomcat guys had was that they needed to support hotloading jars into a running application

micha23:02:32

and they needed a way to organize the classpath in that weird situation

micha23:02:39

so there are some quirky things involved

micha23:02:13

nowadays we can deploy an uberjar to an EC2 (or GAE) instance and don't need to worry about application containers

mobileink23:02:19

yeah, but what "provided" means is not what it says. "compile" is even worse. imho we should be explicit: "provided: means on the compile and test classpaths, intransitive, that's all. so why not ":scope [:compile :test] :transitivity false"?

micha23:02:56

well boot doesn't have "compile and test classpaths"

micha23:02:07

boot is just a clojure program that runs and you program it what to do

micha23:02:33

maven has a built-in idea of "test mode" and "compile mode"

micha23:02:40

and other things, too

micha23:02:54

lein has similar concepts

micha23:02:32

but boot doesn't have any of that

mobileink23:02:41

@micha: imho that would be a problem, because boot does support :scope in depencencies.

micha23:02:58

apache aether supports it

micha23:02:04

which boot uses via pomegranate

micha23:02:29

but it works fine because the only things you care about when you consume a library in boot is whether a dependency is transitive or not

micha23:02:46

so boot is always working in what maven would call the compile classpath

micha23:02:03

well it's not even that simple

mobileink23:02:14

it sounds to me like there is a bit of a clash between boot and the underlying techs it uses.

micha23:02:16

i'm sure you saw the crazy matrix

micha23:02:27

i don't see an issue

micha23:02:43

^^ not trying to be a smartass, just want to know

mobileink23:02:57

fwiw in my experience figuring out what to do with :scope is a headache.

micha23:02:12

right, that's when you're crafting a POM

micha23:02:29

but when you consume a POM it's all very straightforward and automatic

micha23:02:55

like when you add a java dependency to your :dependencies, you don't need to ponder the meaning of scopes for it to work

micha23:02:07

aether takes care of that and it all works out as you'd expect

micha23:02:39

when you're making your own library thta will be used in your own or other people's projects as a :dependency, you need to make a POM and put your library in a repo

micha23:02:53

that's when you care about what the different scopes mean

micha23:02:23

and i personally believe that we only need to care about two of them: "compile" and "test"

mobileink23:02:26

crazy matrix? sounds interesting!

micha23:02:51

oh the maven POM spec has this matrix to "explain" how scopes work

micha23:02:02

but i've never met anyone who really understood it lol

micha23:02:17

i think you need to know a lot about maven the build tool to really get it

micha23:02:57

but i think if you're using boot to make libraries that you want to put in a maven repo you only need to know two scopes: "compile" and "test"

micha23:02:27

"compile" (or no scope, it's the default) is for dependencies your library needs to function correctly when its used in someone else's project

micha23:02:58

"test" is for dependencies your library has in development, that the consumer of your library will not need when they use it

micha23:02:08

and that's all you need to know, imho

micha23:02:32

so for example, if your library uses JSON, you might bring in [cheshire "1.2.3"]

micha23:02:59

that would be "compile" scope because if someone uses your library and they don't bring in that transitive dependency there will be a ClassNotFoundException

micha23:02:33

but suppose you use some tasks to build your library, like [adzerk/boot-cljs "4.5.6"]

micha23:02:01

in that case you'd use [adzerk/boot-cljs "4.5.6" :scope "test"], because when someone uses your library they won't have any use for that boot task

micha23:02:28

there is no need to use "provided" as far as i can tell

mobileink23:02:29

if my runtime env provides the libs i need?

mobileink23:02:45

i mean the prod runtime. e.g. gae.

micha23:02:14

like how do you mean?

micha23:02:22

which runtime are you referring to?

juhoteperi23:02:44

I think in those cases you would remove the dependencies when building the jar for the environment

mobileink23:02:45

so, i have a local dev/test env., and for that i need to include some jars that are already there in the (cloud) runtime.

micha23:02:04

the cloud runtime, is this like tomcat or somthing?

mobileink23:02:37

iow there is not just one "runtime", since we cannot always control eveything.

juhoteperi23:02:42

Yes, Google App Engine is similar to tomcat and such

micha23:02:10

so in that case you deploy applications to it, not libraries

mobileink23:02:14

gae is a derived version of jetty.

mobileink23:02:54

well, the line between lib and app is pretty thin. simple_smile

juhoteperi23:02:56

But yeah, scopes are not required in this case, it is your application packaging that must make the decisions which libraries to include in the package

micha23:02:26

but i don't 100% agree that libs and apps are a contimuum

micha23:02:31

continuum

micha23:02:38

i think there is a clean division

juhoteperi23:02:42

Though for this be easy, uber should probably allow blacklisting dependencies per artifact-id or something

mobileink23:02:06

@juhoteperi : ?? i list stuff in :dependencies, with :scope. am i missing sth.?

micha23:02:12

the difference is this: will the artifact be a dependency in another application?

micha23:02:30

if yes than it's a library, otherwise it's an appilcation

mobileink23:02:34

@micha: no. think servlets and micro-services.

micha23:02:40

if you make a library that needs [cheshire "1.2.3"] and you put that in a repo for people to use, you can't make it :scope "provided"

micha23:02:12

if you're loading jars into a classpath that already has stuff in it, there could be anything in there

micha23:02:28

so making scope "provided" in your special case doesn't work

mobileink23:02:40

we're no longer talking about our grampa's deps.

micha23:02:40

i would use exclusions in your case

micha23:02:59

if GAE already has dependencies on the classpath when it loads your code, you need to exclude those

micha23:02:07

when you make your application's POM

mobileink23:02:21

i csn write a service that will not be listed as a jar dep anywhere, but my app will depend on it. ok i'm splitting hairs, but i think theres sth there there.

micha23:02:33

it's not a dependency situation really

micha23:02:46

the POM is a way to declare dependencies

micha23:02:02

like the dependencies of your application, or the depenedncies of your library

micha23:02:18

applications are built from a collection of dependencies and some code that uses them

micha23:02:55

you wouldn't want to put your application POM in a maven repo probably because it would be broken if someone tried to use it outside of GAE

micha23:02:13

so imo it makes sense to cleanly delineate what is application and what is library

micha23:02:26

this works fine with micro services etc, in my experience

mobileink23:02:26

agreed, but there is no such thing as a mere dependency. they are always scoped. scoping is an essential property of a dependency, even if only implicitly.

micha23:02:48

what's the benefit of scope?

micha23:02:54

the classpath itself has no scope

micha23:02:13

you add jars and stuff to the classpath, and that's it

mobileink23:02:41

which classpath? compile, test, or runtime?

micha23:02:48

the JVM classpath

micha23:02:01

the JVM doesn't care about compile, test, runtime

mobileink23:02:11

no, but we do.

micha23:02:21

the scopes you see in the maven POM are just hints to some tool

micha23:02:31

it either adds the dependency to the classpath or it doesn't

micha23:02:39

but there are no actual scopes

micha23:02:52

like with lisp there are lexical scopes

micha23:02:57

those are a real thing

micha23:02:54

anyway, what i'm getting at is that you don't need scopes when you're making an application

micha23:02:03

and anything you're loading into GAE is an application

micha23:02:24

just make a POM that has the dependencies you need and not the ones that are already provided

micha23:02:42

or, alternatively, add the provided dependencies to the POM with :scope "provided"

micha23:02:05

but don't do that with libraries you have in maven or it will break when used outside of GAE

mobileink23:02:48

ok, we must be talking past each other. scopes do make a difference. i don't want mt test jars in prod so i give them :scope " test".

mobileink23:02:34

it is not the case that anythin i load into gae is an app.

micha23:02:47

yes transitivity does make a difference

mobileink23:02:59

i think i'm not getting my pt across. when developing a gae service, i need some stuff locally that i do not need in prod. not just my lical testing stuff, but stuff that is provided by prod gae but not dev gae. like the servlet api. i need that for compile and dev runtime but not prod runtime (i think).

micha23:02:15

do you make a war file?

micha23:02:24

how does GAE get your program

mobileink23:02:26

no, a war dir.

micha23:02:51

ok so when you build that, you can exclude any jars you don't like, no?

micha23:02:23

you include all your deps in a zip file or something that you upload to GAE?

mobileink23:02:36

sure, it's clojure +boot, i can do anything!

micha23:02:28

wouldn't that solve the problem?

mobileink23:02:38

no, you build a war dir, then run a cmd from the gae kit, passing the wardir.

micha23:02:12

boot has no way to know what the specific version of the GAE engine provides

micha23:02:19

i imagine it changes from time to time

micha23:02:52

but it's easy enough to tell it

micha23:02:28

when you build your war dir just add (set-env :exclusions '[foo.bar/baz baf/quux])

micha23:02:47

if those are the group/artifact ids of the jars provided by the runtime

micha23:02:07

then your war dir won't contain any conflicting jars or whatever

mobileink23:02:55

of course i can hardcode everything, but my originsl pt was more general: maven scopes are bonkers, and boot currently imports the craziness, but it doesn't have to.

micha23:02:07

boot doesn't support scopes

micha23:02:16

that's i think the disconnect here

micha23:02:21

maven supports scopes

micha23:02:35

boot just uses the aether library to resolve dependencies

micha23:02:44

maven also uses the aether library to resolve dependencies

mobileink23:02:58

of course it does! just muck about with the :scope kw in :dependencied.

micha23:02:59

but scopes have only one effect on resolution

micha23:02:20

all the :scope kw affects is how aether resolves dependencies

micha23:02:36

but that is extremely simple

micha23:02:03

that is, provided you don't mess about with anything but "compile" and "test" in your build.boot

micha23:02:44

and one common misconception about scopes is that they don't do anything to dependencies you specify that are not transitive

micha23:02:09

i mean that's the real deal, the misconception is that they do things to dependencies that are not transitive

micha23:02:35

no matter what scope you use in your build.boot, that dependency will be loaded into the classpath

micha23:02:17

like (set-env! '[cheshire "RELEASE" :scope "test"]) is the same as (set-env! '[cheshire "RELEASE" :scope "provided"])

micha23:02:23

there is no difference at all

micha23:02:42

where there is a difference is if you use that to make a POM that you put in a maven repo

micha23:02:59

and aether reads that POM while resolving transitive dependencies

micha23:02:15

that's all

micha23:02:14

in other words, aether, which is doing the resolving of dependency jars, completely ignores :scope for top level (non-transitive) dependencies

micha23:02:35

this is the world that boot lives in