def setup_class(cls): if not cls.extract_path.exists: cls.extract_path.create() print("downloading AUR metadata to {0}".format(cls.extract_path)) download("http://aur3.org/" + cls.tar_filename, cls.extract_path.join(cls.tar_filename)) print("extracting") # using :mod:`tarfile` fails with symlink errors (???) execute("tar xf " + cls.tar_filename, cwd=cls.extract_path.absolute) else: print("using existing metadata from {0}".format(cls.extract_path))
def from_pkgbuild(cls, pkgbuild_path, source_timeout=5, **kwargs): """Create a :class:`PackageMetadata` object from a **PKGBUILD**. This method simply uses bash to do what bash was created to do: and that is parse bash scripts. Parsing a PKGBUILD in any language other than bash *will* inevitably break on some packages, as many packagers and maintainers use parameter expansion, command substitution, and in some cases, even conditionally assign package-critical metadata. Unfortunately, using bash to source a PKGBUILD has been reported to hang on certain 3rd party (i.e., AUR) packages, and blindly sourcing an untrusted PKGBUILD is a security hazard anyway. This method takes a couple of precautions in light of this: 1. Fakeroot is used for each call to bash. 2. The bash subprocess is killed if runtime exceeds **source_timeout** (default is 5 seconds). Any additional keyword arguments passed will override any variables with the same name in the PKGBUILD. """ def filter_variables(line): return len(line.strip()) == len(line) and "=" in line def parse_array(string): array_item_re = "\[\d+\]=\"(.+?)\"" return re.findall(array_item_re, string) or string # Not really necessary to use fakeroot on the first call to bash, but # it can't hurt, can it? On my machine, it doesn't slow things down # all that much. out1 = execute("fakeroot bash -c set", stdout=PIPE).stdout out2 = execute("fakeroot bash -c '. {0}; set'".format(pkgbuild_path), stdout=PIPE, timeout=source_timeout).stdout dicts = map(lambda out: dict(map(lambda line: line.split("=", 1), filter(filter_variables, out.strip().split("\n")))), (out2, out1)) result = {k: parse_array(v) for k, v in dicts[0].items() if k in set.difference(*map(set, dicts))} if "PIPESTATUS" in result: result.pop("PIPESTATUS") result.update(kwargs) return cls(**result)
def sync(self, package): if (self.config.deptest_before_sync and execute("pacman -T " + package, stdout=PIPE).returncode != 0): raise DeferToNextBackend proc = self.pass_through(CAPABS.SYNC, as_root=True, args=(package,), stdout=None, stderr=PIPE) if "target not found" not in proc.stderr: sys.stderr.write(proc.stderr) if proc.returncode != 0: raise DeferToNextBackend
def deptest(*dependencies): return map(Dependency.from_depstring, filter(None, execute("pacman -T " + " ".join(map(str, dependencies)), stdout=PIPE).stdout.split()))