Skip to content

Commit

Permalink
Begin Bazel 8 / rules_java 8 compatibility updates
Browse files Browse the repository at this point in the history
Moves functions out of `//scala:scala.bzl` and updates `WORKSPACE` to
load `//scala:toolchains.bzl` to avoid importing macros that depend on
`JavaInfo` and `java_common` during `WORKSPACE` evaluation. Based on
advice from @hvadehra in bazelbuild#1652.

I haven't tried this under Bzlmod yet, and it still fails with the
following error. This is due to bumping to Protobuf v29.0 and
protobuf-java:4.29.0, and I believe I can update
`ExtraProtobufGenerator.scala` to fix this. But the point is that I do
_not_ have to `load()` files from `@rules_java` after all.

```txt
ERROR: .../external/com_google_protobuf/src/google/protobuf/BUILD.bazel:23:14:
  ProtoScalaPBRule external/com_google_protobuf/src/google/protobuf/any_proto_jvm_extra_protobuf_generator_scalapb.srcjar
  failed: (Exit 1): scalapb_worker failed:
  error executing ProtoScalaPBRule command
  (from target @@com_google_protobuf//src/google/protobuf:any_proto)
  bazel-out/.../bin/src/scala/scripts/scalapb_worker
    ... (remaining 2 arguments skipped)

--jvm_extra_protobuf_generator_out:
  java.lang.NoSuchMethodError:
  'java.lang.Object com.google.protobuf.DescriptorProtos$FieldOptions.getExtension(com.google.protobuf.GeneratedMessage$GeneratedExtension)'
    at scalapb.compiler.DescriptorImplicits$ExtendedFieldDescriptor.fieldOptions(DescriptorImplicits.scala:329)
    at scalapb.compiler.DescriptorImplicits$ExtendedFieldDescriptor.scalaName(DescriptorImplicits.scala:207)
    at scalapb.compiler.ProtoValidation.validateField(ProtoValidation.scala:121)
    at scalapb.compiler.ProtoValidation.$anonfun$validateMessage$3(ProtoValidation.scala:56)
    at scalapb.compiler.ProtoValidation.$anonfun$validateMessage$3$adapted(ProtoValidation.scala:56)
    at scala.collection.Iterator.foreach(Iterator.scala:943)
    at scala.collection.Iterator.foreach$(Iterator.scala:943)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1431)
    at scala.collection.IterableLike.foreach(IterableLike.scala:74)
    at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
    at scalapb.compiler.ProtoValidation.validateMessage(ProtoValidation.scala:56)
    at scalapb.compiler.ProtoValidation.$anonfun$validateFile$2(ProtoValidation.scala:17)
    at scalapb.compiler.ProtoValidation.$anonfun$validateFile$2$adapted(ProtoValidation.scala:17)
    at scala.collection.Iterator.foreach(Iterator.scala:943)
    at scala.collection.Iterator.foreach$(Iterator.scala:943)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1431)
    at scala.collection.IterableLike.foreach(IterableLike.scala:74)
    at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
    at scalapb.compiler.ProtoValidation.validateFile(ProtoValidation.scala:17)
    at scalapb.compiler.ProtoValidation.$anonfun$validateFiles$1(ProtoValidation.scala:10)
    at scalapb.compiler.ProtoValidation.$anonfun$validateFiles$1$adapted(ProtoValidation.scala:10)
    at scala.collection.immutable.Stream.foreach(Stream.scala:533)
    at scalapb.compiler.ProtoValidation.validateFiles(ProtoValidation.scala:10)
    at scalarules.test.extra_protobuf_generator.ExtraProtobufGenerator$.handleCodeGeneratorRequest(ExtraProtobufGenerator.scala:86)
    at scalarules.test.extra_protobuf_generator.ExtraProtobufGenerator$.run(ExtraProtobufGenerator.scala:55)
    at protocbridge.frontend.PluginFrontend$.$anonfun$runWithBytes$1(PluginFrontend.scala:51)
    at scala.util.Try$.apply(Try.scala:213)
    at protocbridge.frontend.PluginFrontend$.runWithBytes(PluginFrontend.scala:51)
    at protocbridge.frontend.PluginFrontend$.runWithInputStream(PluginFrontend.scala:121)
    at protocbridge.frontend.PosixPluginFrontend$.$anonfun$prepare$2(PosixPluginFrontend.scala:40)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
    at scala.concurrent.impl.ExecutionContextImpl$DefaultThreadFactory$$anon$1$$anon$2.block(ExecutionContextImpl.scala:75)
    at java.base/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3118)
    at scala.concurrent.impl.ExecutionContextImpl$DefaultThreadFactory$$anon$1.blockOn(ExecutionContextImpl.scala:87)
    at scala.concurrent.package$.blocking(package.scala:146)
    at protocbridge.frontend.PosixPluginFrontend$.$anonfun$prepare$1(PosixPluginFrontend.scala:38)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
    at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:659)
    at scala.util.Success.$anonfun$map$1(Try.scala:255)
    at scala.util.Success.map(Try.scala:213)
    at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
    at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:42)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:74)
    at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

java.lang.RuntimeException: Exit with code 1
    at scala.sys.package$.error(package.scala:30)
    at scripts.ScalaPBWorker$.work(ScalaPBWorker.scala:44)
    at io.bazel.rulesscala.worker.Worker.persistentWorkerMain(Worker.java:96)
    at io.bazel.rulesscala.worker.Worker.workerMain(Worker.java:49)
    at scripts.ScalaPBWorker$.main(ScalaPBWorker.scala:39)
    at scripts.ScalaPBWorker.main(ScalaPBWorker.scala)

ERROR: .../external/com_google_protobuf/src/google/protobuf/BUILD.bazel:23:14
  Building source jar external/com_google_protobuf/src/google/protobuf/any_proto_scalapb-src.jar
  failed: (Exit 1): scalapb_worker failed:
  error executing ProtoScalaPBRule command
  (from target @@com_google_protobuf//src/google/protobuf:any_proto)
  bazel-out/darwin_arm64-opt-exec-ST-a828a81199fe/bin/src/scala/scripts/scalapb_worker
    ... (remaining 2 arguments skipped)
```
  • Loading branch information
mbland committed Nov 29, 2024
1 parent aa18181 commit cdfec73
Show file tree
Hide file tree
Showing 46 changed files with 422 additions and 428 deletions.
2 changes: 1 addition & 1 deletion .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ build:windows --worker_quit_after_build --enable_runfiles

# Remove upon completing Bzlmod compatibility work.
# - https://github.com/bazelbuild/rules_scala/issues/1482
build --noenable_bzlmod
build --noenable_bzlmod --enable_workspace
2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
37 changes: 16 additions & 21 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
workspace(name = "io_bazel_rules_scala")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//scala:deps.bzl", "load_rules_dependencies")

http_archive(
name = "bazel_skylib",
sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
],
)
load_rules_dependencies()

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")

bazel_skylib_workspace()

load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies")

rules_java_dependencies()

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()

http_archive(
name = "rules_python",
sha256 = "ca77768989a7f311186a29747e3e95c936a41dffac779aff6b443db22290d913",
strip_prefix = "rules_python-0.36.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.36.0/rules_python-0.36.0.tar.gz",
sha256 = "690e0141724abb568267e003c7b6d9a54925df40c275a870a4d934161dc9dd53",
strip_prefix = "rules_python-0.40.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.40.0/rules_python-0.40.0.tar.gz",
)

load("@rules_python//python:repositories.bzl", "py_repositories")
Expand All @@ -39,7 +42,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config(enable_compiler_dependency_tracking = True)

load("//scala:scala.bzl", "scala_toolchains")
load("//scala:toolchains.bzl", "scala_toolchains")

scala_toolchains(
fetch_sources = True,
Expand All @@ -64,14 +67,6 @@ load("@rules_proto//proto:setup.bzl", "rules_proto_setup")

rules_proto_setup()

load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")

rules_proto_toolchains()

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()

# needed for the cross repo proto test
local_repository(
name = "proto_cross_repo_boundary",
Expand Down
2 changes: 1 addition & 1 deletion dt_patches/test_dt_patches/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion dt_patches/test_dt_patches/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config(enable_compiler_dependency_tracking = True)

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")
load(
"@io_bazel_rules_scala//scala:scala_cross_version.bzl",
"default_maven_server_urls",
Expand Down
2 changes: 1 addition & 1 deletion dt_patches/test_dt_patches_user_srcjar/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion dt_patches/test_dt_patches_user_srcjar/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config(enable_compiler_dependency_tracking = True)

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")
load(
"@io_bazel_rules_scala//scala:scala_cross_version.bzl",
"default_maven_server_urls",
Expand Down
2 changes: 1 addition & 1 deletion examples/crossbuild/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion examples/crossbuild/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ scala_config(
],
)

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")

scala_toolchains(scalatest = True)

Expand Down
2 changes: 1 addition & 1 deletion examples/scala3/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion examples/scala3/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config(scala_version = "3.5.2")

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")

scala_toolchains(fetch_sources = True)

Expand Down
2 changes: 1 addition & 1 deletion examples/semanticdb/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion examples/semanticdb/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config(scala_version = "2.13.15")

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")

scala_toolchains(fetch_sources = True)

Expand Down
2 changes: 1 addition & 1 deletion examples/testing/multi_frameworks_toolchain/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion examples/testing/multi_frameworks_toolchain/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config()

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")

scala_toolchains(
fetch_sources = True,
Expand Down
2 changes: 1 addition & 1 deletion examples/testing/scalatest_repositories/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion examples/testing/scalatest_repositories/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config()

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")

scala_toolchains(
fetch_sources = True,
Expand Down
2 changes: 1 addition & 1 deletion examples/testing/specs2_junit_repositories/.bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.5.0
8.0.0rc6
2 changes: 1 addition & 1 deletion examples/testing/specs2_junit_repositories/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config()

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_toolchains")
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_toolchains")

scala_toolchains(
fetch_sources = True,
Expand Down
28 changes: 0 additions & 28 deletions jmh/jmh.bzl
Original file line number Diff line number Diff line change
@@ -1,33 +1,5 @@
load("//scala/private:rules/scala_binary.bzl", "scala_binary")
load("//scala/private:rules/scala_library.bzl", "scala_library")
load(
"//scala:scala_cross_version.bzl",
"default_maven_server_urls",
)
load("//third_party/repositories:repositories.bzl", "repositories")
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_VERSION")

def jmh_artifact_ids():
return [
"io_bazel_rules_scala_org_openjdk_jmh_jmh_core",
"io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_asm",
"io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_reflection",
"io_bazel_rules_scala_org_ow2_asm_asm",
"io_bazel_rules_scala_net_sf_jopt_simple_jopt_simple",
"io_bazel_rules_scala_org_apache_commons_commons_math3",
]

def jmh_repositories(
maven_servers = default_maven_server_urls(),
overriden_artifacts = {}):
repositories(
scala_version = SCALA_VERSION,
for_artifact_ids = jmh_artifact_ids(),
fetch_sources = False,
maven_servers = maven_servers,
overriden_artifacts = overriden_artifacts,
)
native.register_toolchains("@io_bazel_rules_scala_toolchains//jmh:all")

def _scala_generate_benchmark(ctx):
# we use required providers to ensure JavaInfo exists
Expand Down
38 changes: 33 additions & 5 deletions jmh/toolchain/toolchain.bzl
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
load("//scala/private/toolchain_deps:toolchain_deps.bzl", "expose_toolchain_deps")
load("//scala:providers.bzl", "declare_deps_provider", _DepsInfo = "DepsInfo")
load("//scala:scala_cross_version.bzl", "repositories")
load(
"//scala:scala_cross_version.bzl",
"default_maven_server_urls",
_versioned_repositories = "repositories",
)
load("//third_party/repositories:repositories.bzl", "repositories")
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_VERSION")


DEP_PROVIDERS = [
"jmh_classpath",
"jmh_core",
"benchmark_generator",
"benchmark_generator_runtime",
]

def jmh_artifact_ids():
return [
"io_bazel_rules_scala_org_openjdk_jmh_jmh_core",
"io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_asm",
"io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_reflection",
"io_bazel_rules_scala_org_ow2_asm_asm",
"io_bazel_rules_scala_net_sf_jopt_simple_jopt_simple",
"io_bazel_rules_scala_org_apache_commons_commons_math3",
]

def jmh_repositories(
maven_servers = default_maven_server_urls(),
overriden_artifacts = {}):
repositories(
scala_version = SCALA_VERSION,
for_artifact_ids = jmh_artifact_ids(),
fetch_sources = False,
maven_servers = maven_servers,
overriden_artifacts = overriden_artifacts,
)
native.register_toolchains("@io_bazel_rules_scala_toolchains//jmh:all")

def _jmh_toolchain_impl(ctx):
toolchain = platform_common.ToolchainInfo(
dep_providers = ctx.attr.dep_providers,
Expand Down Expand Up @@ -60,7 +88,7 @@ def setup_jmh_toolchain(name):
name = "jmh_core_provider",
deps_id = "jmh_core",
visibility = ["//visibility:public"],
deps = repositories(SCALA_VERSION, [
deps = _versioned_repositories(SCALA_VERSION, [
"@io_bazel_rules_scala_org_openjdk_jmh_jmh_core",
]),
)
Expand All @@ -69,7 +97,7 @@ def setup_jmh_toolchain(name):
name = "jmh_classpath_provider",
deps_id = "jmh_classpath",
visibility = ["//visibility:public"],
deps = repositories(SCALA_VERSION, [
deps = _versioned_repositories(SCALA_VERSION, [
"@io_bazel_rules_scala_net_sf_jopt_simple_jopt_simple",
"@io_bazel_rules_scala_org_apache_commons_commons_math3",
]),
Expand All @@ -81,7 +109,7 @@ def setup_jmh_toolchain(name):
visibility = ["//visibility:public"],
deps = [
"@io_bazel_rules_scala//src/java/io/bazel/rulesscala/jar",
] + repositories(SCALA_VERSION, [
] + _versioned_repositories(SCALA_VERSION, [
"@io_bazel_rules_scala_org_openjdk_jmh_jmh_core",
"@io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_asm",
"@io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_reflection",
Expand All @@ -92,7 +120,7 @@ def setup_jmh_toolchain(name):
name = "benchmark_generator_runtime_provider",
deps_id = "benchmark_generator_runtime",
visibility = ["//visibility:public"],
deps = repositories(SCALA_VERSION, [
deps = _versioned_repositories(SCALA_VERSION, [
"@io_bazel_rules_scala_org_openjdk_jmh_jmh_generator_asm",
]),
)
54 changes: 54 additions & 0 deletions scala/deps.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

def load_rules_dependencies():
if not native.existing_rule("bazel_skylib"):
http_archive(
name = "bazel_skylib",
sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
],
)

if not native.existing_rule("rules_cc"):
http_archive(
name = "rules_cc",
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.1.0/rules_cc-0.1.0.tar.gz"],
sha256 = "4b12149a041ddfb8306a8fd0e904e39d673552ce82e4296e96fac9cbf0780e59",
strip_prefix = "rules_cc-0.1.0",
)

if not native.existing_rule("com_google_absl"):
http_archive(
name = "com_google_absl",
sha256 = "f50e5ac311a81382da7fa75b97310e4b9006474f9560ac46f54a9967f07d4ae3",
strip_prefix = "abseil-cpp-20240722.0",
url = "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240722.0.tar.gz",
)

if not native.existing_rule("rules_java"):
http_archive(
name = "rules_java",
urls = [
"https://github.com/bazelbuild/rules_java/releases/download/8.5.1/rules_java-8.5.1.tar.gz",
],
sha256 = "1389206b2208c5f33a05dd96e51715b0855c480c082b7bb4889a8e07fcff536c",
)

if not native.existing_rule("com_google_protobuf"):
http_archive(
name = "com_google_protobuf",
sha256 = "10a0d58f39a1a909e95e00e8ba0b5b1dc64d02997f741151953a2b3659f6e78c",
strip_prefix = "protobuf-29.0",
url = "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v29.0.tar.gz",
)

if not native.existing_rule("rules_proto"):
http_archive(
name = "rules_proto",
sha256 = "0e5c64a2599a6e26c6a03d6162242d231ecc0de219534c38cb4402171def21e8",
strip_prefix = "rules_proto-7.0.2",
url = "https://github.com/bazelbuild/rules_proto/releases/download/7.0.2/rules_proto-7.0.2.tar.gz",
)

Loading

0 comments on commit cdfec73

Please sign in to comment.