Clojurians
#boot
<
2016-01-23
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

seancorfield00:01:40

All our new Boot-based stuff is in production, along with Clojure 1.8.0 (yay!). No more Leiningen in production!

seancorfield00:01:44

A lot of our little shell script cron jobs have become /path/to/boot some-task as well.

seancorfield00:01:18

Well, technically cd /path/to/project; ./build/bin/boot some-task :smile_cat:

micha00:01:10

i'm really happy it's working for you on windows, too

seancorfield00:01:09

Yeah, that mostly helps when I’m developing FOSS projects on my little laptop while watching TV :simple_smile:

seancorfield00:01:37

We only have Macs for desktop (DEV) and Linux for servers at work.

seancorfield00:01:48

We’re beginning to Dockerize a lot of our stuff so moving stuff out of Ant and into Boot tasks simplifies that process (since we don’t need anything but a JVM and our project in the image — with our Boot wrapper and the boot script itself).

laforge4900:01:11

Glad to hear it, @seancorfield , and glad to find another windows user. :simple_smile:

laforge4900:01:59

--I'm a bit bummed over today, but I'm thinking if I can't unit test, I can always write demos.

seancorfield00:01:29

Ah, did I miss what has you bummed out?

laforge4900:01:13

headless cljs testing.

laforge4900:01:22

i.e. unit testing.

seancorfield00:01:15

Ah, a pain we haven’t felt yet. We abandoned our proof of concept cljs app early last year.

micha00:01:44

@laforge49: do you have access to something like virtualbox?

laforge4900:01:12

I'm very excited over cljc. I want to move my database from clj to cljc

laforge4900:01:19

what is virtualbox?

micha00:01:30

you can run a linux virtual machine in it

micha00:01:48

it's free, at least for linux it is

laforge4900:01:57

@micha my plan now is to focus on system tests via demos. Demos are important anyway. Also, I avoid linux except when there is someone around willing to give me a lot of help. I'm really pathetic at it despite having worked 2 years on solaris and another year on a unix box.

laforge4900:01:20

--I barely survive on windows.

laforge4900:01:36

I focus too much on my own code

laforge4900:01:02

Looking at your counters demo. I'll copy it and add some logging. Just what I need. Starting by creating a demos repository under aatree, of course.

micha00:01:02

how about docker

micha00:01:32

you can run the boot docker image

micha00:01:40

so you'd compute in windows, edit files etc

laforge4900:01:45

I'm already reaching my level of incompetence learning clojure and now clojurescript.

micha00:01:46

but boot would run in the docker container

laforge4900:01:20

I really love the idea of docker! But this isn't the time. :disappointed:

laforge4900:01:07

Right now I want to create enough value that folk will be willing to put up with my boneheadedness!

micha00:01:30

haha i hear ya

laforge4900:01:45

I'm very open about my failings, but I like to show off a bit too.

laforge4900:01:55

I also feel that catering to boneheads will open things up for a wider community. So I don't mind asking the dumb questions and then writing up my understanding.

laforge4900:01:25

But my own self image is not that of a bonehead!

laforge4900:01:15

Love your counters demo. :simple_smile:

laforge4900:01:24

--forking it. :smile:

richiardiandrea01:01:00

Does sift :add-jar accept a symbol and a regex only? not a set of regex like all the other utilities?

micha01:01:39

it adds the contents of a jar from maven

micha01:01:52

identified by the symbol etc

richiardiandrea01:01:29

yes it is super cool, just wondering whether it accepts a regex only or multiple...

richiardiandrea01:01:41

it looks like one only

micha01:01:21

yes, i think that's right

richiardiandrea01:01:54

would you be interested in a patch for multiple regex there?

richiardiandrea01:01:04

or if there is another way to do it

micha01:01:10

sure, will it work on the command line?

richiardiandrea01:01:31

well, I guess is the same as --include for uber

richiardiandrea01:01:40

it accepts a set

micha01:01:01

currently it's accepting a vector i believe

richiardiandrea01:01:16

(boot (built-in/sift :add-jar {jar #"(?i).*\.(clj|cljs|cljc|js)$"}) (built-in/show "-f"))

richiardiandrea01:01:28

this works, where jar is a symbol

micha01:01:42

i mean from the command line though

micha01:01:18

boot sift -j jar:'(?i).*\.(clj|cljs|cljc)$'

micha01:01:28

you can currently do that

micha01:01:36

equivalent to what you did in the repl

richiardiandrea01:01:38

yes one yes, but no more

micha01:01:04

can't you make one regex that does what you need?

micha01:01:33

i don't think there is a way to do that cleanly in the comand line

micha01:01:44

because you can use multiple -j arguments now

richiardiandrea01:01:46

yes true, because it is a compound option

micha01:01:08

the cli stuff is a delicate balance between simplicity and features

richiardiandrea01:01:52

so if add-jar accepted just the jar (symbol), and --include is specified, it could process from there

micha01:01:36

the current behavior is to just combine the two

micha01:01:34

yeah i think the sift task interface could be improved

richiardiandrea01:01:43

what I mean is {jar regex} <- looks redundant and --include could be used

micha01:01:54

yeah i see what you mean

micha01:01:06

like have an "action", like add-jar in this case

micha01:01:12

and then modifiers like --include etc

micha01:01:29

we could do that in a non-breaking change even

micha01:01:35

if we add like

micha01:01:02

boot sift --action add-jar --include foo.\*

micha01:01:23

adding the --action option lets us keep the existing behavior when that isn't provided

richiardiandrea01:01:19

yes but is uglier :smile: then why not a task, but again it is a matter of taste I guess

richiardiandrea01:01:45

just wanted to raise the issue, if you want I can open one and discuss there

micha01:01:47

well for the built-in tasks it's important to utilize the names efficiently

micha01:01:58

like every task name used by boot is one the user can't use

richiardiandrea01:01:35

and on the other end, if you plan to add more actions this is a good starting point

richiardiandrea01:01:35

and it make sense because sift is more like a util function

richiardiandrea01:01:11

for example now I don't think you can combine add-jar and add-meta which is a bummer, it would be so handy (for me at least :))

xpe03:01:51

What are some "go to" links to help me map from leiningen to boot? I've seen https://github.com/boot-clj/boot/wiki/Boot-for-Leiningen-Users

xpe03:01:21

One starter question: I want to add tools.namespace as a dev dependency for REPL reloading

micha03:01:29

@xpe: you can load tools.namespace as a dev dependency like this:

micha03:01:02

(set-env! :dependencies '[[org.clojure/tools.namespace "1.2.3" :scope "test"] ...])

xpe03:01:30

@micha thanks! :scope is what I needed

xpe03:01:32

and am I correct in surmising that :scope "test" is based on how Maven handles dependencies? (e.g. https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html)

xpe03:01:43

(same as lein)

micha03:01:57

exactly right, yes

micha03:01:24

haha your avatar is hilarious

xpe03:01:40

cool. without starting a huge thread about the horror of transitive dependencies, should I expect boot to inherit the usual Maven transitive dependency pains?

xpe03:01:00

oh, thanks, I was surprised that the power supply is so cute

micha03:01:17

boot uses the same dependency mechanism as leiningen, which is the apache aether one wrapped in the clojure pomegranate library

micha03:01:28

maven uses this also

xpe03:01:31

and, thanks to some Hacker News reverse engineering, that power supply is both cute and packed with wise innards

micha03:01:44

wise innards?

xpe03:01:56

oh, all the electronics inside are surprisingly involved

micha03:01:05

i've heard that the apple power supplies are pretty advanced

micha03:01:50

ah right, that's where i read about it :simple_smile:

micha03:01:18

btw for dependency stuff, check out boot show -d and boot show -p

micha03:01:27

help debugging deps issues

xpe03:01:45

yes, I saw those get mentioned

xpe03:01:00

I want to do a deep dive on transitive dependency hell

xpe03:01:21

I know about exclusions, but I want to know the painful history of workarounds

micha03:01:24

pods help you avoid it, pretty much

micha03:01:43

yeah maven is probably the best thing around, because it's been through the war

xpe03:01:43

across tasks, I can see pods helping a lot

micha03:01:01

well pods are also a way to workaround dependency issues

xpe03:01:03

within a particular clojure app, there is always the risk of conflicting transitive versions

micha03:01:14

like if you run into something, you just fire up a pod and move on

xpe03:01:17

could I use pods WITHIN a single clojure app?

micha03:01:24

sure, that's what boot is

micha03:01:55

you need to launch the application with boot though, for now anyway

xpe03:01:57

ok, what I mean one JVM that, say has a library needing ANTLR X and another needs ANTLR Y

micha04:01:15

yeah that's possible with pods, no problem

micha04:01:41

i mean it's possible with the jvm if you arrange your classloaders to accomodate it

micha04:01:52

that's what boot does, before clojure is loaded

micha04:01:24

all dependencies are isolated in pods in boot

xpe04:01:57

very cool! any example code bases you'd recommend that show an example like I mentioned?

micha04:01:08

you can do it very easily yourself:

xpe04:01:08

Re: "maven is probably the best thing around, because it's been through the war" PUN INTENDED!

xpe04:01:22

or maybe the WAR has been through Maven? :simple_smile:

micha04:01:08

(require '[boot.pod :as pod])
(def p1 (pod/make-pod (update-in (get-env) [:dependencies] conj '[antlr "1.0"])))
(def p2 (pod/make-pod (update-in (get-env) [:dependencies] conj '[antlr "2.0"])))

;; then use something antlr
(pod/with-eval-in p1
  (import antlr.whatever)
  (.foo antlrthing))

(pod/with-eval-in p2
  ...

xpe04:01:36

@micha that's very helpful

micha04:01:01

the reason why i did the update-in there is because i may have maven configuration in the (get-env)

micha04:01:08

like repositories, etc

xpe04:01:00

This helps. I'll still have to think a bit more about how this would play out in existing projects.

micha04:01:33

we will hopefully have a thing that lets you create a standalone application that uses pods

micha04:01:52

but as it is right now you would need to have boot be the entry point for the application that uses pods

micha04:01:19

because it's the java part of boot that sets everything up for pods to be able to exist

xpe04:01:20

Ah. That relates to my question, which is about with-eval-in above... does each sub-expression run in some kind of separate JVM? Or at least with a separate classloader? I don't know the details of pods.

micha04:01:52

separate thread, separate classloader

xpe04:01:53

And can each sub-expression communicate with the other one somehow? I'm not sure if they are different threads or what...

micha04:01:15

also no clojure objects can pass between pods sensibly

xpe04:01:16

(interlaced commentary, you answered my question before I pressed enter)

micha04:01:37

because clojure creates protocols, classes, and interfaces dynamically

micha04:01:54

so a function in one clojure runtime doesn't even implement IFn in another clojure runtime

micha04:01:35

so the with-eval-in business is serializing expressions and results at the interface between the pods

micha04:01:58

java objects can pass between pods as long as the classloader the objects are from is visible to both pods

micha04:01:36

but with-eval-in doesn't expose that, it prints the expression to a java string, which is then passed to the pod

xpe04:01:03

thanks for the details!

jethroksy08:01:37

anyone here using inf-clojure with boot?

jethroksy08:01:57

I found an issue with using inf-clojure with boot

jethroksy08:01:01

will update the boot wiki

naomarik10:01:03

there any books that explain boot/java maven/pom/environment stuff for people just getting into this?

naomarik10:01:55

i'm finding i can use lein templates and hack on a project but i have no idea what's going on underneath, and i like boot a lot more cause i can get CIDER to work with it and seems way faster to start

jethroksy10:01:42

the wiki is a great place to start

jethroksy10:01:22

you'll just need to understand the boot env, filesets and pods

naomarik10:01:15

these 3 things and i should be able to configure any webapp i want? :simple_smile:

naomarik10:01:32

i feel there's a lot of underlining java info i need to know

jethroksy10:01:24

for web apps perhaps the most important part is knowing how filesets work

jethroksy10:01:49

the distinction between source-paths and resource-paths

jethroksy10:01:02

I can't imagine how java info would come into play

jethroksy10:01:17

most deployments use boot as an entry point

naomarik10:01:00

cool will look into those, also this seems immensely useful and what i was looking for: https://lionfacelemonface.wordpress.com/2015/01/17/boot-getting-started-with-clojure-in-10-minutes/

naomarik10:01:47

perfect :wink:

naomarik10:01:55

thanks for this

jethroksy10:01:22

feel free to ask questions around here

jethroksy10:01:27

micha is super responsive :simple_smile:

jethroksy10:01:35

also welcome to boot!

naomarik10:01:06

hehe - i've been using it a lil bit with a tenzing generated app, but i find that as i want to do more with it i kind of need to back up and start grokking it from the ground up

naomarik10:01:29

application templates are immensely useful to get started and i would almost not use boot over lein templates, but certain things seem difficult with lein as well and boot-cljs seems superior to figwheel for me

jethroksy10:01:23

modern-cljs would be perfect then

jethroksy10:01:57

I too prefer to build by build.boot file myself

jethroksy10:01:15

sean is working on boot new functionality

jethroksy10:01:50

something along the lines of lein new app would be perfect for me

naomarik10:01:43

honestly that would be amazing

naomarik10:01:47

having boot templates

naomarik10:01:21

would be faster for newcomers to get going

naomarik10:01:41

i liked tenzing but found out the hard way that every dependency it downloaded was outdated

naomarik10:01:51

but was still using that as my boot project after updated everything

naomarik10:01:57

but it was only way i knew how to get going

jethroksy10:01:30

boot show -u shows outdated deps

jaen10:01:33

Oh, nice; I knew of https://github.com/martinklepsch/boot-deps but didn't know something like that was already included in built-ins.

jethroksy11:01:20

It detects the latest stable release

jethroksy11:01:40

Doesn't show snapshot versions

micha12:01:36

@jethroksy: you can use boot show -U if you want to see snapshots

jethroksy12:01:57

ah thanks for that!

laforge4914:01:04

hoplon demos need a boot -u :smile:

laforge4914:01:35

The only problem is that alpha11 release keeps showing up.

laforge4915:01:49

Infinite error loop when using watch.

laforge4915:01:46

I'm using only a slightly modified counters demo: https://github.com/aatree/aademos/tree/master/counters

laforge4915:01:22

Aside from updated repositories, I've also added a cljc file.

laforge4915:01:39

Everything is fine until watch detects a change. Then it goes nuts:

laforge4915:01:17

java.io.IOException: Couldn't delete C:\Users\Bill\.boot\cache\tmp\Users\Bill\Documents\aatree\aademos\counters\fgc\mm3x96\index.html.out\goog\labs\useragent\browser.js http://clojure.java.io/delete-file/invokeStatic io.clj: 434 http://clojure.java.io/delete-file io.clj: 430 ... boot.file/delete-file file.clj: 54 boot.tmpdir.TmpFileSet/commit! tmpdir.clj: 236 boot.core/commit! core.clj: 383 boot.task.built-in/fn/fn/fn/fn/fn/fn built_in.clj: 264 boot.task.built-in/fn/fn/fn/fn/fn built_in.clj: 264 boot.task.built-in/fn/fn/fn/fn built_in.clj: 261 boot.core/run-tasks core.clj: 794 boot.core/boot/fn core.clj: 804 clojure.core/binding-conveyor-fn/fn core.clj: 1938 ... java.io.IOException: Couldn't delete C:\Users\Bill\.boot\cache\tmp\Users\Bill\Documents\aatree\aademos\counters\fgc\mm3x96\index.html.out\goog\iter\iter.js http://clojure.java.io/delete-file/invokeStatic io.clj: 434 etc

laforge4915:01:55

And boot.properties contains BOOT_EMIT_TARGET=no

laforge4915:01:35

Mayhaps it is a windows issue? :disappointed:

micha15:01:41

what does the unmodified demo do?

laforge4915:01:23

the demo you wrote has 10 counters that you can inc/dec

laforge4915:01:51

I just added a log statement and a require for a cljc file.

laforge4915:01:06

Oh, and when I drop the cljc file, watch works fine.

laforge4915:01:11

So it may be having the cljc file on windows, or perhaps just having the cljc file.

micha16:01:08

i'm going to fix that "can't delete" business once and for all

micha16:01:18

but today i am in the weeds with some AWS stuff

laforge4916:01:45

I'm moving the cljc file out of the demo. But first I will create a branch for you that creates the error.

micha16:01:27

i think one issue is that boot sets the temp files in the fileset to be read only

laforge4916:01:28

I'll also create a branch of aautil for the other windows error I reported.

laforge4916:01:03

--which windows interprets as undeletable, hmm? :simple_smile:

micha16:01:06

the idea was that it should throw an exception if the user writes to those files, because if you write to them you end up with a corrupted fileset

micha16:01:35

but i think maybe we just document that, i think it's pretty obvious to most people

laforge4916:01:39

so you need to turn off read-only before deleting!

micha16:01:55

yeah or just not set them to read only in the first place

micha16:01:17

i think read only isn't really respected in general

laforge4916:01:26

updating those temp files is moderately obscure thing to do. So unlikely that you need to worry too much about novices modifying them.

micha16:01:27

by the system

jethroksy16:01:36

output files by the target task are also read only

jethroksy16:01:50

but does modifying them corrupt the fileset?

jaen16:01:24

I think it just syncs the fileset into a given folder and the fileset remains in the temporary directories as it were, so it shouldn't.

micha16:01:29

modifying them while boot is running could cause problems

micha16:01:47

because the target task will by default create hard links to temp files in the fileset

micha16:01:11

this can make things a lot faster obviously, but if you write to a target file while boot is running you will corrupt the fileset

micha16:01:27

however when boot exits those hard links are now linked to unreachable temp files

micha16:01:38

so you can modify them as you like

micha16:01:26

if you are going to be modifying those files while boot is running you can use the --no-link option to the target task

jethroksy16:01:33

IMO read only is still a sensible choice

jaen16:01:18

Ah, so it not only hard links between the temp directories, but with target as well. Good to know, for some reason I assumed the results are not hard linked.

micha16:01:46

it only links some of the things

micha16:01:11

the idea is that it can safely link to any of the tempfiles that will become unreachable when boot exists

micha16:01:48

the scope, or lifetime of a fileset is one invocation of boot

micha16:01:18

because when boot start up it creates a new temporary storage area

micha16:01:44

so when boot exits, the files in there are essentially unreachable

micha16:01:58

so making a hard link to files in there should be okay

micha16:01:22

because only boot knows where the referent files are, and it's not running anymore

micha16:01:43

the next time boot runs it will delete all those temp directories from the last run

micha16:01:57

leaving your hard links as the last remaining version of those files

jaen16:01:20

Right, I just kind of assumed it was a performance optimisation for passing files between the tasks in the fileset and that the results are not optimised in such way, but that was just it - an assumption.

jaen16:01:25

Certainly good to know how it works for real.

micha16:01:57

there are a lot of optimizations that are possible if you assume that something isn't going to be modified by the user

laforge4916:01:42

@micha I've created this branch for you to preserve the error I was getting on windows: https://github.com/aatree/aademos/tree/watch-delete-issue

thosmos23:01:40

I have a git repo in a subdirectory of /resources, and it's getting included in the (watch) task's files. What's the best way to ignore it?:

Starting file watcher (CTRL-C to quit)...
◉ :cp data/.git/objects/28/1e3ddc9b4ecfd2b756ee4709be8018f6b04ba5
◉ :cp data/.git/objects/c8/b9e5a1f12bdb776245f03827b7c19a4f13391e

micha23:01:01

you can make a .bootignore file

micha23:01:12

it should have one java-compatible regex per line

micha23:01:17

so for example:

micha23:01:32

data/.git/.*

micha23:01:52

write that in the project directory as .bootignore

micha23:01:24

@thosmos: ^^