def test_locate(self): with pytest.raises(ParseContext.ContextError): ParseContext.locate() with temporary_dir() as root_dir: a_context = ParseContext(create_buildfile(root_dir, 'a')) b_context = ParseContext(create_buildfile(root_dir, 'b')) def test_in_a(): self.assertEquals(a_context, ParseContext.locate()) return b_context.do_in_context(lambda: ParseContext.locate()) self.assertEquals(b_context, a_context.do_in_context(test_in_a))
def __init__(self, target, msg): address = getattr(target, 'address', None) if address is None: try: location = ParseContext.locate().current_buildfile except ParseContext.ContextError: location = 'unknown location' address = 'unknown target of type %s in %s' % (target.__class__.__name__, location) super(Exception, self).__init__('Error with %s: %s' % (address, msg))
def python_requirements(requirements_relpath='requirements.txt'): """Translates a pip requirements file into an equivalent set of PythonRequirement targets. NB that there are some requirements files that can't be unambiguously translated; ie: multiple find links. For these files a ValueError will be raised that points out the issue. See the requirements file spec here: http://www.pip-installer.org/en/1.1/requirements.html :param string requirements_relpath: The relative path from the parent dir of the BUILD file using this function to the requirements file. By default a `requirements.txt` file sibling to the BUILD file is assumed. """ # TODO(John Sirois): Rework this when Patrick's target re-work branch lands - it may need special # handling. requirements = [] repository = None build_file = ParseContext.locate().current_buildfile requirements_path = os.path.join(build_file.parent_path, requirements_relpath) with open(requirements_path) as fp: for line in fp: line = line.strip() if line and not line.startswith('#'): if not line.startswith('-'): requirements.append(line) else: # handle flags we know about flag_value = line.split(' ', 1) if len(flag_value) == 2: flag = flag_value[0].strip() value = flag_value[1].strip() if flag in ('-f', '--find-links'): if repository is not None: raise ValueError('Only 1 --find-links url is supported per requirements file') repository = value for requirement in requirements: PythonRequirement(requirement, repository=repository)
def __init__(self, name, reinit_check=True, exclusives=None): """ :param string name: The target name. """ # See "get_all_exclusives" below for an explanation of the exclusives parameter. # This check prevents double-initialization in multiple-inheritance situations. # TODO(John Sirois): fix target inheritance - use super() to linearize or use alternatives to # multiple inheritance. if not reinit_check or not hasattr(self, '_initialized'): if not isinstance(name, Compatibility.string): self.address = '%s:%s' % (ParseContext.locate().current_buildfile, str(name)) raise TargetDefinitionException(self, "Invalid target name: %s" % name) self.name = name self.description = None self.address = self._locate() # TODO(John Sirois): Transition all references to self.identifier to eliminate id builtin # ambiguity self.id = self._create_id() self._register() self.labels = set() self._initialized = True self.declared_exclusives = collections.defaultdict(set) if exclusives is not None: for k in exclusives: self.declared_exclusives[k].add(exclusives[k]) self.exclusives = None # For synthetic codegen targets this will be the original target from which # the target was synthesized. self._derived_from = self
def __init__(self, spec, exclusives=None): """ :param string spec: target address. E.g., `src/java/com/twitter/common/util/BUILD\:util` """ # it's critical the spec is parsed 1st, the results are needed elsewhere in constructor flow parse_context = ParseContext.locate() def parse_address(): if spec.startswith(':'): # the :[target] could be in a sibling BUILD - so parse using the canonical address pathish = "%s:%s" % (parse_context.buildfile.canonical_relpath, spec[1:]) return Address.parse(parse_context.buildfile.root_dir, pathish, False) else: return Address.parse(parse_context.buildfile.root_dir, spec, False) try: self.address = parse_address() except IOError as e: self.address = parse_context.buildfile.relpath raise TargetDefinitionException(self, '%s%s' % (self._DEFINITION_ERROR_MSG, e)) # We must disable the re-init check, because our funky __getattr__ breaks it. # We're not involved in any multiple inheritance, so it's OK to disable it here. super(Pants, self).__init__(self.address.target_name, reinit_check=False, exclusives=exclusives)
def _locate(self): parse_context = ParseContext.locate() return Address(parse_context.current_buildfile, self.name)
def _post_construct(self, func, *args, **kwargs): """Registers a command to invoke after this target's BUILD file is parsed.""" ParseContext.locate().on_context_exit(func, *args, **kwargs)
def test_in_a(): self.assertEquals(a_context, ParseContext.locate()) return b_context.do_in_context(lambda: ParseContext.locate())