This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-16
Channels
- # announcements (33)
- # atom-editor (1)
- # aws (21)
- # babashka (174)
- # babashka-sci-dev (2)
- # beginners (59)
- # calva (4)
- # chlorine-clover (9)
- # clj-kondo (51)
- # clojars (7)
- # clojure (86)
- # clojure-czech (4)
- # clojure-europe (21)
- # clojure-france (6)
- # clojure-nl (1)
- # clojure-uk (2)
- # conjure (7)
- # core-async (3)
- # core-logic (3)
- # cursive (10)
- # data-science (8)
- # datalevin (14)
- # datomic (12)
- # events (1)
- # fulcro (5)
- # graalvm (10)
- # gratitude (3)
- # honeysql (3)
- # hyperfiddle (3)
- # introduce-yourself (4)
- # joyride (3)
- # leiningen (3)
- # malli (13)
- # minecraft (15)
- # music (1)
- # off-topic (40)
- # pathom (16)
- # polylith (28)
- # portal (25)
- # rdf (15)
- # remote-jobs (3)
- # shadow-cljs (23)
- # specter (1)
- # sql (5)
- # tools-deps (25)
- # xtdb (31)
It seems that after https://github.com/polyfy/polylith/commit/adf957cc055ba1ceaca25e6119915b4d3ad77b48, the project level tests are not run by default. quickly baked an https://github.com/polyfy/polylith/issues/235 out of that.
Whatabout Integrant & polylith? being able to launch a repl from polylith root is a great feature and you can easily start one integrant system from it. But the integrant-repl reset
calls clojure.tools.namespace.repl/refresh
, which by default finds all code from the repo and things get ugly (all global side effects (multimethods, specs etc) get loaded. As expected, (do (halt) (go))
works, but is there a way to limit the refresh scope in polylith so that something like reset
would work?
I think same applies to mount, and more, as the namespaces themselves can be stateful.
c.t.n.r/refresh
re-loads all code causing unwanted side-effects, regardless of what state management system you use.
but, doesn't poly know the classpaths? Is there, or could there be a (in-project "dispatcher")
repl helper that would create a new classloader with just all the project dependencies? or poly repl project:dispatcher
. .
This is why I tell people to avoid reload/refresh workflows š Aw, c'mon, you knew I was going to pop in and say that!
afair component's repl additions also call ctnr/refresh so using component over integrant wouldn't be a solution by itself
Yeah I donāt use that refresh thing either. Not sure I understand why it would be necessary. I guess thatās a different discussion though lol
I donāt expect everyone to like that š but, many people lean on that and would be nice to get it working with polylith. One can narrow the reload directories with c.t.n
using set-refresh-dirs
. hereās the motivation for the refresh if @U03HTB6V19B if you have not bumped into it earlier: https://github.com/clojure/tools.namespace#reloading-code-motivation
but, a poly repl project:dispatcher
command would be actually much better => āgive me a repl for the project with just all the deps it requires.
It would be nice to educate people to adopt REPL-friendly development practices that made the whole reload/refresh nonsense irrelevant. Sorry, but I feel pretty strongly about this -- you talk to Alex, and Rich, and Stu, and folks like Eric Normand... none of them use this approach, none of them think it is needed. We need to teach people better REPL practices instead.
I personally would really much like to learn how to not need that! but most of the things in the āmotivationā were biting me, before started to use the reloaded workflow.
maybe someone could write a point-by-point āhow to do this withoutā guide?
that also btw spans how libraries are developed, for example, reitit doesnāt have a dev / repl-friendly mode (but it should), the router is always on prod-mode, e.g. compiles the route tree for performance - if you use reloaded workflow, just reset
and it recompiles. If you donāt have, itās not that much fun as changing any route snipplet requires you to reload the ns/def where the router is created.
What about tiny little "library"-style components? Are folks just making components
for those with interface
and impl
or are some of y'all still using some sort of libs
tree inside the monorepo and keeping that code "outside" Polylith?
I ask because that Q came up today at work. I'm breaking apart our "lowlevel" kitchen-sink subproject and there's a with-retry
macro that's used in a number of places in the codebase and it's current, rather arbitrarily, in worldsingles.system
which is being refactored away. My team mate and I couldn't come up with a decent name so we're probably going to have a with-retry
component, at least for the time being, containing just that macro and its implementation helper functions.
It's never going to have an alternative implementation so we're also sort of tempted to stick it in a libs
tree in the repo, "outside" of Polylith, and continue to treat it as if it's "just" a 3rd party library (but use a :local/root
dependency for it).
Suggestions? Thoughts?
We don't use alternative implementations for anything, but we still keep everything under polylith. All kinds of misc stuff goes to util component, though not nearly all of them does get used by every project. It's fairly small though, so we haven't even thought about splitting it yet.
we also have a test-util and util component. I think both of them have just a single macro currently. I don't really have an opinion on that pattern yet because neither of them are used in too many places yet.
FWIW usually I try to avoid adding a util
namespace because it's just too easy to push random stuff there. š
Good question. I feel something similar although I havenāt made tiny libraries yet.
I feel some code is not repo specific (project is ambiguous here) and therefore shouldnāt be a component. Having it as a component clutters the components directory (visually). (Also I think you cannot nest components to fix this.) Then again I would like to have the benefits of a component, e.g. after I make a change to the library, tests of components that are dependent will be triggered on poly test
. So I like the suggestion of @U8ZQ1J1RR as a middle ground.
Another related question I think, what do you think about swappable libs? Code that is more like a library, used across repoās, but that has multiple implementations for different contexts. Right now for instance, Iām working on an http abstraction component
that has multiple implementations, depending on if you are runnning in production or development it has different properties (e.g. not allowing external requests or recording it). In setup a bit similar to https://github.com/clj-easy/tools.misc/tree/main/json
@U0FT7SRLP Funnily enough, one of our two swappable components right now in our monorepo at work is an http client abstraction that is implemented by Hato in one brick and by http-kit in another brick. We've done this for JDK8 compatibility (http-kit) because we still have code that has to be shared with a legacy app that must run on JDK8 (everything else runs on JDK18 at this point).
@U04V70XH6 Ah nice. My goal is to create a Ruby like experience where you use a dev http client that can record external interactions (using vcr-clj under the hood). And I would like to promote it so library authors will use this abstraction instead of choosing an arbitrary client (like clj-http, httpkit or aleph). This would allow to control http work at the root of your project
@U04V70XH6 Maybe itās interesting to see if we can get to a common interface over these libraries and discuss it in a project like tools.misc
(so we can use our own implementation https://github.com/weavejester/ring-oauth2/blob/master/src/ring/middleware/oauth2.clj#L77)