aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykyta Holubakha <hilobakho@gmail.com>2017-06-04 02:41:21 +0300
committerMykyta Holubakha <hilobakho@gmail.com>2017-06-04 02:41:21 +0300
commit859ee9529ea41f54cd589d66c8f4ec01388f17f6 (patch)
treebf0df07a518bd8e108c2d8ef4f68f26f530a270f
parentAssure that portage repo initialization tests pass (diff)
downloadpomu-859ee9529ea41f54cd589d66c8f4ec01388f17f6.tar.gz
pomu-859ee9529ea41f54cd589d66c8f4ec01388f17f6.tar.bz2
pomu-859ee9529ea41f54cd589d66c8f4ec01388f17f6.zip
Implement package source dispatch
-rw-r--r--pomu/source/__init__.py3
-rw-r--r--pomu/source/manager.py72
2 files changed, 69 insertions, 6 deletions
diff --git a/pomu/source/__init__.py b/pomu/source/__init__.py
new file mode 100644
index 0000000..a86679f
--- /dev/null
+++ b/pomu/source/__init__.py
@@ -0,0 +1,3 @@
+from pomu.source.manager import PackageDispatcher
+
+dispatcher = PackageDispatcher()
diff --git a/pomu/source/manager.py b/pomu/source/manager.py
index a15a427..93c05c0 100644
--- a/pomu/source/manager.py
+++ b/pomu/source/manager.py
@@ -1,8 +1,68 @@
-def register_package_handler(source, handler, priority):
- pass
+"""
+Package source manager is responsible for selecting the correct source
+for a requested package, by a provided string.
-def get_package_source(uri):
- pass
+Package sources can provide several handlers with different priorities.
+A handler is a String -> Result function, which tries to parse the passed
+value and return Ok(value).
-def get_package(uri):
- pass
+The package would be handled by the handler with the lowest priority, which
+was added the first.
+
+Example:
+ @dispatcher.source
+ class BgoSource():
+ @dispatcher.handler(priority=5)
+ def parse_int(uri):
+ if uri.is_decimal():
+ return Result.Ok(int(uri))
+ elif uri[0] == '#' and uri[1:].is_decimal():
+ return Result.Ok(int(uri[1:]))
+ return Result.Err('NaN')
+
+ @dispatcher.handler(priority=1)
+ def parse_url(uri):
+ if uri.startswith('http://bugs.gentoo.org/'):
+ ...
+"""
+#TODO: efficient sorted insertion
+#import bisect
+import inspect
+
+class PackageDispatcher():
+ def __init__(self):
+ self.handlers = []
+
+ def source(self, cls):
+ for m, obj in inspect.getmembers(cls):
+ if isinstance(obj, self.handler._handler):
+ self.register_package_handler(cls, obj.handler, obj.priority)
+ return cls
+
+ class handler():
+ class _handler():
+ def __init__(self, handler):
+ self.handler = handler
+ def __call__(self, *args):
+ return self.handler(*args)
+
+ def __init__(self, priority=1000, *args, **kwargs):
+ self.priority = priority
+
+ def __call__(self, func, *args, **kwargs):
+ x = self._handler(func)
+ x.priority = self.priority
+ return x
+
+ def register_package_handler(self, source, handler, priority):
+ i = 0
+ for i in range(len(self.handlers)):
+ if self.handlers[0] > priority:
+ break
+ self.handlers.insert(i, (priority, source, handler))
+
+ def get_package_source(self, uri):
+ for priority, source, handler in self.handlers:
+ if handler(uri).is_ok():
+ return source
+ return None