blob: 46aa4c13892f181979a6fb77de8ff5f5679e0340 [file] [log] [blame]
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Port of Buck native gwt_binary() rule. See discussion in context of
# https://github.com/facebook/buck/issues/109
GERRIT = "GERRIT:"
GERRIT_API = "GERRIT_API:"
MAVEN_CENTRAL = "MAVEN_CENTRAL:"
MAVEN_LOCAL = "MAVEN_LOCAL:"
def _maven_release(ctx, parts):
"""induce jar and url name from maven coordinates."""
if len(parts) not in [3, 4]:
fail('%s:\nexpected id="groupId:artifactId:version[:classifier]"' %
ctx.attr.artifact)
if len(parts) == 4:
group, artifact, version, classifier = parts
file_version = version + "-" + classifier
else:
group, artifact, version = parts
file_version = version
jar = artifact.lower() + "-" + file_version
url = "/".join([
ctx.attr.repository,
group.replace(".", "/"),
artifact,
version,
artifact + "-" + file_version,
])
return jar, url
# Creates a struct containing the different parts of an artifact's FQN
def _create_coordinates(fully_qualified_name):
parts = fully_qualified_name.split(":")
packaging = None
classifier = None
if len(parts) == 3:
group_id, artifact_id, version = parts
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 _format_deps(attr, deps):
formatted_deps = ""
if deps:
if len(deps) == 1:
formatted_deps = formatted_deps + "%s = [\'%s\']," % (attr, deps[0])
else:
formatted_deps = formatted_deps + "%s = [\n" % attr
for dep in deps:
formatted_deps = formatted_deps + " \'%s\',\n" % dep
formatted_deps = formatted_deps + " ],"
return formatted_deps
# Provides the syntax "@jar_name//jar" for bin classifier
# and "@jar_name//src" for sources
def _generate_build_file(ctx, classifier, filename):
contents = """
# DO NOT EDIT: automatically generated BUILD file for maven_jar rule {rule_name}
java_import(
name = '{classifier}',
jars = ['{filename}'],
visibility = ['//visibility:public'],
{deps}
{exports}
)
java_import(
name = 'neverlink',
jars = ['{filename}'],
neverlink = 1,
visibility = ['//visibility:public'],
{deps}
{exports}
)
filegroup(
name = 'file',
srcs = ['{filename}'],
visibility = ['//visibility:public']
)\n""".format(
classifier = classifier,
rule_name = ctx.name,
filename = filename,
deps = _format_deps("deps", ctx.attr.deps),
exports = _format_deps("exports", ctx.attr.exports),
)
ctx.file("%s/BUILD" % ctx.path(classifier), contents, False)
def _maven_jar_impl(ctx):
"""rule to download a Maven archive."""
coordinates = _create_coordinates(ctx.attr.artifact)
name = ctx.name
parts = ctx.attr.artifact.split(":")
# TODO(davido): Only releases for now, implement handling snapshots
jar, url = _maven_release(ctx, parts)
binjar = jar + ".jar"
binjar_path = ctx.path("/".join(["jar", binjar]))
binurl = url + ".jar"
srcjar = jar + "-src.jar"
srcjar_path = ctx.path("/".join(["src", srcjar]))
srcurl = url + "-sources.jar"
python = ctx.which("python")
script = ctx.path(ctx.attr._download_script)
args = [python, script, "-o", binjar_path, "-u", binurl]
if ctx.attr.sha1:
args.extend(["-v", ctx.attr.sha1])
for x in ctx.attr.exclude:
args.extend(["-x", x])
out = ctx.execute(args)
if out.return_code:
fail("failed %s: %s" % (args, out.stderr))
_generate_build_file(ctx, "jar", binjar)
if ctx.attr.src_sha1 or ctx.attr.attach_source:
args = [python, script, "-o", srcjar_path, "-u", srcurl]
if ctx.attr.src_sha1:
args.extend(["-v", ctx.attr.src_sha1])
out = ctx.execute(args)
if out.return_code:
fail("failed %s: %s" % (args, out.stderr))
_generate_build_file(ctx, "src", srcjar)
maven_jar = repository_rule(
attrs = {
"artifact": attr.string(mandatory = True),
"attach_source": attr.bool(default = True),
"exclude": attr.string_list(),
"repository": attr.string(default = MAVEN_CENTRAL),
"sha1": attr.string(mandatory = False),
"src_sha1": attr.string(),
"exports": attr.string_list(),
"deps": attr.string_list(),
"_download_script": attr.label(default = Label("//tools:download_file.py")),
},
local = True,
implementation = _maven_jar_impl,
)