Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using a private ClojureScript build is unreasonably difficult #475

Open
cemerick opened this issue Sep 6, 2017 · 5 comments
Open

Using a private ClojureScript build is unreasonably difficult #475

cemerick opened this issue Sep 6, 2017 · 5 comments

Comments

@cemerick
Copy link
Collaborator

cemerick commented Sep 6, 2017

(…and it's at least partly my fault! :-|)

The typical way to use a private/fork build of a library in leiningen is to:

  1. Put the artifact on e.g. clojars, under your own coordinates. For me, using a custom CLJS build for a time (waiting for a patch to be applied), that'd be [org.clojars.cemerick/clojurescript "whatever"].
  2. Replace the authoritative artifact's coordinates with those of the forked artifact.
  3. Add the authoritative groupId/artifactId to the global :exclusions in project.clj.

This does not work for ClojureScript when using lein-cljsbuild, because the latter adds a org.clojure/clojurescript dependency if it doesn't find one in :dependencies (via the cljsbuild subproject). This puts two revs of CLJS on the classpath (the default dep being quite old at this point), thus guaranteeing a bad time. (Whether Leiningen should be applying the top-level exclusions to the subproject's dependencies before actually launching the new process is a worthwhile question I'll be investigating separately.)

The only way to use a forked build of CLJS right now is to set up your own maven repository, to which you can deploy/host your private artifact using the org.clojure/clojurescript coordinates. (An example is here.) The top-level clojurescript dep then overrides cljsbuild's as always, it just happens to not be an authoritative build. This is a PITA.

A couple ways forward:

  1. If Leiningen's behaviour w.r.t. :exclusions not being applied to subproject dependencies is a bug, then we'll just wait for that to be fixed.
  2. If that behaviour is notabug, then we need to pick up the top-level :exclusions and explicitly add them to the cljsbuild dep that's mixed into the subproject.
  3. If for some reason (2) doesn't work, then maybe cljsbuild shouldn't have a default CLJS dependency. Doing this was on my list back in the day, but that automatic dependency was very useful when CLJS "releases" were less well understood, harder to track, and so on. Things are much different now, and I don't know that the default dependency is doing anyone any favors (i.e. how many CLJS beginners are using a years-old build of the compiler?).

This is just a placeholder for now. I'll return when I understand the :exclusions situation.

@cemerick
Copy link
Collaborator Author

cemerick commented Sep 6, 2017

Global exclusions are applied only once, when the project is initialized: https://github.com/technomancy/leiningen/blob/afd3dee22aecf3e853409931e0557cad6be35ada/leiningen-core/src/leiningen/core/project.clj#L887

This means option (2) above is the most direct solution.

@mneise
Copy link
Collaborator

mneise commented Sep 28, 2017

Thank you for the detailed report!

Regarding (2), just to clarify, we would only take the exclusions that have been specified for the cljsbuild plugin in the initial project.clj file. Or were you picturing something else?

For example, given the following project.clj

(defproject none "0.1.0-SNAPSHOT"
  :description "FIXME: write this!"
  :url "http://example.com/FIXME"
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :plugins [[lein-cljsbuild "1.1.8-SNAPSHOT"]
             :exclusions [org.clojure/clojurescript]]]
...)

the subproject would contain the following dependency:

{:dependencies [[org.clojure/clojure "1.8.0"]
                [lein-cljsbuild "1.1.8-SNAPSHOT"]
                  :exclusions [org.clojure/clojurescript]]]
...}

Regarding (3), I completely agree. People should define their own cljs version instead of relying on the one supplied through cljsbuild.

@cemerick
Copy link
Collaborator Author

cemerick commented Oct 2, 2017

:exclusions can't appear where you show them above; they're either a project top-level entry, or hung off of individual :dependencies entries. What I was thinking was simply carrying over all of the top-level exclusions from the user's project, and adding them to the cljsbuild dependency in the subproject.

But, if you're on board with dropping all of the automatic cljs dependency injection stuff altogether (i.e. option 3), then let's do that 😁

@mfikes
Copy link
Contributor

mfikes commented Jul 8, 2019

A variant of this issue: If you want to depend on ClojureScript as a Git Dep (by, for example, making use of lein-tools-deps), then the ClojureScript gitlib tree is simply added to—and is available on—the classpath. In this scenario, you effectively run into the same issue where the automatically injected ClojureScript dependency causes a "bad time."

@Bost
Copy link

Bost commented Jul 2, 2020

  • Put the artifact on e.g. clojars, under your own coordinates. For me, using a custom CLJS build for a time (waiting for a patch to be applied), that'd be [org.clojars.cemerick/clojurescript "whatever"].

That's exactly my situation. I think I'll try to fork the lein-cljsbuild and put in the coordinates of my own clojurescript fork and then I'll use the forked lein-cljsbuild... or have you found any better solution meanwhile? Thanks in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants