diff options
author | Mykyta Holubakha <hilobakho@gmail.com> | 2017-07-09 14:40:33 +0300 |
---|---|---|
committer | Mykyta Holubakha <hilobakho@gmail.com> | 2017-07-18 23:26:27 +0300 |
commit | cc41d610f76c6de326ec50626ff55a47cde0bc84 (patch) | |
tree | bc847deaf37f4dba911d1d52144659b355f38e48 | |
parent | Overhauled patching support (diff) | |
download | pomu-cc41d610f76c6de326ec50626ff55a47cde0bc84.tar.gz pomu-cc41d610f76c6de326ec50626ff55a47cde0bc84.tar.bz2 pomu-cc41d610f76c6de326ec50626ff55a47cde0bc84.zip |
Further work on patching
fixed some commands with patching
started work on integrating user changes
generation of patches and commit messages
added get_packages() method to Repository
allow adding non-existant (in-memory) patches to packages
-rw-r--r-- | pomu/cli.py | 10 | ||||
-rw-r--r-- | pomu/patch/patch.py | 57 | ||||
-rw-r--r-- | pomu/repo/repo.py | 20 |
3 files changed, 81 insertions, 6 deletions
diff --git a/pomu/cli.py b/pomu/cli.py index 4e7ea7a..9477ff9 100644 --- a/pomu/cli.py +++ b/pomu/cli.py @@ -72,10 +72,10 @@ def status(): @main.command() @click.argument('package', required=True) -@click.argument('--patch', nargs=-1) +@click.option('--patch', nargs=-1) #help='Patches for the package') @needs_repo -def install(package): +def install(package, patch): """Install a package""" pkg = dispatcher.get_package(package).expect() pkg.patch(patch) @@ -92,6 +92,12 @@ def patch(package): pkg.patch(patch).expect() @main.command() +@click.argument('--single', is_flag=True, required=False, default=False) +def commit(single): + repo = pomu_active_repo() + change_map = process_changes(repo).expect() + +@main.command() @click.option('--uri', is_flag=True, help='Specify the package to remove by uri, instead of its name') @click.argument('package', required=True) diff --git a/pomu/patch/patch.py b/pomu/patch/patch.py new file mode 100644 index 0000000..3275cf9 --- /dev/null +++ b/pomu/patch/patch.py @@ -0,0 +1,57 @@ +""" +""" + +from os import path, walk, makedirs +from shutil import copy2 +from time import time + +import subprocess + +from git.repo import Repo +from patch import PatchSet + +from pomu.repo.repo import Repository +from pomu.util.fs import strip_prefix +from pomu.util.misc import list_add +from pomu.util.pkg import cpv_split +from pomu.util.result import Result + +def process_changes(_repo): + # we only tackle repository changes so far + repo = Repo(_repo.root) + chans = repo.head.commit.diff(None, create_patch=True) + new_files = repo.untracked_files + all_pkgs = _repo.get_packages + res = {x: [] for x in all_pkgs} + pkgs = ls + for f in new_files: # process untracked files + pkpref = path.dirname(f).split('/')[0:1].join('/') + if pkpref in res: + res[pkpref].append(new_file_patch(f)) + for diff in chans: # changes in tracked files + pkpref = path.dirname(diff.a_path).split('/')[0:1].join('/') + if pkpref in res: + res[pkpref].append(header(diff.a_path, diff.b_path).join('\n') + + diff.diff.decode('utf-8')) + res = {x: res[x] for x in res if res[x]} + for _pkg, diffs in res.items(): # add each change as its own patch + cat, name, *_ = cpv_split(_pkg) + patch_contents = diffs.join('\n') + pkg = _repo.get_package(cat, name) + patch_name = '{}-user_changes.patch'.format(int(time.time())) + pkg.add_patch(patch_contents, patch_name) + repo.index.add([x.a_path for x in diffs]) + repo.index.add([path.join(_repo.root, 'metadata', cat, name, patch_name)]) + repo.index.commit('{}/{}: imported user changes'.format(cat, name)) + +def new_file_patch(repo, newf): + with open(path.join(repo.root, newf), 'r') as f: + lines = ['+' + x.strip('\n') for x in f.readlines()] + head = header('/dev/null', newf, len(lines)) + return (head + lines).join('\n') + '\n' + +def diff_header(a_path, b_path, lines=None): + header = ['--- ' + a_path, '+++ ' + 'b/' + b_path] + if lines: + header.append('@@ -0,0 +1,' + lines + ' @@') + return header diff --git a/pomu/repo/repo.py b/pomu/repo/repo.py index b60f6c1..1530dfa 100644 --- a/pomu/repo/repo.py +++ b/pomu/repo/repo.py @@ -1,4 +1,5 @@ """Subroutines with repositories""" +123 from os import path, rmdir, makedirs from shutil import copy2 @@ -135,6 +136,11 @@ class Repository(): return self._get_package(category, name, slot) return Result.Err('Package not found') + def get_packages(self): + with open(path.join(self.pomu_dir, 'world'), 'r') as f: + lines = [x.strip() for x in f.readlines() if x.strip() != ''] + return lines + def portage_repos(): """Yield the repositories configured for portage""" @@ -192,12 +198,18 @@ class MergedPackage(Package): self.add_patch(patch) return Result.Ok() - def add_patch(self, patch): + def add_patch(self, patch, name=None): # patch is a path, unless name is passed pkgdir = path.join(self.root, 'metadata', 'pomu', self.category, self.name) if self.slot != '0': pkgdir = path.join(pkgdir, self.slot) patch_dir = path.join(pkgdir, 'patches') makedirs(patch_dir, exist_ok=True) - copy2(patch, patch_dir) - with open(path.join(pkgdir, 'PATCH_ORDER'), 'w+') as f: - f.write(path.basename(patch) + '\n') + if name is None: + copy2(patch, patch_dir) + with open(path.join(pkgdir, 'PATCH_ORDER'), 'w+') as f: + f.write(path.basename(patch) + '\n') + else: + with open(path.join(patch_dir, name), 'w') as f: + f.write(patch) + with open(path.join(pkgdir, 'PATCH_ORDER'), 'w+') as f: + f.write(name + '\n') |