Fork me on GitHub
#polylith
<
2022-06-16
>
ikitommi05:06:21

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.

tengstrand07:06:04

Okay, thanks for reporting this. I will have a look.

👍 1
ikitommi15:06:50

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?

👍 1
ikitommi15:06:50

“reload just all already loaded code” or something.

ikitommi15:06:34

I also could start the repl from the project I’m editing I guess :thinking_face:

ikitommi15:06:41

I think same applies to mount, and more, as the namespaces themselves can be stateful.

Ken Allen17:06:19

sounds like a good reason to use component over integrant imo

ikitommi18:06:36

c.t.n.r/refresh re-loads all code causing unwanted side-effects, regardless of what state management system you use.

ikitommi18:06:17

but true, component is bit better here.

ikitommi18:06:42

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. .

seancorfield19:06:09

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!

😂 3
imre19:06:59

afair component's repl additions also call ctnr/refresh so using component over integrant wouldn't be a solution by itself

☝️ 1
Ken Allen21:06:19

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

seancorfield22:06:16

@U08BJGV6E I never use that .repl stuff for Component either 🙂

😁 1
ikitommi05:06:32

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

ikitommi05:06:45

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.

ikitommi05:06:10

there it would be safe to refresh everything.

seancorfield05:06:11

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.

ikitommi05:06:07

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.

👍 2
ikitommi05:06:42

maybe someone could write a point-by-point “how to do this without” guide?

👍 2
ikitommi06:06:57

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.

seancorfield23:06:47

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?

Hukka05:06:52

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.

Teemu Kaukoranta05:06:40

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. 😄

jeroenvandijk05:06:40

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

seancorfield05:06:49

@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).

jeroenvandijk06:06:44

@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

jeroenvandijk06:06:27

@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)