├── .gitignore
├── LICENSE
├── README.md
├── rules
├── BUILD
├── WORKSPACE
├── def.bzl
├── private
│ ├── BUILD
│ ├── fswatch_and_install_intellij_files_mac.sh.template
│ ├── install_intellij_files.py.template
│ ├── intellij_module.bzl
│ ├── intellij_project.bzl
│ ├── pysrc
│ │ └── rules_intellij_generate.py
│ └── pytest
│ │ └── rules_intellij_generate_test.py
└── tools
│ └── bazel.rc
├── rules_intellij_generate.iml
└── scenarios
├── .bazelversion
├── 01_one_class
├── BUILD
├── README.txt
└── src
│ └── oneclass
│ └── A.java
├── 02_one_class_and_one_test
├── BUILD
├── README.txt
├── src
│ └── one_class_and_one_test
│ │ └── B.java
└── test
│ └── one_class_and_one_test
│ └── BTest.java
├── 03_basic
├── BUILD
├── README.txt
├── dolphin
│ ├── BUILD
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── basic
│ │ │ └── dolphin
│ │ │ └── Echolocation.java
│ │ └── test
│ │ └── java
│ │ └── basic
│ │ └── dolphin
│ │ └── EcholocationTest.java
├── gorilla
│ ├── BUILD
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── basic
│ │ │ └── gorilla
│ │ │ └── KnuckleWalking.java
│ │ └── test
│ │ └── java
│ │ └── basic
│ │ └── gorilla
│ │ └── KnuckleWalkingTest.java
├── human
│ ├── BUILD
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── basic
│ │ │ └── human
│ │ │ └── OpposableThumbs.java
│ │ └── test
│ │ └── java
│ │ └── basic
│ │ └── human
│ │ └── OpposableThumbsTest.java
├── mammal
│ ├── BUILD
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── basic
│ │ │ └── mammal
│ │ │ └── WarmBlood.java
│ │ └── test
│ │ └── java
│ │ └── basic
│ │ └── mammal
│ │ └── WarmBloodTest.java
└── primate
│ ├── BUILD
│ └── src
│ ├── main
│ └── java
│ │ └── basic
│ │ └── primate
│ │ └── ColorVision.java
│ └── test
│ └── java
│ └── basic
│ └── primate
│ └── ColorVisionTest.java
├── 04_transitive_via_export
├── BUILD
├── README.txt
├── child
│ ├── BUILD
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── transitive_via_export
│ │ │ └── parent
│ │ │ └── Child.java
│ │ └── test
│ │ └── java
│ │ └── transitive_via_export
│ │ └── parent
│ │ └── ChildTest.java
├── grandparent
│ ├── BUILD
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── transitive_via_export
│ │ │ └── grandparent
│ │ │ └── Grandparent.java
│ │ └── test
│ │ └── java
│ │ └── transitive_via_export
│ │ └── grandparent
│ │ └── GrandparentTest.java
└── parent
│ ├── BUILD
│ └── src
│ ├── main
│ └── java
│ │ └── transitive_via_export
│ │ └── parent
│ │ └── Parent.java
│ └── test
│ └── java
│ └── transitive_via_export
│ └── parent
│ └── ParentTest.java
├── 05_annotation_processor
├── BUILD
├── README.txt
├── class_generator
│ ├── BUILD
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── annotation_processor
│ │ │ └── class_generator
│ │ │ ├── ClassGeneratorAnnotationProcessor.java
│ │ │ └── GenClass.java
│ │ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── javax.annotation.processing.Processor
├── text_file_generator
│ ├── BUILD
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── annotation_processor
│ │ │ └── text_file_generator
│ │ │ ├── GenTextFile.java
│ │ │ └── TextFileGeneratorAnnotationProcessor.java
│ │ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── javax.annotation.processing.Processor
└── usage
│ ├── BUILD
│ └── src
│ ├── main
│ └── java
│ │ └── annotation_processor
│ │ └── usage
│ │ └── Usage.java
│ └── test
│ └── java
│ └── annotation_processor
│ └── usage
│ └── UsageTest.java
├── 06_protobuf_messages
├── BUILD
├── README.txt
├── html_email
│ ├── BUILD
│ └── src
│ │ └── main
│ │ └── proto
│ │ └── html_email.proto
├── plain_email
│ ├── BUILD
│ └── src
│ │ └── main
│ │ └── proto
│ │ └── plain_email.proto
└── usage
│ ├── BUILD
│ └── src
│ ├── main
│ └── java
│ │ └── protobuf_messages
│ │ └── usage
│ │ └── Usage.java
│ └── test
│ └── java
│ └── protobuf_messages
│ └── usage
│ └── UsageTest.java
├── 07_grpc
├── BUILD
├── README.txt
└── src
│ ├── main
│ ├── java
│ │ └── fortune_grpc
│ │ │ └── FortuneService.java
│ └── proto
│ │ └── fortune.proto
│ └── test
│ └── java
│ └── fortune_grpc
│ └── FortuneServiceTest.java
├── 08_auto_value
├── BUILD
├── README.txt
└── src
│ ├── main
│ └── java
│ │ └── house
│ │ └── House.java
│ └── test
│ └── java
│ └── house
│ └── HouseTest.java
├── 09_python
├── BUILD
├── README.txt
├── src
│ └── echo.py
└── test
│ └── echo_test.py
├── 12_kotlin
├── BUILD
├── README.txt
├── child
│ ├── BUILD
│ ├── src
│ │ └── kotlin_example
│ │ │ └── child
│ │ │ └── Child.kt
│ └── test
│ │ └── kotlin_example
│ │ └── child
│ │ └── ChildTest.kt
└── parent
│ ├── BUILD
│ ├── src
│ └── kotlin_example
│ │ └── parent
│ │ └── Parent.kt
│ └── test
│ └── kotlin_example
│ └── parent
│ └── ParentTest.kt
├── 13_minor_features
├── BUILD
├── README.txt
├── iml_types.xml
├── intellij_project_files
│ └── misc.xml
├── some_file.txt
├── src
│ └── minor_features
│ │ └── B.java
└── test
│ └── minor_features
│ └── BTest.java
├── 14_all_dependency_types
├── BUILD
├── README.txt
├── child2_custom
│ └── BUILD
├── child_data
│ └── BUILD
├── child_dep
│ └── BUILD
├── child_src
│ ├── BUILD
│ └── child.sh
├── custom2.bzl
├── parent
│ ├── BUILD
│ ├── parent.sh
│ └── parent.txt
└── parent2_custom
│ ├── BUILD
│ └── parent2.sh
├── 15_typescript_rules_multi_tsc
├── BUILD
├── deps
│ ├── package-lock.json
│ └── package.json
├── intellij_project_files
│ ├── inspectionProfiles
│ │ └── Project_Default.xml
│ └── misc.xml
├── long-gen
│ ├── BUILD
│ ├── src
│ │ └── long-gen.ts
│ └── test
│ │ └── long-gen-test.ts
├── package-lock.json
├── package.json
├── print-timestamp
│ ├── BUILD
│ └── src
│ │ └── print-timestamp.ts
├── run_single_mocha_test.sh
├── tsconfig.json
└── workspace_xml_fragments
│ └── workspace.RunManager.fragment.xml
├── BUILD
├── WORKSPACE
├── iml_types.xml
├── intellij_project_files
├── compiler.xml
└── misc.xml
├── scenario_tests
├── BUILD
└── pytest
│ ├── all_tests.py
│ ├── s01_one_class_test.py
│ ├── s02_one_class_and_one_test.py
│ ├── s03_basic_test.py
│ ├── s04_transitive_with_export_test.py
│ ├── s05_annotation_processor_test.py
│ ├── s06_protobuf_messages_test.py
│ ├── s07_grpc_test.py
│ ├── s08_auto_value_test.py
│ ├── s09_python_test.py
│ ├── s12_kotlin_test.py
│ ├── s13_minor_features_test.py
│ ├── s14_all_dependency_types_test.py
│ └── scenario_test_support.py
└── tools
└── bazel.rc
/.gitignore:
--------------------------------------------------------------------------------
1 | bazel-*
2 | out/
3 | .idea/
4 | *.iml
5 | !rules_intellij_generate.iml
6 | .DS_Store
7 | *.pyc
8 | node_modules
9 | workspace.xml
10 | .rig_sha1
11 | .python-version
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rules_intellij_generate
2 |
3 | Alpha: rule definitions and behavior may change on short notice.
4 |
5 | Examines your bazel build and generates a complete set of Intellij project configuration files. This is an alternative
6 | approach vs [bazelbuild/intellij](https://github.com/bazelbuild/intellij), and akin to the old
7 | [pants/idea](https://github.com/pantsbuild/pants/blob/d30cca1e0ecb9cc0e1b7e2cd0ff6e7e077e62a52/src/python/pants/backend/project_info/tasks/idea_gen.py) integration.
8 |
9 | - _`**/*.iml`_: Intellij module files are based on iml templates under your control, to which this rule adds module and
10 | jar dependency entries based on examination of your bazel build target relationships.
11 | - _`.idea/modules.xml`_: Automatically creates the Intellij file used to identify all modules in your project.
12 | - _`.idea/workspace.xml`_: “component” entries you define will be placed in your workspace.xml file.
13 | - _`.idea/**/*.xml`_: Intellij project-level files, such as run configurations and source formatting rules, may be
14 | committed to your repo and will be placed under the .idea directory, meaning these may be easily shared across a team.
15 |
16 | ## Example usage
17 |
18 | This repo is split into the [core rules](rules), and a [series of scenarios](scenarios) meant to show how the rules may be typically
19 | applied, that also form the basis of the [scenario tests](scenarios/scenario_tests/pytest). There is a README in the
20 | root of each scenario with a brief description of its purpose.
21 |
22 | ## Background and Motivation
23 |
24 | bazel/intellij originates from Google’s internal approach to Intellij integration. It’s based on a plug-in that puts
25 | bazel operations at the center of how the IDE does its work.
26 |
27 | Many people use this plugin happily and successfully, but its bazel-first philosophy is not without its problems,
28 | very well-expressed in
29 | [this github issue (recommended reading)](https://github.com/bazelbuild/intellij/issues/179#issuecomment-350295025).
30 | Bazel/intellij maintainers state that exploitation
31 | of Intellij’s module system is a non-goal, whereas for this project it’s a key goal.
32 |
33 | The rules_intellij_generate philosophy sees bazel and Intellij as equal partners interacting at arm’s length. It
34 | willingly countenances small compromises away from “bazel purity” so that (for example) the IDE’s code modularity
35 | features are useful in development. Intellij should work for teams that also use bazel, in the most efficient and
36 | fully-realized manner as possible.
37 |
38 | ## Features
39 |
40 | - Uses bazel project configuration to generate an intellij project during the bazel build run
41 | - Maps bazel packages to Intellij modules
42 | - Maps bazel-specified jar dependencies to Intellij module jar library dependencies
43 | - Integration point is plain old Intellij config files - there’s no Intellij plugin
44 | - Express any Intellij module configuration/settings via an entry in iml-types.xml
45 | ([example](scenarios/iml_types.xml))
46 | - Support for distribution, from files in your workspace, of project-level Intellij xml config
47 | ([example](scenarios/intellij_project_files))
48 | - Reference to bazel build output locations in Intellij configuration possible via template variables
49 |
50 | ## Usage
51 |
52 | Once `intellij_module` targets are defined, and an `intellij_project` target exists, run the `intellij_project`
53 | target: this generates the intellij configuration files archive for your project, in sandboxed form. You will need
54 | to run the `install_intellij_files_script`, found under `bazel-bin`, in order for these files to be installed
55 | in your workspace.
56 |
57 | You may want to try this out using the scenarios. Once installed, any scenario should be loadable into Intellij,
58 | by opening up its directory in the IDE as a new project.
59 |
60 | ## Python
61 |
62 | This project has a dependency on python. For now please make sure you have a python 3 interpreter that's findable
63 | by the core-bazel [default toolchain support for python](https://github.com/bazelbuild/rules_python/blob/master/proposals/2019-02-12-design-for-a-python-toolchain.md#default-toolchain).
64 |
65 | If you are using pyenv, install a modern 3.X interpreter, and make it findable by the bazel/python default
66 | toolchain support using:
67 |
68 | ```
69 | pyenv global 3.7.0
70 | ```
71 |
72 | Where "3.7.0" is the version of your python 3 interpreter.
73 |
--------------------------------------------------------------------------------
/rules/BUILD:
--------------------------------------------------------------------------------
1 | # empty
--------------------------------------------------------------------------------
/rules/WORKSPACE:
--------------------------------------------------------------------------------
1 | workspace(name="rules_intellij_generate")
2 |
3 |
--------------------------------------------------------------------------------
/rules/def.bzl:
--------------------------------------------------------------------------------
1 | load("@rules_intellij_generate//private:intellij_project.bzl", _intellij_project = "intellij_project")
2 | load("@rules_intellij_generate//private:intellij_module.bzl", _intellij_module = "intellij_module")
3 |
4 | intellij_project = _intellij_project
5 | intellij_module = _intellij_module
6 |
--------------------------------------------------------------------------------
/rules/private/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//private:__subpackages__"])
2 |
3 | # === EXPORTS ===
4 |
5 | py_binary(
6 | name = "intellij_generate_project_files",
7 | main = "rules_intellij_generate.py",
8 | srcs = ["pysrc/rules_intellij_generate.py"],
9 | visibility = ["//visibility:public"],
10 | )
11 |
12 | exports_files([
13 | "fswatch_and_install_intellij_files_mac.sh.template",
14 | "install_intellij_files.py.template"
15 | ])
16 |
17 | # === PRIVATE ===
18 |
19 | py_library(
20 | name = "py_lib",
21 | srcs = ["pysrc/rules_intellij_generate.py"],
22 | )
23 |
24 | py_test(
25 | name = "py_test",
26 | srcs = glob(["pytest/**/*.py"]),
27 | main = "rules_intellij_generate_test.py",
28 | imports = ["pysrc"],
29 | deps = [
30 | ":py_lib"
31 | ]
32 | )
33 |
--------------------------------------------------------------------------------
/rules/private/fswatch_and_install_intellij_files_mac.sh.template:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | which fswatch > /dev/null
4 |
5 | if [ $? -ne 0 ]; then
6 | echo "fswatch not found, please install it via homebrew:"
7 | echo " brew install fswatch"
8 | exit 1
9 | fi
10 |
11 | set -e
12 |
13 | this_dir=$(dirname $0)
14 | fswatch -0 --event=OwnerModified "$this_dir/intellij_files" | xargs -0 -n 1 -I {} "$this_dir/install_intellij_files_script"
15 |
16 |
--------------------------------------------------------------------------------
/rules/private/install_intellij_files.py.template:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | """
4 | Read in the intellij file archive, and write out individual intellij config files under the project workspace
5 | """
6 |
7 | import os
8 | import sys
9 | from subprocess import Popen, PIPE
10 |
11 | execution_directory = os.getcwd()
12 | script_directory = os.path.dirname(os.path.realpath(__file__))
13 | workspace_path = os.path.join(execution_directory, "WORKSPACE")
14 | rig_sha1_path = os.path.join(execution_directory, ".rig_sha1")
15 | intellij_files_path = os.path.join(script_directory, "intellij_files")
16 |
17 | def get_subcommand_output(call_arr):
18 | p = Popen(call_arr, stdin=PIPE, stdout=PIPE, stderr=PIPE)
19 | output, err = p.communicate()
20 | if p.returncode != 0:
21 | sys.stderr.write("Subcommand unexpectedly failed: %s" % call_arr)
22 | sys.exit(1)
23 | return output
24 |
25 | def read_file(path):
26 | f = open(path, "r")
27 | content = f.read()
28 | f.close()
29 | return content
30 |
31 | def write_file(path, content):
32 | f = open(path, "w")
33 | f.write(content)
34 | f.close()
35 |
36 | if not os.path.isfile(workspace_path):
37 | sys.stderr.write("This script must be run from the workspace root, please change to that directory and re-run.\n")
38 | sys.exit(1)
39 |
40 | if not os.path.isfile(intellij_files_path):
41 | sys.stderr.write("Archive of intellij files not found at path: '%s'\n" % intellij_files_path)
42 | sys.exit(1)
43 |
44 | custom_substitutions = {
45 | # BEFORE_CUSTOM_VARS
46 | # _CUSTOM_ENV_VARS_GO_HERE
47 | # AFTER_CUSTOM_VARS
48 | }
49 |
50 |
51 | # Execute "bazel info", and transform the variable names in the output into
52 | # BAZEL_INFO_VARIABLE_NAME style.
53 | bazel_info = {}
54 | for line in get_subcommand_output(["_BAZELEXE_", "info"]).splitlines():
55 | parts = map(lambda part: part.strip(), line.split(":", 1))
56 | key = "BAZEL_INFO_" + parts[0].upper().replace("-", "_")
57 | value = parts[1]
58 | bazel_info[key] = value
59 |
60 | general_substitutions = {}
61 | general_substitutions.update(custom_substitutions)
62 | general_substitutions.update(bazel_info)
63 |
64 |
65 | # Determine files to process.
66 | # If no .rig_sha1 file is in place from the previous run, process all files in the archive.
67 | # If there is a .rig_sha1, load its contents, and determine what files have changed from the
68 | # previous run, and only process those different files.
69 | sha_section, rest_of_file = read_file(intellij_files_path).split("__SHA1_DIVIDER__\n", 1)
70 | sha1_lines = set(sha_section.splitlines())
71 |
72 | if os.path.isfile(rig_sha1_path):
73 | print("Will only write intellij files that differ from previous run")
74 | existing_sha1_lines = set(read_file(rig_sha1_path).splitlines())
75 | sha1_lines = existing_sha1_lines.symmetric_difference(sha1_lines)
76 |
77 | files_to_process = sorted(set(map(lambda l: l.split(" ", 1)[0].strip(), sha1_lines)))
78 | if len(files_to_process) > 0:
79 | print("Writing %d intellij files..." % len(files_to_process))
80 | else:
81 | print("No intellij files differ from previous run")
82 |
83 | file_contents_section, symlink_section = rest_of_file.split("__SYMLINK_DIVIDER__\n", 1)
84 |
85 | relative_file_path_to_content = {}
86 | for entry in file_contents_section.split("__FILE_DIVIDER__\n"):
87 | relative_path, content = entry.split("\n", 1)
88 | relative_file_path_to_content[relative_path] = content
89 |
90 | files_to_process = filter(lambda f: f in relative_file_path_to_content.keys(), files_to_process)
91 |
92 | symlinks = {}
93 | symlink_entries = map(lambda line: line.split("|",1), filter(lambda l:len(l)>0, symlink_section.split("\n")))
94 | for symlink_entry in symlink_entries:
95 | symlinks[symlink_entry[0]] = symlink_entry[1]
96 |
97 | dot_idea_dir = os.path.dirname(filter(lambda f: f.endswith(".idea/modules.xml"), relative_file_path_to_content.keys())[0])
98 |
99 | # Check for symlink existence and content, create/overwrite if incorrect
100 | for symlink_src in symlinks:
101 | symlink_dest = symlinks[symlink_src]
102 |
103 | for k in general_substitutions:
104 | symlink_src = symlink_src.replace("${%s}" % k, general_substitutions[k])
105 | symlink_dest = symlink_dest.replace("${%s}" % k, general_substitutions[k])
106 |
107 | if os.path.islink(symlink_dest) and os.readlink(symlink_dest) == symlink_src:
108 | continue
109 |
110 | if (os.path.islink(symlink_dest) or os.path.isfile(symlink_dest)) and os.readlink(symlink_dest) != symlink_src:
111 | os.remove(symlink_dest)
112 |
113 | os.symlink(symlink_src, symlink_dest)
114 |
115 | # Split the workspace.xml file into one workspace file per "component" in the file.
116 | # This will create files like .idea/workspace.RunManager.xml
117 | intellij_workspace_xml_path = os.path.join(dot_idea_dir, "workspace.xml")
118 | if os.path.isfile(intellij_workspace_xml_path):
119 | workspace_fragment_to_content = {}
120 | current_fragment_name = None
121 | current_content = ""
122 | for line in read_file(intellij_workspace_xml_path).splitlines():
123 | if "" in line:
124 | current_fragment_name = None
125 | current_content = ""
126 | continue
127 |
128 | if "" in line:
135 | workspace_fragment_to_content[current_fragment_name] = current_content
136 | current_fragment_name = None
137 | current_content = ""
138 |
139 | if len(current_content) > 0:
140 | workspace_fragment_to_content[current_fragment_name] = current_content
141 |
142 | for workspace_fragment in workspace_fragment_to_content:
143 | write_file(
144 | os.path.join(dot_idea_dir, "workspace.%s.fragment.xml" % workspace_fragment),
145 | workspace_fragment_to_content[workspace_fragment])
146 |
147 |
148 | # Write out files to their repective relative paths under the bazel workspace.
149 | # Of note:
150 | # - .iml files will be placed in their bazel package-originating directories,
151 | # i.e. alongside the BUILD file
152 | # - other files are written under .idea, such as .idea/workspace.xml, .idea/modules.xml, etc
153 | # - template variables are replaced here. for example,
154 | # ${BAZEL_INFO_EXECUTION_ROOT}
155 | # would be replace with the "execution root" value found by running "bazel info".
156 | # This is how, for example, jars that bazel places in its output directories are available
157 | # within intellij config files.
158 | for relative_path in files_to_process:
159 | relative_dir = os.path.dirname(relative_path)
160 |
161 | all_substitutions = {}
162 | all_substitutions.update(general_substitutions)
163 | all_substitutions["BAZEL_PACKAGE_GENFILES"] = \
164 | "%s/%s" % (general_substitutions["BAZEL_INFO_BAZEL_GENFILES"], relative_dir)
165 |
166 | file_content = relative_file_path_to_content[relative_path]
167 | for k in all_substitutions:
168 | file_content = file_content.replace("${%s}" % k, all_substitutions[k])
169 |
170 | print("Writing intellij file '%s' (%d bytes)" % (relative_path, len(file_content)))
171 |
172 | if not os.path.isdir(relative_dir) and len(relative_dir) > 0:
173 | os.makedirs(relative_dir)
174 |
175 | write_file(relative_path, file_content)
176 |
177 |
178 | # In the previous step, workspace.xml fragment files may have been written out as well.
179 | # This would have over-written workspace xml fragments already extracted.
180 | # Re-compose workspace.xml by gluing together the contents of the fragment files.
181 | workspace_xml_fragments = []
182 | for path in os.listdir(dot_idea_dir):
183 | if path.startswith("workspace.") and path.endswith(".fragment.xml"):
184 | workspace_xml_fragments.append(read_file(os.path.join(dot_idea_dir, path)))
185 | intellij_workspace_xml_content = \
186 | "\n".join([
187 | "",
188 | ""] +
189 | workspace_xml_fragments +
190 | [""])
191 |
192 | print("Writing intellij workspace file '%s' (%d bytes)" % (intellij_workspace_xml_path, len(intellij_workspace_xml_content)))
193 | write_file(intellij_workspace_xml_path, intellij_workspace_xml_content)
194 |
195 | # Finally, "remember" the digests of the files from this archive, in .rig_sha1
196 | print("Saving intellij file sha1's in '%s'" % rig_sha1_path)
197 | write_file(rig_sha1_path, sha_section)
198 |
--------------------------------------------------------------------------------
/rules/private/intellij_module.bzl:
--------------------------------------------------------------------------------
1 | IntellijModuleConfig = provider(
2 | fields = {
3 | "iml_type": "the type of iml file to use, defined in the iml_types xml file",
4 | "module_name_override": "optional string that overrides the default module name"
5 | }
6 | )
7 |
8 | def _impl(ctx):
9 | return [IntellijModuleConfig(
10 | iml_type=ctx.attr.iml_type,
11 | module_name_override=ctx.attr.module_name_override)]
12 |
13 | intellij_module = rule(
14 | implementation = _impl,
15 | attrs = {
16 | "iml_type": attr.string(mandatory=True,
17 | doc="""
18 | The name of a key in the iml types xml file. rules_intellij_generate.py will
19 | look up this entry, and use its xml contents as the basis of the Intellij module
20 | file for this bazel package/Intellij module.
21 | """),
22 | "module_name_override": attr.string(default="",
23 | doc="""
24 | By default, the Intellij module name is the directory name of the package
25 | (a directory contining a BUILD file). If another module name is deisred,
26 | or (in particular), if there would otherwise be duplicate-named modules,
27 | a situation not allowed by Intellij.
28 | """),
29 | }
30 | )
31 |
--------------------------------------------------------------------------------
/rules/private/intellij_project.bzl:
--------------------------------------------------------------------------------
1 | load(":intellij_module.bzl", "IntellijModuleConfig")
2 |
3 | BazelPackageDep = provider(
4 | fields = {
5 | "bazel_package": "package name",
6 | "label_name": "label name",
7 | "attr_name": "the attribute name through which the dependency was established",
8 | "depends_on_bazel_package": "the bazel package depends on this other package",
9 | }
10 | )
11 |
12 | BazelPackageDeps = provider(
13 | fields = {
14 | "all": "all bazel package dependencies",
15 | }
16 | )
17 |
18 | JarDep = provider(
19 | fields = {
20 | "bazel_package": "package name of the target",
21 | "label_name": "label name of the target that generated this jar",
22 | "generated_by_build": "is this file generated by the build, or already-existing?",
23 | "relative_jar_path": "the path to the jar from the execroot",
24 | "owner_workspace_root": "the workspace root of the owner of the jar",
25 | }
26 | )
27 |
28 | JarDeps = provider(
29 | fields = {
30 | "all": "all jars for module",
31 | }
32 | )
33 |
34 | DeclaredIntellijModule = provider(
35 | fields = {
36 | "bazel_package": "the bazel package that this module represents",
37 | "module_name_override": "intellij module name, must be unique across the project",
38 | "iml_type": "the type of iml file to use, defined in the iml_types xml file",
39 | }
40 | )
41 |
42 | ProjectData = provider(
43 | fields = [
44 | "bazel_package_deps",
45 | "build_managed_label_matchlist",
46 | "iml_types_path",
47 | "jar_deps",
48 | "module_dependency_matchlist",
49 | "modules",
50 | "project_root_files_paths",
51 | "project_root_files_path_ignore_prefix",
52 | "root_bazel_package",
53 | "symlinks",
54 | "test_lib_label_matchlist",
55 | "workspace_xml_fragment_paths",
56 | ]
57 | )
58 |
59 | def _target_attrs_from_struct(a_struct):
60 | """Returns the attrs of a_struct that have a list of Targets"""
61 | attr_name_to_targets = {}
62 |
63 | for attr_candidate_name in dir(a_struct):
64 |
65 | if attr_candidate_name == "to_json" or attr_candidate_name == "to_proto":
66 | continue
67 |
68 | attr_candidate = getattr(a_struct, attr_candidate_name)
69 |
70 | # TODO: also should work for single-target attrs - scenario test for this (custom attrs...)
71 | if type(attr_candidate) == "list" and len(attr_candidate) > 0 and type(attr_candidate[0]) == "Target":
72 | attr_name_to_targets[attr_candidate_name] = attr_candidate
73 |
74 | return attr_name_to_targets
75 |
76 | def _gather_bazel_package_dependencies(target, ctx):
77 | """Recurse through target dependencies, and accumulate all package-to-package dependencies.
78 |
79 | A bazel package dependency, for the purposes of this rules project, is established when a target in
80 | one package relates to a target in another package, via a target attribute that contains a reference
81 | to a label in the other package."""
82 | all_bazel_package_dependencies = {}
83 |
84 | attr_name_to_targets = _target_attrs_from_struct(ctx.rule.attr)
85 | for attr_name in attr_name_to_targets:
86 | for d in attr_name_to_targets[attr_name]:
87 | if BazelPackageDeps in d:
88 | all_bazel_package_dependencies.update(d[BazelPackageDeps].all)
89 |
90 | if target.label.workspace_root == "" and \
91 | d.label.workspace_root == "" and \
92 | target.label.package != d.label.package:
93 |
94 | # make sure we only ever have one copy of this we pass through in the json.
95 | key = "%s;%s;%s;%s" % (target.label.package, target.label.name, attr_name, d.label.package)
96 |
97 | if key not in all_bazel_package_dependencies:
98 | all_bazel_package_dependencies[key] = \
99 | BazelPackageDep(
100 | bazel_package=target.label.package,
101 | label_name=target.label.name,
102 | attr_name=attr_name,
103 | depends_on_bazel_package=d.label.package)
104 |
105 | return [BazelPackageDeps(all=all_bazel_package_dependencies)]
106 |
107 | _gather_bazel_package_dependencies_aspect = aspect(
108 | implementation = _gather_bazel_package_dependencies,
109 | attr_aspects = ["*"],
110 | )
111 |
112 | def _declared_modules(ctx):
113 | """All modules 'declared' in the project, i.e. per intellij_module target."""
114 |
115 | all_modules = []
116 | for intellij_module in ctx.attr.modules:
117 | all_modules.append(
118 | DeclaredIntellijModule(
119 | bazel_package=intellij_module.label.package,
120 | module_name_override=intellij_module[IntellijModuleConfig].module_name_override,
121 | iml_type=intellij_module[IntellijModuleConfig].iml_type))
122 | return all_modules
123 |
124 | def _jar_dep(labeled, jar):
125 | return JarDep(
126 | bazel_package=labeled.label.package,
127 | label_name=labeled.label.name,
128 |
129 | # is_source means "Returns true if this is a source file, i.e. it is not generated."
130 | # We use this to distinguish between build-generated jars, and "external" jars
131 |
132 | generated_by_build=not jar.is_source,
133 | relative_jar_path=jar.path,
134 | owner_workspace_root=jar.owner.workspace_root)
135 |
136 | def _jar_dep_key(j):
137 | # make sure we only ever have one copy of this we pass through in the json.
138 | return "%s;%s;%s;%s;%s" % (j.bazel_package, j.label_name, j.relative_jar_path, j.generated_by_build, j.owner_workspace_root)
139 |
140 | def _jar_deps(target, ctx):
141 | """Walk all dependencies and gather up associations between bazel packages and jars."""
142 |
143 | # We must use transitive_runtime_jars, to get at the full jars, at the moment
144 | # see https://stackoverflow.com/a/45942563
145 |
146 | all_jar_deps = {}
147 |
148 | if JavaInfo in target:
149 | for jar in target[JavaInfo].transitive_runtime_jars.to_list():
150 | j = _jar_dep(target, jar)
151 | key = _jar_dep_key(j)
152 | all_jar_deps[key] = j
153 | if JarDeps in target:
154 | all_jar_deps.update(target[JarDeps].all)
155 |
156 | attr_name_to_targets = _target_attrs_from_struct(ctx.rule.attr)
157 | for attr_name in attr_name_to_targets:
158 | for d in attr_name_to_targets[attr_name]:
159 | if JarDeps in d:
160 | all_jar_deps.update(d[JarDeps].all)
161 | if JavaInfo in d:
162 | for jar in d[JavaInfo].transitive_runtime_jars.to_list():
163 | j = _jar_dep(target, jar)
164 | key = _jar_dep_key(j)
165 | all_jar_deps[key] = j
166 |
167 | return [JarDeps(all=all_jar_deps)]
168 |
169 | _gather_jar_deps_aspect = aspect(
170 | implementation = _jar_deps,
171 | attr_aspects = ["*"],
172 | )
173 |
174 | def _all_jar_deps(ctx):
175 | all_jar_deps = {}
176 |
177 | for dep in ctx.attr.deps:
178 | all_jar_deps.update(dep[JarDeps].all)
179 |
180 | keys_sorted = sorted(all_jar_deps.keys())
181 | results = []
182 | for k in keys_sorted:
183 | results.append(all_jar_deps[k])
184 | return results
185 |
186 | def _bazel_package_deps(ctx):
187 | all_deps = {}
188 | for dep in ctx.attr.deps:
189 | all_deps.update(dep[BazelPackageDeps].all)
190 | keys_sorted = sorted(all_deps.keys())
191 | results = []
192 | for k in keys_sorted:
193 | results.append(all_deps[k])
194 | return results
195 |
196 | def _impl(ctx):
197 | """Main rule method"""
198 | project_data_json_file = ctx.actions.declare_file("project-data.json")
199 | iml_types_file = ctx.attr.iml_types_file.files.to_list()[0]
200 |
201 | inputs = [
202 | iml_types_file,
203 | project_data_json_file,
204 | ]
205 |
206 | # gather up all top-level project files - the xml files that will go under the .idea directory
207 | paths = []
208 | if hasattr(ctx.attr.project_root_filegroup, "files"):
209 | inputs.extend(ctx.attr.project_root_filegroup.files.to_list())
210 | for f in ctx.attr.project_root_filegroup.files.to_list():
211 | paths.append(f.path)
212 |
213 | # gather up all workspace fragment files - these will be used as parts of .idea/workspace.xml
214 | workspace_xml_fragment_paths = []
215 | if hasattr(ctx.attr.workspace_xml_fragments_filegroup, "files"):
216 | inputs.extend(ctx.attr.workspace_xml_fragments_filegroup.files.to_list())
217 | for f in ctx.attr.workspace_xml_fragments_filegroup.files.to_list():
218 | workspace_xml_fragment_paths.append(f.path)
219 |
220 | # call out and gather data about this build, traversing build targets to find package dependencies and jars.
221 | project_data = ProjectData(
222 | root_bazel_package = ctx.label.package,
223 | bazel_package_deps = _bazel_package_deps(ctx),
224 | module_dependency_matchlist = ctx.attr.module_dependency_matchlist,
225 | jar_deps = _all_jar_deps(ctx),
226 | build_managed_label_matchlist = ctx.attr.build_managed_label_matchlist,
227 | test_lib_label_matchlist = ctx.attr.test_lib_label_matchlist,
228 | iml_types_path = iml_types_file.path,
229 | modules = _declared_modules(ctx),
230 | project_root_files_paths = paths,
231 | project_root_files_path_ignore_prefix = ctx.attr.project_root_filegroup_ignore_prefix,
232 | workspace_xml_fragment_paths = workspace_xml_fragment_paths,
233 | symlinks = ctx.attr.symlinks
234 | )
235 |
236 | # this json file is the "input" to the python transformation executable action
237 | ctx.actions.write(
238 | output=project_data_json_file,
239 | content=project_data.to_json())
240 |
241 | # execute the python script that transforms the input project data,
242 | # to an archive files containing all "managed" intellij configuration files.
243 | ctx.actions.run(
244 | executable = ctx.executable._intellij_generate_project_files,
245 | arguments = [
246 | project_data_json_file.path,
247 | ctx.outputs.intellij_files.path
248 | ],
249 | inputs = inputs,
250 | outputs = [ctx.outputs.intellij_files],
251 | progress_message = "Generating intellij project files: %s" % ctx.outputs.intellij_files.path)
252 |
253 | # build up a list of custom substitution variables that the install script will
254 | # use to transform the (templated) files into the intellij archive into
255 | # final intellij config files
256 | all_substitutions = {}
257 | all_substitutions.update(ctx.attr.custom_substitutions)
258 |
259 | custom_env_vars_str = ""
260 | for k in all_substitutions:
261 | # note: the "tools" attribute magically causes expand_location to see the dependencies specified there
262 | # see https://stackoverflow.com/a/44025866
263 | custom_env_vars_str += "'%s':'%s',\n" % (k, ctx.expand_location(all_substitutions[k]))
264 |
265 | if custom_env_vars_str == "":
266 | custom_env_vars_str = "# (note: no custom substitutions defined)"
267 |
268 | ctx.actions.expand_template(
269 | output=ctx.outputs.install_intellij_files_script,
270 | template=ctx.file._install_script_template_file,
271 | substitutions={
272 | "# _CUSTOM_ENV_VARS_GO_HERE": custom_env_vars_str,
273 | "_BAZELEXE_": ctx.attr.bazelexec,
274 | },
275 | is_executable=True)
276 |
277 | ctx.actions.expand_template(
278 | output=ctx.outputs.fswatch_and_install_intellij_files_mac_sh,
279 | template=ctx.file._fswatch_and_install_intellij_files_mac_template_file,
280 | substitutions={},
281 | is_executable=True)
282 |
283 |
284 | intellij_project = rule(
285 | implementation = _impl,
286 | attrs = {
287 | "_intellij_generate_project_files": attr.label(
288 | default=Label("//private:intellij_generate_project_files"),
289 | executable=True,
290 | cfg="target"),
291 |
292 | "_install_script_template_file": attr.label(
293 | default=Label("//private:install_intellij_files.py.template"), allow_single_file=True),
294 |
295 | "_fswatch_and_install_intellij_files_mac_template_file": attr.label(
296 | default=Label("//private:fswatch_and_install_intellij_files_mac.sh.template"), allow_single_file=True),
297 |
298 | "bazelexec": attr.string(
299 | default='bazel',
300 | doc="""
301 | The install_intellij_files script gets information about the version of bazel you are using.
302 | If you are using something like bazelisk, you can specify ./bazelisk instead of a system bazel.
303 | """),
304 |
305 | "deps": attr.label_list(
306 | default=[],
307 | aspects=[_gather_bazel_package_dependencies_aspect, _gather_jar_deps_aspect],
308 | doc="""
309 | This is the list of targets that the aspects will walk, to gather information about target
310 | and jar dependencies.
311 |
312 | So, these targets are what determine what packages are related, and therefore,
313 | what Intellij modules are related.
314 | """),
315 |
316 | "module_dependency_matchlist": attr.string_list(
317 | default=[ # in the attr docs...srcs/data/deps are the three principle types of dependencies
318 | '{"attr":"data"}',
319 | '{"attr":"deps"}',
320 | '{"attr":"srcs"}',
321 | ], doc="""
322 | A series of match rules on a source target, one of its attributes names, and a target that it depends on,
323 | which decides what entries drive the determination of bazel package dependnencies, and therefore,
324 | intellij module dependencies.
325 |
326 | An entry in the matchlist is a stringified json document of the form:
327 |
328 | {"package":"foo","attr":"deps","to_package":"bar"}
329 |
330 | This example would be very restrictive: only module dependencies flowing from package foo to package bar,
331 | via an attribute on foo called deps, would impact how the Intellij project is constructed.
332 |
333 | Wildcards are possible:
334 |
335 | {"package":"foo","attr":"deps","to_package":"*"}
336 |
337 | The now means: consider all dependencies found flowing from foo, via attr deps.
338 |
339 | The equivalent shorthand:
340 |
341 | {"package":"foo","attr":"deps"}
342 |
343 | Any ommitted attribute is treated as an implicit * / "match all", so:
344 |
345 | {"attr":"zorg"}
346 |
347 | means all dependencies established from any package, to any other package, via the attribute name "zorg",
348 | will be used to construct Intellij module dependencies.
349 | """),
350 |
351 | "build_managed_label_matchlist": attr.string_list(default=[],
352 | doc="""
353 | A matcher list of the form
354 |
355 | {"package":"*","label_name":"java_grpc"}
356 |
357 | which determines what jars, that are generated based on code in
358 | the project, are "bazel-managed" - that is to say, Intellij
359 | does not attempt any sort of compilation related to these jars.
360 |
361 | The most prominent example is protobuf-codegen. Users need
362 | the generated code, compiled, and jar'd, to be available in order
363 | to sensibly develop code based on these proto defintions.
364 |
365 | Assuming all java proto codegen targets are named "java_proto",
366 | this match rule will cause all proto jars to be included as
367 | module jar libraries:
368 |
369 | {"label_name":"java_proto"}
370 | """),
371 |
372 | "test_lib_label_matchlist": attr.string_list(default=[],
373 | doc="""
374 | A matcher list of the form
375 |
376 | {"package":"*","label_name":"java_test"}
377 |
378 | which determines what jar libraries are marked as "Test" libraries
379 | in Intellij modules. Note: any jars that are dependencies of
380 | non-test targets in the same module/bazel package, will cause
381 | the jar dependency to be marked as a "Compile" jar library.
382 | """),
383 |
384 | "custom_substitutions": attr.string_dict(default={},
385 | doc="""
386 | Variables that may be used in intellij xml files and templates, which
387 | are committed into the client project. At intellij project file
388 | installation time, these variables are substituted for their values,
389 | specified here.
390 | """),
391 |
392 | "iml_types_file": attr.label(mandatory=True, allow_single_file=True,
393 | doc = """
394 | A file containing iml type names, and xml contents that form the basis of
395 | intellij module files, for a given iml type.
396 | """),
397 |
398 | "project_root_filegroup": attr.label(default=None,
399 | doc="""
400 | Filegroup of files that will be placed under the .idea directory -
401 | i.e. the intellij project directory.
402 | """),
403 |
404 | "project_root_filegroup_ignore_prefix": attr.string(
405 | doc="""
406 | Prefix that should be stripped off the project_root_filegroup files, before they're placed under the .idea
407 | directory.
408 |
409 | (This is not the most elegant idea, but I can't think of a better approach for accomplishing this goal,
410 | at the moment)
411 | """),
412 |
413 | "workspace_xml_fragments_filegroup": attr.label(default=None,
414 | doc="""
415 | A filegroup of xml files that should each correspond to
416 | a workspace.xml "component". These should be named with
417 | the component name in the middle of the filename, ex:
418 |
419 | workspace.RunManager.xml
420 |
421 | The installer will overwrite any components with these names.
422 |
423 | This way, it's possible to control the contents of (only) parts
424 | of workspace.xml, and let other parts be managed directly by
425 | Intellij.
426 | """),
427 | "modules": attr.label_list(default=[],
428 | doc="""
429 | intellij_module targets must be added here in order to appear in the intellij project.
430 | """),
431 |
432 | "symlinks": attr.string_dict(default={}),
433 |
434 | "tools": attr.label_list(default=[], allow_files=True),
435 | },
436 |
437 | outputs={
438 | "intellij_files": "intellij_files",
439 | "install_intellij_files_script": "install_intellij_files_script",
440 | "fswatch_and_install_intellij_files_mac_sh": "fswatch_and_install_intellij_files_mac.sh",
441 | },
442 | )
443 |
--------------------------------------------------------------------------------
/rules/private/pytest/rules_intellij_generate_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from rules_intellij_generate import *
4 |
5 |
6 | class RulesIntellijGenerateTest(unittest.TestCase):
7 |
8 | def test_xml_indent(self):
9 | a_element = parse_xml("")
10 | a_element.append(parse_xml("1"))
11 | a_element.append(parse_xml("9"))
12 | a_element.append(parse_xml("2"))
13 | a_element.append(parse_xml("3"))
14 | a_element.append(parse_xml("4"))
15 | a_element.append(parse_xml("5"))
16 | self.assertEqual(
17 | "\n".join(
18 | [
19 | "",
20 | " 1",
21 | " ",
22 | " 9",
23 | " ",
24 | " 2",
25 | " 3",
26 | " 4",
27 | " ",
28 | " ",
29 | " 5",
30 | " ",
31 | " ",
32 | "",
33 | ""
34 | ]), ET.tostring(xml_indent(a_element)).decode("utf-8"))
35 |
36 | def test_iml_paths(self):
37 | root_intellij_module = {
38 | "bazel_package": "",
39 | "module_name": "foo",
40 | "iml_type": "java"
41 | }
42 |
43 | regular_intellij_module = {
44 | "bazel_package": "some_package/bar",
45 | "iml_type": "java"
46 | }
47 |
48 | self.assertEqual("foo.iml", iml_path_from_declared_intellij_module(root_intellij_module, "foo"))
49 | self.assertEqual("some_package/bar/bar.iml", iml_path_from_declared_intellij_module(regular_intellij_module, ""))
50 |
51 | def test_check_unique_intellij_module_names(self):
52 | check_unique_intellij_module_names([
53 | {"bazel_package": "a/foo"},
54 | {"bazel_package": "b/bar"},
55 | ], "the_root_package")
56 |
57 | check_unique_intellij_module_names([
58 | {"bazel_package": "a/foo"},
59 | {"bazel_package": "b/foo", "module_name_override": "bar"},
60 | ], "the_root_package")
61 |
62 | def do_non_unique_module_names():
63 | check_unique_intellij_module_names([
64 | {"bazel_package": "a/foo"},
65 | {"bazel_package": "b/foo"},
66 | ], "the_root_package")
67 |
68 | self.assertRaises(DuplicateModuleNameException, do_non_unique_module_names)
69 |
70 | def do_override_to_non_unique_module_names():
71 | check_unique_intellij_module_names([
72 | {"bazel_package": "a/foo"},
73 | {"bazel_package": "b/bar", "module_name_override": "foo"},
74 | ], "the_root_package")
75 |
76 | self.assertRaises(DuplicateModuleNameException, do_override_to_non_unique_module_names)
77 |
78 |
79 | def test_basic_composer_and_conversion_to_xml(self):
80 | iml_types_xml = """
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | """.strip()
93 |
94 | expected_root_iml_content = """
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | """.strip() + "\n"
103 |
104 | declared_intellij_module = {
105 | "bazel_package": "some_package/bar",
106 | "iml_type": "java"
107 | }
108 |
109 | self.assertEqual(
110 | {"some_package/bar/bar.iml": expected_root_iml_content},
111 | composers_to_xmls(
112 | make_bazel_package_iml_composers(
113 | iml_types_xml,
114 | [declared_intellij_module]), "root_package"))
115 |
116 | def test_insert_jar_dep_into_iml_element_as_module_library(self):
117 | iml_base_content = """
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | """.strip() + "\n"
127 |
128 | expected_content_1 = """
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | """.strip() + "\n"
147 |
148 | element1 = parse_xml(iml_base_content)
149 | insert_jar_dep_into_iml_element_as_module_library(
150 | element1,
151 | "some/lib.jar",
152 | is_test_mode=False)
153 |
154 | self.assertEqual(expected_content_1, convert_xml_element_to_pretty_printed_xml_string(element1))
155 |
156 | expected_content_2 = """
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 | """.strip() + "\n"
175 |
176 | element2 = parse_xml(iml_base_content)
177 | insert_jar_dep_into_iml_element_as_module_library(
178 | element2,
179 | "some/lib.jar",
180 | is_test_mode=True)
181 |
182 | self.assertEqual(expected_content_2, convert_xml_element_to_pretty_printed_xml_string(element2))
183 |
184 | def test_add_jar_libraries(self):
185 | iml_base_content = """
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 | """.strip() + "\n"
194 |
195 | element = parse_xml(iml_base_content)
196 | insert_all_jar_libraries(
197 | {"foo": IntellijModuleComposer({}, element)},
198 | ['{"label_name":"managed_by_build_tool"}'],
199 | ['{"package":"fo*","label_name":"some_test_lib_label_name"}'],
200 | [
201 | {
202 | "bazel_package": "foo",
203 | "label_name": "not_managed_by_build_tool",
204 | "test_mode": True,
205 | "generated_by_build": True,
206 | "relative_jar_path": "some/relative/path/off/the/execroot/a-was-generated-by-the-build.jar",
207 | "owner_workspace_root": ""
208 | },
209 | {
210 | "bazel_package": "foo",
211 | "label_name": "some_test_lib_label_name",
212 | "test_mode": True,
213 | "generated_by_build": False,
214 | "relative_jar_path": "some/relative/path/off/the/execroot/b-show-up-in-test-mode-only.jar",
215 | "owner_workspace_root": "external"
216 | },
217 | {
218 | "bazel_package": "foo",
219 | "label_name": "some_label_name",
220 | "test_mode": False,
221 | "generated_by_build": False,
222 | "relative_jar_path": "some/relative/path/off/the/execroot/c-show-up-in-non-test-mode-only.jar",
223 | "owner_workspace_root": "external"
224 | },
225 | {
226 | "bazel_package": "foo",
227 | "label_name": "some_test_lib_label_name",
228 | "test_mode": True,
229 | "generated_by_build": False,
230 | "relative_jar_path": "some/relative/path/off/the/execroot/d-show-up-in-both-modes.jar",
231 | "owner_workspace_root": "external"
232 | },
233 | {
234 | "bazel_package": "foo",
235 | "label_name": "some_label_name",
236 | "test_mode": False,
237 | "generated_by_build": False,
238 | "relative_jar_path": "some/relative/path/off/the/execroot/d-show-up-in-both-modes.jar",
239 | "owner_workspace_root": "external"
240 | },
241 | {
242 | "bazel_package": "foo",
243 | "label_name": "managed_by_build_tool",
244 | "test_mode": False,
245 | "generated_by_build": True,
246 | "relative_jar_path": "some/relative/path/off/the/execroot/e-was-generated-by-the-build.jar",
247 | "owner_workspace_root": ""
248 | },
249 | ])
250 |
251 | # - libs generated by the build:
252 | # ...that are generated outside of this workspace, are considered,
253 | # ...that have label names that are declared to be managed by the build, are considered
254 | # ...(or thus,) that are buildable by the ide, are not considered,
255 | # - libs only discovered via test mode are scope="TEST"
256 | # - libs that are present in both test mode and non-test mode, are considered compile dependencies (so, no scope attribute)
257 |
258 | expected_content = """
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 | """.strip() + "\n"
303 | self.assertEqual(expected_content, convert_xml_element_to_pretty_printed_xml_string(element))
304 |
305 | def match_parse_failure():
306 | JarDependencyMatcher('xyxyx')
307 |
308 | self.assertRaises(JarDependencyMatchFormatException, match_parse_failure)
309 |
310 | def test_determine_module_deps(self):
311 | # basic match/no-match
312 | self.assertEqual({"a_package": ["b_package", "e_package"]},
313 | determine_package_deps([{"bazel_package": "a_package",
314 | "label_name": "x_label_name",
315 | "attr_name": "deps",
316 | "depends_on_bazel_package": "b_package"},
317 | {"bazel_package": "c_package",
318 | "label_name": "x_label_name",
319 | "attr_name": "NOMATCH",
320 | "depends_on_bazel_package": "d_package"},
321 | {"bazel_package": "a_package",
322 | "label_name": "x_label_name",
323 | "attr_name": "deps",
324 | "depends_on_bazel_package": "e_package"}],
325 | [ModuleDependencyMatcher('{"attr":"deps"}')],
326 | "the_root_package"))
327 |
328 | # filesystem-like wildcarding
329 | self.assertEqual({"a_package": ["b_package", "e_package"]},
330 | determine_package_deps([{"bazel_package": "a_package",
331 | "label_name": "x_label_name",
332 | "attr_name": "deps",
333 | "depends_on_bazel_package": "b_package"},
334 | {"bazel_package": "c_package",
335 | "label_name": "x_label_name",
336 | "attr_name": "NOMATCH",
337 | "depends_on_bazel_package": "d_package"},
338 | {"bazel_package": "a_package",
339 | "label_name": "x_label_name",
340 | "attr_name": "deps",
341 | "depends_on_bazel_package": "e_package"}],
342 | [ModuleDependencyMatcher('{"attr":"de*"}')],
343 | "the_root_package"))
344 |
345 | # match on multiple attrs
346 | self.assertEqual({"a_package": ["b_package"],
347 | "c_package": ["b_package"]},
348 | determine_package_deps([{"bazel_package": "a_package",
349 | "label_name": "x_label_name",
350 | "attr_name": "deps",
351 | "depends_on_bazel_package": "b_package"},
352 | {"bazel_package": "c_package",
353 | "label_name": "x_label_name",
354 | "attr_name": "deps",
355 | "depends_on_bazel_package": "b_package"},
356 | {"bazel_package": "a_package",
357 | "label_name": "x_label_name",
358 | "attr_name": "deps",
359 | "depends_on_bazel_package": "e_package"}],
360 | [ModuleDependencyMatcher('{"to_package":"b_package", "attr":"deps"}')],
361 | "the_root_package"))
362 |
363 | def match_parse_failure():
364 | ModuleDependencyMatcher('xyxyx')
365 | self.assertRaises(ModuleDependencyMatchFormatException, match_parse_failure)
366 |
367 | def test_convert_bazel_package_deps_to_intellij_module_deps(self):
368 | defined_modules = [
369 | {"bazel_package": "z/foo"},
370 | {"bazel_package": "z/bar"},
371 | {"bazel_package": "z/a"},
372 | {"bazel_package": "z/bbb", "module_name_override": "b"},
373 | {"bazel_package": "z/c"},
374 | {"bazel_package": "d"},
375 | {"bazel_package": ""},
376 | ]
377 |
378 | self.assertEqual({
379 | "z/foo": ["a", "b"],
380 | "z/bar": ["c", "d"]
381 | }, convert_bazel_package_deps_to_intellij_module_deps({
382 | "z/foo": ["z/a", "z/bbb", "z/not_available_in_list"],
383 | "z/bar": ["z/c", "d"]
384 | }, defined_modules, "yyy"))
385 |
386 | # root package
387 | self.assertEqual({
388 | "": ["a"]
389 | }, convert_bazel_package_deps_to_intellij_module_deps({
390 | "": ["z/a"],
391 | }, defined_modules, "yyy"))
392 |
393 | def test_insert_bazel_package_dep_into_iml_element_as_module_dep(self):
394 | iml_base_content = """
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 | """.strip() + "\n"
404 |
405 | expected_content = """
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 | """.strip() + "\n"
417 |
418 | element1 = parse_xml(iml_base_content)
419 | insert_bazel_package_dep_into_iml_element_as_module_dep(element1, "bar")
420 | insert_bazel_package_dep_into_iml_element_as_module_dep(element1, "zzz")
421 |
422 | self.assertEqual(expected_content, convert_xml_element_to_pretty_printed_xml_string(element1))
423 |
424 | def test_add_bazel_package_deps(self):
425 | iml_base_content = """
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 | """.strip() + "\n"
435 |
436 | expected_content = """
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 | """.strip() + "\n"
448 |
449 | element = parse_xml(iml_base_content)
450 | insert_all_module_deps(
451 | {"foo": IntellijModuleComposer({}, element)},
452 | {"foo": ["bar", "zzz"]})
453 |
454 | self.assertEqual(expected_content, convert_xml_element_to_pretty_printed_xml_string(element))
455 |
456 | def test_make_modules_xml(self):
457 | expected_content = """
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 | """.strip() + "\n"
466 |
467 | self.assertEqual(
468 | expected_content,
469 | make_modules_xml("root/subroot", ["root/subroot/foo/subfoo.iml", "root/subroot/bar.iml"]))
470 |
471 | def test_xmls_to_sha1s(self):
472 | self.assertEqual(
473 | {"bar.iml": "4d18aab61d7c4874a70ff4750f1e066291fff399",
474 | "foo.iml": "13e190a16a3937a346f2f2104210a9d0af775cec"},
475 | xmls_to_sha1s({"bar.iml": "", "foo.iml": ""}))
476 |
477 | def test_intellij_files_archive(self):
478 | expected_archive_contents = """
479 | sha1bar bar.iml
480 | sha1foo foo.iml
481 | __SHA1_DIVIDER__
482 | bar.iml
483 |
484 | __FILE_DIVIDER__
485 | foo.iml
486 |
487 | __SYMLINK_DIVIDER__
488 | some_execroot_file|symlink_under_project_file
489 | """.strip()
490 | self.assertEqual(
491 | expected_archive_contents,
492 | make_intellij_files_archive(
493 | {"sha1foo": "foo.iml",
494 | "sha1bar": "bar.iml"},
495 | {"foo.iml": "", "bar.iml": ""},
496 | {"some_execroot_file":"symlink_under_project_file"}))
497 |
498 |
499 | # TODO: test that workspace xml fragment paths are relative to .idea
500 |
501 | if __name__ == '__main__':
502 | suite = unittest.TestSuite()
503 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(RulesIntellijGenerateTest))
504 |
505 | # python unit test main's must end with this or the test will exit with status code 0,
506 | # and thus it will not fail the bazel test run if there's a test failure.
507 | return_value = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
508 | sys.exit(return_value)
509 |
--------------------------------------------------------------------------------
/rules/tools/bazel.rc:
--------------------------------------------------------------------------------
1 | test --test_output=errors --action_env="GTEST_COLOR=1"
2 |
--------------------------------------------------------------------------------
/rules_intellij_generate.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/scenarios/.bazelversion:
--------------------------------------------------------------------------------
1 | 0.24.1
2 |
--------------------------------------------------------------------------------
/scenarios/01_one_class/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
5 |
6 | java_binary(
7 | name = "run_A",
8 | main_class="oneclass.A",
9 | srcs = glob(["src/**/*.java"]),
10 | )
11 |
12 | java_library(
13 | name="lib",
14 | srcs = glob(["src/**/*.java"]),
15 | )
16 |
17 | intellij_module(name="iml", iml_type="java-simple")
18 |
19 | intellij_project(
20 | name="project_01",
21 | deps=[":lib"],
22 | iml_types_file="//:iml_types.xml",
23 | project_root_filegroup="//:automatically_placed_intellij_project_files",
24 | project_root_filegroup_ignore_prefix="intellij_project_files",
25 | modules=[":iml"]
26 | )
27 |
--------------------------------------------------------------------------------
/scenarios/01_one_class/README.txt:
--------------------------------------------------------------------------------
1 | The simplest possible java project.
2 |
3 | Layout is not maven-standard.
4 |
--------------------------------------------------------------------------------
/scenarios/01_one_class/src/oneclass/A.java:
--------------------------------------------------------------------------------
1 | package oneclass;
2 |
3 | class A {
4 | public static void main(String[] args) {
5 | System.out.println("hello from A");
6 | }
7 | }
--------------------------------------------------------------------------------
/scenarios/02_one_class_and_one_test/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
6 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
7 |
8 | java_library(
9 | name="java_lib",
10 | srcs = glob(["src/**/*.java"]),
11 | )
12 |
13 | java_library(
14 | name="java_test_lib",
15 | srcs = glob(["test/**/*.java"]),
16 | deps=[":java_lib"] + JUNIT5_MINIMAL_DEPS,
17 | )
18 |
19 | junit5_all_in_package_test(
20 | name="java_tests",
21 | java_package="one_class_and_one_test",
22 | runtime_deps=[":java_test_lib"]
23 | )
24 |
25 | intellij_module(name="iml", iml_type="java-simple")
26 |
27 | intellij_project(
28 | name="project_02",
29 | deps=[":java_test_lib"],
30 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
31 | iml_types_file="//:iml_types.xml",
32 | project_root_filegroup="//:automatically_placed_intellij_project_files",
33 | project_root_filegroup_ignore_prefix="intellij_project_files",
34 | modules=[":iml"]
35 | )
36 |
--------------------------------------------------------------------------------
/scenarios/02_one_class_and_one_test/README.txt:
--------------------------------------------------------------------------------
1 | The simplest possible java project that has tests.
2 |
3 | Layout is not maven-standard.
4 |
--------------------------------------------------------------------------------
/scenarios/02_one_class_and_one_test/src/one_class_and_one_test/B.java:
--------------------------------------------------------------------------------
1 | package one_class_and_one_test;
2 |
3 | class B {
4 | public int theNumber() {
5 | return 77;
6 | }
7 | }
--------------------------------------------------------------------------------
/scenarios/02_one_class_and_one_test/test/one_class_and_one_test/BTest.java:
--------------------------------------------------------------------------------
1 | package one_class_and_one_test;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 |
7 | public class BTest {
8 | @Test
9 | public void the_number() {
10 | assertEquals(77, new B().theNumber());
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/scenarios/03_basic/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 | intellij_project(
5 | name="project_03",
6 | deps=[
7 | "//03_basic/dolphin:java_test_lib",
8 | "//03_basic/gorilla:java_test_lib",
9 | "//03_basic/human:java_test_lib",
10 | "//03_basic/primate:java_test_lib",
11 | "//03_basic/mammal:java_test_lib",
12 | ],
13 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
14 | iml_types_file="//:iml_types.xml",
15 | project_root_filegroup="//:automatically_placed_intellij_project_files",
16 | project_root_filegroup_ignore_prefix="intellij_project_files",
17 | modules=[
18 | "//03_basic/dolphin:iml",
19 | "//03_basic/gorilla:iml",
20 | "//03_basic/human:iml",
21 | "//03_basic/mammal:iml",
22 | "//03_basic/primate:iml",
23 | ]
24 | )
25 |
--------------------------------------------------------------------------------
/scenarios/03_basic/README.txt:
--------------------------------------------------------------------------------
1 | - standard maven layout (see: https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html)
2 | - a few modules that are interdependent:
3 |
4 | mammal
5 | |
6 | |-- primate
7 | | |
8 | | |-- gorilla
9 | | |-- human
10 | |
11 | -- dolphin
12 |
13 | - main methods in species-level modules
14 |
--------------------------------------------------------------------------------
/scenarios/03_basic/dolphin/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//03_basic:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//03_basic/mammal:java_lib",
12 | ]
13 | )
14 |
15 | java_library(
16 | name="java_test_lib",
17 | srcs = glob(["src/test/java/**/*.java"]),
18 | deps=[
19 | ":java_lib",
20 |
21 | "//03_basic/mammal:java_lib",
22 | ] + JUNIT5_MINIMAL_DEPS,
23 | )
24 |
25 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
26 | junit5_all_in_package_test(
27 | name="java_tests",
28 | java_package="basic.dolphin",
29 | runtime_deps=[":java_test_lib"]
30 | )
31 |
32 | intellij_module(name="iml", iml_type="java-maven-style")
33 |
--------------------------------------------------------------------------------
/scenarios/03_basic/dolphin/src/main/java/basic/dolphin/Echolocation.java:
--------------------------------------------------------------------------------
1 | package basic.dolphin;
2 |
3 | import basic.mammal.WarmBlood;
4 |
5 | public class Echolocation extends WarmBlood {
6 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/dolphin/src/test/java/basic/dolphin/EcholocationTest.java:
--------------------------------------------------------------------------------
1 | package basic.dolphin;
2 |
3 | import basic.mammal.WarmBlood;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import static org.junit.jupiter.api.Assertions.assertTrue;
7 |
8 | class EcholocationTest {
9 | @Test
10 | public void ancestry() {
11 | assertTrue(WarmBlood.class.isAssignableFrom(Echolocation.class));
12 | }
13 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/gorilla/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//03_basic:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//03_basic/primate:java_lib",
12 | ]
13 | )
14 |
15 | java_library(
16 | name="java_test_lib",
17 | srcs = glob(["src/test/java/**/*.java"]),
18 | deps=[
19 | ":java_lib",
20 |
21 | "//03_basic/mammal:java_lib",
22 | "//03_basic/primate:java_lib",
23 | ] + JUNIT5_MINIMAL_DEPS,
24 | )
25 |
26 | junit5_all_in_package_test(
27 | name="java_tests",
28 | java_package="basic.gorilla",
29 | runtime_deps=[":java_test_lib"]
30 | )
31 |
32 | intellij_module(name="iml", iml_type="java-maven-style")
33 |
--------------------------------------------------------------------------------
/scenarios/03_basic/gorilla/src/main/java/basic/gorilla/KnuckleWalking.java:
--------------------------------------------------------------------------------
1 | package basic.gorilla;
2 |
3 | import basic.primate.ColorVision;
4 |
5 | public class KnuckleWalking extends ColorVision {
6 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/gorilla/src/test/java/basic/gorilla/KnuckleWalkingTest.java:
--------------------------------------------------------------------------------
1 | package basic.gorilla;
2 |
3 | import basic.mammal.WarmBlood;
4 | import basic.primate.ColorVision;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import static org.junit.jupiter.api.Assertions.assertTrue;
8 |
9 | class KnuckleWalkingTest {
10 | @Test
11 | public void ancestry() {
12 | assertTrue(ColorVision.class.isAssignableFrom(KnuckleWalking.class));
13 | assertTrue(WarmBlood.class.isAssignableFrom(KnuckleWalking.class));
14 | }
15 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/human/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//03_basic:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//03_basic/primate:java_lib",
12 | ]
13 | )
14 |
15 | java_library(
16 | name="java_test_lib",
17 | srcs = glob(["src/test/java/**/*.java"]),
18 | deps=[
19 | ":java_lib",
20 |
21 | "//03_basic/mammal:java_lib",
22 | "//03_basic/primate:java_lib",
23 | ] + JUNIT5_MINIMAL_DEPS,
24 | )
25 |
26 | junit5_all_in_package_test(
27 | name="java_tests",
28 | java_package="basic.human",
29 | runtime_deps=[":java_test_lib"]
30 | )
31 |
32 | intellij_module(name="iml", iml_type="java-maven-style")
33 |
--------------------------------------------------------------------------------
/scenarios/03_basic/human/src/main/java/basic/human/OpposableThumbs.java:
--------------------------------------------------------------------------------
1 | package basic.human;
2 |
3 | import basic.primate.ColorVision;
4 |
5 | public class OpposableThumbs extends ColorVision {
6 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/human/src/test/java/basic/human/OpposableThumbsTest.java:
--------------------------------------------------------------------------------
1 | package basic.human;
2 |
3 | import basic.mammal.WarmBlood;
4 | import basic.primate.ColorVision;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import static org.junit.jupiter.api.Assertions.assertTrue;
8 |
9 | class OpposableThumbsTest {
10 | @Test
11 | public void ancestry() {
12 | assertTrue(ColorVision.class.isAssignableFrom(OpposableThumbs.class));
13 | assertTrue(WarmBlood.class.isAssignableFrom(OpposableThumbs.class));
14 | }
15 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/mammal/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//03_basic:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | )
11 |
12 | java_library(
13 | name="java_test_lib",
14 | srcs = glob(["src/test/java/**/*.java"]),
15 | deps=[":java_lib"] + JUNIT5_MINIMAL_DEPS,
16 | )
17 |
18 | junit5_all_in_package_test(
19 | name="java_tests",
20 | java_package="basic.mammal",
21 | runtime_deps=[":java_test_lib"]
22 | )
23 |
24 | intellij_module(name="iml", iml_type="java-maven-style")
25 |
--------------------------------------------------------------------------------
/scenarios/03_basic/mammal/src/main/java/basic/mammal/WarmBlood.java:
--------------------------------------------------------------------------------
1 | package basic.mammal;
2 |
3 | public class WarmBlood {
4 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/mammal/src/test/java/basic/mammal/WarmBloodTest.java:
--------------------------------------------------------------------------------
1 | package basic.mammal;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | class WarmBloodTest {
6 | @Test
7 | public void does_nothing() {
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/scenarios/03_basic/primate/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//03_basic:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//03_basic/mammal:java_lib",
12 | ]
13 | )
14 |
15 | java_library(
16 | name="java_test_lib",
17 | srcs = glob(["src/test/java/**/*.java"]),
18 | deps=[
19 | ":java_lib",
20 |
21 | "//03_basic/mammal:java_lib",
22 | ] + JUNIT5_MINIMAL_DEPS,
23 | )
24 |
25 | junit5_all_in_package_test(
26 | name="java_tests",
27 | java_package="basic.primate",
28 | runtime_deps=[":java_test_lib"]
29 | )
30 |
31 | intellij_module(name="iml", iml_type="java-maven-style")
32 |
--------------------------------------------------------------------------------
/scenarios/03_basic/primate/src/main/java/basic/primate/ColorVision.java:
--------------------------------------------------------------------------------
1 | package basic.primate;
2 |
3 | import basic.mammal.WarmBlood;
4 |
5 | public class ColorVision extends WarmBlood {
6 | }
--------------------------------------------------------------------------------
/scenarios/03_basic/primate/src/test/java/basic/primate/ColorVisionTest.java:
--------------------------------------------------------------------------------
1 | package basic.primate;
2 |
3 | import basic.mammal.WarmBlood;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import static org.junit.jupiter.api.Assertions.assertTrue;
7 |
8 | class ColorVisionTest {
9 | @Test
10 | public void ancestry() {
11 | assertTrue(WarmBlood.class.isAssignableFrom(ColorVision.class));
12 | }
13 | }
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 |
5 | intellij_project(
6 | name="project_04",
7 | deps=["//04_transitive_via_export/child:java_test_lib"],
8 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
9 | iml_types_file="//:iml_types.xml",
10 | project_root_filegroup="//:automatically_placed_intellij_project_files",
11 | project_root_filegroup_ignore_prefix="intellij_project_files",
12 | modules=[
13 | "//04_transitive_via_export/grandparent:iml",
14 | "//04_transitive_via_export/parent:iml",
15 | "//04_transitive_via_export/child:iml",
16 | ]
17 | )
18 |
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/README.txt:
--------------------------------------------------------------------------------
1 | This scenario simulates the issue I ran across in the course of using the
2 | appengine bazel rules, in which the java servlet library is exported:
3 |
4 | https://github.com/bazelbuild/rules_appengine/blob/master/appengine/BUILD#L2
5 |
6 | This causes the servlet library to be available to AppEngine servlets. In
7 | order to build a working intellij module, we therefore need that exported
8 | jar's classes to be available to module code.
9 |
10 | Also see the java_library documentation on exports:
11 | https://docs.bazel.build/versions/master/be/java.html#java_library.exports
12 |
13 | Open question: should java_library exports be exposed as intellij dependency exports,
14 | or (current state) be expressed as simple library dependencies in child modules?
15 |
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/child/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//04_transitive_via_export:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//04_transitive_via_export/parent:java_lib"
12 | ],
13 | )
14 |
15 | java_library(
16 | name="java_test_lib",
17 | srcs = glob(["src/test/java/**/*.java"]),
18 | deps=[
19 | ":java_lib",
20 | ] + JUNIT5_MINIMAL_DEPS,
21 | )
22 |
23 | junit5_all_in_package_test(
24 | name="java_tests",
25 | java_package="transitive_via_export.child",
26 | runtime_deps=[":java_test_lib"]
27 | )
28 |
29 | intellij_module(name="iml", iml_type="java-maven-style")
30 |
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/child/src/main/java/transitive_via_export/parent/Child.java:
--------------------------------------------------------------------------------
1 | package transitive_via_export.parent;
2 |
3 | class Child {
4 | public boolean canIUseGuava() {
5 | // demonstrates use of guava,
6 | // only accessible because the grandparent exports the library
7 |
8 | try {
9 | Class.forName("com.google.common.base.Strings");
10 | return true;
11 | } catch (ClassNotFoundException e) {
12 | return false;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/child/src/test/java/transitive_via_export/parent/ChildTest.java:
--------------------------------------------------------------------------------
1 | package transitive_via_export.parent;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 | import static org.junit.jupiter.api.Assertions.assertFalse;
7 | import static org.junit.jupiter.api.Assertions.assertTrue;
8 |
9 | class ChildTest {
10 | @Test
11 | public void print_hello_three_times() {
12 | assertTrue(new Child().canIUseGuava());
13 | }
14 | }
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/grandparent/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//04_transitive_via_export:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "@com_google_guava_guava//jar",
12 | ],
13 | exports = [
14 | "@com_google_guava_guava//jar"
15 | ],
16 | )
17 |
18 | java_library(
19 | name="java_test_lib",
20 | srcs = glob(["src/test/java/**/*.java"]),
21 | deps=[
22 | ":java_lib",
23 | ] + JUNIT5_MINIMAL_DEPS,
24 | )
25 |
26 | junit5_all_in_package_test(
27 | name="java_tests",
28 | java_package="transitive_via_export.grandparent",
29 | runtime_deps=[":java_test_lib"]
30 | )
31 |
32 | intellij_module(name="iml", iml_type="java-maven-style")
33 |
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/grandparent/src/main/java/transitive_via_export/grandparent/Grandparent.java:
--------------------------------------------------------------------------------
1 | package transitive_via_export.grandparent;
2 |
3 | import com.google.common.base.Strings;
4 |
5 | class Grandparent {
6 | public String hello3times() {
7 | // demonstrates use of guava
8 |
9 | try {
10 | Class.forName("com.google.common.base.Strings");
11 | } catch (ClassNotFoundException e) {
12 | throw new RuntimeException(e);
13 | }
14 |
15 | return Strings.repeat("hello", 3);
16 | }
17 | }
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/grandparent/src/test/java/transitive_via_export/grandparent/GrandparentTest.java:
--------------------------------------------------------------------------------
1 | package transitive_via_export.grandparent;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 |
7 | class GrandparentTest {
8 | @Test
9 | public void print_hello_three_times() {
10 | assertEquals("hellohellohello", new Grandparent().hello3times());
11 | }
12 | }
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/parent/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//04_transitive_via_export:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//04_transitive_via_export/grandparent:java_lib"
12 | ],
13 | )
14 |
15 | java_library(
16 | name="java_test_lib",
17 | srcs = glob(["src/test/java/**/*.java"]),
18 | deps=[
19 | ":java_lib",
20 | ] + JUNIT5_MINIMAL_DEPS,
21 | )
22 |
23 | junit5_all_in_package_test(
24 | name="java_tests",
25 | java_package="transitive_via_export.parent",
26 | runtime_deps=[":java_test_lib"]
27 | )
28 |
29 | intellij_module(name="iml", iml_type="java-maven-style")
30 |
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/parent/src/main/java/transitive_via_export/parent/Parent.java:
--------------------------------------------------------------------------------
1 | package transitive_via_export.parent;
2 |
3 | import com.google.common.base.Strings;
4 |
5 | class Parent {
6 | public String hello4times() {
7 | // demonstrates use of guava,
8 | // only accessible because the grandparent exports the library
9 |
10 | try {
11 | Class.forName("com.google.common.base.Strings");
12 | } catch (ClassNotFoundException e) {
13 | throw new RuntimeException(e);
14 | }
15 |
16 | return Strings.repeat("hello", 4);
17 | }
18 | }
--------------------------------------------------------------------------------
/scenarios/04_transitive_via_export/parent/src/test/java/transitive_via_export/parent/ParentTest.java:
--------------------------------------------------------------------------------
1 | package transitive_via_export.parent;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 |
7 | class ParentTest {
8 | @Test
9 | public void print_hello_three_times() {
10 | assertEquals("hellohellohellohello", new Parent().hello4times());
11 | }
12 | }
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 |
5 | intellij_project(
6 | name="project_05",
7 | deps=["//05_annotation_processor/usage:java_test_lib"],
8 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
9 | iml_types_file="//:iml_types.xml",
10 | project_root_filegroup="//:automatically_placed_intellij_project_files",
11 | project_root_filegroup_ignore_prefix="intellij_project_files",
12 | modules=[
13 | "//05_annotation_processor/class_generator:iml",
14 | "//05_annotation_processor/text_file_generator:iml",
15 | "//05_annotation_processor/usage:iml",
16 | ]
17 | )
18 |
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/README.txt:
--------------------------------------------------------------------------------
1 | In an earlier version of this library, Annotation processing had deep integration
2 | with the intellij rules, however this (generating compiler.xml) turned out to be
3 | of modest benefit, and in practice the end-user experience was not great.
4 |
5 | In this newer version of the library, the approach is to just provide compiler.xml as
6 | an automatically-copied project file. This scenario + test is kept as a demonstration
7 | of how it works (as simple as it is).
8 |
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/class_generator/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//05_annotation_processor:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | java_plugin(
6 | name="annotation_processor",
7 | srcs = glob(["src/main/java/**/*.java"]),
8 | processor_class = "annotation_processor.class_generator.ClassGeneratorAnnotationProcessor",
9 | resources = ["src/main/resources/META-INF/services/javax.annotation.processing.Processor"],
10 | generates_api = 1, # must be specified or dependent targets will not see gen'd classfiles
11 | )
12 |
13 | intellij_module(name="iml", iml_type="java-maven-style-with-resources")
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/class_generator/src/main/java/annotation_processor/class_generator/ClassGeneratorAnnotationProcessor.java:
--------------------------------------------------------------------------------
1 | package annotation_processor.class_generator;
2 |
3 | import javax.annotation.processing.AbstractProcessor;
4 | import javax.annotation.processing.RoundEnvironment;
5 | import javax.annotation.processing.SupportedAnnotationTypes;
6 | import javax.annotation.processing.SupportedSourceVersion;
7 | import javax.lang.model.SourceVersion;
8 | import javax.lang.model.element.Element;
9 | import javax.lang.model.element.Name;
10 | import javax.lang.model.element.TypeElement;
11 | import javax.tools.Diagnostic;
12 | import javax.tools.JavaFileObject;
13 | import java.io.IOException;
14 | import java.io.PrintWriter;
15 | import java.util.Set;
16 |
17 | import static java.lang.String.format;
18 |
19 | @SupportedSourceVersion(SourceVersion.RELEASE_8)
20 | @SupportedAnnotationTypes("annotation_processor.class_generator.GenClass")
21 | public class ClassGeneratorAnnotationProcessor extends AbstractProcessor {
22 | @Override
23 | public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
24 | for (TypeElement annotation : annotations) {
25 | for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(annotation)) {
26 | GenClass genClassAnnotation = annotatedElement.getAnnotation(GenClass.class);
27 | if (genClassAnnotation == null) {
28 | continue;
29 | }
30 | String genClassName = genClassAnnotation.genClassName();
31 | Name annotatedClass = annotatedElement.getSimpleName();
32 | processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
33 | format("found GenClass annotation on class '%s', " +
34 | "generating class '%s'", annotatedClass, genClassName));
35 | try {
36 | JavaFileObject builderFile = processingEnv.getFiler().createSourceFile("somepackage." + genClassName);
37 | try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
38 | out.write("package somepackage;\n");
39 | out.write("\n");
40 | out.write(format("public class %s {\n", genClassName));
41 | out.write(" public int foo = 77;\n");
42 | out.write("}\n");
43 | }
44 | } catch (IOException e) {
45 | throw new RuntimeException(e);
46 | }
47 | }
48 | }
49 | return false;
50 | }
51 | }
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/class_generator/src/main/java/annotation_processor/class_generator/GenClass.java:
--------------------------------------------------------------------------------
1 | package annotation_processor.class_generator;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.SOURCE)
9 | @Target(ElementType.TYPE)
10 | public @interface GenClass {
11 | String genClassName();
12 | }
13 |
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/class_generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor:
--------------------------------------------------------------------------------
1 | annotation_processor.class_generator.ClassGeneratorAnnotationProcessor
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/text_file_generator/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//05_annotation_processor:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | java_plugin(
6 | name="annotation_processor",
7 | srcs = glob(["src/main/java/**/*.java"]),
8 | processor_class = "annotation_processor.text_file_generator.TextFileGeneratorAnnotationProcessor",
9 | resources = ["src/main/resources/META-INF/services/javax.annotation.processing.Processor"],
10 | )
11 |
12 | intellij_module(name="iml", iml_type="java-maven-style-with-resources")
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/text_file_generator/src/main/java/annotation_processor/text_file_generator/GenTextFile.java:
--------------------------------------------------------------------------------
1 | package annotation_processor.text_file_generator;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.SOURCE)
9 | @Target(ElementType.TYPE)
10 | public @interface GenTextFile {
11 | String genTextFileName();
12 | }
13 |
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/text_file_generator/src/main/java/annotation_processor/text_file_generator/TextFileGeneratorAnnotationProcessor.java:
--------------------------------------------------------------------------------
1 | package annotation_processor.text_file_generator;
2 |
3 | import javax.annotation.processing.AbstractProcessor;
4 | import javax.annotation.processing.RoundEnvironment;
5 | import javax.annotation.processing.SupportedAnnotationTypes;
6 | import javax.annotation.processing.SupportedSourceVersion;
7 | import javax.lang.model.SourceVersion;
8 | import javax.lang.model.element.Element;
9 | import javax.lang.model.element.Name;
10 | import javax.lang.model.element.TypeElement;
11 | import javax.tools.Diagnostic;
12 | import javax.tools.FileObject;
13 | import javax.tools.JavaFileObject;
14 | import javax.tools.StandardLocation;
15 | import java.io.IOException;
16 | import java.io.PrintWriter;
17 | import java.util.Set;
18 |
19 | import static java.lang.String.format;
20 |
21 | @SupportedSourceVersion(SourceVersion.RELEASE_8)
22 | @SupportedAnnotationTypes("annotation_processor.class_generator.GenClass")
23 | public class TextFileGeneratorAnnotationProcessor extends AbstractProcessor {
24 | @Override
25 | public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
26 | for (TypeElement annotation : annotations) {
27 | for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(annotation)) {
28 | GenTextFile genTextFileAnnotation = annotatedElement.getAnnotation(GenTextFile.class);
29 | if (genTextFileAnnotation == null) {
30 | continue;
31 | }
32 | String genTextFileName = genTextFileAnnotation.genTextFileName();
33 | Name annotatedClass = annotatedElement.getSimpleName();
34 | processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
35 | format("found GenTextFile annotation on class '%s', " +
36 | "generating text file '%s'", annotatedClass, genTextFileName));
37 | try {
38 | FileObject builderFile = processingEnv.getFiler().createResource(
39 | StandardLocation.SOURCE_OUTPUT,
40 | "text_files",
41 | genTextFileName);
42 | try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
43 | out.write(format("content of text file %s\n", genTextFileName));
44 | }
45 | } catch (IOException e) {
46 | throw new RuntimeException(e);
47 | }
48 | }
49 | }
50 | return false;
51 | }
52 | }
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/text_file_generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor:
--------------------------------------------------------------------------------
1 | annotation_processor.text_file_generator.TextFileGeneratorAnnotationProcessor
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/usage/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//05_annotation_processor/class_generator:annotation_processor",
12 | "//05_annotation_processor/text_file_generator:annotation_processor",
13 | ],
14 | )
15 |
16 | java_library(
17 | name="java_test_lib",
18 | srcs = glob(["src/test/java/**/*.java"]),
19 | deps=[
20 | ":java_lib",
21 |
22 | "//05_annotation_processor/class_generator:annotation_processor",
23 | "//05_annotation_processor/text_file_generator:annotation_processor",
24 | ] + JUNIT5_MINIMAL_DEPS,
25 | )
26 |
27 | junit5_all_in_package_test(
28 | name="java_tests",
29 | java_package="annotation_processor.usage",
30 | runtime_deps=[":java_test_lib"]
31 | )
32 |
33 | intellij_module(name="iml", iml_type="java-maven-style")
34 |
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/usage/src/main/java/annotation_processor/usage/Usage.java:
--------------------------------------------------------------------------------
1 | package annotation_processor.usage;
2 |
3 | import annotation_processor.class_generator.GenClass;
4 | import annotation_processor.text_file_generator.GenTextFile;
5 |
6 | @GenTextFile(genTextFileName = "this_is_a_text_file.txt")
7 | @GenClass(genClassName = "ThisIsAClassname")
8 | class Usage {
9 |
10 | }
--------------------------------------------------------------------------------
/scenarios/05_annotation_processor/usage/src/test/java/annotation_processor/usage/UsageTest.java:
--------------------------------------------------------------------------------
1 | package annotation_processor.usage;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import somepackage.ThisIsAClassname;
5 |
6 | import java.net.URL;
7 | import java.nio.file.Files;
8 | import java.nio.file.Paths;
9 |
10 | import static org.junit.jupiter.api.Assertions.assertEquals;
11 | import static org.junit.jupiter.api.Assertions.assertNotNull;
12 |
13 | public class UsageTest {
14 | @Test
15 | public void gen_class() {
16 | assertEquals(77, new ThisIsAClassname().foo);
17 | }
18 |
19 | @Test
20 | public void gen_text_file() throws Exception {
21 | // this test fails in the bazel test //... run,
22 | // but I'm not sure how to fix it. How do we get this_is_a_text_file.txt to be available via classloader?
23 | if (System.getenv().containsKey("TEST_WORKSPACE")) {
24 | return;
25 | }
26 |
27 | URL resource = getClass().getClassLoader().getResource("generated/text_files/this_is_a_text_file.txt");
28 | assertNotNull(resource);
29 | String content = new String(Files.readAllBytes(Paths.get(resource.toURI())));
30 | assertEquals("content of text file this_is_a_text_file.txt\n", content);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 |
5 | intellij_project(
6 | name="project_06",
7 | deps=["//06_protobuf_messages/usage:java_test_lib"],
8 | build_managed_label_matchlist=['{"label_name":"java_proto"}'],
9 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
10 | iml_types_file="//:iml_types.xml",
11 | project_root_filegroup="//:automatically_placed_intellij_project_files",
12 | project_root_filegroup_ignore_prefix="intellij_project_files",
13 | modules=[
14 | "//06_protobuf_messages/html_email:iml",
15 | "//06_protobuf_messages/plain_email:iml",
16 | "//06_protobuf_messages/usage:iml",
17 | ]
18 | )
19 |
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/README.txt:
--------------------------------------------------------------------------------
1 | Demonstration of use of protobuf bazel tasks,
2 | and how the generated code integrates with an
3 | intellij project.
4 |
5 | Messages only, no RPC.
6 |
7 |
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/html_email/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | proto_library(
6 | name = "proto",
7 | srcs = ["src/main/proto/html_email.proto"],
8 | deps = [
9 | "//06_protobuf_messages/plain_email:proto",
10 |
11 | # bring in "well known proto" descriptor.proto.
12 | # This was enabled only recently, via this PR: https://github.com/google/protobuf/pull/3594
13 | "@com_google_protobuf//:descriptor_proto"
14 | ],
15 | )
16 |
17 | java_proto_library(
18 | name = "java_proto",
19 | deps = [":proto"],
20 | )
21 |
22 | intellij_module(name="iml", iml_type="java-maven-style")
23 |
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/html_email/src/main/proto/html_email.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package html_email;
3 |
4 | // This example is also a demonstration of use of proto extensions.
5 | // As of this writing, there has only recently been a merge of this
6 | // fix, to make "well known protos" work:
7 | // https://github.com/google/protobuf/pull/3594
8 | // Which makes it so one can pull in well-known protos in a bazel build.
9 | // see https://github.com/google/protobuf/pull/3594/files
10 | import "google/protobuf/descriptor.proto";
11 |
12 | // see https://github.com/bazelbuild/bazel/issues/2039#issuecomment-258896609
13 | // "Protobuf import statements must be fully qualified, relative to the current
14 | // workspace (I believe), and relative to the importer workspace this is the
15 | // path to the importee."
16 | import "06_protobuf_messages/plain_email/src/main/proto/plain_email.proto";
17 |
18 | message SearchIndex {
19 | bool should_index = 1;
20 | }
21 |
22 | extend google.protobuf.FieldOptions {
23 | SearchIndex search_index = 50000;
24 | }
25 |
26 | message HtmlEmail {
27 | plain_email.PlainEmail plain_email = 1;
28 | string body_html = 2 [(search_index).should_index=true];
29 | }
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/plain_email/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | proto_library(
6 | name = "proto",
7 | srcs = ["src/main/proto/plain_email.proto"],
8 | )
9 |
10 | java_proto_library(
11 | name = "java_proto",
12 | deps = [":proto"],
13 | )
14 |
15 | intellij_module(name="iml", iml_type="java-maven-style")
16 |
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/plain_email/src/main/proto/plain_email.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package plain_email;
3 |
4 | message Identity {
5 | string name = 1;
6 | string email = 2;
7 | }
8 |
9 | message PlainEmail {
10 | Identity from = 1;
11 | Identity to = 2;
12 | string body_text = 3;
13 | }
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/usage/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 |
7 | java_library(
8 | name="java_lib",
9 | srcs = glob(["src/main/java/**/*.java"]),
10 | deps=[
11 | "//06_protobuf_messages/plain_email:java_proto",
12 | "//06_protobuf_messages/html_email:java_proto",
13 |
14 | "@com_google_protobuf//:protobuf_java",
15 | ],
16 | )
17 |
18 | java_library(
19 | name="java_test_lib",
20 | srcs = glob(["src/test/java/**/*.java"]),
21 | deps=[
22 | ":java_lib",
23 |
24 | "//06_protobuf_messages/plain_email:java_proto",
25 | "//06_protobuf_messages/html_email:java_proto",
26 |
27 | "@com_google_protobuf//:protobuf_java",
28 | ] + JUNIT5_MINIMAL_DEPS,
29 | )
30 |
31 | junit5_all_in_package_test(
32 | name="java_tests",
33 | java_package="protobuf_messages.usage",
34 | runtime_deps=[":java_test_lib"]
35 | )
36 |
37 | intellij_module(name="iml", iml_type="java-maven-style")
38 |
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/usage/src/main/java/protobuf_messages/usage/Usage.java:
--------------------------------------------------------------------------------
1 | package protobuf_messages.usage;
2 |
3 | import com.google.protobuf.DescriptorProtos;
4 | import com.google.protobuf.Descriptors;
5 | import html_email.HtmlEmailOuterClass.HtmlEmail;
6 | import plain_email.PlainEmailOuterClass.Identity;
7 | import plain_email.PlainEmailOuterClass.PlainEmail;
8 |
9 | import java.util.List;
10 |
11 | import static java.lang.String.format;
12 |
13 | class Usage {
14 | public PlainEmail makePlainEmail() {
15 | return PlainEmail.newBuilder()
16 | .setFrom(Identity.newBuilder()
17 | .setName("Mom")
18 | .setEmail("mom@example.com")
19 | .build())
20 | .setTo(Identity.newBuilder()
21 | .setName("Kid")
22 | .setEmail("kid@example.com")
23 | .build())
24 | .setBodyText("hi how are you doing today?")
25 | .build();
26 | }
27 |
28 | public HtmlEmail makeHtmlEmail() {
29 | PlainEmail plainEmail = makePlainEmail();
30 | return HtmlEmail.newBuilder()
31 | .setBodyHtml(format("%s", plainEmail.getBodyText()))
32 | .setPlainEmail(plainEmail)
33 | .build();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/scenarios/06_protobuf_messages/usage/src/test/java/protobuf_messages/usage/UsageTest.java:
--------------------------------------------------------------------------------
1 | package protobuf_messages.usage;
2 |
3 | import com.google.protobuf.Descriptors;
4 | import html_email.HtmlEmailOuterClass;
5 | import html_email.HtmlEmailOuterClass.HtmlEmail;
6 | import html_email.HtmlEmailOuterClass.SearchIndex;
7 | import org.junit.jupiter.api.Test;
8 | import plain_email.PlainEmailOuterClass.Identity;
9 | import plain_email.PlainEmailOuterClass.PlainEmail;
10 |
11 | import java.util.Map;
12 |
13 | import static org.junit.jupiter.api.Assertions.assertEquals;
14 |
15 | public class UsageTest {
16 | @Test
17 | public void plain_email() {
18 | assertEquals(PlainEmail.newBuilder()
19 | .setFrom(Identity.newBuilder()
20 | .setName("Mom")
21 | .setEmail("mom@example.com")
22 | .build())
23 | .setTo(Identity.newBuilder()
24 | .setName("Kid")
25 | .setEmail("kid@example.com")
26 | .build())
27 | .setBodyText("hi how are you doing today?")
28 | .build(),
29 | new Usage().makePlainEmail());
30 | }
31 |
32 | @Test
33 | public void html_email() {
34 | HtmlEmail actual = new Usage().makeHtmlEmail();
35 | assertEquals(HtmlEmail.newBuilder()
36 | .setBodyHtml("hi how are you doing today?")
37 | .setPlainEmail(PlainEmail.newBuilder()
38 | .setFrom(Identity.newBuilder()
39 | .setName("Mom")
40 | .setEmail("mom@example.com")
41 | .build())
42 | .setTo(Identity.newBuilder()
43 | .setName("Kid")
44 | .setEmail("kid@example.com")
45 | .build())
46 | .setBodyText("hi how are you doing today?")
47 | .build())
48 | .build(),
49 | actual);
50 |
51 | // demonstration of retrieval of an option
52 | Map.Entry optionEntry =
53 | actual.getDescriptorForType().findFieldByNumber(HtmlEmail.BODY_HTML_FIELD_NUMBER)
54 | .getOptions().getAllFieldsRaw().entrySet().iterator().next();
55 |
56 | assertEquals("search_index", optionEntry.getKey().getName());
57 | assertEquals(SearchIndex.newBuilder().setShouldIndex(true).build(), optionEntry.getValue());
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/scenarios/07_grpc/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")
4 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
5 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
6 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
7 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
8 |
9 | proto_library(
10 | name = "proto",
11 | srcs = [
12 | "src/main/proto/fortune.proto"
13 | ],
14 | deps = [
15 | "@com_google_protobuf//:descriptor_proto",
16 | ]
17 | )
18 |
19 | java_proto_library(
20 | name = "java_proto",
21 | deps = [":proto"],
22 | )
23 |
24 | # see https://groups.google.com/forum/#!topic/bazel-discuss/75DSeUTYBxE
25 | #
26 | # from https://github.com/grpc/grpc-java/issues/2756
27 | # Args:
28 | # name: (str) A unique name for this rule. Required.
29 | # srcs: (list) a single proto_library target that contains the schema of the
30 | # service. Required.
31 | # deps: (list) a single java_proto_library target for the proto_library in
32 | # srcs. Required.
33 | # flavor: (str) "normal" (default) for normal proto runtime. "lite"
34 | # for the lite runtime.
35 | # visibility: (list) the visibility list
36 | java_grpc_library(
37 | name = "java_grpc",
38 | deps = [":java_proto"],
39 | srcs = [
40 | ":proto",
41 | ],
42 | )
43 |
44 | java_library(
45 | name="java_lib",
46 | srcs = glob(["src/main/java/**/*.java"]),
47 | deps = [
48 | ":java_proto",
49 | ":java_grpc",
50 |
51 | "@io_grpc_grpc_java//stub",
52 | "@com_google_protobuf//:protobuf_java",
53 | ]
54 | )
55 |
56 | java_library(
57 | name="java_test_lib",
58 | srcs = glob(["src/test/java/**/*.java"]),
59 | deps=[
60 | ":java_lib",
61 | ":java_proto",
62 |
63 | "@io_grpc_grpc_java//stub",
64 | "@com_google_protobuf//:protobuf_java",
65 | ] + JUNIT5_MINIMAL_DEPS,
66 | )
67 |
68 | junit5_all_in_package_test(
69 | name="java_tests",
70 | java_package="fortune_grpc",
71 | runtime_deps=[":java_test_lib"]
72 | )
73 |
74 | intellij_module(name="iml", iml_type="java-maven-style")
75 |
76 | intellij_project(
77 | name="project_07",
78 | deps=[":java_test_lib"],
79 | build_managed_label_matchlist=['{"label_name":"java_proto"}', '{"label_name":"java_grpc"}'],
80 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
81 | iml_types_file="//:iml_types.xml",
82 | project_root_filegroup="//:automatically_placed_intellij_project_files",
83 | project_root_filegroup_ignore_prefix="intellij_project_files",
84 | modules=[":iml"]
85 | )
86 |
--------------------------------------------------------------------------------
/scenarios/07_grpc/README.txt:
--------------------------------------------------------------------------------
1 | Demonstration of generation of grpc stubs.
2 |
3 | Builds on the protobuf scenario.
4 |
--------------------------------------------------------------------------------
/scenarios/07_grpc/src/main/java/fortune_grpc/FortuneService.java:
--------------------------------------------------------------------------------
1 | package fortune_grpc;
2 |
3 | import fortune.Fortune.GetFortuneRequest;
4 | import fortune.Fortune.GetFortuneResponse;
5 | import fortune.FortuneServiceGrpc.FortuneServiceImplBase;
6 | import io.grpc.stub.StreamObserver;
7 |
8 | import java.util.LinkedHashMap;
9 | import java.util.Map;
10 |
11 | import static java.lang.String.format;
12 |
13 | public class FortuneService extends FortuneServiceImplBase {
14 | private static Map FORTUNE_NUMBER_TO_MESSAGE =
15 | new LinkedHashMap() {{
16 | put(0, "You laugh now, wait till you get home.");
17 | put(1, "Wouldn't it be ironic...to die in the living room?");
18 | put(2, "About time I got out of that cookie.");
19 | put(3, "Your resemblance to a muppet will prevent the world from taking you seriously.");
20 | put(4, "You will be hungry again in one hour.");
21 | put(5, "run.");
22 | }};
23 |
24 | @Override
25 | public void getFortune(GetFortuneRequest request, StreamObserver responseObserver) {
26 | if (!FORTUNE_NUMBER_TO_MESSAGE.containsKey(request.getFortuneNumber())) {
27 | throw new IllegalStateException(format("invalid fortune number: %s", request.getFortuneNumber()));
28 | }
29 |
30 | responseObserver.onNext(
31 | GetFortuneResponse.newBuilder()
32 | .setFortuneContent(FORTUNE_NUMBER_TO_MESSAGE.get(request.getFortuneNumber()))
33 | .build()
34 | );
35 | responseObserver.onCompleted();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/scenarios/07_grpc/src/main/proto/fortune.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package fortune;
3 |
4 | import "google/protobuf/descriptor.proto";
5 |
6 | message GetFortuneRequest {
7 | int32 fortune_number = 1;
8 | }
9 |
10 | message Truth {
11 | bool is_the_fortune_actually_real = 1;
12 | }
13 |
14 | extend google.protobuf.FieldOptions {
15 | Truth the_truth = 50000;
16 | }
17 |
18 | message GetFortuneResponse {
19 | string fortune_content = 1 [(the_truth).is_the_fortune_actually_real=true];
20 | }
21 |
22 | service FortuneService {
23 | rpc GetFortune (GetFortuneRequest) returns (GetFortuneResponse) {}
24 | }
--------------------------------------------------------------------------------
/scenarios/07_grpc/src/test/java/fortune_grpc/FortuneServiceTest.java:
--------------------------------------------------------------------------------
1 | package fortune_grpc;
2 |
3 | import com.google.protobuf.Descriptors;
4 | import fortune.Fortune;
5 | import fortune.Fortune.GetFortuneRequest;
6 | import fortune.Fortune.GetFortuneResponse;
7 | import io.grpc.stub.StreamObserver;
8 | import org.junit.jupiter.api.Test;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | import static java.util.Arrays.asList;
15 | import static java.util.stream.Collectors.toList;
16 | import static org.junit.jupiter.api.Assertions.assertEquals;
17 |
18 | public class FortuneServiceTest {
19 | @Test
20 | public void get_fortune() {
21 | List results = new ArrayList<>();
22 | FortuneService fortuneService = new FortuneService();
23 |
24 | FakeStreamObserver responseObserver = new FakeStreamObserver<>();
25 | fortuneService.getFortune(GetFortuneRequest.newBuilder()
26 | .setFortuneNumber(4)
27 | .build(),
28 | responseObserver);
29 |
30 | assertEquals(
31 | asList("You will be hungry again in one hour."),
32 | responseObserver.results.stream().map(GetFortuneResponse::getFortuneContent).collect(toList()));
33 |
34 |
35 | GetFortuneResponse actual = responseObserver.results.get(0);
36 | // demonstration of retrieval of an option
37 | Map.Entry optionEntry =
38 | actual.getDescriptorForType().findFieldByNumber(Fortune.Truth.IS_THE_FORTUNE_ACTUALLY_REAL_FIELD_NUMBER)
39 | .getOptions().getAllFieldsRaw().entrySet().iterator().next();
40 |
41 | assertEquals("the_truth", optionEntry.getKey().getName());
42 | assertEquals(Fortune.Truth.newBuilder().setIsTheFortuneActuallyReal(true).build(), optionEntry.getValue());
43 | }
44 |
45 | class FakeStreamObserver implements StreamObserver {
46 | public List results = new ArrayList<>();
47 |
48 | @Override
49 | public void onNext(T value) {
50 | results.add(value);
51 | }
52 |
53 | @Override
54 | public void onError(Throwable t) {
55 | throw new UnsupportedOperationException();
56 | }
57 |
58 | @Override
59 | public void onCompleted() {
60 | // no-op
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/scenarios/08_auto_value/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
5 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
6 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
7 |
8 | # see https://www.kchodorow.com/blog/2016/11/12/using-autovalue-with-bazel/
9 | java_plugin(
10 | name = "autovalue_plugin",
11 | generates_api = 1,
12 | processor_class = "com.google.auto.value.processor.AutoValueProcessor",
13 | deps = ["@com_google_auto_value//jar"],
14 | )
15 |
16 | java_library(
17 | name="java_lib",
18 | srcs = glob(["src/main/java/**/*.java"]),
19 | deps=[
20 | ":autovalue_plugin",
21 |
22 | "@com_google_auto_value//jar",
23 | ],
24 | )
25 |
26 | java_library(
27 | name="java_test_lib",
28 | srcs = glob(["src/test/java/**/*.java"]),
29 | deps=[":java_lib"] + JUNIT5_MINIMAL_DEPS,
30 | )
31 |
32 | junit5_all_in_package_test(
33 | name="java_tests",
34 | java_package="house",
35 | runtime_deps=[":java_test_lib"]
36 | )
37 |
38 | intellij_module(name="iml", iml_type="java-maven-style")
39 |
40 | intellij_project(
41 | name="project_08",
42 | deps=[":java_test_lib"],
43 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
44 | iml_types_file="//:iml_types.xml",
45 | project_root_filegroup="//:automatically_placed_intellij_project_files",
46 | project_root_filegroup_ignore_prefix="intellij_project_files",
47 | modules=[":iml"]
48 | )
49 |
--------------------------------------------------------------------------------
/scenarios/08_auto_value/README.txt:
--------------------------------------------------------------------------------
1 | Demonstration of use of auto value, which uses annotation processing.
2 |
--------------------------------------------------------------------------------
/scenarios/08_auto_value/src/main/java/house/House.java:
--------------------------------------------------------------------------------
1 | package house;
2 |
3 | import com.google.auto.value.AutoValue;
4 |
5 | @AutoValue
6 | public abstract class House {
7 | public abstract String color();
8 | public abstract int floors();
9 |
10 | public static House.Builder builder() {
11 | return new AutoValue_House.Builder();
12 | }
13 |
14 | @AutoValue.Builder
15 | public abstract static class Builder {
16 | public abstract House.Builder setColor(String color);
17 | public abstract House.Builder setFloors(int numFloors);
18 |
19 | public abstract House build();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/scenarios/08_auto_value/src/test/java/house/HouseTest.java:
--------------------------------------------------------------------------------
1 | package house;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 |
7 | public class HouseTest {
8 | @Test
9 | public void build_it() {
10 | House house = House.builder().setColor("red").setFloors(3).build();
11 | assertEquals("red", house.color());
12 | assertEquals(3, house.floors());
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/scenarios/09_python/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
5 |
6 | py_library(
7 | name = "py_lib",
8 | srcs = ["src/echo.py"],
9 | )
10 |
11 | py_library(
12 | name = "py_test_lib",
13 | srcs = ["test/echo_test.py"],
14 | deps = [":py_lib"],
15 | )
16 |
17 | py_test(
18 | name = "echo_test",
19 | srcs = ["test/echo_test.py"],
20 | deps = [":py_lib"],
21 | )
22 |
23 | intellij_module(name="iml", iml_type="python-simple")
24 |
25 | intellij_project(
26 | name="project_09",
27 | deps=[":py_test_lib"],
28 | iml_types_file="//:iml_types.xml",
29 | project_root_filegroup="//:automatically_placed_intellij_project_files",
30 | project_root_filegroup_ignore_prefix="intellij_project_files",
31 | modules=[":iml"]
32 | )
33 |
--------------------------------------------------------------------------------
/scenarios/09_python/README.txt:
--------------------------------------------------------------------------------
1 | A simple python project. The iml must contain a "python facet"
2 | in order to take advantage of pycharm Intellij features.
3 |
--------------------------------------------------------------------------------
/scenarios/09_python/src/echo.py:
--------------------------------------------------------------------------------
1 | def echo(x):
2 | return "echoing: %s" % x
3 |
--------------------------------------------------------------------------------
/scenarios/09_python/test/echo_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | import sys, os
4 | sys.path.append(os.path.join(os.path.dirname(__file__), '../src'))
5 |
6 | from echo import echo
7 |
8 | class EchoTest(unittest.TestCase):
9 | def test_echo(self):
10 | self.assertEqual("echoing: yy", echo ("yy"))
--------------------------------------------------------------------------------
/scenarios/12_kotlin/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 |
5 | intellij_project(
6 | name="project_12",
7 | deps=[
8 | "//12_kotlin/child:kt_test_lib",
9 | "//12_kotlin/parent:kt_test_lib"
10 | ],
11 | test_lib_label_matchlist=['{"label_name":"kt_test_lib"}'],
12 | iml_types_file="//:iml_types.xml",
13 | project_root_filegroup="//:automatically_placed_intellij_project_files",
14 | project_root_filegroup_ignore_prefix="intellij_project_files",
15 | modules=[
16 | "//12_kotlin/child:iml",
17 | "//12_kotlin/parent:iml",
18 | ]
19 | )
20 |
--------------------------------------------------------------------------------
/scenarios/12_kotlin/README.txt:
--------------------------------------------------------------------------------
1 | Demonstration of kotlin, making use of rules_kotlin.
2 |
3 | This is more or less like a plain java example, but
4 | with these special rules, and the Kotlin facet in
5 | iml files.
6 |
--------------------------------------------------------------------------------
/scenarios/12_kotlin/child/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 | load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
7 |
8 | kt_jvm_library(
9 | name = "kt_lib",
10 | srcs = glob(["src/**/*.kt"]),
11 | deps=[
12 | "//12_kotlin/parent:kt_lib",
13 | ]
14 | )
15 |
16 | kt_jvm_library(
17 | name="kt_test_lib",
18 | srcs = glob(["test/**/*.kt"]),
19 | deps=[
20 | ":kt_lib",
21 | ] + JUNIT5_MINIMAL_DEPS,
22 | )
23 |
24 | junit5_all_in_package_test(
25 | name="kt_tests",
26 | java_package="kotlin_example",
27 | runtime_deps=[":kt_test_lib"]
28 | )
29 |
30 | intellij_module(name="iml", iml_type="kotlin-simple")
--------------------------------------------------------------------------------
/scenarios/12_kotlin/child/src/kotlin_example/child/Child.kt:
--------------------------------------------------------------------------------
1 | package kotlin_example.child
2 |
3 | import kotlin_example.parent.Parent
4 | import java.lang.String.format
5 |
6 | class Child {
7 | fun sayHello(): String {
8 | return "hello"
9 | }
10 |
11 | fun sayHelloAndLa(): String {
12 | return sayHello() + Parent().la4times()
13 | }
14 | }
--------------------------------------------------------------------------------
/scenarios/12_kotlin/child/test/kotlin_example/child/ChildTest.kt:
--------------------------------------------------------------------------------
1 | package kotlin_example.child
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 |
6 | class ChildTest {
7 | @Test
8 | fun `say hello`() {
9 | assertEquals("hello", Child().sayHello())
10 | }
11 |
12 | @Test
13 | fun `say hello and la 4 times`() {
14 | assertEquals("hellolalalala", Child().sayHelloAndLa())
15 | }
16 | }
--------------------------------------------------------------------------------
/scenarios/12_kotlin/parent/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
6 | load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
7 |
8 | kt_jvm_library(
9 | name = "kt_lib",
10 | srcs = glob(["src/**/*.kt"]),
11 | deps = [
12 | "@com_google_guava_guava//jar",
13 | ]
14 | )
15 |
16 | kt_jvm_library(
17 | name="kt_test_lib",
18 | srcs = glob(["test/**/*.kt"]),
19 | deps=[
20 | ":kt_lib",
21 | ] + JUNIT5_MINIMAL_DEPS,
22 | )
23 |
24 | junit5_all_in_package_test(
25 | name="kt_tests",
26 | java_package="kotlin_example",
27 | runtime_deps=[":kt_test_lib"]
28 | )
29 |
30 | intellij_module(name="iml", iml_type="kotlin-simple")
--------------------------------------------------------------------------------
/scenarios/12_kotlin/parent/src/kotlin_example/parent/Parent.kt:
--------------------------------------------------------------------------------
1 | package kotlin_example.parent
2 |
3 | import com.google.common.base.Strings
4 |
5 | class Parent {
6 | fun la4times(): String {
7 | return Strings.repeat("la", 4)
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/scenarios/12_kotlin/parent/test/kotlin_example/parent/ParentTest.kt:
--------------------------------------------------------------------------------
1 | package kotlin_example.parent
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 |
6 | class ParentTest {
7 | @Test
8 | fun `la 4 times`() {
9 | assertEquals("lalalala", Parent().la4times())
10 | }
11 | }
--------------------------------------------------------------------------------
/scenarios/13_minor_features/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_junit5//:def.bzl", "JUNIT5_MINIMAL_DEPS")
4 | load("@rules_junit5//:def.bzl", "junit5_all_in_package_test")
5 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
6 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
7 |
8 | java_library(
9 | name="java_lib",
10 | srcs = glob(["src/**/*.java"]),
11 | )
12 |
13 | java_library(
14 | name="java_test_lib",
15 | srcs = glob(["test/**/*.java"]),
16 | deps=[":java_lib"] + JUNIT5_MINIMAL_DEPS,
17 | )
18 |
19 | junit5_all_in_package_test(
20 | name="java_tests",
21 | java_package="minor_features",
22 | runtime_deps=[":java_test_lib"]
23 | )
24 |
25 | filegroup(
26 | name="automatically_placed_intellij_project_files",
27 | srcs=glob(["intellij_project_files/**/*.xml"])
28 | )
29 |
30 | intellij_module(name="iml", iml_type="java-simple2", module_name_override="13_mymodulename")
31 |
32 | intellij_project(
33 | name="project_13",
34 | bazelexec="my-bazel-script",
35 | deps=[":java_test_lib"],
36 | test_lib_label_matchlist=['{"label_name":"java_test_lib"}'],
37 | custom_substitutions={
38 | "MY_BICYCLE_COLOR": "red",
39 | "SOME_FILE": "$(location :some_file.txt)"
40 | },
41 | iml_types_file=":iml_types.xml",
42 | project_root_filegroup=":automatically_placed_intellij_project_files",
43 | project_root_filegroup_ignore_prefix="13_minor_features/intellij_project_files",
44 | modules=[":iml"],
45 | tools=[":some_file.txt"],
46 | )
47 |
--------------------------------------------------------------------------------
/scenarios/13_minor_features/README.txt:
--------------------------------------------------------------------------------
1 | This scenario demonstrates minor features:
2 | - module name overriding
3 | - custom substitutions
4 | - default substitutions (e.g. bazel package)
5 |
--------------------------------------------------------------------------------
/scenarios/13_minor_features/iml_types.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/scenarios/13_minor_features/intellij_project_files/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/scenarios/13_minor_features/some_file.txt:
--------------------------------------------------------------------------------
1 | which has this content
2 |
--------------------------------------------------------------------------------
/scenarios/13_minor_features/src/minor_features/B.java:
--------------------------------------------------------------------------------
1 | package minor_features;
2 |
3 | class B {
4 | public int theNumber() {
5 | return 77;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/scenarios/13_minor_features/test/minor_features/BTest.java:
--------------------------------------------------------------------------------
1 | package minor_features;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertEquals;
6 |
7 | public class BTest {
8 | @Test
9 | public void the_number() {
10 | assertEquals(77, new B().theNumber());
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 | intellij_project(
5 | name="project_14",
6 | deps=[
7 | "//14_all_dependency_types/child_data:child_data",
8 | "//14_all_dependency_types/child_dep:child_dep",
9 | "//14_all_dependency_types/child_src:child_src",
10 |
11 | "//14_all_dependency_types/child2_custom:from_child2",
12 | "//14_all_dependency_types/parent2_custom:lib",
13 | ],
14 | iml_types_file="//:iml_types.xml",
15 | project_root_filegroup="//:automatically_placed_intellij_project_files",
16 | project_root_filegroup_ignore_prefix="intellij_project_files",
17 | modules=[
18 | "//14_all_dependency_types/child_data:iml",
19 | "//14_all_dependency_types/child_dep:iml",
20 | "//14_all_dependency_types/child_src:iml",
21 | "//14_all_dependency_types/parent:iml",
22 |
23 | "//14_all_dependency_types/child2_custom:iml",
24 | "//14_all_dependency_types/parent2_custom:iml",
25 | ],
26 | module_dependency_matchlist = [
27 | '{"attr":"data"}',
28 | '{"attr":"deps"}',
29 | '{"attr":"srcs"}',
30 |
31 | '{"attr":"gorps"}',
32 | ],
33 | )
34 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/README.txt:
--------------------------------------------------------------------------------
1 | A package relationship established by any of the three types of dependencies:
2 | data,
3 | deps,
4 | srcs
5 | Will result in the intellij integration determining that there exists a dependency relationship
6 | among the intellij modules that correspond to the bazel packages in question.
7 |
8 | https://docs.bazel.build/versions/master/build-ref.html#types_of_dependencies
9 |
10 | This also demonstrates how the "depdendency attrs" may be changed / customized.
11 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/child2_custom/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 | load("//14_all_dependency_types:custom2.bzl", "custom2")
5 |
6 | custom2(
7 | name = "from_child2",
8 | gorps = ["//14_all_dependency_types/parent2_custom:lib"]
9 | )
10 |
11 | intellij_module(name="iml", iml_type="java-simple")
12 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/child_data/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | sh_library(
6 | name = "child_data",
7 | data = ["//14_all_dependency_types/parent:parent.txt"],
8 | )
9 |
10 | intellij_module(name="iml", iml_type="java-simple")
11 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/child_dep/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | sh_library(
6 | name = "child_dep",
7 | deps = ["//14_all_dependency_types/parent:parent"],
8 | )
9 |
10 | intellij_module(name="iml", iml_type="java-simple")
11 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/child_src/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | sh_library(
6 | name = "child_src",
7 | srcs = ["//14_all_dependency_types/parent:parent.sh"]
8 | )
9 |
10 | intellij_module(name="iml", iml_type="java-simple")
11 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/child_src/child.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | echo "hi, i'm the child."
4 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/custom2.bzl:
--------------------------------------------------------------------------------
1 | def _impl(ctx):
2 | pass
3 |
4 | custom2 = rule(
5 | implementation = _impl,
6 | attrs = {
7 | "gorps": attr.label_list(),
8 | },
9 | outputs={},
10 | )
11 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/parent/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | sh_library(
6 | name = "parent",
7 | srcs = ["parent.sh"],
8 | data = ["parent.txt"],
9 | )
10 |
11 | intellij_module(name="iml", iml_type="java-simple")
12 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/parent/parent.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | echo "hi, i'm the parent. btw there's nothing java-related about this at all."
4 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/parent/parent.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sconover/rules_intellij_generate/f738a6306637b72a04ff80a0dfd9e70980bb08c1/scenarios/14_all_dependency_types/parent/parent.txt
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/parent2_custom/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
4 |
5 | sh_library(
6 | name = "lib",
7 | srcs = ["parent2.sh"],
8 | )
9 |
10 | intellij_module(name="iml", iml_type="java-simple")
11 |
--------------------------------------------------------------------------------
/scenarios/14_all_dependency_types/parent2_custom/parent2.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | echo "hi, i'm the parent. btw there's nothing java-related about this at all."
4 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_intellij_generate//:def.bzl", "intellij_project")
4 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
5 |
6 | exports_files(["tsconfig.json", "run_single_mocha_test.sh"])
7 |
8 | intellij_module(name="iml", iml_type="web-simple")
9 |
10 | filegroup(
11 | name="automatically_placed_intellij_project_files_for_ts",
12 | srcs=glob(["intellij_project_files/**/*.xml"])
13 | )
14 |
15 | filegroup(
16 | name="workspace_xml_fragments",
17 | srcs=glob(["workspace_xml_fragments/*.xml"])
18 | )
19 |
20 | intellij_project(
21 | name="project_10",
22 | iml_types_file="//:iml_types.xml",
23 | project_root_filegroup=":automatically_placed_intellij_project_files_for_ts",
24 | project_root_filegroup_ignore_prefix="15_typescript_rules_multi_tsc/intellij_project_files",
25 | workspace_xml_fragments_filegroup=":workspace_xml_fragments",
26 | deps=[
27 | "//15_typescript_rules_multi_tsc/long-gen:tsc",
28 | "//15_typescript_rules_multi_tsc/print-timestamp:tsc",
29 | ],
30 | modules=[
31 | ":iml",
32 | "//15_typescript_rules_multi_tsc/long-gen:iml",
33 | "//15_typescript_rules_multi_tsc/print-timestamp:iml",
34 | ],
35 | symlinks={
36 | "${BAZEL_INFO_EXECUTION_ROOT}/external/node_modules_15_typescript_rules_multi_tsc/node_modules": "15_typescript_rules_multi_tsc/node_modules",
37 | "${BAZEL_INFO_EXECUTION_ROOT}/external/node_modules_15_typescript_rules_multi_tsc/package.json": "15_typescript_rules_multi_tsc/package.json",
38 | "${BAZEL_INFO_EXECUTION_ROOT}/external/node_modules_15_typescript_rules_multi_tsc/package-lock.json": "15_typescript_rules_multi_tsc/package-lock.json",
39 | },
40 | )
41 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/deps/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-rules-multi-tsc-example",
3 | "version": "0.0.0",
4 | "scripts": {},
5 | "private": true,
6 | "dependencies": {
7 | "long": "4.0.0",
8 | "bson": "4.0.1",
9 | "buffer": "5.2.1"
10 | },
11 | "devDependencies": {
12 | "@types/mocha": "5.2.5",
13 | "@types/chai": "4.1.7",
14 | "mocha": "5.2.0",
15 | "chai": "4.1.0",
16 | "typescript": "3.2.2",
17 | "ts-node": "7.0.1",
18 | "@types/long": "4.0.0",
19 | "@types/bson": "1.0.11",
20 | "rollup": "0.67.4",
21 | "rollup-plugin-alias": "1.5.1",
22 | "rollup-plugin-node-resolve": "3.4.0",
23 | "rollup-plugin-commonjs": "9.2.0",
24 | "rollup-plugin-includepaths": "0.2.3",
25 | "uglify-es": "3.3.9",
26 | "tsconfig-paths": "3.7.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/intellij_project_files/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/intellij_project_files/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/long-gen/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_multi_tsc//:def.bzl", "tsc")
4 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
5 |
6 | tsc(
7 | name="tsc",
8 | ts_path="lgen",
9 | srcs=glob(["src/*.ts"]),
10 | deps=[
11 | "@node_modules_15_typescript_rules_multi_tsc//:default_typings",
12 | ],
13 |
14 | node_executable="@node//:bin/node",
15 | tsc_script="@node_modules_15_typescript_rules_multi_tsc//:node_modules/typescript/lib/tsc.js",
16 | tsconfig_json="//15_typescript_rules_multi_tsc:tsconfig.json",
17 | )
18 |
19 | filegroup(name = "src_file", srcs = ["src/long-gen.ts"])
20 | filegroup(name = "test_file", srcs = ["test/long-gen-test.ts"])
21 |
22 | sh_library(
23 | name = "ts_lib",
24 | srcs = [":src_file"],
25 | data = [
26 | "@node//:bin/node",
27 | "@node_modules_15_typescript_rules_multi_tsc//:all_files",
28 | ":src_file",
29 | ],
30 | )
31 |
32 | sh_test(
33 | name = "ts_test",
34 | srcs = ["//15_typescript_rules_multi_tsc:run_single_mocha_test.sh"],
35 | deps = [":ts_lib"],
36 | args = [
37 | "external/node_modules_15_typescript_rules_multi_tsc/node_modules",
38 | "$(location @node//:bin/node)",
39 | "$(location //15_typescript_rules_multi_tsc:tsconfig.json)",
40 | "$(location @node_modules_15_typescript_rules_multi_tsc//:node_modules/mocha/bin/mocha)",
41 | "$(location :test_file)"
42 | ],
43 | data = [
44 | "@node//:bin/node",
45 | "//15_typescript_rules_multi_tsc:tsconfig.json",
46 | "@node_modules_15_typescript_rules_multi_tsc//:all_files",
47 | "@node_modules_15_typescript_rules_multi_tsc//:node_modules/mocha/bin/mocha",
48 | ":src_file",
49 | ":test_file",
50 | ],
51 | )
52 |
53 | intellij_module(name="iml", iml_type="web-simple")
54 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/long-gen/src/long-gen.ts:
--------------------------------------------------------------------------------
1 | import * as Long from "long"
2 |
3 | export function longGen(): Long {
4 | return new Long(77777)
5 | }
6 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/long-gen/test/long-gen-test.ts:
--------------------------------------------------------------------------------
1 | import * as Long from "long"
2 | import {longGen} from "lgen/long-gen"
3 | import {assert} from "chai"
4 | import "mocha" // this MUST be imported or ts compilation will fail because mocha won't be aware of the mocha types
5 |
6 | suite("long-gen suite", () => {
7 | test("long-gen returns a long with 7's", () => {
8 | assert.deepEqual(longGen(), new Long(77777))
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/package-lock.json:
--------------------------------------------------------------------------------
1 | /private/var/tmp/_bazel_sc/db911cb03fe700319ffc76f57730fb32/execroot/rules_intellij_generate_scenarios/external/node_modules_15_typescript_rules_multi_tsc/package-lock.json
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/package.json:
--------------------------------------------------------------------------------
1 | /private/var/tmp/_bazel_sc/db911cb03fe700319ffc76f57730fb32/execroot/rules_intellij_generate_scenarios/external/node_modules_15_typescript_rules_multi_tsc/package.json
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/print-timestamp/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | load("@rules_multi_tsc//:def.bzl", "tsc")
4 | load("@rules_intellij_generate//:def.bzl", "intellij_module")
5 |
6 | tsc(
7 | name="tsc",
8 | srcs=glob(["src/*.ts"]),
9 | deps=[
10 | "@node_modules_15_typescript_rules_multi_tsc//:default_typings",
11 | "//15_typescript_rules_multi_tsc/long-gen:tsc",
12 | ],
13 |
14 | node_executable="@node//:bin/node",
15 | tsc_script="@node_modules_15_typescript_rules_multi_tsc//:node_modules/typescript/lib/tsc.js",
16 | tsconfig_json="//15_typescript_rules_multi_tsc:tsconfig.json",
17 | )
18 |
19 | intellij_module(name="iml", iml_type="web-simple")
20 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/print-timestamp/src/print-timestamp.ts:
--------------------------------------------------------------------------------
1 | import {longGen} from "lgen/long-gen"
2 | import {Timestamp} from "bson"
3 |
4 | export function printTimestamp() {
5 | const l = longGen()
6 | const t = Timestamp.fromBits(l.low, l.high)
7 | console.log(t)
8 | }
9 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/run_single_mocha_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | node_path=$1
4 | node_js=$2
5 | tsconfig_json_path=$3
6 | mocha_bin=$4
7 | test_path=$5
8 |
9 | # see https://github.com/TypeStrong/ts-node/issues/561#issuecomment-375836931
10 | # ..and https://www.sitepoint.com/community/t/ts-node-how-to-use-tsconfig-paths-with-node-modules/300468/6
11 |
12 | exec env NODE_PATH=$node_path TS_NODE_PROJECT=$tsconfig_json_path $node_js $mocha_bin --ui tdd --require ts-node/register --require tsconfig-paths/register $test_path
13 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2015",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "lib": [
10 | "es2015",
11 | "dom"
12 | ],
13 | "noImplicitAny": true,
14 | "suppressImplicitAnyIndexErrors": true,
15 | "outDir": "../whatever",
16 | "baseUrl": ".",
17 | "skipDefaultLibCheck": true,
18 | "allowSyntheticDefaultImports": true,
19 | "paths": {
20 | "lgen/*": [
21 | "long-gen/src/*"
22 | ]
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/scenarios/15_typescript_rules_multi_tsc/workspace_xml_fragments/workspace.RunManager.fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | project
35 |
36 |
37 | true
38 |
39 |
40 |
42 |
43 |
44 | tdd
45 | --require ts-node/register --require tsconfig-paths/register
46 | DIRECTORY
47 |
48 | false
49 |
50 |
51 |
--------------------------------------------------------------------------------
/scenarios/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//:__subpackages__"])
2 |
3 | exports_files(["iml_types.xml"])
4 |
5 | filegroup(
6 | name="automatically_placed_intellij_project_files",
7 | srcs=glob(["intellij_project_files/**/*.xml"])
8 | )
9 |
10 |
--------------------------------------------------------------------------------
/scenarios/WORKSPACE:
--------------------------------------------------------------------------------
1 | workspace(name="rules_intellij_generate_scenarios")
2 |
3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
4 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
5 |
6 | maven_jar(name="com_google_guava_guava", artifact="com.google.guava:guava:19.0")
7 | maven_jar(name="com_google_auto_value", artifact="com.google.auto.value:auto-value:1.5.2")
8 |
9 | local_repository(
10 | name = "rules_intellij_generate",
11 | path = "../rules",
12 | )
13 |
14 | rules_junit5_sha = "e86a061d86ccb695f705d32c70804f9dc2f4d760"
15 | http_archive(
16 | name = "rules_junit5",
17 | url = "https://github.com/sconover/rules_junit5/archive/%s.tar.gz" % rules_junit5_sha,
18 | strip_prefix = "rules_junit5-%s" % rules_junit5_sha,
19 | )
20 | load("@rules_junit5//:def.bzl", "junit5_repositories")
21 | junit5_repositories()
22 |
23 |
24 | http_archive(
25 | name = "com_google_protobuf",
26 | strip_prefix = "protobuf-3.11.0",
27 | urls = ["https://github.com/protocolbuffers/protobuf/archive/v3.11.0.tar.gz"],
28 | )
29 | http_archive(
30 | name = "com_google_protobuf_javalite",
31 | strip_prefix = "protobuf-javalite",
32 | urls = ["https://github.com/google/protobuf/archive/javalite.zip"],
33 | )
34 |
35 | http_archive(
36 | name = "io_grpc_grpc_java",
37 | urls = ["https://github.com/grpc/grpc-java/archive/fd7d2e5eb4dd020bb892278c78f7b3ef901232c1.zip"],
38 | strip_prefix = "grpc-java-fd7d2e5eb4dd020bb892278c78f7b3ef901232c1",
39 | )
40 | load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
41 | grpc_java_repositories(
42 | omit_com_google_guava=True,
43 | omit_com_google_protobuf=True,
44 | omit_com_google_protobuf_javalite=True,
45 | )
46 |
47 | # see https://github.com/bazelbuild/rules_nodejs
48 |
49 | # rules_nodejs depends on bazel_skylib
50 | # Bazel doesn't support transitive workspace deps so you must copy this.
51 | http_archive(
52 | name = "bazel_skylib",
53 | url = "https://github.com/bazelbuild/bazel-skylib/archive/0.3.1.zip",
54 | strip_prefix = "bazel-skylib-0.3.1",
55 | sha256 = "95518adafc9a2b656667bbf517a952e54ce7f350779d0dd95133db4eb5c27fb1",
56 | )
57 |
58 | git_repository(
59 | name = "build_bazel_rules_nodejs",
60 | remote = "https://github.com/bazelbuild/rules_nodejs.git",
61 | tag = "0.27.12", # 2019-04-09. check for the latest tag when you install
62 | )
63 |
64 | load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
65 | load("@build_bazel_rules_nodejs//:defs.bzl", "npm_install")
66 |
67 |
68 | # for all js/ts-related examples
69 | http_archive(
70 | name = "node",
71 | url = "https://nodejs.org/dist/v10.14.2/node-v10.14.2-darwin-x64.tar.gz",
72 | strip_prefix = "node-v10.14.2-darwin-x64",
73 | build_file_content="""
74 | exports_files([
75 | "bin/node",
76 | ])
77 | """
78 | )
79 |
80 | # 12_kotlin
81 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
82 |
83 | rules_kotlin_version = "legacy-1.3.0-rc3"
84 | rules_kotlin_sha = "54678552125753d9fc0a37736d140f1d2e69778d3e52cf454df41a913b964ede"
85 | http_archive(
86 | name = "io_bazel_rules_kotlin",
87 | urls = ["https://github.com/bazelbuild/rules_kotlin/archive/%s.zip" % rules_kotlin_version],
88 | type = "zip",
89 | strip_prefix = "rules_kotlin-%s" % rules_kotlin_version,
90 | sha256 = rules_kotlin_sha,
91 | )
92 |
93 | load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains")
94 | kotlin_repositories()
95 | kt_register_toolchains()
96 |
97 |
98 | # 15_typescript_rules_multi_tsc
99 | new_local_repository(
100 | name="node_modules_15_typescript_rules_multi_tsc",
101 | path="15_typescript_rules_multi_tsc/deps",
102 | build_file_content="""
103 | exports_files([
104 | "package.json",
105 | "package-lock.json",
106 | "node_modules/mocha/bin/mocha",
107 | "node_modules/typescript/lib/tsc.js",
108 | ])
109 |
110 | filegroup(
111 | name = "all_files",
112 | srcs = glob([
113 | "node_modules/**",
114 | ]),
115 | visibility = ["//visibility:public"],
116 | )
117 |
118 | filegroup(
119 | name = "default_typings",
120 | srcs = glob([
121 | "node_modules/@types/**",
122 | ]),
123 | visibility = ["//visibility:public"],
124 | )
125 | """
126 | )
127 |
128 | rules_multi_tsc_version = "b532865f32eff58338f6a9822adaa7d3142c845d"
129 |
130 | http_archive(
131 | name = "rules_multi_tsc",
132 | urls = ["https://github.com/sconover/rules_multi_tsc/archive/%s.zip" % rules_multi_tsc_version],
133 | type = "zip",
134 | strip_prefix = "rules_multi_tsc-%s/rules" % rules_multi_tsc_version
135 | )
136 |
137 | http_archive(
138 | name = "rules_python",
139 | sha256 = "e5470e92a18aa51830db99a4d9c492cc613761d5bdb7131c04bd92b9834380f6",
140 | strip_prefix = "rules_python-4b84ad270387a7c439ebdccfd530e2339601ef27",
141 | urls = ["https://github.com/bazelbuild/rules_python/archive/4b84ad270387a7c439ebdccfd530e2339601ef27.tar.gz"],
142 | )
143 |
144 | http_archive(
145 | name = "zlib",
146 | build_file = "@com_google_protobuf//:third_party/zlib.BUILD",
147 | sha256 = "629380c90a77b964d896ed37163f5c3a34f6e6d897311f1df2a7016355c45eff",
148 | strip_prefix = "zlib-1.2.11",
149 | urls = ["https://github.com/madler/zlib/archive/v1.2.11.tar.gz"],
150 | )
151 |
--------------------------------------------------------------------------------
/scenarios/iml_types.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/scenarios/intellij_project_files/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/scenarios/intellij_project_files/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/BUILD:
--------------------------------------------------------------------------------
1 | package(default_visibility = ["//scenario_tests:__subpackages__"])
2 |
3 | py_test(
4 | name = "py_tests",
5 | srcs = glob(["pytest/**/*.py"]),
6 | main = "all_tests.py",
7 | data=[
8 | "//01_one_class:intellij_files",
9 | "//02_one_class_and_one_test:intellij_files",
10 | "//03_basic:intellij_files",
11 | "//04_transitive_via_export:intellij_files",
12 | "//05_annotation_processor:intellij_files",
13 | "//06_protobuf_messages:intellij_files",
14 | "//07_grpc:intellij_files",
15 | "//08_auto_value:intellij_files",
16 | "//09_python:intellij_files",
17 | "//12_kotlin:intellij_files",
18 | "//13_minor_features:intellij_files",
19 | "//13_minor_features:install_intellij_files_script",
20 | "//14_all_dependency_types:intellij_files",
21 | ]
22 | )
23 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/all_tests.py:
--------------------------------------------------------------------------------
1 | import unittest, sys
2 | from s01_one_class_test import S01OneClassTest
3 | from s02_one_class_and_one_test import S02OneClassAndOneTest
4 | from s03_basic_test import S03BasicTest
5 | from s04_transitive_with_export_test import S04TransitiveWithExportTest
6 | from s05_annotation_processor_test import S05AnnotationProcessorTest
7 | from s06_protobuf_messages_test import S06ProtobufMessagesTest
8 | from s07_grpc_test import S07GrpcTest
9 | from s08_auto_value_test import S08AutoValueTest
10 | from s09_python_test import S09PythonTest
11 | from s12_kotlin_test import S12KotlinTest
12 | from s13_minor_features_test import S13MinorFeaturesTest
13 | from s14_all_dependency_types_test import S14AllDependencyTypesTest
14 |
15 | if __name__ == '__main__':
16 | suite = unittest.TestSuite()
17 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S01OneClassTest))
18 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S02OneClassAndOneTest))
19 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S03BasicTest))
20 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S04TransitiveWithExportTest))
21 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S05AnnotationProcessorTest))
22 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S06ProtobufMessagesTest))
23 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S07GrpcTest))
24 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S08AutoValueTest))
25 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S08AutoValueTest))
26 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S09PythonTest))
27 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S12KotlinTest))
28 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S13MinorFeaturesTest))
29 | suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(S14AllDependencyTypesTest))
30 |
31 | # python unit test main's must end with this or the test will exit with status code 0,
32 | # and thus it will not fail the bazel test run if there's a test failure.
33 | return_value = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
34 | sys.exit(return_value)
35 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s01_one_class_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S01OneClassTest(unittest.TestCase):
5 |
6 | archive = load_archive("01_one_class/intellij_files")
7 |
8 | iml_content = archive["01_one_class/01_one_class.iml"]
9 | modules_xml_content = archive["01_one_class/.idea/modules.xml"]
10 |
11 | def test_source_folders(self):
12 | self.assertEqual([
13 | "file://$MODULE_DIR$/out/production/generated",
14 | "file://$MODULE_DIR$/out/test/generated_tests",
15 | "file://$MODULE_DIR$/src",
16 | "file://$MODULE_DIR$/test"
17 | ], xpath_attribute_list(self.iml_content, "./component/content/sourceFolder", "url"))
18 |
19 | self.assertEqual(
20 | ["false", "true", "false", "true"],
21 | xpath_attribute_list(self.iml_content, "./component/content/sourceFolder", "isTestSource"))
22 |
23 | def test_output_folders(self):
24 | self.assertEqual(
25 | ["file://$MODULE_DIR$/out/production"],
26 | xpath_attribute_list(self.iml_content, "./component/output", "url"))
27 |
28 | self.assertEqual(
29 | ["file://$MODULE_DIR$/out/test"],
30 | xpath_attribute_list(self.iml_content, "./component/output-test", "url"))
31 |
32 | def test_libraries(self):
33 | self.assertEqual(
34 | [],
35 | xpath_attribute_list(self.iml_content,
36 | "./component/orderEntry[@type='module-library']/library/CLASSES/root",
37 | "url"))
38 |
39 | def test_modules_xml(self):
40 | self.assertEqual(["file://$PROJECT_DIR$/01_one_class.iml"],
41 | xpath_attribute_list(self.modules_xml_content, "./component/modules/module", "fileurl"))
42 |
43 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s02_one_class_and_one_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S02OneClassAndOneTest(unittest.TestCase):
5 |
6 | archive = load_archive("02_one_class_and_one_test/intellij_files")
7 |
8 | iml_content = archive["02_one_class_and_one_test/02_one_class_and_one_test.iml"]
9 |
10 | def test_source_folders(self):
11 | self.assertEqual([
12 | "file://$MODULE_DIR$/out/production/generated",
13 | "file://$MODULE_DIR$/out/test/generated_tests",
14 | "file://$MODULE_DIR$/src",
15 | "file://$MODULE_DIR$/test"
16 | ], xpath_attribute_list(self.iml_content, "./component/content/sourceFolder", "url"))
17 |
18 | self.assertEqual(
19 | ["false", "true", "false", "true"],
20 | xpath_attribute_list(self.iml_content, "./component/content/sourceFolder", "isTestSource"))
21 |
22 | def test_output_folders(self):
23 | self.assertEqual(
24 | ["file://$MODULE_DIR$/out/production"],
25 | xpath_attribute_list(self.iml_content, "./component/output", "url"))
26 |
27 | self.assertEqual(
28 | ["file://$MODULE_DIR$/out/test"],
29 | xpath_attribute_list(self.iml_content, "./component/output-test", "url"))
30 |
31 | def test_libraries(self):
32 | self.assertEqual([], find_all_plain_jar_libraries(self.iml_content))
33 | self.assertEqual(junit5_jars(), find_all_test_jar_libraries(self.iml_content))
34 |
35 |
36 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s03_basic_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S03BasicTest(unittest.TestCase):
5 |
6 | archive = load_archive("03_basic/intellij_files")
7 |
8 | dolphin_iml_content = archive["03_basic/dolphin/dolphin.iml"]
9 | human_iml_content = archive["03_basic/human/human.iml"]
10 | gorilla_iml_content = archive["03_basic/gorilla/gorilla.iml"]
11 | primate_iml_content = archive["03_basic/primate/primate.iml"]
12 | mammal_iml_content = archive["03_basic/mammal/mammal.iml"]
13 |
14 | modules_xml_content = archive["03_basic/.idea/modules.xml"]
15 |
16 | def test_source_folders_sample(self):
17 | self.assertEqual([
18 | "file://$MODULE_DIR$/out/production/generated",
19 | "file://$MODULE_DIR$/out/test/generated_tests",
20 | "file://$MODULE_DIR$/src/main/java",
21 | "file://$MODULE_DIR$/src/test/java"
22 | ], xpath_attribute_list(self.dolphin_iml_content, "./component/content/sourceFolder", "url"))
23 |
24 | self.assertEqual(
25 | ["false", "true", "false", "true"],
26 | xpath_attribute_list(self.dolphin_iml_content, "./component/content/sourceFolder", "isTestSource"))
27 |
28 | def test_output_folders(self):
29 | self.assertEqual(
30 | ["file://$MODULE_DIR$/out/production"],
31 | xpath_attribute_list(self.dolphin_iml_content, "./component/output", "url"))
32 |
33 | self.assertEqual(
34 | ["file://$MODULE_DIR$/out/test"],
35 | xpath_attribute_list(self.dolphin_iml_content, "./component/output-test", "url"))
36 |
37 | def test_libraries(self):
38 | self.assertEqual([], find_all_plain_jar_libraries(self.dolphin_iml_content))
39 | self.assertEqual(junit5_jars(), find_all_test_jar_libraries(self.dolphin_iml_content))
40 |
41 | def test_module_dependencies(self):
42 | self.assertEqual([],
43 | xpath_attribute_list(self.mammal_iml_content,
44 | "./component/orderEntry[@type='module']",
45 | "module-name"))
46 |
47 | self.assertEqual(["mammal"],
48 | xpath_attribute_list(self.primate_iml_content,
49 | "./component/orderEntry[@type='module']",
50 | "module-name"))
51 |
52 | self.assertEqual(["mammal"],
53 | xpath_attribute_list(self.dolphin_iml_content,
54 | "./component/orderEntry[@type='module']",
55 | "module-name"))
56 |
57 | self.assertEqual(["mammal", "primate"],
58 | xpath_attribute_list(self.human_iml_content,
59 | "./component/orderEntry[@type='module']",
60 | "module-name"))
61 |
62 | self.assertEqual(["mammal", "primate"],
63 | xpath_attribute_list(self.gorilla_iml_content,
64 | "./component/orderEntry[@type='module']",
65 | "module-name"))
66 |
67 | def test_modules_xml(self):
68 | self.assertEqual([
69 | "file://$PROJECT_DIR$/dolphin/dolphin.iml",
70 | "file://$PROJECT_DIR$/gorilla/gorilla.iml",
71 | "file://$PROJECT_DIR$/human/human.iml",
72 | "file://$PROJECT_DIR$/mammal/mammal.iml",
73 | "file://$PROJECT_DIR$/primate/primate.iml",
74 | ], xpath_attribute_list(self.modules_xml_content, "./component/modules/module", "fileurl"))
75 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s04_transitive_with_export_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S04TransitiveWithExportTest(unittest.TestCase):
5 |
6 | archive = load_archive("04_transitive_via_export/intellij_files")
7 |
8 | grandparent_iml_content = archive["04_transitive_via_export/grandparent/grandparent.iml"]
9 | parent_iml_content = archive["04_transitive_via_export/parent/parent.iml"]
10 | child_iml_content = archive["04_transitive_via_export/child/child.iml"]
11 |
12 | def test_compile_deps_dont_show_up_in_test_deps(self):
13 | self.assertEqual(junit5_jars(), find_all_test_jar_libraries(self.child_iml_content))
14 |
15 | def test_sample_jar_dependencies(self):
16 | self.assertEqual([
17 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_guava_guava/jar/guava-19.0.jar!/"
18 | ], find_all_plain_jar_libraries(self.grandparent_iml_content))
19 |
20 | self.assertEqual([
21 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_guava_guava/jar/guava-19.0.jar!/"
22 | ], find_all_plain_jar_libraries(self.parent_iml_content))
23 |
24 | self.assertEqual([
25 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_guava_guava/jar/guava-19.0.jar!/"
26 | ], find_all_plain_jar_libraries(self.child_iml_content))
27 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s05_annotation_processor_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S05AnnotationProcessorTest(unittest.TestCase):
5 |
6 | archive = load_archive("05_annotation_processor/intellij_files")
7 |
8 | usage_iml_content = archive["05_annotation_processor/usage/usage.iml"]
9 | compiler_xml_content = archive["05_annotation_processor/.idea/compiler.xml"]
10 |
11 | def test_annotation_processor_config(self):
12 | self.assertEqual(
13 | ["foo_profile", "my_idea_auto_value_annotation_processor_profile"],
14 | xpath_attribute_list(self.compiler_xml_content, "./component/annotationProcessing/profile", "name"))
15 |
16 | self.assertEqual(junit5_jars(), find_all_test_jar_libraries(self.usage_iml_content))
17 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s06_protobuf_messages_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | from scenario_test_support import *
4 |
5 |
6 | class S06ProtobufMessagesTest(unittest.TestCase):
7 | archive = load_archive("06_protobuf_messages/intellij_files")
8 |
9 | usage_iml_content = archive["06_protobuf_messages/usage/usage.iml"]
10 |
11 | def test_libraries(self):
12 | self.assertEqual([
13 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/com_google_protobuf/libdescriptor_proto-speed.jar!/",
14 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/06_protobuf_messages/html_email/libproto-speed.jar!/",
15 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/06_protobuf_messages/plain_email/libproto-speed.jar!/",
16 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/com_google_protobuf/libprotobuf_java.jar!/",
17 | ], find_all_plain_jar_libraries(self.usage_iml_content))
18 |
19 | self.assertEqual(junit5_jars(), find_all_test_jar_libraries(self.usage_iml_content))
20 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s07_grpc_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import re
3 | from scenario_test_support import *
4 |
5 | class S07GrpcTest(unittest.TestCase):
6 | maxDiff = None
7 |
8 | archive = load_archive("07_grpc/intellij_files")
9 |
10 | fortune_grpc_iml_content = archive["07_grpc/07_grpc.iml"]
11 |
12 | def test_libraries(self):
13 | self.assertEqual([
14 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_errorprone_error_prone_annotations/error_prone_annotations-X.X.X.jar!/",
15 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_guava_failureaccess/failureaccess-X.X.X.jar!/",
16 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_code_gson_gson/gson-X.X.X.jar!/",
17 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_guava_guava/jar/guava-X.X.jar!/",
18 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_jXobjc_jXobjc_annotations/jXobjc-annotations-X.X.jar!/",
19 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_code_findbugs_jsrX/jsrX-X.X.X.jar!/",
20 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/io_grpc_grpc_java/api/libapi.jar!/",
21 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/io_grpc_grpc_java/context/libcontext.jar!/",
22 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/com_google_protobuf/libdescriptor_proto-speed.jar!/",
23 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/X_grpc/libjava_grpc.jar!/",
24 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/X_grpc/libproto-speed.jar!/",
25 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/io_grpc_grpc_java/protobuf-lite/libprotobuf-lite.jar!/",
26 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/io_grpc_grpc_java/protobuf/libprotobuf.jar!/",
27 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/com_google_protobuf/libprotobuf_java.jar!/",
28 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/com_google_protobuf/libprotobuf_java_util.jar!/",
29 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/bazel-out/darwin-fastbuild/bin/external/io_grpc_grpc_java/stub/libstub.jar!/",
30 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_api_grpc_proto_google_common_protos/proto-google-common-protos-X.X.X.jar!/",
31 | ], list(map(lambda x: re.sub(r"[0-9]+", "X", x), find_all_plain_jar_libraries(self.fortune_grpc_iml_content))))
32 |
33 | self.assertEqual(junit5_jars(), find_all_test_jar_libraries(self.fortune_grpc_iml_content))
34 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s08_auto_value_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S08AutoValueTest(unittest.TestCase):
5 |
6 | archive = load_archive("08_auto_value/intellij_files")
7 |
8 | compiler_xml_content = archive["08_auto_value/.idea/compiler.xml"]
9 |
10 | def test_source_folders(self):
11 | self.assertEqual([
12 | "foo_profile", "my_idea_auto_value_annotation_processor_profile"
13 | ], xpath_attribute_list(self.compiler_xml_content, "./component/annotationProcessing/profile", "name"))
14 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s09_python_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S09PythonTest(unittest.TestCase):
5 |
6 | archive = load_archive("09_python/intellij_files")
7 |
8 | iml_content = archive["09_python/09_python.iml"]
9 |
10 | def test_python_facet(self):
11 | self.assertEqual(["Python"], xpath_attribute_list(self.iml_content, "./component/facet", "name"))
12 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s12_kotlin_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S12KotlinTest(unittest.TestCase):
5 | maxDiff = None
6 |
7 | archive = load_archive("12_kotlin/intellij_files")
8 |
9 | parent_iml_content = archive["12_kotlin/parent/parent.iml"]
10 | child_iml_content = archive["12_kotlin/child/child.iml"]
11 |
12 | def test_kotlin_facet(self):
13 | self.assertEqual(["Kotlin"], xpath_attribute_list(self.parent_iml_content, "./component/facet", "name"))
14 | self.assertEqual(["Kotlin"], xpath_attribute_list(self.child_iml_content, "./component/facet", "name"))
15 |
16 |
17 | def test_source_folders(self):
18 | expected = [
19 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_google_guava_guava/jar/guava-19.0.jar!/",
20 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib.jar!/",
21 | ]
22 |
23 | self.assertEqual(expected, find_all_plain_jar_libraries(self.child_iml_content))
24 | self.assertEqual(expected, find_all_plain_jar_libraries(self.parent_iml_content))
25 |
26 | def test_module_dependencies(self):
27 | self.assertEqual(["parent"],
28 | xpath_attribute_list(self.child_iml_content,
29 | "./component/orderEntry[@type='module']",
30 | "module-name"))
31 |
32 | self.assertEqual([],
33 | xpath_attribute_list(self.parent_iml_content,
34 | "./component/orderEntry[@type='module']",
35 | "module-name"))
36 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s13_minor_features_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 |
5 | class S13MinorFeaturesTest(unittest.TestCase):
6 | archive = load_archive("13_minor_features/intellij_files")
7 |
8 | iml_content = archive["13_minor_features/13_mymodulename.iml"]
9 |
10 | def test_source_folders(self):
11 | self.assertEqual([
12 | "file://$MODULE_DIR$/out/production/generated",
13 | "file://$MODULE_DIR$/out/test/generated_tests",
14 | "file://$MODULE_DIR$/src",
15 | "file://$MODULE_DIR$/test",
16 | "file://$MODULE_DIR$/${MY_BICYCLE_COLOR}",
17 | "file://$MODULE_DIR$/${SOME_FILE}",
18 | "file://${BAZEL_PACKAGE_GENFILES}",
19 | ], xpath_attribute_list(self.iml_content, "./component/content/sourceFolder", "url"))
20 |
21 | def test_provide_bash_exports_for_custom_substitutions(self):
22 | script_content = read_file(generated_file_path("13_minor_features/install_intellij_files_script"))
23 | custom_vars_in_python = script_content.split("# BEFORE_CUSTOM_VARS")[1].split("# AFTER_CUSTOM_VARS")[0]
24 |
25 | self.assertEqual(
26 | "'MY_BICYCLE_COLOR':'red',\n" +
27 | "'SOME_FILE':'13_minor_features/some_file.txt',",
28 | custom_vars_in_python.strip())
29 |
30 | self.assertContains(script_content,
31 | 'for line in get_subcommand_output(["my-bazel-script", "info"]).splitlines()')
32 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/s14_all_dependency_types_test.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from scenario_test_support import *
3 |
4 | class S14AllDependencyTypesTest(unittest.TestCase):
5 |
6 | archive = load_archive("14_all_dependency_types/intellij_files")
7 |
8 | child_data_iml_content = archive["14_all_dependency_types/child_data/child_data.iml"]
9 | child_dep_iml_content = archive["14_all_dependency_types/child_dep/child_dep.iml"]
10 | child_src_iml_content = archive["14_all_dependency_types/child_src/child_src.iml"]
11 | parent_iml_content = archive["14_all_dependency_types/parent/parent.iml"]
12 |
13 | child2_custom_iml_content = archive["14_all_dependency_types/child2_custom/child2_custom.iml"]
14 |
15 | def test_module_dependencies(self):
16 | self.assertEqual([],
17 | xpath_attribute_list(self.parent_iml_content,
18 | "./component/orderEntry[@type='module']",
19 | "module-name"))
20 |
21 | self.assertEqual(["parent"],
22 | xpath_attribute_list(self.child_src_iml_content,
23 | "./component/orderEntry[@type='module']",
24 | "module-name"))
25 |
26 | self.assertEqual(["parent"],
27 | xpath_attribute_list(self.child_data_iml_content,
28 | "./component/orderEntry[@type='module']",
29 | "module-name"))
30 |
31 | self.assertEqual(["parent2_custom"],
32 | xpath_attribute_list(self.child2_custom_iml_content,
33 | "./component/orderEntry[@type='module']",
34 | "module-name"))
35 |
--------------------------------------------------------------------------------
/scenarios/scenario_tests/pytest/scenario_test_support.py:
--------------------------------------------------------------------------------
1 | import xml.etree.ElementTree as ET
2 | import os
3 |
4 | dir_path = os.path.dirname(os.path.realpath(__file__))
5 |
6 |
7 | def is_bazel_run():
8 | return "TEST_WORKSPACE" in os.environ
9 |
10 |
11 | def read_file(path):
12 | f = open(path, "r")
13 | content = f.read()
14 | f.close()
15 | return content
16 |
17 |
18 | def parse_xml(xml_str):
19 | return ET.fromstring(xml_str)
20 |
21 |
22 | def xpath_list(xml_str, xpath):
23 | return parse_xml(xml_str).findall(xpath)
24 |
25 |
26 | # unfortunately ElementTree doesn't handle returning xpath attribute values, this is a workaround.
27 | def xpath_attribute_list(xml_str, xpath, attribute_name):
28 | return list(map(lambda e: e.get(attribute_name), parse_xml(xml_str).findall(xpath)))
29 |
30 |
31 | def generated_file_path(relative_path):
32 | return relative_path \
33 | if is_bazel_run() \
34 | else os.path.join(dir_path, "../../bazel-bin/%s" % relative_path)
35 |
36 | def load_archive(intellij_files_archive_path):
37 | intellij_files_archive_path = generated_file_path(intellij_files_archive_path)
38 |
39 | entries = read_file(intellij_files_archive_path) \
40 | .split("__SYMLINK_DIVIDER__\n", 1)[0] \
41 | .split("__SHA1_DIVIDER__\n", 1)[1] \
42 | .split("\n__FILE_DIVIDER__\n")
43 |
44 | relative_path_to_content = {}
45 | for entry in entries:
46 | parts = entry.split("\n", 1)
47 | relative_path_to_content[parts[0]] = parts[1]
48 |
49 | return relative_path_to_content
50 |
51 | def find_all_plain_jar_libraries(iml_content):
52 | return list(map(lambda e: e.find("./library/CLASSES/root").get("url"),
53 | filter(lambda e: e.get("type") == "module-library" and "scope" not in e.keys(),
54 | parse_xml(iml_content).findall("./component/orderEntry"))))
55 |
56 | def find_all_test_jar_libraries(iml_content):
57 | return list(map(lambda e: e.find("./library/CLASSES/root").get("url"),
58 | filter(lambda e: e.get("type") == "module-library" and e.get("scope") == "TEST",
59 | parse_xml(iml_content).findall("./component/orderEntry"))))
60 |
61 | def junit5_jars():
62 | return [
63 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/org_apiguardian_apiguardian_api/jar/apiguardian-api-1.0.0.jar!/",
64 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/org_junit_jupiter_junit_jupiter_api/jar/junit-jupiter-api-5.0.1.jar!/",
65 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/org_junit_platform_junit_platform_commons/jar/junit-platform-commons-1.0.1.jar!/",
66 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/org_junit_platform_junit_platform_engine/jar/junit-platform-engine-1.0.1.jar!/",
67 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/org_junit_platform_junit_platform_launcher/jar/junit-platform-launcher-1.0.1.jar!/",
68 | "jar://${BAZEL_INFO_EXECUTION_ROOT}/external/org_opentest4j_opentest4j/jar/opentest4j-1.0.0.jar!/"]
69 |
--------------------------------------------------------------------------------
/scenarios/tools/bazel.rc:
--------------------------------------------------------------------------------
1 | build --strategy=KotlinCompile=worker
2 | test --test_output=errors --action_env="GTEST_COLOR=1"
3 |
--------------------------------------------------------------------------------