{"id":13450897,"url":"https://github.com/OrhanKupusoglu/bazelize-maven-plugin","last_synced_at":"2025-03-23T16:32:37.139Z","repository":{"id":53032447,"uuid":"139044101","full_name":"OrhanKupusoglu/bazelize-maven-plugin","owner":"OrhanKupusoglu","description":"Maven plugin for migration from Apache Maven to Google Bazel","archived":false,"fork":false,"pushed_at":"2023-11-14T23:39:11.000Z","size":121,"stargazers_count":14,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-13T09:04:27.170Z","etag":null,"topics":["apache-maven","bazel","bazelize","google-bazel","maven","migration","migrator"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OrhanKupusoglu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-06-28T16:35:49.000Z","updated_at":"2023-04-15T15:36:45.000Z","dependencies_parsed_at":"2023-11-15T00:40:32.018Z","dependency_job_id":null,"html_url":"https://github.com/OrhanKupusoglu/bazelize-maven-plugin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrhanKupusoglu%2Fbazelize-maven-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrhanKupusoglu%2Fbazelize-maven-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrhanKupusoglu%2Fbazelize-maven-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OrhanKupusoglu%2Fbazelize-maven-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OrhanKupusoglu","download_url":"https://codeload.github.com/OrhanKupusoglu/bazelize-maven-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221856498,"owners_count":16892454,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache-maven","bazel","bazelize","google-bazel","maven","migration","migrator"],"created_at":"2024-07-31T07:00:39.961Z","updated_at":"2024-10-28T16:32:08.012Z","avatar_url":"https://github.com/OrhanKupusoglu.png","language":"Java","readme":"# Bazelize Maven Plugin\n\nThis [Apache Maven](https://maven.apache.org/) plugin prepares scripts required for the [Google Bazel](https://bazel.build/) build tool.\n\nMaven interprets the [Project Object Model](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html) configurations, contained in **pom.xml** files, which are essential for a Maven build.\n\n\u003e It is an XML file that contains information about the project and configuration details used by Maven to build the project.\n\nBazel uses [Skylark](https://docs.bazel.build/versions/master/skylark/language.html), syntactically a subset of both Python 2 and Python 3, which is optimized for configuration management.\n\n\u003e Skylark is designed to be small, simple, and thread-safe. Although it is inspired from Python, it is not a general-purpose language and most Python features are not included.\n\nMigration from Maven to Bazel means basically generation of Skylark **WORKSPACE** and **BUILD** scripts from a set of **pom.xml** configuration files.\n\nThe main culprit for the migration from Maven to Bazel is the slowness of the Maven builds. With the current emphasis on DevOps and CI, this slowness can be considered as *highly unsatisfactory*.\n\nAlthough equipped with an impressive feature set, **Google Bazel** faces the usual *unfamiliarity issues*. For Java developers, after so many years of Maven experience, Bazel looks like a time-consuming challenge from **Maven's declarative (what to do)** to **Bazel's imperative (how to do)** mindset.\n\n\u0026nbsp;\n\n## Alternatives\n\nBazel itself provides a [systematic approach](https://docs.bazel.build/versions/master/migrate-maven.html) to migrate from Maven to Bazel. The required **WORKSPACE** script can be generated with [Migration tooling](https://github.com/bazelbuild/migration-tooling). The **BUILD** scripts require manual intervention.\n\nThe [migrator-maven-plugin](https://github.com/zmeggyesi/migrator-maven-plugin) by *Zalán Meggyesi* may be a good starting point for Java developers.\n\nThe curated list [Awesome Bazel](https://github.com/jin/awesome-bazel) by *Jingwen* holds up-to-date pointers about Bazel.\n\n\u0026nbsp;\n\n## Apache Maven\n\nThe plugin is built with the following Maven version:\n\n```\n$ mvn --version\nApache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-24T22:49:05+03:00)\nMaven home: /home/me/dev/tools/apache-maven-3.5.3\nJava version: 1.8.0_171, vendor: Oracle Corporation\nJava home: /usr/lib/jvm/java-8-oracle/jre\nDefault locale: en_US, platform encoding: UTF-8\nOS name: \"linux\", version: \"4.10.0-38-generic\", arch: \"amd64\", family: \"unix\"\n```\n\nDue to its popularity, Maven has good [documentation](https://maven.apache.org/plugin-developers/index.html) and [Internet presence](https://books.sonatype.com/mvnref-book/reference/index.html). To see the command line help:\n\n```\n$ mvn --help\n```\n\n### Effective POM\n\nA **POM** combines with other settings and profiles, and creates an **effective pom.xml**. The so-called [Effective POM](http://maven.apache.org/plugins/maven-help-plugin/effective-pom-mojo.html) gives details about the current configuration.\n\n```\n$ mvn help:effective-pom\n$ mvn help:effective-pom -Doutput=pom-effective.xml\n```\n\n### Inspection\n\nMaven has many built-in goals for inspection of the current project. Listed dependencies and plugins can be checked easily for updates, too.\n\n```\n$ mvn dependency:list\n$ mvn dependency:resolve\n$ mvn dependency:tree\n$ mvn versions:display-dependency-updates\n$ mvn versions:display-plugin-updates\n```\n\n### Maven Coordinates\n\n[Semantic Versioning](https://semver.org/) is an important concept to follow. [Maven coordinates](https://maven.apache.org/pom.html#Maven_Coordinates) uniquely identify a project, dependency, or plugin defined in a **POM** with `groupId:artifactId:version` properties. As a project grows, its version increases, too. Instead of changing versions with ad hoc *find-replace*, Maven provides goals with the [Versions Maven Plugin](http://www.mojohaus.org/versions-maven-plugin/).\n\n```\n# Enter the new version\n$ mvn versions:set\n\n# Set immediately\n$ mvn versions:set -DnewVersion=0.3.3\n\n# Revert back\n$ mvn versions:revert\n\n# Remove the 'pom.xml.versionsBackup' files.\n$ mvn versions:commit\n```\n\n### Build\n\nTypically a Maven project is built with **clean** and **install**.\n\n```\n$ mvn clean install\n```\nTests are called automatically, but this step can be skipped with `maven.test.skip` property.\n\n[Apache Maven Surefire](http://maven.apache.org/surefire/index.html) test framework contains [Maven Failsafe Plugin](http://maven.apache.org/surefire/maven-failsafe-plugin/index.html)  for unit tests  and  [Maven Surefire Plugin](http://maven.apache.org/surefire/maven-surefire-plugin/index.html) for integration tests. **Failsafe** can be configured with the `skipTests`  property. **Surefire** plugin introduces the `skipITs` property. In contrast to Maven's own `maven.test.skip` property, both plugins compile the tests, but do not run them.\n\n```\n$ mvn clean install -Dmaven.test.skip\n\n# skip unit tests with Failsafe\n$ mvn clean install -DskipTests\n\n# skip integration tests with Surefire\n$ mvn clean install -DskipITs\n```\n\n### Reports\n\nThe [Apache Maven Site Plugin](https://maven.apache.org/plugins/maven-site-plugin/) generates a Web site for the plugin, which includes the standard [Javadoc](https://en.wikipedia.org/wiki/Javadoc) pages by default.\n\nIf the [Apache Maven Plugin](https://maven.apache.org/plugin-tools/maven-plugin-plugin/) is repeated in the **\u003creporting\u003e** element of the **pom.xml**, then extra **plugin documentation** pages with details about each goal are added. The documentation is generated by default in `${project.build.directory}/site` which is the **target/site** directory.\n\n```\n$ mvn site\n```\nThe [Apache Maven Javadoc Plugin](https://maven.apache.org/plugins/maven-javadoc-plugin/) can be explicitly configured to run during a build phase, of course. The plugin can be called by itself, too.\n\n\n```\n$ mvn javadoc:javadoc\n$ mvn javadoc:test-javadoc\n```\n\nThe [Apache Maven JXR Plugin](https://maven.apache.org/jxr/maven-jxr-plugin/) generates line-numbered HTML pages for each source file.\n\nThe [Apache Maven Documentation Checker Plugin](http://maven.apache.org/plugins/maven-docck-plugin/usage.html) rates the configuration for a better output. However the **check** fails quite easily.\n\n```\n$ mvn docck:check\n```\n\n### Sources\n\nThe [Apache Maven Source Plugin](https://maven.apache.org/plugins/maven-source-plugin/index.html) creates JAR archives of the source files of the current project in the **target** directory. If configured, **source:jar** goal is called during the **package/install** phases automatically.\n\n```\n$ mvn source:jar\n```\nIn general, bundling Test sources and Javadoc pages is best left to their plugin's respective goals.\n\n```\n$ mvn source:test-jar\n$ mvn site:jar\n$ mvn javadoc:jar\n$ mvn javadoc:test-jar\n```\n\u0026nbsp;\n\n## Google Bazel\n\nFor years Google was using an internal automation tool called **Blaze**. In March 2015 a subset of this tool is released as the open-source project **Bazel**. **Google Bazel** aims to build and test software of any size, quickly and reliably. The project's motto is:\n\n\u003e {Fast, Correct} - Choose two\n\nJava is only one of the many languages Bazel supports.\n\n[Building a Java project with Bazel](https://docs.bazel.build/versions/master/tutorial/java.html) requires one **WORKSPACE** file to identify project's root directory and one or many **BUILD** files containing build instructions. The **WORKSPACE** and **BUILD** files can even be empty, but their mere existence may fulfill the Bazel requirements.\n\n```\n$ bazel version\nBuild label: 0.14.1\nBuild target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar\nBuild time: Fri Jun 8 12:17:35 2018 (1528460255)\nBuild timestamp: 1528460255\nBuild timestamp as int: 1528460255\n```\n\nAs expected, Bazel has extensive [documentation](https://docs.bazel.build/versions/master/bazel-overview.html). Bazel's [target pattern syntax](https://docs.bazel.build/versions/master/command-line-reference.html#target-pattern-syntax) determines the way rules are referred to.\n\n\u003e All target patterns starting with '//' are resolved relative to the current workspace.\n\nTo see the command line help:\n```\n$ bazel help\n```\n\n#### Caveat\n\nOne major caveat is Bazel's lack of support for [OSGi bundles](https://www.osgi.org/). Built-in support for [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) is now OK [for Java](https://blog.bazel.build/2017/02/27/protocol-buffers.html).\n\nUnfortunately OSGi bundles are required for the [Apache Karaf](https://karaf.apache.org/) runtime environment, and can be easily generated on Maven with [Maven Bundle Plugin](http://felix.apache.org/components/bundle-plugin/).\n\nMissing features can be added by writing [extensions](https://docs.bazel.build/versions/master/skylark/concepts.html):\n\u003e Bazel extensions are files ending in .bzl. Use the load statement to import a symbol from an extension.\n\n\u0026nbsp;\n\n## Goals of the Bazelize Maven Plugin\n\nThe **Bazelize Maven Plugin** aims to generate all of the required **WORKSPACE** and **BUILD** scripts by processing **pom.xml** configuration files with four successive [goals](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html). A further four goals are added for convenience.\n\n```\n$ mvn clean install\n# for example:\n$ cd ../project-to-migrate\n$ mvn kupusoglu.orhan:bazelize-maven-plugin:GOAL -Dproperty1=value1 -Dproperty2=value2\n```\n\nThe first four goals are expected to be called in succession. A single goal is a too big code with no granularity for each step, and calling other goals with **@Execute** [annotation](https://maven.apache.org/plugin-tools/maven-plugin-plugin/examples/using-annotations.html) works only just once.\n\n| GOAL          | ORDER | DESCRIPTION                              |\n| :------------ | ----- | ---------------------------------------- |\n| **module**    | 1     | Traverses a project's source files, typically **src/main/java** directories, and saves one **tmp-bzl-module.json** file for each corresponding **pom.xml**. |\n| **meta**      | 2     | Parses **tmp-bzl-module.json** files, each containing a module's meta data, and consolidates this data into a single **tmp-bzl-meta.json** file. |\n| **build**     | 3     | Generates a **BUILD** file corresonding to a **pom.xml** consisting of *Bazel java_library* rules. Serializes dependency and server data to **tmp-bzl-dependency.json** and **tmp-bzl-server.json** files respectively. Finds resources  and adds to the rule. |\n| **workspace** | 4     | Generates a **WORKSPACE** file to download all dependencies referred in **BUILD** files with *Bazel maven_server* and *maven_jar* rules. |\n| **test**      | -     | Appends to **BUILD** files a *Bazel test rule* for each Java Test class. Finds resources  and adds to the rule. |\n| **binary**    | -     | Appends to the root BUILD file a *Bazel binary rule*, which refers to all other Java libraries. Requires the main class for the **MANIFEST.MF** file, of course: **-DmainClass=com.mycompany.app.App** |\n| **clean**     | -     | Cleans all temporary files. With **-Dexpunge** cleans **WORKSPACE** and **BUILD** files, too. |\n| **help**      | -     | Displays help.                           |\n\n\u0026nbsp;\n\n## Strict Dependencies\n\nThe test rules generated by the plugin depend upon the **java_library** rule contained in the same BUILD file.\nTherefore as explained in the documentation for [options](https://docs.bazel.build/versions/master/user-manual.html), to prevent build and test errors the option **--strict_java_deps=off** is necessary except for simple classes.\n\n\u003e This option controls whether javac checks for missing direct dependencies. Java targets must explicitly declare all directly used targets as dependencies. This flag instructs javac to determine the jars actually used for type checking each java file, and warn/error if they are not the output of a direct dependency of the current target.\n\n\u0026nbsp;\n\n## Maven Plugin Prefix Resolution\n\nThe four goals must be called like this:\n\n```\n$ mvn kupusoglu.orhan:bazelize-maven-plugin:module\n$ mvn kupusoglu.orhan:bazelize-maven-plugin:meta\n$ mvn kupusoglu.orhan:bazelize-maven-plugin:build\n$ mvn kupusoglu.orhan:bazelize-maven-plugin:workspace\n```\n\nClearly this a verbose process, which can be shortened with [Maven plugin prefix resolution](https://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html). Since the plugin follows the Maven convention of `${prefix}-maven-plugin` names, its **groupID** can be declared in the [Maven settings file](https://maven.apache.org/settings.html). The Maven settings file is located at `${user.home}/.m2/settings.xml`.\n\n```xml\n\u003csettings\u003e\n...\n    \u003cpluginGroups\u003e\n        \u003cpluginGroup\u003ekupusoglu.orhan\u003c/pluginGroup\u003e\n    \u003c/pluginGroups\u003e\n...\n\u003c/settings\u003e\n```\n\nWith this simplification the goals can be called succinctly:\n\n```\n$ mvn bazelize:module\n$ mvn bazelize:meta\n$ mvn bazelize:build\n$ mvn bazelize:workspace\n```\n\n\u0026nbsp;\n\n## Maven Lifecycle\n\nThe [Maven lifecycle extension](https://maven.apache.org/examples/maven-3-lifecycle-extensions.html) uses *sessions*, but found to be of limited use. Still it can be seen in action by declaring the plugin in the target project's **pom.xml**:\n\n```xml\n\u003cproject\u003e\n...\n    \u003cbuild\u003e\n        \u003cextensions\u003e\n            \u003cextension\u003e\n                \u003cgroupId\u003ekupusoglu.orhan\u003c/groupId\u003e\n                \u003cartifactId\u003ebazelize-maven-plugin\u003c/artifactId\u003e\n                \u003cversion\u003e0.3.3\u003c/version\u003e\n            \u003c/extension\u003e\n        \u003c/extensions\u003e\n    \u003c/build\u003e\n...\n\u003c/project\u003e\n```\n\nWith this addition, calling the first goal and the third goal is enough:\n\n```\n$ mvn bazelize:module\n$ mvn bazelize:build\n```\n\nAnother benefit is sharing [context](http://maven.apache.org/ref/3.5.4/maven-core/apidocs/org/apache/maven/project/MavenProject.html#getContextValue-java.lang.String-) between succeeding executions. For example, with the following executions, backup suffixes for the temporary module and meta JSON files, and for the BUILD and WORKSPACE files will be identical, respectively.\n\n```\n$ mvn bazelize:module -Dbackup=true\n$ mvn bazelize:build -Dbackup=true\n```\n\n\u0026nbsp;\n\n## Sample Migration\n\nAfter installing the **Maven-Bazelize** plugin, a sample project is needed.\n\nWith the [Maven Archetype Plugin](https://maven.apache.org/archetype/maven-archetype-plugin/index.html) Maven can generate a [sample project](https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html), which just prints, not surprisingly, *Hello World*.\n\n```\n$ cd ..\n$ mvn archetype:generate -DgroupId=com.mycompany.app \\\n                         -DartifactId=my-app \\\n                         -DarchetypeArtifactId=maven-archetype-quickstart \\\n                         -DinteractiveMode=false\n$ cd my-app\n$ mvn package\n$ java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App\nHello World!\n```\n\nThe **Bazelize Maven Plugin** must be called to work on this Maven project:\n\n```\n$ mvn bazelize:module\n$ mvn bazelize:meta\n$ mvn bazelize:build\n$ mvn bazelize:workspace\n```\n\nNow a **WORKSPACE** and **BUILD** script is generated, so building with Bazel is now possible.\n\nWith the other goals test and binary rules can be added, and clean without **-Dexpunge** removes the temporary JSON files:\n\n```\n$ mvn bazelize:help\n$ mvn bazelize:test\n$ mvn bazelize:binary -DmainClass=com.mycompany.app.App\n$ mvn bazelize:clean\n```\n\nCheck the **WORKSPACE** script:\n\n```\n$ cat WORKSPACE\nmaven_jar(\n    name = \"junit_junit_3_8_1\",\n    artifact = \"junit:junit:3.8.1\",\n)\n```\n\nCheck the **BUILD** script:\n\n```\n$ cat BUILD\njava_library(\n    name = \"com_mycompany_app_my_app_1_0_SNAPSHOT\",\n    visibility = [\"//visibility:public\"],\n    srcs = glob([\"src/main/java/com/mycompany/app/*.java\"]),\n    resources = [\n    ],\n    deps = [\n        \"@junit_junit_3_8_1//jar\",\n    ],\n)\n\njava_test(\n    name = \"com_mycompany_app_AppTest\",\n    size = \"small\",\n    test_class = \"com.mycompany.app.AppTest\",\n    srcs = [\"src/test/java/com/mycompany/app/AppTest.java\"],\n    resources = [\n    ],\n    deps = [\n        \":com_mycompany_app_my_app_1_0_SNAPSHOT\",\n    ],\n)\n\njava_binary(\n    name = \"com_mycompany_app_App\",\n    main_class = \"com.mycompany.app.App\",\n    runtime_deps = [\n        \":com_mycompany_app_my_app_1_0_SNAPSHOT\",\n    ],\n)\n```\n\nLet's test with Bazel:\n\n```\n$ bazel build ...\nStarting local Bazel server and connecting to it...\n.........\nINFO: Analysed 3 targets (17 packages loaded).\nINFO: Found 3 targets...\nINFO: Elapsed time: 9.332s, Critical Path: 2.62s\nINFO: 7 processes: 2 linux-sandbox, 2 local, 3 worker.\nINFO: Build completed successfully, 16 total actions\n\n# to call all tests: bazel test ...\n# to capture the test output: --test_output all\n\n$ bazel test com_mycompany_app_AppTest\nINFO: Analysed target //:com_mycompany_app_AppTest (0 packages loaded).\nINFO: Found 1 test target...\nTarget //:com_mycompany_app_AppTest up-to-date:\n  bazel-bin/com_mycompany_app_AppTest.jar\n  bazel-bin/com_mycompany_app_AppTest\nINFO: Elapsed time: 0.513s, Critical Path: 0.28s\nINFO: 1 process, linux-sandbox.\nINFO: Build completed successfully, 2 total actions\n//:com_mycompany_app_AppTest                                             PASSED in 0.2s\n\nExecuted 1 out of 1 test: 1 test passes.\n\n$ bazel run com_mycompany_app_App\nINFO: Analysed target //:com_mycompany_app_App (0 packages loaded).\nINFO: Found 1 target...\nTarget //:com_mycompany_app_App up-to-date:\n  bazel-bin/com_mycompany_app_App.jar\n  bazel-bin/com_mycompany_app_App\nINFO: Elapsed time: 0.272s, Critical Path: 0.00s\nINFO: 0 processes.\nINFO: Build completed successfully, 1 total action\n\nINFO: Running command line: bazel-bin/com_mycompany_app_App\nHello World!\n\n$ bazel build libcom_mycompany_app_my_app_1_0_SNAPSHOT-src.jar\nINFO: Analysed target //:libcom_mycompany_app_my_app_1_0_SNAPSHOT-src.jar (0 packages loaded).\nINFO: Found 1 target...\nTarget //:libcom_mycompany_app_my_app_1_0_SNAPSHOT-src.jar up-to-date:\n  bazel-bin/libcom_mycompany_app_my_app_1_0_SNAPSHOT-src.jar\nINFO: Elapsed time: 0.309s, Critical Path: 0.06s\nINFO: 1 process, linux-sandbox.\nINFO: Build completed successfully, 3 total actions\n\n$ bazel build com_mycompany_app_App_deploy.jar\nINFO: Analysed target //:com_mycompany_app_App_deploy.jar (0 packages loaded).\nINFO: Found 1 target...\nTarget //:com_mycompany_app_App_deploy.jar up-to-date:\n  bazel-bin/com_mycompany_app_App_deploy.jar\nINFO: Elapsed time: 0.297s, Critical Path: 0.07s\nINFO: 1 process, linux-sandbox.\nINFO: Build completed successfully, 4 total actions\n\n$ bazel build com_mycompany_app_AppTest-src.jar\nINFO: Analysed target //:com_mycompany_app_AppTest-src.jar (0 packages loaded).\nINFO: Found 1 target...\nTarget //:com_mycompany_app_AppTest-src.jar up-to-date:\n  bazel-bin/com_mycompany_app_AppTest-src.jar\nINFO: Elapsed time: 0.309s, Critical Path: 0.05s\nINFO: 1 process, linux-sandbox.\nINFO: Build completed successfully, 3 total actions\n\n$ bazel build com_mycompany_app_AppTest_deploy.jar\nINFO: Analysed target //:com_mycompany_app_AppTest_deploy.jar (0 packages loaded).\nINFO: Found 1 target...\nTarget //:com_mycompany_app_AppTest_deploy.jar up-to-date:\n  bazel-bin/com_mycompany_app_AppTest_deploy.jar\nINFO: Elapsed time: 0.306s, Critical Path: 0.06s\nINFO: 1 process, linux-sandbox.\nINFO: Build completed successfully, 3 total actions\n\n# after review\n$ bazel clean --expunge\nINFO: Starting clean (this may take a while). Consider using --async if the clean takes more than several minutes.\n```\nBazel can create a [JAR file](https://docs.bazel.build/versions/master/be/java.html#java_binary) containing the sources collected from the transitive closure of the target:\n\n```\n$ bazel build com_mycompany_app_App_deploy-src.jar\n$ bazel build com_mycompany_app_AppTest_deploy-src.jar\n```\n\nBazel can [profile](https://docs.bazel.build/versions/master/skylark/performance.html) a build for [issues](https://www.kchodorow.com/blog/2015/09/18/build-y-u-go-slow/). An HTML page, here *myprofile.out.html*, can be generated to review the build in minute detail:\n\n```\n$ bazel build --profile=bazelize.out ...\n$ bazel analyze-profile --html bazelize.out\n```\n\n### Script\n\nUsing [heredoc](https://en.wikipedia.org/wiki/Here_document) a simple shell script to call the goals can easily be prepared at target project's root.\n\nThis plugin is designed for an old version of Bazel, therefore [Bazelisk](https://github.com/bazelbuild/bazelisk) is required.\n\nFor an example, please refer to the [Quicksort](https://github.com/OrhanKupusoglu/quicksort-duplicates) repository.\n\n```\n$ cat \u003c\u003c 'EOF' \u003e bazelize.sh\n#!/bin/bash\n\n# customize the following declarations\n# ------------------------------------------------------------------------------\nexport USE_BAZEL_VERSION=0.14.1\nBAZEL_BIN=/home/unknown/dev/bazelisk/bin/bazelisk-linux-amd64\nMAIN_CLASS=com.mycompany.app.App\n# ------------------------------------------------------------------------------\n\nMAVEN_PLUGIN=kupusoglu.orhan:bazelize-maven-plugin\nSEPARATOR=$(printf \"%0.s=\" {1..80})\nOPTION=$1\n\ncase $OPTION in\n    -h | --help )\n        printf \"usage:\\n\"\n        printf \"\\t$0 \u003coption\u003e\\n\"\n        printf \"options:\\n\"\n        printf \"\\tmigrate to bazel: -m | --migrate | -g | --generate\\n\"\n        printf \"\\tclean bazel:      -c | --clean\\n\"\n        printf \"\\tbuild with bazel: -b | --build\\n\"\n        printf \"\\ttest with bazel:  -t | --test\\n\"\n        printf \"\\trun with bazel:   -r | --run\\n\"\n        printf \"requires Bazelisk for Bazel v${USE_BAZEL_VERSION}:\\n\"\n        printf \"\\t$BAZEL_BIN\\n\"\n        exit 0\n        ;;\n\n    -m | --migrate | -g | --generate )\n        MSG=\"migrate\"\n        ;;\n\n    -c | --clean )\n        MSG=\"clean\"\n        ;;\n\n    -b | --build )\n        MSG=\"build\"\n        ;;\n\n    -t | --test )\n        MSG=\"test\"\n        ;;\n\n    -r | --run )\n        MSG=\"run\"\n        ;;\n\n    * )\n        echo \"ERROR - unknown option: $OPTION\"\n        exit 1\nesac\n\nMSG=\"$MSG | bazel version: $USE_BAZEL_VERSION\"\n\nprintf \"$SEPARATOR\\n\"\nprintf \"== ${MSG}\\n\"\nprintf \"$SEPARATOR\\n\\n\"\n\nif [ ! -f $BAZEL_BIN ]\nthen\n    echo \"ERROR - missing Bazelisk\"\n    echo \"path: $BAZEL_BIN\"\n    exit 2\nfi\n\ncase $OPTION in\n    -m | --migrate | -g | --generate )\n        mvn ${MAVEN_PLUGIN}:clean -Dexpunge\n        mvn ${MAVEN_PLUGIN}:module\n        mvn ${MAVEN_PLUGIN}:meta\n        mvn ${MAVEN_PLUGIN}:build\n        mvn ${MAVEN_PLUGIN}:workspace\n        mvn ${MAVEN_PLUGIN}:clean\n        mvn ${MAVEN_PLUGIN}:test\n\n        if [[ ! -z $MAIN_CLASS ]]\n        then\n            mvn ${MAVEN_PLUGIN}:binary -DmainClass=${MAIN_CLASS}\n        fi\n        ;;\n\n    -c | --clean )\n        $BAZEL_BIN clean --expunge\n        rm -f bazelize.out bazelize.out.html\n        ;;\n\n    -b | --build )\n        $BAZEL_BIN build ... --strict_java_deps=off --profile=bazelize.out\n        $BAZEL_BIN analyze-profile --html bazelize.out\n        ;;\n\n    -t | --test )\n        $BAZEL_BIN test ... --strict_java_deps=off --test_output all\n        ;;\n\n    -r | --run )\n        if [[ -z $MAIN_CLASS ]]\n        then\n            echo \"ERROR: no main class is given\"\n        else\n            MAIN_BAZEL=${MAIN_CLASS//./_}\n            $BAZEL_BIN run $MAIN_BAZEL\n        fi\n        ;;\nesac\nEOF\n```\n\nAfter making this script executable, migration and other other options are available:\n\n```\n## make the script executable\n$ chmod +x bazelize.sh\n\n## check options\n$ ./bazelize.sh -h\nusage:\n\t./bazelize.sh \u003coption\u003e\noptions:\n\tmigrate to bazel: -m | --migrate | -g | --generate\n\tclean bazel:      -c | --clean\n\tbuild with bazel: -b | --build\n\ttest with bazel:  -t | --test\n\trun with bazel:   -r | --run\nrequires Bazelisk for Bazel v0.14.1:\n\t/home/unknown/dev/bazelisk/bin/bazelisk-linux-amd64\n\n## migrate to Bazel\n$ ./bazelize.sh -m\n```\n\n\u0026nbsp;\n\n## Parameters\n\nParameters for each goal are supplied with **-Dname=value**, for example:\n\n```\n$ mvn kupusoglu.orhan:bazelize-maven-plugin:test -DsrcTest=src/test/java\n```\n\nThe **backup** and **suffix** parameters are useful for debugging the plugin.\n\nDetailed plugin documentation can be generated with [Maven Site Plugin](https://maven.apache.org/plugins/maven-site-plugin/)'s **mvn site** goal, please check the HTML pages at **target/site/index.html**.\nFor example: **Project Reports \u003e Plugin Documentation \u003e bazelize:test**\n\n### goal: clean\n| Parameter | Default Value | Description                                                            |\n| :-------- | ------------- | ---------------------------------------------------------------------- |\n| expunge   | false         | delete all generated files including **BUILD** and **WORKSPACE** files |\n\n### goal: module\n| Parameter        | Default Value                               | Description                                                                             |\n| :--------------- | ------------------------------------------- | --------------------------------------------------------------------------------------- |\n| backup           | false                                       | if true back up the **BUILD** and **tmp-bzl-meta.json** files - to be used by LifeCycle |\n| suffix           | \"\"                                          | if empty set current timestamp as suffix - to be used by LifeCycle                      |\n| whiteListPattern | \"src/\"                                      | pattern for directories to include                                                      |\n| blackListPattern | \"/test\u0026#124;/integration-test\u0026#124;/target\" | pattern for directories to exclude                                                      |\n\n### goal: meta\n| Parameter        | Default Value        | Description                                      |\n| :--------------- | -------------------- | ------------------------------------------------ |\n| backup           | false                | if true back up the **tmp-bzl-meta.json** files  |\n| suffix           | \"\"                   | if empty set current timestamp as suffix         |\n\n### goal: build\n| Parameter        | Default Value        | Description                                      |\n| :--------------- | -------------------- | ------------------------------------------------ |\n| settingsFile     | \"../settings.xml\"    | path of the settings file relative to local repo |\n| backup           | false                | if true back up the **BUILD** files              |\n| suffix           | \"\"                   | if empty set current timestamp as suffix         |\n| blackListPattern | \"^jdk_tools\"         | add dependency to the black list to be ignored   |\n| defaultServer    | \"central\"            | default remote repository                        |\n| addScope         | true                 | set scope of the Maven dependency                |\n| addHash          | false                | add hash of the Maven dependency                 |\n| addServer        | false                | add remote server of the Maven dependency        |\n| resMain          | \"src/main/resources\" | path of the resource files                       |\n\n### goal: workspace\n| Parameter     | Default Value | Description                              |\n| :------------ | ------------- | ---------------------------------------- |\n| backup        | false         | if true back up the **WORKSPACE** file   |\n| suffix        | \"\"            | if empty set current timestamp as suffix |\n| workspaceName | \"\"            | if empty no workspace() line is added    |\n\n### goal: test\n| Parameter | Default Value        | Description                              |\n| :---------| -------------------- | ---------------------------------------- |\n| backup    | false                | if true back  up the **BUILD** files     |\n| suffix    | \"\"                   | if empty set current timestamp as suffix |\n| srcTest   | \"src/test/java\"      | path of the test source files            |\n| resTest   | \"src/test/resources\" | path of the test resource files          |\n\n### goal: binary\n| Parameter     | Default Value  | Description                                        |\n| :------------ | -------------- | -------------------------------------------------- |\n| backup        | false          | if true back up the **BUILD** file                 |\n| suffix        | \"\"             | if empty set current timestamp as suffix           |\n| binName       | \"\"             | if empty use name of the main class as rule's name |\n| mainClass     |                | name of the main class, **required**               |\n\n\u0026nbsp;\n\n## Next Steps\n\nUnlike a [Hello World](https://en.wikipedia.org/wiki/%22Hello,_World!%22_program) application, a large Java Maven project like [ONOS SDN Controller](https://onosproject.org/) will require some tweaks.\n\n### Parameters\n\nThe **module** goal can add or remove source file locations with the **whiteListPattern** and **blackListPattern** parameters respectively:\n\n```\n$ mvn bazelize:module -DwhiteListPattern=src/ -DblackListPattern=/test|/integration-test|/target\n```\n\nThe **build** goal can eliminate unwanted dependencies with the **blackListPattern** parameter:\n\n```\n$ mvn bazelize:build -DblackListPattern=\"^jdk_tools|^com_sun_tools\"\n```\n\nThe **workspace** goal may add name to the WORKSPACE:\n```\n$ mvn bazelize:workspace -DworkspaceName=my-app\n$ head -n 1 WORKSPACE\nworkspace(name = \"my-app\")\n```\n\n### Files\n\nPre-arranged text files containing Bazel rules can simply be *prepended* or *appended* to **WORKSPACE** and specific **BUILD** scripts.\n\nAnother option is the **bzl-build-dependency.json** files. The **module** goal reads these files to add or remove source files, which are located in unusual directories. The **build** goal reads these files to add or remove dependencies to configure Bazel for correct builds .\n\n```\n$ cat bzl-build-dependency.json\n{\n    \"srcWhiteList\": [\"src/main/java/org/project/white/net\"],\n    \"srcBlackList\": [\"src/main/java/org/project/black/net\"],\n    \"depBlackList\": [\"^jdk_tools\", \"^com_sun_tools\"],\n    \"addDep\": [\":exp_rule\"],\n    \"removeDep\": [\"@io_netty_netty_3_10_5_Final//jar\",\n                  \"@io_netty_netty_all_4_0_31_Final//jar\"]\n}\n```\n\n| FILE                                    | DESCRIPTION                                             |\n| :-------------------------------------- | ------------------------------------------------------- |\n| **bzl\u0026dash;build-prepend\u0026dash;txt**     | Prepend Bazel rules to a BUILD file                     |\n| **bzl\u0026dash;build\u0026dash;append.txt**      | Append Bazel rules to a BUILD file                      |\n| **bzl\u0026dash;build\u0026dash;dependency.json** | Inject or remove dependencies/sources from a BUILD file |\n| **bzl-workspace-prepend.txt**           | Prepend Bazel rules to a WORKSPACE file                 |\n| **bzl-workspace-append.txt**            | Append Bazel rules to a WORKSPACE file                  |\n\n\u0026nbsp;\n\n## Source Lines of Code\n\n[SLOC](https://en.wikipedia.org/wiki/Source_lines_of_code) of the project can be counted by the [Source Lines of Code Maven Plugin](https://github.com/OrhanKupusoglu/sloc-maven-plugin).\n\n```\n$ mvn kupusoglu.orhan:sloc-maven-plugin:sloc\n[INFO] Scanning for projects...\n[INFO] Inspecting build with total of 1 modules...\n[INFO] Installing Nexus Staging features:\n[INFO]   ... total of 1 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin\n[INFO]\n[INFO] ---------------\u003c kupusoglu.orhan:bazelize-maven-plugin \u003e----------------\n[INFO] Building Maven-to-Bazel Migration Plugin 0.3.3\n[INFO] ----------------------------[ maven-plugin ]----------------------------\n[INFO]\n[INFO] --- sloc-maven-plugin:0.1.4:sloc (default-cli) @ bazelize-maven-plugin ---\n[INFO] SLOC - directory: /home/orhanku/ME/DEV/OK/bazelize-maven-plugin/src\n+------------------+----------------------+----------+----------+----------+----------+----------+----------+\n| Package Name     | File Name            | Type     | Blank    | JavaDoc  | Comment  | Code     | Total    |\n+------------------+----------------------+----------+----------+----------+----------+----------+----------+\n| goal             | GoalBinary.java      | src      |       14 |       26 |        0 |       52 |       92 |\n| goal             | GoalBuild.java       | src      |       77 |       50 |       10 |      282 |      419 |\n| goal             | GoalClean.java       | src      |        9 |       16 |        0 |       35 |       60 |\n| goal             | GoalMeta.java        | src      |       11 |       20 |        0 |       39 |       70 |\n| goal             | GoalModule.java      | src      |       33 |       42 |        1 |      121 |      197 |\n| goal             | GoalTest.java        | src      |       13 |       28 |        0 |       48 |       89 |\n| goal             | GoalWorkspace.java   | src      |       12 |       24 |        0 |       41 |       77 |\n| goal             | LifeCycle.java       | src      |       26 |        5 |        2 |      106 |      139 |\n+------------------+----------------------+----------+----------+----------+----------+----------+----------+\n| model            | Common.java          | src      |      107 |       12 |        9 |      508 |      636 |\n| model            | CommonTest.java      | test     |       40 |        0 |        0 |      150 |      190 |\n| model            | CreateBinary.java    | src      |       22 |        7 |        2 |      109 |      140 |\n| model            | CreateTest.java      | src      |       26 |        7 |        2 |      112 |      147 |\n| model            | CreateWorkspace.java | src      |       45 |        7 |        0 |      169 |      221 |\n| model            | FindMeta.java        | src      |       31 |        6 |        0 |      111 |      148 |\n| model            | MavenDependency.java | src      |       34 |       22 |        0 |      145 |      201 |\n| model            | MavenMeta.java       | src      |       41 |        3 |        0 |      158 |      202 |\n| model            | MavenServer.java     | src      |       23 |       17 |        0 |       71 |      111 |\n| model            | SaveBinary.java      | src      |       12 |        3 |        0 |       43 |       58 |\n| model            | SaveMeta.java        | src      |       12 |        3 |        0 |       34 |       49 |\n| model            | SaveTest.java        | src      |       12 |        3 |        0 |       46 |       61 |\n| model            | SaveWorkspace.java   | src      |       12 |        3 |        0 |       42 |       57 |\n| model            | SourceMeta.java      | src      |       28 |       14 |        0 |      140 |      182 |\n+------------------+----------------------+----------+----------+----------+----------+----------+----------+\n| 2 package(s)     | 22 file(s)           | java     |      640 |      318 |       26 |     2562 |     3546 |\n+------------------+----------------------+----------+----------+----------+----------+----------+----------+\n\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time: 0.992 s\n[INFO] Finished at: 2018-12-05T10:06:48+03:00\n[INFO] ------------------------------------------------------------------------\n```\n","funding_links":[],"categories":["Tooling"],"sub_categories":["Migration"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOrhanKupusoglu%2Fbazelize-maven-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOrhanKupusoglu%2Fbazelize-maven-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOrhanKupusoglu%2Fbazelize-maven-plugin/lists"}