From 9d452c05c864087df9a6e727545a31c1aa12008c Mon Sep 17 00:00:00 2001 From: Mykyta Holubakha Date: Mon, 26 Jun 2017 07:48:34 +0300 Subject: Add local ebuild file backend introduce a way to query the impure world (and the user) --- pomu/source/file.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ pomu/source/portage.py | 29 ++++++++++++++++++++- pomu/util/query.py | 26 ++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 pomu/source/file.py create mode 100644 pomu/util/query.py diff --git a/pomu/source/file.py b/pomu/source/file.py new file mode 100644 index 0000000..8b1a650 --- /dev/null +++ b/pomu/source/file.py @@ -0,0 +1,71 @@ +""" +A package source module to import packages from filesystem locations (ebuilds) +""" + +import os + +from os import path +from shutil import copy2 +from tempfile import mkdtemp + +from pomu.package import Package +from pomu.source import dispatcher +from pomu.source.portage import cpv_split, ver_str +from pomu.util.query import query +from pomu.util.result import Result + +class LocalEbuild(): + """A class to represent a local ebuild""" + __name__ = 'fs' + + # slots? + def __init__(self, category, name, version, path): + self.category = category + self.name = name + self.version = version + self.path = path + + def fetch(self): + root = mkdtemp() + pkgpath = path.join(root, self.category, self.name) + os.makedirs(pkgpath) + copy2(self.path, pkgpath) + return Package(self, self.name, root, self.category, self.version) + + @staticmethod + def from_data_file(path): + with open(path, 'r') as f: + return LocalEbuildSource.parse_ebuild_path(f.readline()).unwrap() + + def write_meta(self, pkgdir): + with open(path.join(pkgdir, 'FS_ORIG_PATH'), 'w') as f: + f.write(self.path + '\n') + + def __str__(self): + return '{}/{}-{} (from {})'.format(self.category, self.name, self.version, self.path) + +@dispatcher.source +class LocalEbuildSource(): + """The source module responsible for importing local ebuilds""" + @dispatcher.handler(priority=5) + def parse_ebuild_path(uri): + if not path.isfile(uri) or not path.endswith('.ebuild'): + return Result.Err() + uri = path.abspath(uri) + dirn, basen = path.split(uri) + basen = basen[:-7] + _, name, v1, v2, v3 = cpv_split(basen) + ver = ver_str(v1, v2, v3) + parent = dirn.split('/')[-1] + # we need to query the impure world + # TODO: write a global option which would set the impure values non-interactively + if not ver: + ver = query('version', 'Please specify package version for {}'.format(basen)).expect() + category = query('category', 'Please enter category for {}'.format(basen), parent).expect() + return Result.Ok(LocalEbuild(category, name, ver, uri)) + + @dispatcher.handler() + def parse_full(uri): + if not uri.startswith('fs:'): + return Result.Err() + return LocalEbuildSource.parse_ebuild_path(uri) diff --git a/pomu/source/portage.py b/pomu/source/portage.py index dde9330..40ad964 100644 --- a/pomu/source/portage.py +++ b/pomu/source/portage.py @@ -95,7 +95,33 @@ class PortageSource(): elif uri.startswith(':'): repo = None uri = uri[1:] - return parse_spec(uri, repo) + return PortageSource.parse_spec(uri, repo) + + @dispatcher.handler(priority=4) + def parse_repo_ebuild(uri): + if not path.exists(uri): + return Result.Err() + uri = path.abspath(uri) + prefixes = [(x, portage_repo_path(x)) for x in portage_repos()] + for repo, repo_path in prefixes: + repo_path = repo_path.rstrip('/') + '/' + if uri.startswith(repo): + if path.isfile(uri): + if not uri.endswith('.ebuild'): + return Result.Err() + _, name, v1, v2, v3 = cpv_split(path.basename(uri)) + ver = ver_str(v1, v2, v3) + dircomps = path.dirname(uri)[len(repo_path):].split('/') + if len(dircomps) != 2: + return Result.Err() + return PortageSource.parse_spec('{}/{}-{}::{}'.format(dircomps[0], name, ver, repo)) + elif path.isdir(uri): + dircomps = path.dirname(uri)[len(repo_path):].split('/') + if len(dircomps) != 2: + return Result.Err() + return PortageSource.parse_spec('{}/{}'.format(*dircomps)) + return Result.Err() + @classmethod def fetch_package(cls, pkg): @@ -160,6 +186,7 @@ def repo_pkgs(repo, category, name, ver=None, slot=None): res.append((repo, d, name, best_ver(repo, d, name))) return res +#NOTE: consider moving cpv_split and ver_str into util def cpv_split(pkg): # dev-libs/openssl-0.9.8z_p8-r100 category, _, pkg = pkg.rpartition('/') # category may be omitted diff --git a/pomu/util/query.py b/pomu/util/query.py new file mode 100644 index 0000000..035fe1b --- /dev/null +++ b/pomu/util/query.py @@ -0,0 +1,26 @@ +""" +A module to (non)interactively query the user for impure values +""" + +import sys + +from pomu.util.result import Result + +def query(name, prompt=None, default=None): + """ + Queries the impure world for name + TODO: non-interactive + """ + if not prompt: + prompt = 'Please enter ' + name + if default: prompt += ' ({})'.format(default) + prompt += ' > ' + res = None + try: + res = input(prompt) + except EOFError: pass + if not res: + res = default + if not res: + return Result.Err('No {} or default provided'.format(name)) + return Result.Ok() -- cgit v1.2.3-65-gdbad