This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-03-15
Channels
- # admin-announcements (25)
- # beginners (21)
- # boot (487)
- # cider (8)
- # clara (2)
- # cljsrn (35)
- # clojure (44)
- # clojure-austin (6)
- # clojure-russia (211)
- # clojure-uk (25)
- # clojurescript (225)
- # core-matrix (1)
- # data-science (3)
- # datomic (23)
- # events (1)
- # hoplon (9)
- # immutant (14)
- # jobs (1)
- # jobs-discuss (5)
- # ldnclj (3)
- # lein-figwheel (2)
- # off-topic (2)
- # om (65)
- # onyx (65)
- # parinfer (3)
- # pedestal (4)
- # proton (1)
- # protorepl (1)
- # re-frame (16)
- # reagent (3)
- # ring-swagger (1)
- # specter (11)
- # untangled (1)
- # yada (8)
from inside the webjar? sorry that's why I was asking, I am not very familiar with webjar and I should have googled it 😉
There are no externs in webjars. Extern only exist in Cljsjs.
there’s no way to see what options were passed to a task from within another task, right? Specifically knowing where the target
task is outputting the fileset?
is it possible to load and use code from inside your project inside the build.boot file? I'm having issues requiring code and then using it.
definitely possible
what issues are you having?
@adamfrey: there are ways to work around this but generally this introduces hidden coupling between tasks. Whats the motivation?
is there a way to detect from my Clojure code if it's being run from boot in development mode or in production from uberjar?
I have a command-line app that uses (System/exit ...)
which is really bad for repl, so I want to use it only in production
does it make sense to split the code so that System/exit
is only ever called when going through -main
and -main
is never called in development?
I took the code layout from https://github.com/clojure/tools.cli#example-usage
another option is to throw some sort of exception that will only get caught in -main
and trigger exit
i use environment variables to hold that kind of configuration, like dev vs production environment etc
when i deploy to production i have an upstart script that launches the appliction and that's where the production environment variable setup happens
and i have scripts that can set up a shell with dev environment via source
or eval
in bash
@martinklepsch: I’m adding a boot task to James Reeves’ codox library, and I was trying to match the lein plugin’s behavior of printing a message that lists the absolute path where the docs are generated. But James said that it was ok that the boot version prints a relative path, so I’m all good.
nice @adamfrey looking forward to giving it a try
hey @georgek welcom 👋
@adamfrey: There is a boot task for codeina (which is codox fork): https://github.com/funcool/boot-codeina should be helpful to check how it has beem implemented
Im experimenting with making production version of my boot cljs project with "boot cljs -O advanced -- target", only thing missing is sass stylesheets. Any way to compile sass along into target/css ? For sass Im using [mathias/boot-sassc "0.1.5"]
@hlolli: there is a boot task for sass : https://github.com/Deraen/boot-sass
And an example here : https://github.com/Deraen/saapas/blob/master/build.boot#L80 I never used mathias/boot-sassc though so I can't compare
ahh ok, this is a different sass dependancy for boot. Well, I think what's standing in my way is that Im first time actually deploying something vs always developing. I think I need to read alot now. I notice differences from lein where a target directory was created with all the *js files ready to be lunched without serving the directory. (but my memory could be wrong) (sorry js not java)
@hlolli: are you developing a CLJ+CLJS app?
(as in a single project/build?)
no, it's all pure clojurescript built on tenzing actually. I see there is a production deftask, cant seem to wrap my head around how to use it.
boot production build
essentially the production task acts like a profile setting all the parameters required for production builds
ok, I wonder where the target directory is? Maybe I need to supply it with -- target ? I do boot production build but I see no files generated.
@seancorfield: hey, how would you feel about moving boot-new to the boot groupId instead of making it a builtin?
yeah, try boot production build target
I usually have some task that syncs things to S3 or similar
@hlolli: if you're deploying a static site, checkout this: https://github.com/confetti-clj/confetti
@juhoteperi: thanks! I didn’t know about that
@dominicm: For first year and for limited resources (but the limits are quite high)
@alandipert: I’m fine with that but it’s still going to be a bit of a mouthful to type boot -d boot/boot-new new -t app -n myapp
compared to boot new -t app -n myapp
yes?
@seancorfield: i was thinking boot -d boot/new new
, but yeah it will still be slightly longer
@seancorfield: Can't people just copy a snippet to their boot.profile?
Maybe boot-new could be maintained in separate repo and artifact but the task could be included in core?
Would make it easier to develop boot-new separately but would be easy to use for everyone
How about if the task itself moved to Boot core but all the built-in templates and machinery stayed in boot/new
and that dependency was brought in at run time?
the reason for waiting is just that new
is just such a juicy builtin (and project task name), and micha and i talked ourselves into thinking that it might be good to wait and see a bit longer if something else makes more sense to go there
i think our reservations are less about where the code lives and more about the new
builtin
Agreed, which was why I was initially holding off wanting to integrate it — but with 2.6.0 coming up faster than I expected, it seemed like a good opportunity… and I think it was @micha who’d originally asked if I planned to send a PR 😸
i could still go the other way, just wanted to discuss
i think it might be good to let it percolate for a little while longer before fully integrating it, so it won't be too disruptive to make changes
I’m happy to continue to maintain it separately tho’ if that’s what you would prefer… and making it boot/new
rather than seancorfield/boot-new
would be fine if I continue to maintain it there.
informing my thinking is making a new project is relatively rare compared to the other tasks, and that we will live with the builtins for probably decades
centuries!
Indeed. And lein new
was lein-newnew
as a plugin for ages before it was integrated.
so that we get a significant percentage of users who would use it to check it out and provide feedback?
Strangely I hadn’t even thought of adding it to profile.boot
— because I didn’t want to drag in the dependency on every boot
call
Indirection solves everything
You’d have to duplicate all the argument processing tho’ … that’s quite a lot of code …
It would be more convenient / easier to add a boot-new
shell script that invoked boot -d seancorfield/boot-new new "$@"
or something...
alias n="boot -d seancorfield/boot-new new"
or i guess we could distribute multiple shell scripts that are different entrypoints into the app jar... but then we'd need a real installer
(! 1157)-> cat ~/bin/boot-new
#!/bin/sh
boot -d seancorfield/boot-new new "$@"
OK, I’m happy now 
(and, yeah, alias
would work too but I don’t have any shell aliases at the moment … color me weird)
oh here's an idea
Anyways, I’m happy to go whichever way you want at this point. I restructured the boot-new
code to be easier to integrate and that’s an improvement anyway. I’m happy to maintain it under my user or move it to the boot
org and maintain it there or… whatever…
so probably most new users obtain via homebrew? maybe we could add the stub script as part of the brew formula
@seancorfield: cool. thanks for making and contributing, it's super cool we don't rely on lein anymore
Yeah, I’m using Boot for FW/1 stuff now as well which is nicer than Leiningen. And I’m starting to use it for generators in other projects too.
Since you can just add a boot.generate.whatever
namespace to your project for any new thing you want to generate
is it possible to load and use code from inside your project inside the build.boot file? I'm having issues requiring code and then using it. What I'm trying to do ultimately is support modern deep linking in a cljs application. it works fine in production but for testing i think i need to have a custom ring handler for the serve task, so urls like: http://host/blah/blah can be mapped to http://host/index.html
@hlolli: any success with the deploying?
and i'd like to implement the ring handler in the current project versus build it somewhere out of context.
@fenton: if you're using boot-http
you can have a custom handler that you supply as a fully namepspaced symbol
yes this worked! Just the way I wanted it. I will upload it tomorrow to a server, I just used python simple http to confirm. It still needs few last-minute text fixes, but I just wanted to know this process today in case it would drag on tomorrow.
@martinklepsch: i tried to fully namespace it, but still complains it cant find it.
@martinklepsch: sorry this example has too much crap in it...i'll make a streamlined one later today to show my issue.
@martinklepsch: does that symbol have to come from an external library or can it be simply defined in the current project.
and more generically can boot use code that is defined in the current project, or only code that comes in through external libraries?
micha: okay. i was able to require it, but when i tried to use it...it complained it couldn't be found...i'll try out the resolve part.
@fenton: you may need o quote the symbol
single quote gave same error #'
gave:
â•â”€fenton@ss9 ~/projects/pcbe-web ‹ft-auto2*›
╰─➤ boot dev 1 ↵
clojure.lang.ExceptionInfo: Unable to resolve var: pcbe-web.ring-handler/handler in this context
data: {:file "/tmp/boot.user5558579707800723701.clj", :line 27}
java.lang.RuntimeException: Unable to resolve var: pcbe-web.ring-handler/handler in this context
...
boot.main/-main/fn main.clj: 192
boot.main/-main main.clj: 192
...
boot.App.runBoot App.java: 390
boot.App.main App.java: 467
...
boot.Loader.main Loader.java: 253
â•â”€fenton@ss9 ~/projects/pcbe-web ‹ft-auto2*›
╰─➤
@fenton: what error did the single quote give you? Is the namespace in resources?
@micha: @dominicm @flyboarder thank you guys.
boot.user=> (doc serve)
-------------------------
pandeiro.boot-http/serve
([& {:as *opts*, :keys [help dir handler init cleanup resource-root port httpkit silent reload nrepl not-found]}])
Start a web server on localhost, serving resources and optionally a directory.
Listens on port 3000 by default.
Keyword Args:
:help bool Print this help info.
:dir str The directory to serve; created if doesn't exist.
:handler sym The ring handler to serve.
:init sym A function to run prior to starting the server.
:cleanup sym A function to run after the server stops.
:resource-root str The root prefix when serving resources from classpath
:port int The port to listen on. (Default: 3000)
:httpkit bool Use Http-kit server instead of Jetty
:silent bool Silent-mode (don't output anything)
:reload bool Reload modified namespaces on each request.
:nrepl edn nREPL server parameters e.g. "{:port 3001, :bind "0.0.0.0"}"
:not-found sym a ring handler for requested resources that aren't in your directory. Useful for pushState.
nil
Re: boot-new, nobody asked me but I don't miss that part of the lein ecosystem, both because scaffolding new projects is not such a common task (and I kind of enjoy it), and because there's such a limited range of extendability, basically all configuration possibilities need to be thought of in advance and added to the template.
What I do think would be useful is for framework/architecture tools (like luminus, for example), had generator commands like rails or yeoman to quickly scaffold a particular new view or model
@pandeiro: Someone i know has been working on something like templates, but architected around git branches & tags, and when you want to get template updates, you "just" merge with the master. It's an interesting idea, trying to figure out the conflicts is hard though.
(when-let [changed-sql (seq (->> (fileset-diff @fs-prev-state fileset) input-files (by-ext [".sql"])))] (println "Changed these files: " changed-sql) (doseq [db-file (by-name ["db.clj"] (input-files fileset))] (touch db-file)))
i think there must be a more straightforward way to achieve this without messing with files
I want to make it so everytime a .sql file is changed, the db.clj file is "updated" so that system reloads the namespaces
@pandeiro: That's pretty much what he's suggesting. With a couple branches for specific styles (e.g. webapp)
if the .sql files were .clj files it would work, because you could require them in db.clj
yeah i mean the way i would do that is to generate clojure namespaces from the sql files
@pandeiro: the macros do reload, it's just the code running already has the old macros
there is no way for tools.namespace to know that this macro depends on doing IO to read some text file
OR, you could use the namespace's refresh-all
, OR require them manually after changes to them..
but you still have the problem of expressing the dependency relationships in a sane way
Sounds like something better thought of and handled as part of the build chain, not app code
it would be pretty strightforward to have a task that finds .sql files and creates namespaces from them
if you do want to update the mtime of a thing in the fileset you can do it by copying the file to a temp dir, updating the mtime, then adding that temp dir back to the fileset
subsequent tasks in the pipeline will see the updated mtime, but it won't affect your actual project files
1. make a task that generates clojure namespaces that you can require in db.clj, thereby using the existing clojure dependency system and tools.namespace for reloading
2. extend tools.namespace to accomodate arbitrary dependencies in addition to what clojure already provides, that is adding some kind of annotation to the namespace that declares the dependency on those .sql files
boot is exceptionally good at generating things like clojure namespaces from other formats
like with hoplon we had haml files that would be transformed into hoplon files which would be transformed into clojurescript namespaces + html files, which would be compiled by the cljs compiler into js
well, would it be even easier to create a new ns-file, dump all the text into a str var in the new ns, and pass that string var to yesql?
(doseq [db-file (by-name ["db.clj"] (input-files fileset))]
(println db-file)
(cp fileset db-file ( tmp "db.clj")))
I'm using pod/call-in*
to execute code in a pod, and am getting nil
back. If I add println
to the code in the pod, I can see it returning a value - any tips on debugging that?
@tcrawley: that's probably because the pod is returning something that isn't printable/readable
(http://clojure.java.io/copy (http://clojure.java.io/file "/tmp/blahdb.clj") (http://clojure.java.io/file tmp (tmp-path db-file)))
getting
java.io.FileNotFoundException: /Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/nwf/dkd4k1/doublethedonation/db.clj (No such file or directory)
so if you update the mtime on the file you will see a strange interaction with the watch task
so the next time you change a file in your project the mtime will be reset back to the older mtime
side-question.. how I make cljs not recompile when editing non-cljs files? it seems to do it for every file
â—‰ :cp doublethedonation/controller.clj
#'doublethedonation.system/dev-system:refreshing:doublethedonation.controller
#'doublethedonation.system/dev-system:refreshing:doublethedonation.handler
#'doublethedonation.system/dev-system:refreshing:doublethedonation.system
Compiling ClojureScript...
• public/js/ddplugin.js
Elapsed time: 1.024 sec
and use the output of the compiler analysis to make a better decision of when to call it
â—‰ :cp doublethedonation/controller.clj
#'doublethedonation.system/dev-system:refreshing:doublethedonation.controller
#'doublethedonation.system/dev-system:refreshing:doublethedonation.handler
#'doublethedonation.system/dev-system:refreshing:doublethedonation.system
Compiling ClojureScript...
• public/js/ddplugin.js
Elapsed time: 1.041 sec
â—‰ :cp doublethedonation/integrations/router.cljs
Compiling ClojureScript...
• public/js/ddplugin.js
Compiling /Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/-rcsl8f/doublethedonation/integrations/router.cljs
Compiling /Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/-rcsl8f/doublethedonation/integrations/core.cljs
Reading analysis cache for file:/Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/-rcsl8f/doublethedonation/integrations/router.cljs
WARNING: Use of undeclared Var doublethedonation.integrations.core/update-data at line 370 src-cljs/doublethedonation/integrations/core.cljs
Compiling /Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/-rcsl8f/doublethedonation/core.cljs
Compiling /Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/y82kcs/boot/cljs/main30310.cljs
Reading analysis cache for file:/Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/-rcsl8f/adzerk/boot_reload.cljs
Copying file:/Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/-rcsl8f/doublethedonation/integrations/router.cljs to /Users/kanwei/.boot/cache/tmp/Users/kanwei/Projects/doubledonation/o3d/-b1oyye/public/js/ddplugin.out/doublethedonation/integrations/router.cljs
Elapsed time: 1.270 sec
{:require [doublethedonation.core]
:compiler-options {:asset-path "/api/js/ddplugin.out"
:externs ["public/js/externs.js"]
:preamble []}}
this is what i get on my machine, and it's compiling hoplon etc, with reload and whatnot
without cljs
â—‰ :cp doublethedonation/controller.clj
#'doublethedonation.system/dev-system:refreshing:doublethedonation.controller
#'doublethedonation.system/dev-system:refreshing:doublethedonation.handler
#'doublethedonation.system/dev-system:refreshing:doublethedonation.system
Elapsed time: 0.497 sec
(deftask dev
"Run when developing"
[]
#_(lein-generate)
(comp #_(environ :env {:dev "true"
:http-port 3000})
(watch :verbose true)
#_(refresh-sql-files :db-files ["db.clj"])
#_(serve :init 'doublethedonation.handler/init
:handler 'doublethedonation.handler/app
:reload true)
#_(system :sys #'dev-system
:auto true
:files ["handler.clj"
"db.clj"])
#_(sass)
#_(reload :asset-path "/api/")
#_(cljs :source-map true
:compiler-options {:output-wrapper true
:devcards true}
:optimizations :none)
#_(repl :port 62909
:server true)))
but if you have the target task it might need to write files there, which can take time
How do you get correct aot build ordering? It seems to ignore imports and requires in determing the order of .cljc files to compile.
@laforge49: how do you mean?
I specify both base and AAVector to be aot's. and indeed, it compiles 1/2 and can't find the interface defined in the second because it is compiling in the wrong order.
but it might be faster for more complex things when you need to get fileset diffs and such
ns durable.AAVector #?(:clj (:gen-class :main false :extends clojure.lang.APersistentVector :implements [clojure.lang.IObj durable.base.INoded] :constructors {[java.lang.Object clojure.lang.IPersistentMap] [] [java.lang.Object clojure.lang.IPersistentMap clojure.lang.IPersistentMap] []} :init init :state state)) (:require [durable.base :as base]) #?(:clj (:import (durable AAVector) (durable.base INode) (clojure.lang IPersistentMap))))
:extends clojure.lang.APersistentVector :implements [clojure.lang.IObj durable.base.INoded]
I'm thinking that anything that needs to be imported by an aot'd file must be in a clj file.
Is there a way to prepend a javascript file to my output bundle in boot-cljs?
@pesterhazy: Define the file as foreign-lib using deps.cljs
in local project and require the namespace from cljs. Saapas should have example: https://github.com/Deraen/saapas/blob/master/src/cljs/deps.cljs
@juhoteperi: I think I actually need the file to be at the top of the file, before everything else
@pesterhazy: Foreign libs are placed before anything else, and if you require this foreign lib the first (main namespace, first require line) it should be before anything else
@juhoteperi: I'll try that then
@juhoteperi: that worked fabulously
@pesterhazy: another option might be just creating a new file and appending the built js? doesn't require foreign libs hackery...
there is also the :preamble
compiler option if you want to prepend something like a license or copyright comment
foreign libs seem to work, but :preamble
seems an even better
and all just to make the react-native packager happy
@micha, I actually need it for optimizations simple and above only
@pesterhazy: @micha still thinking prepending with a task might be better, user could have their own preamble set.
prepending with a task sounds good except I'd need to figure out how to do that with boot
hmm preamble doesn't seem to work
WARNING: Preamble resource file not found: prelude.js
needs to be in the resource dir I assume
hardly
I'll always find a way to do it in a hacky way
it's in my nature
thanks guys you've helped a lot
if only react-native had a channel like this
(with-pre-wrap [fs]
(let [path "some.js"
out (tmp-dir!)
f (tmp-file (get-in fs [:tree path]))
newf (io/file out path)]
(io/make-parents newf)
(spit newf (str "mypreamble" (slurp f)))
(-> fs (add-resource out) commit!)))
@pesterhazy: didn't try any of this but should give you at least a starting point
thanks!