aboutsummaryrefslogtreecommitdiff
blob: 69a0821240a221c6b8bf2354ea718589cc6d237b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""
A package source module to import packages from filesystem locations (ebuilds)
"""

from os import path, mkdtemp

from pomu.package import Package
from pomu.source import dispatcher
from pomu.util.pkg import cpv_split, ver_str
from pomu.util.query import query
from pomu.util.result import Result

class Patcher():
    """A class to represent a local ebuild"""
    __name__ = 'patch'
    
    def __init__(self, wrapped, *patches):
        self.patches = patches
        self.wrapped = wrapped
        # nested patching
        if wrapped is Patcher:
            self.patches = wrapped.patches + self.patches
            self.wrapped = wrapped.wrapped

    def fetch(self):
        pkg = self.wrapped.fetch()
        pkg.backend = self
        pd = mkdtemp()
        pkg.merge_into(pd)
        pkg.apply_patches(pd, self.patches)
        return Package(pkg.name, pd, self, pkg.category, pkg.version)
    
    @staticmethod
    def from_data_dir(pkgdir):
        with open(path.join(pkgdir, 'PATCH_ORIG_BACKEND'), 'r') as f:
            wrapped = dispatcher.backends[bname].from_meta_dir(pkgdir)
        patches = [path.join(pkgdir, 'patches', x.strip())
                for x in open(path.join(pkgdir, 'PATCH_PATCHES_ORDER'))]

    def write_meta(self, pkgdir):
        with open(path.join(pkgdir, 'PATCH_ORIG_BACKEND'), 'w') as f:
            f.write('{}\n'.format(self.wrapped.__name__))
        with open(path.join(pkgdir, 'PATCH_PATCHES_ORDER'), 'w') as f:
            for p in self.patches:
                f.write(path.basename(p) + '\n')
        os.makedirs(path.join(pkgdir, 'patches'), exist_ok=True)
        for p in self.patches:
            shutil.copy2(p, path.join(pkgdir, 'patches'))
        # write originals?

    def __str__(self):
        return '{}/{}-{} (from {})'.format(self.category, self.name, self.version, self.path)

@dispatcher.source
class LocalEbuildSource():
    """The source module responsible for importing and patching various ebuilds"""
    @dispatcher.handler()
    def parse_full(uri):
        if not uri.startswith('patch:'):
            return Result.Err()
        uri = uri[6:]
        patchf, _, pks = uri.partition(':')
        if not path.isfile(patchf):
            return Result.Err('Invalid patch file')
        if not pks:
            return Result.Err('Package not provided')
        pkg = dispatcher.get_package(pks)
        return Result.Ok(Patcher(patchf, pkg)

    @classmethod
    def from_meta_dir(cls, metadir):
        return Patcher.from_data_dir(cls, metadir)