When it comes to both Clojure namespaces and artifact coordinates for maven/clojars, normally we use inverted domain naming conventions, but for brevity (e.g. to omit the com, net, etc) can you just use your GitHub handle as the qualifier? So in my case, lambeaux.project-name for example? I vaguely remember that being allowed but I want to double check if anyone else recalls that too.
I believe people use io.github.username because GitHub pages gives them control of that subdomain
I've heard of that. But I'm trying to recall the semantic significance of artifacts without any domain qualifier in front.
I'm not saying it's good or bad, but I know it used to be done, and now for backward compatibility reasons, for those projects still lingering around without domain qualification, what assumptions hold true?
I'll take a look at that. Thanks.
Because dependency resolution is done by name, securing names becomes critical, and typically how that is done in maven is by saying only the domain owner can use a particular group id, then whoever controls a group id can use whatever names under it they want
Alright I guess I'm using dev.lambeaux.project-name instead. Does this mean if I qualify my keywords, I have to include dev in those too?
Or is that a bit more relaxed for brevity reasons?
Well, maven names don't have to have anything to do with names in your project
And keyword name space names don't have to have anything to do with code namespaces
But there's no agreed upon convention that they have to match, right?
If you own lambeaux.dev as a domain, it's reasonable to use that - dev.lambeaux - as your group ID for deploying projects. I would not expect anyone else in the Clojure world to be using lambeaux.* as a namespace so you're probably safe to omit dev. (for the ns, not for the group). But the ns and the group ID are not related - it's just a convention to make them similar that some (most?) folks follow...
Okay so if my group is dev.lambeaux I can keep my namespaces and key qualifiers to be lambeaux.project.etc and it should be fine?
In my two most popular oss projects, the group ID is com.github.seancorfield but none of that is in the ns names:melting_face:
Ah, that makes me feel better about this then. Thank you.
As hiredman notes, qualified keywords do not need to match actual nses. It's all about avoiding collisions with other libraries (and user application code).
Take this as anecdata of one person who never worked on world-scale projects (in the sense of number of developers involved), but I think that the risk of key collisions is overblown. As long as you attach any namespace at all to a keyword (like :foo/key), you'll never conflict with another person's :foo/key that they decided to put into the same hashmap as you.
Doubly so for code namespaces. Clojure ecosystem is tiny, and you can count the number of same-name libraries with one hand.
In Clojars it's done as a security measure. Domain squatting is a real risk.
Nice. I'm using a fairly concise alias namespace for all my qualifications. Should be more than enough.
Gotcha. I was less concerned about group ID and more so about namespaces and key qualifications.
To trust a published artifact, if you know the source is from http://github.com/foo or owned by http://www.someperson.com by having verification of domain ownership you can trust the source of the published package.
For namespaces, I'd say, it's trickier. If one day I depend on two libs that clash, I'm just screwed.
I personally do not like using github domain for my projects because I don't like depending on a third party service outside of my control for things like this. What if the service disappears or I no longer want to use it? Now I'm stuck maintaining the name regardless, which is why I'd prefer just projectname.ns format.
That's why I use my own domain for my libs. But it comes with a cost of paying for one, and some extra bookkeeping of it. That's why they offer the github/gitlab one
But back to namespaces.... I'd say either go: projectname/... So super small, so it's really convenient. But higher chances of clash. Or go full reverse domain com.domain.project/... Because if it's already too long I'll need to copy/paste it, then why not make sure it never clashes?
But keywords, that's a whole other question. I think it's more nuanced for keywords. Like what is the keyword for? How is it meant to be used, etc.
> If one day I depend on two libs that clash, I'm just screwed. If one day the cosmic radiation flips a bit in your non-ECC memory, you are screwed as well. The chance of two used and useful Clojure libraries clashing in names is virtually zero.
@alexyakushev Well, that might be because we use namespaces as a convention no?
I mean projectname/ns-name I agree has very low chances of clashing. Adding a domain prefix might be overkill.
But if it was just ns-name there would for sure be a lot more chances of a clash.
Afaik it is common convention in Clojure to always have at least 1 parent "package" namespace. E.g clojure.core, not just core.
Re: keywords though, I generally tend to not use namespaced keywords unless they are directly tied to a specific part of something where it makes sense to group keywords. I.e I'm currently working on a HTML parser, and I've "grouped" node map keys as :node/name, :node/attrs, :node/children. I only really use :projectname/something key for a project-wide constant kind of thing. Not sure if this applies at all to some agreed upon convention or not, just what my intuition has made me do.
@lambeauxworks I agree with everyone else.
org.project/name
Is good if you want to tie multiple "libs" back to an "org" and make that explicit.
Otherwise
project/name
Is good enough I think.
But project artifact should still be full reverse domain for security.
@asko304 JDK isn't very fond of packageless classes (which is what you get if you use a single-section namespace name), so having at least two parts is safer. Otherwise, having acme.core as your Acme library namespace doesn't make it much safer vs somebody else who has decided to name their library Acme and use acme.core too.
But my point is that with a small community like Clojure has, people who make libraries that other people use usually are aware about other things going on in the ecosystem, and are very unlikely to pick identical names for their projects (for marketing purposes, if nothing else).
As for the artifact name, sure, the FQDN is preferred, but that is already enforced by Clojars, so no choice there anyway.
I like to have the public API sit in <project-group>.core mostly because trying to guess (and remember) the nses without reading the code is a chore because they very often go undocumented
@doppiaelle1999 Not sure I followed?
The only reason <project-group>.core is so common is that Leiningen auto-added .core if you used a single-segment project name instead of rejecting it and making people "do the right thing". I think .core is a bit lazy -- think of a better name for the API or the CLI or whatever is the entry point to your program.
For example, Cognitect's test runner: -M main entry point is cognitect.test-runner and -X exec/API entry point ns is cognitect.test-runner.api
Oh I had no idea about this historical artifact, I just thought it was common convention.
@didibus It would protect from a kind of supply chain attack where I create a small library that gets used by people, and then I add a ring.core namespace to it, which is exactly like the ring.core from ring, but also runs a bitcoin miner on your server. If my library happens to be before ring on the classpath, mine is the one that gets loaded.
I mean, you might as well add the bitcoin miner on the main ns at that point
I appreciate this discussion everyone. Regarding the artifact group, that seems like an open and shut case.
Regarding ns names I think I'm warming up to just using the project name. Now that I think about it, I've definitely seen that pattern everywhere.
Which, makes me wonder, would some form of Clojure project name availability check be of use? To keep the benefits of concise naming and also help ensure no collisions. How often have any of you hit collisions that resulted in "being screwed"?
From a security perspective, I would really like to live in a world where all artifacts have a FQDN as their group ID and all packages / nses inside that artifact start with groupid.artifactid, and that is enforced at multiple points in the chain (e.g. by Maven/Clojars, but also by the JVM at load time).
We're not living in that world, but I still wanted to log that in as a reason to use fully-qualified ns names.
(To clarify, in this context, my concern is not about accidental name clashes.)
@gaverhae What would that buy you from a security point?
I think when you use the projectname.nsname convention, you do kind of run into the issue of what should the "main" namespace be called. Which is where "core" comes from as it imitated clojure.core I assume: projectname.core
I've seen projectname.projectname as an alternative.
But given this, having an orgname.projectname does make that nicer as you can do orgname.projectname as the "core" namespace for projectname and then you can have extra namespaces under orgname.projectname.otherns
Yeah, in my case, it'll now be project-name.core for my "main" namespace.
Actually, right now I have it as project-name.alpha.api instead.