def test_normalize_deps__skip_pomgen_mode_allows_refs_to_same_package( self): ws = workspace.Workspace("so/path", [], exclusions.src_exclusions(), maveninstallinfo.NOOP, pom_content=pomcontent.NOOP) package = "a/b/c" art1 = buildpom.MavenArtifactDef("g1", "a1", "1", bazel_package=package, pom_generation_mode=pomgenmode.SKIP) dep1 = dependency.MonorepoDependency(art1, bazel_target=None) art2 = buildpom.MavenArtifactDef("g2", "a2", "1", bazel_package=package) dep2 = dependency.MonorepoDependency(art2, bazel_target=None) art3 = buildpom.MavenArtifactDef("g1", "a1", "1", bazel_package="d/e/f") dep3 = dependency.MonorepoDependency(art3, bazel_target=None) dep4 = dependency.ThirdPartyDependency("name", "g101", "a101", "1") # the result of this method is based on bazel_package comparison deps = ws.normalize_deps(art1, [dep1, dep2, dep3, dep4]) self.assertEqual([dep1, dep2, dep3, dep4], deps)
def test_template_var_sub__monorepo_deps(self): """ Verifies references to monorepo versions in a pom template. """ ws = workspace.Workspace("some/path", "", [], exclusions.src_exclusions()) artifact_def = buildpom.MavenArtifactDef("groupId", "artifactId", "1.2.3") srpc_artifact_def = buildpom.MavenArtifactDef("com.grail.srpc", "srpc-api", "5.6.7") dep = dependency.new_dep_from_maven_artifact_def(artifact_def) pomgen = pom.TemplatePomGen(ws, artifact_def, dep, template_content=""" srpc #{com.grail.srpc:srpc-api:version}""") pomgen.register_dependencies_globally( set([ dependency.MonorepoDependency(srpc_artifact_def, bazel_target=None) ]), set()) generated_pom = pomgen.gen() self.assertIn("srpc 5.6.7", generated_pom)
def test_library_root(self): repo_root = tempfile.mkdtemp("monorepo") art_def_1 = buildpom.MavenArtifactDef("g1", "a1", "1.0.0", bazel_package="lib1/pack1") self._touch_file_at_path(repo_root, "lib1", "MVN-INF", "LIBRARY.root") art_def_2 = buildpom.MavenArtifactDef("g1", "a2", "1.0.0", bazel_package="foo/lib2/pack1") self._touch_file_at_path(repo_root, "foo/lib2", "MVN-INF", "LIBRARY.root") art_def_1 = artifactprocessor.augment_artifact_def(repo_root, art_def_1, exclusions.src_exclusions()) art_def_2 = artifactprocessor.augment_artifact_def(repo_root, art_def_2, exclusions.src_exclusions()) self.assertEqual("lib1", art_def_1.library_path) self.assertEqual("foo/lib2", art_def_2.library_path)
def test_dot_gitignore_changes_are_ignored(self): src_exclusions = exclusions.src_exclusions(file_names=(".gitignore", )) package = "a/b/c" repo_root_path = self._setup_repo_with_package(package) self._touch_file_at_path(repo_root_path, package, "MVN-INF", "BUILD.pom") self._touch_file_at_path(repo_root_path, package, "f", ".gitignore") self._commit(repo_root_path) current_artifact_hash = git.get_dir_hash(repo_root_path, [package], src_exclusions) art_def = buildpom.MavenArtifactDef( "g1", "a1", "1.1.0", bazel_package=package, released_version="1.2.0", released_artifact_hash=current_artifact_hash) # update .md file - that change should be ignored self._touch_file_at_path(repo_root_path, package, "f", ".gitignore") self._commit(repo_root_path) art_def = artifactprocessor.augment_artifact_def( repo_root_path, art_def, src_exclusions) self.assertNotEqual(None, art_def.requires_release) self.assertFalse(art_def.requires_release)
def test_depman_pom__sanity(self): """ Ensures that dependency management pom generation isn't totally broken. """ ws = workspace.Workspace("some/path", [], exclusions.src_exclusions(), maveninstallinfo.NOOP, pomcontent.NOOP) artifact_def = buildpom.MavenArtifactDef( "g1", "a2", "1.2.3", gen_dependency_management_pom=True) dep = dependency.new_dep_from_maven_artifact_def(artifact_def) pomgen = pom.DependencyManagementPomGen(ws, artifact_def, dep, TEST_POM_TEMPLATE) guava = dependency.new_dep_from_maven_art_str("google:guava:1", "guav") force = dependency.new_dep_from_maven_art_str("force:commons:1", "forc") pomgen.register_dependencies_transitive_closure__artifact(( guava, force, )) generated_pom = pomgen.gen(pom.PomContentType.RELEASE) self.assertIn("<packaging>pom</packaging>", generated_pom) self.assertIn("<dependencyManagement>", generated_pom) self.assertIn("<artifactId>guava</artifactId>", generated_pom) self.assertIn("<artifactId>commons</artifactId>", generated_pom)
def test_template_var_sub__conflicting_gav__ext_and_BUILDpom(self): """ Verifies error handling when gavs are conflicting between external deps and what is set in BUILD.pom files. """ ws = workspace.Workspace("some/path", [], exclusions.src_exclusions(), self._mocked_mvn_install_info("maven"), pomcontent.NOOP) artifact_def = buildpom.maven_artifact("groupId", "artifactId", "1.2.3") dep = dependency.new_dep_from_maven_artifact_def(artifact_def) artifact_def.custom_pom_template_content = "srpc #{g:a:version}" pomgen = pom.TemplatePomGen(ws, artifact_def, dep) art = buildpom.MavenArtifactDef("com.google.guava", "guava", "26.0", bazel_package="a/b/c") d = dependency.MonorepoDependency(art, bazel_target=None) pomgen.register_dependencies_transitive_closure__library(set([d])) with self.assertRaises(Exception) as ctx: pomgen.gen(pom.PomContentType.RELEASE) self.assertIn( "Found multiple artifacts with the same groupId:artifactId", str(ctx.exception)) self.assertIn("com.google.guava:guava", str(ctx.exception))
def test_source_dependency__from_artifact_definition__no_changes(self): """ Ensures the Dependency instance for a source dependency looks right. Here we explicitly declare that the source has *NOT* changed since it was last released. """ group_id = "g1" artifact_id = "a1" version = "1.1.0" released_version = "1.2.3" package = "pack1" art_def = buildpom.MavenArtifactDef(group_id, artifact_id, version, bazel_package=package, requires_release=False, released_version=released_version, released_artifact_hash="123456789") dep = dependency.new_dep_from_maven_artifact_def(art_def, None) self.assertEqual(group_id, dep.group_id) self.assertEqual(artifact_id, dep.artifact_id) self.assertEqual(released_version, dep.version) self.assertEqual(package, dep.bazel_package) self.assertTrue(dep.external)
def test_pom_released_changes_are_ignored(self): package = "a/b/c" repo_root_path = self._setup_repo_with_package(package) self._touch_file_at_path(repo_root_path, package, "MVN-INF", "pom.xml.released") self._touch_file_at_path(repo_root_path, package, "", "some_file") self._commit(repo_root_path) current_artifact_hash = git.get_dir_hash(repo_root_path, [package], exclusions.src_exclusions()) art_def = buildpom.MavenArtifactDef( "g1", "a1", "1.1.0", bazel_package=package, released_version="1.2.0", released_artifact_hash=current_artifact_hash) # update pom.xml.released and commit - that change should be ignored self._touch_file_at_path(repo_root_path, package, "MVN-INF", "pom.xml.released") self._commit(repo_root_path) art_def = artifactprocessor.augment_artifact_def( repo_root_path, art_def, exclusions.src_exclusions()) self.assertNotEqual(None, art_def.requires_release) self.assertFalse(art_def.requires_release)
def test_template_var_sub__conflicting_gav__ext_and_BUILDpom(self): """ Verifies error handling when gavs are conflicting between external deps and what is set in BUILD.pom files. """ ws = workspace.Workspace( "some/path", """ native.maven_jar( name = "name", artifact = "g:a:20", )""", [], exclusions.src_exclusions()) artifact_def = buildpom.maven_artifact("groupId", "artifactId", "1.2.3") dep = dependency.new_dep_from_maven_artifact_def(artifact_def) pomgen = pom.TemplatePomGen(ws, artifact_def, dep, template_content=""" srpc #{g:a:version}""") art = buildpom.MavenArtifactDef("g", "a", "1", bazel_package="a/b/c") d = dependency.MonorepoDependency(art, bazel_target=None) pomgen.register_dependencies_globally(set([d]), set()) with self.assertRaises(Exception) as ctx: pomgen.gen() self.assertIn( "Found multiple artifacts with the same groupId:artifactId", str(ctx.exception)) self.assertIn("g:a", str(ctx.exception))
def test_artifact_with_changes_since_last_release__local_edits(self): """ We added uncommitted change detection to improve the local developer experience: any artifact that has uncommitted changes should get marked as needing to be released. """ package = "pack1/pack2" repo_root_path = self._setup_repo_with_package(package) current_artifact_hash = git.get_dir_hash(repo_root_path, [package], exclusions.src_exclusions()) art_def = buildpom.MavenArtifactDef( "g1", "a1", "1.1.0", released_version="1.2.0", bazel_package=package, released_artifact_hash=current_artifact_hash) # add a new file ... self._touch_file_at_path(repo_root_path, package, "", "Foo.java") # ... but DON't commit art_def = artifactprocessor.augment_artifact_def( repo_root_path, art_def, exclusions.src_exclusions()) self.assertNotEqual(None, art_def.requires_release) self.assertTrue(art_def.requires_release, "Expected artifact to require release") self.assertIs(releasereason.ReleaseReason.UNCOMMITTED_CHANGES, art_def.release_reason)
def test_additional_change_detected_packages__not_set(self): package1 = "path/pack1" # change detected (by default) package2 = "path/pack2" # ignored repo_root_path = self._setup_repo_with_package(package1) self._add_package(repo_root_path, package2) self._touch_file_at_path(repo_root_path, package1, "", "Blah.java") self._touch_file_at_path(repo_root_path, package2, "", "Blah.java") self._commit(repo_root_path) current_artifact_hash = git.get_dir_hash(repo_root_path, [package1], exclusions.src_exclusions()) art_def = buildpom.MavenArtifactDef( "g1", "a1", "1.1.0", released_version="1.2.0", bazel_package=package1, released_artifact_hash=current_artifact_hash) # modify an existing file in package2 - since we are not explicitly # detecting changes in it, it shouldn't matter: self._touch_file_at_path(repo_root_path, package2, "", "Blah.java") self._commit(repo_root_path) art_def = artifactprocessor.augment_artifact_def( repo_root_path, art_def, exclusions.src_exclusions()) self.assertNotEqual(None, art_def.requires_release) self.assertFalse(art_def.requires_release, "Artifact should not be released")
def test_artifact_with_changes_since_last_release__modified_file(self): package = "pack1/pack2" repo_root_path = self._setup_repo_with_package(package) self._touch_file_at_path(repo_root_path, package, "", "Blah.java") self._commit(repo_root_path) current_artifact_hash = git.get_dir_hash(repo_root_path, [package], exclusions.src_exclusions()) art_def = buildpom.MavenArtifactDef( "g1", "a1", "1.1.0", released_version="1.2.0", bazel_package=package, released_artifact_hash=current_artifact_hash) # modify an existing file: self._touch_file_at_path(repo_root_path, package, "", "Blah.java") self._commit(repo_root_path) art_def = artifactprocessor.augment_artifact_def( repo_root_path, art_def, exclusions.src_exclusions()) self.assertNotEqual(None, art_def.requires_release) self.assertTrue(art_def.requires_release, "Expected artifact to require release") self.assertIs(releasereason.ReleaseReason.ARTIFACT, art_def.release_reason)
def test_missing_library_root_file(self): repo_root = tempfile.mkdtemp("monorepo") art_def_1 = buildpom.MavenArtifactDef("g1", "a1", "1.0.0", bazel_package="lib1/pack1") with self.assertRaises(Exception) as ctx: artifactprocessor.augment_artifact_def(repo_root, art_def_1, exclusions.src_exclusions()) self.assertIn("Did not find LIBRARY.root at", str(ctx.exception)) self.assertIn("or any parent dir", str(ctx.exception))
def test_artifact_def_without_relased_artifact_hash(self): art_def = buildpom.MavenArtifactDef("g1", "a1", "1.0.0", bazel_package="") repo_root = tempfile.mkdtemp("monorepo") self._touch_file_at_path(repo_root, "", "MVN-INF", "LIBRARY.root") self.assertIs(None, art_def.released_artifact_hash) art_def = artifactprocessor.augment_artifact_def(repo_root, art_def, exclusions.src_exclusions()) self.assertTrue(art_def.requires_release)
def test_artifact_without_changes_since_last_release(self): repo_root_path = self._setup_repo_with_package("pack1/pack2") current_artifact_hash = git.get_dir_hash(repo_root_path, "pack1/pack2", exclusions.src_exclusions()) art_def = buildpom.MavenArtifactDef("g1", "a1", "1.1.0", bazel_package="pack1/pack2", released_version="1.2.0", released_artifact_hash=current_artifact_hash) art_def = artifactprocessor.augment_artifact_def(repo_root_path, art_def, exclusions.src_exclusions()) self.assertNotEqual(None, art_def.requires_release) self.assertFalse(art_def.requires_release) self.assertEqual(None, art_def.release_reason)
def test_template__library_transitives(self): """ Verifies that transitive dependencies can be referenced using the property pomgen.transitive_closure_of_library_dependencies. """ pom_template = """ <project> <dependencyManagement> <dependencies> #{pomgen.transitive_closure_of_library_dependencies} </dependencies> </dependencyManagement> </project> """ expected_pom = """ <project> <dependencyManagement> <dependencies> <dependency> <groupId>com.grail.srpc</groupId> <artifactId>srpc-api</artifactId> <version>5.6.7</version> </dependency> <dependency> <groupId>cg</groupId> <artifactId>ca</artifactId> <version>0.0.1</version> </dependency> </dependencies> </dependencyManagement> </project> """ ws = workspace.Workspace("some/path", [], exclusions.src_exclusions(), maveninstallinfo.NOOP, pomcontent.NOOP) artifact_def = buildpom.maven_artifact("groupId", "artifactId", "1.2.3") dep = dependency.new_dep_from_maven_artifact_def(artifact_def) artifact_def.custom_pom_template_content = pom_template pomgen = pom.TemplatePomGen(ws, artifact_def, dep) srpc_artifact_def = buildpom.MavenArtifactDef("com.grail.srpc", "srpc-api", "5.6.7", bazel_package="a/b/c") internal_dep = dependency.MonorepoDependency(srpc_artifact_def, bazel_target=None) external_dep = dependency.ThirdPartyDependency("name", "cg", "ca", "0.0.1") pomgen.register_dependencies_transitive_closure__library( set([external_dep, internal_dep])) generated_pom = pomgen.gen(pom.PomContentType.RELEASE) self.assertEqual(expected_pom, generated_pom)
def main(args): args = _parse_arguments(args) repo_root = common.get_repo_root(args.repo_root) cfg = config.load(repo_root) mvn_install_info = maveninstallinfo.MavenInstallInfo(cfg.maven_install_paths) ws = workspace.Workspace(repo_root, cfg.excluded_dependency_paths, cfg.all_src_exclusions, mvn_install_info, pomcontent.NOOP) group_id = "all_ext_deps_group" if args.group_id is None else args.group_id artifact_id = "all_ext_deps_art" if args.artifact_id is None else args.artifact_id version = "0.0.1-SNAPSHOT" if args.version is None else args.version artifact_def = buildpom.MavenArtifactDef(group_id=group_id, artifact_id=artifact_id, version=version) if args.stdin: dep_labels = set() # we want to de-dupe labels dependencies = [] for line in sys.stdin: line = line.strip() if len(line) == 0: continue if not line.startswith("@"): continue if _starts_with_ignored_prefix(line): continue dep_labels.add(line) dependencies = ws.parse_dep_labels(dep_labels) else: dependencies = list(ws.name_to_external_dependencies.values()) # note that it is possible to end up with duplicate dependencies # because different labels may point to the same dependency (gav) # (for ex: @maven//:org_antlr_ST4 and @antlr//:org_antlr_ST4) # however those indentical gavs may have distinct exclusions dependencies.sort() if args.exclude_all_transitives: # ignore what was specified in the pinned dependencies files # and add an "exclude all" dependency for all dependencies that # will end up in the generated pom ws.dependency_metadata.clear() for dep in dependencies: ws.dependency_metadata.register_exclusions( dep, [dependency.EXCLUDE_ALL_PLACEHOLDER_DEP]) pomgen = ThirdPartyDepsPomGen(ws, artifact_def, dependencies, cfg.pom_template) pomgen.process_dependencies() return pomgen.gen(pom.PomContentType.RELEASE)
def test_template_var_sub__monorepo_deps(self): """ Verifies references to monorepo versions in a pom template. """ ws = workspace.Workspace("some/path", [], exclusions.src_exclusions(), maveninstallinfo.NOOP, pomcontent.NOOP) artifact_def = buildpom.MavenArtifactDef("groupId", "artifactId", "1.2.3") dep = dependency.new_dep_from_maven_artifact_def(artifact_def) artifact_def.custom_pom_template_content = "srpc #{com.grail.srpc:srpc-api:version}" srpc_artifact_def = buildpom.MavenArtifactDef("com.grail.srpc", "srpc-api", "5.6.7", bazel_package="a/b/c") srpc_dep = dependency.MonorepoDependency(srpc_artifact_def, bazel_target=None) pomgen = pom.TemplatePomGen(ws, artifact_def, dep) pomgen.register_dependencies_transitive_closure__library( set([srpc_dep])) generated_pom = pomgen.gen(pom.PomContentType.RELEASE) self.assertIn("srpc 5.6.7", generated_pom)
def _build_node(self, artifact_id, bazel_package, pom_generation_mode=pomgenmode.DYNAMIC, parent_node=None): art_def = buildpom.MavenArtifactDef( "g1", artifact_id, "1.0.0", bazel_package=bazel_package, pom_generation_mode=pom_generation_mode) dep = dependency.new_dep_from_maven_artifact_def(art_def) return crawlerm.Node(parent=parent_node, artifact_def=art_def, dependency=dep)
def test_source_dependency__references_artifact__template_pom_gen_mode(self): group_id = "g1" artifact_id = "a1" version = "1.1.0" released_version = "1.2.3" package = "pack1/pack2" art_def = buildpom.MavenArtifactDef(group_id, artifact_id, version, pom_generation_mode=pomgenmode.TEMPLATE, bazel_package=package, requires_release=False, released_version=released_version, released_artifact_hash="123456789") dep = dependency.new_dep_from_maven_artifact_def(art_def) self.assertTrue(dep.references_artifact)
def test_source_dependency__bazel_target__defaulted(self): """ If bazel_target is not set, it is defaulted based on the package. """ target = None group_id = "g1" artifact_id = "a1" version = "1.1.0" released_version = "1.2.3" package = "pack1/pack2" art_def = buildpom.MavenArtifactDef(group_id, artifact_id, version, bazel_package=package, requires_release=False, released_version=released_version, released_artifact_hash="123456789") dep = dependency.new_dep_from_maven_artifact_def(art_def, target) self.assertEqual("pack2", dep.bazel_target)
def test_source_dependency__bazel_target__explicit(self): """ bazel_target can be set explicitly. """ target = "foo_target" group_id = "g1" artifact_id = "a1" version = "1.1.0" released_version = "1.2.3" package = "pack1/pack2" art_def = buildpom.MavenArtifactDef(group_id, artifact_id, version, bazel_package=package, requires_release=False, released_version=released_version, released_artifact_hash="123456789") dep = dependency.new_dep_from_maven_artifact_def(art_def, target) self.assertEqual(target, dep.bazel_target)
def test_artifact_without_changes_always_release(self): repo_root_path = self._setup_repo_with_package("pack1/pack2") current_artifact_hash = git.get_dir_hash(repo_root_path, "pack1/pack2", exclusions.src_exclusions()) art_def = buildpom.MavenArtifactDef( "g1", "a1", "1.1.0", bazel_package="pack1/pack2", released_version="1.2.0", released_artifact_hash=current_artifact_hash, change_detection=False) art_def = artifactprocessor.augment_artifact_def( repo_root_path, art_def, exclusions.src_exclusions()) self.assertNotEqual(None, art_def.requires_release) self.assertTrue(art_def.requires_release, "Expected artifact to require release") self.assertEqual(releasereason.ReleaseReason.ALWAYS, art_def.release_reason)
def main(args): args = _parse_arguments(args) repo_root = common.get_repo_root(args.repo_root) cfg = config.load(repo_root) ws = workspace.Workspace(repo_root, cfg.external_dependencies, cfg.excluded_dependency_paths, cfg.all_src_exclusions) group_id = "all_ext_deps_group" if args.group_id is None else args.group_id artifact_id = "all_ext_deps_art" if args.artifact_id is None else args.artifact_id version = "0.0.1-SNAPSHOT" if args.version is None else args.version artifact_def = buildpom.MavenArtifactDef(group_id=group_id, artifact_id=artifact_id, version=version) if args.stdin: dep_labels = [] dependencies = [] for line in sys.stdin: line = line.strip() if len(line) == 0: continue if not line.startswith("@"): continue if not line.endswith("//jar"): continue if _starts_with_ignored_prefix(line): continue dep_labels.append(line) unique_dependencies = set(ws.parse_dep_labels(dep_labels)) dependencies = list(unique_dependencies) else: dependencies = list(ws.name_to_external_dependencies.values()) dependencies.sort() pomgen = ThirdPartyDepsPomGen(ws, artifact_def, dependencies, cfg.pom_template) pomgen.process_dependencies() return pomgen.gen()
def test_dynamic_pom__do_not_include_deps(self): """ Tests the seldomly used "include_deps = False" BUILD.pom attribute. """ ws = workspace.Workspace("some/path", [], exclusions.src_exclusions(), maveninstallinfo.NOOP, pomcontent.NOOP) artifact_def = buildpom.MavenArtifactDef("g1", "a2", "1.2.3", include_deps=False) dep = dependency.new_dep_from_maven_artifact_def(artifact_def) pomgen = pom.DynamicPomGen(ws, artifact_def, dep, "") org_function = bazel.query_java_library_deps_attributes try: bazel.query_java_library_deps_attributes = lambda r, p: 1 / 0 # fails pomgen.process_dependencies() generated_pom = pomgen.gen(pom.PomContentType.RELEASE) self.assertNotIn("dependencies", generated_pom) finally: bazel.query_java_library_deps_attributes = org_function
def test_test_changes_are_ignored(self): """ We are assuming the de-facto Maven directory structure standard: src/main/... - prod code src/test/... - tests """ src_exclusions = exclusions.src_exclusions(relative_paths=("src/test",)) package = "pack" repo_root_path = self._setup_repo_with_package(package) self._touch_file_at_path(repo_root_path, package, "MVN-INF", "BUILD.pom.released") self._touch_file_at_path(repo_root_path, package, "src/main", "MyClass.java") self._touch_file_at_path(repo_root_path, package, "src/test", "MyTest.java") self._commit(repo_root_path) current_artifact_hash = git.get_dir_hash(repo_root_path, package, src_exclusions) art_def = buildpom.MavenArtifactDef("g1", "a1", "1.1.0", bazel_package=package, released_version="1.2.0", released_artifact_hash=current_artifact_hash) # update test class and commit - that change should be ignored self._touch_file_at_path(repo_root_path, package, "src/test", "MyTest.java") self._commit(repo_root_path) art_def = artifactprocessor.augment_artifact_def(repo_root_path, art_def, src_exclusions) self.assertNotEqual(None, art_def.requires_release) self.assertFalse(art_def.requires_release)