class BuildFileAddresses(Collection.of(BuildFileAddress)): @property def addresses(self): """Converts the BuildFileAddress objects in this collection to Address objects.""" return [bfa.to_address() for bfa in self.dependencies]
class Specs(Collection.of(Spec)): """A collection of Spec subclasses."""
# Licensed under the Apache License, Version 2.0 (see LICENSE). from __future__ import (absolute_import, division, generators, nested_scopes, print_function, unicode_literals, with_statement) import collections import inspect from functools import update_wrapper import six from pants.build_graph.address import Address, BuildFileAddress from pants.engine.objects import Resolvable, Serializable from pants.util.objects import Collection, TypeConstraintError Addresses = Collection.of(Address) class BuildFileAddresses(Collection.of(BuildFileAddress)): @property def addresses(self): """Converts the BuildFileAddress objects in this collection to Address objects.""" return [bfa.to_address() for bfa in self.dependencies] class NotSerializableError(TypeError): """Indicates an addressable descriptor is illegally installed in a non-Serializable type.""" class MutationError(AttributeError): """Indicates an illegal attempt to mutate an addressable attribute that already has a value."""
def test_mismatching_paths(self): with self.assertRaises(DifferingFamiliesError): AddressFamily.create('one', [AddressMap('/dev/null/one/0', {}), AddressMap('/dev/null/two/0', {})]) def test_duplicate_names(self): with self.assertRaises(DuplicateNameError): AddressFamily.create('name/space', [AddressMap('name/space/0', {'one': Thing(name='one', age=42)}), AddressMap('name/space/1', {'one': Thing(name='one', age=37)})]) UnhydratedStructs = Collection.of(UnhydratedStruct) class AddressMapperTest(unittest.TestCase, SchedulerTestBase): def setUp(self): # Set up a scheduler that supports address mapping. symbol_table = TargetTable() address_mapper = AddressMapper(parser=JsonParser(symbol_table), build_patterns=('*.BUILD.json',)) rules = create_fs_rules() + create_graph_rules(address_mapper, symbol_table) # TODO handle updating the rule graph when passed unexpected root selectors. # Adding the following task allows us to get around the fact that SelectDependencies # requests are not currently supported. rules.append(TaskRule(UnhydratedStructs, [SelectDependencies(UnhydratedStruct, BuildFileAddresses,
class HydratedTargets(Collection.of(HydratedTarget)): """An intransitive set of HydratedTarget objects."""
def test_mismatching_paths(self): with self.assertRaises(DifferingFamiliesError): AddressFamily.create('one', [AddressMap('/dev/null/one/0', {}), AddressMap('/dev/null/two/0', {})]) def test_duplicate_names(self): with self.assertRaises(DuplicateNameError): AddressFamily.create('name/space', [AddressMap('name/space/0', {'one': Thing(name='one', age=42)}), AddressMap('name/space/1', {'one': Thing(name='one', age=37)})]) UnhydratedStructs = Collection.of(UnhydratedStruct) @rule(UnhydratedStructs, [Select(BuildFileAddresses)]) def unhydrated_structs(build_file_addresses): uhs = yield [Get(UnhydratedStruct, Address, a) for a in build_file_addresses.addresses] yield UnhydratedStructs(uhs) class AddressMapperTest(unittest.TestCase, SchedulerTestBase): def setUp(self): # Set up a scheduler that supports address mapping. symbol_table = TargetTable() address_mapper = AddressMapper(parser=JsonParser(symbol_table), build_patterns=('*.BUILD.json',))
def files(self): return [p for p in self.path_stats if type(p.stat) == File] @property def file_stats(self): return [p.stat for p in self.files] class DirectoryToMaterialize( datatype([('path', text_type), ('directory_digest', DirectoryDigest)])): """A request to materialize the contents of a directory digest at the provided path.""" pass FilesContent = Collection.of(FileContent) # TODO(cosmicexplorer): don't recreate this in python, get this from # fs::EMPTY_DIGEST somehow. _EMPTY_FINGERPRINT = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' EMPTY_DIRECTORY_DIGEST = DirectoryDigest( fingerprint=text_type(_EMPTY_FINGERPRINT), serialized_bytes_length=0) EMPTY_SNAPSHOT = Snapshot( directory_digest=EMPTY_DIRECTORY_DIGEST, path_stats=(), ) def create_fs_rules():
return [p.stat for p in self.dirs] @property def files(self): return [p for p in self.path_stats if type(p.stat) == File] @property def file_stats(self): return [p.stat for p in self.files] class DirectoryToMaterialize(datatype([('path', text_type), ('directory_digest', DirectoryDigest)])): """A request to materialize the contents of a directory digest at the provided path.""" pass FilesContent = Collection.of(FileContent) # TODO(cosmicexplorer): don't recreate this in python, get this from # fs::EMPTY_DIGEST somehow. _EMPTY_FINGERPRINT = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' EMPTY_DIRECTORY_DIGEST = DirectoryDigest( fingerprint=text_type(_EMPTY_FINGERPRINT), serialized_bytes_length=0 ) EMPTY_SNAPSHOT = Snapshot( directory_digest=EMPTY_DIRECTORY_DIGEST, path_stats=(),
) return self._raise_or_return(result) def lease_files_in_graph(self): self._native.lib.lease_files_in_graph(self._scheduler) def garbage_collect_store(self): self._native.lib.garbage_collect_store(self._scheduler) def new_session(self): """Creates a new SchedulerSession for this Scheduler.""" return SchedulerSession(self, self._native.new_session(self._scheduler)) _PathGlobsAndRootCollection = Collection.of(PathGlobsAndRoot) _DirectoryDigests = Collection.of(DirectoryDigest) class SchedulerSession(object): """A handle to a shared underlying Scheduler and a unique Session. Generally a Session corresponds to a single run of pants: some metrics are specific to a Session. """ def __init__(self, scheduler, session): self._scheduler = scheduler self._session = session self._run_count = 0
) return self._raise_or_return(result) def lease_files_in_graph(self): self._native.lib.lease_files_in_graph(self._scheduler) def garbage_collect_store(self): self._native.lib.garbage_collect_store(self._scheduler) def new_session(self): """Creates a new SchedulerSession for this Scheduler.""" return SchedulerSession(self, self._native.new_session(self._scheduler)) _PathGlobsAndRootCollection = Collection.of(PathGlobsAndRoot) _DirectoryDigests = Collection.of(DirectoryDigest) _DirectoriesToMaterialize = Collection.of(DirectoryToMaterialize) class SchedulerSession(object): """A handle to a shared underlying Scheduler and a unique Session. Generally a Session corresponds to a single run of pants: some metrics are specific to a Session. """ execution_error_type = ExecutionError
from __future__ import (absolute_import, division, generators, nested_scopes, print_function, unicode_literals, with_statement) import collections import inspect from functools import update_wrapper import six from pants.build_graph.address import Address, BuildFileAddress from pants.engine.objects import Resolvable, Serializable from pants.util.objects import Collection, TypeConstraintError Addresses = Collection.of(Address) class BuildFileAddresses(Collection.of(BuildFileAddress)): @property def addresses(self): """Converts the BuildFileAddress objects in this collection to Address objects.""" return [bfa.to_address() for bfa in self.dependencies] class NotSerializableError(TypeError): """Indicates an addressable descriptor is illegally installed in a non-Serializable type.""" class MutationError(AttributeError): """Indicates an illegal attempt to mutate an addressable attribute that already has a value."""
self._to_value(_DirectoryDigests(directory_digests)), ) return self._raise_or_return(result) def lease_files_in_graph(self): self._native.lib.lease_files_in_graph(self._scheduler) def garbage_collect_store(self): self._native.lib.garbage_collect_store(self._scheduler) def new_session(self): """Creates a new SchedulerSession for this Scheduler.""" return SchedulerSession(self, self._native.new_session(self._scheduler)) _PathGlobsAndRootCollection = Collection.of(PathGlobsAndRoot) _DirectoryDigests = Collection.of(DirectoryDigest) class SchedulerSession(object): """A handle to a shared underlying Scheduler and a unique Session. Generally a Session corresponds to a single run of pants: some metrics are specific to a Session. """ def __init__(self, scheduler, session): self._scheduler = scheduler self._session = session
def test_collection_iteration(self): self.assertEqual([1, 2], [x for x in Collection.of(int)([1, 2])])
self._to_value(_DirectoriesToMaterialize(directories_paths_and_digests)), ) return self._raise_or_return(result) def lease_files_in_graph(self): self._native.lib.lease_files_in_graph(self._scheduler) def garbage_collect_store(self): self._native.lib.garbage_collect_store(self._scheduler) def new_session(self): """Creates a new SchedulerSession for this Scheduler.""" return SchedulerSession(self, self._native.new_session(self._scheduler)) _PathGlobsAndRootCollection = Collection.of(PathGlobsAndRoot) _DirectoryDigests = Collection.of(DirectoryDigest) _DirectoriesToMaterialize = Collection.of(DirectoryToMaterialize) class SchedulerSession(object): """A handle to a shared underlying Scheduler and a unique Session. Generally a Session corresponds to a single run of pants: some metrics are specific to a Session. """