summaryrefslogtreecommitdiff
path: root/gbp
diff options
context:
space:
mode:
authorbiao716.wang <biao716.wang@samsung.com>2022-11-25 22:24:26 +0900
committerbiao716.wang <biao716.wang@samsung.com>2022-11-28 21:21:23 +0900
commit6f7ef991f742eb5c5226272ca28edd71a2424143 (patch)
tree8dc1dda13dca3149b20cfdf77ed97e1732e56fe9 /gbp
parent0ddd0409b7ba0e9cb3e5234a506041ff032c2e27 (diff)
downloadgit-buildpackage-6f7ef991f742eb5c5226272ca28edd71a2424143.tar.gz
git-buildpackage-6f7ef991f742eb5c5226272ca28edd71a2424143.tar.bz2
git-buildpackage-6f7ef991f742eb5c5226272ca28edd71a2424143.zip
porting code to python3.x with os patch
Change-Id: I3deda71d6bde7c3363800d79d2e9ae6998bdb9e7 Signed-off-by: biao716.wang <biao716.wang@samsung.com>
Diffstat (limited to 'gbp')
-rw-r--r--gbp/command_wrappers.py4
-rw-r--r--gbp/deb/changelog.py10
-rw-r--r--gbp/deb/format.py2
-rw-r--r--gbp/format.py20
-rw-r--r--gbp/git/__init__.py1
-rw-r--r--gbp/git/fastimport.py42
-rw-r--r--gbp/git/modifier.py29
-rw-r--r--gbp/git/repository.py274
-rw-r--r--gbp/patch_series.py27
-rwxr-xr-xgbp/paths.py26
-rw-r--r--gbp/rpm/__init__.py37
-rw-r--r--gbp/rpm/linkedlist.py2
-rw-r--r--gbp/scripts/common/buildpackage.py5
-rw-r--r--gbp/scripts/common/import_orig.py6
-rw-r--r--gbp/scripts/common/pq.py26
-rw-r--r--gbp/scripts/import_dscs.py42
-rwxr-xr-xgbp/scripts/import_srpm.py2
-rwxr-xr-xgbp/scripts/pq.py6
-rwxr-xr-xgbp/scripts/pq_rpm.py10
-rwxr-xr-xgbp/scripts/rpm_ch.py3
-rw-r--r--gbp/scripts/supercommand.py8
21 files changed, 348 insertions, 234 deletions
diff --git a/gbp/command_wrappers.py b/gbp/command_wrappers.py
index 0d29af17..b4f24457 100644
--- a/gbp/command_wrappers.py
+++ b/gbp/command_wrappers.py
@@ -43,7 +43,7 @@ class Command(object):
self.run_error = "'%s' failed" % (" ".join([self.cmd] + self.args))
self.shell = shell
self.retcode = 1
- self.stderr = ''
+ self.stderr = b''
self.capture_stderr = capture_stderr
self.cwd = cwd
if extra_env is not None:
@@ -62,7 +62,7 @@ class Command(object):
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
log.debug("%s %s %s" % (self.cmd, self.args, args))
- self.stderr = ''
+ self.stderr = b''
stderr_arg = subprocess.PIPE if self.capture_stderr else None
cmd = [ self.cmd ] + self.args + args
if self.shell:
diff --git a/gbp/deb/changelog.py b/gbp/deb/changelog.py
index 9b3c03bb..41aca947 100644
--- a/gbp/deb/changelog.py
+++ b/gbp/deb/changelog.py
@@ -93,10 +93,10 @@ class ChangeLog(object):
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- (output, errors) = cmd.communicate(self._contents)
+ (output, errors) = cmd.communicate(self._contents.encode('utf-8'))
if cmd.returncode:
raise ParseChangeLogError("Failed to parse changelog. "
- "dpkg-parsechangelog said:\n%s" % (errors, ))
+ "dpkg-parsechangelog said:\n%s" % errors.decode().strip()))
# Parse the result of dpkg-parsechangelog (which looks like
# email headers)
cp = email.message_from_string(output)
@@ -115,8 +115,8 @@ class ChangeLog(object):
self._cp = cp
def _read(self):
- with open(self.filename) as f:
- self._contents = f.read()
+ with open(self.filename, encoding='utf-8') as f:
+ self._contents = f.read()
def __getitem__(self, item):
return self._cp[item]
@@ -131,7 +131,7 @@ class ChangeLog(object):
@property
def name(self):
- """The packges name"""
+ """The packages name"""
return self._cp['Source']
@property
diff --git a/gbp/deb/format.py b/gbp/deb/format.py
index 3a4c8ab3..cd56cdfb 100644
--- a/gbp/deb/format.py
+++ b/gbp/deb/format.py
@@ -84,7 +84,7 @@ class DebianSourceFormat(object):
>>> import tempfile, os
>>> with tempfile.NamedTemporaryFile(delete=False) as t:
- ... t.write("3.0 (quilt)")
+ ... ret = t.write(b"3.0 (quilt)")
>>> d = DebianSourceFormat.parse_file(t.name)
>>> d.version
'3.0'
diff --git a/gbp/format.py b/gbp/format.py
index 2a4af15c..59c932d8 100644
--- a/gbp/format.py
+++ b/gbp/format.py
@@ -42,3 +42,23 @@ def format_msg(msg, args):
raise GbpError("Failed to format %s: Missing value %s in %s" % (msg, e, args))
+def format_b(fmtstr, *args):
+ """String-like interpolation for bytes objects.
+
+ NOTE: This is a compatibility wrapper for older versions (<3.5) of Python 3
+ which do not support the percent operator ('%') for bytes objects. This
+ function should be removed (and replaced by simple '%') when Python 3.5
+ has gained wide enough adoption.
+
+ >>> format_b(b'%s %d', b'foo', 123)
+ b'foo 123'
+ >>> format_b(b'foo 123')
+ b'foo 123'
+ >>> format_b('%s %d', b'foo', 123)
+ Traceback (most recent call last):
+ ...
+ AttributeError: 'str' object has no attribute 'decode'
+ """
+ fmtstr = fmtstr.decode()
+ strargs = tuple([(a.decode() if isinstance(a, bytes) else a) for a in args])
+ return (fmtstr % strargs).encode() \ No newline at end of file
diff --git a/gbp/git/__init__.py b/gbp/git/__init__.py
index 57b74eff..53c2bfcd 100644
--- a/gbp/git/__init__.py
+++ b/gbp/git/__init__.py
@@ -43,3 +43,4 @@ def rfc822_date_to_git(rfc822_date):
return '%d %s' % (seconds, tz)
# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·:
+
diff --git a/gbp/git/fastimport.py b/gbp/git/fastimport.py
index 435d5e0e..9b27a2b6 100644
--- a/gbp/git/fastimport.py
+++ b/gbp/git/fastimport.py
@@ -20,6 +20,9 @@
import subprocess
import time
from gbp.errors import GbpError
+from gbp.format import format_b
+from gbp.paths import to_bin
+
class FastImport(object):
"""Add data to a git repository using I{git fast-import}"""
@@ -36,7 +39,7 @@ class FastImport(object):
"""
self._repo = repo
try:
- self._fi = subprocess.Popen([ 'git', 'fast-import', '--quiet'],
+ self._fi = subprocess.Popen(['git', 'fast-import', '--quiet'],
stdin=subprocess.PIPE, cwd=repo.path)
self._out = self._fi.stdin
except OSError as err:
@@ -46,17 +49,17 @@ class FastImport(object):
"Invalid argument when spawning git fast-import: %s" % err)
def _do_data(self, fd, size):
- self._out.write("data %s\n" % size)
+ self._out.write(format_b(b"data %d\n", size))
while True:
data = fd.read(self._bufsize)
self._out.write(data)
if len(data) != self._bufsize:
break
- self._out.write("\n")
+ self._out.write(b"\n")
def _do_file(self, filename, mode, fd, size):
- name = "/".join(filename.split('/')[1:])
- self._out.write("M %d inline %s\n" % (mode, name))
+ name = b"/".join(to_bin(filename).split(b'/')[1:])
+ self._out.write(format_b(b"M %d inline %s\n", mode, name))
self._do_data(fd, size)
def add_file(self, filename, fd, size, mode=m_regular):
@@ -83,9 +86,11 @@ class FastImport(object):
@param linktarget: the target the symlink points to
@type linktarget: C{str}
"""
- self._out.write("M %d inline %s\n" % (self.m_symlink, linkname))
- self._out.write("data %s\n" % len(linktarget))
- self._out.write("%s\n" % linktarget)
+ linktarget = to_bin(linktarget)
+ linkname = to_bin(linkname)
+ self._out.write(format_b(b"M %d inline %s\n", self.m_symlink, linkname))
+ self._out.write(format_b(b"data %d\n", len(linktarget)))
+ self._out.write(format_b(b"%s\n", linktarget))
def start_commit(self, branch, committer, msg):
"""
@@ -108,24 +113,23 @@ class FastImport(object):
else:
from_ = ''
- self._out.write("""commit refs/heads/%(branch)s
+ s = """commit refs/heads/%(branch)s
committer %(name)s <%(email)s> %(time)s
data %(length)s
-%(msg)s%(from)s""" %
- { 'branch': branch,
- 'name': committer.name,
- 'email': committer.email,
- 'time': committer.date,
- 'length': length,
- 'msg': msg,
- 'from': from_,
- })
+%(msg)s%(from)s""" % {'branch': branch,
+ 'name': committer.name,
+ 'email': committer.email,
+ 'time': committer.date,
+ 'length': length,
+ 'msg': msg,
+ 'from': from_}
+ self._out.write(s.encode())
def deleteall(self):
"""
Issue I{deleteall} to fastimport so we start from a empty tree
"""
- self._out.write("deleteall\n")
+ self._out.write(b"deleteall\n")
def close(self):
"""
diff --git a/gbp/git/modifier.py b/gbp/git/modifier.py
index 5f5b5999..ba5ad763 100644
--- a/gbp/git/modifier.py
+++ b/gbp/git/modifier.py
@@ -20,7 +20,8 @@ Someone who modifiers something in git
like committing changes or authoring a patch
"""
-import calendar, datetime
+import calendar
+import datetime
from gbp.git.errors import GitError
@@ -72,7 +73,7 @@ class GitModifier(object):
self._date = date
else:
self._date = date.replace(tzinfo=tz)
- elif date != None:
+ elif date is not None:
raise ValueError("Date '%s' not timestamp, "
"datetime object or git raw date" % date)
@@ -119,9 +120,11 @@ class GitModifier(object):
"""
Get env vars for authorship information
- >>> g = GitModifier("foo", "bar")
- >>> g.get_author_env()
- {'GIT_AUTHOR_EMAIL': 'bar', 'GIT_AUTHOR_NAME': 'foo'}
+ >>> g = GitModifier("Joey Ramone", "joey@example.com")
+ >>> g.get_author_env()['GIT_AUTHOR_EMAIL']
+ 'joey@example.com'
+ >>> g.get_author_env()['GIT_AUTHOR_NAME']
+ 'Joey Ramone'
@return: Author information suitable to use as environment variables
@rtype: C{dict}
@@ -132,15 +135,23 @@ class GitModifier(object):
"""
Get env vars for committer information
- >>> g = GitModifier("foo", "bar")
- >>> g.get_committer_env()
- {'GIT_COMMITTER_NAME': 'foo', 'GIT_COMMITTER_EMAIL': 'bar'}
+ >>> g = GitModifier("Joey Ramone", "joey@example.com")
+ >>> g.get_committer_env()['GIT_COMMITTER_EMAIL']
+ 'joey@example.com'
+ >>> g.get_committer_env()['GIT_COMMITTER_NAME']
+ 'Joey Ramone'
- @return: Commiter information suitable to use as environment variables
+ @return: Committer information suitable to use as environment variables
@rtype: C{dict}
"""
return self._get_env('committer')
+ def get(self, key, default=None):
+ if key in self.keys():
+ return self.__getitem__(key)
+ else:
+ return default
+
def __getitem__(self, key):
if key == 'date':
return self.date
diff --git a/gbp/git/repository.py b/gbp/git/repository.py
index 42661678..3dfecdc1 100644
--- a/gbp/git/repository.py
+++ b/gbp/git/repository.py
@@ -19,14 +19,17 @@
import subprocess
import os.path
import re
+import sys
from collections import defaultdict
import select
import gbp.log as log
+from gbp.format import format_b
from gbp.git.modifier import GitModifier
from gbp.git.commit import GitCommit
from gbp.git.errors import GitError
from gbp.git.args import GitArgs
+from gbp.paths import to_bin
class GitRepositoryError(GitError):
@@ -85,7 +88,7 @@ class GitRepository(object):
"Failed to get repository git dir at '%s'" % self.path)
# Set git meta data dir
- git_dir = out.strip()
+ git_dir = out.strip().decode(sys.getfilesystemencoding())
if os.path.isabs(git_dir):
self._git_dir = git_dir
else:
@@ -106,6 +109,7 @@ class GitRepository(object):
# Check for bare repository
out, dummy, ret = self._git_inout('rev-parse', ['--is-bare-repository'],
capture_stderr=True)
+ cdup = out.strip().decode(sys.getfilesystemencoding())
if ret:
raise GitRepositoryError("No Git repository at '%s': '%s'" % (self.path, out))
self._bare = False if out.strip() != 'true' else True
@@ -298,9 +302,8 @@ class GitRepository(object):
except Exception as excobj:
raise GitRepositoryError("Error running git %s: %s" % (command, excobj))
if ret:
- raise GitRepositoryError("Error running git %s: %s" %
- (command, stderr.strip()))
-
+ detail = stderr or stdout
+ raise GitRepositoryError("Error running git %s: %s" % (command, detail.decode().strip()))
def _cmd_has_feature(self, command, feature):
"""
@@ -315,12 +318,12 @@ class GitRepository(object):
"""
args = GitArgs(command, '-m')
help, stderr, ret = self._git_inout('help',
- args.args,
- extra_env={'LC_ALL': 'C'},
- capture_stderr=True)
+ args.args,
+ extra_env={'LC_ALL': 'C'},
+ capture_stderr=True)
if ret:
raise GitRepositoryError("Invalid git command '%s': %s"
- % (command, stderr[:-1]))
+ % (command, stderr.decode().strip()))
# Parse git command man page
section_re = re.compile(r'^(?P<section>[A-Z].*)')
@@ -328,7 +331,7 @@ class GitRepository(object):
optopt_re = re.compile(r'--\[(?P<prefix>[a-zA-Z\-]+)\]-?')
backspace_re = re.compile(".\b")
man_section = None
- for line in help.splitlines():
+ for line in help.decode().splitlines():
if man_section == "OPTIONS" and line.startswith(' -'):
opts = line.split(',')
for opt in opts:
@@ -359,7 +362,7 @@ class GitRepository(object):
@property
def bare(self):
- """Wheter this is a bare repository"""
+ """Whether this is a bare repository"""
return self._bare
@property
@@ -377,7 +380,7 @@ class GitRepository(object):
@property
def head(self):
- """return the SHA1 of the current HEAD"""
+ """SHA1 of the current HEAD"""
return self.rev_parse('HEAD')
#{ Branches and Merging
@@ -433,13 +436,13 @@ class GitRepository(object):
@raises GitRepositoryError: if HEAD is not a symbolic ref
(e.g. when in detached HEAD state)
"""
- out, dummy, ret = self._git_inout('symbolic-ref', [ 'HEAD' ],
- capture_stderr=True)
+ out, _, ret = self._git_inout('symbolic-ref', ['HEAD'],
+ capture_stderr=True)
if ret:
# We don't append stderr since
# "fatal: ref HEAD is not a symbolic ref" confuses people
raise GitRepositoryError("Currently not on a branch")
- ref = out.split('\n')[0]
+ ref = out.decode().split('\n')[0]
# Check if ref really exists
try:
@@ -517,9 +520,9 @@ class GitRepository(object):
args.add(commit2)
sha1, stderr, ret = self._git_inout('merge-base', args.args, capture_stderr=True)
if not ret:
- return self.strip_sha1(sha1)
+ return self.strip_sha1(sha1.decode())
else:
- raise GitRepositoryError("Failed to get common ancestor: %s" % stderr.strip())
+ raise GitRepositoryError("Failed to get common ancestor: %s" % stderr.decode().strip())
def merge(self, commit, verbose=False, edit=False):
"""
@@ -529,7 +532,7 @@ class GitRepository(object):
@type commit: C{str}
@param verbose: whether to print a summary after the merge
@type verbose: C{bool}
- @param edit: wheter to invoke an editor to edit the merge message
+ @param edit: whether to invoke an editor to edit the merge message
@type edit: C{bool}
"""
args = GitArgs()
@@ -559,14 +562,15 @@ class GitRepository(object):
"""
has_local = False # local repo has new commits
has_remote = False # remote repo has new commits
- out = self._git_getoutput('rev-list', ["--left-right",
+ out = self._git_getoutput('rev-list',
+ ["--left-right",
"%s...%s" % (from_branch, to_branch),
"--"])[0]
- if not out: # both branches have the same commits
+ if not out: # both branches have the same commits
return True, True
- for line in out:
+ for line in (l.decode() for l in out):
if line.startswith("<"):
has_local = True
elif line.startswith(">"):
@@ -588,10 +592,10 @@ class GitRepository(object):
@return: local or remote branches
@rtype: C{list}
"""
- args = [ '--format=%(refname:short)' ]
- args += [ 'refs/remotes/' ] if remote else [ 'refs/heads/' ]
+ args = ['--format=%(refname:short)']
+ args += ['refs/remotes/'] if remote else ['refs/heads/']
out = self._git_getoutput('for-each-ref', args)[0]
- return [ ref.strip() for ref in out ]
+ return [ref.decode().strip() for ref in out]
def get_local_branches(self):
"""
@@ -649,8 +653,8 @@ class GitRepository(object):
args.add('--contains')
args.add(commit)
- out, ret = self._git_getoutput('branch', args.args)
- for line in out:
+ out, ret = self._git_getoutput('branch', args.args)
+ for line in [l.decode() for l in out]:
# remove prefix '*' for current branch before comparing
line = line.replace('*', '')
if line.strip() == branch:
@@ -703,7 +707,7 @@ class GitRepository(object):
out = self._git_getoutput('for-each-ref', args.args)[0]
- return out[0].strip()
+ return out[0].decode().strip()
#{ Tags
@@ -802,9 +806,9 @@ class GitRepository(object):
tag, err, ret = self._git_inout('describe', args.args,
capture_stderr=True)
if ret:
- raise GitRepositoryError("Can't describe %s. Git error: %s" % \
- (commitish, err.strip()))
- return tag.strip()
+ raise GitRepositoryError("Can't describe %s. Git error: %s" %
+ (commitish, err.decode().strip()))
+ return tag.decode().strip()
def find_tag(self, commit, pattern=None):
"""
@@ -828,8 +832,8 @@ class GitRepository(object):
@return: tags
@rtype: C{list} of C{str}
"""
- args = [ '-l', pattern ] if pattern else []
- return [ line.strip() for line in self._git_getoutput('tag', args)[0] ]
+ args = ['-l', pattern] if pattern else []
+ return [line.decode().strip() for line in self._git_getoutput('tag', args)[0]]
def verify_tag(self, tag):
"""
@@ -902,7 +906,7 @@ class GitRepository(object):
# Get a more helpful error message.
out = self._status(porcelain=False,
ignore_untracked=ignore_untracked)
- return (False, "".join(out))
+ return (False, "".join([e.decode() for e in out]))
else:
return (True, '')
@@ -946,16 +950,16 @@ class GitRepository(object):
if ret:
raise GitRepositoryError("Can't get repository status: %s" % err)
- elements = out.split('\x00')
+ elements = out.split(b'\x00')
result = defaultdict(list)
- while elements[0] != '':
+ while elements[0] != b'':
element = elements.pop(0)
- status = element[:2]
+ status = element[:2].decode()
filepath = element[3:]
# Expect to have two filenames for renames and copies
if status[0] in ['R', 'C']:
- filepath = elements.pop(0) + '\x00' + filepath
+ filepath = elements.pop(0) + b'\x00' + filepath
result[status].append(filepath)
return result
@@ -989,7 +993,7 @@ class GitRepository(object):
capture_stderr=True)
if ret:
raise GitRepositoryError("revision '%s' not found" % name)
- return self.strip_sha1(sha.splitlines()[0], short)
+ return self.strip_sha1(sha[0].decode(), short)
@staticmethod
def strip_sha1(sha1, length=0):
@@ -1002,7 +1006,7 @@ class GitRepository(object):
>>> GitRepository.strip_sha1('58ef37d', 10)
Traceback (most recent call last):
...
- GitRepositoryError: '58ef37d' is not a valid sha1 of length 10
+ gbp.git.repository.GitRepositoryError: '58ef37d' is not a valid sha1 of length 10
>>> GitRepository.strip_sha1('58ef37d', 7)
'58ef37d'
>>> GitRepository.strip_sha1('123456789', 7)
@@ -1010,16 +1014,16 @@ class GitRepository(object):
>>> GitRepository.strip_sha1('foobar')
Traceback (most recent call last):
...
- GitRepositoryError: 'foobar' is not a valid sha1
+ gbp.git.repository.GitRepositoryError: 'foobar' is not a valid sha1
"""
maxlen = 40
s = sha1.strip()
- l = length or maxlen
+ sl = length or maxlen
- if len(s) < l or len(s) > maxlen:
+ if len(s) < sl or len(s) > maxlen:
raise GitRepositoryError("'%s' is not a valid sha1%s" %
- (s, " of length %d" % l if length else ""))
+ (s, " of length %d" % sl if length else ""))
return s
#{ Trees
@@ -1041,9 +1045,9 @@ class GitRepository(object):
@return: C{True} if the repository has that tree, C{False} otherwise
@rtype: C{bool}
"""
- _out, _err, ret = self._git_inout('ls-tree', [treeish],
- capture_stderr=True)
- return [ True, False ][ret != 0]
+ _out, _err, ret = self._git_inout('ls-tree', [treeish],
+ capture_stderr=True)
+ return [True, False][ret != 0]
def write_tree(self, index_file=None):
"""
@@ -1063,28 +1067,30 @@ class GitRepository(object):
extra_env=extra_env,
capture_stderr=True)
if ret:
- raise GitRepositoryError("Can't write out current index: %s" % stderr[:-1])
- return tree.strip()
+ raise GitRepositoryError("Can't write out current index: %s" % stderr.decode().strip())
+ return tree.decode().strip()
def make_tree(self, contents):
"""
- Create a tree based on contents. I{contents} has the same format than
- the I{GitRepository.list_tree} output.
+ Create a tree based on contents.
+
+ @param contents: same format as I{GitRepository.list_tree} output.
+ @type contents: C{list} of C{str}
"""
- out=''
+ objs = b''
args = GitArgs('-z')
- for obj in contents:
- mode, type, sha1, name = obj
- out += '%s %s %s\t%s\0' % (mode, type, sha1, name)
+ for mode, type_, sha1, name in contents:
+ name = to_bin(name)
+ objs += format_b(b'%s %s %s\t%s\0', mode.encode(), type_.encode(), sha1.encode(), name)
- sha1, err, ret = self._git_inout('mktree',
- args.args,
- out,
- capture_stderr=True)
+ sha1, err, ret = self._git_inout('mktree',
+ args.args,
+ objs,
+ capture_stderr=True)
if ret:
raise GitRepositoryError("Failed to mktree: '%s'" % err)
- return self.strip_sha1(sha1)
+ return self.strip_sha1(sha1.decode())
def get_obj_type(self, obj):
"""
@@ -1098,12 +1104,12 @@ class GitRepository(object):
out, ret = self._git_getoutput('cat-file', args=['-t', obj])
if ret:
raise GitRepositoryError("Not a Git repository object: '%s'" % obj)
- return out[0].strip()
+ return out[0].decode().strip()
def list_tree(self, treeish, recurse=False, paths=None):
"""
Get a trees content. It returns a list of objects that match the
- 'ls-tree' output: [ mode, type, sha1, path ].
+ 'ls-tree' output: [mode, type, sha1, path].
@param treeish: the treeish object to list
@type treeish: C{str}
@@ -1118,14 +1124,18 @@ class GitRepository(object):
args.add("--")
args.add_cond(paths, paths)
- out, err, ret = self._git_inout('ls-tree', args.args, capture_stderr=True)
+ out, err, ret = self._git_inout('ls-tree', args.args, capture_stderr=True)
if ret:
- raise GitRepositoryError("Failed to ls-tree '%s': '%s'" % (treeish, err))
+ raise GitRepositoryError("Failed to ls-tree '%s': '%s'" % (treeish, err.decode().strip()))
tree = []
- for line in out.split('\0'):
+ for line in out.split(b'\0'):
if line:
- tree.append(line.split(None, 3))
+ parts = line.split(None, 3)
+ # decode everything but the file name
+ for i in range(len(parts) - 1):
+ parts[i] = parts[i].decode()
+ tree.append(parts)
return tree
#}
@@ -1139,8 +1149,9 @@ class GitRepository(object):
@rtype: C{str}
"""
value, ret = self._git_getoutput('config', [ name ])
- if ret: raise KeyError
- return value[0][:-1] # first line with \n ending removed
+ if ret:
+ raise KeyError("'%s' not found in git config")
+ return value[0].decode()[:-1] # first line with \n ending removed
def get_author_info(self):
"""
@@ -1151,11 +1162,11 @@ class GitRepository(object):
@rtype: L{GitModifier}
"""
try:
- name = self.get_config("user.name")
+ name = self.get_config("user.name")
except KeyError:
- name = os.getenv("USER")
+ name = os.getenv("USER")
try:
- email = self.get_config("user.email")
+ email = self.get_config("user.email")
except KeyError:
email = os.getenv("EMAIL")
email = os.getenv("GIT_AUTHOR_EMAIL", email)
@@ -1173,19 +1184,19 @@ class GitRepository(object):
"""
out, err, ret = self._git_inout('remote', [], capture_stderr=True)
if ret:
- raise GitRepositoryError('Failed to get list of remotes: %s' % err)
+ raise GitRepositoryError('Failed to get list of remotes: %s' % err.decode().strip())
# Get information about all remotes
remotes = {}
- for remote in out.splitlines():
+ for remote in out.decode().splitlines():
out, err, _ret = self._git_inout('remote', ['show', '-n', remote],
capture_stderr=True)
if ret:
raise GitRepositoryError('Failed to get information for remote '
- '%s: %s' % (remote, err))
+ '%s: %s' % (remote, err.decode().strip()))
fetch_url = None
push_urls = []
- for line in out.splitlines():
+ for line in out.decode().splitlines():
match = re.match('\s*Fetch\s+URL:\s*(\S.*)', line)
if match:
fetch_url = match.group(1)
@@ -1208,11 +1219,11 @@ class GitRepository(object):
stdout, stderr, ret = self._git_inout('remote', ['-v'],
capture_stderr=True)
if ret:
- raise GitRepositoryError('Failed to get remotes: %s' % stderr)
+ raise GitRepositoryError('Failed to get remotes: %s' % stderr.decode().strip())
remotes = {}
for rem in stdout.splitlines():
- name, url_urltype = rem.split('\t', 1)
+ name, url_urltype = rem.remote.decode().strip().split('\t', 1)
url, urltype = url_urltype.rsplit(' ', 1)
urltype = urltype.strip('()')
if not name in remotes:
@@ -1404,12 +1415,12 @@ class GitRepository(object):
@param types: list of types to show
@type types: C{list}
- @return: list of files
+ @return: list of files as byte string
@rtype: C{list} of C{str}
"""
- all_types = [ 'cached', 'deleted', 'others', 'ignored', 'stage'
- 'unmerged', 'killed', 'modified' ]
- args = [ '-z' ]
+ all_types = ['cached', 'deleted', 'others', 'ignored', 'stage'
+ 'unmerged', 'killed', 'modified']
+ args = ['-z']
for t in types:
if t in all_types:
@@ -1420,7 +1431,7 @@ class GitRepository(object):
if ret:
raise GitRepositoryError("Error listing files: '%d'" % ret)
if out:
- return [ file for file in out[0].split('\0') if file ]
+ return [file for file in out[0].split(b'\0') if file]
else:
return []
@@ -1430,7 +1441,7 @@ class GitRepository(object):
Hash a single file and write it into the object database
@param filename: the filename to the content of the file to hash
- @type filename: C{str}
+ @type filename: C{bytestr}
@param filters: whether to run filters
@type filters: C{bool}
@return: the hash of the file
@@ -1444,10 +1455,9 @@ class GitRepository(object):
args.args,
capture_stderr=True)
if not ret:
- return self.strip_sha1(sha1)
+ return self.strip_sha1(sha1.decode())
else:
- raise GitRepositoryError("Failed to hash %s: %s" % (filename,
- stderr))
+ raise GitRepositoryError("Failed to hash %s: %s" % (filename, stderr.decode().strip()))
#}
#{ Comitting
@@ -1606,13 +1616,13 @@ class GitRepository(object):
args += [ '-p' , parent ]
sha1, stderr, ret = self._git_inout('commit-tree',
args,
- msg,
+ msg.encode(),
extra_env,
capture_stderr=True)
if not ret:
- return self.strip_sha1(sha1)
+ return self.strip_sha1(sha1.decode())
else:
- raise GitRepositoryError("Failed to commit tree: %s" % stderr)
+ raise GitRepositoryError("Failed to commit tree: %s" % stderr.decode().strip())
#{ Commit Information
@@ -1645,22 +1655,26 @@ class GitRepository(object):
args.add_cond(options, options)
args.add("--")
if isinstance(paths, str):
- paths = [ paths ]
+ paths = [paths]
args.add_cond(paths, paths)
commits, ret = self._git_getoutput('log', args.args)
if ret:
where = " on %s" % paths if paths else ""
raise GitRepositoryError("Error getting commits %s..%s%s" %
- (since, until, where))
- return [ commit.strip() for commit in commits ]
+ (since, until, where))
+ return [commit.decode().strip() for commit in commits]
def show(self, id):
- """git-show id"""
+ """
+ Show a git object
+
+ @rtype: C{bytestr}
+ """
obj, stderr, ret = self._git_inout('show', ["--pretty=medium", id],
- capture_stderr=True)
+ capture_stderr=True)
if ret:
- raise GitRepositoryError("can't get %s: %s" % (id, stderr.rstrip()))
+ raise GitRepositoryError("can't get %s: %s" % (id, stderr.decode().rstrip()))
return obj
def grep_log(self, regex, since=None):
@@ -1682,9 +1696,9 @@ class GitRepository(object):
capture_stderr=True)
if ret:
raise GitRepositoryError("Error grepping log for %s: %s" %
- (regex, stderr[:-1]))
+ (regex, stderr.decode().strip()))
if stdout:
- return [ commit.strip() for commit in stdout.split('\n')[::-1] ]
+ return [commit.strip() for commit in stdout.decode().split('\n')[::-1]]
else:
return []
@@ -1713,36 +1727,38 @@ class GitRepository(object):
args = GitArgs('--pretty=format:%an%x00%ae%x00%ad%x00%cn%x00%ce%x00%cd%x00%s%x00%f%x00%b%x00',
'-z', '--date=raw', '--no-renames', '--name-status',
commit_sha1)
- out, err, ret = self._git_inout('show', args.args)
+ out, err, ret = self._git_inout('show', args.args)
if ret:
raise GitRepositoryError("Unable to retrieve commit info for %s"
% commitish)
- fields = out.split('\x00')
+ fields = out.split(b'\x00')
- author = GitModifier(fields[0].strip(),
- fields[1].strip(),
- fields[2].strip())
- committer = GitModifier(fields[3].strip(),
- fields[4].strip(),
- fields[5].strip())
+ author = GitModifier(fields[0].decode().strip(),
+ fields[1].decode().strip(),
+ fields[2].decode().strip())
+ committer = GitModifier(fields[3].decode().strip(),
+ fields[4].decode().strip(),
+ fields[5].decode().strip())
files = defaultdict(list)
file_fields = fields[9:]
+
# For some reason git returns one extra empty field for merge commits
- if file_fields[0] == '': file_fields.pop(0)
- while len(file_fields) and file_fields[0] != '':
- status = file_fields.pop(0).strip()
+ if file_fields[0] == b'':
+ file_fields.pop(0)
+ while len(file_fields) and file_fields[0] != b'':
+ status = file_fields.pop(0).decode().strip()
path = file_fields.pop(0)
files[status].append(path)
- return {'id' : commitish,
- 'author' : author,
- 'committer' : committer,
- 'subject' : fields[6],
- 'patchname' : fields[7],
- 'body' : fields[8],
- 'files' : files}
+ return {'id': commitish,
+ 'author': author,
+ 'committer': committer,
+ 'subject': fields[6].decode(),
+ 'patchname': fields[7].decode(),
+ 'body': fields[8].decode(),
+ 'files': files}
#{ Patches
def format_patches(self, start, end, output_dir,
@@ -1803,7 +1819,7 @@ class GitRepository(object):
@param ignore_submodules: ignore changes to submodules
@type ignore_submodules: C{bool}
@return: diff
- @rtype: C{str}
+ @rtype: C{binary}
"""
options = GitArgs('-p', '--no-ext-diff')
if stat is True:
@@ -1836,11 +1852,11 @@ class GitRepository(object):
options = GitArgs('--name-status', '-z', obj1, obj2)
output, stderr, ret = self._git_inout('diff', options.args)
- elements = output.split('\x00')
+ elements = output.split(b'\x00')
result = defaultdict(list)
- while elements[0] != '':
- status = elements.pop(0)[0]
+ while elements[0] != b'':
+ status = elements.pop(0).decode()[0]
filepath = elements.pop(0)
# Expect to have two filenames for renames and copies
if status in ['R', 'C']:
@@ -1879,8 +1895,7 @@ class GitRepository(object):
if output:
out, err, ret = self._git_inout('archive', args.args)
if ret:
- raise GitRepositoryError("Unable to archive %s: %s" % (treeish,
- err))
+ raise GitRepositoryError("Unable to archive %s: %s" % (treeish, err.decode().strip()))
else:
return self._git_inout2('archive', args.args)
@@ -1969,13 +1984,16 @@ class GitRepository(object):
args += ['-r']
out, ret = self._git_getoutput('ls-tree', args, cwd=path)
- for line in out:
- mode, objtype, commit, name = line[:-1].split(None, 3)
+ for line in out.split(b'\n'):
+ if not line:
+ continue
+ mode, objtype, commit, name = line.decode().split(None, 3)
+
# A submodules is shown as "commit" object in ls-tree:
if objtype == "commit":
nextpath = os.path.join(path, name)
- submodules.append( (nextpath.replace(self.path,'').lstrip('/'),
- commit) )
+ submodules.append((nextpath.replace(self.path, '').lstrip('/'),
+ commit))
if recursive:
submodules += self.get_submodules(commit, path=nextpath,
recursive=recursive)
@@ -2004,7 +2022,7 @@ class GitRepository(object):
try:
if not os.path.exists(abspath):
os.makedirs(abspath)
- stderr = ''
+ stderr = b''
try:
for out in klass.__git_inout(command='init',
args=args.args,
@@ -2015,7 +2033,7 @@ class GitRepository(object):
capture_stdout=True):
stderr += out[1]
except GitRepositoryError:
- raise GitRepositoryError("Error running git init: %s" % stderr)
+ raise GitRepositoryError("Error running git init: %s" % stderr.decode().strip())
except Exception as excobj:
raise GitRepositoryError("Error running git init: %s" % excobj)
if description:
@@ -2025,7 +2043,7 @@ class GitRepository(object):
return klass(abspath)
except OSError as err:
raise GitRepositoryError("Cannot create Git repository at '%s': %s"
- % (abspath, err[1]))
+ % (abspath, err))
return None
@classmethod
@@ -2068,7 +2086,7 @@ class GitRepository(object):
try:
if not os.path.exists(abspath):
os.makedirs(abspath)
- stderr = ''
+ stderr = b''
try:
for out in klass.__git_inout(command='clone',
args=args.args,
@@ -2079,7 +2097,7 @@ class GitRepository(object):
capture_stdout=True):
stderr += out[1]
except GitRepositoryError:
- raise GitRepositoryError("Error running git clone: %s" % stderr)
+ raise GitRepositoryError("Error running git clone: %s" % stderr.decode())
except Exception as excobj:
raise GitRepositoryError("Error running git clone: %s" % excobj)
diff --git a/gbp/patch_series.py b/gbp/patch_series.py
index f608f200..caebfbfe 100644
--- a/gbp/patch_series.py
+++ b/gbp/patch_series.py
@@ -49,7 +49,7 @@ class Patch(object):
repr = "<gbp.patch_series.Patch path='%s' " % self.path
if self.topic:
repr += "topic='%s' " % self.topic
- if self.strip != None:
+ if self.strip is not None:
repr += "strip=%d " % self.strip
repr += ">"
return repr
@@ -62,22 +62,23 @@ class Patch(object):
"""
self.info = {}
body = tempfile.NamedTemporaryFile(prefix='gbp_')
- pipe = subprocess.Popen("git mailinfo '%s' /dev/null 2>/dev/null < '%s'" %
+ pipe = subprocess.Popen("git mailinfo -k '%s' /dev/null 2>/dev/null < '%s'" %
(body.name, self.path),
shell=True,
stdout=subprocess.PIPE).stdout
for line in pipe:
+ line = line.decode()
if ':' in line:
rfc_header, value = line.split(" ", 1)
header = rfc_header[:-1].lower()
self.info[header] = value.strip()
try:
- self.long_desc = body.read()
- body.close()
- except IOError as msg:
+ self.long_desc = "".join([l.decode("utf-8", "backslashreplace") for l in body])
+ except (IOError, UnicodeDecodeError) as msg:
raise GbpError("Failed to read patch header of '%s': %s" %
- (self.patch, msg))
+ (self.path, msg))
finally:
+ body.close()
if os.path.exists(body.name):
os.unlink(body.name)
@@ -112,7 +113,7 @@ class Patch(object):
if ext in self.patch_exts:
subject = base
except ValueError:
- pass # No ext so keep subject as is
+ pass # No ext so keep subject as is
return subject.lstrip('0123456789-') or subject
def _get_info_field(self, key, get_val=None):
@@ -125,9 +126,9 @@ class Patch(object):
@param key: key to fetch
@type key: C{str}
@param get_val: alternate value if key is not in info dict
- @type get_val: C{str}
+ @type get_val: C{()->str}
"""
- if self.info == None:
+ if self.info is None:
self._read_info()
if key in self.info:
@@ -205,11 +206,11 @@ class PatchSeries(list):
queue = PatchSeries()
for line in series:
try:
- if line[0] in [ '\n', '#' ]:
+ if line[0] in ['\n', '#']:
continue
except IndexError:
- continue # ignore empty lines
- queue.append(klass._parse_line(line, patch_dir))
+ continue # ignore empty lines
+ queue.append(cls._parse_line(line, patch_dir))
return queue
@staticmethod
@@ -223,7 +224,7 @@ class PatchSeries(list):
>>> PatchSeries._get_topic("/asdf")
"""
topic = os.path.dirname(line)
- if topic in [ '', '/' ]:
+ if topic in ['', '/']:
topic = None
return topic
diff --git a/gbp/paths.py b/gbp/paths.py
new file mode 100755
index 00000000..1cb7bcca
--- /dev/null
+++ b/gbp/paths.py
@@ -0,0 +1,26 @@
+# vim: set fileencoding=utf-8 :
+#
+# (C) 2017 Guido Günther <agx@sigxcpu.org>
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, please see
+# <http://www.gnu.org/licenses/>
+"Helpers to handle paths"
+
+
+def to_bin(path):
+ """Convert to binary if not already
+
+ We want paths to be binary since we can't assume an encoding but
+ it shall still be convenient to pass in unicode strings
+ """
+ return path.encode() if not isinstance(path, bytes) else path
diff --git a/gbp/rpm/__init__.py b/gbp/rpm/__init__.py
index 0a376e18..62f0c279 100644
--- a/gbp/rpm/__init__.py
+++ b/gbp/rpm/__init__.py
@@ -38,6 +38,11 @@ from gbp.rpm.linkedlist import LinkedList
from gbp.rpm.lib_rpm import librpm, get_librpm_log
+def _decode(s):
+ if s is not None:
+ return s.decode()
+
+
class NoSpecError(Exception):
"""Spec file parsing error"""
pass
@@ -72,8 +77,8 @@ class SrcRpmFile(object):
@property
def version(self):
"""Get the (downstream) version of the RPM package"""
- version = dict(upstreamversion = self.rpmhdr[librpm.RPMTAG_VERSION],
- release = self.rpmhdr[librpm.RPMTAG_RELEASE])
+ version = dict(upstreamversion=self.rpmhdr[librpm.RPMTAG_VERSION].decode(),
+ release=self.rpmhdr[librpm.RPMTAG_RELEASE].decode())
if self.rpmhdr[librpm.RPMTAG_EPOCH] is not None:
version['epoch'] = str(self.rpmhdr[librpm.RPMTAG_EPOCH])
return version
@@ -81,17 +86,17 @@ class SrcRpmFile(object):
@property
def name(self):
"""Get the name of the RPM package"""
- return self.rpmhdr[librpm.RPMTAG_NAME]
+ return self.rpmhdr[librpm.RPMTAG_NAME].decode()
@property
def upstreamversion(self):
"""Get the upstream version of the RPM package"""
- return self.rpmhdr[librpm.RPMTAG_VERSION]
+ return self.rpmhdr[librpm.RPMTAG_VERSION].decode()
@property
def packager(self):
"""Get the packager of the RPM package"""
- return self.rpmhdr[librpm.RPMTAG_PACKAGER]
+ return _decode(self.rpmhdr[librpm.RPMTAG_PACKAGER])
def unpack(self, dest_dir):
"""
@@ -159,13 +164,13 @@ class SpecFile(object):
# Other initializations
source_header = self._specinfo.packages[0].header
- self.name = source_header[librpm.RPMTAG_NAME]
- self.upstreamversion = source_header[librpm.RPMTAG_VERSION]
- self.release = source_header[librpm.RPMTAG_RELEASE]
+ self.name = source_header[librpm.RPMTAG_NAME].decode()
+ self.upstreamversion = source_header[librpm.RPMTAG_VERSION].decode()
+ self.release = source_header[librpm.RPMTAG_RELEASE].decode()
# rpm-python returns epoch as 'long', convert that to string
self.epoch = str(source_header[librpm.RPMTAG_EPOCH]) \
- if source_header[librpm.RPMTAG_EPOCH] != None else None
- self.packager = source_header[librpm.RPMTAG_PACKAGER]
+ if source_header[librpm.RPMTAG_EPOCH] is not None else None
+ self.packager = _decode(source_header[librpm.RPMTAG_PACKAGER])
self._tags = {}
self._special_directives = defaultdict(list)
self._gbp_tags = defaultdict(list)
@@ -184,7 +189,7 @@ class SpecFile(object):
def _parse_filtered_spec(self, skip_tags):
"""Parse a filtered spec file in rpm-python"""
skip_tags = [tag.lower() for tag in skip_tags]
- with tempfile.NamedTemporaryFile(prefix='gbp') as filtered:
+ with tempfile.NamedTemporaryFile(prefix='gbp', mode='w+') as filtered:
filtered.writelines(str(line) for line in self._content
if str(line).split(":")[0].strip().lower() not in skip_tags)
filtered.flush()
@@ -303,7 +308,7 @@ class SpecFile(object):
tagvalue = None
# We don't support "multivalue" tags like "Provides:" or "SourceX:"
# Rpm python doesn't support many of these, thus the explicit list
- if type(tagvalue) is int or type(tagvalue) is int:
+ if isinstance(tagvalue, int):
tagvalue = str(tagvalue)
elif type(tagvalue) is list or tagname in self._listtags:
tagvalue = None
@@ -853,11 +858,11 @@ def guess_spec_repo(repo, treeish, topdir='', recursive=True, preferred_name=Non
"""
topdir = topdir.rstrip('/') + ('/') if topdir else ''
try:
- file_list = [nam for (mod, typ, sha, nam) in
- repo.list_tree(treeish, recursive, topdir) if typ == 'blob']
+ file_list = [nam.decode() for (mod, typ, sha, nam) in
+ repo.list_tree(treeish, recursive, topdir) if typ == 'blob']
except GitRepositoryError as err:
raise NoSpecError("Cannot find spec file from treeish %s, Git error: %s"
- % (treeish, err))
+ % (treeish, err))
spec_path = guess_spec_fn(file_list, preferred_name)
return spec_from_repo(repo, treeish, spec_path)
@@ -865,7 +870,7 @@ def guess_spec_repo(repo, treeish, topdir='', recursive=True, preferred_name=Non
def spec_from_repo(repo, treeish, spec_path):
"""Get and parse a spec file from a give Git treeish"""
try:
- spec = SpecFile(filedata=repo.show('%s:%s' % (treeish, spec_path)))
+ spec = SpecFile(filedata=repo.show('%s:%s' % (treeish, spec_path)).decode())
spec.specdir = os.path.dirname(spec_path)
spec.specfile = os.path.basename(spec_path)
return spec
diff --git a/gbp/rpm/linkedlist.py b/gbp/rpm/linkedlist.py
index 4d223422..c622f603 100644
--- a/gbp/rpm/linkedlist.py
+++ b/gbp/rpm/linkedlist.py
@@ -193,7 +193,7 @@ class LinkedList(collections.abc.Iterable):
'foo'
>>> [str(data) for data in list]
['foo', 'bar']
- >>> print "%s" % node3
+ >>> print("%s" % node3)
<BLANKLINE>
>>> str(list.delete(node1))
'bar'
diff --git a/gbp/scripts/common/buildpackage.py b/gbp/scripts/common/buildpackage.py
index a2122866..12eede9e 100644
--- a/gbp/scripts/common/buildpackage.py
+++ b/gbp/scripts/common/buildpackage.py
@@ -150,8 +150,9 @@ def dump_tree(repo, export_dir, treeish, with_submodules, recursive=True):
if recursive:
paths = ''
else:
- paths = [nam for _mod, typ, _sha, nam in repo.list_tree(treeish) if
- typ == 'blob']
+ paths = ["'%s'" % nam.decode() for _mod, typ, _sha, nam in
+ repo.list_tree(treeish) if typ == 'blob']
+
try:
data = repo.archive('tar', '', None, treeish, paths)
untar_data(export_dir, data)
diff --git a/gbp/scripts/common/import_orig.py b/gbp/scripts/common/import_orig.py
index 30df6101..55516689 100644
--- a/gbp/scripts/common/import_orig.py
+++ b/gbp/scripts/common/import_orig.py
@@ -26,7 +26,7 @@ import gbp.log
# Try to import readline, since that will cause raw_input to get fancy
# line editing and history capabilities. However, if readline is not
-# available, raw_input will still work.
+# available, input() will still work.
try:
import readline
except ImportError:
@@ -48,7 +48,7 @@ def ask_package_name(default, name_validator_func, err_msg):
"""
while True:
sourcepackage = input("What will be the source package name? [%s] " % default)
- if not sourcepackage: # No input, use the default.
+ if not sourcepackage: # No input, use the default.
sourcepackage = default
# Valid package name, return it.
if name_validator_func(sourcepackage):
@@ -67,7 +67,7 @@ def ask_package_version(default, ver_validator_func, err_msg):
"""
while True:
version = input("What is the upstream version? [%s] " % default)
- if not version: # No input, use the default.
+ if not version: # No input, use the default.
version = default
# Valid version, return it.
if ver_validator_func(version):
diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py
index 60157b2f..0ea9f9e8 100644
--- a/gbp/scripts/common/pq.py
+++ b/gbp/scripts/common/pq.py
@@ -151,7 +151,7 @@ def pq_branch_base(pq_branch, options):
def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds):
"""Parse gbp commands from commit message"""
cmd_re = re.compile(r'^%s:\s*(?P<cmd>[a-z-]+)(\s+(?P<args>\S.*))?' %
- cmd_tag, flags=re.I)
+ cmd_tag, flags=re.I)
commands = {}
other_lines = []
for line in info['body'].splitlines():
@@ -168,7 +168,7 @@ def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds):
commands[cmd] = match.group('args')
else:
gbp.log.warn("Ignoring unknown gbp-command '%s' in commit %s"
- % (line, info['id']))
+ % (line, info['id']))
else:
other_lines.append(line)
return commands, other_lines
@@ -196,7 +196,7 @@ def write_patch_file(filename, commit_info, diff):
gbp.log.debug("I won't generate empty diff %s" % filename)
return None
try:
- with open(filename, 'w') as patch:
+ with open(filename, 'wb') as patch:
msg = Message()
charset = Charset('utf-8')
charset.body_encoding = None
@@ -208,13 +208,13 @@ def write_patch_file(filename, commit_info, diff):
# Git compat: put name in quotes if special characters found
if re.search("[,.@()\[\]\\\:;]", name):
name = '"%s"' % name
- from_header = Header(str(name, 'utf-8'), charset, 77, 'from')
- from_header.append(str('<%s>' % email))
+ from_header = Header(name.encode('utf-8'), charset, 77, 'from')
+ from_header.append(email.encode('utf-8'))
msg['From'] = from_header
date = commit_info['author'].datetime
datestr = date.strftime('%a, %-d %b %Y %H:%M:%S %z')
- msg['Date'] = Header(str(datestr, 'utf-8'), charset, 77, 'date')
- msg['Subject'] = Header(str(commit_info['subject'], 'utf-8'),
+ msg['Date'] = Header(datestr.encode('utf-8'), charset, 77, 'date')
+ msg['Subject'] = Header(commit_info['subject'].encode('utf-8'),
charset, 77, 'subject')
# Write message body
if commit_info['body']:
@@ -224,11 +224,11 @@ def write_patch_file(filename, commit_info, diff):
msg.set_payload(body.encode('ascii'))
except UnicodeDecodeError:
msg.set_payload(body, charset)
- patch.write(msg.as_string(unixfrom=False))
+ patch.write(msg.as_string(unixfrom=False).encode('utf-8'))
# Write diff
- patch.write('---\n')
- patch.write(diff)
+ patch.write(b'---\n')
+ patch.write(diff.encode())
except IOError as err:
raise GbpError('Unable to create patch file: %s' % err)
return filename
@@ -278,7 +278,7 @@ def format_diff(outdir, filename, repo, start, end, path_exclude_regex=None):
info['subject'] = "Raw diff %s..%s" % (start, end)
info['body'] = ("Raw diff between %s '%s' and\n%s '%s'\n" %
(repo.get_obj_type(start), start,
- repo.get_obj_type(end), end))
+ repo.get_obj_type(end), end))
if not filename:
filename = '%s-to-%s.diff' % (start, end)
filename = os.path.join(outdir, filename)
@@ -323,7 +323,7 @@ def get_maintainer_from_control(repo):
stdout=subprocess.PIPE).stdout.readlines()
if len(cmdout) > 0:
- maintainer = cmdout[0].strip()
+ maintainer = cmdout[0].decode().strip()
m = re.match('(?P<name>.*[^ ]) *<(?P<email>.*)>', maintainer)
if m:
return GitModifier(m.group('name'), m.group('email'))
@@ -361,7 +361,7 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None):
"""apply a single patch 'patch', add topic 'topic' and commit it"""
author = {'name': patch.author,
'email': patch.email,
- 'date': patch.date }
+ 'date': patch.date}
patch_fn = os.path.basename(patch.path)
if not (author['name'] and author['email']):
diff --git a/gbp/scripts/import_dscs.py b/gbp/scripts/import_dscs.py
index c37cea80..7ed5e70f 100644
--- a/gbp/scripts/import_dscs.py
+++ b/gbp/scripts/import_dscs.py
@@ -1,6 +1,6 @@
# vim: set fileencoding=utf-8 :
#
-# (C) 2008, 2009, 2010 Guido Guenther <agx@sigxcpu.org>
+# (C) 2008, 2009, 2010, 2017 Guido Günther <agx@sigxcpu.org>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@@ -12,9 +12,9 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""Import multiple dsc files into GIT in one go"""
+# along with this program; if not, please see
+# <http://www.gnu.org/licenses/>
+"""Import multiple dsc files into Git in one go"""
import glob
import os
@@ -37,6 +37,32 @@ class DscCompareVersions(DpkgCompareVersions):
return DpkgCompareVersions.__call__(self, dsc1.version, dsc2.version)
+def cmp_to_key(mycmp):
+ 'Convert a cmp= function into a key= function'
+ class K(object):
+ def __init__(self, obj, *args):
+ self.obj = obj
+
+ def __lt__(self, other):
+ return mycmp(self.obj, other.obj) < 0
+
+ def __gt__(self, other):
+ return mycmp(self.obj, other.obj) > 0
+
+ def __eq__(self, other):
+ return mycmp(self.obj, other.obj) == 0
+
+ def __le__(self, other):
+ return mycmp(self.obj, other.obj) <= 0
+
+ def __ge__(self, other):
+ return mycmp(self.obj, other.obj) >= 0
+
+ def __ne__(self, other):
+ return mycmp(self.obj, other.obj) != 0
+ return K
+
+
class GitImportDsc(object):
def __init__(self, args):
self.args = args
@@ -46,7 +72,7 @@ class GitImportDsc(object):
def fetch_snapshots(pkg, downloaddir):
- "Fetch snapshots using debsnap von snapshots.debian.org"
+ "Fetch snapshots using debsnap from snapshots.debian.org"
dscs = None
gbp.log.info("Downloading snapshots of '%s' to '%s'..." %
@@ -93,7 +119,7 @@ def main(argv):
dscs = []
ret = 0
verbose = False
- dsc_cmp = DscCompareVersions()
+ dsc_key = cmp_to_key(DscCompareVersions())
use_debsnap = False
try:
@@ -128,9 +154,9 @@ def main(argv):
if use_debsnap:
dirs['tmp'] = os.path.abspath(tempfile.mkdtemp())
- dscs = [ DscFile.parse(f) for f in fetch_snapshots(pkg, dirs['tmp']) ]
+ dscs = [DscFile.parse(f) for f in fetch_snapshots(pkg, dirs['tmp'])]
- dscs.sort(cmp=dsc_cmp)
+ dscs.sort(key=dsc_key)
importer = GitImportDsc(import_args)
try:
diff --git a/gbp/scripts/import_srpm.py b/gbp/scripts/import_srpm.py
index 0712288e..88ca4819 100755
--- a/gbp/scripts/import_srpm.py
+++ b/gbp/scripts/import_srpm.py
@@ -81,7 +81,7 @@ def download_file(target_dir, url):
def download_source(pkg, dirs):
"""Download package from a remote location"""
if re.match(r'[a-z]{1,5}://', pkg):
- mode = 'python urllib2'
+ mode = 'python urllib'
else:
mode = 'yumdownloader'
diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py
index 029e7182..4430d5fa 100755
--- a/gbp/scripts/pq.py
+++ b/gbp/scripts/pq.py
@@ -167,9 +167,9 @@ def export_patches(repo, branch, options):
pq_branch = pq_branch_name(branch, options)
try:
shutil.rmtree(PATCH_DIR)
- except OSError as msg:
- if msg.errno != errno.ENOENT:
- raise GbpError("Failed to remove patch dir: %s" % msg)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise GbpError("Failed to remove patch dir: %s" % e.strerror)
else:
gbp.log.debug("%s does not exist." % PATCH_DIR)
diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py
index 011c4165..92954eec 100755
--- a/gbp/scripts/pq_rpm.py
+++ b/gbp/scripts/pq_rpm.py
@@ -292,8 +292,8 @@ def safe_patches(queue, tmpdir_base):
safequeue = PatchSeries()
if len(queue) > 0:
- gbp.log.debug("Safeing patches '%s' in '%s'" %
- (os.path.dirname(queue[0].path), tmpdir))
+ gbp.log.debug("Saving patches '%s' in '%s'" %
+ (os.path.dirname(queue[0].path), tmpdir))
for patch in queue:
base, _archive_fmt, comp = parse_archive_filename(patch.path)
uncompressors = {'gzip': gzip.open, 'bzip2': bz2.BZ2File}
@@ -308,11 +308,11 @@ def safe_patches(queue, tmpdir_base):
raise GbpError("Unsupported patch compression '%s', giving up"
% comp)
else:
- src = open(patch.path, 'r')
+ src = open(patch.path, 'rb')
dst_name = os.path.join(tmpdir, os.path.basename(patch.path))
- dst = open(dst_name, 'w')
- dst.writelines(src)
+ dst = open(dst_name, 'wb')
+ dst.write(src.read())
src.close()
dst.close()
if _archive_fmt:
diff --git a/gbp/scripts/rpm_ch.py b/gbp/scripts/rpm_ch.py
index e5fddb4e..b2a836aa 100755
--- a/gbp/scripts/rpm_ch.py
+++ b/gbp/scripts/rpm_ch.py
@@ -92,7 +92,8 @@ def load_customizations(customization_file):
return
customizations = {}
try:
- exec(compile(open(customization_file, "rb").read(), customization_file, 'exec'), customizations, customizations)
+ with open(customization_file) as f:
+ exec(f.read(), customizations, customizations)
except Exception as err:
raise GbpError("Failed to load customization file: %s" % err)
diff --git a/gbp/scripts/supercommand.py b/gbp/scripts/supercommand.py
index 7a91625b..7e35877a 100644
--- a/gbp/scripts/supercommand.py
+++ b/gbp/scripts/supercommand.py
@@ -53,7 +53,7 @@ def version(prog):
from gbp.version import gbp_version
except ImportError:
gbp_version = '[Unknown version]'
- print(("%s %s" % (os.path.basename(prog), gbp_version)))
+ print("%s %s" % (os.path.basename(prog), gbp_version))
def import_command(cmd):
@@ -62,7 +62,7 @@ def import_command(cmd):
"""
modulename = sanitize(cmd)
if (not re.match(r'[a-z][a-z0-9_]', modulename) or
- modulename in invalid_modules):
+ modulename in invalid_modules):
raise ImportError('Illegal module name %s' % modulename)
return __import__('gbp.scripts.%s' % modulename, fromlist='main', level=0)
@@ -90,7 +90,7 @@ def list_available_commands():
path = os.path.dirname(mod.__file__)
maxlen = 0
- print(("Available commands in %s\n" % path))
+ print("Available commands in %s\n" % path)
cmds = sorted(get_available_commands(path))
for cmd in cmds:
if len(cmd[0]) > maxlen:
@@ -98,7 +98,7 @@ def list_available_commands():
for cmd in cmds:
mod = import_command(cmd[0])
doc = mod.__doc__
- print((" %s - %s" % (cmd[0].rjust(maxlen), doc)))
+ print(" %s - %s" % (cmd[0].rjust(maxlen), doc))
print('')