blob: 68766a34f0ef0d39f3f00d902f02ea362de9200b [file] [log] [blame]
GERRIT = "GERRIT:"
GERRIT_API = "GERRIT_API:"
MAVEN_CENTRAL = "MAVEN_CENTRAL:"
MAVEN_LOCAL = "MAVEN_LOCAL:"
ECLIPSE = "ECLIPSE:"
MAVEN_SNAPSHOT = "https://oss.sonatype.org/content/repositories/snapshots"
SNAPSHOT = "-SNAPSHOT-"
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
repository = ctx.attr.repository
if "-SNAPSHOT-" in version:
start = version.index(SNAPSHOT)
end = start + len(SNAPSHOT) - 1
# file version without snapshot constant, but with post snapshot suffix
file_version = version[:start] + version[end:]
# version without post snapshot suffix
version = version[:end]
# overwrite the repository with Maven snapshot repository
repository = MAVEN_SNAPSHOT
jar = artifact.lower() + "-" + file_version
url = "/".join([
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 += "%s = [\'%s\']," % (attr, deps[0])
else:
formatted_deps += "%s = [\n" % attr
for dep in deps:
formatted_deps += " \'%s\',\n" % dep
formatted_deps += " ],"
return formatted_deps
def _generate_build_files(ctx, binjar, srcjar):
header = "# DO NOT EDIT: automatically generated BUILD file for maven_jar rule %s" % ctx.name
srcjar_attr = ""
if srcjar:
srcjar_attr = 'srcjar = "%s",' % srcjar
contents = """
{header}
load("@rules_java//java:defs.bzl", "java_import")
package(default_visibility = ['//visibility:public'])
java_import(
name = 'jar',
jars = ['{binjar}'],
{srcjar_attr}
{deps}
{exports}
)
java_import(
name = 'neverlink',
jars = ['{binjar}'],
neverlink = 1,
{deps}
{exports}
)
\n""".format(
srcjar_attr = srcjar_attr,
header = header,
binjar = binjar,
deps = _format_deps("deps", ctx.attr.deps),
exports = _format_deps("exports", ctx.attr.exports),
)
if srcjar:
contents += """
java_import(
name = 'src',
jars = ['{srcjar}'],
)
""".format(srcjar = srcjar)
ctx.file("%s/BUILD" % ctx.path("jar"), contents, False)
# Compatibility layer for java_import_external from rules_closure
contents = """
{header}
package(default_visibility = ['//visibility:public'])
alias(
name = "{rule_name}",
actual = "@{rule_name}//jar",
)
\n""".format(rule_name = ctx.name, header = header)
ctx.file("BUILD", contents, False)
def _maven_jar_impl(ctx):
"""rule to download a Maven archive."""
coordinates = _create_coordinates(ctx.attr.artifact)
name = ctx.name
sha1 = ctx.attr.sha1
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"
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", 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))
srcjar = None
if ctx.attr.src_sha1 or ctx.attr.attach_source:
srcjar = jar + "-src.jar"
srcurl = url + "-sources.jar"
srcjar_path = ctx.path("jar/" + srcjar)
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_files(ctx, binjar, 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(),
"src_sha1": attr.string(),
"unsign": attr.bool(default = False),
"exports": attr.string_list(),
"deps": attr.string_list(),
"_download_script": attr.label(default = Label("//tools:download_file.py")),
},
local = True,
implementation = _maven_jar_impl,
)