This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-03-09
Channels
- # aleph (1)
- # announcements (4)
- # asami (6)
- # babashka (45)
- # beginners (19)
- # biff (3)
- # calva (35)
- # cider (4)
- # clojars (5)
- # clojure (117)
- # clojure-art (3)
- # clojure-denmark (2)
- # clojure-europe (89)
- # clojure-gamedev (5)
- # clojure-nl (4)
- # clojure-norway (17)
- # clojure-spec (3)
- # clojure-uk (5)
- # clojurescript (84)
- # conjure (13)
- # datomic (11)
- # emacs (2)
- # figwheel (2)
- # fulcro (16)
- # graphql (5)
- # honeysql (7)
- # introduce-yourself (1)
- # lsp (86)
- # malli (16)
- # music (1)
- # off-topic (2)
- # pathom (14)
- # polylith (28)
- # re-frame (11)
- # reagent (23)
- # releases (1)
- # reveal (19)
- # shadow-cljs (72)
- # spacemacs (13)
- # sql (1)
- # test-check (3)
- # timbre (4)
- # tools-deps (45)
- # vim (18)
I'm reading the Polymath docs and the https://polylith.gitbook.io/polylith/architecture/2.3.-component says
> A component's interface is a namespace that exposes a collection of functions for other components or bases to call. Each function in a component’s interface “passes-through” to an equivalent function in its private implementation (the core
namespace in this example). This “pass-through” approach enables full code navigation and refactoring, whilst maintaining encapsulation.
I don't really get a pass-through namespace helps. Is it to allow separate evolution of the interface and the core?
The https://polylith.gitbook.io/poly/architecture/interface page explains the reasoning behind Polylith using pass-through functions. Though if you’ve already read that page and it still isn’t clear, feel free to ask more questions.
The idea is similar to interfaces in object orientation. By looking in the interface
namespace you get a quick overview of what
you can do with that component. If you go into the implementing namespaces, then you can see how
it is implemented. For example, take a look at the https://github.com/polyfy/polylith/tree/master/components/text-table/src/polylith/clj/core/text_table component that is used by the poly
tool to render the different tables used by the info
, libs
and deps
commands. It has a single interface
namespace that delegates to the other seven implementing namespaces. This is also an example of how to group functions that perform a specific task into their own namespaces, instead of putting everything in a single namespace (e.g. core
).
I’ve created a visual board to introduce Polylith, highlighting important parts from the documentation. Have a https://beta.scrintal.com/b/polylith-architecture--9c4px and share if you like!
Hmm. My coworker is using poly test project:foo
to run tests and it works for him. For me, it does not run anything and just says Execution time: 0 seconds
. I wonder if I've made some obvious mistake
poly test
is incremental, so if you have no changes from the last stable tag, no tests will be run. You need to use poly test :all
to force all tests to be run, regardless of changes.
Ok. Is there a way to run tests for a single project even though nothing has changed? I tried poly test :all project:foo
but it runs tests for all projects of course
Maybe we should change the curren hehaviour so that if we specify both :all and project:foo, we should only run all tests for specified project(s).
Just realised that I can tag the initial commit of the repo git tag always ...
and run poly test project:foo since:always
to force-run the tests
I created a GitHub issue about this here: https://github.com/polyfy/polylith/issues/189
Could someone please remind me what the solution is for the ridiculous fact that interface
is a reserved keyword on JavaScript? :face_with_rolling_eyes:
(as a reminder we are considering switching to polylith and the codebase has mixed hosts, so I'd like to know if, should we take the plunge, we'll have to specify an alternative interface namespace throughout the repo or if there's a more flexible way)
(edited for clarity)
In workspace.edn
, specify a different word for the interface ns.
:interface-ns "interface"
You can change that to something else -- and it will be repo-wide.Right, thanks!
I was actually wondering if there was a way to e.g. override :interface-ns
for specific bricks or something because having only a repo-wide setting kind of forces teams to either be aware of javascript's limitation before they switch or risk having to refactor a lot of code later on.
As far as I know, it's a single, global setting. So set it up to an agreed string before you start to migrate to Polylith.
cljs.user=> (ns foo.interface.bar)
WARNING: Namespace foo.interface.bar contains a reserved JavaScript keyword, the corresponding Google Closure namespace will be munged to foo.interface$.bar at line 1 <cljs repl>
foo.interface.bar=>
Since it is only a warning (and would only affect JS interop), maybe you could just stick with interface
and live with the JS/ClojureScript interop issue there?@U1S4MH05T The poly
tool isn't going to check any JS files so their structure can be whatever. I don't remember if the poly
tool checks .cljs
files? Pretty sure it checks .cljc
files (as Clojure). This is an area we'll have to deal with later this year, since we'll be doing our first cljs work since 2015 and our first within the Polylith setup...
We've migrated all our cljs into bases so far, but getting to the point where we'll be extracting bits. We also have some fullstack node repos though, which we want to change to poly too. Haven't started thinking through it yet though.
Just OOC, what is the interop issue this could cause? It's been a good while since I've done any clojurescript.
One idea is to support more than one interface name, like :interface-ns ["ifc" "interface"]
. It would still support the old syntax where the value is just a string.
Yeah I would like to see the support for a vector, I just went through and did a rename of all interface files last night and there import statements, leaving the clj ones as interface and using something else for cljs would have been much simpler most of my code is cljs so it can be shared
Polygaul is ultimately convention. So you can also do something like foo.interface-js
(if you prefer to keep the clj interface name)
We’ve actually have a such a case where some of our existing architecture did not fit entirely with polylith. But having it as a convention means we could also add checks around it as well as ensure uniformity