def find(path, *, unsafe_ignore_extension=False): build_root = make_callback.build_root target = normalize_path(repo_root, build_root, path) if target in make_callback.find_cache: return make_callback.find_cache[target] if build_root is None: raise BuildException( "Rules files can only define functions, not invoke find()") if not unsafe_ignore_extension: ext = path.split(".")[-1] if "/" in ext: raise BuildException( "Cannot find() files without specifying an extension") out = [ os.path.relpath(path, repo_root) for path in glob( normalize_path(repo_root, build_root, path), recursive=True, ) ] make_callback.find_cache[target] = out = [ "//" + path for path in out if path in src_files ] return sorted(out)
def load_rules(path): path = normalize_path(repo_root, make_load_rules.rules_root, path) if not path.endswith(".py"): raise BuildException(f"Cannot import from a non .py file: {path}") if path in LOAD_FRAME_CACHE: return LOAD_FRAME_CACHE[path] start_time_stack.append(time.time()) old_rules_root = make_load_rules.rules_root __builtins__["load"] = make_load_rules(repo_root, path) # We hide the callback here, since you should not be running the # callback (or anything else!) in an import, but just providing defs frame = {"__builtins__": __builtins__} reset_mock_imports(frame, ["load"]) cached_root = make_callback.build_root make_callback.build_root = None with open(path) as f: try: exec(f.read(), frame) except Exception: raise BuildException( f"Error while processing rules file {path}:\n" + f"\n{Style.RESET_ALL}" + traceback.format_exc()) make_callback.build_root = cached_root make_load_rules.rules_root = old_rules_root TIMINGS[path] = load_time = time.time() - start_time_stack.pop() start_time_stack[0] += load_time out = LOAD_FRAME_CACHE[path] = Struct(frame) return out
def make_depset(*args): return GlobDepSet( lambda build_root=make_callback.build_root: ( dep if isinstance(dep, DepSet) else normalize_path(build_root, dep) for dep in (arg() if callable(arg) else arg for arg in args) ) )
def find(path, *, unsafe_ignore_extension=False): build_root = make_callback.build_root if not unsafe_ignore_extension: ext = path.split(".")[-1] if "/" in ext: raise BuildException( "Cannot find() files without specifying an extension" ) if build_root is None and not path.startswith("//"): raise BuildException( "find() cannot be invoked outside a BUILD file except using a repo-relative path." ) target = normalize_path(build_root, path) if target in make_callback.find_cache: return make_callback.find_cache[target] def gen(): return sorted( os.path.relpath(f, os.curdir) for f in glob( target, recursive=True, ) if os.path.relpath(os.path.realpath(f), os.curdir) in src_files ) out = make_callback.find_cache[target] = GlobDepSet(gen) return out
def resolve(path): build_root = make_callback.build_root if build_root is None: raise BuildException( "Rules files can only define functions, not invoke resolve(). " "If you are in an impl() function, use ctx.resolve() instead.") return "//" + normalize_path(repo_root, build_root, path)
def callback( *, name: Optional[str] = None, deps: Sequence[str] = (), impl: Callable, out: Union[str, Sequence[str]] = (), do_not_symlink: bool = False, ): build_root = make_callback.build_root if build_root is None: raise BuildException( "Rules files can only define functions, not invoke callback()") if isinstance(out, str): out = [out] rule = Rule( name=name, location=build_root, deps=[ dep if dep.startswith(":") else normalize_path( repo_root, build_root, dep) for dep in deps ], impl=impl, outputs=[ normalize_path(repo_root, build_root, output) for output in out ], do_not_symlink=do_not_symlink, ) for output in rule.outputs: add_target_rule(output, rule) if name is not None: add_target_rule(":" + name, rule) return f":{name}"
def callback( *, name: Optional[str] = None, deps: Sequence[str] = (), impl: Callable = lambda _: None, out: Union[str, Sequence[str]] = (), do_not_symlink: bool = False, do_not_cache: bool = False, ): build_root = make_callback.build_root if build_root is None: raise BuildException( "Rules files can only define functions, not invoke callback()" ) if isinstance(out, str): out = [out] def wrapped_impl(ctx): ctx.add_deps(deps) return impl(ctx) rule = Rule( name=name, location=build_root, impl=wrapped_impl, outputs=[normalize_path(build_root, output) for output in out], do_not_symlink=do_not_symlink, do_not_cache=do_not_cache, ) for output in rule.outputs: add_target_rule(output, rule) if name is not None: add_target_rule(":" + name, rule) return f":{name}"
def register_output_directory(self, path: str): self._check_active() self.output_directories.append( normalize_path(os.curdir, os.curdir, path))
def chdir(self, dest: str): self.cwd = normalize_path(self.cwd, dest)
def absolute(self, path: str): return normalize_path(self.cwd, path)
def chdir(self, dest: str): self.cwd = os.path.abspath( Path(self.repo_root).joinpath( normalize_path(self.repo_root, self.cwd, dest)))