diff --git a/README.md b/README.md index 2e4f944c4..ecdb89f07 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Key changes: * Replace the macros with three basic rules. `kt_jvm_binary`, `kt_jvm_library` and `kt_jvm_test`. * Android rules. `kt_android_library` and `kt_android_binary` -* Friend support for tests (supports access to `internal` types and functions) +* Friend support for tests and other use-cases (supports access to `internal` types and functions) * Use a single `deps` attribute instead of `java_dep` and `dep`. * Add support for the following standard java rules attributes: * `data` @@ -137,6 +137,43 @@ KOTLINC_RELEASE = { kotlin_repositories(compiler_release = KOTLINC_RELEASE) ``` +## Friends/Internal support + +The rules support kotlin `internal` visibility (usually accessible only to the compilation unit) +by allowing a library or test to specify that it is friends with another library like so: + +``` +kt_jvm_library( + name = "foo", + srcs = glob(["*.kt"]), + friend = "//some/other:target", + # ... +) +``` + +> Note: declaring friends of a kt_android_library requires adding _kt to the target, e.g. +> `//some/other:target_kt`. This is because the kt_android_library rule is a macro with a +> `kt_jvm_library` under the hood, and the surfaced rule is an android_rule which doesn't have +> kotlin providers. This will be fixed in the future. + +This grants access to `internal` members of `//some/other:target`. A library can only be friends +with one other library, which must be a kotlin-aware target. It inherits the module name from that +library. Only one friend can be declared, because of the assumptions made here about module +membership. Since friendship can be transitive (see below), this constrains the visibility so it +does not become an arbitrarily growing lattice of trust, defeating the purpose. + +Very common use-cases for this are: + + * tests and test-libraries depending on internals of the system under test. + * clusters of targets that represent one logical unit, with public, private, + fake, testing-utilities, configuration, or other targets that comprise the + whole unit. + +Friendship has limited transitivity. Consider projects `C`, `B`, and `A` with a dependency +relationship `C->B->A`. If `C` declares friendship in `B`, and `B` declares friendship with `A`, +then they are all treated as logically one module for `internal` purposes. However it doesn't +skip. Once the line of friendship is broken, a separate module is presumed by kotlinc. + # Bazel Kotlin Rules compatibility Which version of *rules_kotlin* can you use with which version of Bazel (best