Toggle diff (444 lines)
diff --git a/gnu/local.mk b/gnu/local.mk
index 5091f93eb8..ac29c00c79 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1052,7 +1052,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 \
diff --git a/gnu/packages/patches/breezy-fix-gio.patch b/gnu/packages/patches/breezy-fix-gio.patch
deleted file mode 100644
index f70e761555..0000000000
--- a/gnu/packages/patches/breezy-fix-gio.patch
+++ /dev/null
@@ -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)
-
diff --git a/gnu/packages/version-control.scm b/gnu/packages/version-control.scm
index 2a95bc79e1..a40de4c812 100644
--- a/gnu/packages/version-control.scm
+++ b/gnu/packages/version-control.scm
@@ -60,6 +60,7 @@
;;; Copyright © 2024 Ashish SHUKLA <ashish.is@lostca.se>
;;; Copyright © 2024 Wilko Meyer <w@wmeyer.eu>
;;; Copyright © 2025 Artyom V. Poptsov <poptsov.artyom@gmail.com>
+;;; Copyright © 2025 Dariqq <dariqq@posteo.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -180,7 +181,7 @@ (define-module (gnu packages version-control)
(define-public breezy
(package
(name "breezy")
- (version "3.2.2")
+ (version "3.3.9")
(source
(origin
(method url-fetch)
@@ -192,51 +193,106 @@ (define-public breezy
(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
- ;; by