Fork me on GitHub

:optimizations :none


Hey, there is some How to run boot Direct on cljs, using lumo or something like?


I’m running a clojure.spec test from a boot task. When I invoke the test from the REPL it works fine, but when I invoke it from the task, it executes zero tests…

(deftask run []
  (with-pass-thru [_]
    (let [res (stest/check `run-script-with-deps)
          summary (stest/summarize-results res)]
      (println res)
      (println summary))))
Any idea why?


I moved code to normal source files, now it works


I have boot tasks which look like this:

(deftask scss []
  (merge-env! :source-paths ["scss"])
   (sift :move {#"main.css$" "css/main.css"})))

(deftask dev []
  (merge-env! :source-paths ["src"])
   (watch :verbose true)
this works fine 90% of the time. but sometimes the css i not compiled, and the scss files don’t show up in the initial output from watch :verbose. can the merge-env! :source-paths in the scss task be a problem because this is only called after watch?


saw a q on #clojure about compiling kotlin, scala etc. with leiningen. seems like it would be pretty easy with boot but googsearch turns up zilch. anybody do that?


i haven't seen, i would enjoy a kotlin one tho


i made one for an obscure language called yeti, boot-yeti


i didn't actually learn its compiler api. i just call its main method in a pod


same approach could probably used for scala etc


there were downsides tho, like it wanted to exit the jvm when compile fails. i worked around that with jvm security craziness lol


I wonder how would jvm security help without crashing the yeti build tool itself?


yeah, i haven't used it very much. i'm sure there are problems. better solution is to learn actual compiler api for language you want to make task for


compiler api is very low level. language-specialized build tools provide a lot of stuff besides compiling: they track whether dependencies and artefacts need to be fetched (or are already present) and which parts of the project need to be re-built, to name a few concerns they handle.


weaving different languages at the compiler level would constrain your fluency with each language's part of your project, or you'd need to re-write major swaths of your language-specific build tool in order to avoid some of them..


the idea of boot-gcc has been haunting me for some time.


I wonder if there are other examples of cross-language building made with boot


i use the javac task all the time


well that can be done even in lein


i don't agree that language variety decreases fluency, because fluency is not zero-sum


ummm no offense to yeti of course 🙂


and a large project is indistinguishable from a small project with lots of library dependencies produced by other languages


the nice thing about boot is you can sequester all the stuff using pods and filesets.


there are various boot libs that do this, eg css stuff, for example. i've used it for the Great NetRexx.


good point. i use the sass task every day


also the hoplon task, but even more contrived use case than yeti since i co-invented the hoplon language 😁


@alandipert and until now I thought clojure was an original choice of me 🙂


Do any of these examples synchronize dependencies between different languages such that one builds when the other has changed and so forth? I am not sure how the css stuff mentioned here provides a parallel to this, probably in my own fault


I still think you'd never use e.g. the scala compiler directly, because then you'll need to change your code for every source directory you add and the like, stuff that sbt abstracts away


the generall recipe is, to start from nothing, and put tasks in dependency order


ie if i'm making a clj program with a .java dep, i'd compile the java first, then pass the fileset to the part that AOTs clojure


in this respect you're right, css isn't really a good example, since it doesn't produce compile-time dependencies


the dependencies are resolved in the browser at runtime


haven't used scala, just rashly assuming you could wrap sbt in some fiendishly clever way.


of course it is easy to wrap sbt, but it is notoriously heavy on the jvm, if everything needs to run in the same jvm sbt will not work well, it does some crazy stuff to the jvm, internally. it should probably run as a shell command.. which might defeat the purpose of boot's architecture (?!)


i've used templating engines, which technically are compilers kindasorta, to produced clj and java source that gets compiled by a later task and then discarded.


ah, that's different.


if boot in some way helps, alleviates or a similar verb of your choice, the running of an external build tool beyond what I'd get with ant or my own clojure code, I'd use it for sbt.


i work with google appengine test server which also mucks things up by forking its own jvm and classpath. i end up dumping all to target and serving from that instead of a fileset.


the big difference is, boot delivers a filesystem value that it manages efficiently. an immutable value type you can "add files" to, test for equality, store for caching, etc


define "external build tool"?


and so you can compose tasks like compilers functionally, without worrying about filesystem hygiene


Oh, because file systems are in fact virtualized through filesets?


this reminds me a little of gulp, a node.js abomination


@mbjarland I should have said build tools which cannot be run inside the same JVM but rather as a shell command.


@matan precisely. similar to gulp, except instead of individual files getting piped through, entire "filesystem values" get piped through, composites.


sorry i dunno anything about sbt. really sorry you brought it up, because now i won't be able to sleep until i figure it out. 😂


are filesets also persistent? or should they be created from scratch on each run of a step?


their lifecycle is that of the jvm


@mobileink sbt is the main/only scala build tool. it is quite horrific as it was predicated on scala being a good language for DSL, which it is not, really


there is a separate mechanism for caching things across jvm invocations


a content-addressed kv store type thing, not as featureful


@alandipert wait, i thought i read somewhere filesets should not be thought of as a virtual fs?


but a typical pattern is for a task to store the "last seen" fileset, and if none of the files changed, to add previously-created files without doing work


It sounds like boot can be used for this job, but certainly not deeply designed for it. I'd avoid trying at this state of affairs, unless I had some mileage with boot already 🙂


@mobileink yeah it's not a great analogy, since filesystems are mutable


i think of the fs stuff as a kind of opaque memory, just like clojure uses memory when you e.g. assoc a map.


@alandipert I like that pattern you mentioned, that should nail some of the complication.


@mobileink not sure the url is working, but I can guess the idea. being given two weeks of extra life in a parallel universe where there is boot and clojure but no schedules might be needed as well.


stupid link! these boots are made for walking


another value of just using sbt you wouldn't get with boot


is intellij wouldn't work


same for kotlin


well, i've been thinking about discovering why clojure is better than scala, maybe now's the time. a while back i saw a video of the main scala guy at the time explaining why it sucks and why he left. ouch. so i've stayed away.


what people do there is generate a project.clj for IDEs use, would probably need to do something similar in order for scala/kotlin to be usable


yeah, meshing different tools would undermine any chances of using an IDE (which clojure guys don't use much anyway).


of course, you can get pretty far with auto compile/reload and ctags


just depends how much you think you need what IDEs do, which varies by human


@mobileink scala is different than clojure in 1) not being homoiconic (macros are unstable and really close to experimental and 2) provides a conventional yet vastly improved OO paradigm compared to Java, aside its functional paradigm. If these things speak to you and you are not married to lisps, go for it.


similarities with clojure: immutability first, java interop.


as i recall the guy's main complaint was that the internal architecture was unsustainable. maybe that's changed. thing is now there are lot's of options if you want strong types. Idris is my current fav, although jvm support is weka.


I'm into choosing languages that other humans around me might use too should I need to expand into a team setting 🙂


The guy's main complaint is probably true, although java is nearing that point too though in softer ways. I mean look at lambda in java 9..


are you working in a very commercial setting? open source? other?


doing obscure r&d in a non-sw company that is nervous about getting disrupted. got some open source stuff in the oven i mean to release Real Soon Now, webbish, involving webcomponents and polymer. you?


lambda in java 9. i don't know that i have the strength to look at that.


it kinda makes me sad to even think about it.


this thread keeps popping up for me whenever I open slack... is it the same for you?


no gui ides? no intellij, eclipse? that's a feature!


to the point of boot being used to weave different jvm languages in a single project, do the docs nail it as a resonating No? > Boot's primary purpose is to bootstrap Clojure applications. I fail to see how you'd get e.g. an uberjar of a mixed-language project, with pods, but more essentially if that's really the core aim of boot, I posit that it is the wrong tool for such integrations like the task this discussion evolved from.


i'm going to push back on the idea that the primary purpose of boot is to bootstrap Clojure applications. That might have been the original goal, but i think the devs, like many geniuses, did not fully appreciate the earth-shattering significance of what they had wrought. boot is the Job Control Language par excellance: JCL done right. It leverages Clojure, but is not limited to it.


and you can use it for any job control (batch) pipeline; software construction is just a special case.


the classic mainframe dataprocessing pipeline: run n batch programs each of which takes data from the preceeding step, maybe reads some other files, and passes the transformed data to the next step.