aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pomu/source/file.py71
-rw-r--r--pomu/source/portage.py29
-rw-r--r--pomu/util/query.py26
3 files changed, 125 insertions, 1 deletions
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()