This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-02-23
Channels
- # aws-lambda (1)
- # beginners (11)
- # boot (456)
- # cider (3)
- # cljsrn (7)
- # clojure (340)
- # clojure-berlin (6)
- # clojure-dev (207)
- # clojure-germany (12)
- # clojure-greece (3)
- # clojure-italy (3)
- # clojure-russia (12)
- # clojure-spec (42)
- # clojure-uk (29)
- # clojured (7)
- # clojurescript (125)
- # datascript (1)
- # datomic (47)
- # defnpodcast (4)
- # emacs (30)
- # events (7)
- # hoplon (13)
- # instaparse (64)
- # jobs (13)
- # jobs-discuss (1)
- # lein-figwheel (1)
- # leiningen (10)
- # luminus (1)
- # lumo (14)
- # off-topic (10)
- # om (16)
- # om-next (3)
- # onyx (1)
- # pedestal (3)
- # protorepl (5)
- # re-frame (17)
- # reagent (66)
- # ring (1)
- # ring-swagger (13)
- # spacemacs (12)
- # specter (4)
- # untangled (272)
- # vim (4)
- # yada (24)
when i run boot -h
, it takes like eight seconds to complete, and looks like it spins up a separate windowed java program at some point, which tabs me out of my terminal window?
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
#!/usr/bin/env bash declare -a "options=($BOOT_JVM_OPTIONS)" self="${BASH_SOURCE[0]}" selfdir="$(cd "$(dirname "${self}")" ; pwd)" selfpath="$selfdir/$(basename "$self")" exec ${BOOT_JAVA_COMMAND:-java} "${options[@]}" -Dboot.app.path="$selfpath" -jar "$0" "$@"
@mobileink that’s not the response i was hoping for :’(
i sympathize. maybe there's a better way, but boot is so far beyond category that i'll take my lumps to use it.
@richiardiandrea Related, did I hear a rumour that you have a data-driven project definition boot task?
@cfleming wow things are moving fast in this little town 😄
@richiardiandrea My spies are everywhere 🙂
cfleming: so the project is here: https://github.com/adzerk-oss/bootlaces/pull/16
if people start liking the idea, for Cursive it will basically be as easy as passing a var
mixed feelings, it would actually help if it could end up in boot.core
, maybe @U055HMK9L can give us his opinion given he's here 😉
ok the mention here does not work
ah ah 😄
looks like private but it is not 😄
Your example would be very easy to analyse, but in real projects those maps will be created programmatically
Either way, the user will have to provide a task which returns a data structure with that data to Cursive, for any non-trivial case.
yeah that's also true
maybe you could provide this macro as "cursive" macro and "force" the user to use it (or cursive won't support it)
Yes, it is, but there was concern in the main channel about having to modify the boot file for any project you want to open in Cursive.
is integration with cursive similar to the situation in the shell with programmable completion?
it looks like the same kind of problem yes
good point
Basically, I need to know the libraries and paths required by the project. The issue with boot as I see it is that to build up an environment of “everything you might want” I would have to execute all tasks.
Something like Andrea’s solution makes it easier to structure your project so that all the data required by the different tasks is held is maps which could then be combined by some Cursive task into one
Yes, that would be easy. But I still need some solution for users who want to open arbitrary boot projects that may not be designed for Cursive.
it seems maybe reasonable to have some middle of the road approach, like bash completion maybe?
I can statically analyse quite a lot for basic projects, which I hope will get quite far.
i mean some library that helps you annotate your project so that cursive can know things
it's interesting to me because it forms a sort of api, and a framework for thinking about how to design the build stuff in a way that's compatible with cursive
I need to play with boot more to know how feasible all this is, and how non-intrusive it can be made for arbitrary projects.
Here’s how this works. The issue is that IntelliJ works from source and other project artifacts, like jars that are used by the project.
In a Java project, all the source gets indexed, and the .class files from jars do as well.
I suspect an additional complication would be that a single build.boot
file can create a different classpath / environment for each task and can span multiple “projects”...
In Clojure it’s similar, but it’s complicated by various factors - most libs are source only, some are not, datomic has no source at all, etc.
For example, at World Singles, we have “context” tasks that add different source directories and different dependencies to the environment, so we might start one app with boot some-context run
and a different app with boot other-context run
@U04V70XH6 Yes, that’s another problem. In what is conceptually a multi-module project, there’s nothing in the boot file I can read that indicates that.
exactly @U04V70XH6 that is why I quite liked the option of having a "descriptor"
So basically, for IntelliJ to index, it needs to know what to index - where the source is, what the dependent jars are, etc.
that I can pass to my tasks...still does not solve every problem
(my point is there’s likely no “perfect” solution for Boot / Cursive for the general case — so I think @richiardiandrea is going in a good direction: if you want Cursive support for your Boot project, you need to structure it a particular way)
what about logging the events that cursive cares about and using that info to build a descriptor file
@U055HMK9L wouldn't it be similar to having a macro that generate a task from data?
Executing tasks automatically is a bit dangerous tho’… what if a task performs some file system operation or deploys an artifact to a repository?
An additional problem is that if someone has a task which adds a jar to the classpath and then immediately uses that classpath to launch rockets, those rockets will be launched… right.
I thought @cfleming was talking about Cursive running the Boot file?
Right. They can’t really even open their project in any useful way without this information.
based on this exchange: > cfleming [1 minute ago] The problem is that it still needs to execute all tasks to get them all. micha [1 minute ago] then you let cursive run it the same way ubt without the option
☝️:skin-tone-2: Yeah, it would have to be manual — Cursive could not automate that.
I like the above ^ but we should probably instrument boot itself for it
So the user would have to do that manually before opening a project in Cursive. That’s very different to the workflow of every other build system (in IntelliJ, say open project, select project.clj/gradle file/pom, and the project opens).
It also still relies on project authors making sure to not side-effect in tasks which supply project info.
and if the edn file is older than the build.boot file maybe cursive would run it to regenerate the edn file
what if boot generates that file that then Cursive will find on the classpath
Perhaps have metadata on tasks indicating what needs to be run by Cursive?
Much like making normal code reloadable, except that build tasks are expected to side effect all the time.
yeah ^
which in any case it is true
Then users can split a side-effecting task into two parts: task1 - build the environment; task2 - actually run something.
I do like the instrumentation idea, since that would save users having to write that task themselves.
Yeah, but if Cursive requires certain classpath info etc, it can’t get it from a Boot file in general — only in very simple cases.
@U04V70XH6 Right.
For simple projects that have set-env!
/ merge-env!
only at the top-level, you could mostly just load build.boot
.
For anything more complex, you need something Cursive-specific, right?
@U055HMK9L because I need to know which tasks to run, and those tasks have to be structured so that they don’t side effect when they’re just providing information.
You can’t risk having Cursive run a task that happens to deploy an artifact to http://clojars.org for example.
Because the user will end up with their project being build, or rockets being fired, just so they can open their project.
launching nukes isn't something you'd sanely do when you're developing and noodling around in an IDE
How would Cursive know what to run?
It will have to be, if that task adds project info (like adds deps or source dirs) before deploying.
Cursive has to figure out the classpath etc in order to do anything with the code
Ok, imagine that I have a boot task which adds some deps to the classpath, builds something and then deploys it to clojars.
Adding classprth in deploy task is weird
It should never happen
so let's imagine that we add an option to boot to obtain debug logs of events like jars added to classpath, etc
vim != Cursive
I think the problem here is @U055HMK9L doesn’t understand why Cursive is so different to other IDEs?
Ok, accepting the part where the user has to do some manual thing to open a project, I’m with you
Now I want you to build your uberjar, and in that uberjar I want a jar which is only required on EC2
(because you’re using a mock for dev?)
I’m willing to bet you a beer that when I add this we find a lot of projects that do that, or similar things.
I mean, whatever I do is going to involve a certain amount of “if you want this to work in Cursive, don’t do that"
When developing in CLJS, I often have a dev.core and a prod.core. I use dev when deving, and prod when prodding.
In any case we are going to instrument tasks and you could warn if there is no meta :boot/cursive
on it
Sorry, reading 😀
So when developing, dev will be on my source path, but when uberjarring, prod will be.
Boot is probably saner in this way, I usually change task for dev and prod and keep deploy as unique just for pushing things out
So I'd do boot cider dev --prod
if I need to dev on prod
i mean i always use environment variables and have just core.cljs, so nevermind what i'd do
but how does it make sense to want to use an IDE to edit a file that cannot run in my computer?
I’m often editing files that are intended to run only on CI/QA/production...
IntelliJ has to be able to index them, and it has to know where they are to do that.
i guess what i am thinking is why can't prod.cljs be on the classpath in both dev and uberjar
I think I’m going to try to implement something, and we’ll have to deal with problems as they occur. The instrumentation would undoubtedly be helpful though.
A concrete example from World Singles: we have a data migrations task that adds a new source folder to the classpath and a couple of additional JARs needed only by that task. We don’t want to drag that into the main project (because the data migrations task pulls in a huge number of namespaces etc). In order to edit the source files associated with data migration in Cursive, the IDE has to know about that source folder and those JARs in order to provide assistance.
like if you can launch a repl with all the things you will be editing available, then cursive will be good to go also
Yeah, I think that’s your basic disconnect @U055HMK9L — Cursive works very differently.
@U04V70XH6 That’s a great example, thanks.
Cursive does a huge amount of stuff without a REPL, right @cfleming ?
Yes from what I understand Cursive does static analysys
Even when the repl is off
i don't see how @U04V70XH6 example is different
It can do that with Leiningen projects because they are purely declarative (like ant/gradle etc).
And then I'll pass the mic to you @cfleming sorry 😀
like if you want to access migrations stuff in the repl you need to have it on the classpath
Cursive would not be able to provide any Clojure-specific assistance if I edited those data migration source files and it did not know about the changes to the environment from that task.
No, Cursive != REPL.
And I can’t find that source root without running the task, which does tons of migration or whatever.
The issue is that I can’t find out what the classpath is without executing the task.
Trade-offs gents lol 😁
So this can be solved, by Sean splitting his task into two, one to create the data and one to do the work.
Basically
But my issue is that lots of people don’t do that right now, with code that is out in the wild.
Which is probably ok in the case where whoever wants that to happen has some control over the project, but is not for some thing they downloaded off Github.
In any case cursive does not work atm so it is maybe better to push a sane default (imho)
@richiardiandrea Definitely.
like the requirement "cursive must be able to see anything you want to edit on the classpath" seems pretty straightforward
Hopefully once I actually add the support, enough people will use Cursive to create pressure for that to happen in projects even when the authors don’t care about Cursive.
It also seem an easier first approach to test the waters
And they could potentially be marked with metadata or whatever, or a list supplied to Cursive. It’s going to be weird for IntelliJ users who aren’t used to it, but they’ll get over it I guess.
The simplest approach — that doesn’t involve modifying Boot and wouldn’t require the user to run anything — would be to require that users add ^:boot/cursive
or similar to tasks that they needed Cursive to run?
That way the simplest projects should “just work” (load build.boot
and look at the classpath / env / etc).
Probably yes ^ then all those task will it the edn
Yeah, or supply a list of tasks at project import, perhaps. That might be difficult in the case of a project you don’t understand.
Anything else — with tasks that modify the classpath / env — would need some annotations on tasks to indicate they are safe to run: making it opt in from a user’s point of view.
Doing anything “automagically” is likely to be dangerous.
Yes probably you are right Sean
I don’t see any need to generate an external EDN file for this tho’?
It would just mean that I don’t have to run boot on every project open if nothing has changed.
(as a project maintainer, I’d certainly be happy to split up any tasks that would be needed to satisfy Cursive)
Ah, so a cache of metadata?
But you could run it and inspect the classpath / env and write that metadata yourself from Cursive, right?
Ah! That can be interesting for boot itself
@U04V70XH6 Sure, that would work too.
@U055HMK9L does a boot -z
sound like a good thing for boot in general? It seems like it to me.
{:name "single"
:group "single"
:version "0.1.0-SNAPSHOT"
:dependencies [{:artifact-id "clojure"
:classifier "sources"
:file "@repo/org/clojure/clojure/1.6.0/clojure-1.6.0-sources.jar"
:group-id "org.clojure"
:scope "compile"
:version "1.6.0"}
{:group-id "org.clojure"
:artifact-id "clojure"
:version "1.6.0"
:file "@repo/org/clojure/clojure/1.6.0/clojure-1.6.0.jar"
:scope "compile"}]
:repositories {"central" {:snapshots false
:url " "}
"clojars" {:url " "}}
:deps-tree {"org.clojure/clojure:1.6.0" {}
"org.clojure/clojure:1.6.0:sources" {}}
:source-paths ["@/src"]
:resource-paths ["@/dev-resources"
"@/resources"]
:test-paths ["@/test"]
:compile-path "@/target/classes"
:target-path "@/target"
:aot [test.main "namespaces.*"]}
:profiles
["base" "debug" "default" "leiningen/default" "leiningen/test"
"offline" "uberjar" "update" "user"]}
Basically - deps, source/test/resource paths, artifact details for all artifacts, repositories, dependency tree info if you have it (just for display, nice to have), compile output dirs, AOT info, CLJS info
You tend to do that via different pipelines of tasks 🙂
You can run boot repl -sp PORT wait
I think… with the caveat that you might need additional tasks in there.
(for comparison, ProtoREPL’s default is boot —no-colors dev repl —server wait
so it expects you to have a dev
task I think)
And it gets the port from .nrepl-port
(confirmed)
-s
is the alias for —server
(end of work day for me — but I’ll be back online later if this thread continues!)
Ok, thanks @U04V70XH6
Awesome on my side as well, following on buses and the final part at the dentist but it was worth it 😀
@cfleming yes nRepl for both clj and cljs
BTW, re: that code post looking huge in thread view -- if you click "All Threads" and expand the convo there, it's full-width and the code looks fine 🙂
So in that view I can see the thread full width, but can’t expand it to just look at this thread.
I agree it's less than intuitive... I consider it a "1.0" version so I'll cut them some "slack"... 😆 ...
awesome thread! 🙂
as @U0CLCL6T0 mentioned currently you can my little task which will generate an actual project.clj
which is pretty much that .edn
file boot -z
would emit.
@U055HMK9L you should have a look at my analysis of the problem at https://github.com/cursive-ide/cursive/issues/692#issuecomment-257907140
reading the conversation i've noticed that there is some fundamental misunderstanding regarding what a user might want to do and what do they expect to happen.
i think the most effective way to dissolve these misconceptions is to gather for a screen sharing session where we can show each other our workflows and see how those correlate
one good edge-case which highlights the fundamental differences between cider/fireplace vs cursive is editing the build.boot
file itself, which is:
1. not on the class path, so you can't require it.
2. it's "not a valid .clj
file" in that sense it doesn't start with an ns
form
3. it has implicit dependencies (`boot.core`, boot.util
, etc) besides clojure.core
@U04V70XH6 @cfleming i think when micha said "it's the same problem what a REPL has" he meant: if you would want to get a REPL with the same environment your migration task has, BUT without actually running the migration itself, is exactly what Cursive might want to do.
but it indeed sounded a little bit like he would assume "u must have a repl running anyway to make cursive work"
yeah i meant that getting a repl ready involves the same setup as getting cursive ready -- meaning that you need to have the things on the classpath etc to be able to compile them in the reql with require
, just the same as you need them available to cursive on the classpath etc when it does its static analysis
so i imagine there is some comparable facility in cursive for loading a file from the filesystem
yeah, i was using that a lot lately actually. would be good to highlight it somewhere in the getting started guide if it's not there yet...
I’m definitely down for a screen share to understand all this better, and in general it’s probably faster to discuss some of this.
I’m away today and Monday (it’s currently Friday here) but other than that any time next week is good.
An interesting question I have is: What of a task might load a couple of things, depending on others. It might be good to have metadata which can specify which dependencies this task might have, or point to a function for finding them.
@U09LZR36F yeah I do that all the time, that is why I have created that macro above above
Implicit target dir is deprecated, please use the target task instead.
Set BOOT_EMIT_TARGET=no to disable implicit target dir.
real 0m3.093s
user 0m8.824s
sys 0m0.452s
Implicit target dir is deprecated, please use the target task instead.
Set BOOT_EMIT_TARGET=no to disable implicit target dir.
real 0m3.062s
user 0m8.810s
sys 0m0.492s
fwiw, when the separate application is started up, the os x menu bar just says “Boot” in the top-left
huh, this happens to me when I use boot.test/runtests
, I never really thought about it being a problem. It is kind of annoying, though
yeah, i've experienced this java gui mode too. on macOS it has the side effect of a java logo appearing amongst the apps u see on the dock or the cmd-tab list.
Yeah, that cmd-tab thing is how I noticed it at first too. I don't think mine is related to webdriver, but I'm sure it's something similar with another lib. I tried to narrow it down a bit last night, but didn't find anything conclusive.
basically, I have a file in a fileset which (conceptually) I need to slurp, str/replace
with a regex, and spit out again, replacing what was there
apply a .diff
file?
this is an example of what you have in mind I think essentially: https://github.com/mjmeintjes/boot-react-native/blob/master/src/mattsum/boot_react_native.clj#L58
not sure about best practices though 🙂
I think the pattern above is the most common one, write in a tmp-dir!
the new content
sifting out the old file
can't vouch for that, someone with more boot knowledge would have to answer
@favila add-resource
adds to the fileset abstraction, merging in case of conflict (don't remember off the top of my head the default one though)
so you could use sift
to exclude the file you want to remove and then add-resource
won't have the conflict
(if I understood the problem correctly :))
@favila if you do not need the original file in output, put it in :source-paths and you won't need to sift.
@kenny it would give the same UI experience as figwheel
(nothing more, nothing less)
I used figwheel wayyyy back when we used lein, so I forget the difference in UI. Is there an example showing what I would gain with the figwheel UI?
yep it is on the lein-figwheel
website, yeah that sample works
After running the example and skimming the lein-figwheel readme, I still can't see what I would be gaining in terms of the UI. boot-reload also has the heads up display.
@kenny if you are ok with boot-reload
why change it 🙂
no well, figwheel does a bunch of things, at the moment only the client has been ported but it is probably easy now to even use the repl side of it
as anything, if people will pick it, it will expand and we will share code with figwheel, in theory pushing in there instead in boot-reload
for changes
and things will grow in that direction
if not, Deraen is actually doing a very good job with boot-reload
so there will maybe no need to use figwheel whatsoever 😉
Gotcha. Cool, thanks for the info @richiardiandrea 🙂
I actually find that dirac has replaced my need for almost everything -- figwhell, devcards, brepl, etc ...
yeah dirac is a good tool, the only thing is that I am too used to emacs 😄
@richiardiandrea : can you imagine how much overall emacs productivity you could generate if you turned 'dirac' into a repl that emacs could control?
does dirac
expose a cljs repl itself?
you should be able to do something like this with emacs: https://github.com/binaryage/dirac/blob/master/docs/integration.md
if emacs has at least one normal nREPL client implementation it should be possible without any changes on emacs side
@darwin yes emacs only has 1 implementation, which is a nRepl 🙂
@darwin , @richiardiandrea : how many pizzas would it take for the two of you to get emacs/dirac talking to each other?
it probably already works
the only thing is that you need to use inf-clojure
probably
I don't know/think that the cider middleware is supported
however you could try to do boot cider dirac repl -s wait
and see what happens 😄