def _register(cls, source_root_dir, mutable, *allowed_target_types): """Registers a source root. :param string source_root_dir: The source root directory against which we resolve source paths, relative to the build root. :param list allowed_target_types: Optional list of target types. If specified, we enforce that only targets of those types appear under this source root. """ # Temporary delegation to the new implementation, until this entire file goes away. SourceRootConfig.global_instance().get_source_roots().add_source_root( source_root_dir) source_root_dir = SourceRoot._relative_to_buildroot(source_root_dir) types = cls._TYPES_BY_ROOT.get(source_root_dir) if types is None: types = OrderedSet() cls._TYPES_BY_ROOT[source_root_dir] = types for allowed_target_type in allowed_target_types: types.add(allowed_target_type) roots = cls._ROOTS_BY_TYPE.get(allowed_target_type) if roots is None: roots = OrderedSet() cls._ROOTS_BY_TYPE[allowed_target_type] = roots roots.add(source_root_dir) cls._SOURCE_ROOT_TREE.add_root(source_root_dir, allowed_target_types, mutable)
def _register(cls, source_root_dir, mutable, *allowed_target_types): """Registers a source root. :param string source_root_dir: The source root directory against which we resolve source paths, relative to the build root. :param list allowed_target_types: Optional list of target types. If specified, we enforce that only targets of those types appear under this source root. """ # Temporary delegation to the new implementation, until this entire file goes away. SourceRootConfig.global_instance().get_source_roots().add_source_root(source_root_dir) source_root_dir = SourceRoot._relative_to_buildroot(source_root_dir) types = cls._TYPES_BY_ROOT.get(source_root_dir) if types is None: types = OrderedSet() cls._TYPES_BY_ROOT[source_root_dir] = types for allowed_target_type in allowed_target_types: types.add(allowed_target_type) roots = cls._ROOTS_BY_TYPE.get(allowed_target_type) if roots is None: roots = OrderedSet() cls._ROOTS_BY_TYPE[allowed_target_type] = roots roots.add(source_root_dir) cls._SOURCE_ROOT_TREE.add_root(source_root_dir, allowed_target_types, mutable)
def create_python_awslambda(self, addr: str) -> Tuple[str, bytes]: lambdex_setup = self.request_single_product( LambdexSetup, Params( PythonSetup.global_instance(), PythonNativeCode.global_instance(), SubprocessEnvironment.global_instance(), Lambdex.global_instance(), )) target = self.request_single_product(HydratedTarget, Address.parse(addr)) created_awslambda = self.request_single_product( CreatedAWSLambda, Params( target.adaptor, lambdex_setup, SourceRootConfig.global_instance(), PythonSetup.global_instance(), PythonNativeCode.global_instance(), SubprocessEnvironment.global_instance(), )) files_content = list( self.request_single_product(FilesContent, Params(created_awslambda.digest))) assert len(files_content) == 1 return created_awslambda.name, files_content[0].content
def __init__(self, options, run_tracker, target_roots, requested_goals=None, target_base=None, build_graph=None, build_file_parser=None, address_mapper=None, console_outstream=None, scm=None, workspace=None, spec_excludes=None, invalidation_report=None): """ :API: public """ deprecated_conditional(lambda: spec_excludes is not None, '0.0.75', 'Use address_mapper#build_ignore_patterns instead.') self._options = options self.build_graph = build_graph self.build_file_parser = build_file_parser self.address_mapper = address_mapper self.run_tracker = run_tracker self._log = self.Log(run_tracker) self._target_base = target_base or Target self._products = Products() self._buildroot = get_buildroot() self._source_roots = SourceRootConfig.global_instance().get_source_roots() self._lock = OwnerPrintingPIDLockFile(os.path.join(self._buildroot, '.pants.run')) self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self._console_outstream = console_outstream or sys.stdout self._scm = scm or get_scm() self._workspace = workspace or (ScmWorkspace(self._scm) if self._scm else None) self._spec_excludes = spec_excludes self._replace_targets(target_roots) self._invalidation_report = invalidation_report
def __init__(self, options, run_tracker, target_roots, requested_goals=None, target_base=None, build_graph=None, build_file_parser=None, build_configuration=None, address_mapper=None, console_outstream=None, scm=None, workspace=None, invalidation_report=None, scheduler=None): self._options = options # We register a callback that will cause build graph edits to invalidate our caches, and we hold # a handle directly to the callback function to ensure that it is not GC'd until the context is. self.build_graph = build_graph self._clear_target_cache_handle = self._clear_target_cache self._targets_cache = dict() self.build_graph.add_invalidation_callback(self._clear_target_cache_handle) self._build_file_parser = build_file_parser self.build_configuration = build_configuration self.address_mapper = address_mapper self.run_tracker = run_tracker self._log = run_tracker.logger self._target_base = target_base or Target self._products = Products() self._buildroot = get_buildroot() self._source_roots = SourceRootConfig.global_instance().get_source_roots() self._lock = OwnerPrintingInterProcessFileLock(os.path.join(self._buildroot, '.pants.workdir.file_lock')) self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self._console_outstream = console_outstream or sys.stdout.buffer self._scm = scm or get_scm() self._workspace = workspace or (ScmWorkspace(self._scm) if self._scm else None) self._replace_targets(target_roots) self._invalidation_report = invalidation_report self._scheduler = scheduler
def __init__( self, options, run_tracker, target_roots, requested_goals=None, target_base=None, build_graph=None, build_file_parser=None, address_mapper=None, console_outstream=None, scm=None, workspace=None, invalidation_report=None, ): self._options = options self.build_graph = build_graph self.build_file_parser = build_file_parser self.address_mapper = address_mapper self.run_tracker = run_tracker self._log = self.Log(run_tracker) self._target_base = target_base or Target self._products = Products() self._buildroot = get_buildroot() self._source_roots = SourceRootConfig.global_instance().get_source_roots() self._lock = OwnerPrintingInterProcessFileLock(os.path.join(self._buildroot, ".pants.workdir.file_lock")) self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self._console_outstream = console_outstream or sys.stdout self._scm = scm or get_scm() self._workspace = workspace or (ScmWorkspace(self._scm) if self._scm else None) self._replace_targets(target_roots) self._invalidation_report = invalidation_report
def source_root(self): """:returns: the source root for these sources, or None if they're not under a source root.""" # TODO: It's a shame that we have to access the singleton directly here, instead of getting # the SourceRoots instance from context, as tasks do. In the new engine we could inject # this into the target, rather than have it reach out for global singletons. return SourceRootConfig.global_instance().get_source_roots( ).find_by_path(self.rel_path)
def test_all_roots_with_root_at_buildroot(self): options = { "pants_ignore": [], "root_patterns": ["/"], } options.update(self.options[""]) # We need inherited values for pants_workdir etc. self.context( for_subsystems=[SourceRootConfig], options={SourceRootConfig.options_scope: options} ) source_root_config = SourceRootConfig.global_instance() # This function mocks out reading real directories off the file system def provider_rule(path_globs: PathGlobs) -> Snapshot: dirs = ("foo",) # A python package at the buildroot. return Snapshot(Digest("abcdef", 10), (), dirs) output = run_rule( list_roots.all_roots, rule_args=[source_root_config], mock_gets=[ MockGet(product_type=Snapshot, subject_type=PathGlobs, mock=provider_rule), MockGet( product_type=OptionalSourceRoot, subject_type=SourceRootRequest, mock=lambda req: OptionalSourceRoot(SourceRoot(".")), ), ], ) self.assertEqual({SourceRoot(".")}, set(output))
def source_root(self): """:returns: the source root for these sources, or None if they're not under a source root.""" # TODO: It's a shame that we have to access the singleton directly here, instead of getting # the SourceRoots instance from context, as tasks do. In the new engine we could inject # this into the target, rather than have it reach out for global singletons. return SourceRootConfig.global_instance().get_source_roots( ).find_by_path(self.rel_path)
def test_collapse_source_root(self): self.context(for_subsystems=[SourceRootConfig], options={ SourceRootConfig.options_scope: { 'source_roots': { '/src/java': [], '/tests/java': [], '/some/other': [] }, 'unmatched': 'fail' } }) source_roots = SourceRootConfig.global_instance().get_source_roots() source_set_list = [] self.assertEquals([], Project._collapse_by_source_root(source_roots, source_set_list)) source_sets = [ SourceSet('/repo-root', 'src/java', 'org/pantsbuild/app', False), SourceSet('/repo-root', 'tests/java', 'org/pantsbuild/app', True), SourceSet('/repo-root', 'some/other', 'path', False), ] results = Project._collapse_by_source_root(source_roots, source_sets) self.assertEquals(SourceSet('/repo-root', 'src/java', '', False), results[0]) self.assertFalse(results[0].is_test) self.assertEquals(SourceSet('/repo-root', 'tests/java', '', True), results[1]) self.assertTrue(results[1].is_test) # If there is no registered source root, the SourceSet should be returned unmodified self.assertEquals(source_sets[2], results[2]) self.assertFalse(results[2].is_test)
def assert_sources( self, expected_files, expected_packages, expected_namespace_packages, expected_package_data, addrs, ): srcs = self.request_single_product( SetupPySources, Params( SetupPySourcesRequest(Targets( [self.tgt(addr) for addr in addrs]), py2=False), SourceRootConfig.global_instance(), ), ) chroot_snapshot = self.request_single_product(Snapshot, Params(srcs.digest)) assert sorted(expected_files) == sorted(chroot_snapshot.files) assert sorted(expected_packages) == sorted(srcs.packages) assert sorted(expected_namespace_packages) == sorted( srcs.namespace_packages) assert expected_package_data == dict(srcs.package_data)
def __init__(self, options, run_tracker, target_roots, requested_goals=None, target_base=None, build_graph=None, build_file_parser=None, address_mapper=None, console_outstream=None, scm=None, workspace=None, invalidation_report=None): self._options = options self.build_graph = build_graph self.build_file_parser = build_file_parser self.address_mapper = address_mapper self.run_tracker = run_tracker self._log = self.Log(run_tracker) self._target_base = target_base or Target self._products = Products() self._buildroot = get_buildroot() self._source_roots = SourceRootConfig.global_instance( ).get_source_roots() self._lock = OwnerPrintingInterProcessFileLock( os.path.join(self._buildroot, '.pants.workdir.file_lock')) self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self._console_outstream = console_outstream or sys.stdout self._scm = scm or get_scm() self._workspace = workspace or (ScmWorkspace(self._scm) if self._scm else None) self._replace_targets(target_roots) self._invalidation_report = invalidation_report
def assert_error(self, addr: str, exc_cls: Type[Exception]): with pytest.raises(ExecutionError) as excinfo: self.request_single_product( SetupPyChroot, Params(SetupPyChrootRequest(ExportedTarget(self.tgt(addr))), SourceRootConfig.global_instance())) ex = excinfo.value assert len(ex.wrapped_exceptions) == 1 assert type(ex.wrapped_exceptions[0]) == exc_cls
def assert_chroot(self, expected_files, expected_setup_kwargs, addr): chroot = self.request_single_product( SetupPyChroot, Params(SetupPyChrootRequest(ExportedTarget(self.tgt(addr))), SourceRootConfig.global_instance())) snapshot = self.request_single_product(Snapshot, Params(chroot.digest)) assert sorted(expected_files) == sorted(snapshot.files) kwargs = json.loads(chroot.setup_keywords_json) assert expected_setup_kwargs == kwargs
def target_base(self): """:returns: the source root path for this target.""" # TODO: It's a shame that we have to access the singleton directly here, instead of getting # the SourceRoots instance from context, as tasks do. In the new engine we could inject # this into the target, rather than have it reach out for global singletons. source_root = SourceRootConfig.global_instance().get_source_roots().find(self) if not source_root: raise TargetDefinitionException(self, 'Not under any configured source root.') return source_root.path
def target_base(self): """:returns: the source root path for this target.""" # TODO: It's a shame that we have to access the singleton directly here, instead of getting # the SourceRoots instance from context, as tasks do. In the new engine we could inject # this into the target, rather than have it reach out for global singletons. source_root = SourceRootConfig.global_instance().get_source_roots( ).find(self) if not source_root: raise TargetDefinitionException( self, 'Not under any configured source root.') return source_root.path
def assert_ancestor_init_py(self, expected_init_pys: Iterable[str], addrs: Iterable[str]) -> None: ancestor_init_py_files = self.request_single_product( AncestorInitPyFiles, Params(HydratedTargets([self.tgt(addr) for addr in addrs]), SourceRootConfig.global_instance())) snapshots = [ self.request_single_product(Snapshot, Params(digest)) for digest in ancestor_init_py_files.digests ] init_py_files_found = set( [file for snapshot in snapshots for file in snapshot.files]) # NB: Doesn't include the root __init__.py or the missing src/python/foo/bar/__init__.py. assert sorted(expected_init_pys) == sorted(init_py_files_found)
def test_all_roots(self): self.create_dir("contrib/go/examples/3rdparty/go") self.create_dir("contrib/go/examples/src/go/src") self.create_dir("src/java") self.create_dir("src/python") self.create_dir("src/kotlin") self.create_dir("src/example/java") self.create_dir("src/example/python") self.create_dir("my/project/src/java") self.create_dir("fixed/root/jvm") self.create_dir("not/a/srcroot/java") options = { "pants_ignore": [], "source_root_patterns": ["src/*", "src/example/*"], "source_roots": { # Fixed roots should trump patterns which would detect contrib/go/examples/src/go here. "contrib/go/examples/src/go/src": ["go"], # Dir does not exist, should not be listed as a root. "java": ["java"], }, } options.update(self.options[""] ) # We need inherited values for pants_workdir etc. self.context(for_subsystems=[SourceRootConfig], options={SourceRootConfig.options_scope: options}) source_roots = SourceRootConfig.global_instance().get_source_roots() # Ensure that we see any manually added roots. source_roots.add_source_root("fixed/root/jvm", ("java", "scala"), TEST) source_roots.all_roots() self.assertEqual( { SourceRoot("contrib/go/examples/3rdparty/go", ("go", ), THIRDPARTY), SourceRoot("contrib/go/examples/src/go/src", ("go", ), SOURCE), SourceRoot("src/java", ("java", ), SOURCE), SourceRoot("src/python", ("python", ), SOURCE), SourceRoot("src/kotlin", ("kotlin", ), SOURCE), SourceRoot("src/example/java", ("java", ), SOURCE), SourceRoot("src/example/python", ("python", ), SOURCE), SourceRoot("my/project/src/java", ("java", ), SOURCE), SourceRoot("fixed/root/jvm", ("java", "scala"), TEST), }, set(source_roots.all_roots()), )
def test_all_roots(self): self.create_dir('contrib/go/examples/3rdparty/go') self.create_dir('contrib/go/examples/src/go/src') self.create_dir('src/java') self.create_dir('src/python') self.create_dir('src/kotlin') self.create_dir('src/example/java') self.create_dir('src/example/python') self.create_dir('my/project/src/java') self.create_dir('fixed/root/jvm') self.create_dir('not/a/srcroot/java') options = { 'pants_ignore': [], 'source_root_patterns': ['src/*', 'src/example/*'], 'source_roots': { # Fixed roots should trump patterns which would detect contrib/go/examples/src/go here. 'contrib/go/examples/src/go/src': ['go'], # Dir does not exist, should not be listed as a root. 'java': ['java'] } } options.update(self.options[''] ) # We need inherited values for pants_workdir etc. self.context(for_subsystems=[SourceRootConfig], options={SourceRootConfig.options_scope: options}) source_roots = SourceRootConfig.global_instance().get_source_roots() # Ensure that we see any manually added roots. source_roots.add_source_root('fixed/root/jvm', ('java', 'scala'), TEST) source_roots.all_roots() self.assertEqual( { SourceRoot('contrib/go/examples/3rdparty/go', ('go', ), THIRDPARTY), SourceRoot('contrib/go/examples/src/go/src', ('go', ), SOURCE), SourceRoot('src/java', ('java', ), SOURCE), SourceRoot('src/python', ('python', ), SOURCE), SourceRoot('src/kotlin', ('kotlin', ), SOURCE), SourceRoot('src/example/java', ('java', ), SOURCE), SourceRoot('src/example/python', ('python', ), SOURCE), SourceRoot('my/project/src/java', ('java', ), SOURCE), SourceRoot('fixed/root/jvm', ('java', 'scala'), TEST) }, set(source_roots.all_roots()))
def assert_stripped_source_file(self, *, original_path: str, expected_path: str, target_type_alias=None): init_subsystem(SourceRootConfig) adaptor = Mock() adaptor.sources = Mock() source_files = {original_path: "print('random python')"} adaptor.sources.snapshot = self.make_snapshot(source_files) adaptor.address = Mock() adaptor.address.spec_path = original_path if target_type_alias: adaptor.type_alias = target_type_alias target = HydratedTarget('some/target/address', adaptor, tuple()) stripped_sources = self.request_single_product( SourceRootStrippedSources, Params(target, SourceRootConfig.global_instance())) self.assertEqual(stripped_sources.snapshot.files, (expected_path, ))
def __init__(self, options, run_tracker, target_roots, requested_goals=None, target_base=None, build_graph=None, build_file_parser=None, address_mapper=None, console_outstream=None, scm=None, workspace=None, spec_excludes=None, invalidation_report=None): """ :API: public """ deprecated_conditional( lambda: spec_excludes is not None, '0.0.75', 'Use address_mapper#build_ignore_patterns instead.') self._options = options self.build_graph = build_graph self.build_file_parser = build_file_parser self.address_mapper = address_mapper self.run_tracker = run_tracker self._log = self.Log(run_tracker) self._target_base = target_base or Target self._products = Products() self._buildroot = get_buildroot() self._source_roots = SourceRootConfig.global_instance( ).get_source_roots() self._lock = OwnerPrintingPIDLockFile( os.path.join(self._buildroot, '.pants.run')) self._java_sysprops = None # Computed lazily. self.requested_goals = requested_goals or [] self._console_outstream = console_outstream or sys.stdout self._scm = scm or get_scm() self._workspace = workspace or (ScmWorkspace(self._scm) if self._scm else None) self._spec_excludes = spec_excludes self._replace_targets(target_roots) self._invalidation_report = invalidation_report
def test_all_roots(self): self.create_dir('contrib/go/examples/3rdparty/go') self.create_dir('contrib/go/examples/src/go/src') self.create_dir('src/java') self.create_dir('src/python') self.create_dir('src/example/java') self.create_dir('src/example/python') self.create_dir('my/project/src/java') self.create_dir('fixed/root/jvm') self.create_dir('not/a/srcroot/java') options = { 'build_file_rev': None, 'pants_ignore': [], 'source_root_patterns': ['src/*', 'src/example/*'], 'source_roots': { # Fixed roots should trump patterns which would detect contrib/go/examples/src/go here. 'contrib/go/examples/src/go/src': ['go'], # Dir does not exist, should not be listed as a root. 'java': ['java']} } options.update(self.options['']) # We need inherited values for pants_workdir etc. self.context(for_subsystems=[SourceRootConfig], options={ SourceRootConfig.options_scope: options }) source_roots = SourceRootConfig.global_instance().get_source_roots() # Ensure that we see any manually added roots. source_roots.add_source_root('fixed/root/jvm', ('java', 'scala'), TEST) source_roots.all_roots() self.assertEquals({SourceRoot('contrib/go/examples/3rdparty/go', ('go',), THIRDPARTY), SourceRoot('contrib/go/examples/src/go/src', ('go',), SOURCE), SourceRoot('src/java', ('java',), SOURCE), SourceRoot('src/python', ('python',), SOURCE), SourceRoot('src/example/java', ('java',), SOURCE), SourceRoot('src/example/python', ('python',), SOURCE), SourceRoot('my/project/src/java', ('java',), SOURCE), SourceRoot('fixed/root/jvm', ('java','scala'), TEST)}, set(source_roots.all_roots()))
def source_root(self): """:returns: the source root for these sources, or None if they're not under a source root.""" # TODO: It's a shame that we have to access the singleton directly here, instead of getting # the SourceRoots instance from context, as tasks do. return SourceRootConfig.global_instance().get_source_roots( ).find_by_path(self.rel_path)
def test_all_roots(self): dirs = ( "contrib/go/examples/src/go/src", "src/java", "src/python", "src/python/subdir/src/python", # We allow source roots under source roots. "src/kotlin", "my/project/src/java", "src/example/java", "src/example/python", "fixed/root/jvm", ) options = { "pants_ignore": [], "root_patterns": [ "src/*", "src/example/*", "contrib/go/examples/src/go/src", # Dir does not exist, should not be listed as a root. "java", "fixed/root/jvm", ], } options.update(self.options[""]) # We need inherited values for pants_workdir etc. self.context( for_subsystems=[SourceRootConfig], options={SourceRootConfig.options_scope: options} ) source_root_config = SourceRootConfig.global_instance() # This function mocks out reading real directories off the file system. def provider_rule(path_globs: PathGlobs) -> Snapshot: return Snapshot(Digest("abcdef", 10), (), dirs) def source_root_mock_rule(req: SourceRootRequest) -> OptionalSourceRoot: for d in dirs: if str(req.path).startswith(d): return OptionalSourceRoot(SourceRoot(str(req.path))) return OptionalSourceRoot(None) output = run_rule( list_roots.all_roots, rule_args=[source_root_config], mock_gets=[ MockGet(product_type=Snapshot, subject_type=PathGlobs, mock=provider_rule), MockGet( product_type=OptionalSourceRoot, subject_type=SourceRootRequest, mock=source_root_mock_rule, ), ], ) self.assertEqual( { SourceRoot("contrib/go/examples/src/go/src"), SourceRoot("src/java"), SourceRoot("src/python"), SourceRoot("src/python/subdir/src/python"), SourceRoot("src/kotlin"), SourceRoot("src/example/java"), SourceRoot("src/example/python"), SourceRoot("my/project/src/java"), SourceRoot("fixed/root/jvm"), }, set(output), )
def test_all_roots(self): SOURCE = SourceRootCategories.SOURCE TEST = SourceRootCategories.TEST THIRDPARTY = SourceRootCategories.THIRDPARTY options = { 'pants_ignore': [], 'source_root_patterns': ['src/*', 'src/example/*'], 'source_roots': { # Fixed roots should trump patterns which would detect contrib/go/examples/src/go here. 'contrib/go/examples/src/go/src': ['go'], # Dir does not exist, should not be listed as a root. 'java': ['java'] } } options.update(self.options[''] ) # We need inherited values for pants_workdir etc. self.context(for_subsystems=[SourceRootConfig], options={SourceRootConfig.options_scope: options}) source_root_config = SourceRootConfig.global_instance() source_roots = source_root_config.get_source_roots() # Ensure that we see any manually added roots. source_roots.add_source_root('fixed/root/jvm', ('java', 'scala'), TEST) # This function mocks out reading real directories off the file system def provider_rule(path_globs: PathGlobs) -> Snapshot: dirs = ( 'contrib/go/examples/3rdparty/go', 'contrib/go/examples/src/go/src', 'src/java', 'src/python', 'src/kotlin', 'my/project/src/java', 'src/example/java', 'src/example/python', 'fixed/root/jvm', # subdirectories of source roots should not show up in final output 'src/kotlin/additional/directories/that/might/get/matched/src/foo', ) return Snapshot(Digest('abcdef', 10), (), dirs) output = run_rule(list_roots.all_roots, source_root_config, {(Snapshot, PathGlobs): provider_rule}) self.assertEqual( { SourceRoot('contrib/go/examples/3rdparty/go', ('go', ), THIRDPARTY), SourceRoot('contrib/go/examples/src/go/src', ('go', ), SOURCE), SourceRoot('src/java', ('java', ), SOURCE), SourceRoot('src/python', ('python', ), SOURCE), SourceRoot('src/kotlin', ('kotlin', ), SOURCE), SourceRoot('src/example/java', ('java', ), SOURCE), SourceRoot('src/example/python', ('python', ), SOURCE), SourceRoot('my/project/src/java', ('java', ), SOURCE), SourceRoot('fixed/root/jvm', ('java', 'scala'), TEST) }, set(output))
def test_all_roots(self): SOURCE = SourceRootCategories.SOURCE TEST = SourceRootCategories.TEST THIRDPARTY = SourceRootCategories.THIRDPARTY options = { "pants_ignore": [], "source_root_patterns": ["src/*", "src/example/*"], "source_roots": { # Fixed roots should trump patterns which would detect contrib/go/examples/src/go here. "contrib/go/examples/src/go/src": ["go"], # Dir does not exist, should not be listed as a root. "java": ["java"], }, } options.update(self.options[""] ) # We need inherited values for pants_workdir etc. self.context(for_subsystems=[SourceRootConfig], options={SourceRootConfig.options_scope: options}) source_root_config = SourceRootConfig.global_instance() source_roots = source_root_config.get_source_roots() # Ensure that we see any manually added roots. source_roots.add_source_root("fixed/root/jvm", ("java", "scala"), TEST) # This function mocks out reading real directories off the file system def provider_rule(path_globs: PathGlobs) -> Snapshot: dirs = ( "contrib/go/examples/3rdparty/go", "contrib/go/examples/src/go/src", "src/java", "src/python", "src/kotlin", "my/project/src/java", "src/example/java", "src/example/python", "fixed/root/jvm", # subdirectories of source roots should not show up in final output "src/kotlin/additional/directories/that/might/get/matched/src/foo", ) return Snapshot(Digest("abcdef", 10), (), dirs) output = run_rule( list_roots.all_roots, rule_args=[source_root_config], mock_gets=[ MockGet(product_type=Snapshot, subject_type=PathGlobs, mock=provider_rule) ], ) self.assertEqual( { SourceRoot("contrib/go/examples/3rdparty/go", ("go", ), THIRDPARTY), SourceRoot("contrib/go/examples/src/go/src", ("go", ), SOURCE), SourceRoot("src/java", ("java", ), SOURCE), SourceRoot("src/python", ("python", ), SOURCE), SourceRoot("src/kotlin", ("kotlin", ), SOURCE), SourceRoot("src/example/java", ("java", ), SOURCE), SourceRoot("src/example/python", ("python", ), SOURCE), SourceRoot("my/project/src/java", ("java", ), SOURCE), SourceRoot("fixed/root/jvm", ("java", "scala"), TEST), }, set(output), )