This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-01
Channels
- # adventofcode (93)
- # announcements (44)
- # asami (23)
- # aws (1)
- # babashka (48)
- # beginners (112)
- # calva (26)
- # cider (57)
- # clj-kondo (17)
- # cljfx (5)
- # cljs-dev (21)
- # clojure (124)
- # clojure-europe (19)
- # clojure-hungary (40)
- # clojure-nl (3)
- # clojure-spec (7)
- # clojure-uk (3)
- # clojurescript (3)
- # cursive (81)
- # datalog (11)
- # events (21)
- # exercism (1)
- # fulcro (37)
- # graalvm (1)
- # introduce-yourself (8)
- # jobs (1)
- # lsp (1)
- # malli (5)
- # membrane-term (17)
- # minecraft (3)
- # nextjournal (5)
- # off-topic (14)
- # other-lisps (14)
- # polylith (58)
- # reagent (16)
- # reclojure (3)
- # reitit (6)
- # remote-jobs (1)
- # shadow-cljs (55)
- # spacemacs (15)
- # testing (2)
- # tools-build (7)
- # tools-deps (191)
just released Clojure CLI prerelease 1.10.3.1036 which adds license info to clj -X:deps list
, give it a try if you like
Here's an example output in tools.deps.alpha itself
works with Maven deps, pom-based file deps, local jars, but not with deps-only local/git deps
What causes this limitation @U064X3EF3?
I'm pulling the pom license info, deps projects don't have that in a known place. Can potentially fill that gap.
I would imagine that 90% of projects that have an explicit license have a LICENSE
file at the top level? GitHub does that by default when you create a new repo and select a license, and both lein new
and deps-new
(and clj-new
) create LICENSE
(EPL, but with a note in the README that you can change licenses). boot-new
too, not that anyone uses that these days 🙂
for sure, but what do I do with a blob of text in a LICENSE file?
I have not spent the time yet to devise a strategy to go from that to "license name"
maybe just the first line is often sufficient
Ah, right, I hadn't thought that through very much...
it seemed worth releasing it without that before I figured that part out :)
...looking across a bunch of LICENSE
files here, I suspect you could pattern match common ones from the first non-blank line of the file (which looks to be the first line in nearly all cases).
yeah, that's probably a decent hack
(! 647)-> head -1 */LICENSE
==> build-clj/LICENSE <==
Apache License
==> clj-new/LICENSE <==
Eclipse Public License - v 1.0
==> deps-new/LICENSE <==
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
==> expectations/LICENSE <==
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
==> next.jdbc/LICENSE <==
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
==> polylith/LICENSE <==
Eclipse Public License - v 1.0
==> sean-polylith/LICENSE <==
Eclipse Public License - v 1.0
(just what I have on hand on this machine)Looking across my whole machine, a lot of LICENSE files begin with a copyright line. Nearly all of those have this text, whatever license this is:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
FYI it would be better to adopt existing best practice in this area i.e. https://spdx.dev/license-list/matching-guidelines/
The folks involved in that initiative have spent a LOT of time considering this problem, including “corner cases” that are a lot more common than you might think (e.g. dual-or-more licensed software where the author has concatenated all of the licenses’ texts into a single ./LICENSE
or ./COPYING
or whatever file).
I'm not going to do text matching of any license text as I don't want to "pay" for maintaining or including or downloading the text to match against
Right. Just pointing out best practice, based on years of experience (others’, to clarify, not mine).
I linked this site in the prior discussion, I am aware of it
You’ll also hit the issue that many MANY Maven artifacts don’t include license information at all, either in their pom.xml
or as a LICENSE
or COPYING
file. In fact a bunch of Clojure’s own JARs are like this too.
actually, Maven central requires license declaration in the pom and virtually all libs do include it
Clojars does not but in practice seems most I've looked at do include it
so just using pom info yields a pretty high success rate
That may be a recent thing, as there certainly are a large number of popular Maven-hosted artifacts that don’t.
it has always been a requirement on central
or "always" since I started deploying stuff there 10-15 yrs ago
other repos are more lax
Remember: perfect is the enemy of good. So unless you're going to write a patch for tools.deps.alpha, what we have is "good enough" for a lot of people I suspect 🙂
I am happy to get about two standard deviations of "good"
Pretty sure you’re incorrect about that @U064X3EF3 - here’s an example POM published today that does not contain any license information: https://repo1.maven.org/maven2/com/amazonaws/aws-java-sdk-core/1.12.122/aws-java-sdk-core-1.12.122.pom
if there is another hack or two to cover the deps license files cases, at least for the ~5 most common Clojure libs, I'd take that (and want to consider a way to let people say this more deterministically without a pom)
it's in the parent pom
https://repo1.maven.org/maven2/com/amazonaws/aws-java-sdk-pom/1.12.122/aws-java-sdk-pom-1.12.122.pom
Not that it’s complete (at all), but https://github.com/pmonks/tools-licenses at least attempts to look for license texts inside deps (both Maven and git coord).
I'll get those too
It uses a similar strategy to the one you and @seancorfield were discussing above (simple text matching the header of the license), which SPDX does not recommend.
% clj -X:deps list :extra '{:deps {com.amazonaws/aws-java-sdk-core {:mvn/version "1.12.122"}}}'
com.amazonaws/aws-java-sdk-core 1.12.122 (Apache-2.0)
com.fasterxml.jackson.core/jackson-annotations 2.12.3 (Apache-2.0)
com.fasterxml.jackson.core/jackson-core 2.12.3 (Apache-2.0)
com.fasterxml.jackson.core/jackson-databind 2.12.3 (Apache-2.0)
com.fasterxml.jackson.dataformat/jackson-dataformat-cbor 2.12.3 (Apache-2.0)
commons-codec/commons-codec 1.15 (Apache-2.0)
commons-logging/commons-logging 1.2 (Apache-2.0)
joda-time/joda-time 2.8.1 (Apache 2)
org.apache.httpcomponents/httpclient 4.5.13 (Apache-2.0)
org.apache.httpcomponents/httpcore 4.4.13 (Apache-2.0)
org.clojure/clojure 1.10.3 (EPL-1.0)
org.clojure/core.specs.alpha 0.2.56 (EPL-1.0)
org.clojure/spec.alpha 0.2.194 (EPL-1.0)
software.amazon.ion/ion-java 1.0.2 (The Apache License, Version 2.0)
^^ works just fine on the one you mentioned
https://central.sonatype.org/publish/requirements/#license-information
they have rules that check this ^^
Another example (from 2018): https://repo1.maven.org/maven2/javax/mail/javax.mail-api/1.6.2/javax.mail-api-1.6.2.pom
(and yes, I realise there is license text in an XML comment at the top)
again ,parent poms have the license info
% clj -X:deps list :extra '{:deps {javax.mail/javax.mail-api {:mvn/version "1.6.2"}}}'
javax.mail/javax.mail-api 1.6.2 (CDDL/GPLv2+CE)
org.clojure/clojure 1.10.3 (EPL-1.0)
org.clojure/core.specs.alpha 0.2.56 (EPL-1.0)
org.clojure/spec.alpha 0.2.194 (EPL-1.0)
no license text matching stuff is needed imo for Maven artifacts, it's there for 99.9% of things without that
Right, which leaves other Maven repos (Clojars in particular), and git coords.
Clojars seems to be relatively high even without a requirement, so not worried about that either
mostly trying to look at local/git deps projects
but I'd rather solve this by creating a well-known place to list the equivalent to the pom fields
For that you’d likely have to rely on LICENSE
or COPYING
files.
Which is why https://github.com/pmonks/tools-pom exists…
Though because it can take its input from anywhere, it’s not helpful for determining licenses.
(also because tools.build task names are not standardised, so there’s no “API” for a license determination task to invoke to generate a POM and then parse that)
sure there is :)
tools.deps and tools.build can both generate and parse poms :)
Sure, but only incomplete ones.
I don't understand what we're even talking about now. to the problem hand, I can just define a well known attribute in the deps.edn to pull this from
There’s no way (as of about a month ago, when I last looked into this in some detail) to tell tools.deps / tools.build about “extra” pom.xml elements that I want included in the poms it generates*. *short of checking in an incomplete “template” pom.xml in my repo, which creates other problems for downstream tooling
you can give it a base pom and sync into it
Which messes with downstream tooling that now thinks my project is buildable with Maven.
and eventually I'll get around to making something broader there
you can call it something that's not pom.xml
How many steps am I away from solving my business problem now? 😉
well like I said, none of this has anything to do with the problem I'm trying to solve
I just wanted to make sure my project isn’t violating my organisation’s open source consumption policies, and now I’m creating thisisnotapom.xml
files and learning how to tell my build tooling to consume it. 😉
That’s the thing though - these two areas are intertwined (for better or worse - I’m not advocating on behalf of how Maven pom.xml and repositories work - I’m simply stating how they work).
well I don't know what you're doing, this has nothing to do with providing a license name for a deps.edn project
Sure it does - as you yourself said, putting license information in a pom.xml file makes that use case easy. How do I do that with tools.deps / tools.build?
put it in the deps.edn file, and give it to tools.build from there?
Oh yeah - I don’t. Since that’s not readily supported yet (without checking in pom.xml fragments in my repo).
“Those who cannot remember the past are condemned to repeat it.” ¯\(ツ)/¯
"Which messes with downstream tooling that now thinks my project is buildable with Maven." -- that's just not true. The source file for tools.build
to generate pom.xml
from does not need to be called pom.xml
nor does it need to be in the root of the project.
(I do this in some of my projects -- which is why I jumped on your comment as blatantly false @deactivateduser10790)
Yet that’s the default?
Others here have commented on this in the past, and I don’t have much interest in parroting their (well-founded, IMO) arguments in this regard.
And yet you do.
Not at all. I jumped into this thread to share my experience with license detection, both as someone who had responsibility for it professionally (at an open source Foundation), and as someone who recently scratched an itch because this didn’t previously exist in the tools.build ecosystem.
If you’re not interested in learning from experience, just say so. There’s no need for you or @U064X3EF3 to be dicks about it.
@deactivateduser10790 As frustrated as you might be by the conversation, please avoid ad hominem rhetoric. We don’t talk about other people like that in the Clojure community. https://clojure.org/community/etiquette
Very nice! Just ran it on our code base and it starts with
bidi/bidi 2.1.6 (MIT)
camel-snake-kebab/camel-snake-kebab 0.4.2 (EPL)
cfml-interop/cfml-interop 0.3.0 (EPL)
cheshire/cheshire 5.10.0 (MIT)
clj-antlr/clj-antlr 0.2.5 (EPL)
clj-commons/fs 1.6.309 (Eclipse Public License - v 1.0)
clj-stacktrace/clj-stacktrace 0.2.8 (MIT)
clj-tuple/clj-tuple 0.2.2 (MIT)
clojure-csv/clojure-csv 2.0.2
clojure.java-time/clojure.java-time 0.3.3 (MIT)
clout/clout 2.2.1 (EPL)
com.adobe.xmp/xmpcore 6.1.11 (The BSD 3-Clause License (BSD3))
com.braintreepayments.gateway/braintree-java 2.104.0 (MIT license)
com.cognitect/anomalies 0.1.12 (Apache-2.0)
com.cognitect/http-client 0.1.106 (Apache-2.0)
com.cognitect.aws/api 0.8.524 (Apache-2.0)
com.cognitect.aws/endpoints 1.1.12.69 (Apache-2.0)
com.cognitect.aws/s3 814.2.991.0 (Apache-2.0)
com.corundumstudio.socketio/netty-socketio 1.7.17 (Apache v2)
com.drewnoakes/metadata-extractor 2.16.0 (Apache-2.0)
com.fasterxml.jackson.core/jackson-annotations 2.8.11 (Apache-2.0)
...
(I have no idea where that Adobe dependency is coming from 😆 )
how do you identify licenses? And do you preserve copyright notices when using :full
?
"all" published maven deps have a license section so I'm taking from there. :full gives you whatever the project lists (this is license, not copyright) whereas :short is a canonicalized shortened form, trying to use https://spdx.org/licenses/ ids
the "shortener" is literally text matching but I seeded it based on real data (and if not found, just falls back to full)
so it's super dumb, but works about 95% of the time
I'm seeing some very strange behavior in my current system. I'm setting up tools build to be used, and as a part of it I'm using the merge-edns
function from tools deps. I have the latest version of tools deps and tools build on the classpath, but this function is not accessible. The only accessible functions are combine-aliases
, lib-location
, make-classpath
, print-tree
, and resolve-deps
. Is this some strange behavior where a very old version of tools deps is being loaded first on the classpath and as a result the version I have at the root of my deps tree is being overriden?
sounds like it
I do see that a different alias put a different version of tools deps as a root dependency. What's the way that the cli chooses which to use?
usually it will take the newest but hard to say without more detail
well I had 0.8.695 in an alias that came first on the comamndline and version 0.12.1084 on an alias that came later.
so I'm guessing that older version is what got loaded, after changing it everything loads fine
But I was expecting the latest to be used, not a first-one-wins
well, without specifics, hard for me to say more
What more information would be helpful? I unfortunately can't just share the project as it's proprietary.
I could build a minimal repro deps edn though
;; In deps.edn
{:aliases {:dev {:extra-deps {org.clojure/tools.deps.alpha {:mvn/version "0.8.695"}}}
:build {:deps {org.clojure/tools.deps.alpha {:mvn/version "0.12.1084"}}}}}
$ clj -A:dev:build
Clojure 1.10.3
user=> (require '[clojure.tools.deps.alpha :as t])
nil
user=> t/merge-edns
Syntax error compiling at (REPL:0:0).
No such var: t/merge-edns
This is a minimal reproduction case
looking at it I expect it might have something to do with the build alias using :deps while the dev alias uses :extra-deps
but this is more or less intended because normally the build alias will be invoked with -T, but in this case it's added with -A for a devtime repl with access to both the development code and also the build script.
aliases will merge in order for identical deps like that, so this is the expected behavior
so clj -A:build:dev
would presumably have worked
Okay, cool. Good to know this is expected behavior.
Thanks for the help!
High-level question: is it possible to create a custom name and refer to it elsewhere? E.g.
{:custom-name <some-long-path>
{:aliases {:a {:extra-deps [:custom-name,....]}
:b { blah-blah :custom-name etc..}}}}
Intent is to avoid duplicating a long path b/w different aliases.
Or even to refer to another alias within an alias?
Thx for any comment...
this is already what aliases are for. in some cases aliases can be used as a reference to data, but I'm not sure where it is supported...
OK thx @borkdue. I just found a doc segment addressing that. If I understand correctly I can refer to anything inside the aliases section, and then use it from anywhere…however I want to refer to an alias from within the aliases section.
…and since custom names are declared (only?) in the aliases section it seems non-trivial as a deps.edn newbie..
lots of things are non-trivial to implement, but not non-trivial in the sense of added complexity in the long run :)
some people (including me) have a deps.edn-generation-from-templates approach for some projects.
https://ask.clojure.org/index.php/10564/specify-an-alias-that-is-a-set-of-other-aliases?show=10564#q10564 That does not exist but you can upvote this feature request on http://ask.clojure.org
Indeed, I can see why now. I would have thought this a great selling feature for deps.edn. @borkdude, maybe you should work your magic to generate a parser which inserts custom declarations 🙂
this is pretty trivial to do using e.g. a script that uses selmer and then spits out the real deps.edn. usually you want to preserve whitespace. selmer is included in babashka so you could write a script using that and hook it up to a git hook or so
for a tool that uses rewrite-clj / rewrite-edn you can check this as an example: https://github.com/babashka/neil
Will look at both. I just though of another approach, dont’ know if it’s possible as is: merging aliases? E.g.
clj -A:a:b:c
{:aliases {:a {:extra-deps {}} :b {:extra-deps {}}
clj -A:a:b
gives you a REPL with both the deps from a and bFantastic - thank you! So one can write mergeable aliases without resorting to custom names this way.
yes - it wasn't even obvious to me that this is something you didn't know yet - sorry for that :)
I always wanted to learn deps.edn and cli tools, but keep getting lost in the weeds and forget/re-learn every time.
@kingcode Here's how I start my REPL (as an example of merging aliases):
SOCKET_REPL_PORT=5000 clojure -J-Dlog4j2.configurationFile=log4j2-sean.properties -M:rebel:classes:reflect:jedi-time:portal:everything:dev:test:runner:build:dev/repl
(`:dev` and :test
come from the Polylith portion of our project, :everything
and :runner
are the equivalents for the non-Polylith "legacy" portion, :build
is so I can work on our build.clj
script in the REPL, the rest come from my user ~/.clojure/deps.edn
file which is up on GH)
Thx @seancorfield, nice example. Do you need to worry about a profile over-riding another during the merge?
often you rely on later things shadowing earlier. and nested values have different ways of being merged with an appropriate accumulator. ie, extra deps don’t clobber, they aggregate
Yeah, the rules are pretty straightforward, once you know them 🙂
I still see a need for being able to refer to other aliases, as some tools require specific aliases and won’t allow the user to pick several of them at once. So having a single alias referring to a bunch of others (unless one is ready to copy reams of path data across aliases) would be handy in this one use case.
@kingcode can you give an example of such tools? I think such tools should allow a seqable of aliases
Yes indeed - I am currently following setup instructions to make CIDER work with shadow-cljs. I haven’t gone through the flow yet, but Cider expects :cider-clj and :cider-cljs aliases, and I currently have a :dev alias with :extra-deps, :extra-paths inside it. So I will need to copy/merge whatever is in :dev alias within :cider-clj/s.
What I would like to do is declare :dev-base-extra-deps, :dev-base-extra-paths aliases, and inside e.g. :cider-clj, have {:extra-deps [:dev-base-extra-deps, <local extra deps>]}
If custom names were allowed outside of :aliases this woud be trivial, as shown in the https://clojure.org/reference/deps_and_cli#_paths
ok thx…sorry to take your time - will try that. In previous attempts CIDER would only give single choices.
cider doesn’t expect any aliases. it constructs its own with its required dependencies and adds them in
Those tools read deps.edn
and resolve aliases themselves.
We do this at work -- treating aliases as data -- so we can have a generic build.clj
script in our Polylith monorepo and it can build any of the projects within it.
Example in thread...
(doseq [p projects]
(println "\nRunning: uber on" p)
(let [project-dir (str (System/getProperty "user.dir") "/projects/" p)
aliases (with-dir (io/file project-dir) (get-project-aliases))]
(binding [b/*project-root* project-dir]
(bb/clean {})
(bb/uber (assoc (:uberjar aliases)
:compile-opts {:direct-linking true}))
(bb/clean {}))))
pulls the :uberjar
alias out of each project's deps.edn
file.and that alias is just data that specifies the :main
namespace so compile-clj
and uber
know what to do in tools.build
:uberjar
{:uber-file "../../../build/uberjars/api-1.0.0.jar"
:main api.main}
That's the alias from projects/api/deps.edn
so the generic build can compile api.main
and declare it as the Main-Class
in the uberjar and it knows where to create the uberjar file.(defn- get-project-aliases []
(let [edn-fn (juxt :root-edn :project-edn)]
(-> (t/find-edn-maps)
(edn-fn)
(t/merge-edns)
:aliases)))
t
is tools.deps.alpha
, b
is tools.build
, bb
is build-clj
.
And with-dir
comes from t.d.a in another ns.
LMK if you have further Qs.
No, that's from our Polylith monorepo at work.
But I think Polylith itself has a similar build.clj
if I recall correctly from the PR I sent them...
It has generic jar
and uberjar
tasks that read alias data from the projects/*/deps.edn
files.
I modeled the PR on how we do it at work.
I suspect that may be one of the most "powerful" build.clj
scripts out there in OSS land?
I think shadow just reads the aliases from the config file and then calls clojure -Spath -A:alias1:alias2
to get the classpath and then continues its course
I looked into the source. It constructs a command line call to invoke a Clojure main program with the aliases in place.
@deactivateduser10790 As frustrated as you might be by the conversation, please avoid ad hominem rhetoric. We don’t talk about other people like that in the Clojure community. https://clojure.org/community/etiquette