mirror of
git://git.savannah.gnu.org/guix.git
synced 2023-12-14 03:33:07 +01:00
gnu: breezy: Update to 3.2.2.
* gnu/packages/patches/breezy-fix-gio.patch: New file. * gnu/local.mk (dist_patch_DATA): Register it. * gnu/packages/version-control.scm (breezy): Update to 3.2.2. [source]{snippet}: Delete pre-generated cythonized C files. {patches}: Apply patch. [tests?]: Disable tests. [phases]{patch-test-shebangs, check}: New phase and override. [native-inputs]: Add nano, python-cython, python-docutils, and python-testrepository. [inputs]: Use new style. Add python-launchpadlib and python-pygobject. [description]: Adjust Bazaar URL.
This commit is contained in:
parent
dad15bdb26
commit
dc71b4f1c6
3 changed files with 388 additions and 15 deletions
|
@ -916,6 +916,7 @@ dist_patch_DATA = \
|
|||
%D%/packages/patches/bloomberg-bde-cmake-module-path.patch \
|
||||
%D%/packages/patches/bloomberg-bde-tools-fix-install-path.patch \
|
||||
%D%/packages/patches/bpftrace-disable-bfd-disasm.patch \
|
||||
%D%/packages/patches/breezy-fix-gio.patch \
|
||||
%D%/packages/patches/byobu-writable-status.patch \
|
||||
%D%/packages/patches/bubblewrap-fix-locale-in-tests.patch \
|
||||
%D%/packages/patches/cabal-install-base16-bytestring1.0.patch \
|
||||
|
|
338
gnu/packages/patches/breezy-fix-gio.patch
Normal file
338
gnu/packages/patches/breezy-fix-gio.patch
Normal file
|
@ -0,0 +1,338 @@
|
|||
This patch combines https://code.launchpad.net/~jelmer/brz/enable-gio/+merge/419150
|
||||
and https://bazaar.launchpad.net/~jelmer/brz/fix-gio/revision/7570.
|
||||
|
||||
=== modified file 'breezy/transport/gio_transport.py'
|
||||
--- a/breezy/transport/gio_transport.py 2022-04-09 12:17:41 +0000
|
||||
+++ b/breezy/transport/gio_transport.py 2022-04-09 12:33:51 +0000
|
||||
@@ -52,11 +52,7 @@
|
||||
from ..tests.test_server import TestServer
|
||||
|
||||
try:
|
||||
- import glib
|
||||
-except ImportError as e:
|
||||
- raise errors.DependencyNotPresent('glib', e)
|
||||
-try:
|
||||
- import gio
|
||||
+ from gi.repository import Gio as gio
|
||||
except ImportError as e:
|
||||
raise errors.DependencyNotPresent('gio', e)
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@
|
||||
raise errors.DependencyNotPresent('gio', e)
|
||||
|
||||
|
||||
+from gi.repository.GLib import GError
|
||||
+
|
||||
+
|
||||
class GioLocalURLServer(TestServer):
|
||||
"""A pretend server for local transports, using file:// urls.
|
||||
|
||||
@@ -81,7 +84,7 @@
|
||||
def __init__(self, transport, relpath):
|
||||
FileStream.__init__(self, transport, relpath)
|
||||
self.gio_file = transport._get_GIO(relpath)
|
||||
- self.stream = self.gio_file.create()
|
||||
+ self.stream = self.gio_file.create(0, None)
|
||||
|
||||
def _close(self):
|
||||
self.stream.close()
|
||||
@@ -90,7 +93,7 @@
|
||||
try:
|
||||
# Using pump_string_file seems to make things crash
|
||||
osutils.pumpfile(BytesIO(bytes), self.stream)
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
# self.transport._translate_gio_error(e,self.relpath)
|
||||
raise errors.BzrError(str(e))
|
||||
|
||||
@@ -98,12 +101,12 @@
|
||||
class GioStatResult(object):
|
||||
|
||||
def __init__(self, f):
|
||||
- info = f.query_info('standard::size,standard::type')
|
||||
+ info = f.query_info('standard::size,standard::type', 0, None)
|
||||
self.st_size = info.get_size()
|
||||
type = info.get_file_type()
|
||||
- if (type == gio.FILE_TYPE_REGULAR):
|
||||
+ if type == gio.FileType.REGULAR:
|
||||
self.st_mode = stat.S_IFREG
|
||||
- elif type == gio.FILE_TYPE_DIRECTORY:
|
||||
+ elif type == gio.FileType.DIRECTORY:
|
||||
self.st_mode = stat.S_IFDIR
|
||||
|
||||
|
||||
@@ -122,7 +125,7 @@
|
||||
user, netloc = netloc.rsplit('@', 1)
|
||||
# Seems it is not possible to list supported backends for GIO
|
||||
# so a hardcoded list it is then.
|
||||
- gio_backends = ['dav', 'file', 'ftp', 'obex', 'sftp', 'ssh', 'smb']
|
||||
+ gio_backends = ['dav', 'file', 'ftp', 'obex', 'sftp', 'ssh', 'smb', 'http']
|
||||
if scheme not in gio_backends:
|
||||
raise urlutils.InvalidURL(base,
|
||||
extra="GIO support is only available for " +
|
||||
@@ -138,13 +141,10 @@
|
||||
_from_transport=_from_transport)
|
||||
|
||||
def _relpath_to_url(self, relpath):
|
||||
- full_url = urlutils.join(self.url, relpath)
|
||||
- if isinstance(full_url, str):
|
||||
- raise urlutils.InvalidURL(full_url)
|
||||
- return full_url
|
||||
+ return urlutils.join(self.url, relpath)
|
||||
|
||||
def _get_GIO(self, relpath):
|
||||
- """Return the ftplib.GIO instance for this object."""
|
||||
+ """Return the GIO instance for this object."""
|
||||
# Ensures that a connection is established
|
||||
connection = self._get_connection()
|
||||
if connection is None:
|
||||
@@ -152,7 +152,7 @@
|
||||
connection, credentials = self._create_connection()
|
||||
self._set_connection(connection, credentials)
|
||||
fileurl = self._relpath_to_url(relpath)
|
||||
- file = gio.File(fileurl)
|
||||
+ file = gio.File.new_for_uri(fileurl)
|
||||
return file
|
||||
|
||||
def _auth_cb(self, op, message, default_user, default_domain, flags):
|
||||
@@ -197,7 +197,7 @@
|
||||
try:
|
||||
obj.mount_enclosing_volume_finish(res)
|
||||
self.loop.quit()
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self.loop.quit()
|
||||
raise errors.BzrError(
|
||||
"Failed to mount the given location: " + str(e))
|
||||
@@ -209,12 +209,12 @@
|
||||
user, password = credentials
|
||||
|
||||
try:
|
||||
- connection = gio.File(self.url)
|
||||
+ connection = gio.File.new_for_uri(self.url)
|
||||
mount = None
|
||||
try:
|
||||
mount = connection.find_enclosing_mount()
|
||||
- except gio.Error as e:
|
||||
- if (e.code == gio.ERROR_NOT_MOUNTED):
|
||||
+ except GError as e:
|
||||
+ if e.code == gio.IOErrorEnum.NOT_MOUNTED:
|
||||
self.loop = glib.MainLoop()
|
||||
ui.ui_factory.show_message('Mounting %s using GIO' %
|
||||
self.url)
|
||||
@@ -227,7 +227,7 @@
|
||||
m = connection.mount_enclosing_volume(op,
|
||||
self._mount_done_cb)
|
||||
self.loop.run()
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
raise errors.TransportError(msg="Error setting up connection:"
|
||||
" %s" % str(e), orig_error=e)
|
||||
return connection, (user, password)
|
||||
@@ -257,8 +257,8 @@
|
||||
if stat.S_ISREG(st.st_mode) or stat.S_ISDIR(st.st_mode):
|
||||
return True
|
||||
return False
|
||||
- except gio.Error as e:
|
||||
- if e.code == gio.ERROR_NOT_FOUND:
|
||||
+ except GError as e:
|
||||
+ if e.code == gio.IOErrorEnum.NOT_FOUND:
|
||||
return False
|
||||
else:
|
||||
self._translate_gio_error(e, relpath)
|
||||
@@ -281,10 +281,10 @@
|
||||
buf = fin.read()
|
||||
fin.close()
|
||||
return BytesIO(buf)
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
# If we get a not mounted here it might mean
|
||||
# that a bad path has been entered (or that mount failed)
|
||||
- if (e.code == gio.ERROR_NOT_MOUNTED):
|
||||
+ if e.code == gio.IOErrorEnum.NOT_MOUNTED:
|
||||
raise errors.PathError(relpath,
|
||||
extra='Failed to get file, make sure the path is correct. '
|
||||
+ str(e))
|
||||
@@ -307,19 +307,19 @@
|
||||
closed = True
|
||||
try:
|
||||
f = self._get_GIO(tmppath)
|
||||
- fout = f.create()
|
||||
+ fout = f.create(0, None)
|
||||
closed = False
|
||||
length = self._pump(fp, fout)
|
||||
fout.close()
|
||||
closed = True
|
||||
self.stat(tmppath)
|
||||
dest = self._get_GIO(relpath)
|
||||
- f.move(dest, flags=gio.FILE_COPY_OVERWRITE)
|
||||
+ f.move(dest, flags=gio.FileCopyFlags.OVERWRITE)
|
||||
f = None
|
||||
if mode is not None:
|
||||
self._setmode(relpath, mode)
|
||||
return length
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relpath)
|
||||
finally:
|
||||
if not closed and fout is not None:
|
||||
@@ -335,7 +335,7 @@
|
||||
f = self._get_GIO(relpath)
|
||||
f.make_directory()
|
||||
self._setmode(relpath, mode)
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relpath)
|
||||
|
||||
def open_write_stream(self, relpath, mode=None):
|
||||
@@ -369,14 +369,11 @@
|
||||
f.delete()
|
||||
else:
|
||||
raise errors.NotADirectory(relpath)
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relpath)
|
||||
except errors.NotADirectory as e:
|
||||
# just pass it forward
|
||||
raise e
|
||||
- except Exception as e:
|
||||
- mutter('failed to rmdir %s: %s' % (relpath, e))
|
||||
- raise errors.PathError(relpath)
|
||||
|
||||
def append_file(self, relpath, file, mode=None):
|
||||
"""Append the text in the file-like object into the final
|
||||
@@ -392,7 +389,7 @@
|
||||
result = 0
|
||||
fo = self._get_GIO(tmppath)
|
||||
fi = self._get_GIO(relpath)
|
||||
- fout = fo.create()
|
||||
+ fout = fo.create(0, None)
|
||||
try:
|
||||
info = GioStatResult(fi)
|
||||
result = info.st_size
|
||||
@@ -400,11 +397,11 @@
|
||||
self._pump(fin, fout)
|
||||
fin.close()
|
||||
# This separate except is to catch and ignore the
|
||||
- # gio.ERROR_NOT_FOUND for the already existing file.
|
||||
+ # gio.IOErrorEnum.NOT_FOUND for the already existing file.
|
||||
# It is valid to open a non-existing file for append.
|
||||
# This is caused by the broken gio append_to...
|
||||
- except gio.Error as e:
|
||||
- if e.code != gio.ERROR_NOT_FOUND:
|
||||
+ except GError as e:
|
||||
+ if e.code != gio.IOErrorEnum.NOT_FOUND:
|
||||
self._translate_gio_error(e, relpath)
|
||||
length = self._pump(file, fout)
|
||||
fout.close()
|
||||
@@ -413,9 +410,11 @@
|
||||
raise errors.BzrError("Failed to append size after "
|
||||
"(%d) is not original (%d) + written (%d) total (%d)" %
|
||||
(info.st_size, result, length, result + length))
|
||||
- fo.move(fi, flags=gio.FILE_COPY_OVERWRITE)
|
||||
+ fo.move(
|
||||
+ fi, flags=gio.FileCopyFlags.OVERWRITE, cancellable=None,
|
||||
+ progress_callback=None)
|
||||
return result
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relpath)
|
||||
|
||||
def _setmode(self, relpath, mode):
|
||||
@@ -429,8 +428,8 @@
|
||||
try:
|
||||
f = self._get_GIO(relpath)
|
||||
f.set_attribute_uint32(gio.FILE_ATTRIBUTE_UNIX_MODE, mode)
|
||||
- except gio.Error as e:
|
||||
- if e.code == gio.ERROR_NOT_SUPPORTED:
|
||||
+ except GError as e:
|
||||
+ if e.code == gio.IOErrorEnum.NOT_SUPPORTED:
|
||||
# Command probably not available on this server
|
||||
mutter("GIO Could not set permissions to %s on %s. %s",
|
||||
oct(mode), self._remote_path(relpath), str(e))
|
||||
@@ -444,8 +443,8 @@
|
||||
mutter("GIO move (rename): %s => %s", rel_from, rel_to)
|
||||
f = self._get_GIO(rel_from)
|
||||
t = self._get_GIO(rel_to)
|
||||
- f.move(t)
|
||||
- except gio.Error as e:
|
||||
+ f.move(t, flags=0, cancellable=None, progress_callback=None)
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, rel_from)
|
||||
|
||||
def move(self, rel_from, rel_to):
|
||||
@@ -455,8 +454,8 @@
|
||||
mutter("GIO move: %s => %s", rel_from, rel_to)
|
||||
f = self._get_GIO(rel_from)
|
||||
t = self._get_GIO(rel_to)
|
||||
- f.move(t, flags=gio.FILE_COPY_OVERWRITE)
|
||||
- except gio.Error as e:
|
||||
+ f.move(t, flags=gio.FileCopyFlags.OVERWRITE)
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relfrom)
|
||||
|
||||
def delete(self, relpath):
|
||||
@@ -466,7 +465,7 @@
|
||||
mutter("GIO delete: %s", relpath)
|
||||
f = self._get_GIO(relpath)
|
||||
f.delete()
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relpath)
|
||||
|
||||
def external_url(self):
|
||||
@@ -489,11 +488,11 @@
|
||||
try:
|
||||
entries = []
|
||||
f = self._get_GIO(relpath)
|
||||
- children = f.enumerate_children(gio.FILE_ATTRIBUTE_STANDARD_NAME)
|
||||
+ children = f.enumerate_children(gio.FILE_ATTRIBUTE_STANDARD_NAME, 0, None)
|
||||
for child in children:
|
||||
entries.append(urlutils.escape(child.get_name()))
|
||||
return entries
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relpath)
|
||||
|
||||
def iter_files_recursive(self):
|
||||
@@ -519,7 +518,7 @@
|
||||
mutter("GIO stat: %s", relpath)
|
||||
f = self._get_GIO(relpath)
|
||||
return GioStatResult(f)
|
||||
- except gio.Error as e:
|
||||
+ except GError as e:
|
||||
self._translate_gio_error(e, relpath, extra='error w/ stat')
|
||||
|
||||
def lock_read(self, relpath):
|
||||
@@ -556,21 +555,21 @@
|
||||
mutter("GIO Error: %s %s" % (str(err), path))
|
||||
if extra is None:
|
||||
extra = str(err)
|
||||
- if err.code == gio.ERROR_NOT_FOUND:
|
||||
+ if err.code == gio.IOErrorEnum.NOT_FOUND:
|
||||
raise errors.NoSuchFile(path, extra=extra)
|
||||
- elif err.code == gio.ERROR_EXISTS:
|
||||
+ elif err.code == gio.IOErrorEnum.EXISTS:
|
||||
raise errors.FileExists(path, extra=extra)
|
||||
- elif err.code == gio.ERROR_NOT_DIRECTORY:
|
||||
+ elif err.code == gio.IOErrorEnum.NOT_DIRECTORY:
|
||||
raise errors.NotADirectory(path, extra=extra)
|
||||
- elif err.code == gio.ERROR_NOT_EMPTY:
|
||||
+ elif err.code == gio.IOErrorEnum.NOT_EMPTY:
|
||||
raise errors.DirectoryNotEmpty(path, extra=extra)
|
||||
- elif err.code == gio.ERROR_BUSY:
|
||||
+ elif err.code == gio.IOErrorEnum.BUSY:
|
||||
raise errors.ResourceBusy(path, extra=extra)
|
||||
- elif err.code == gio.ERROR_PERMISSION_DENIED:
|
||||
+ elif err.code == gio.IOErrorEnum.PERMISSION_DENIED:
|
||||
raise errors.PermissionDenied(path, extra=extra)
|
||||
- elif err.code == gio.ERROR_HOST_NOT_FOUND:
|
||||
+ elif err.code == gio.IOErrorEnum.HOST_NOT_FOUND:
|
||||
raise errors.PathError(path, extra=extra)
|
||||
- elif err.code == gio.ERROR_IS_DIRECTORY:
|
||||
+ elif err.code == gio.IOErrorEnum.IS_DIRECTORY:
|
||||
raise errors.PathError(path, extra=extra)
|
||||
else:
|
||||
mutter('unable to understand error for path: %s: %s', path, err)
|
||||
|
|
@ -187,29 +187,63 @@ as well as the classic centralized workflow.")
|
|||
(uri (string-append "https://launchpad.net/brz/"
|
||||
(version-major+minor version) "/" version
|
||||
"/+download/breezy-" version ".tar.gz"))
|
||||
(modules '((guix build utils)))
|
||||
;; Delete pre-generated Cython C files.
|
||||
(snippet '(for-each delete-file (find-files "." "\\pyx.c$")))
|
||||
(sha256
|
||||
(base32 "1md4b6ajawf5h50fqizmjj0g833ihc674dh7fn0mvl4d412nwyhq"))))
|
||||
(base32
|
||||
"1md4b6ajawf5h50fqizmjj0g833ihc674dh7fn0mvl4d412nwyhq"))
|
||||
(patches (search-patches "breezy-fix-gio.patch"))))
|
||||
(build-system python-build-system)
|
||||
;; TODO: Maybe regenerate C files with Cython?
|
||||
(inputs
|
||||
`(("gettext" ,gettext-minimal)
|
||||
("python-configobj" ,python-configobj)
|
||||
("python-dulwich" ,python-dulwich)
|
||||
("python-fastbencode" ,python-fastbencode)
|
||||
("python-fastimport" ,python-fastimport)
|
||||
("python-paramiko" ,python-paramiko)
|
||||
("python-patiencediff" ,python-patiencediff)
|
||||
("python-pycryptodome" ,python-pycryptodome)
|
||||
("python-pygpgme" ,python-pygpgme)))
|
||||
(arguments
|
||||
`(#:tests? #f)) ; no tests in release tarball
|
||||
(list
|
||||
#:tests? #f ;FIXME: the test suite hangs
|
||||
#:phases
|
||||
#~(modify-phases %standard-phases
|
||||
(add-after 'unpack 'patch-test-shebangs
|
||||
(lambda _
|
||||
(substitute* (append (find-files "breezy/bzr/tests")
|
||||
(find-files "breezy/tests"))
|
||||
(("#!/bin/sh")
|
||||
(format #f "#!~a" (which "sh"))))))
|
||||
(replace 'check
|
||||
(lambda* (#:key tests? #:allow-other-keys)
|
||||
(when tests?
|
||||
;; The test_read_bundle tests fails with "TypeError: a
|
||||
;; bytes-like object is required, not '_ResultTuple'" (see:
|
||||
;; https://bugs.launchpad.net/brz/+bug/1968415/comments/4).
|
||||
(substitute* "breezy/bzr/tests/__init__.py"
|
||||
(("'test_read_bundle'," all)
|
||||
(string-append "# " all)))
|
||||
(setenv "BZR_EDITOR" "nano")
|
||||
(setenv "HOME" "/tmp")
|
||||
(invoke "testr" "init")
|
||||
(invoke "testr" "run")))))))
|
||||
(native-inputs
|
||||
(list nano ;for tests
|
||||
python-cython
|
||||
python-docutils
|
||||
python-subunit
|
||||
python-testrepository))
|
||||
(inputs
|
||||
(list gettext-minimal
|
||||
python-configobj
|
||||
python-dulwich
|
||||
python-fastbencode
|
||||
python-fastimport
|
||||
python-launchpadlib
|
||||
python-paramiko
|
||||
python-patiencediff
|
||||
python-pycryptodome
|
||||
python-pygobject
|
||||
python-pygpgme))
|
||||
(home-page "https://www.breezy-vcs.org/")
|
||||
(synopsis "Decentralized revision control system")
|
||||
(description
|
||||
"Breezy (@command{brz}) is a decentralized revision control system. By
|
||||
default, Breezy provides support for both the
|
||||
@uref{https://www.bazaar-vcs.org, Bazaar} and @uref{https://www.git-scm.com,
|
||||
Git} file formats. Breezy is backwards compatible with Bazaar's disk format
|
||||
@uref{https://bazaar.canonical.com/, Bazaar} and @uref{https://www.git-scm.com,
|
||||
Git} file formats. Breezy is backwabrds compatible with Bazaar's disk format
|
||||
and protocols. One of the key differences with Bazaar is that Breezy runs on
|
||||
Python 3.3 and later, rather than on Python 2.")
|
||||
(license license:gpl2+)))
|
||||
|
|
Loading…
Reference in a new issue