diff options
Diffstat (limited to 'tools/build_defs/repo/maven_rules.bzl')
-rw-r--r-- | tools/build_defs/repo/maven_rules.bzl | 334 |
1 files changed, 161 insertions, 173 deletions
diff --git a/tools/build_defs/repo/maven_rules.bzl b/tools/build_defs/repo/maven_rules.bzl index 953532dd98..8e18b9ddd2 100644 --- a/tools/build_defs/repo/maven_rules.bzl +++ b/tools/build_defs/repo/maven_rules.bzl @@ -44,101 +44,96 @@ DEPS = ["mvn", "openssl", "awk"] MVN_PLUGIN = "org.apache.maven.plugins:maven-dependency-plugin:2.10" - def _execute(ctx, command): - return ctx.execute(["bash", "-c", """ + return ctx.execute(["bash", "-c", """ set -ex %s""" % command]) - # Fail fast def _check_dependencies(ctx): - for dep in DEPS: - if ctx.which(dep) == None: - fail("%s requires %s as a dependency. Please check your PATH." % (ctx.name, dep)) - + for dep in DEPS: + if ctx.which(dep) == None: + fail("%s requires %s as a dependency. Please check your PATH." % (ctx.name, dep)) def _validate_attr(ctx): - if hasattr(ctx.attr, "server") and (ctx.attr.server != None): - fail("%s specifies a 'server' attribute which is currently not supported." % ctx.name) - + if hasattr(ctx.attr, "server") and (ctx.attr.server != None): + fail("%s specifies a 'server' attribute which is currently not supported." % ctx.name) def _artifact_dir(coordinates): - return "/".join(coordinates.group_id.split(".") + - [coordinates.artifact_id, coordinates.version]) - + return "/".join(coordinates.group_id.split(".") + + [coordinates.artifact_id, coordinates.version]) # Creates a struct containing the different parts of an artifact's FQN. # If the fully_qualified_name does not specify a packaging and the rule does # not set a default packaging then JAR is assumed. -def _create_coordinates(fully_qualified_name, packaging="jar"): - parts = fully_qualified_name.split(":") - classifier = None - - if len(parts) == 3: - group_id, artifact_id, version = parts - # Updates the FQN with the default packaging so that the Maven plugin - # downloads the correct artifact. - fully_qualified_name = "%s:%s" % (fully_qualified_name, packaging) - elif len(parts) == 4: - group_id, artifact_id, version, packaging = parts - elif len(parts) == 5: - group_id, artifact_id, version, packaging, classifier = parts - else: - fail("Invalid fully qualified name for artifact: %s" % fully_qualified_name) - - return struct( - fully_qualified_name = fully_qualified_name, - group_id = group_id, - artifact_id = artifact_id, - packaging = packaging, - classifier = classifier, - version = version, - ) - +def _create_coordinates(fully_qualified_name, packaging = "jar"): + parts = fully_qualified_name.split(":") + classifier = None + + if len(parts) == 3: + group_id, artifact_id, version = parts + + # Updates the FQN with the default packaging so that the Maven plugin + # downloads the correct artifact. + fully_qualified_name = "%s:%s" % (fully_qualified_name, packaging) + elif len(parts) == 4: + group_id, artifact_id, version, packaging = parts + elif len(parts) == 5: + group_id, artifact_id, version, packaging, classifier = parts + else: + fail("Invalid fully qualified name for artifact: %s" % fully_qualified_name) + + return struct( + fully_qualified_name = fully_qualified_name, + group_id = group_id, + artifact_id = artifact_id, + packaging = packaging, + classifier = classifier, + version = version, + ) # NOTE: Please use this method to define ALL paths that the maven_* # rules use. Doing otherwise will lead to inconsistencies and/or errors. # # CONVENTION: *_path refers to files, *_dir refers to directories. def _create_paths(ctx, coordinates): - """Creates a struct that contains the paths to create the cache WORKSPACE""" - - # e.g. guava-18.0.jar - artifact_filename = "%s-%s" % (coordinates.artifact_id, - coordinates.version) - if coordinates.classifier: - artifact_filename += "-" + coordinates.classifier - artifact_filename += "." + coordinates.packaging - sha1_filename = "%s.sha1" % artifact_filename + """Creates a struct that contains the paths to create the cache WORKSPACE""" - # e.g. com/google/guava/guava/18.0 - relative_artifact_dir = _artifact_dir(coordinates) - - # The symlink to the actual artifact is stored in this dir, along with the - # BUILD file. The dir has the same name as the packaging to support syntax - # like @guava//jar and @google_play_services//aar. - symlink_dir = coordinates.packaging - - m2 = ".m2" - m2_repo = "/".join([m2, "repository"]) # .m2/repository - - return struct( - artifact_filename = artifact_filename, - sha1_filename = sha1_filename, - - symlink_dir = ctx.path(symlink_dir), - - # e.g. external/com_google_guava_guava/ \ - # .m2/repository/com/google/guava/guava/18.0/guava-18.0.jar - artifact_path = ctx.path("/".join([m2_repo, relative_artifact_dir, artifact_filename])), - artifact_dir = ctx.path("/".join([m2_repo, relative_artifact_dir])), - - sha1_path = ctx.path("/".join([m2_repo, relative_artifact_dir, sha1_filename])), - - # e.g. external/com_google_guava_guava/jar/guava-18.0.jar - symlink_artifact_path = ctx.path("/".join([symlink_dir, artifact_filename])), - ) + # e.g. guava-18.0.jar + artifact_filename = "%s-%s" % ( + coordinates.artifact_id, + coordinates.version, + ) + if coordinates.classifier: + artifact_filename += "-" + coordinates.classifier + artifact_filename += "." + coordinates.packaging + sha1_filename = "%s.sha1" % artifact_filename + + # e.g. com/google/guava/guava/18.0 + relative_artifact_dir = _artifact_dir(coordinates) + + # The symlink to the actual artifact is stored in this dir, along with the + # BUILD file. The dir has the same name as the packaging to support syntax + # like @guava//jar and @google_play_services//aar. + symlink_dir = coordinates.packaging + + m2 = ".m2" + m2_repo = "/".join([m2, "repository"]) # .m2/repository + + return struct( + artifact_filename = artifact_filename, + sha1_filename = sha1_filename, + symlink_dir = ctx.path(symlink_dir), + + # e.g. external/com_google_guava_guava/ \ + # .m2/repository/com/google/guava/guava/18.0/guava-18.0.jar + artifact_path = ctx.path("/".join([m2_repo, relative_artifact_dir, artifact_filename])), + artifact_dir = ctx.path("/".join([m2_repo, relative_artifact_dir])), + sha1_path = ctx.path("/".join([m2_repo, relative_artifact_dir, sha1_filename])), + + # e.g. external/com_google_guava_guava/jar/guava-18.0.jar + symlink_artifact_path = ctx.path("/".join([symlink_dir, artifact_filename])), + ) _maven_jar_build_file_template = """ # DO NOT EDIT: automatically generated BUILD file for maven_jar rule {rule_name} @@ -178,98 +173,95 @@ filegroup( # Provides the syntax "@jar_name//jar" for dependencies def _generate_build_file(ctx, template, paths): - deps_string = "\n".join(["'%s'," % dep for dep in ctx.attr.deps]) - contents = template.format( - rule_name = ctx.name, - artifact_filename = paths.artifact_filename, - deps_string = deps_string) - ctx.file('%s/BUILD' % paths.symlink_dir, contents, False) - + deps_string = "\n".join(["'%s'," % dep for dep in ctx.attr.deps]) + contents = template.format( + rule_name = ctx.name, + artifact_filename = paths.artifact_filename, + deps_string = deps_string, + ) + ctx.file("%s/BUILD" % paths.symlink_dir, contents, False) def _file_exists(ctx, filename): - return _execute(ctx, "[[ -f %s ]] && exit 0 || exit 1" % filename).return_code == 0 - + return _execute(ctx, "[[ -f %s ]] && exit 0 || exit 1" % filename).return_code == 0 # Constructs the maven command to retrieve the dependencies from remote # repositories using the dependency plugin, and executes it. def _mvn_download(ctx, paths, fully_qualified_name): - # If a custom settings file exists, we'll use that. If not, Maven will use the default settings. - mvn_flags = "" - if hasattr(ctx.attr, "settings") and ctx.attr.settings != None: - ctx.symlink(ctx.attr.settings, "settings.xml") - mvn_flags += "-s %s " % "settings.xml" - - # dependency:get step. Downloads the artifact into the local repository. - mvn_get = MVN_PLUGIN + ":get" - mvn_artifact = "-Dartifact=%s" % fully_qualified_name - mvn_transitive = "-Dtransitive=false" - if hasattr(ctx.attr, "repository") and ctx.attr.repository != "": - mvn_flags += "-Dmaven.repo.remote=%s " % ctx.attr.repository - command = " ".join(["mvn", mvn_flags, mvn_get, mvn_transitive, mvn_artifact]) - exec_result = _execute(ctx, command) - if exec_result.return_code != 0: - fail("%s\n%s\nFailed to fetch Maven dependency" % (exec_result.stdout, exec_result.stderr)) - - # dependency:copy step. Moves the artifact from the local repository into //external. - mvn_copy = MVN_PLUGIN + ":copy" - mvn_output_dir = "-DoutputDirectory=%s" % paths.artifact_dir - command = " ".join(["mvn", mvn_flags, mvn_copy, mvn_artifact, mvn_output_dir]) - exec_result = _execute(ctx, command) - if exec_result.return_code != 0: - fail("%s\n%s\nFailed to fetch Maven dependency" % (exec_result.stdout, exec_result.stderr)) - + # If a custom settings file exists, we'll use that. If not, Maven will use the default settings. + mvn_flags = "" + if hasattr(ctx.attr, "settings") and ctx.attr.settings != None: + ctx.symlink(ctx.attr.settings, "settings.xml") + mvn_flags += "-s %s " % "settings.xml" + + # dependency:get step. Downloads the artifact into the local repository. + mvn_get = MVN_PLUGIN + ":get" + mvn_artifact = "-Dartifact=%s" % fully_qualified_name + mvn_transitive = "-Dtransitive=false" + if hasattr(ctx.attr, "repository") and ctx.attr.repository != "": + mvn_flags += "-Dmaven.repo.remote=%s " % ctx.attr.repository + command = " ".join(["mvn", mvn_flags, mvn_get, mvn_transitive, mvn_artifact]) + exec_result = _execute(ctx, command) + if exec_result.return_code != 0: + fail("%s\n%s\nFailed to fetch Maven dependency" % (exec_result.stdout, exec_result.stderr)) + + # dependency:copy step. Moves the artifact from the local repository into //external. + mvn_copy = MVN_PLUGIN + ":copy" + mvn_output_dir = "-DoutputDirectory=%s" % paths.artifact_dir + command = " ".join(["mvn", mvn_flags, mvn_copy, mvn_artifact, mvn_output_dir]) + exec_result = _execute(ctx, command) + if exec_result.return_code != 0: + fail("%s\n%s\nFailed to fetch Maven dependency" % (exec_result.stdout, exec_result.stderr)) def _check_sha1(ctx, paths, sha1): - actual_sha1 = _execute(ctx, "openssl sha1 %s | awk '{printf $2}'" % paths.artifact_path).stdout - - if sha1.lower() != actual_sha1.lower(): - fail(("{rule_name} has SHA-1 of {actual_sha1}, " + - "does not match expected SHA-1 ({expected_sha1})").format( - rule_name = ctx.name, - expected_sha1 = sha1, - actual_sha1 = actual_sha1)) - else: - _execute(ctx, "echo %s %s > %s" % (sha1, paths.artifact_path, paths.sha1_path)) - + actual_sha1 = _execute(ctx, "openssl sha1 %s | awk '{printf $2}'" % paths.artifact_path).stdout + + if sha1.lower() != actual_sha1.lower(): + fail(("{rule_name} has SHA-1 of {actual_sha1}, " + + "does not match expected SHA-1 ({expected_sha1})").format( + rule_name = ctx.name, + expected_sha1 = sha1, + actual_sha1 = actual_sha1, + )) + else: + _execute(ctx, "echo %s %s > %s" % (sha1, paths.artifact_path, paths.sha1_path)) def _maven_artifact_impl(ctx, default_rule_packaging, build_file_template): - # Ensure that we have all of the dependencies installed - _check_dependencies(ctx) - - # Provide warnings and errors about attributes - _validate_attr(ctx) + # Ensure that we have all of the dependencies installed + _check_dependencies(ctx) - # Create a struct to contain the different parts of the artifact FQN - coordinates = _create_coordinates(ctx.attr.artifact, default_rule_packaging) + # Provide warnings and errors about attributes + _validate_attr(ctx) - # Create a struct to store the relative and absolute paths needed for this rule - paths = _create_paths(ctx, coordinates) + # Create a struct to contain the different parts of the artifact FQN + coordinates = _create_coordinates(ctx.attr.artifact, default_rule_packaging) - _generate_build_file( - ctx = ctx, - template = build_file_template, - paths = paths, - ) + # Create a struct to store the relative and absolute paths needed for this rule + paths = _create_paths(ctx, coordinates) - if _execute(ctx, "mkdir -p %s" % paths.symlink_dir).return_code != 0: - fail("%s: Failed to create dirs in execution root.\n" % ctx.name) + _generate_build_file( + ctx = ctx, + template = build_file_template, + paths = paths, + ) - # Download the artifact - _mvn_download( - ctx = ctx, - paths = paths, - fully_qualified_name = coordinates.fully_qualified_name - ) + if _execute(ctx, "mkdir -p %s" % paths.symlink_dir).return_code != 0: + fail("%s: Failed to create dirs in execution root.\n" % ctx.name) - if (ctx.attr.sha1 != ""): - _check_sha1( + # Download the artifact + _mvn_download( ctx = ctx, paths = paths, - sha1 = ctx.attr.sha1, + fully_qualified_name = coordinates.fully_qualified_name, ) - ctx.symlink(paths.artifact_path, paths.symlink_artifact_path) + if (ctx.attr.sha1 != ""): + _check_sha1( + ctx = ctx, + paths = paths, + sha1 = ctx.attr.sha1, + ) + ctx.symlink(paths.artifact_path, paths.symlink_artifact_path) _common_maven_rule_attrs = { "artifact": attr.string( @@ -285,11 +277,10 @@ _common_maven_rule_attrs = { } def _maven_jar_impl(ctx): - _maven_artifact_impl(ctx, "jar", _maven_jar_build_file_template) - + _maven_artifact_impl(ctx, "jar", _maven_jar_build_file_template) def _maven_aar_impl(ctx): - _maven_artifact_impl(ctx, "aar", _maven_aar_build_file_template) + _maven_artifact_impl(ctx, "aar", _maven_aar_build_file_template) maven_jar = repository_rule( implementation = _maven_jar_impl, @@ -298,18 +289,17 @@ maven_jar = repository_rule( "repository": attr.string(default = ""), "server": attr.label(default = None), }.items()), - local=False, + local = False, ) maven_aar = repository_rule( - implementation=_maven_aar_impl, - attrs=_common_maven_rule_attrs, - local=False, + implementation = _maven_aar_impl, + attrs = _common_maven_rule_attrs, + local = False, ) - def _maven_dependency_plugin_impl(ctx): - _BUILD_FILE = """ + _BUILD_FILE = """ # DO NOT EDIT: automatically generated BUILD file for maven_dependency_plugin filegroup( @@ -318,9 +308,9 @@ filegroup( visibility = ['//visibility:public'] ) """ - ctx.file("BUILD", _BUILD_FILE, False) + ctx.file("BUILD", _BUILD_FILE, False) - _SETTINGS_XML = """ + _SETTINGS_XML = """ <!-- # DO NOT EDIT: automatically generated settings.xml for maven_dependency_plugin --> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" @@ -336,27 +326,25 @@ filegroup( </mirrors> </settings> """.format( - localRepository = ctx.path("repository"), - mirror = MAVEN_CENTRAL_URL, - ) - settings_path = ctx.path("settings.xml") - ctx.file("%s" % settings_path, _SETTINGS_XML, False) - - # Download the plugin with transitive dependencies - mvn_flags = "-s %s" % settings_path - mvn_get = MVN_PLUGIN + ":get" - mvn_artifact = "-Dartifact=%s" % MVN_PLUGIN - command = " ".join(["mvn", mvn_flags, mvn_get, mvn_artifact]) + localRepository = ctx.path("repository"), + mirror = MAVEN_CENTRAL_URL, + ) + settings_path = ctx.path("settings.xml") + ctx.file("%s" % settings_path, _SETTINGS_XML, False) - exec_result = _execute(ctx, command) - if exec_result.return_code != 0: - fail("%s\nFailed to fetch Maven dependency" % exec_result.stderr) + # Download the plugin with transitive dependencies + mvn_flags = "-s %s" % settings_path + mvn_get = MVN_PLUGIN + ":get" + mvn_artifact = "-Dartifact=%s" % MVN_PLUGIN + command = " ".join(["mvn", mvn_flags, mvn_get, mvn_artifact]) + exec_result = _execute(ctx, command) + if exec_result.return_code != 0: + fail("%s\nFailed to fetch Maven dependency" % exec_result.stderr) _maven_dependency_plugin = repository_rule( - implementation=_maven_dependency_plugin_impl, + implementation = _maven_dependency_plugin_impl, ) - def maven_dependency_plugin(): - _maven_dependency_plugin(name = "m2") + _maven_dependency_plugin(name = "m2") |