clojurephant

Quick Start

Create a new Clojure library:

clj -A:new clojurephant-clj-lib myname/mylib

Create a new Clojure application:

clj -A:new clojurephant-clj-app myname/myapp

Create a new ClojureScript appliation:

clj -A:new clojurephant-cljs-app myname/myapp

If the documentation doesn’t answer your questions, please visit either the ClojureVerse gradle-clojure channel or the Clojurian’s Slack #gradle channel.

Plugins

clojurephant uses the common pattern of providing capability plugins and convention plugins. Capability plugins provide the basic machinery for using the language, but leaves it to you to configure. Convention plugins provide configuration on top of the capabilities to support common use cases.

Convention Capability
dev.clojurephant.clojure dev.clojurephant.clojure-base
dev.clojurephant.clojurescript dev.clojurephant.clojurescript-base

dev.clojurephant.clojure-base

Tip: gradlew tasks --all shows all these created tasks. Beware: The main build is somewhat special and its name is not included in the task names so it has e.g. compileClojure.

Clojure Builds

You can define a custom build:

clojure {
 builds {
   // Defaults noted here are for custom builds, the convention plugin configures the builds it adds differently
   mybuild {
     sourceSet = sourceSets.mystuff // no default
     // Configuration of the check<Build>Clojure task
     reflection = 'fail' // defaults to 'silent', can also be 'warn'
     checkNamespaces = ['my.core', 'my.base'] // defaults to no namespaces checked
     checkNamespaces.add('my-core') // just add a single namespace
     checkAll() // checks any namespaces found in the source set
     // Configuration of the compile<Build>Clojure task
     compiler {
       disableLocalsClearing = true // defaults to false
       elideMeta = ['doc', 'file'] // defaults to empty list
       directLinking = true // defaults to false
     }
     aotNamespaces = ['my.core', 'my.base'] // defaults to no namespaces aoted
     aotNamespaces.add('my-core') // just add a single namespace
     aotAll() // aots any namespaces found in the source set
   }
 }
}

You can also modify the configuration of the auto-added builds, f.ex. the “main” one:

clojure {
    builds {
      main {
        reflection = 'warn'
      }
    }
}

dev.clojurephant.clojure

dev.clojurephant.clojurescript-base

ClojureScript Builds

NOTE: While Figwheel options are available when clojurescript-base is applied, the necessary dependencies and middleware are not configured unless you apply clojurescript.

See ClojureScript compiler options and Figwheel Main configuration options for details on what each option does and defaults to.

clojurescript {
 builds {
   // Defaults noted here are for custom builds, the convention plugin configures the builds it adds differently
   mybuild {
     sourceSet = sourceSets.mystuff // no default
     // Configuration of the compile<Build>ClojureScript task (defaults match what is defaulted in the ClojureScript compile options)
     compiler {
       outputTo = 'public/some/file/path.js' // path is relative to the task's destinationDir
       outputDir = 'public/some/path' // path is relative to the task's destinationDir
       optimizations = 'advanced'
       main = 'foo.bar'
       assetPath = 'public/some/path'
       sourceMap = 'public/some/file/path.js.map' // path is relative to the task's destinationDir
       verbose = true
       prettyPrint = false
       target = 'nodejs'
       // foreignLibs
       externs = ['jquery-externs.js']
       // modules
       // stableNames
       preloads = ['foo.dev']
       npmDeps = ['lodash': '4.17.4']
       installDeps = true
       checkedArrays = 'warn'
     }
     figwheel {
       watchDirs.from = files() // defaults to the source set's CLJS source dirs
       cssDirs.from = files('src/main/resources/public/css') // defaults to empty
       ringHandler = 'my-project.server/handler'
       ringServerOptions = [port: 1234, host: 'my.domain.com']
       rebelReadline = false
       pprintConfig = true
       openFileCommand = 'myfile-opener'
       figwheelCore = false
       hotReloadCljs = false
       connectUrl = 'ws://[[config-hostname]]:[[server-port]]/figwheel-connect'
       openUrl = 'http://[[server-hostname]]:[[server-port]]'
       reloadCljFiles = false
       logFile = file('figwheel-main.log')
       logLevel = 'error'
       clientLogLevel = 'warning'
       logSyntaxErrorStyle = 'concise'
       loadWarningedCode = true
       ansiColorOutput = false
       validateConfig = false
       launchNode = false
       inspectNode = false
       nodeCommand = 'node'
       cljsDevtools = false
     }
   }
 }
}

dev.clojurephant.clojurescript

Project Layout

<project>/
  src/
    main/
      clojure/
        sample_clojure/
          core.clj
      clojurescript/
        sample_clojure/
          main.cljs
    test/
      clojure/
        sample_clojure/
          core_test.clj
      clojurescript/
        sample_clojure/
          main_test.cljs // right now we don't support cljs.test
    dev/
      clojure/
        user.clj
      clojurescript/
        user.cljs
  gradle/
    wrapper/
      gradle-wrapper.jar
      gradle-wrapper.properties
  build.gradle
  gradlew
  gradlew.bat

Task Configuration

ClojureNRepl

clojureRepl {
  port = 55555 // defaults to a random open port (which will be printed in the build output)

  // handler and middleware are both optional, but don't provide both
  handler = 'cider.nrepl/cider-nrepl-handler' // fully-qualified name of function
  middleware = ['my.stuff/wrap-stuff'] // list of fully-qualified middleware function names (override any existing)
  middleware 'dev/my-middleware', 'dev/my-other-middleware' // one or more full-qualified middleware function names (append to any existing)

  // clojureRepl provides fork options to customize the Java process for compilation
  forkOptions {
    memoryMaximumSize = '2048m'
    jvmArgs = ['-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005', '-Djava.awt.headless=true']
  }
}

The ClojureNRepl task also supports command-line options for some of it’s parameters. Multiple middleware must be specified as separate options.

./gradlew clojureRepl --port=1234 --handler=cider.nrepl/cider-nrepl-handler
./gradlew clojureRepl --port=4321 --middleware=dev/my-middleware --middleware=dev/my-other-middleware

check or compile tasks

Always configure compiler options and reflection settings via the clojure or clojurescript extensions. These options may be immutable on the tasks at some point in the future.

The only settings you should configure directly on the tasks are the forkOptions, if you need to customize the JVM that is used.

checkClojure {
  // to customize the Java process for compilation
  forkOptions {
    memoryMaximumSize = '2048m'
    jvmArgs = ['-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005', '-Djava.awt.headless=true']
  }
}