1
0
mirror of https://git.savannah.gnu.org/git/guix.git synced 2026-04-06 21:20:33 +02:00

gnu: breezy: Update to 3.3.9.

breezy now depends on a rust compiler and crates so we need to switch to
cargo-build-system to set up rust and then readd all the python phases.

* gnu/packages/version-control.scm (breezy): Update to 3.3.9.
[build-system]: switch to cargo-build-system
[#:phases]: Convert back to python-build-system
Add a phase to install the bash-completion file.
Run the testsuite again.

[native-inputs]: Remove python-docutils, python-testrepository
Add gettext-minimal, python-wrapper, python-setuptools, python-setuptools-rust,
python-setuptools-gettext, python-tomli, python wheel.
Add python testtools and python packaging for tests.
[inputs]: Remove gettext-minimal, python-pygobject.
Add python-merge3, python-pygithub, python-pyyaml, python-tzlocal,
python-urllib3
Replace python-pycrptodome and python-pygpgme with python-gpg

* gnu/packages/patches/breezy-fix-gio.patch: Remove patch
* gnu/local.mk : Deregister it.

Change-Id: I69d6c4491442a9ba93a748137fb2ad810a423abd
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Dariqq
2025-01-26 12:27:10 +00:00
committed by Ludovic Courtès
parent eaf538df40
commit 8e5094497c
3 changed files with 89 additions and 372 deletions

View File

@@ -1060,7 +1060,6 @@ dist_patch_DATA = \
%D%/packages/patches/bloomberg-bde-tools-fix-install-path.patch \
%D%/packages/patches/boolector-find-googletest.patch \
%D%/packages/patches/boost-fix-duplicate-definitions-bug.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/busybox-add-missing-sha-NI-guard.patch \

View File

@@ -1,338 +0,0 @@
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)

View File

@@ -63,6 +63,7 @@
;;; Copyright © 2024 Herman Rimm <herman@rimm.ee>
;;; Copyright © 2024 Sharlatan Hellseher <sharlatanus@gmail.com>
;;; Copyright © 2025 Artyom V. Poptsov <poptsov.artyom@gmail.com>
;;; Copyright © 2025 Dariqq <dariqq@posteo.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -184,7 +185,7 @@
(define-public breezy
(package
(name "breezy")
(version "3.2.2")
(version "3.3.9")
(source
(origin
(method url-fetch)
@@ -196,51 +197,106 @@
(snippet '(for-each delete-file (find-files "." "\\pyx.c$")))
(sha256
(base32
"1md4b6ajawf5h50fqizmjj0g833ihc674dh7fn0mvl4d412nwyhq"))
(patches (search-patches "breezy-fix-gio.patch"))))
(build-system python-build-system)
"1n6mqd1iy50537kb4lsr52289yyr1agmkxpchxlhb9682zr8nn62"))))
(build-system cargo-build-system)
(arguments
(list
#:tests? #f ;FIXME: the test suite hangs
#:cargo-inputs (list rust-lazy-static-1
rust-pyo3-0.22
rust-regex-1)
#:install-source? #f
#:modules
'((guix build cargo-build-system)
((guix build python-build-system) #:prefix py:)
(guix build utils))
#:imported-modules
`(,@%cargo-build-system-modules
,@%python-build-system-modules)
#:phases
#~(modify-phases %standard-phases
(add-after 'unpack 'ensure-no-mtimes-pre-1980
(assoc-ref py:%standard-phases 'ensure-no-mtimes-pre-1980))
(add-after 'ensure-no-mtimes-pre-1980 'enable-bytecode-determinism
(assoc-ref py:%standard-phases 'enable-bytecode-determinism))
(add-after 'enable-bytecode-determinism 'ensure-no-cythonized-files
(assoc-ref py:%standard-phases 'ensure-no-cythonized-files))
(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
(add-before 'build 'adjust-for-python-3.10
(lambda _
(substitute* '("breezy/doc_generate/__init__.py"
"breezy/tests/test_selftest.py")
;; AttributeError: module 'datetime' has no attribute 'UTC'
;; This only works for python >= 3.11
(("datetime.UTC") "datetime.timezone.utc"))))
(replace 'build
(assoc-ref py:%standard-phases 'build))
(delete 'check) ;moved after the install phase
(replace 'install
(assoc-ref py:%standard-phases 'install))
(add-after 'install 'add-install-to-pythonpath
(assoc-ref py:%standard-phases 'add-install-to-pythonpath))
(add-after 'add-install-to-pythonpath 'add-install-to-path
(assoc-ref py:%standard-phases 'add-install-to-path))
(add-after 'add-install-to-path 'install-completion
(lambda* (#:key outputs #:allow-other-keys)
(let* ((out (assoc-ref outputs "out"))
(bash (string-append out "/share/bash-completion"
"/completions")))
(install-file "contrib/bash/brz" bash))))
(add-after 'add-install-to-path 'wrap
(assoc-ref py:%standard-phases 'wrap))
(add-after 'wrap '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))
(invoke "brz" "selftest" "--verbose" "--parallel=fork"
;; This test hangs
"-x" "breezy.tests.blackbox.test_serve"
;; No GnuPG key results for pattern: bazaar@example.com
"-x" "breezy.tests.test_gpg"
;; compgen: command not found
"-x" "bash_completion"
;; No such file or directory: '/etc/mtab'
"-x" "breezy.tests.blackbox.test_diff.TestExternalDiff.test_external_diff"
;; Value "/etc/ssl/certs/ca-certificates.crt" is not valid for "ssl.ca_certs"
"-x" "breezy.tests.test_https_urllib.CaCertsConfigTests.test_default_exists"
;; Unknown Failure
"-x" "breezy.tests.test_plugins.TestLoadPluginAt.test_compiled_loaded"
"-x" "breezy.tests.test_plugins.TestPlugins.test_plugin_get_path_pyc_only"
"-x" "breezy.tests.test_selftest.TestActuallyStartBzrSubprocess.test_start_and_stop_bzr_subprocess_send_signal"))))
(add-before 'strip 'rename-pth-file
(assoc-ref py:%standard-phases 'rename-pth-file)))))
(native-inputs (list gettext-minimal
python-wrapper
python-cython
python-setuptools
python-setuptools-gettext
python-setuptools-rust
python-tomli
python-wheel
;; tests
nano
python-testtools
python-packaging
python-subunit))
(inputs (list python-configobj
python-dulwich
python-fastbencode
python-fastimport
python-launchpadlib
python-merge3
python-paramiko
python-gpg
python-patiencediff
python-pygithub
python-pyyaml
python-tzlocal
python-urllib3))
(home-page "https://www.breezy-vcs.org/")
(synopsis "Decentralized revision control system")
(description