Clojurians
#boot
<
2016-03-05
>

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

laggybit01:03:02

Anyone using boot-reload on windows? I can't seem to get CSS reload to work

alandipert02:03:07

@dominic: I used to feel that way about frameworks too, but now I feel more like this http://blog.ryanflorence.com/you-cant-not-have-a-framework.html

onetom06:03:06

@laggybit: there was some css reload issue with chrome i think, last year still but it was an long outstanding issue, so not sure if it's fixed yet. we just setup a sandbox project for testing auth0, but we used it to fine-tune the whole page load process: http://github.com/exicon/auth you can try in that repo whether the css reload works for u. it worked for us on mac chrome.

laggybit07:03:58

@onetom: I just figured it out: the changed path is sent as-is to the client, that is, with backslash separators

laggybit07:03:22

Gotta love windows...

dominicm08:03:40

@seancorfield: Yeah. A nice little simple thing really.

dominicm08:03:49

@alandipert: That's an interesting view actually. The important distinction I think is that you can "update" your framework to your requirements.

seancorfield08:03:20

@alandipert: yeah the FW/1 framework has existed in CFML since 2009 and is used by thousands so it's evolved based on constant usage. I ported it to Clojure with inspiration from Chas Emerick originally in 2011 I think. Now I'm moving CFML FW/1 apps - that are already used in production - to Clojure in FW/1. It's an interesting exercise.

seancorfield08:03:51

I hadn't realized how much imperative, state-based thinking (and OOP) was baked into the CFML version.

dominicm08:03:55

Oh my, I didn't realise what CFML was. I bet you're glad to be shifting away from that.

seancorfield08:03:19

It's a modern, dynamic scripting language for the JVM with multiple free open source implementations. But it's not what we want to be building apps with going forward.

seancorfield08:03:43

Most people still think about the old tag-based proprietary language that Allaire created.

seancorfield08:03:06

The reason we're moving to Clojure is immutability and concurrency.

dominicm08:03:35

Wait, it isn't Adobe's thing?

seancorfield09:03:24

@dominicm: Allaire created CFML in '95 and Microsoft nearly bought it. They bought another company that created what became asp.

seancorfield09:03:07

Macromedia bought Allaire in 2001 (I worked at Macromedia at the time).

seancorfield09:03:49

Adobe bought Macromedia in 2006. I left adobe in 2007.

seancorfield09:03:48

The free open source versions of CFML appeared around that time and have led the field in terms of language enhancements since.

dominicm09:03:54

Oh wow, you've got quite a background @seancorfield. The CFML I've looked at is definitely the tag-based language, that makes me feel like it's an enterprise PHP.

dominicm09:03:20

I'll have to look into CFML and see if I can learn much else from it.

seancorfield18:03:30

@dominicm if you're curious about modern CFML take a look at https://github.com/seancorfield/datamapper which is our CFML wrapper around our Clojure persistence layer (yes, we use Clojure inside our CFML web apps!)

dominicm18:03:53

@seancorfield I'll check that out, probably perfect for satisfying curiosity. Thanks.

seancorfield18:03:12

(The indentation is messed up - we were moving from tabs to spaces back when I posted those but it should give a flavor of the scripting language CFML has become - it has closures, map / filter / reduce on collection types, dynamic meta programming: that code has onMissingMethod at its core, for example, but you can add methods to objects on the fly etc)

mobileink19:03:57

just came across http://12factor.net/config which recommends env vars for config stuff. I would've prolly agreed bb. (before boot) now i think not. has boot perverted my mind? wondering how the boot masters would respond to that.

mobileink19:03:47

ps. maybe you guys should write a manifesto.

aiba20:03:02

Is it the case that BOOT_JVM_OPTIONS must be set in the shell env, not from a boot.properties file?

micha20:03:02

@mobileink: i really like using environment variables for configuring the application

micha20:03:30

@aiba: yes, because the build.boot files is a clojure program, which runs in the JVM

micha20:03:48

there is no way to have a JVM program tell the JVM how to start up simple_smile

aiba20:03:56

OK, that makes sense. Might be worth noting on https://github.com/boot-clj/boot/wiki/Configuring-Boot that this particular variable is special in that regard

aiba20:03:38

(I could propose an edit if that’d be helpful)

micha20:03:39

it could be done in linux, but in windows it would be more difficult

micha20:03:08

on unix it would be pretty easy to inspect the boot.properties and set jvm options before the jvm starts

micha20:03:30

@aiba: sure, feel free to add a note as you wish

aiba20:03:40

Actually, that’d be even better, if it could read that var from boot.properties. I assume that’d involve editing the embedded script that exists at the beginning of the boot.jar file?

micha20:03:06

but that approach doesn't work on windows

aiba20:03:57

If the majority of users are on unixy systems, it could be worth adding it even if it doesn’t work on windows. Personally I’d like that feature and I use osx.

micha20:03:03

haha yes we've considered that, but it seems like a slippery slope

micha20:03:44

you can make a shell wrapper for boot

aiba20:03:03

Being able to check in JVM options (for production) to the git repo was a feature I liked about lein. Yeah, in the boot world i just made a ./boot.sh file in git, but it’s an extra file.

micha20:03:29

for production i will usually make an upstart config or something like that

aiba20:03:36

And i worry about someone accidentally typing “boot dev” instead of “./boot.sh dev” and having different jvm options without realizing it

micha20:03:51

and i configure the environment there, usually from a file that's checked into git

micha20:03:34

because i usually want the service to start when the machine boots and respawn if it is killed etc

aiba20:03:56

yeah that sounds like a great solution for production that i should adopt :thum

aiba20:03:52

but i guess i also use this for dev. i suppose it’s tricky since there are some jvm options that we want shared among all developers (like which gc to use) and some we want to be personalized (like how much ram to use)

aiba20:03:01

lein profiles worked OK for that

micha20:03:33

interesting

micha20:03:50

i can't remember the last time i messed with jvm options for development

micha20:03:10

i used to have the insanemode speedup jvm options set

micha20:03:19

but now i just use normal jvm defaults

micha20:03:52

since i am mostly working in a persistent build environment

micha20:03:00

like watch mode incremental compiles

aiba20:03:08

yeah, in my case the jvm options are for runtime performance of JVM clojure code that’s sensitive to things like the GC tuning and whether strings are interned, etc., so sometimes we want to change the default JVM options and sync among all developers

aiba20:03:43

but right now i’d be happy just to have the boot.jar shell header read JVM_OPTIONS from a boot.properties file. Would that be a welcome PR if I took at stab at it?

micha20:03:01

the windows issue though

micha20:03:18

it seems like it would complicate things even more for windows users

micha20:03:42

if windows boot is configured differently than unix boot

aiba20:03:03

actually it just occured to me that i could somehow check whether boot was invoked via “./boot.sh …” or “boot …” and abort if the latter, which would solve my present concern about people not picking up the desired jvm options

micha20:03:41

yes boot actually binds a dynamic var

micha20:03:57

i mean a system property

micha20:03:29

boot.app.path

aiba20:03:33

like the equivalent of “$0” ?

micha20:03:22

more or less yeah

micha20:03:42

it has some things to get the full path even if $0 is in your PATH

aiba20:03:45

cool i’m going opt for this and put all the boot vars in this ./boot.sh file, removing boot.properties, so the total number of boot-related files in git remains at 2

aiba20:03:02

thanks for talking this through!

micha20:03:04

i like it!

aiba20:03:24

oh, and i’ll propose the edit i would have liked to have on that wiki page noting the special status of BOOT_JVM_OPTIONS

micha20:03:34

if you find it works and solves your problem it would be most appreciated if you could make a note on the wiki simple_smile

aiba20:03:51

will do!

micha20:03:25

man, programming at all levels

micha20:03:29

super into it

micha20:03:41

way better than adding more configuration!

mobileink20:03:37

@micha me too, bb. at least for some kinds of config, e.g a password. but having learned how to work with edn files in boot I'm rethinking. can't really think of an argument against env vars, except maybe that it involves the os. I like the idea of everything hermetically sealed in a clojure env. FWIW I'm soon going to be doing work with the intel edison, which now officially supports java. eager to see how boot works there. think std Linux os env will be available.

micha20:03:47

yeah the main thing i like about env vars is that you don't need to have a file, so i don't ever need to have anything sensitive in a plaintext file anywhere

micha20:03:17

like passwords i can have in a gpg encrypted file and just decrpty the file and pipe to eval

micha20:03:26

to get the secret passwords into my environment

micha20:03:53

i mean in the shell when i'm developing

mobileink20:03:37

hmm, yes. but perhaps you misunderestimate the genius of boot? ;) you can put them in a file in a fileset, no?

micha20:03:59

where do they come from though? the values?

micha20:03:25

like my usual workflow is to do something like

micha20:03:51

eval "$(gpg -d some_secrets.asc)"

micha20:03:03

then i can do boot build-and-serve or whatever

micha20:03:33

and it will have whatever passwords it needs, etc from the environment

micha20:03:57

i have a bash function to automate the eval and gpg part

mobileink20:03:31

well I guess they have to start somewhere. btw I'm talking out my butt here. I'm just thinking whatever you can do to get something from e.g some_secrets.asc into the env you could also do to put it in a fileset. sorry, I've gone fileset mad.

micha20:03:49

oh i see what you mean

micha20:03:12

that's interesting, i haven't tried that

micha20:03:27

boot does have gpg support via bouncycastle built in

micha20:03:48

and also various functions to use the gpg program if it's available on your system

mobileink20:03:52

and what if you need diff. pwds for different parts of the build? never thought of this before, but once you erase the distinction between build and app coding anything is possible.

micha20:03:28

it has an :as :edn kwarg option to support loading encrypted config files

mobileink20:03:01

nice. I'll get to it, someday. ;)

mobileink20:03:34

fortunately I don't have to worry about that kinda stuff quite yet.

mobileink20:03:41

e.g. some builds can only be made by peeps with the right creds. runtime creds are completely different.

micha20:03:55

very true

mobileink21:03:30

like you don't want the noobs building prod stuff.

micha21:03:09

or you need more access to create resources

micha21:03:26

but once the resources are created other users with less access can use them

mobileink21:03:46

boot has completely blown my mind. I'm beginning to see things I didn't know existed. ;)

micha21:03:50

like if you have various environments for testing etc

mobileink21:03:52

env stuff is total. with filesets you get security scope!

mobileink21:03:28

or at least less gassle.

mobileink21:03:40

thesis: 12 factor is premised on particular technologies. boot exposes that and make mo' better possible.

micha21:03:53

yep, Lisp Can Do It

mobileink21:03:29

it's a good thing I have a patient bosd. have I mentioned Knuth's warning about Metafont? "May be harmful to your normal intersts." Or sth like that.

micha21:03:31

precisely!

mobileink21:03:47

boss, not bosd.

mobileink21:03:06

so you've mentioned models before, I think wrt boot-gae. maybe some kind of boot model (or best practices) wrt config, esp. security stuff is in order for the todo list?

micha21:03:21

yes i bet there would be some interesting discussion there

mobileink21:03:09

when are you guys gonna have a boot conference? your drinks are on me, I promise!

micha21:03:18

there is @danielsz's boot-system work which is an interesting model

micha21:03:36

haha where are you located in the wide world?

micha21:03:08

we're in Durham NC

mobileink21:03:48

have you considered a conf? I think boot is gating to that point.

mobileink21:03:04

can't typppe

micha21:03:28

we have not, but if it's something that people would be interested in we can see what we can do

mobileink21:03:39

link to Daniel's stuff? the slack profile is sparese.

micha21:03:57

he has an excellent video too

micha21:03:34

ah cool, it's embedded in the readme

mobileink21:03:32

thx. let's not forget some kind of conf. by now I'm pretty well convinced boot is beyond category as far as build tools go, that that's just one apical ion of the core cocepts.

mobileink21:03:10

no, I don't know what an apical ion is. in on my phone, since #!/&^#comcast went down, again. I think I meant application.

micha21:03:10

i don't have any experience organizing such a thing, but alan has done similar things in the past

mobileink21:03:15

I'm sure that amongst the community we can figure sth out.

micha21:03:23

yep sounds good to me

mobileink21:03:44

World Domination starts in N.C. Everybody knows that.

mobileink21:03:20

is boot a framework? I'm inclined to view boot as 2 things. 1. a kernel (mainly filesets), which has no essential connection with build stuff; and 2. an app, which leverages the kernel to support domain - specific (I.e.build) solutions. here's the cool thing: we can view the boot kernel as a language extension, just like e.g. core.async.

micha21:03:17

and clojure.core is something i would consider a framework, too

micha21:03:46

like clojure.core is just a collection of functions, which you can choose to use or not use as you wish

micha21:03:54

but they are universally available

micha21:03:09

which allows you to coordinate around those abstractions

micha21:03:25

like consider the issues in scheme with lazy lists and streams

micha21:03:39

it's hard to coordinate around them because they're not universally available

micha21:03:25

vs in clojure if you use functions in clojure.core you're going to be able to use lazy seqs

micha21:03:43

and you can pass lazy seqs to other code that you don't control that also uses clojure.core functions

micha21:03:28

the word framework pushes people's buttons sometimes but i think frameworks are a good thing

micha21:03:36

i mean if they're good, of course

mobileink22:03:04

I guess I think of a "framework" as an add-on that uses the language. but Clojure's meta programming facilities let us extend the language itself. clojure.core might contain a lot of stuff that is not really primitive, but it does (imo) define the language in some sense. Any defmacro extends the language insofar as it introduces new syntax. So deftask counts as a language extension. But that's specific to build stuff. I think Fileset is a much more general language extension. You haven't broken it out, but you could. you could build an immutable file system lib on filesets, one that doesn't care about builds, just lets you do fs stuff for ant reason with immutability.

mobileink22:03:13

ant reason -> any reason

mobileink22:03:32

I'm guessing you guys came up with Fileset to solve a specific problem. Which it does. But it seems uchicago more general than that to me.

micha22:03:55

we haven't really needed an immutable fileset type of thing at the application level yet

micha22:03:37

the reason we spent so much time on it in boot is because the existing paradigms for bootstrapping a system all revolve around files

mobileink22:03:00

uchicago? ? damn this autocorrecting phone! I wrote "much".

micha22:03:03

so the fileset is a way of isolating interactions with the fileset in the same way that pods isolate interactions with the JVM classpath

micha22:03:46

also the classpath si intrinsically coupled to files

micha22:03:00

so to correctly manage one you need to be able to correctly manage the other

mobileink22:03:10

ok, but let's forget about classpaths for now. I just want to futz with the filesys, immutably. Filesets! A thing of beauty!

micha22:03:51

also another thing that's weird about building vs applications is the need for lots of temporary directories

mobileink22:03:29

coupling of filesets and cp is specific to the task.

micha22:03:04

i imagine that applications will probably not want to use temp directories because if something crashes you will want to respawn with those files intact to the application can continue processing them

mobileink22:03:02

ah, temp dirs. no! a 1000 time no! ;) that's an implementation detail. don't think about files, think about mamespaced.

micha22:03:31

i mean like the adservers i work on for example

micha22:03:48

they write log files that contain the important information they're processing

micha22:03:06

that's the ultimate failsafe, like if everything crashes those files will be there

mobileink22:03:14

boot kernel could be implemented using in-mem db, or remote db, or anything.

micha22:03:20

and we can pump them back into the data pipeline somehow

mobileink22:03:57

ok the adservers write "logfiles". are they really files? they don't have to be - they're just bytestreams.

micha22:03:38

they're files because they need to be lowest possible technology

micha22:03:51

like if everything else is down at least you can write to a file

micha22:03:07

as long as you don't let the disk get full simple_smile

micha22:03:11

they're actually files that contain one json object per line, which means you can do things with them manually with shell tools, if you really need to

micha22:03:24

which is also good when things go horribly wrong someday

mobileink22:03:43

do you see what I'm getting at? maybe stoopid, I'm blabbing, filesystem, in-mem database, remote db - who cares? what counts is the interface.

micha22:03:25

yeah i agree there

mobileink22:03:46

that's the beauty of boot, as far as I can see.

micha22:03:49

that's a cool thing about the classpath btw, too

micha22:03:11

they engineered it so you don't know or care if it's files, memory, or even some URL that's on a server on the internet

micha22:03:28

you just interact with "resources"

mobileink22:03:41

man, I wish I had about 6 months to write sw based on boot!

mobileink22:03:22

I wasn't joking when I said it was Clojure's killer app!

micha22:03:58

the nicest thing i've heard yet simple_smile

mobileink22:03:09

yeah, I've just begun to see what you guys mean by saying the other tools rely on file locations and boot doesnt. it's really critical but far fromobvious.

mobileink22:03:29

now I'm thinking of fs paths as namespaces, which have no location. makes perfect sense!

micha22:03:04

and when you interact with programs that need named places on the filesystem you can copy things into a temp dir from the fileset, run the program in a pod, and collect the files that program creates and integrate them into the fileset

micha22:03:24

so you can isolate the pieces that expect the filesystem to have special named places in it

micha22:03:52

so they don't all need to work together with the same assumptions about the filesystem (when you have multiple pieces like that)

mobileink22:03:06

I think of Fileset as kernel, and Pods as orthogonal to that. Neither of which has any essential connection with builds, they're just programming. Sound ok?

mobileink22:03:54

"programs that need named places" Step back and look at that a bit. there are no named "places", there are only names. we're tricked into thinking they're places by the filesystem conventions. boot fixes this - when you io/file sth into a tmp-dir your not giving the name of a locn, you're just giving an identifier in a namespace - "location" be damned. in the os fs, the identifier is connected to a locn - exactly like a var is connected to a member locn. Filesets hide the one just like clojure hides the other. The mind boggles.

mobileink22:03:15

that's why I think Fileset goes far beyond the boot app.

mobileink23:03:13

iow, if you say (def a 0), 'a' is just a name. behind the curtains it is certainly a mem locn, but we don't care - clojure handles it. I think (?) Fileset does the same - you add a "file", which means you map a filename to a bytestream, and you don't care where it is. boot (or Fileset) deals with it.

micha23:03:31

yep, exactly

mobileink23:03:52

beyond awesome.

mobileink23:03:21

takes a little work to grok at first, but once you get it there's no turning back.

mobileink23:03:17

cool thing is, pods and filesets are orthogonal - you could have either without the other. I think. ?

micha23:03:29

yep, in fact in boot pods don't have any interaction with filesets directly

micha23:03:04

you might evaluate expressions in there that do, but the pod implementation doesn't use filesets at all

micha23:03:28

like you said before, the classpath is orthogonal

micha23:03:36

and pods are just about the classpath

micha23:03:47

and the clojure runtime, of course