replikativ / hasch

Cross-platform (JVM and JS atm.) edn data structure hashing for Clojure.
Eclipse Public License 1.0
111 stars 13 forks source link

Dependencies shouldn't bring in clojurescript #1

Closed lbradstreet closed 7 years ago

lbradstreet commented 7 years ago

My feeling is that hasch shouldn't bring in clojurescript by default, and it should be part of the dev dependencies. This will avoid clojure users having it as part of their dependencies, and clojurescript users have it as a dependency anyway.

Thanks!

jcf commented 7 years ago

Perhaps the dependency on Clojurescript could be moved to the :provided profile.

The :provided profile is used to specify dependencies that should be available during jar creation, but not propagated to other code that depends on your project. These are dependencies that the project assumes will be provided by whatever environment the jar is used in, but are needed during the development of the project. This is often used for frameworks like Hadoop that provide their own copies of certain libraries.

https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#default-profiles

whilo commented 7 years ago

I have had dependency problems with maven resolution lately, too. (This was mostly because I tried to use some AOT compilation, which hard wires all dependencies from each project and does not allow maven to use a different classpath (somewhat late binding)). But maven dependency resolution in general is a too unpredictable imo.

While using :provided or :dev profiles to factor out dependencies is very reasonable, it does not fix the underlying problem, as is also pointed out here: https://github.com/cemerick/piggieback/issues/70 The problem is that every codebase is developped and tested against a specific version of Clojure and ClojureScript and currently it is at least visible that way. If we move the Clojure(Script) dependency out of the main project, then leiningen (and maven) cannot tell you anymore that you have conflicts, e.g. with lein deps :tree.

On the other hand if you have to manually :exclude dependencies from a jar, it is clear that you take responsibility in providing a proper version (or no version, because you don't need that portion of the codebase.) Atm. I don't see a way of excluding the ClojureScript dependency automatically if you don't need it without also hiding the version the code depends on when you do. Is :exclude reasonable for you or do you know a better way? I am not an expert in leiningen/maven.

jcf commented 7 years ago

@whilo when I've wanted to test support for explicit Clojure(script) versions in the past, I've used profiles. Then I can run tests against a specific version of Clojure with something like lein with-profile default,+1.9 test.

Pandect is one library I know uses this approach. Ring does too.

The problem is that every codebase is developped and tested against a specific version of Clojure and ClojureScript and currently it is at least visible that way. If we move the Clojure(Script) dependency out of the main project, then leiningen (and maven) cannot tell you anymore that you have conflicts, e.g. with lein deps :tree.

I'd list the supported versions of Clojure(script) in the project documentation and avoid, for example, pulling browser-based dependencies/REPL tooling into people's backend applications.

I'm not sure people use lein deps :tree to work out if a library like Hasch works with Clojure 1.9. In fact, you can't encode the versions of Clojure(script) you're compatible with using lein deps :tree because you can only depend on one single version of each, and more than likely Hasch will work with more than one version of Clojure and Clojurescript.

Funnily enough, Rich Hickey has just done a talk on dependencies, Maven, and things like SemVer called Spec-ulation that may be worth a watch - I certainly found it thought provoking.

whilo commented 7 years ago

@jcf Thanks, the talk is fairly spot-on. What he describes is actually monotonic deployment and aligns nicely with replikativ (CRDTs). Using spec to break-down SemVer is also very reasonable, I already hate version dumps just to propagate changes. If you like to you can go ahead and adjust the project.clj file as you would like to have it and open a pull-request. Otherwise I would move to profiles and a provided scope similar to Pandect as soon as possible and I will also gradually introduce specs now that most libs work with 1.9.

jcf commented 7 years ago

@whilo I might get some time this evening to open a PR. Watch this space.

whilo commented 7 years ago

I have integrated the changes and minimized the incognito dependencies. Feel free to reopen or open further issues, if you need something :).

jcf commented 7 years ago

Awesome! Thank you @whilo.

whilo commented 7 years ago

Just as a quick note, I have now adapted the incognito deps, which is better imo. This should not affect anybody though.