Skip to content

Commit

Permalink
Allow non-default targets
Browse files Browse the repository at this point in the history
  • Loading branch information
simontoens committed Dec 13, 2024
1 parent 01e8116 commit 0170ff3
Show file tree
Hide file tree
Showing 18 changed files with 186 additions and 121 deletions.
24 changes: 19 additions & 5 deletions crawl/buildpom.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class MavenArtifactDef(object):
Represents an instance of a maven_artifact rule defined in BUILD.pom file.
Information from the BUILD.pom.released file is added, if that file exists.
==== Read out of the BUILD.pom file ====
group_id: the maven artifact groupId of the bazel package.
Expand Down Expand Up @@ -64,6 +65,7 @@ class MavenArtifactDef(object):
version_increment_strategy_name: specifies how this artifacts version should
be incremented.
==== Read out of the optional BUILD.pom.released file ====
released_version: the previously released version to Nexus
Expand All @@ -72,19 +74,22 @@ class MavenArtifactDef(object):
previously released to Nexus
===== Internal attributes (never specified by the user) ====
deps: additional targets this package depends on; list of Bazel labels.
For example: deps = ["//projects/libs/servicelibs/srpc/srpc-thrift-svc-runtime"]
Only used by tests.
The deps attribute is only used by tests.
bazel_package: the bazel package the BUILD (and MVN-INF/) files live in
bazel_package: the bazel package the BUILD.pom file lives in
bazel_target: the bazel target that builds this artifact
library_path: the path to the root directory of the library this
monorepo package is part of
library_path: the path to the root directory of the library this artifact
is part of
requires_release: whether this monorepo package should be released (to Nexus
requires_release: whether this artifact should be released (to Nexus
or local Maven repository)
release_reason: the reason for releasing this artifact
Expand All @@ -93,6 +98,7 @@ class MavenArtifactDef(object):
BUILD.pom file, the content of the pom.xml.released file
=====
Implementation notes:
- properties are kept read-only whenever possible
- the constructor provides default values for easier instantiation
Expand All @@ -115,6 +121,7 @@ def __init__(self,
released_version=None,
released_artifact_hash=None,
bazel_package=None,
bazel_target=None,
library_path=None,
requires_release=None,
released_pom_content=None):
Expand All @@ -133,6 +140,7 @@ def __init__(self,
self._released_version = released_version
self._released_artifact_hash = released_artifact_hash
self._bazel_package = bazel_package
self._bazel_target = bazel_target
self._library_path = library_path
self._requires_release = requires_release
self._release_reason = None
Expand Down Expand Up @@ -206,6 +214,10 @@ def released_artifact_hash(self, value):
def bazel_package(self):
return self._bazel_package

@property
def bazel_target(self):
return self._bazel_target

@property
def library_path(self):
return self._library_path
Expand Down Expand Up @@ -279,6 +291,7 @@ def parse_maven_artifact_def(root_path, package):
additional_change_detected_packages=ma_attrs.get("additional_change_detected_packages", []),
gen_dependency_management_pom=ma_attrs.get("generate_dependency_management_pom", False),
jar_path=ma_attrs.get("jar_path", None),
bazel_target=ma_attrs.get("target_name", None),
deps=ma_attrs.get("deps", []))

template_path = ma_attrs.get("pom_template_file", None)
Expand Down Expand Up @@ -348,6 +361,7 @@ def _augment_art_def_values(user_art_def, rel_art_def, bazel_package,
gen_dependency_management_pom=False if user_art_def.gen_dependency_management_pom is None else user_art_def.gen_dependency_management_pom,
jar_path=None if user_art_def.jar_path is None else os.path.normpath(os.path.join(bazel_package, mdfiles.MD_DIR_NAME, user_art_def.jar_path)),
deps=user_art_def.deps,
bazel_target=user_art_def.bazel_target if user_art_def.bazel_target is not None else os.path.basename(bazel_package),
released_version=rel_art_def.version if rel_art_def is not None else None,
released_artifact_hash=rel_art_def.artifact_hash if rel_art_def is not None else None,
bazel_package=bazel_package,
Expand Down
39 changes: 12 additions & 27 deletions crawl/crawler.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,11 @@ def _get_deps_transitive_closure_for_library(self, library_path,
# other, but these references are not guaranteed)
artifacts = self.library_to_artifact[library_path]
for art_def in artifacts:
all_deps.add(dependency.new_dep_from_maven_artifact_def(art_def, bazel_target=None))

all_deps.add(dependency.new_dep_from_maven_artifact_def(art_def))
return all_deps

def _get_crawled_packages_as_deps(self):
deps = [dependency.new_dep_from_maven_artifact_def(art_def, bazel_target=None) for art_def in self.package_to_artifact.values()]
deps = [dependency.new_dep_from_maven_artifact_def(art_def) for art_def in self.package_to_artifact.values()]
deps = set(self._filter_non_artifact_referencing_deps(deps))
return deps

Expand Down Expand Up @@ -510,7 +509,10 @@ def _crawl(self, package, dep, parent_node, follow_references):
Returns a Node instance for the crawled package.
"""
target_key = self._get_target_key(package, dep)
artifact_def = self.workspace.parse_maven_artifact_def(package)
if artifact_def is None:
raise Exception("No artifact defined at package %s" % package)
target_key = self._get_target_key(package, dep, artifact_def)
if target_key in self.target_to_node:
# if we have already processed this target, we can re-use the
# children we discovered previously
Expand All @@ -532,13 +534,7 @@ def _crawl(self, package, dep, parent_node, follow_references):
else:
if self.verbose:
logger.info("Processing [%s]" % target_key)
artifact_def = self.workspace.parse_maven_artifact_def(package)

if artifact_def is None:
raise Exception("No artifact defined at package %s" % package)

self._validate_default_target_dep(parent_node, dep, artifact_def)

self.package_to_artifact[package] = artifact_def
self.library_to_artifact[artifact_def.library_path].append(artifact_def)
pomgen = self._get_pom_generator(artifact_def, dep)
Expand All @@ -563,20 +559,6 @@ def _crawl(self, package, dep, parent_node, follow_references):
self._store_if_leafnode(node)
return node

def _validate_default_target_dep(self, parent_node, dep, artifact_def):
if dep is not None:
if artifact_def.pom_generation_mode.produces_artifact:
# if the current bazel target produces an artifact
# (pom/jar that goes to Nexus), validate that the BUILD
# file pointing at this target uses the default bazel
# package target
# this is a current pomgen requirement:
# 1 bazel package produces one artifact, named after the
# bazel package
dflt_package_name = os.path.basename(artifact_def.bazel_package)
if dep.bazel_target != dflt_package_name:
raise Exception("Non default-package references are only supported to non-artifact producing packages: [%s] can only reference [%s], [%s:%s] is not allowed" % (parent_node.artifact_def.bazel_package, artifact_def.bazel_package, artifact_def.bazel_package, dep.bazel_target))

def _get_pom_generator(self, artifact_def, dep):
if dep is None:
# make a real dependency instance here so we can pass it along
Expand All @@ -587,12 +569,15 @@ def _get_pom_generator(self, artifact_def, dep):
dep)

@classmethod
def _get_target_key(clazz, package, dep):
def _get_target_key(clazz, package, dep, artifact_def=None):
if dep is None:
target = os.path.basename(package)
# initial bootstrap - we start a bazel package and we don't
# have a dep pointing here
assert artifact_def is not None
target = artifact_def.bazel_target
else:
target = dep.bazel_target
assert target is not None, "Target is None for dep %s" % dep
assert target is not None, "Target is None for package %s" % package
return "%s:%s" % (package, target)

def _store_if_leafnode(self, node):
Expand Down
5 changes: 3 additions & 2 deletions crawl/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,9 @@ def new_dep_from_maven_art_str(maven_artifact_str, name):


def new_dep_from_maven_artifact_def(artifact_def, bazel_target=None):
if bazel_target is not None:
assert len(bazel_target) > 0, "bazel target must not be empty for artifact def %s" % artifact_def.bazel_package
if bazel_target is None:
bazel_target = artifact_def.bazel_target
assert bazel_target is not None
return MonorepoDependency(artifact_def, bazel_target)


Expand Down
2 changes: 1 addition & 1 deletion crawl/pomparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,5 +213,5 @@ def _import_lxml():
return etree
except ImportError as ex:
print("Module lxml is not installed, please execute the following in your environment:")
print("pip install --user lxml")
print("pip3 install --user lxml")
return None
2 changes: 1 addition & 1 deletion crawl/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def _parse_dep_label(self, dep_label):
raise Exception("Unknown external dependency - please make sure all maven install json files have been registered with pomgen (by setting maven_install_paths in the pomgen config file): [%s]" % dep_label)
return self._label_to_ext_dep[dep_label]
elif dep_label.startswith("//"):
# monorepo src ref:
# src ref:
package_path = dep_label[2:] # remove leading "//"
target_name = None
i = package_path.rfind(":")
Expand Down
2 changes: 1 addition & 1 deletion examples/hello-world/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The command above specifies:
- The **library** to generate poms for: `examples/hello-world/juicer`


pomgen follows refernces between libraries; since `juicer` depends on 2 other libraries `healthyfoods` and `wintervegerables`, pomgen generated pom.xml files for all 3 libraries, ie for all modules that are part of those libraries. Usually this is the right behavior, but if there a lot of upstream libraries, it may be desirable in some cases to not follow library references. This can be accomplished by setting `-i` (ignore references) flag:
pomgen follows references between libraries; since `juicer` depends on 2 other libraries `healthyfoods` and `wintervegerables`, pomgen generated pom.xml files for all 3 libraries, ie for all modules that are part of those libraries. Usually this is the right behavior, but if there a lot of upstream libraries, it may be desirable in some cases to not follow library references. This can be accomplished by setting `-i` (ignore references) flag:

```
bazel run @pomgen//maven -- -a pomgen -l examples/hello-world/juicer -i
Expand Down
6 changes: 3 additions & 3 deletions examples/hello-world/juicer/BUILD
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
java_library(
name = "juicer",
name = "juicer_lib",
srcs = glob(["src/main/java/**/*.java"]),
deps = ["//examples/hello-world/healthyfoods/fruit-api",
"//examples/hello-world/healthyfoods/vegetable-api",
"//examples/hello-world/wintervegetables",
"//examples/hello-world/wintervegetables:wintervegetables_lib2",
"@maven//:com_google_guava_guava",
]
)

java_binary(
name = "make-juice",
runtime_deps = [":juicer"],
runtime_deps = [":juicer_lib"],
main_class = "com.pomgen.example.Main",
)
1 change: 1 addition & 0 deletions examples/hello-world/juicer/MVN-INF/BUILD.pom
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ maven_artifact(
artifact_id = "juicer",
version = "10.0.0-qual1-SNAPSHOT",
pom_generation_mode = "dynamic",
target_name = "juicer_lib",
)

maven_artifact_update(
Expand Down
2 changes: 1 addition & 1 deletion examples/hello-world/wintervegetables/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
java_library(
name = "wintervegetables",
name = "wintervegetables_lib2",
srcs = glob(["src/main/java/**/*.java"]),
deps = ["//examples/hello-world/healthyfoods/vegetable-api"],
visibility = ["//examples/hello-world/juicer:__subpackages__"],
Expand Down
1 change: 1 addition & 0 deletions examples/hello-world/wintervegetables/MVN-INF/BUILD.pom
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ maven_artifact(
artifact_id = "wintervegetables",
version = "20200416.1-SNAPSHOT",
pom_generation_mode = "dynamic",
target_name = "wintervegetables_lib2",
)

maven_artifact_update(
Expand Down
27 changes: 17 additions & 10 deletions maven/maven_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,24 @@ _for_each_pom() {
process_jar_artifact=0
else
echo "ERROR: Did not find jar at custom path [${jar_artifact_path}]."
echo "This is a bug"
exit 1
fi
else
local build_pom_path="$src_dir_package_path/MVN-INF/BUILD.pom"
# check if the BUILD.pom file specifies a custom target name
local target_name=$(grep target_name "$build_pom_path" | grep -v '^[[:space:]]*#' | tr -s ' ' | cut -d= -f2 | tr -d '", ' || echo -n "")
if [ -z "$target_name" ]; then
# default target
target_name="$package_name"
fi
# the filename of the jar built by Bazel uses this pattern:
jar_artifact_path="$build_dir_package_path/lib${package_name}.jar"
jar_artifact_path="$build_dir_package_path/lib${target_name}.jar"
# bazel's java_library rule has an implicit target that builds
# a jar containing the sources, see
# https://bazel.build/reference/be/java#java_library:
# lib<name>-src.jar: An archive containing the sources
# note that this file only exists if that implicit target ran!
sources_jar_path="$build_dir_package_path/lib${package_name}-src.jar"
sources_jar_path="$build_dir_package_path/lib${target_name}-src.jar"
if [ ! -f "${jar_artifact_path}" ]; then
echo "WARN: lib${package_name}.jar not found, looking for alternatives"
# we also support executable jars - this is an edge case but
Expand All @@ -117,19 +123,20 @@ _for_each_pom() {

# first we look for the special <target-name>_deploy.jar
# created by java_binary
jar_artifact_path="$build_dir_package_path/${package_name}_deploy.jar"
jar_artifact_path="$build_dir_package_path/${target_name}_deploy.jar"
if [ -f "${jar_artifact_path}" ]; then
echo "INFO: Found ${package_name}_deploy.jar"
echo "INFO: Found ${jar_artifact_path}"
else
# last attempt: maybe a jar called <target-name>.jar
# exists
jar_artifact_path="$build_dir_package_path/${package_name}.jar"
# exists - this is used by springboot packaging:
# https://github.com/salesforce/rules_spring
jar_artifact_path="$build_dir_package_path/${target_name}.jar"
if [ -f "${jar_artifact_path}" ]; then
echo "INFO: Found ${package_name}.jar"
echo "INFO: Found ${jar_artifact_path}"
fi
fi
# we've seen jar break in weird ways when trying to unjar
# large "uber" jars:
# we've seen the jar cmd break in weird ways when trying
# to unjar large "uber" jars:
# java.io.FileNotFoundException: META-INF/LICENSE (Is a directory)
# so do not attempt to add the generated pom.xml to uber
# jars, since the pom isn't required for uber jars anyway:
Expand Down
Loading

0 comments on commit 0170ff3

Please sign in to comment.