Skip to content

Commit ae097aa

Browse files
authored
Merge pull request #68 from griffinbank/clojure_repl_rule
add `classpath_dirs` to `clojure_repl`
2 parents 13d7646 + 1239e07 commit ae097aa

File tree

4 files changed

+60
-20
lines changed

4 files changed

+60
-20
lines changed

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ rules_clojure_setup()
3535

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

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

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

@@ -70,10 +70,14 @@ Note that AOT will determine whether a library should appear in `deps` or `runti
7070
```
7171
clojure_repl(
7272
name = "foo_repl",
73-
deps = [":foo"])
73+
main_class = "clojure.main",
74+
main_args = ["-e", "foo.main"],
75+
runtime_deps = [":foo", "@deps//:__all"],
76+
classpath_dirs = ["src", "dev", "test"],
77+
data = [])
7478
```
7579

76-
Behaves as you'd expect. Delegates to `java_binary` with `main_class clojure.main`.
80+
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.
7781

7882
### clojure_test
7983

rules.bzl

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("//rules:jar.bzl", _clojure_jar_impl = "clojure_jar_impl")
2+
load("//rules:repl.bzl", _clojure_repl_impl = "clojure_repl_impl")
23

34
clojure_library = rule(
45
doc = "Define a clojure library",
@@ -30,20 +31,19 @@ def clojure_binary(name, **kwargs):
3031
runtime_deps = deps + runtime_deps,
3132
**kwargs)
3233

33-
def clojure_repl(name, deps=[], ns=None, **kwargs):
34-
args = []
35-
36-
if ns:
37-
args.extend(["-e", """\"(require '[{ns}]) (in-ns '{ns})\"""".format(ns = ns)])
38-
39-
args.extend(["-e", "(clojure.main/repl)"])
40-
41-
native.java_binary(name=name,
42-
runtime_deps=deps,
43-
jvm_flags=["-Dclojure.main.report=stderr"],
44-
main_class = "clojure.main",
45-
args = args,
46-
**kwargs)
34+
clojure_repl = rule(
35+
doc = "Define a clojure repl",
36+
attrs = {
37+
"main_class": attr.string(),
38+
"runtime_deps": attr.label_list(default = [], providers = [[JavaInfo]]),
39+
"classpath_dirs": attr.label_list(default = [], allow_files = True),
40+
"data": attr.label_list(default = [], allow_files = True),
41+
"jvm_flags": attr.string_list(default=[], doc = "Optional jvm_flags to pass to the repl binary"),
42+
},
43+
executable = True,
44+
provides = [],
45+
toolchains = ["@bazel_tools//tools/jdk:toolchain_type"],
46+
implementation = _clojure_repl_impl)
4747

4848
def clojure_test(name, *, test_ns, deps=[], runtime_deps=[], **kwargs):
4949
# ideally the library name and the bin name would be the same. They can't be.

rules/repl.bzl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
### rule to start a clojure repl. We don't use `java_binary` because
2+
### we want to support adding directories to the classpath (and in the
3+
### future, possibly running from the source tree rather than `bazel-bin`), both in support of
4+
### `clj` live reloading semantics
5+
6+
def clojure_repl_impl(ctx):
7+
8+
java_deps = depset(transitive = [d[JavaInfo].transitive_runtime_jars for d in ctx.attr.runtime_deps])
9+
10+
classpath_files = ["$BUILD_WORKSPACE_DIRECTORY/%s" % d.short_path for d in ctx.files.classpath_dirs]
11+
12+
jars = [d.short_path for d in java_deps.to_list()]
13+
14+
## It's important that the dirs go ahead of jars, or live reloading breaks
15+
classpath = classpath_files + jars
16+
classpath_str = ":".join(classpath)
17+
18+
sh_file = ctx.actions.declare_file(ctx.attr.name)
19+
20+
runfiles = ctx.runfiles(files = ctx.files.data,
21+
transitive_files = java_deps)
22+
runfiles.merge_all([d[DefaultInfo].default_runfiles for d in ctx.attr.runtime_deps])
23+
24+
default_info = DefaultInfo(executable=sh_file,
25+
runfiles = runfiles)
26+
27+
cmd = """java {jvm_flags} -cp {cp} {main_class} {args}""".format(cp=classpath_str,
28+
main_class = ctx.attr.main_class,
29+
args = " ".join(ctx.attr.args),
30+
jvm_flags = " ".join(ctx.attr.jvm_flags))
31+
32+
ctx.actions.write(output=sh_file,
33+
content=cmd,
34+
is_executable=True)
35+
36+
return [ default_info ]

src/rules_clojure/gen_build.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -868,10 +868,10 @@
868868
(cond-> m
869869
(seq (:deps m)) (update :deps (comp vec distinct))
870870
(:deps m) (update :deps (comp vec distinct))))))))))))))))))
871-
[(emit-bazel (list 'clojure_library (kwargs
871+
[(emit-bazel (list 'java_library (kwargs
872872
{:name "__all"
873-
:deps (->> jar->lib
874-
(mapv (comp library->label val)))})))]))
873+
:runtime_deps (->> jar->lib
874+
(mapv (comp library->label val)))})))]))
875875

876876
:encoding "UTF-8"))
877877

0 commit comments

Comments
 (0)