Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose list of all artifacts, including transitive #648

Merged
merged 4 commits into from
Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ To use it, add the load statement to the top of your BUILD file:
load("@rules_jvm_external//:defs.bzl", "artifact")
```

Full `group:artifact:[packaging:[classifier:]]version` maven coordinates are also
supported and translate to corresponding versionless target.

Note that usage of this macro makes BUILD file refactoring with tools like
`buildozer` more difficult, because the macro hides the actual target label at
the syntax level.
Expand Down Expand Up @@ -855,6 +858,31 @@ maven_install(
)
```

It is also possible to change strict visibility value from default `//visibility:private`
to a value specified by `strict_visibility_value` attribute.

### Accessing transitive dependencies list

It is possible to retrieve full list of dependencies in the dependency tree, including
transitive, source, javadoc and other artifacts. `maven_artifacts` list contains full
versioned maven coordinate strings of all dependencies.

For example:
```python
load("@maven//:defs.bzl", "maven_artifacts")

load("@rules_jvm_external//:defs.bzl", "artifact")
load("@rules_jvm_external//:specs.bzl", "parse")

all_jar_coordinates = [c for c in maven_artifacts if parse.parse_maven_coordinate(c).get("packaging", "jar") == "jar"]
all_jar_targets = [artifact(c) for c in all_jar_coordinates]

java_library(
name = "depends_on_everything",
runtime_deps = all_jar_targets,
)
```

### Fetch and resolve timeout

The default timeout to fetch and resolve artifacts is 600 seconds. If you need
Expand Down
4 changes: 4 additions & 0 deletions coursier.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -471,11 +471,13 @@ def _pinned_coursier_fetch_impl(repository_ctx):
"load(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")",
"def pinned_maven_install():",
]
maven_artifacts = []
netrc_entries = {}

for artifact in dep_tree["dependencies"]:
if artifact.get("url") != None:
http_file_repository_name = escape(artifact["coord"])
maven_artifacts.extend([artifact["coord"]])
http_files.extend([
" http_file(",
" name = \"%s\"," % http_file_repository_name,
Expand All @@ -499,6 +501,8 @@ def _pinned_coursier_fetch_impl(repository_ctx):

http_files.extend(_get_jq_http_files())

http_files.extend(["maven_artifacts = [\n%s\n]" % (",\n".join([" \"%s\"" % artifact for artifact in maven_artifacts]))])

repository_ctx.file("defs.bzl", "\n".join(http_files), executable = False)
repository_ctx.file(
"netrc",
Expand Down
4 changes: 4 additions & 0 deletions private/coursier_utilities.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def strip_packaging_and_classifier(coord):
return ":".join(coordinates)

def strip_packaging_and_classifier_and_version(coord):
coordinates = coord.split(":")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding a test to tests/unit/coursier_utilities_test.bzl for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a test case now

# Support for simplified versionless groupId:artifactId coordinate format
if len(coordinates) == 2:
return ":".join(coordinates)
return ":".join(strip_packaging_and_classifier(coord).split(":")[:-1])

# TODO: Should these methods be combined with _parse_maven_coordinate_string in specs.
Expand Down
22 changes: 14 additions & 8 deletions private/rules/artifact.bzl
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
load("//:specs.bzl", "parse")
load("//private:constants.bzl", "DEFAULT_REPOSITORY_NAME")
load("//private:coursier_utilities.bzl", "strip_packaging_and_classifier_and_version")

def artifact(a, repository_name = DEFAULT_REPOSITORY_NAME):
artifact_obj = _parse_artifact_str(a) if type(a) == "string" else a
return "@%s//:%s" % (repository_name, _escape(artifact_obj["group"] + ":" + artifact_obj["artifact"]))
artifact_str = _make_artifact_str(a) if type(a) != "string" else a
return "@%s//:%s" % (repository_name, _escape(strip_packaging_and_classifier_and_version(artifact_str)))

def maven_artifact(a):
return artifact(a, repository_name = DEFAULT_REPOSITORY_NAME)

def _escape(string):
return string.replace(".", "_").replace("-", "_").replace(":", "_")

def _parse_artifact_str(artifact_str):
pieces = artifact_str.split(":")
if len(pieces) == 2:
return {"group": pieces[0], "artifact": pieces[1]}
else:
return parse.parse_maven_coordinate(artifact_str)
# inverse of parse_maven_coordinate
def _make_artifact_str(artifact_obj):
# produce either simplified g:a or standard g:a:[p:[c:]]v Maven coordinate string
coord = [artifact_obj["group"], artifact_obj["artifact"]]
if "version" in artifact_obj:
if "packaging" in artifact_obj:
coord.extend([artifact_obj["packaging"]])
if "classifier" in artifact_obj:
coord.extend([artifact_obj["classifier"]])
coord.extend([artifact_obj["version"]])
return ":".join(coord)
6 changes: 6 additions & 0 deletions tests/unit/coursier_utilities_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ def _strip_packaging_and_classifier_and_version_test_impl(ctx):
"groupId:artifactId",
strip_packaging_and_classifier_and_version("groupId:artifactId:pom:sources:version"),
)
# versionless coordinates aren't standard Maven coordinates but are useful for the artifact() macro
asserts.equals(
env,
"groupId:artifactId",
strip_packaging_and_classifier_and_version("groupId:artifactId"),
)
return unittest.end(env)

strip_packaging_and_classifier_and_version_test = unittest.make(_strip_packaging_and_classifier_and_version_test_impl)
Expand Down