Fork me on GitHub
#boot
<
2016-02-27
>
richiardiandrea00:02:09

so if I have a profile.boot and I do:

(task-options! environ {:env {:db-port "4334"
                              :db-host ""
                              :db-name "dev"}})
should my env see the change?

richiardiandrea00:02:03

a custom task works, just tried

settinghead06:02:23

anyone used boot-template before? if i put a file under resources folder, say public/index.html, should i use the path “public/index.html”?

onetom14:02:54

@richiardiandrea: what do u mean by "should my env see the change"? whether the value for the environ task set in your profile.boot is "overwritten" by the on in your build.boot? it sounds obvious to try, so i suspect u meant something else

micha14:02:05

@settinghead: how do you mean "use the path"?

micha14:02:04

like with the :paths/`-p` option?

mobileink15:02:18

hi folks. i'm trying to figure out how to use the ".cljs.edn" technique in boot-gae, using boot-reload as a guid. i've got the basic logic down, but i'm stuck on idempotency. by that i mean i have a reloader task that injects some config data (`:reload`) into web.xml.edn and does add-resource to the result. other tasks may inject other config data. i want to ensure that invoking reloader more than once makes no difference. my first try: filter on output files, see if web.xml.edn is there, and if it already contains the :reload key do nothing, otherwise add it, or if it is not in output files try the input files. couldn't get it to work. but i see boot-reload uses an atom, prev-pre, with fileset-diff and (reset! prev-pre fileset). can somebody explain how that works? does that make the task stateful?

mobileink15:02:40

a related question: it just occurred to me that tasks are actually closures rather than functions. if you do (defn f [] ...body...), the defn will intern f with the entire body as its val. but it looks like deftask pulls out the closure (fn [next-handler] (fn [fileset]...)). so any local bindings you put before the closure only get evaluated once, at compile time. is that correct? that's the only way i can make sense of using atoms like prev-pre.

mobileink15:02:42

or in other words, tasks are functions, but deftask is not defn.

micha15:02:37

@mobileink: the fileset-diff makes the task stateful

micha15:02:03

that function itself is pure: it takes two filesets, before and after

micha15:02:29

and it returns a new immutable fileset that contains files that have been added or changed from before to after

micha15:02:42

you get a fileset that contains the diff, basically

micha15:02:59

so when the task runs you can save the current fileset in an atom

micha15:02:12

so you can diff it with the next fileset when the task runs again

micha15:02:47

if you pass in nil as the before fileset the after fileset is returned (i.e. all files are changed, naturally)

micha15:02:47

the atom holding prev-fs makes the task stateful

micha15:02:07

you can use the diff to guide your caching strategy in your task

micha15:02:15

like you know which files change from one run to the next

micha15:02:27

and you can decide which cached results need to be invalidated

mobileink15:02:16

ok, i guess my functional programming naivety is showing - i was treating the (let [foo ... stuff at the beginning of tasks as behaving just the way it would in a fn. but when deftask returns a (fn [x]... that's a closure, which is ordinary. i knew that. really i did. 😉

micha15:02:07

deftask is just defn with some syntax sugar on it

micha15:02:19

so i think you were right

mobileink15:02:23

so using an atom with fileset-diff, i'll know that anything in the diff has changed since i last set the atom

mobileink15:02:24

re: deftask its now on my list to write some doco to alert those who are not really used to programming with higher-order functions. i've been doing it for a while, so i'm a going to have to have a stern talk with myself about this...

mobileink15:02:02

but just because i know my web.xml.edn has changed doesn't tell me what to do - i'll still have to examine it to see if the part my task is interested in has changed. Correct? so i'll look for :reloader and if its there i'll leave it alone, otherwise add it.

mobileink15:02:13

another question wrt fileset-diff: file role does not matter? i.e. a file with input role could have changed, correct? iow, just because a file has INPUT only role does not mean it cannot be changed without acquiring the OUTPUT role also?

micha15:02:40

the role info is part of the TmpFile object

micha15:02:59

so changing roles will also be part of the equality test used in the diff

micha15:02:15

actually wait

micha15:02:25

the diff is configurable

micha15:02:37

sorry, the first thing i said was incorrect

micha15:02:59

you can use file contents hash or modification time or both

mobileink15:02:18

ok, so if i just copy a file with INPUT to tmp and then to add-asset, it will be in the diff even though it's an identity xform wrt name and content

micha15:02:48

if the modtime and contents of the file are the same it won't show up in the diff

micha15:02:57

and the path in the fileset of course

mobileink15:02:01

and by the same token i could in principle just change the timestamp on an INPUT-only file and it would show up in the diff even though its role did not change

micha15:02:21

yeah roles are not considered in the fileset-diff

mobileink15:02:36

ah, right an identity xform would put a different timestamp on the target so it would be in the diff because of that, not because of the role

micha15:02:10

yeah basically a blob in the blob store is identified by the md5 hash of the contents and the modification time as long int

micha15:02:48

the name of the file is like bc998f59ac.12345

micha15:02:19

the name of the actual file in the blob store i mean

mobileink15:02:24

ok i think i see how to make my tasks idempotent then, thanks!

micha15:02:32

the files in the fileset are just hard links to those blob files

richiardiandrea16:02:07

@onetom just meant to say that my task-options! above in profile.boot did not work, it looks like it does not set the options, which actually makes sense, probably task-options! it local to the file it resides in

micha16:02:48

@richiardiandrea: task-options! calls alter-var-root on the task functions

micha16:02:54

to curry the arguments

micha16:02:04

it is a macro that expands to successive calls to the replace-task! macro

richiardiandrea16:02:09

Right, in any case I need to task it up

micha16:02:13

haha oops

micha16:02:35

i took that pic at the facebook offices

micha16:02:48

i failed the interview though

richiardiandrea16:02:12

At the Facebook office really ?

micha16:02:19

lol no, that was a joke

micha16:02:38

we were talking about PHP in the hoplon channel

richiardiandrea16:02:41

Well very informative interviews :)

micha16:02:11

i found a picture of the core PHP dev team

micha16:02:52

when you do (task-options! foo {:x y}) you're actually replacing the foo function

micha16:02:58

with a curried version

richiardiandrea16:02:29

Yeah now it is clear why it was not working

richiardiandrea16:02:05

So I put task-options! In profile boot, then my pipeline sees the curried task right?

richiardiandrea16:02:41

Ok so I was just missing the (curried) call to environ

micha16:02:29

i'm not sure if environ works across pods or not

micha16:02:49

i think there was some activity to make modifications to support that

micha16:02:01

but i don't know if it made it into a release

micha16:02:29

because environ stores values in vars, which are isolated in pods

micha16:02:13

it doesn't do as much as environ though

richiardiandrea16:02:16

If it saves a file like in lein, maybe yes, but I will try..what is sure is that launching the environ task worked for me

richiardiandrea16:02:06

I mean without task-options! but a wrapper task calling environ in the pipeline

richiardiandrea16:02:16

So I assume it will work

micha16:02:28

yeah in the pipeline you're all in one pod

micha16:02:57

i'm not sure about what happens if you set environ things in the core pod and then expect other pods to see those setings

richiardiandrea16:02:09

Yeah, my use case though was to set env vars for the app so mission accomplished for now ;)

richiardiandrea16:02:22

Childish but always effective :)))

micha16:02:45

hahaha yes

hlolli19:02:16

I may be asking this question many times. But there's something obvious Im missing from boot. I'm simply trying to get cider to work with bREPL, in a way that I can just do C-x-e or M-x in emacs. If I do boot repl -c and then (start-repl) I get the brepl but its not cider. If I do boot cider repl and then (start-repl) it crashes. If I do cider connect to nrepl started by boot, it wont even load up clojure.core. From leinigen i was able to "live code", but I know Im just missing something in boot.

micha19:02:11

i wish i could help but i don't use emacs myself

hlolli19:02:29

(I ment C-M-x of course not M-x)

hlolli19:02:49

ah.. what do you use if I may ask?

micha19:02:54

i use vim with fireplace

micha19:02:21

and i use a different kind of cljs repl, i basically use live reload as a repl

micha19:02:25

i just use basic expression evaluation in the editor, nothing fancy

hlolli19:02:35

ok, I've been doing that so far.. just annoying to print the state, sometimes I would like to mutate an atom and just see how the state chaned. My workflow is slow, use the brepl from terminal and/or print to console

micha19:02:43

i always have the repl open in tmux for anything fancy

micha19:02:22

yeah i have a bunch of logging and inspection macros i use with cljs

micha19:02:48

makes it pretty easy for me to work that way without needing to get repls working and stuff

micha19:02:17

for a while everything was changing so much that it was pointless to try to have a working repl at all in cljs

micha19:02:23

and i found i prefer to work the other way

hlolli19:02:13

ok, yes, all the documentation seems to suggest this kind of workflow. But Im so used to JVM and miss having this instant feedback. Yes, I guess when you are at a certain level then you dont need this.

micha19:02:38

it also depends on your application i think

micha19:02:51

like hoplon is well suited to the non-repl workflow i think

micha19:02:15

you can just put logging stuff in a cell formula

micha19:02:35

so it's very similar to how i use fireplace in clojure

hlolli19:02:19

ok.. do you have link to some of those macros loggers that you use, or you just made it yourself?

micha19:02:15

yeah it's just some simple wrappers around the existing console stuff

micha19:02:36

the macros allow me to use those a lot and not have to worry about them being left in when i do a production build

hlolli19:02:39

ok nice, haven't tried this

hlolli19:02:53

yes I see, I will check this out for now, thanks

hlolli20:02:39

ok, I dont know if I was stupid there or emacs. Shit, but I have the repl working now. Just restarted emacs and did cider-connect and from there (start-repl) everything worked without error. Im glad, I open a beer for this.

micha20:02:14

i will also open a beer

hlolli20:02:41

hehe, its saturday... what else to do, play some techno and code

micha20:02:57

naturally

settinghead20:02:53

i was using this in boot.build like this: (template :paths ["public/index.html”] :subs {"%BC_SCRIPT%" (str "" port-browser-client-static-server-dev "/js/browser-client-main.js")})

settinghead21:02:20

i essentially want to sub a variable in my index.html file

micha21:02:24

that didn't work?

micha21:02:06

boot.user=> (doc template)
-------------------------
adzerk.boot-template/template
([& {:as *opts*, :keys [help paths subs output-type]}])
  Perform text substitution on files in the fileset using StringTemplate.  For instance, with a file foo/bar.txt in the fileset with this content:
  
       My name is $name$
  
   And this task used like this:
  
     (template :paths ["foo/bar.txt"] :subs {"name" "Barney"})
  
   foo/bar.txt will appear in the target directory with this content:
  
       My name is Barney
  
  Keyword Args:
    :help         bool       Print this help info.
    :paths        #{str}     FileSet root-relative paths of input file(s) to perform substitutions on.
    :subs         {str str}  String substitutions to perform on the file(s).
    :output-type  kw         Optional output type; can be one of :resource or :source.  Default is :resource.

micha21:02:21

looks like :paths is a set of strings

richiardiandrea23:02:57

@hlolli for a working cljs sample with boot you can look at https://github.com/Lambda-X/cljs-repl-web

richiardiandrea23:02:13

And I use the conf in the boot wiki (which I enhanced with the .dir-locals.el trick) simple_smile