Skip to content

Commit 744af9b

Browse files
authored
Ability add or excluded additional dependencies. (#212)
1 parent cc4c17c commit 744af9b

File tree

11 files changed

+136
-9
lines changed

11 files changed

+136
-9
lines changed

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ py_library(
1919
"src/generate/impl/py/*.py"]),
2020
data = ["src/config/pom_template.xml"],
2121
visibility = ["//misc:__pkg__",],
22+
imports = ["src"],
2223
)
2324

2425
py_binary(

docs/mdfiles.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ Default value: `None`
9191

9292
See the `java_import` [example](../examples/java-import).
9393

94+
##### maven_artifact.emitted_dependencies
95+
96+
Additional dependencies, as a list of strings to include/exclude in/from the generated manifest. Exclusions are specified by prefixing the dependency with a `-`. The dependencies are specified using their "target manifest" syntax, for example, for pom files, they use "gav" syntax for inclusion and `-group_id:artifact_id` for exclusion.
97+
98+
Default value: `[]`
99+
94100

95101
### LIBRARY.root (required)
96102

examples/hello-world/juicer/MVN-INF/BUILD.pom

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ maven_artifact(
44
version = "10.0.0-qual1-SNAPSHOT",
55
pom_generation_mode = "dynamic",
66
target_name = "juicer_lib",
7+
emitted_dependencies = ["com.sales:foo:1.0.0"],
78
)
89

910
maven_artifact_update(

src/crawl/buildpom.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ class MavenArtifactDef(object):
6464
version_increment_strategy_name: specifies how this artifacts version should
6565
be incremented.
6666
67+
emitted_dependencies: specifies extra dependencies to include, or exclude,
68+
in the generated manifest. Use manifest-native syntax, and prefix with
69+
'-' to exclude.
70+
6771
6872
==== Read out of the optional BUILD.pom.released file ====
6973
@@ -126,7 +130,8 @@ def __init__(self,
126130
bazel_target=None,
127131
library_path=None,
128132
requires_release=None,
129-
released_pom_content=None):
133+
released_pom_content=None,
134+
emitted_dependencies=[]):
130135
self._group_id = group_id
131136
self._artifact_id = artifact_id
132137
self._version = version
@@ -147,6 +152,7 @@ def __init__(self,
147152
self._requires_release = requires_release
148153
self._release_reason = None
149154
self._released_pom_content = released_pom_content
155+
self._emitted_dependencies = emitted_dependencies
150156

151157
# data cleanup/verification/sanitization
152158
# these are separate methods for better readability
@@ -251,6 +257,10 @@ def release_reason(self, value):
251257
def released_pom_content(self):
252258
return self._released_pom_content
253259

260+
@property
261+
def emitted_dependencies(self):
262+
return self._emitted_dependencies
263+
254264
@property
255265
def version_increment_strategy_name(self):
256266
return self._version_increment_strategy_name
@@ -294,7 +304,8 @@ def parse_maven_artifact_def(root_path, package):
294304
gen_dependency_management_pom=ma_attrs.get("generate_dependency_management_pom", False),
295305
jar_path=ma_attrs.get("jar_path", None),
296306
bazel_target=ma_attrs.get("target_name", None),
297-
deps=ma_attrs.get("deps", []))
307+
deps=ma_attrs.get("deps", []),
308+
emitted_dependencies=ma_attrs.get("emitted_dependencies", []))
298309

299310
template_path = ma_attrs.get("pom_template_file", None)
300311
if template_path is not None:
@@ -368,4 +379,5 @@ def _augment_art_def_values(user_art_def, rel_art_def, bazel_package,
368379
released_artifact_hash=rel_art_def.artifact_hash if rel_art_def is not None else None,
369380
bazel_package=bazel_package,
370381
released_pom_content=released_pom_content,
371-
version_increment_strategy_name=version_increment_strategy_name)
382+
version_increment_strategy_name=version_increment_strategy_name,
383+
emitted_dependencies=user_art_def.emitted_dependencies)

src/crawl/crawler.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,34 @@ def _register_dependencies(self, target_to_transitive_closure_deps):
183183
- the transitive closure of the library's dependencies
184184
"""
185185
for ctx in self.genctxs:
186-
directs = self.target_to_dependencies[ctx.label]
186+
additional_deps, excluded_deps = self._load_custom_output_dependencies(ctx.artifact_def)
187+
directs = [dep for dep in self.target_to_dependencies[ctx.label] if dep not in excluded_deps] + additional_deps
187188
ctx.register_artifact_directs(directs)
188-
transitive_closure = target_to_transitive_closure_deps[ctx.label]
189+
190+
transitive_closure = [dep for dep in target_to_transitive_closure_deps[ctx.label] if dep not in excluded_deps]
189191
ctx.register_artifact_transitive_closure(transitive_closure)
190-
lib_transitive_closure = self\
192+
193+
lib_transitive_closure = [dep for dep in self\
191194
._get_deps_transitive_closure_for_library(
192195
ctx.artifact_def.library_path,
193-
target_to_transitive_closure_deps)
196+
target_to_transitive_closure_deps) if dep not in excluded_deps]
194197
ctx.register_library_transitive_closure(lib_transitive_closure)
195198

199+
def _load_custom_output_dependencies(self, artifact_def):
200+
additional_deps = []
201+
excluded_deps = []
202+
for str_repr in artifact_def.emitted_dependencies:
203+
exclude = False
204+
if str_repr.startswith("-"):
205+
str_repr = str_repr[1:]
206+
exclude = True
207+
dep = self.generation_strategy.load_dependency_by_native_repr(str_repr)
208+
if exclude:
209+
excluded_deps.append(dep)
210+
else:
211+
additional_deps.append(dep)
212+
return additional_deps, excluded_deps
213+
196214
def _get_deps_transitive_closure_for_library(
197215
self, library_path, target_to_transitive_closure_deps):
198216
all_deps = set()

src/crawl/pom.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,6 @@ def _sort(s):
637637
"""
638638
Converts the specified set to a list, and returns the list, sorted.
639639
"""
640-
assert isinstance(s, set), "Expected a set"
641-
the_list = list(s)
640+
the_list = list(s) if isinstance(s, set) else s
642641
the_list.sort()
643642
return the_list

src/generate/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ def load_dependency(self, label, artifact_def):
2929
"""
3030
pass
3131

32+
@abstractmethod
33+
def load_dependency_by_native_repr(self, str_repr):
34+
pass
35+
3236
@abstractmethod
3337
def load_transitive_closure(self, dependency):
3438
"""

src/generate/impl/pomgenerationstrategy.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ def load_dependency(self, label, artifact_def):
2020
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]" % label.canonical_form)
2121
return self.workspace._label_to_ext_dep[label.canonical_form]
2222

23+
def load_dependency_by_native_repr(self, str_repr):
24+
if str_repr.count(":") == 1:
25+
str_repr += ":-1"
26+
return dependency.new_dep_from_maven_art_str(str_repr, None)
27+
2328
def load_transitive_closure(self, dependency):
2429
depmd = self.workspace.dependency_metadata
2530
return depmd.get_transitive_closure(dependency)

src/generate/impl/pygenerationstrategy.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,8 @@ def load_dependency(self, label, artifact_def):
5555
"""
5656
pass
5757

58+
def load_dependency_by_native_repr(self, str_repr):
59+
pass
60+
5861
def load_transitive_closure(self, dependency):
5962
pass

tests/crawlerunittest.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from common import maveninstallinfo
1111
from common import pomgenmode
1212
from config import config
13+
from crawl import artifactgenctx as artifactgenctx
1314
from crawl import buildpom
1415
from crawl import crawler as crawlerm
1516
from crawl import dependency
@@ -562,6 +563,72 @@ def test_remove_package_private_labels__skip_mode_allows_them(self):
562563

563564
self.assertEqual([l1, l2, l3, l4], labels)
564565

566+
def test_register_dependencies(self):
567+
pom_template = ""
568+
library_path = "projects/libs/lib"
569+
d1 = self._get_3rdparty_dep("com:d1:1.0.0", "d1")
570+
d2 = self._get_3rdparty_dep("com:d2:1.0.0", "d2")
571+
d3 = self._get_3rdparty_dep("com:d3:1.0.0", "d3")
572+
d4 = self._get_3rdparty_dep("com:d4:1.0.0", "d4")
573+
node1 = self._build_node("art1", "projects/libs/lib/p1",
574+
library_path=library_path)
575+
node2 = self._build_node("art2", "projects/libs/lib/p2",
576+
library_path=library_path)
577+
ws = self._get_workspace()
578+
ctx = artifactgenctx.ArtifactGenerationContext(
579+
ws, pom_template, node1.artifact_def, node1.label)
580+
strategy = pomgenerationstrategy.PomGenerationStrategy(ws, pom_template)
581+
crawler = crawlerm.Crawler(ws, strategy, pom_template)
582+
crawler.library_to_nodes[library_path].append(node1)
583+
crawler.library_to_nodes[library_path].append(node2)
584+
crawler.genctxs = [ctx]
585+
crawler.target_to_dependencies = {node1.label: [d1,d2]}
586+
target_to_transitive_closure_deps = {
587+
node1.label: [d1, d2, d3],
588+
node2.label: [d4],
589+
}
590+
591+
crawler._register_dependencies(target_to_transitive_closure_deps)
592+
593+
self.assertEqual(set([d1, d2]), set(ctx.direct_dependencies))
594+
self.assertEqual(set([d1, d2, d3]), set(ctx.artifact_transitive_closure))
595+
self.assertEqual(set([d1, d2, d3, d4]), set(ctx.library_transitive_closure))
596+
597+
def test_register_dependencies_with_exclusions(self):
598+
pom_template = ""
599+
library_path = "projects/libs/lib"
600+
d1 = self._get_3rdparty_dep("com:d1:1.0.0", "d1")
601+
d2 = self._get_3rdparty_dep("com:d2:1.0.0", "d2")
602+
d3 = self._get_3rdparty_dep("com:d3:1.0.0", "d3")
603+
d4 = self._get_3rdparty_dep("com:d4:1.0.0", "d4")
604+
d5 = self._get_3rdparty_dep("com:d5:1.0.0", "d5")
605+
node1 = self._build_node("art1", "projects/libs/lib/p1",
606+
library_path=library_path)
607+
node2 = self._build_node("art2", "projects/libs/lib/p2",
608+
library_path=library_path)
609+
ws = self._get_workspace()
610+
ctx = artifactgenctx.ArtifactGenerationContext(
611+
ws, pom_template, node1.artifact_def, node1.label)
612+
strategy = pomgenerationstrategy.PomGenerationStrategy(ws, pom_template)
613+
crawler = crawlerm.Crawler(ws, strategy, pom_template)
614+
crawler.library_to_nodes[library_path].append(node1)
615+
crawler.library_to_nodes[library_path].append(node2)
616+
crawler.genctxs = [ctx]
617+
crawler.target_to_dependencies = {node1.label: [d1,d2]}
618+
target_to_transitive_closure_deps = {
619+
node1.label: [d1, d2, d3],
620+
node2.label: [d4],
621+
}
622+
# add one additional dependency and exclude d2
623+
node1.artifact_def._emitted_dependencies = ["com:d5:1.0.0", "-com:d2",]
624+
625+
crawler._register_dependencies(target_to_transitive_closure_deps)
626+
627+
self.assertEqual(set([d1, d5]), set(ctx.direct_dependencies))
628+
self.assertEqual(set([d1, d3]), set(ctx.artifact_transitive_closure))
629+
self.assertEqual(set([d1, d3, d4]), set(ctx.library_transitive_closure))
630+
631+
565632
def _build_node(self, artifact_id, bazel_package,
566633
pom_generation_mode=pomgenmode.DYNAMIC,
567634
parent_node=None, library_path=None):

0 commit comments

Comments
 (0)