cursive-ide / cursive

Cursive: The IDE for beautiful Clojure code
588 stars 7 forks source link

Add basic support for boot #692

Open jeluard opened 9 years ago

jeluard commented 9 years ago

I started using boot exclusively (i.e. without any project.clj) for some new project. I find the combo boot + cursive extremely powerful especially for ClojureScript projects. Unfortunately cursive won't recognize my sources/dependencies in this case.

Given the simple structure of a build.boot file it could be easy to support boot only project as a first step.

A simple build.boot

(set-env!
 :source-paths #{"src"}
 :dependencies '[[org.clojure/clojure "1.6.0"     :scope "provided"]
                 [boot/core           "2.0.0-rc1" :scope "provided"]
                 [some/dep            "0.1.0"]])
aadrian commented 9 years ago

Boot looks really interesting, but considering however how many open issues Cursive still has, maybe some sort of user based extensions (plug-ins for the Cursive plug-in) would allow the many frameworks (some that come and go) to have some support in Clojure directly from the framework authors?

cursive-ide commented 9 years ago

I'm actually very interested in boot, and will probably be adding support for it soon, not least because I want to use it for the Cursive build. Until I do, there are some workarounds that have been discussed here in issues and on the mailing list. The easiest way to handle this right now is to have a project.clj just to trick Cursive into adding support. See #665 for a way to get Cursive to add source folders, and there's a gist here: https://gist.github.com/bsima/88969126962803a6500f which describes how to have boot read the dependencies from the project.clj, which Cursive will also sync. People are also using the External Tools functionality to call boot tasks. I think the only way to get a decent REPL right now would be to run boot's REPL in headless mode (if it allows that) and then connect from Cursive with a remote REPL config.

An extension API for all this would be lovely and is definitely planned, but it's a significant amount of work. Additionally API support for things like build tooling is not top of the priority list - things like symbol resolution are much higher.

caskolkm commented 9 years ago

Any process on this issue?

cursive-ide commented 9 years ago

No, I'm afraid not - I've been busy with other things.

danielcompton commented 9 years ago

Theres an updated Boot wiki page on this https://github.com/boot-clj/boot/wiki/For-Cursive-Users

peterromfeldhk commented 8 years ago

+1 for adding support (the hacks with keeping project.clj and build.boot same doesnt look very nice to work with, though thanks for the temporary workaround)

onetom commented 8 years ago

+5 in the name of our team :)

dimitertodorov commented 8 years ago

+1 From I !!

bonega commented 8 years ago

+2

ghost commented 8 years ago

Any news on this? This would be pretty neat for our team.

vikeri commented 8 years ago

Also still interested in this. At least properly parsing build.boot would be nice.

redinger commented 8 years ago

+1, using build.boot instead of requiring the "generate lein project file" workaround would be great.

onetom commented 8 years ago

Until there is progress on this issue, let me recommend a workaround which I'm using successfully lately and I find it more convenient than using the lein-generate boot task: https://github.com/andrewmed/boot-maven-interop

Here comes my slightly reformatted version:

; To inform IntelliJ explicitely about deftask, set-env!, task-options!
(require '[boot.core :refer :all]
  '[boot.task.built-in :refer :all])

(require 'clojure.xml)

(defn build-edn [x]
  (let [[groupdId] (:groupId x)
        [artifactId] (:artifactId x)
        [version] (:version x)]
    (vector (symbol (str groupdId "/" artifactId))
      (str version))))

(defn convert [result x]
  (let [val (:content x) key (:tag x)] (assoc result key val)))

(defn build-deps [col]
  (map (partial reduce convert {}) col))

(defn get-deps [x]
  (when-let [tag (:tag x)] (if (= tag :dependencies) (:content x))))

(defn maven-import
  "Makes a vector of maps of deps from a local pom.xml file" []
  (when-let [rdr (java.io.File. "pom.xml")]
    (->> rdr
      clojure.xml/parse
      :content
      (mapcat get-deps)
      (map :content)
      build-deps
      (map build-edn)
      vec)))

(set-env!
  :dependencies (maven-import)
  :source-paths #{"src"}
  :asset-paths #{"assets"})

It starts with some boot.* requires to help IntelliJ with symbol resolution, but I also have to ln -s ../build.boot src/build.boot to make it visible under the source route and edit that symlink. If you can use the latest 1.4.0-eap Cursive, then you can even tell it to interpret deftask as defs (by pressing opt-enter on any deftask word), so you can even jump to the definitions of tasks. Read more on it on the Cursive mailing list: https://cursive-ide.com/archive/2129.html

I just copy this snippet to every new project's build.boot as a start.

Editing the pom.xml might feel disgusting at first but

  1. you can use tab to auto-complete the xml tag names (dep)
  2. it can auto-complete groupId, artifactId and version too (can use ctrl-space later to lookup newer versions)

To make auto-completion work you have to add clojars to your pom.xml manually just below the <project> tag:

    <repositories>
        <repository>
            <id>clojars.org</id>
            <name>Clojars</name>
            <url>https://clojars.org/repo</url>
        </repository>
    </repositories>

After this it should appear in the list on the Preferences / Build, Execution, Deployment / Build Tools / Maven / Repositories dialog.

If you press the Update button on the right for each repo, then IntelliJ will download the package list for them. Auto-completion works from these package indexes.

vikeri commented 8 years ago

@onetom: Great work! I did not go all the way into working with the pom.xml-file. But I tried creating a symlink from my build.boot-file into the src folder. But it did not work, boot threw me an error saying Too many levels of symbolic links and in Cursive it still said build.boot is not under a source root. Did I miss something?

onetom commented 8 years ago

@vikeri sounds like your link is incorrectly pointing onto itself. it should look like this from within the src directory:

src> ls -l build.boot
lrwxr-xr-x  1 pair  staff  13 Jul 13 06:21 build.boot -> ../build.boot
vikeri commented 8 years ago

@onetom Thanks for the help. I had incorrectly created the symlink. But to get it to find boot without editing the pom.xml I had to modify the :dependency-key in generate-lein.project-file! to add boot/core:

:dependencies (conj
                  (get-env :dependencies)
                  ['boot/core "2.6.0" :scope "compile"])

The only thing still yellow now is the symbols in the input argument vector to the boot task 🎉

vikeri commented 8 years ago

Updated the lein-generate wiki page in boot as well: https://github.com/boot-clj/boot/wiki/For-Cursive-Users

onetom commented 8 years ago

Prepared an example repo with revised pom.xml import functionality which supports dependency :exclusions: https://github.com/addplus/maven-cursive-boot-template

onetom commented 8 years ago

I gave up on using the IntelliJ Maven support because it's just inconvenient to transform the XML representation of Maven repo specs and dependency exclusions into EDN.

Instead I've enhanced https://github.com/darongmean/boot-lein-generate a little bit and published it under https://clojars.org/onetom/boot-lein-generate

You can see an example build.boot which uses it in the https://github.com/onetom/hoplon-layouts The order of expressions in build.boot matter a lot so be careful when you are trying to roll your own.

  1. Use the symlinked src/build.boot to edit build.boot so you can enjoy symbol resolution
  2. (require '[boot.core :refer :all] ...) at the very top
  3. (task-options! pom {:project ... :version ...}) just so you can easily tell the different build.boot files apart from each other by always just looking at the very top of them (instead of being in the middle, after the variable length dependency list...) boot.lein/generate needs this info.
  4. (set-env! :dependencies ...) because boot.lein/generate needs this info too
  5. (require 'boot.lein) (boot.lein/generate) to create a project.clj
  6. boot repl to actually create the project.clj for the 1st time
  7. Now you can load/create the IntelliJ project. If you would try to load/create earlier, Cursive would complain about the missing project.clj...
cursive-ide commented 8 years ago

@onetom Thanks so much for investigating and documenting all this!

chillenious commented 7 years ago

+1

marco-m commented 7 years ago

Hello any news ?

ags799 commented 7 years ago

I've attempted to automate @onetom's fabulous comment in my bootlaces project. It's hosted on Clojars, and the documentation is meant to be self-sufficient. Feel free to use it and submit issues (and maybe PRs 😛 ).

Maurice-Fingher commented 3 years ago

Hi, I just saw that there is a plugin for IntelliJ-based tool, like Cursive, that seems to allow using boot. Its name is Clojure-Kit (https://github.com/gregsh/Clojure-Kit).

Has anybody tried it? Would it be possible to use it along with Cursive and, if yes, how?