boot

:boot-clj: https://boot-clj.github.io/ — build tooling for Clojure. Dev chat in #boot-dev
flyboarder 2019-01-16T01:51:24.181500Z

@jeroenvandijk how stable has that been?

2019-01-16T03:42:35.183300Z

Is there a boot noop to put into a pipeline when conditionally building it? Like (comp (when (= :env :dev) (draft))?

flyboarder 2019-01-16T03:45:20.183800Z

@jayzawrotny ok so the boot task is like a double wrapped function

flyboarder 2019-01-16T03:46:00.184900Z

when you create a task you are returning a function that returns a fileset

flyboarder 2019-01-16T03:46:20.185700Z

so to conditionally wrap that you would use a cond->

flyboarder 2019-01-16T03:46:35.186200Z

I do it often, one sec I have demos

2019-01-16T03:46:40.186400Z

Ah right, the middleware so would need to be like (comp (if (= :env :prod) (draft) (noop)) where noop is like (fn [next-handler] (fn [fs] (next-handler fs))

flyboarder 2019-01-16T03:48:24.187300Z

yeah I find the threading macro easy tho

(cond-> (identity)
  (= :env :dev) (comp (dev)))

flyboarder 2019-01-16T03:48:42.187700Z

that way I can build up a pipeline of conditional tasks

flyboarder 2019-01-16T03:50:32.188900Z

I could also see a really easy reduce-task that takes a coll of tasks and reduces them to a pipeline

2019-01-16T03:51:52.190400Z

(comp
  (perun/global-metadata)
  (perun/markdown :md-exts {:all true})
  (perun/draft)
  (perun/print-meta)
  (perun/slug)
  (perun/ttr)
  (perun/word-count)
  (perun/build-date)
  (perun/gravatar :source-key :author-email :target-key :author-gravatar)
  (perun/render :renderer '<http://eccentric-j.site.post/render|eccentric-j.site.post/render>)
  (perun/collection :renderer 'eccentric-j.site.index/render :page "index.html")
  (perun/tags :renderer 'eccentric-j.site.tags/render)
  (perun/paginate :renderer 'eccentric-j.site.paginate/render)
  (perun/static :renderer 'eccentric-j.site.about/render :page "about.html")
  (perun/sitemap)
  (perun/rss :description "Eccentric J's Blog")
  (perun/atom-feed)
  (sass)
  (cljs :optimizations (if (= build-env :production) :advanced :none))
  (clean :exclude #{#".git"})
  (target :no-clean true)
  (notify)))
Is my pipeline thus far, some of those steps are conditional depending on env and some of those steps may take different args depending on the env. Maybe I should manipulate a list then reduce it into a pipeline?

flyboarder 2019-01-16T03:52:15.191100Z

I think the correct answer to your question tho is just return an identity fn as the task, so it returns the previous tasks fileset

2019-01-16T03:52:31.191500Z

Otherwise I’m going to have (cond-&gt;) all over the place.

2019-01-16T03:52:49.192100Z

Thanks, though you got me thinking I need to rethink my approach

flyboarder 2019-01-16T03:53:22.192700Z

ok I see what you are doing, take a look at what I have done here: http://github.com/degree9/meta

flyboarder 2019-01-16T03:54:53.194400Z

those tasks use the thread approach, it seems you probably want to breakup the pipeline into smaller sub-tasks

2019-01-16T03:55:22.194900Z

Ok, I was just starting to think that 🙂

2019-01-16T03:56:15.195600Z

[meta] seems really nice! I may have just found a stack for clojure desktop app dev!

flyboarder 2019-01-16T03:57:09.195800Z

yeah we are using it everyday

2019-01-16T04:33:31.196400Z

(deftask build
  "Build the blog source and output to target/public"
  [e build-env BUILD-ENV kw    "Environment keyword like :dev or :production"]
  (let [prod? (= env :prod)]
    (-&gt;&gt; [(perun/global-metadata)
          (perun/markdown :md-exts {:all true})
          (when-not prod? (perun/draft))
          (perun/print-meta)
          (perun/slug)
          (perun/ttr)
          (perun/word-count)
          (perun/build-date)
          (perun/gravatar :source-key :author-email :target-key :author-gravatar)
          (perun/render :renderer '<http://eccentric-j.site.post/render|eccentric-j.site.post/render>)
          (perun/collection :renderer 'eccentric-j.site.index/render :page "index.html")
          (perun/tags :renderer 'eccentric-j.site.tags/render)
          (perun/paginate :renderer 'eccentric-j.site.paginate/render)
          (perun/static :renderer 'eccentric-j.site.about/render :page "about.html")
          (perun/sitemap)
          (perun/rss :description "Eccentric J's Blog")
          (perun/atom-feed)
          (sass)
          (cljs :optimizations (if prod? :advanced :none))
          (clean :exclude #{#".git"})
          (target :no-clean true)
          (notify)]
         (keep identity)
         (apply comp))))

2019-01-16T04:36:28.197900Z

Going this route, I think this should keep things pretty clean. I didn’t see a natural split in the steps because they all work towards building the blog. Without any of these steps I’m not sure the result would be meaningful.

flyboarder 2019-01-16T04:41:23.198900Z

If it builds ™️

2019-01-16T17:22:49.200200Z

Is there a way to get watch to respond to changes in a target/public directory instead of the resources dir?

micha 2019-01-16T23:01:22.200900Z

@jayzawrotny no, by design

micha 2019-01-16T23:02:01.201800Z

the target dir is not immutable, it's the final IO at the end of the pipeline

2019-01-16T23:02:14.202200Z

Sounds like I’m trying to use it incorrectly then.

micha 2019-01-16T23:02:55.203600Z

one of the reasons why tasks like watch can be made simple and reliable is that they only manipulate immutable filesets

micha 2019-01-16T23:03:15.204400Z

so you can "roll back" to a previous state easily

2019-01-16T23:03:22.204600Z

The intention was to serve the files compiled to target/public as a website and when those files change run through boot-livereload. Sounds like I need to put those in the build pipeline.

micha 2019-01-16T23:03:58.205800Z

right

micha 2019-01-16T23:04:13.206400Z

you can use :asset-dirs or :resource-dirs

2019-01-16T23:05:00.207400Z

Actually, let me back up. I’m learning boot while developing a static site with http://perun.io. I had a watch task that would build the markdown files, gen the html files, compile the scss and the cljs. But I’m curious if I could set it up to be a bit smarter. Currently if I change a markdown file both the scss and cljs get recompiled.

micha 2019-01-16T23:05:30.207900Z

are you sure they're really getting recompiled?

micha 2019-01-16T23:05:43.208300Z

so there are two usual approaches to build tooling

2019-01-16T23:05:47.208500Z

Well the tasks are firing and output is being logged

micha 2019-01-16T23:05:53.208800Z

you have an approach like Make

micha 2019-01-16T23:06:06.209200Z

where it computes dependencies and triggers tasks that need to run

micha 2019-01-16T23:06:10.209400Z

boot doesn't do it that way

micha 2019-01-16T23:06:19.209800Z

boot always runs the pipeline every time

micha 2019-01-16T23:06:31.210200Z

but each task can hold a reference to the previous immutable fileset

micha 2019-01-16T23:06:38.210500Z

and it can efficiently diff the files

micha 2019-01-16T23:06:54.211Z

so each task is responsible for figuring out for itself whether it needs to do any work or not

micha 2019-01-16T23:07:09.211400Z

so while those tasks will run, they probably are not actually doing any work

micha 2019-01-16T23:07:33.212300Z

they diff the new and old filesets and see that no scss files changed, and just pass the cached results from the previous run onward

2019-01-16T23:07:49.212700Z

I see, unfortunately they do slow down the recompile a bit. It’s not the end of the world though.

micha 2019-01-16T23:08:12.213Z

perhaps there is a reason why they need to recompile something?

micha 2019-01-16T23:08:24.213400Z

or perhaps there is a bug in the task that can be found and fixed

2019-01-16T23:11:52.214300Z

I don’t see anything that strikes me as diffing https://github.com/Deraen/boot-sass/blob/master/src/deraen/boot_sass.clj

2019-01-16T23:12:36.214700Z

No wait, I see it

2019-01-16T23:12:39.214900Z

You’re right

2019-01-16T23:12:45.215200Z

line 41

micha 2019-01-16T23:12:46.215400Z

no line numbers there but see the fileset-diff part?

2019-01-16T23:12:54.215800Z

Yeah I see it now

micha 2019-01-16T23:12:57.216Z

yep exactly

2019-01-16T23:13:09.216200Z

Very cool!

micha 2019-01-16T23:13:31.216600Z

the reasoning there was that only the task itself really knows what it depends on

micha 2019-01-16T23:13:35.216800Z

it can get pretty complex

micha 2019-01-16T23:13:54.217200Z

the build tool can't really know

2019-01-16T23:16:35.219200Z

Good point. Also, I think I see the issue. It’s setup to diff the entire fileset which is why it’s always recompiling for me. Does this mean I could create another task to compose a sift with just .scss files with boot-sass to make it more efficient?

micha 2019-01-16T23:17:36.219700Z

do you have a large number of scss files?

micha 2019-01-16T23:17:50.220100Z

i know sometimes those things can have a ridiculous number of files

2019-01-16T23:18:14.220600Z

Nope, so far just one but if I was using this build system for a bigger site it’s possible.

micha 2019-01-16T23:18:35.220900Z

it's slow with only a small number of files?

micha 2019-01-16T23:18:43.221300Z

the diffing is usually quite fast

micha 2019-01-16T23:19:04.222100Z

since it's all immutable it can do various tricks

2019-01-16T23:19:50.222700Z

I don’t think it’s the diffing that’s slow, I’m just saying if I change a markdown file: the fileset this task receives will be different than the previous fileset it diffs against and will recompile

micha 2019-01-16T23:20:20.223Z

it will only recompile if a scss file changes though

micha 2019-01-16T23:20:29.223400Z

at least that's how it looks from the code

micha 2019-01-16T23:20:51.223800Z

the (when (seq sources) ... part

2019-01-16T23:21:13.224300Z

Right, and sources is the result of diffing filtered by the sass extensions

micha 2019-01-16T23:21:13.224400Z

sources is the .scss files that changed

micha 2019-01-16T23:21:21.224600Z

right

micha 2019-01-16T23:21:51.225100Z

seems like it should skip recompiling if only a markdown file is changed, no?

2019-01-16T23:22:37.226Z

Agreed, boot-sass is definitely designed to work that way.

2019-01-16T23:24:08.227Z

I’ll try again tonight by removing previous steps from the build pipeline until it behaves as expected.

micha 2019-01-16T23:24:49.227400Z

you can try boot -vv ... too

micha 2019-01-16T23:25:06.227800Z

that will log a bunch of debug messages that might show something

2019-01-16T23:25:29.228Z

Thanks

micha 2019-01-16T23:26:57.228200Z

👍