Skip to content

Commit 4c5059c

Browse files
committed
Move crawler/query related logic out of pom generation code
1 parent 564f2ea commit 4c5059c

File tree

8 files changed

+177
-214
lines changed

8 files changed

+177
-214
lines changed

examples/dependency-management/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Dependency Management POM Example
22

3-
This examples shows how pomgen can optionally generate a dependencyManagement "companion" pom. This pom file is generate in addition to the regular pom.xml, when the attribute `generate_dependency_management_pom` is to to `True` in the [BUILD.pom file](juicer/MVN-INF/BUILD.pom).
3+
This examples shows how pomgen can optionally generate a dependencyManagement "companion" pom. This pom file is generated in addition to the regular pom.xml, when the attribute `generate_dependency_management_pom` is to to `True` in the [BUILD.pom file](juicer/MVN-INF/BUILD.pom).
44

55
The dependency management pom contains a `<dependencyManagement>` section with the transitive closure of all dependencies of the artifact it was generated for. It uses the `artifact_id` specified in the BUILD.pom file, suffixed with `.depmanagement`.
66

misc/extdeps_pomgen.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,13 @@ def _parse_arguments(args):
5050

5151

5252
class ThirdPartyDepsPomGen(pom.DynamicPomGen):
53+
5354
def __init__(self, workspace, artifact_def, dependencies, pom_template):
5455
super(ThirdPartyDepsPomGen, self).__init__(workspace, artifact_def,
5556
dependency=None,
5657
pom_template=pom_template)
5758
self.dependencies = dependencies
5859

59-
def _load_additional_dependencies_hook(self):
60-
return self.dependencies
61-
6260

6361
def _starts_with_ignored_prefix(line):
6462
for prefix in IGNORED_DEPENDENCY_PREFIXES:
@@ -71,11 +69,12 @@ def main(args):
7169
repo_root = common.get_repo_root(args.repo_root)
7270
cfg = config.load(repo_root)
7371

74-
# For the primary function of pomgen (generating pom.xml files for publishing)
75-
# there are sometimes maven_install namespaces that are ignored in .pomgenrc.
76-
# These are identified as maven_install paths that begin with - .
77-
# For extdeps, we need to have full access to all maven_install namespaces, so
78-
# we tell maveninstallinfo to not honor the excludes.
72+
# For the primary function of pomgen, generating pom.xml files for
73+
# publishing to Nexus or similar, there are sometimes maven_install
74+
# namespaces that are ignored in .pomgenrc
75+
# These are identified as maven_install paths that begin with -
76+
# For extdeps, we need to have full access to all maven_install namespaces,
77+
# so we tell maveninstallinfo to not honor those excludes
7978
allow_excludes = False
8079

8180
mvn_install_info = maveninstallinfo.MavenInstallInfo(cfg.maven_install_paths, allow_excludes)
@@ -141,7 +140,7 @@ def main(args):
141140

142141
pomgen = ThirdPartyDepsPomGen(ws, artifact_def, dependencies,
143142
cfg.pom_template)
144-
pomgen.process_dependencies()
143+
145144
return pomgen.gen(pom.PomContentType.RELEASE)
146145

147146

src/crawl/artifactprocessor.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,14 @@ def augment_artifact_def(repo_root_path,
2222
art_def,
2323
source_exclusions,
2424
change_detection_enabled):
25+
26+
# library path
2527
art_def.library_path = _get_library_path(repo_root_path, art_def)
2628

29+
# build file exists?
30+
art_def._has_build_file = _has_build_file(repo_root_path, art_def)
31+
32+
# release state
2733
if art_def.released_version is None or art_def.released_artifact_hash is None:
2834
# never released?
2935
art_def.requires_release = True
@@ -49,6 +55,15 @@ def augment_artifact_def(repo_root_path,
4955
return art_def
5056

5157

58+
def _has_build_file(repo_root_path, art_def):
59+
path = os.path.join(repo_root_path, art_def.bazel_package)
60+
if os.path.exists(os.path.join(path, "BUILD")):
61+
return True
62+
if os.path.exists(os.path.join(path, "BUILD.bazel")):
63+
return True
64+
return False
65+
66+
5267
def _get_library_path(repo_root_path, art_def):
5368
"""
5469
Starts at the path the specified artifact lives at and "walks up" to find

src/crawl/buildpom.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
class MavenArtifactDef(object):
1919
"""
20-
Represents an instance of a maven_artifact rule defined in BUILD.pom file.
20+
Represents an instance of a maven_artifact rule defined in a BUILD.pom file.
2121
Information from the BUILD.pom.released file is added, if that file exists.
2222
2323
@@ -67,34 +67,39 @@ class MavenArtifactDef(object):
6767
6868
==== Read out of the optional BUILD.pom.released file ====
6969
70-
released_version: the previously released version to Nexus
70+
released_version: the previously released version to Nexus.
7171
7272
released_artifact_hash: the hash of the artifact at the time it was
73-
previously released to Nexus
73+
previously released to Nexus.
7474
7575
76-
77-
===== Internal attributes (never specified by the user) ====
76+
===== Internal attributes (never specified by the user in config/md files)
7877
7978
deps: additional targets this package depends on; list of Bazel labels.
80-
For example: deps = ["//projects/libs/servicelibs/srpc/srpc-thrift-svc-runtime"]
79+
For example: deps = ["//projects/libs/srpc/srpc-thrift-svc-runtime"]
80+
The deps attribute is typically only used by tests, that's why it is
81+
listed here under "internal attributes", although it is specified in the
82+
BUILD.pom file.
8183
82-
The deps attribute is only used by tests.
84+
bazel_package: the bazel package (relative path to the directory) where the
85+
MVN-INF directory and the build file live. The build file is not
86+
guaranteed to exist (see attr below) because pomgen supports "pom only"
87+
artifacts, which are foreign to bazel.
8388
84-
bazel_package: the bazel package the BUILD (and MVN-INF/) files live in
89+
has_build_file: whether the bazel package actually has a build file.
8590
86-
bazel_target: the bazel target that builds this artifact
91+
bazel_target: the bazel target that builds this artifact.
8792
8893
library_path: the path to the root directory of the library this artifact
89-
is part of
94+
is part of.
9095
9196
requires_release: whether this artifact should be released (to Nexus
92-
or local Maven repository)
97+
or local Maven repository).
9398
94-
release_reason: the reason for releasing this artifact
99+
release_reason: the reason for releasing this artifact.
95100
96101
released_pom_content: if the file pom.xml.released exists next to the
97-
BUILD.pom file, the content of the pom.xml.released file
102+
BUILD.pom file, the content of the pom.xml.released file.
98103
=====
99104
100105
@@ -144,6 +149,7 @@ def __init__(self,
144149
self._requires_release = requires_release
145150
self._release_reason = None
146151
self._released_pom_content = released_pom_content
152+
self._has_build_file = False
147153

148154
# data cleanup/verification/sanitization
149155
# these are separate methods for better readability
@@ -213,6 +219,10 @@ def released_artifact_hash(self, value):
213219
def bazel_package(self):
214220
return self._bazel_package
215221

222+
@property
223+
def has_build_file(self):
224+
return self._has_build_file
225+
216226
@property
217227
def bazel_target(self):
218228
return self._bazel_target

src/crawl/crawler.py

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,15 @@ def _crawl(self, package, dep, parent_node, follow_references):
534534

535535
self.package_to_artifact[package] = artifact_def
536536
self.library_to_artifact[artifact_def.library_path].append(artifact_def)
537-
pomgen = self._get_pom_generator(artifact_def, dep)
537+
if dep is None:
538+
# make a real dependency instance here
539+
# this is a bootstrapping problem: the root
540+
# artifacts (that we start with) have nothing pointing at them
541+
dep = dependency.new_dep_from_maven_artifact_def(artifact_def)
542+
pomgen = pom.get_pom_generator(self.workspace, self.pom_template,
543+
artifact_def, dep)
538544
self.pomgens.append(pomgen)
539-
source_deps, ext_deps, all_deps = pomgen.process_dependencies()
545+
source_deps, ext_deps, all_deps = self._discover_dependencies(artifact_def, dep)
540546
self.target_to_dependencies[target_key] = all_deps
541547
if self.verbose:
542548
logger.debug("Determined deps for artifact: [%s] with target key [%s]" % (artifact_def, target_key))
@@ -556,14 +562,58 @@ def _crawl(self, package, dep, parent_node, follow_references):
556562
self._store_if_leafnode(node)
557563
return node
558564

559-
def _get_pom_generator(self, artifact_def, dep):
560-
if dep is None:
561-
# make a real dependency instance here so we can pass it along
562-
# into the pom generator
563-
dep = dependency.new_dep_from_maven_artifact_def(artifact_def)
564-
return pom.get_pom_generator(self.workspace,
565-
self.pom_template, artifact_def,
566-
dep)
565+
def _discover_dependencies(self, artifact_def, dep):
566+
"""
567+
Discovers the dependencies of the given artifact (bazel target).
568+
569+
This method returns a tuple of 3 (!) lists of Dependency instances:
570+
(l1, l2, l3)
571+
l1: all source dependencies (== references to other bazel packages)
572+
l2: all external dependencies (maven jars)
573+
l3: l1 and l2 together, in "discovery order"
574+
"""
575+
assert artifact_def is not None
576+
assert dep is not None, "dep is None for artifact %s" % artifact_def
577+
all_deps = ()
578+
if artifact_def.deps is not None:
579+
all_deps = self.workspace.parse_dep_labels(artifact_def.deps)
580+
if artifact_def.has_build_file:
581+
all_deps += self._query_dependencies(artifact_def, dep)
582+
583+
source_dependencies = []
584+
ext_dependencies = []
585+
for dep in all_deps:
586+
if dep.bazel_package is None:
587+
ext_dependencies.append(dep)
588+
else:
589+
source_dependencies.append(dep)
590+
591+
return (tuple(source_dependencies),
592+
tuple(ext_dependencies),
593+
tuple(all_deps))
594+
595+
# this method delegates to bazel query to get the value of a bazel target's
596+
# "deps" and "runtime_deps" attributes
597+
def _query_dependencies(self, artifact_def, dependency):
598+
if not artifact_def.include_deps:
599+
return ()
600+
else:
601+
assert artifact_def.bazel_package is not None
602+
assert dependency.bazel_target is not None
603+
assert len(dependency.bazel_target) > 0
604+
label = "%s:%s" % (artifact_def.bazel_package, dependency.bazel_target)
605+
try:
606+
# the rule attributes to query for dependencies, typically
607+
# "deps" and "runtime_deps"
608+
attrs = artifact_def.pom_generation_mode.dependency_attributes
609+
dep_labels = bazel.query_java_library_deps_attributes(
610+
self.workspace.repo_root_path, label, attrs,
611+
self.workspace.verbose)
612+
deps = self.workspace.parse_dep_labels(dep_labels)
613+
return self.workspace.normalize_deps(artifact_def, deps)
614+
except Exception as e:
615+
msg = e.message if hasattr(e, "message") else type(e)
616+
raise Exception("Error while processing dependencies: %s %s caused by %s\nOne possible cause for this error is that the java_libary rule that builds the jar artifact is not the default bazel package target (same name as dir it lives in)" % (msg, artifact_def, repr(e)))
567617

568618
@classmethod
569619
def _get_target_key(clazz, package, dep, artifact_def=None):

src/crawl/pom.py

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from common import pomgenmode
1111
import copy
12-
from crawl import bazel
1312
from crawl import pomparser
1413
import os
1514
import re
@@ -90,38 +89,6 @@ def bazel_package(self):
9089
def dependency(self):
9190
return self._dependency
9291

93-
def process_dependencies(self):
94-
"""
95-
Discovers the dependencies of this artifact (bazel target).
96-
97-
This method *must* be called before requesting this instance to generate
98-
a pom.
99-
100-
This method returns a tuple of 3 (!) lists of Dependency instances:
101-
(l1, l2, l3)
102-
l1: all source dependencies (== references to other bazel packages)
103-
l2: all external dependencies (maven jars)
104-
l3: l1 and l2 together, in "discovery order"
105-
106-
This method is not meant to be overwritten by subclasses.
107-
"""
108-
all_deps = ()
109-
if self._artifact_def.deps is not None:
110-
all_deps = self._workspace.parse_dep_labels(self._artifact_def.deps)
111-
all_deps += self._load_additional_dependencies_hook()
112-
113-
source_dependencies = []
114-
ext_dependencies = []
115-
for dep in all_deps:
116-
if dep.bazel_package is None:
117-
ext_dependencies.append(dep)
118-
else:
119-
source_dependencies.append(dep)
120-
121-
return (tuple(source_dependencies),
122-
tuple(ext_dependencies),
123-
tuple(all_deps))
124-
12592
def register_dependencies(self, dependencies):
12693
"""
12794
Registers the dependencies the backing artifact references explicitly.
@@ -162,15 +129,6 @@ def get_companion_generators(self):
162129
"""
163130
return ()
164131

165-
def _load_additional_dependencies_hook(self):
166-
"""
167-
Returns a list of dependency instances referenced by the current
168-
package.
169-
170-
Only meant to be overridden by subclasses.
171-
"""
172-
return ()
173-
174132
def _artifact_def_version(self, pomcontenttype):
175133
"""
176134
Returns the associated artifact's version, based on the specified
@@ -279,10 +237,6 @@ class NoopPomGen(AbstractPomGen):
279237
def __init__(self, workspace, artifact_def, dependency):
280238
super(NoopPomGen, self).__init__(workspace, artifact_def, dependency)
281239

282-
def _load_additional_dependencies_hook(self):
283-
return _query_dependencies(self._workspace, self._artifact_def,
284-
self._dependency)
285-
286240

287241
class TemplatePomGen(AbstractPomGen):
288242

@@ -543,10 +497,6 @@ def gen(self, pomcontenttype):
543497
"#{dependencies}", self._gen_dependencies(pomcontenttype))
544498
return content
545499

546-
def _load_additional_dependencies_hook(self):
547-
return _query_dependencies(self._workspace, self._artifact_def,
548-
self._dependency)
549-
550500
def _gen_dependencies(self, pomcontenttype):
551501
content = ""
552502
content, indent = self._xml(content, "dependencies", indent=_INDENT)
@@ -687,9 +637,6 @@ def gen(self, pomcontenttype):
687637
def get_companion_generators(self):
688638
return (self.depmanpomgen,)
689639

690-
def _load_additional_dependencies_hook(self):
691-
return self.pomgen._load_additional_dependencies_hook()
692-
693640

694641
_INDENT = pomparser.INDENT
695642

@@ -702,34 +649,3 @@ def _sort(s):
702649
the_list = list(s)
703650
the_list.sort()
704651
return the_list
705-
706-
707-
# this method delegates to bazel query to get the value of a bazel target's
708-
# "deps" and "runtime_deps" attributes. it really doesn't belong in this module,
709-
# because it has nothing to do with generating a pom.xml file.
710-
# it could move into common.pomgenmode or live closer to the crawler
711-
def _query_dependencies(workspace, artifact_def, dependency):
712-
if not artifact_def.include_deps:
713-
return ()
714-
else:
715-
try:
716-
label = _build_bazel_label(artifact_def.bazel_package,
717-
dependency.bazel_target)
718-
719-
# the rule attributes to query for dependencies
720-
dep_attrs=artifact_def.pom_generation_mode.dependency_attributes
721-
dep_labels = bazel.query_java_library_deps_attributes(
722-
workspace.repo_root_path, label, dep_attrs,
723-
workspace.verbose)
724-
deps = workspace.parse_dep_labels(dep_labels)
725-
return workspace.normalize_deps(artifact_def, deps)
726-
except Exception as e:
727-
msg = e.message if hasattr(e, "message") else type(e)
728-
raise Exception("Error while processing dependencies: %s %s caused by %s\nOne possible cause for this error is that the java_libary rule that builds the jar artifact is not the default bazel package target (same name as dir it lives in)" % (msg, artifact_def, repr(e)))
729-
730-
731-
def _build_bazel_label(package, target):
732-
assert package is not None, "package should not be None"
733-
assert target is not None, "target should not be None"
734-
assert len(target) > 0, "target should not be an empty string for package [%s]" % package
735-
return "%s:%s" % (package, target)

tests/crawlertest_misc.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from config import config
1111
from crawl import crawler as crawlerm
1212
from crawl import dependencymd as dependencym
13-
from crawl import pom
1413
from crawl import pomcontent
1514
from crawl import workspace
1615

@@ -27,13 +26,6 @@ class CrawlerTest(unittest.TestCase):
2726
Various one-off crawler related test cases that require file-system setup.
2827
"""
2928

30-
def setUp(self):
31-
self.org_query_method = pom._query_dependencies
32-
pom._query_dependencies = lambda ws, art_def, dep: ()
33-
34-
def tearDown(self):
35-
pom._query_dependencies = self.org_query_method
36-
3729
def test_default_package_ref(self):
3830
"""
3931
lib/a2 can reference lib/a1.

0 commit comments

Comments
 (0)