Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ rules_clojure_setup()

Differs from [simuons/rules_clojure](https://github.com/simuons/rules_clojure) that it uses `java_library` and `java_binary` as much as possible.

`clojure_binary`, `clojure_repl` and `clojure_test` are all macros that delegate to `java_binary`. `clojure_library` is new code.
`clojure_binary`, and `clojure_test` are macros that delegate to `java_binary`. `clojure_library` is new code.

For fast compilation, `clojure_library` is a Bazel persistent worker.

Expand Down Expand Up @@ -70,10 +70,14 @@ Note that AOT will determine whether a library should appear in `deps` or `runti
```
clojure_repl(
name = "foo_repl",
deps = [":foo"])
main_class = "clojure.main",
main_args = ["-e", "foo.main"],
runtime_deps = [":foo", "@deps//:__all"],
classpath_dirs = ["src", "dev", "test"],
data = [])
```

Behaves as you'd expect. Delegates to `java_binary` with `main_class clojure.main`.
Like `java_binary`, the repl process runs from the bazel-bin package directory. Unlike the built-in java rules, it supports `classpath_dirs`, which allows adding directories to the classpath, like a conventional clojure repl.

### clojure_test

Expand Down
28 changes: 14 additions & 14 deletions rules.bzl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("//rules:jar.bzl", _clojure_jar_impl = "clojure_jar_impl")
load("//rules:repl.bzl", _clojure_repl_impl = "clojure_repl_impl")

clojure_library = rule(
doc = "Define a clojure library",
Expand Down Expand Up @@ -30,20 +31,19 @@ def clojure_binary(name, **kwargs):
runtime_deps = deps + runtime_deps,
**kwargs)

def clojure_repl(name, deps=[], ns=None, **kwargs):
args = []

if ns:
args.extend(["-e", """\"(require '[{ns}]) (in-ns '{ns})\"""".format(ns = ns)])

args.extend(["-e", "(clojure.main/repl)"])

native.java_binary(name=name,
runtime_deps=deps,
jvm_flags=["-Dclojure.main.report=stderr"],
main_class = "clojure.main",
args = args,
**kwargs)
clojure_repl = rule(
doc = "Define a clojure repl",
attrs = {
"main_class": attr.string(),
"runtime_deps": attr.label_list(default = [], providers = [[JavaInfo]]),
"classpath_dirs": attr.label_list(default = [], allow_files = True),
"data": attr.label_list(default = [], allow_files = True),
"jvm_flags": attr.string_list(default=[], doc = "Optional jvm_flags to pass to the repl binary"),
},
executable = True,
provides = [],
toolchains = ["@bazel_tools//tools/jdk:toolchain_type"],
implementation = _clojure_repl_impl)

def clojure_test(name, *, test_ns, deps=[], runtime_deps=[], **kwargs):
# ideally the library name and the bin name would be the same. They can't be.
Expand Down
36 changes: 36 additions & 0 deletions rules/repl.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
### rule to start a clojure repl. We don't use `java_binary` because
### we want to support adding directories to the classpath (and in the
### future, possibly running from the source tree rather than `bazel-bin`), both in support of
### `clj` live reloading semantics

def clojure_repl_impl(ctx):

java_deps = depset(transitive = [d[JavaInfo].transitive_runtime_jars for d in ctx.attr.runtime_deps])

classpath_files = ["$BUILD_WORKSPACE_DIRECTORY/%s" % d.short_path for d in ctx.files.classpath_dirs]

jars = [d.short_path for d in java_deps.to_list()]

## It's important that the dirs go ahead of jars, or live reloading breaks
classpath = classpath_files + jars
classpath_str = ":".join(classpath)

sh_file = ctx.actions.declare_file(ctx.attr.name)

runfiles = ctx.runfiles(files = ctx.files.data,
transitive_files = java_deps)
runfiles.merge_all([d[DefaultInfo].default_runfiles for d in ctx.attr.runtime_deps])

default_info = DefaultInfo(executable=sh_file,
runfiles = runfiles)

cmd = """java {jvm_flags} -cp {cp} {main_class} {args}""".format(cp=classpath_str,
main_class = ctx.attr.main_class,
args = " ".join(ctx.attr.args),
jvm_flags = " ".join(ctx.attr.jvm_flags))

ctx.actions.write(output=sh_file,
content=cmd,
is_executable=True)

return [ default_info ]
6 changes: 3 additions & 3 deletions src/rules_clojure/gen_build.clj
Original file line number Diff line number Diff line change
Expand Up @@ -868,10 +868,10 @@
(cond-> m
(seq (:deps m)) (update :deps (comp vec distinct))
(:deps m) (update :deps (comp vec distinct))))))))))))))))))
[(emit-bazel (list 'clojure_library (kwargs
[(emit-bazel (list 'java_library (kwargs
{:name "__all"
:deps (->> jar->lib
(mapv (comp library->label val)))})))]))
:runtime_deps (->> jar->lib
(mapv (comp library->label val)))})))]))

:encoding "UTF-8"))

Expand Down