aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykyta Holubakha <hilobakho@gmail.com>2017-07-09 14:40:33 +0300
committerMykyta Holubakha <hilobakho@gmail.com>2017-07-18 23:26:27 +0300
commitcc41d610f76c6de326ec50626ff55a47cde0bc84 (patch)
treebc847deaf37f4dba911d1d52144659b355f38e48
parentOverhauled patching support (diff)
downloadpomu-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.py10
-rw-r--r--pomu/patch/patch.py57
-rw-r--r--pomu/repo/repo.py20
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')