Merge lp:~jelmer/brz/join-debian into lp:brz

Proposed by Jelmer Vernooij
Status: Needs review
Proposed branch: lp:~jelmer/brz/join-debian
Merge into: lp:brz
Diff against target: 29488 lines (+28438/-97)
115 files modified
.github/workflows/pythonpackage.yml (+2/-1)
Cargo.lock (+145/-57)
breezy/bugtracker.py (+2/-0)
breezy/commands.py (+2/-2)
breezy/git/bzr_receive_pack.py (+24/-6)
breezy/git/bzr_upload_pack.py (+24/-6)
breezy/git/git_remote_bzr.py (+16/-13)
breezy/merge.py (+2/-2)
breezy/plugins/debian/Dockerfile.deb-auto-backport (+7/-0)
breezy/plugins/debian/Dockerfile.deb-import-uncommitted (+7/-0)
breezy/plugins/debian/Dockerfile.deb-move-orphaned (+7/-0)
breezy/plugins/debian/Dockerfile.deb-new-upstream (+7/-0)
breezy/plugins/debian/Makefile (+46/-0)
breezy/plugins/debian/README.rst (+342/-0)
breezy/plugins/debian/__init__.py (+271/-0)
breezy/plugins/debian/apt_repo.py (+280/-0)
breezy/plugins/debian/builder.py (+142/-0)
breezy/plugins/debian/byov.conf (+21/-0)
breezy/plugins/debian/bzrtools_import.py (+241/-0)
breezy/plugins/debian/changelog.py (+124/-0)
breezy/plugins/debian/cmds.py (+2021/-0)
breezy/plugins/debian/config.py (+406/-0)
breezy/plugins/debian/default.conf (+6/-0)
breezy/plugins/debian/dep3.py (+255/-0)
breezy/plugins/debian/directory.py (+266/-0)
breezy/plugins/debian/doc/user_manual/building.rst (+99/-0)
breezy/plugins/debian/doc/user_manual/configuration.rst (+160/-0)
breezy/plugins/debian/doc/user_manual/hooks.rst (+71/-0)
breezy/plugins/debian/doc/user_manual/html4css1.css (+279/-0)
breezy/plugins/debian/doc/user_manual/index.rst (+74/-0)
breezy/plugins/debian/doc/user_manual/installing.rst (+57/-0)
breezy/plugins/debian/doc/user_manual/license.rst (+41/-0)
breezy/plugins/debian/doc/user_manual/merge.rst (+147/-0)
breezy/plugins/debian/doc/user_manual/mode_selector.rst (+33/-0)
breezy/plugins/debian/doc/user_manual/native.rst (+140/-0)
breezy/plugins/debian/doc/user_manual/normal.rst (+316/-0)
breezy/plugins/debian/doc/user_manual/split.rst (+99/-0)
breezy/plugins/debian/doc/user_manual/upstream_tarballs.rst (+34/-0)
breezy/plugins/debian/doc/user_manual/user_manual.css (+55/-0)
breezy/plugins/debian/errors.py (+28/-0)
breezy/plugins/debian/extract.py (+254/-0)
breezy/plugins/debian/hooks.py (+42/-0)
breezy/plugins/debian/import_dsc.py (+1647/-0)
breezy/plugins/debian/import_uncommitted.py (+666/-0)
breezy/plugins/debian/info.py (+42/-0)
breezy/plugins/debian/launchpad.py (+82/-0)
breezy/plugins/debian/local.conf (+2/-0)
breezy/plugins/debian/merge_changelog.py (+110/-0)
breezy/plugins/debian/merge_package.py (+627/-0)
breezy/plugins/debian/merge_upstream.py (+275/-0)
breezy/plugins/debian/move_orphaned.py (+416/-0)
breezy/plugins/debian/new_upstream.py (+1678/-0)
breezy/plugins/debian/quilt_refresh.py (+100/-0)
breezy/plugins/debian/release.py (+92/-0)
breezy/plugins/debian/repack_tarball.py (+233/-0)
breezy/plugins/debian/revspec.py (+122/-0)
breezy/plugins/debian/scripts/deb-new-upstream (+24/-0)
breezy/plugins/debian/source_distiller.py (+284/-0)
breezy/plugins/debian/specs/build-against-remote (+36/-0)
breezy/plugins/debian/specs/builddeb-setup-command (+52/-0)
breezy/plugins/debian/specs/do-command (+38/-0)
breezy/plugins/debian/specs/hooks (+30/-0)
breezy/plugins/debian/specs/import-dsc (+154/-0)
breezy/plugins/debian/specs/new-upstream-release-handling (+130/-0)
breezy/plugins/debian/specs/svn-support (+27/-0)
breezy/plugins/debian/specs/upstream-patch-handling (+24/-0)
breezy/plugins/debian/specs/upstream-tarball-fetching (+28/-0)
breezy/plugins/debian/tagging.py (+36/-0)
breezy/plugins/debian/tests/__init__.py (+477/-0)
breezy/plugins/debian/tests/blackbox/__init__.py (+37/-0)
breezy/plugins/debian/tests/blackbox/test_builddeb.py (+212/-0)
breezy/plugins/debian/tests/blackbox/test_debrelease.py (+120/-0)
breezy/plugins/debian/tests/blackbox/test_dep3.py (+159/-0)
breezy/plugins/debian/tests/blackbox/test_do.py (+219/-0)
breezy/plugins/debian/tests/blackbox/test_get_tar.py (+122/-0)
breezy/plugins/debian/tests/blackbox/test_import_dsc.py (+140/-0)
breezy/plugins/debian/tests/blackbox/test_import_upstream.py (+171/-0)
breezy/plugins/debian/tests/blackbox/test_merge_package.py (+233/-0)
breezy/plugins/debian/tests/blackbox/test_merge_upstream.py (+340/-0)
breezy/plugins/debian/tests/test_apt_repo.py (+202/-0)
breezy/plugins/debian/tests/test_builder.py (+81/-0)
breezy/plugins/debian/tests/test_bzrtools_import.py (+234/-0)
breezy/plugins/debian/tests/test_commit_message.py (+166/-0)
breezy/plugins/debian/tests/test_config.py (+185/-0)
breezy/plugins/debian/tests/test_dep3.py (+265/-0)
breezy/plugins/debian/tests/test_directory.py (+114/-0)
breezy/plugins/debian/tests/test_extract.py (+190/-0)
breezy/plugins/debian/tests/test_hooks.py (+86/-0)
breezy/plugins/debian/tests/test_import_dsc.py (+2114/-0)
breezy/plugins/debian/tests/test_merge_changelog.py (+411/-0)
breezy/plugins/debian/tests/test_merge_package.py (+649/-0)
breezy/plugins/debian/tests/test_merge_upstream.py (+45/-0)
breezy/plugins/debian/tests/test_repack_tarball.py (+146/-0)
breezy/plugins/debian/tests/test_repack_tarball_extra.py (+150/-0)
breezy/plugins/debian/tests/test_revspec.py (+112/-0)
breezy/plugins/debian/tests/test_source_distiller.py (+277/-0)
breezy/plugins/debian/tests/test_tagging.py (+34/-0)
breezy/plugins/debian/tests/test_upstream.py (+1648/-0)
breezy/plugins/debian/tests/test_upstream_uscan.py (+125/-0)
breezy/plugins/debian/tests/test_util.py (+1068/-0)
breezy/plugins/debian/update_packaging.py (+133/-0)
breezy/plugins/debian/upstream/__init__.py (+554/-0)
breezy/plugins/debian/upstream/branch.py (+846/-0)
breezy/plugins/debian/upstream/pristinetar.py (+1162/-0)
breezy/plugins/debian/upstream/tags.py (+186/-0)
breezy/plugins/debian/upstream/uscan.py (+349/-0)
breezy/plugins/debian/user.conf (+3/-0)
breezy/plugins/debian/util.py (+901/-0)
breezy/plugins/debian/vcs_up_to_date.py (+183/-0)
breezy/tests/test_foreign.py (+1/-1)
crates/debian/Cargo.toml (+11/-0)
crates/debian/src/lib.rs (+1/-0)
pyproject.toml (+23/-1)
setup.py (+0/-6)
tarmac.conf (+3/-2)
To merge this branch: bzr merge lp:~jelmer/brz/join-debian
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+455336@code.launchpad.net

Commit message

Import debian plugin

Description of the change

Import debian plugin

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Fixup command "sudo apt -y update && sudo apt -y install git quilt cargo rustc python3-venv python3-tdb python3-pyinotify python3-gpg libpython3-dev make python3-setuptools-rust openssh-client patch mypy rustfmt xz-utils" failed: Command exited with 2

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Attempt to merge into lp:brz failed due to conflicts:

text conflict in tarmac.conf

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Fixup command "sudo apt -y update && sudo apt -y install git quilt cargo rustc python3-venv python3-tdb python3-pyinotify python3-gpg libpython3-dev make python3-setuptools-rust openssh-client patch mypy rustfmt xz-utils python3-pip && pip3 install --break-system-packages ruff" failed: Command exited with 2

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Attempt to merge into lp:brz failed due to conflicts:

text conflict in tarmac.conf

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Attempt to merge into lp:brz failed due to conflicts:

text conflict in tarmac.conf

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (18.9 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 2.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.7-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.7-py3-none-any.whl (5.5 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.7
Obtaining file:///tmp/tarmac/branch.jmvsvy6s
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.3-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.4)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 1.7 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (11.6 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 2.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.7-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.7-py3-none-any.whl (5.5 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.7
Obtaining file:///tmp/tarmac/branch.cqrqkrag
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.3-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.5)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 2.0 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (12.0 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.7-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.7-py3-none-any.whl (5.5 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.7
Obtaining file:///tmp/tarmac/branch.xp8dimlq
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.3-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.5)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 2.4 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (12.0 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.7-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.7-py3-none-any.whl (5.5 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.7
Obtaining file:///tmp/tarmac/branch.zua7ut_h
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.3-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.5)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 2.4 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Attempt to merge into lp:brz failed due to conflicts:

text conflict in Cargo.lock

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Attempt to merge into lp:brz failed due to conflicts:

text conflict in Cargo.lock

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (12.0 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.7-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.7-py3-none-any.whl (5.5 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.7
Obtaining file:///tmp/tarmac/branch.0d4ayhym
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.5)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 2.1 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (12.5 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Using cached setuptools_gettext-0.1.7-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Using cached setuptools_gettext-0.1.7-py3-none-any.whl (5.5 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.7
Obtaining file:///tmp/tarmac/branch.2mqzdls8
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Using cached testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Using cached testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Using cached python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.6)
Collecting docutils
  Using cached docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Using cached sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Using cached sphinx_epytext-0.0.4-py3-none-any.whl
Collecting fastimport
  Using cached fastimport-0.9.14-py2.py3-none-any.whl
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
Requirement already satisfied: httplib2 in /usr/lib/python3/dist-packages (from launchpadlib>=1.6.3) (0.20.4)
Requirement already satisfied: lazr.restfulclient>=0.14.2 in /usr/lib/python3/dist-packages (from launchpadlib>=1.6.3) (0.14.5)
Requirement already satisfied:...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (12.5 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.7-py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.7-py3-none-any.whl (5.5 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.7
Obtaining file:///tmp/tarmac/branch.sv_t844m
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.6)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 2.2 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (12.5 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.8-py3-none-any.whl.metadata (1.9 kB)
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.8-py3-none-any.whl (12 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.8
Obtaining file:///tmp/tarmac/branch.kti0gmbf
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.9)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 2.7 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
R...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (11.3 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 2.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.8-py3-none-any.whl.metadata (1.9 kB)
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.8-py3-none-any.whl (12 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.8
Obtaining file:///tmp/tarmac/branch.uowdbirk
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (6.0.1)
Collecting testtools>=0.9.5
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit
  Downloading python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29
  Using cached Cython-3.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (0.1.11)
Collecting docutils
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (68.1.2)
Collecting sphinx
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.8/41.8 kB 2.3 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/python3/dist-packages (1.11.0)
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/lib/python3.11/dist-packages (3.3.1)
Requirement already satisfied: gpg in /usr/lib/python3/dist-packages (1.18.0)
...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Attempt to merge into lp:brz failed due to conflicts:

text conflict in Cargo.lock
text conflict in crates/graph-py/src/lib.rs

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (13.3 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.11-py3-none-any.whl.metadata (1.9 kB)
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.11-py3-none-any.whl (13 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.11
Obtaining file:///tmp/tarmac/branch._4ouwour
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (6.0.1)
Collecting testtools>=0.9.5 (from breezy==3.4.0.dev0)
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios (from breezy==3.4.0.dev0)
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit (from breezy==3.4.0.dev0)
  Downloading python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29 (from breezy==3.4.0.dev0)
  Using cached Cython-3.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (from breezy==3.4.0.dev0) (0.2.2)
Collecting docutils (from breezy==3.4.0.dev0)
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (from breezy==3.4.0.dev0) (68.1.2)
Collecting sphinx (from breezy==3.4.0.dev0)
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext (from breezy==3.4.0.dev0)
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport (from breezy==3.4.0.dev0)
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (13.4 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.11-py3-none-any.whl.metadata (1.9 kB)
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.11-py3-none-any.whl (13 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.11
Obtaining file:///tmp/tarmac/branch.6x_as0h0
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (6.0.1)
Collecting testtools>=0.9.5 (from breezy==3.4.0.dev0)
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios (from breezy==3.4.0.dev0)
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl (21 kB)
Collecting python-subunit (from breezy==3.4.0.dev0)
  Downloading python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29 (from breezy==3.4.0.dev0)
  Using cached Cython-3.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (from breezy==3.4.0.dev0) (0.2.2)
Collecting docutils (from breezy==3.4.0.dev0)
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (from breezy==3.4.0.dev0) (68.1.2)
Collecting sphinx (from breezy==3.4.0.dev0)
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext (from breezy==3.4.0.dev0)
  Downloading sphinx-epytext-0.0.4.tar.gz (3.6 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport (from breezy==3.4.0.dev0)
  Downloading fastimport-0.9.14.tar.gz (41 kB)
     ━━━...

Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :
Download full text (13.4 KiB)

The attempt to merge lp:~jelmer/brz/join-debian into lp:brz failed. Command exited with 1.
Below is the output from the failed tests.

Collecting setuptools-gettext
  Downloading setuptools_gettext-0.1.11-py3-none-any.whl.metadata (1.9 kB)
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.11/site-packages (from setuptools-gettext) (68.1.2)
Downloading setuptools_gettext-0.1.11-py3-none-any.whl (13 kB)
Installing collected packages: setuptools-gettext
Successfully installed setuptools-gettext-0.1.11
Obtaining file:///tmp/tarmac/branch.nky9u_7g
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Requirement already satisfied: configobj in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (5.0.8)
Requirement already satisfied: fastbencode in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.2)
Requirement already satisfied: patiencediff in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.2.13)
Requirement already satisfied: merge3 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.0.8)
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (0.21.6)
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (1.26.18)
Requirement already satisfied: pyyaml in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (6.0.1)
Collecting testtools>=0.9.5 (from breezy==3.4.0.dev0)
  Downloading testtools-2.7.1-py3-none-any.whl.metadata (5.3 kB)
Collecting testscenarios (from breezy==3.4.0.dev0)
  Downloading testscenarios-0.5.0-py2.py3-none-any.whl.metadata (12 kB)
Collecting python-subunit (from breezy==3.4.0.dev0)
  Downloading python_subunit-1.4.4-py3-none-any.whl.metadata (22 kB)
Collecting cython>=0.29 (from breezy==3.4.0.dev0)
  Using cached Cython-3.0.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.2 kB)
Requirement already satisfied: ruff in /usr/local/lib/python3.11/dist-packages (from breezy==3.4.0.dev0) (0.3.4)
Requirement already satisfied: types-paramiko in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (3.3)
Requirement already satisfied: types-PyYAML in /usr/lib/python3/dist-packages (from breezy==3.4.0.dev0) (6.0)
Collecting docutils (from breezy==3.4.0.dev0)
  Downloading docutils-0.20.1-py3-none-any.whl.metadata (2.8 kB)
Requirement already satisfied: setuptools in ./lib/python3.11/site-packages (from breezy==3.4.0.dev0) (68.1.2)
Collecting sphinx (from breezy==3.4.0.dev0)
  Downloading sphinx-7.2.6-py3-none-any.whl.metadata (5.9 kB)
Collecting sphinx-epytext (from breezy==3.4.0.dev0)
  Downloading sphinx-epyt...

Unmerged revisions

7910. By Jelmer Vernooij

Merge lp:brz

7909. By Jelmer Vernooij

Fix clippy

7908. By Jelmer Vernooij

Merge trunk

7907. By Jelmer Vernooij

Install apt from git

7906. By Jelmer Vernooij

Install python3-apt

7905. By Jelmer Vernooij

Merge truk:

7904. By Jelmer Vernooij

Fix tests

7903. By Jelmer Vernooij

Another round of type fixes

7902. By Jelmer Vernooij

Fix typing

7901. By Jelmer Vernooij

Fix up bp.debian; apply ruff fixes

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.github/workflows/pythonpackage.yml'
2--- .github/workflows/pythonpackage.yml 2023-09-29 22:34:48 +0000
3+++ .github/workflows/pythonpackage.yml 2024-02-18 23:22:42 +0000
4@@ -45,7 +45,8 @@
5 python -m pip install --upgrade pip
6 python -m pip install -U pip "setuptools>=60" setuptools-gettext cython setuptools-rust
7 python -m pip install -U pip coverage codecov cython testscenarios git+https://github.com/dulwich/dulwich
8- python -m pip install ".[dev,paramiko,doc,launchpad,git,fastimport]"
9+ python -m pip install git+https://salsa.debian.org/apt-team/python-apt
10+ python -m pip install ".[dev,paramiko,doc,launchpad,git,fastimport,debian]"
11 - name: Install dependencies (linux/pip)
12 run: |
13 sudo apt install libgpgme-dev
14
15=== modified file 'Cargo.lock'
16--- Cargo.lock 2024-01-27 13:58:35 +0000
17+++ Cargo.lock 2024-02-18 23:22:42 +0000
18@@ -198,6 +198,14 @@
19 ]
20
21 [[package]]
22+name = "breezy-debian"
23+version = "2.8.78"
24+dependencies = [
25+ "debian-changelog",
26+ "debian-control",
27+]
28+
29+[[package]]
30 name = "breezy-git"
31 version = "3.4.0"
32 dependencies = [
33@@ -289,9 +297,9 @@
34
35 [[package]]
36 name = "bumpalo"
37-version = "3.14.0"
38+version = "3.15.0"
39 source = "registry+https://github.com/rust-lang/crates.io-index"
40-checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
41+checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f"
42
43 [[package]]
44 name = "byteorder"
45@@ -316,13 +324,15 @@
46
47 [[package]]
48 name = "chrono"
49-version = "0.4.33"
50+version = "0.4.34"
51 source = "registry+https://github.com/rust-lang/crates.io-index"
52-checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb"
53+checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b"
54 dependencies = [
55 "android-tzdata",
56 "iana-time-zone",
57+ "js-sys",
58 "num-traits",
59+ "wasm-bindgen",
60 "windows-targets 0.52.0",
61 ]
62
63@@ -344,6 +354,12 @@
64 checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
65
66 [[package]]
67+name = "countme"
68+version = "3.0.1"
69+source = "registry+https://github.com/rust-lang/crates.io-index"
70+checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
71+
72+[[package]]
73 name = "cpufeatures"
74 version = "0.2.12"
75 source = "registry+https://github.com/rust-lang/crates.io-index"
76@@ -354,9 +370,9 @@
77
78 [[package]]
79 name = "crc32fast"
80-version = "1.3.2"
81+version = "1.4.0"
82 source = "registry+https://github.com/rust-lang/crates.io-index"
83-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
84+checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
85 dependencies = [
86 "cfg-if",
87 ]
88@@ -372,6 +388,54 @@
89 ]
90
91 [[package]]
92+name = "deb822-lossless"
93+version = "0.1.7"
94+source = "registry+https://github.com/rust-lang/crates.io-index"
95+checksum = "2419c03e447e68c58bb4b2b0fe61833104821791fbada165d235aa36510430ea"
96+dependencies = [
97+ "regex",
98+ "rowan",
99+ "serde",
100+]
101+
102+[[package]]
103+name = "debian-changelog"
104+version = "0.1.10"
105+source = "registry+https://github.com/rust-lang/crates.io-index"
106+checksum = "cf0fbdc5e8c585c4c35454d1fad4a1cf1f5cbae4c55071f4ae80fbb65662ac0b"
107+dependencies = [
108+ "chrono",
109+ "debversion",
110+ "lazy-regex",
111+ "log",
112+ "rowan",
113+ "textwrap",
114+ "whoami",
115+]
116+
117+[[package]]
118+name = "debian-control"
119+version = "0.1.7"
120+source = "registry+https://github.com/rust-lang/crates.io-index"
121+checksum = "6cec8b5ba6189640ab127f182d35e98959b7ed90b6953bf7d71e0b45a9127321"
122+dependencies = [
123+ "deb822-lossless",
124+ "debversion",
125+ "regex",
126+ "rowan",
127+ "url",
128+]
129+
130+[[package]]
131+name = "debversion"
132+version = "0.2.2"
133+source = "registry+https://github.com/rust-lang/crates.io-index"
134+checksum = "e65a0a572fa10f34b89addac251b7c8f40266606ee5847d769ab8db4d56ca11b"
135+dependencies = [
136+ "lazy-regex",
137+]
138+
139+[[package]]
140 name = "digest"
141 version = "0.10.7"
142 source = "registry+https://github.com/rust-lang/crates.io-index"
143@@ -566,9 +630,9 @@
144
145 [[package]]
146 name = "hermit-abi"
147-version = "0.3.4"
148+version = "0.3.6"
149 source = "registry+https://github.com/rust-lang/crates.io-index"
150-checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f"
151+checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
152
153 [[package]]
154 name = "hostname"
155@@ -583,9 +647,9 @@
156
157 [[package]]
158 name = "iana-time-zone"
159-version = "0.1.59"
160+version = "0.1.60"
161 source = "registry+https://github.com/rust-lang/crates.io-index"
162-checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
163+checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
164 dependencies = [
165 "android_system_properties",
166 "core-foundation-sys",
167@@ -616,9 +680,9 @@
168
169 [[package]]
170 name = "indexmap"
171-version = "2.1.0"
172+version = "2.2.3"
173 source = "registry+https://github.com/rust-lang/crates.io-index"
174-checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
175+checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
176 dependencies = [
177 "equivalent",
178 "hashbrown",
179@@ -644,9 +708,9 @@
180
181 [[package]]
182 name = "js-sys"
183-version = "0.3.67"
184+version = "0.3.68"
185 source = "registry+https://github.com/rust-lang/crates.io-index"
186-checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
187+checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
188 dependencies = [
189 "wasm-bindgen",
190 ]
191@@ -671,7 +735,7 @@
192 "proc-macro2",
193 "quote",
194 "regex",
195- "syn 2.0.48",
196+ "syn 2.0.49",
197 ]
198
199 [[package]]
200@@ -682,9 +746,9 @@
201
202 [[package]]
203 name = "libc"
204-version = "0.2.152"
205+version = "0.2.153"
206 source = "registry+https://github.com/rust-lang/crates.io-index"
207-checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
208+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
209
210 [[package]]
211 name = "libredox"
212@@ -745,9 +809,9 @@
213
214 [[package]]
215 name = "lru"
216-version = "0.12.1"
217+version = "0.12.2"
218 source = "registry+https://github.com/rust-lang/crates.io-index"
219-checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7"
220+checksum = "db2c024b41519440580066ba82aab04092b333e09066a5eb86c7c4890df31f22"
221 dependencies = [
222 "hashbrown",
223 ]
224@@ -801,9 +865,9 @@
225
226 [[package]]
227 name = "miniz_oxide"
228-version = "0.7.1"
229+version = "0.7.2"
230 source = "registry+https://github.com/rust-lang/crates.io-index"
231-checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
232+checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
233 dependencies = [
234 "adler",
235 ]
236@@ -821,9 +885,9 @@
237
238 [[package]]
239 name = "num-traits"
240-version = "0.2.17"
241+version = "0.2.18"
242 source = "registry+https://github.com/rust-lang/crates.io-index"
243-checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
244+checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
245 dependencies = [
246 "autocfg",
247 ]
248@@ -952,9 +1016,9 @@
249
250 [[package]]
251 name = "pkg-config"
252-version = "0.3.29"
253+version = "0.3.30"
254 source = "registry+https://github.com/rust-lang/crates.io-index"
255-checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb"
256+checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
257
258 [[package]]
259 name = "ppv-lite86"
260@@ -1027,7 +1091,7 @@
261 "proc-macro2",
262 "pyo3-macros-backend",
263 "quote",
264- "syn 2.0.48",
265+ "syn 2.0.49",
266 ]
267
268 [[package]]
269@@ -1039,7 +1103,7 @@
270 "heck",
271 "proc-macro2",
272 "quote",
273- "syn 2.0.48",
274+ "syn 2.0.49",
275 ]
276
277 [[package]]
278@@ -1137,16 +1201,35 @@
279 checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
280
281 [[package]]
282+name = "rowan"
283+version = "0.15.15"
284+source = "registry+https://github.com/rust-lang/crates.io-index"
285+checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49"
286+dependencies = [
287+ "countme",
288+ "hashbrown",
289+ "memoffset",
290+ "rustc-hash",
291+ "text-size",
292+]
293+
294+[[package]]
295 name = "rustc-demangle"
296 version = "0.1.23"
297 source = "registry+https://github.com/rust-lang/crates.io-index"
298 checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
299
300 [[package]]
301+name = "rustc-hash"
302+version = "1.1.0"
303+source = "registry+https://github.com/rust-lang/crates.io-index"
304+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
305+
306+[[package]]
307 name = "rustix"
308-version = "0.38.30"
309+version = "0.38.31"
310 source = "registry+https://github.com/rust-lang/crates.io-index"
311-checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
312+checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
313 dependencies = [
314 "bitflags 2.4.2",
315 "errno",
316@@ -1193,14 +1276,14 @@
317 dependencies = [
318 "proc-macro2",
319 "quote",
320- "syn 2.0.48",
321+ "syn 2.0.49",
322 ]
323
324 [[package]]
325 name = "serde_yaml"
326-version = "0.9.30"
327+version = "0.9.31"
328 source = "registry+https://github.com/rust-lang/crates.io-index"
329-checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38"
330+checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e"
331 dependencies = [
332 "indexmap",
333 "itoa",
334@@ -1254,9 +1337,9 @@
335
336 [[package]]
337 name = "syn"
338-version = "2.0.48"
339+version = "2.0.49"
340 source = "registry+https://github.com/rust-lang/crates.io-index"
341-checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
342+checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
343 dependencies = [
344 "proc-macro2",
345 "quote",
346@@ -1289,13 +1372,12 @@
347
348 [[package]]
349 name = "tempfile"
350-version = "3.9.0"
351+version = "3.10.0"
352 source = "registry+https://github.com/rust-lang/crates.io-index"
353-checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
354+checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
355 dependencies = [
356 "cfg-if",
357 "fastrand",
358- "redox_syscall",
359 "rustix",
360 "windows-sys 0.52.0",
361 ]
362@@ -1322,10 +1404,16 @@
363 ]
364
365 [[package]]
366+name = "text-size"
367+version = "1.1.1"
368+source = "registry+https://github.com/rust-lang/crates.io-index"
369+checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
370+
371+[[package]]
372 name = "textwrap"
373-version = "0.16.0"
374+version = "0.16.1"
375 source = "registry+https://github.com/rust-lang/crates.io-index"
376-checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
377+checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
378 dependencies = [
379 "smawk",
380 "unicode-linebreak",
381@@ -1334,22 +1422,22 @@
382
383 [[package]]
384 name = "thiserror"
385-version = "1.0.56"
386+version = "1.0.57"
387 source = "registry+https://github.com/rust-lang/crates.io-index"
388-checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
389+checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
390 dependencies = [
391 "thiserror-impl",
392 ]
393
394 [[package]]
395 name = "thiserror-impl"
396-version = "1.0.56"
397+version = "1.0.57"
398 source = "registry+https://github.com/rust-lang/crates.io-index"
399-checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
400+checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
401 dependencies = [
402 "proc-macro2",
403 "quote",
404- "syn 2.0.48",
405+ "syn 2.0.49",
406 ]
407
408 [[package]]
409@@ -1480,9 +1568,9 @@
410
411 [[package]]
412 name = "wasm-bindgen"
413-version = "0.2.90"
414+version = "0.2.91"
415 source = "registry+https://github.com/rust-lang/crates.io-index"
416-checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
417+checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
418 dependencies = [
419 "cfg-if",
420 "wasm-bindgen-macro",
421@@ -1490,24 +1578,24 @@
422
423 [[package]]
424 name = "wasm-bindgen-backend"
425-version = "0.2.90"
426+version = "0.2.91"
427 source = "registry+https://github.com/rust-lang/crates.io-index"
428-checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
429+checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
430 dependencies = [
431 "bumpalo",
432 "log",
433 "once_cell",
434 "proc-macro2",
435 "quote",
436- "syn 2.0.48",
437+ "syn 2.0.49",
438 "wasm-bindgen-shared",
439 ]
440
441 [[package]]
442 name = "wasm-bindgen-macro"
443-version = "0.2.90"
444+version = "0.2.91"
445 source = "registry+https://github.com/rust-lang/crates.io-index"
446-checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
447+checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
448 dependencies = [
449 "quote",
450 "wasm-bindgen-macro-support",
451@@ -1515,22 +1603,22 @@
452
453 [[package]]
454 name = "wasm-bindgen-macro-support"
455-version = "0.2.90"
456+version = "0.2.91"
457 source = "registry+https://github.com/rust-lang/crates.io-index"
458-checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
459+checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
460 dependencies = [
461 "proc-macro2",
462 "quote",
463- "syn 2.0.48",
464+ "syn 2.0.49",
465 "wasm-bindgen-backend",
466 "wasm-bindgen-shared",
467 ]
468
469 [[package]]
470 name = "wasm-bindgen-shared"
471-version = "0.2.90"
472+version = "0.2.91"
473 source = "registry+https://github.com/rust-lang/crates.io-index"
474-checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
475+checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
476
477 [[package]]
478 name = "whoami"
479@@ -1751,7 +1839,7 @@
480 dependencies = [
481 "proc-macro2",
482 "quote",
483- "syn 2.0.48",
484+ "syn 2.0.49",
485 ]
486
487 [[package]]
488
489=== modified file 'breezy/bugtracker.py'
490--- breezy/bugtracker.py 2023-11-07 10:54:10 +0000
491+++ breezy/bugtracker.py 2024-02-18 23:22:42 +0000
492@@ -322,6 +322,8 @@
493 :return: iterator over (url, status) tuples
494 """
495 for line in bug_lines:
496+ if not line:
497+ continue
498 try:
499 url, status = line.split(None, 2)
500 except ValueError as exc:
501
502=== modified file 'breezy/commands.py'
503--- breezy/commands.py 2023-11-16 15:15:02 +0000
504+++ breezy/commands.py 2024-02-18 23:22:42 +0000
505@@ -26,7 +26,7 @@
506 import contextlib
507 import os
508 import sys
509-from typing import List, Optional, Union
510+from typing import List, Optional
511
512 from . import i18n, option, trace
513 from .lazy_import import lazy_import
514@@ -489,7 +489,7 @@
515
516 aliases: List[str] = []
517 takes_args: List[str] = []
518- takes_options: List[Union[str, option.Option]] = []
519+ takes_options: list[str | option.Option] = []
520 encoding_type: str = "strict"
521 invoked_as: Optional[str] = None
522 l10n: bool = True
523
524=== renamed file 'breezy/git/bzr-receive-pack' => 'breezy/git/bzr_receive_pack.py'
525--- breezy/git/bzr-receive-pack 2023-01-31 01:05:40 +0000
526+++ breezy/git/bzr_receive_pack.py 2024-02-18 23:22:42 +0000
527@@ -1,5 +1,21 @@
528 #!/usr/bin/env python3
529
530+# Copyright (C) 2010 Jelmer Vernooij <jelmer@jelmer.uk>
531+
532+# This program is free software; you can redistribute it and/or modify
533+# it under the terms of the GNU General Public License as published by
534+# the Free Software Foundation; either version 2 of the License, or
535+# (at your option) any later version.
536+#
537+# This program is distributed in the hope that it will be useful,
538+# but WITHOUT ANY WARRANTY; without even the implied warranty of
539+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
540+# GNU General Public License for more details.
541+#
542+# You should have received a copy of the GNU General Public License
543+# along with this program; if not, write to the Free Software
544+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
545+
546 import os
547 import sys
548
549@@ -10,9 +26,11 @@
550 import breezy.git
551 from breezy.git.server import BzrBackend
552
553-if len(sys.argv) < 2:
554- print("usage: %s <git-dir>" % os.path.basename(sys.argv[0]))
555- sys.exit(1)
556-
557-backend = BzrBackend(breezy.transport.get_transport("/"))
558-sys.exit(serve_command(ReceivePackHandler, backend=backend))
559+
560+def main():
561+ if len(sys.argv) < 2:
562+ print("usage: %s <git-dir>" % os.path.basename(sys.argv[0]))
563+ sys.exit(1)
564+
565+ backend = BzrBackend(breezy.transport.get_transport("/"))
566+ sys.exit(serve_command(ReceivePackHandler, backend=backend))
567
568=== renamed file 'breezy/git/bzr-upload-pack' => 'breezy/git/bzr_upload_pack.py'
569--- breezy/git/bzr-upload-pack 2023-01-31 01:05:40 +0000
570+++ breezy/git/bzr_upload_pack.py 2024-02-18 23:22:42 +0000
571@@ -1,5 +1,21 @@
572 #!/usr/bin/env python3
573
574+# Copyright (C) 2010 Jelmer Vernooij <jelmer@jelmer.uk>
575+
576+# This program is free software; you can redistribute it and/or modify
577+# it under the terms of the GNU General Public License as published by
578+# the Free Software Foundation; either version 2 of the License, or
579+# (at your option) any later version.
580+#
581+# This program is distributed in the hope that it will be useful,
582+# but WITHOUT ANY WARRANTY; without even the implied warranty of
583+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
584+# GNU General Public License for more details.
585+#
586+# You should have received a copy of the GNU General Public License
587+# along with this program; if not, write to the Free Software
588+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
589+
590 import os
591 import sys
592
593@@ -10,9 +26,11 @@
594 import breezy.git
595 from breezy.git.server import BzrBackend
596
597-if len(sys.argv) < 2:
598- print("usage: %s <git-dir>" % os.path.basename(sys.argv[0]))
599- sys.exit(1)
600-
601-backend = BzrBackend(breezy.transport.get_transport("/"))
602-sys.exit(serve_command(UploadPackHandler, backend=backend))
603+
604+def main():
605+ if len(sys.argv) < 2:
606+ print("usage: %s <git-dir>" % os.path.basename(sys.argv[0]))
607+ sys.exit(1)
608+
609+ backend = BzrBackend(breezy.transport.get_transport("/"))
610+ sys.exit(serve_command(UploadPackHandler, backend=backend))
611
612=== renamed file 'breezy/git/git-remote-bzr' => 'breezy/git/git_remote_bzr.py'
613--- breezy/git/git-remote-bzr 2023-01-31 01:05:40 +0000
614+++ breezy/git/git_remote_bzr.py 2024-02-18 23:22:42 +0000
615@@ -28,6 +28,7 @@
616 def handle_sigint(signal, frame):
617 sys.exit(0)
618
619+
620 signal.signal(signal.SIGINT, handle_sigint)
621
622 import breezy
623@@ -38,18 +39,20 @@
624
625 load_plugins()
626
627-from breezy.git.git_remote_helper import (RemoteHelper, open_local_dir,
628- open_remote_dir)
629+from breezy.git.git_remote_helper import RemoteHelper, open_local_dir, open_remote_dir
630 from breezy.trace import warning
631
632-parser = optparse.OptionParser()
633-(opts, args) = parser.parse_args()
634-(shortname, url) = args
635-
636-warning(
637- 'git-remote-bzr is experimental and has not been optimized for '
638- 'performance. Use \'brz fast-export\' and \'git fast-import\' for '
639- 'large repositories.')
640-
641-helper = RemoteHelper(open_local_dir(), shortname, open_remote_dir(url))
642-helper.process(sys.stdin.buffer, sys.stdout.buffer)
643+
644+def main():
645+ parser = optparse.OptionParser()
646+ (opts, args) = parser.parse_args()
647+ (shortname, url) = args
648+
649+ warning(
650+ "git-remote-bzr is experimental and has not been optimized for "
651+ "performance. Use 'brz fast-export' and 'git fast-import' for "
652+ "large repositories."
653+ )
654+
655+ helper = RemoteHelper(open_local_dir(), shortname, open_remote_dir(url))
656+ helper.process(sys.stdin.buffer, sys.stdout.buffer)
657
658=== modified file 'breezy/merge.py'
659--- breezy/merge.py 2023-11-16 15:15:02 +0000
660+++ breezy/merge.py 2024-02-18 23:22:42 +0000
661@@ -16,7 +16,7 @@
662
663 import contextlib
664 import tempfile
665-from typing import Type
666+from typing import Optional, Type
667
668 from .lazy_import import lazy_import
669
670@@ -177,7 +177,7 @@
671 """
672
673 name_prefix: str
674- default_files = None
675+ default_files: Optional[list[str]] = None
676
677 def __init__(self, merger):
678 super().__init__(merger)
679
680=== added directory 'breezy/plugins/debian'
681=== added file 'breezy/plugins/debian/Dockerfile.deb-auto-backport'
682--- breezy/plugins/debian/Dockerfile.deb-auto-backport 1970-01-01 00:00:00 +0000
683+++ breezy/plugins/debian/Dockerfile.deb-auto-backport 2024-02-18 23:22:42 +0000
684@@ -0,0 +1,7 @@
685+FROM debian:sid-slim
686+RUN apt -y update && apt install -y git dctrl-tools
687+COPY . /code
688+RUN apt satisfy -y "$(grep-dctrl -n -w -s Build-Depends '' /code/debian/control)"
689+ENV PYTHONPATH=/code
690+VOLUME /data
691+ENTRYPOINT ["/code/scripts/deb-auto-backport", "-d", "/data"]
692
693=== added file 'breezy/plugins/debian/Dockerfile.deb-import-uncommitted'
694--- breezy/plugins/debian/Dockerfile.deb-import-uncommitted 1970-01-01 00:00:00 +0000
695+++ breezy/plugins/debian/Dockerfile.deb-import-uncommitted 2024-02-18 23:22:42 +0000
696@@ -0,0 +1,7 @@
697+FROM debian:sid-slim
698+RUN apt -y update && apt install -y git dctrl-tools
699+COPY . /code
700+RUN apt satisfy -y "$(grep-dctrl -n -w -s Build-Depends '' /code/debian/control)"
701+ENV PYTHONPATH=/code
702+VOLUME /data
703+ENTRYPOINT ["/code/scripts/deb-import-uncommitted", "-d", "/data"]
704
705=== added file 'breezy/plugins/debian/Dockerfile.deb-move-orphaned'
706--- breezy/plugins/debian/Dockerfile.deb-move-orphaned 1970-01-01 00:00:00 +0000
707+++ breezy/plugins/debian/Dockerfile.deb-move-orphaned 2024-02-18 23:22:42 +0000
708@@ -0,0 +1,7 @@
709+FROM debian:sid-slim
710+RUN apt -y update && apt install -y git dctrl-tools
711+COPY . /code
712+RUN apt satisfy -y "$(grep-dctrl -n -w -s Build-Depends '' /code/debian/control)"
713+ENV PYTHONPATH=/code
714+VOLUME /data
715+ENTRYPOINT ["/code/scripts/deb-move-orphaned", "-d", "/data"]
716
717=== added file 'breezy/plugins/debian/Dockerfile.deb-new-upstream'
718--- breezy/plugins/debian/Dockerfile.deb-new-upstream 1970-01-01 00:00:00 +0000
719+++ breezy/plugins/debian/Dockerfile.deb-new-upstream 2024-02-18 23:22:42 +0000
720@@ -0,0 +1,7 @@
721+FROM debian:sid-slim
722+RUN apt -y update && apt install -y git dctrl-tools
723+COPY . /code
724+RUN apt satisfy -y "$(grep-dctrl -n -w -s Build-Depends '' /code/debian/control)"
725+ENV PYTHONPATH=/code
726+VOLUME /data
727+ENTRYPOINT ["/code/scripts/deb-new-upstream", "-d", "/data"]
728
729=== added file 'breezy/plugins/debian/Makefile'
730--- breezy/plugins/debian/Makefile 1970-01-01 00:00:00 +0000
731+++ breezy/plugins/debian/Makefile 2024-02-18 23:22:42 +0000
732@@ -0,0 +1,46 @@
733+BRZ ?= $(shell which brz)
734+BRZ_OPTIONS ?= -Derror
735+SETUP ?= $(PYTHON) ./setup.py
736+TESTS ?= "^breezy.plugins.debian." "^unittest"
737+
738+all: update-pot
739+
740+.PHONY: update-pot po/breezy-debian.pot
741+update-pot: po/breezy-debian.pot
742+
743+TRANSLATABLE_PYFILES:=$(shell find . -name '*.py' \
744+ | grep -v 'tests/' \
745+ )
746+
747+po/breezy-debian.pot: $(PYFILES) $(DOCFILES)
748+ BRZ_PLUGINS_AT=builddeb@$(shell pwd) $(BRZ) export-pot \
749+ --plugin=builddeb > po/breezy-debian.pot
750+ echo $(TRANSLATABLE_PYFILES) | xargs \
751+ xgettext --package-name "breezy-debian" \
752+ --msgid-bugs-address "<bazaar@lists.canonical.com>" \
753+ --copyright-holder "Canonical Ltd. <bazaar@lists.canonical.com>" \
754+ --from-code ISO-8859-1 --sort-by-file --join --add-comments=i18n: \
755+ -d breezy-debian -p po -o breezy-debian.pot
756+
757+check:: testsuite
758+
759+testsuite:
760+ BRZ_PLUGINS_AT=debian@$(shell pwd) $(BRZ) $(BRZ_OPTIONS) selftest $(TEST_OPTIONS) $(TESTS)
761+
762+check:: flake8
763+
764+flake8:
765+ flake8 . scripts/deb-*
766+
767+mypy:
768+ BRZ_PLUGINS_AT=debian@$(shell pwd) mypy -p breezy.plugins.debian
769+
770+docker:
771+ buildah build -t ghcr.io/breezy-team/deb-new-upstream:latest -f Dockerfile.deb-new-upstream .
772+ buildah push ghcr.io/breezy-team/deb-new-upstream:latest
773+ buildah build -t ghcr.io/breezy-team/deb-auto-backport:latest -f Dockerfile.deb-auto-backport .
774+ buildah push ghcr.io/breezy-team/deb-auto-backport:latest
775+ buildah build -t ghcr.io/breezy-team/deb-move-orphaned:latest -f Dockerfile.deb-move-orphaned .
776+ buildah push ghcr.io/breezy-team/deb-move-orphaned:latest
777+ buildah build -t ghcr.io/breezy-team/deb-import-uncommitted:latest -f Dockerfile.deb-import-uncommitted .
778+ buildah push ghcr.io/breezy-team/deb-import-uncommitted:latest
779
780=== added file 'breezy/plugins/debian/README.rst'
781--- breezy/plugins/debian/README.rst 1970-01-01 00:00:00 +0000
782+++ breezy/plugins/debian/README.rst 2024-02-18 23:22:42 +0000
783@@ -0,0 +1,342 @@
784+brz-debian
785+==========
786+
787+Overview
788+--------
789+
790+This is brz-debian, a plugin for `Breezy`_ that allows you to build `Debian`_
791+packages from a Breezy compatible branch, like a Git repository or a Bazaar
792+branch.
793+
794+.. _Breezy: https://www.breezy-vcs.org/
795+.. _Debian: http://www.debian.org/
796+
797+Note that there is a user manual available at
798+/usr/share/doc/brz-debian/user_manual/index.html that gives more
799+information than this file.
800+
801+Installation
802+------------
803+
804+This plugin requires `python-debian`_ and Breezy.
805+
806+.. _python-debian: http://bzr.debian.org/pkg-python-debian/trunk/
807+
808+It also requires the ``dpkg-dev`` package to be installed (for the
809+``dpkg-mergechangelogs`` tool)::
810+
811+ apt install dpkg-dev
812+
813+This plugin can be installed in two ways. As you are probably using a Debian
814+system you can probably just use the Debian packages. The other way is to
815+branch it in to ``~/.breezy/plugins/debian``, i.e::
816+
817+ brz branch https://code.breezy-vcs.org/breezy-debian/trunk/ \
818+ ~/.config/breezy/plugins/debian
819+
820+This will give you a ``brz builddeb`` command (alias ``bd``).
821+
822+Help for this plugin can be found by running ``brz help builddeb``.
823+
824+There is also a script named ``brz-buildpackage`` provided in /usr/bin
825+that provides access to the tool as well. It is just a wrapper script that
826+calls ``brz builddeb`` with the arguments you provide, so the rest of the
827+documentation applies equally well to using this script. Probably the only
828+difference is that help will be got with ``brz-buildpackage ---help``
829+(as ``brz builddeb --help`` also works and does the same as
830+``brz help builddeb``). The script is provided for two reasons, the first
831+is similarity to the other ``-buildpackage`` systems, and the second is so
832+that the Debian package can provide the ``brz-buildpackage`` package, and
833+so make it easier for people to find the package.
834+
835+Configuration
836+-------------
837+
838+There are also configuration files that can be used, these are, in the order
839+that values will be used if found::
840+
841+ * .bzr-builddeb/local.conf (in the package directory)
842+ * ~/.bazaar/builddeb.conf
843+ * .bzr-builddeb/default.conf (in the package directory)
844+
845+The last of these should be used for values that will be used by all users of
846+the package, for instance 'merge = True'. The others are for the user to add
847+or override settings that are specific to them, either globally or per package.
848+
849+There is one complication to this however. As arbitrary commands can be
850+specified for some of the options there is a potential security hole. This
851+is closed by only taking these options from the configuration file in your
852+home directory, which can't be changed by another committer to the branch.
853+I apologise if this breaks your setup, and if you can't work around it please
854+talk to me to try to find an approach that satisfies you and does not open
855+any security holes.
856+
857+These files must start with::
858+
859+ [BUILDDEB]
860+
861+Configuration Options
862+~~~~~~~~~~~~~~~~~~~~~
863+
864+The following options are read from the configuration files. Most can also be
865+used as command line arguments by prepending ``--`` to the names and not using
866+the ``\=`` symbol. There are a few exceptions to this that are noted in the
867+descriptions.
868+
869+Directories
870+###########
871+
872+These change the directories that the plugin uses for various things.
873+
874+ * ``build-dir = path``
875+
876+ The directory in which the build takes place. (Defaults to
877+ ``../build-area`` relative to the branch).
878+
879+ * ``result-dir = path``
880+
881+ The directory the resulting files will be placed in. (Defaults to ``..``)
882+
883+ * ``orig-dir = path``
884+
885+ The directory to search for the ``.orig.tar.gz`` when not in native mode.
886+ (Defaults to ``..`` relative to the branch).
887+
888+Modes
889+#####
890+
891+These change the way in which the plugin operates. They can be set depending
892+on the type of package you are building.
893+
894+ * ``merge = True``
895+
896+ Turns on merge mode. This is where only the ``debian/`` directory is
897+ versioned. It uses and ``orig.tar.gz`` for the upstream and combines the
898+ two before building. It works with both the ``debian/`` directory in the
899+ branch, or the contents of ``debian/`` (e.g. ``rules``, ``control``)
900+ directly in the top level directory of the branch. (Defaults to ``False``).
901+
902+ * ``native = True``
903+
904+ If you want to build a native package from a branch then turn on this
905+ option. It will stop the plugin from looking for an ``orig.tar.gz`` and
906+ build a native package instead. This has no effect if merge mode is on,
907+ as I don't think it makes any sense to version the ``debian/`` separately
908+ for a native package. If you disagree let me know.
909+
910+ * ``split = True``
911+
912+ This takes a package from a branch that includes both the upstream source
913+ and the ``debian/`` dir and creates a non-native package from it by
914+ creating an ``orig.tar.gz`` from the code outside of ``debian/``. This
915+ is probably most useful if you are bot upstream and Debian maintainer
916+ of a non-native package. This has no effect if ``merge`` or ``native``
917+ are true, the former is for use when you don't version the full source,
918+ the second for when you don't need an ``orig.tar.gz`` so they make no sense
919+ to be used together.
920+
921+ * ``export-upstream = path``
922+
923+ This option takes a path (remote or local) to a brz branch that contains
924+ the upstream code. If this is set then the plugin will export the code
925+ from that branch to create the ``.orig.tar.gz``. This option only has any
926+ effect if ``merge`` is set.
927+
928+ * ``export-upstream-revision = revision``
929+
930+ This sets the revision that the upstream code will be branched at. It takes
931+ the same revision spec as the normal --revision parameter. Use it to
932+ associate an upstream version number with a particular revision of the
933+ upstream code. This has no effect if ``export-upstream`` is not set.
934+
935+Builders
936+########
937+
938+These configure the commands that are used to build the package in different
939+situations.
940+
941+ * ``builder = command``
942+
943+ The command to use to build the package. Defaults to ``debuild``).
944+ Will only be read from the file in your home directory.
945+
946+ * ``quick-builder = command``
947+
948+ The command used to build the package if the ``--quick`` option is used.
949+ (Defaults to ``fakeroot debian/rules binary``). Will only be read from
950+ the file in your home directory.
951+
952+The idea is that certain options can be set in ``.bzr-builddeb/default.conf``
953+that apply to the package on all systems, or that there is a default that is
954+wanted that differs from the default provided. ``merge = True`` is a perfect
955+example of this.
956+
957+Then the user can override this locally if they want for all of their packages
958+(they prefer ``builder = pdebuild``), so they can set this in
959+``~/.bazaar/builddeb.conf``. They can override it for the package if they want
960+(e.g. they have a different location for upstream tarballs of a package if
961+they are involved with upstream as well, so they set ``orig_dir =
962+/home/.../releases/``), this can be done in ``.bzr-builddeb/local.conf``).
963+
964+Creating a package
965+------------------
966+
967+Below are instructions for creating a package. These instructions differ
968+depending on whether you want to use merge mode or not.
969+
970+First the common start create a directory to hold your work. This is not
971+absolutely necessary, but as you still get all the power of brz when using
972+this plugin, so you might want to branch etc. and so this will be useful
973+later on::
974+
975+ $ mkdir path/to/project
976+
977+If you are going to be using branches then the following is a good optimisation
978+you can use::
979+
980+ $ brz init-repo --trees path/to/project
981+
982+Now create your global config file if you want to change something like the
983+builder in use, or have a global result directory or similar::
984+
985+ $ echo "[BUILDDEB]" > ~/.bazaar/builddeb.conf
986+ $ $EDITOR ~/.bazaar/builddeb.conf
987+
988+and any options that you want.
989+
990+I will describe creating a new project, but for existing projects you can
991+copy the code over and call ``brz init`` then continue in the same way.
992+
993+I will also describe the setup that conforms to the default options for
994+directories. If you wish to use a different layout set up the options to
995+your liking and tweak the commands below as necessary.
996+
997+Using merge mode
998+~~~~~~~~~~~~~~~~
999+
1000+Merge mode is when only the ``debian/`` directory of the package is versioned,
1001+with the upstream version of the code living elsewhere. It allows for clear
1002+separation of the Debian specific changes from the upstream code.
1003+
1004+First copy the ``.orig.tar.gz`` file for the current version in to the parent
1005+directory. If you do not have the upstream tarball for the current version,
1006+but you do have a ``watch`` file detailing where it can be found then the
1007+plugin will automatically retrieve the tarballs as they are needed.
1008+
1009+Now create the branch for the ``debian/`` directory::
1010+
1011+ $ brz init project
1012+
1013+Now you can either create a ``project/debian/`` directory for all the files,
1014+or add them in the ``project`` directory.
1015+
1016+Now tell bzr-builddeb that this is a merge mode project::
1017+
1018+ $ cd project/
1019+ $ mkdir .bzr-builddeb/
1020+ $ echo -e "[BUILDDEB]\nmerge = True" > .bzr-builddeb/default.conf
1021+
1022+Now you are ready to create the project. Create the usual files, and edit them
1023+to your satisfaction. When you have the files run::
1024+
1025+ $ brz add
1026+ $ brz ci
1027+
1028+from the root of the project branch.
1029+
1030+You are now ready to build the project. See below for instructions on doing
1031+this.
1032+
1033+Non-merge mode
1034+~~~~~~~~~~~~~~
1035+
1036+This is a little simpler to set up. Create the branch for the project::
1037+
1038+ $ cd path/to/project
1039+ $ brz init project
1040+
1041+Now add all the project files to the branch, and add the to bzr::
1042+
1043+ $ cd project
1044+ $ brz add
1045+ $ brz ci
1046+
1047+There are two options when you want to build a Debian package, whether
1048+it is a native package or not. Most packages are non-native so I will describe
1049+that first.
1050+
1051+To create a non-native package you need an upstream tarball to build against.
1052+Set the ``orig-dir`` variable to the directory containing the tarball that
1053+you want to use and the plugin will pick it up and you will have a non-native
1054+package. If you do not have the upstream tarball corresponding to the version
1055+of the package you are trying to build, but you have a ``watch`` file
1056+detailing where it can be found then it will be automatically retrieved when
1057+needed.
1058+
1059+However sometimes you might be upstream of a package as well as Debian
1060+maintainer, but it is not a native package. In that case you may version
1061+the whole source including ``debian/``, but not want to have to manually
1062+make a tarball without the ``debian/`` directory. In that case see the
1063+``split`` variable. If you set that then the plugin will create you an
1064+appropriately named orig.tar.gz of everything outside of ``debian/``.
1065+
1066+If you want to have a native package you don't need to worry about
1067+``orig-dir``, but instead set ``native = True`` in the
1068+``.bzr-builddeb/default.conf`` file (make sure it starts with ``[BUILDDEB]``
1069+if you create it).
1070+
1071+Now you are ready to build using the plugin.
1072+
1073+Building a Package
1074+------------------
1075+
1076+Once your package is set up then building it is easy. Run the following
1077+command from the top-level of the project branch, after checking in all
1078+changes::
1079+
1080+ $ brz bd
1081+
1082+If you used the default options this should build the package and leave the
1083+resulting files in ``../build-area``.
1084+
1085+Note that most of the options can be used as parameters to this command as well
1086+by prefixing their name with ``--``. So you can do for example::
1087+
1088+ $ brz bd --builder pdebuild
1089+
1090+to change from what is in the configuration files. Note that there is currently
1091+no way to set the binary options to false if they are set to true in the
1092+configuration files. It would be possible to allow this, but it would bloat
1093+the code and the help listings quite a lot, so I will only it if asked to.
1094+
1095+Tips
1096+----
1097+
1098+If you have a slow builder defined in your configuration (for instance
1099+``pdebuild``, you can bypass this by using the ``--quick`` option. This uses
1100+whatever the ``quick_builder`` option is (defaults to ``fakeroot debian/rules
1101+binary``).
1102+
1103+If you are running in merge mode, and you have a large upstream tarball, and
1104+you do not want to unpack it at every build you can speed things up even more.
1105+This involves reusing the tarball each build, so saving the need to unpack it.
1106+To do this run::
1107+
1108+ $ brz bd --export-only
1109+
1110+once to create a build-dir to use. (``-e`` is the short option for this). Then
1111+on the next builds you can use the ``--reuse`` and ``--dont-purge`` options to
1112+keep using this build directory. **N.B. This may cause build problems,
1113+especially if files are removed**, it is advisable to run a build without
1114+``--reuse`` after removing any files.
1115+
1116+Workflow
1117+--------
1118+
1119+brz-debian is designed to fit in with the workflow that brz encourages. It
1120+is designed as a plugin, so that it just becomes one more ``brz`` command that
1121+you run while working on the package.
1122+
1123+It also works fine with the frequent branching approach of brz, so that you
1124+can branch to test something new for the package, or for a bug fix, and then
1125+merge it back in to your main branch when it is done.
1126
1127=== added file 'breezy/plugins/debian/__init__.py'
1128--- breezy/plugins/debian/__init__.py 1970-01-01 00:00:00 +0000
1129+++ breezy/plugins/debian/__init__.py 2024-02-18 23:22:42 +0000
1130@@ -0,0 +1,271 @@
1131+# __init__.py -- The plugin for bzr
1132+# Copyright (C) 2005 Jamie Wilkinson <jaq@debian.org>
1133+# 2006, 2007 James Westby <jw+debian@jameswestby.net>
1134+# 2007 Reinhard Tartler <siretart@tauware.de>
1135+# 2008 Canonical Ltd.
1136+#
1137+# This file is part of brz-debian.
1138+#
1139+# brz-debian is free software; you can redistribute it and/or modify
1140+# it under the terms of the GNU General Public License as published by
1141+# the Free Software Foundation; either version 2 of the License, or
1142+# (at your option) any later version.
1143+#
1144+# brz-debian is distributed in the hope that it will be useful,
1145+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1146+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1147+# GNU General Public License for more details.
1148+#
1149+# You should have received a copy of the GNU General Public License
1150+# along with brz-debian; if not, write to the Free Software
1151+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1152+#
1153+
1154+"""manage versioned Debian packages."""
1155+
1156+import os
1157+
1158+import breezy # noqa: F401
1159+
1160+from ... import trace
1161+from ...commands import plugin_cmds
1162+from ...directory_service import (
1163+ AliasDirectory,
1164+ directories,
1165+)
1166+from ...hooks import install_lazy_named_hook
1167+from ...i18n import load_plugin_translations
1168+from ...revisionspec import revspec_registry
1169+from ...tag import tag_sort_methods
1170+from .info import ( # noqa: F401
1171+ brz_plugin_version as version_info,
1172+)
1173+
1174+translation = load_plugin_translations("brz-debian")
1175+gettext = translation.gettext
1176+
1177+
1178+commands = {
1179+ "builddeb_do": ["bd-do"],
1180+ "builddeb": ["bd", "debuild"],
1181+ "get_orig_source": [],
1182+ "dep3_patch": [],
1183+ "import_dsc": [],
1184+ "import_upstream": [],
1185+ "merge_upstream": ["mu"],
1186+ "debrelease": [],
1187+}
1188+
1189+for command, aliases in commands.items():
1190+ plugin_cmds.register_lazy("cmd_" + command, aliases, __name__ + ".cmds")
1191+
1192+
1193+def global_conf():
1194+ from ...bedding import config_dir
1195+
1196+ return os.path.join(config_dir(), "builddeb.conf")
1197+
1198+
1199+default_build_dir = "../build-area"
1200+default_orig_dir = ".."
1201+default_result_dir = ".."
1202+
1203+
1204+directories.register_lazy(
1205+ "apt:",
1206+ __name__ + ".directory",
1207+ "AptDirectory",
1208+ "Directory that uses Vcs-* control fields in apt to look up branches",
1209+)
1210+directories.register_lazy(
1211+ "dgit:",
1212+ __name__ + ".directory",
1213+ "DgitDirectory",
1214+ "Directory that uses Debian Dgit control fields to look up branches",
1215+)
1216+directories.register_lazy(
1217+ "vcs:",
1218+ __name__ + ".directory",
1219+ "VcsDirectory",
1220+ "Directory that uses local Debian Vcs-* control fields to look up " "branches",
1221+)
1222+
1223+AliasDirectory.branch_aliases.register_lazy(
1224+ "upstream",
1225+ __name__ + ".directory",
1226+ "upstream_branch_alias",
1227+ help="upstream branch (for packaging branches)",
1228+)
1229+
1230+tag_sort_methods.register_lazy(
1231+ "debversion", __name__ + ".tagging", "sort_debversion", "Sort like Debian versions."
1232+)
1233+
1234+revspec_registry.register_lazy(
1235+ "package:", __name__ + ".revspec", "RevisionSpec_package"
1236+)
1237+revspec_registry.register_lazy(
1238+ "upstream:", __name__ + ".revspec", "RevisionSpec_upstream"
1239+)
1240+
1241+
1242+def debian_changelog_commit_message(commit, start_message):
1243+ if start_message is not None:
1244+ return start_message
1245+ cl_path = "debian/changelog"
1246+ if not commit.work_tree.has_filename(cl_path):
1247+ return start_message
1248+ if not commit.work_tree.is_versioned(cl_path):
1249+ return start_message
1250+ if cl_path in commit.exclude:
1251+ return start_message
1252+ if commit.specific_files and cl_path not in commit.specific_files:
1253+ return start_message
1254+ from .changelog import changelog_changes
1255+
1256+ changes = changelog_changes(
1257+ commit.work_tree, commit.work_tree.basis_tree(), cl_path
1258+ )
1259+ if not changes:
1260+ return start_message
1261+
1262+ from .util import strip_changelog_message
1263+
1264+ changes = strip_changelog_message(changes)
1265+
1266+ return "".join(changes)
1267+
1268+
1269+def debian_changelog_commit(commit, start_message):
1270+ """Hooked into breezy.msgeditor set_commit_message.
1271+ Set the commit message from debian/changelog and set any LP: #1234 to bug
1272+ fixed tags.
1273+ """
1274+ from .util import find_bugs_fixed
1275+
1276+ changes = debian_changelog_commit_message(commit, start_message)
1277+ if changes is None:
1278+ return None
1279+
1280+ bugs_fixed = find_bugs_fixed([changes], commit.work_tree.branch)
1281+ commit.builder._revprops["bugs"] = "\n".join(bugs_fixed)
1282+
1283+ return changes
1284+
1285+
1286+def changelog_merge_hook_factory(merger):
1287+ from . import merge_changelog
1288+
1289+ return merge_changelog.ChangeLogFileMerge(merger)
1290+
1291+
1292+def tree_debian_tag_name(tree, branch, subpath="", vendor=None):
1293+ from .config import BUILD_TYPE_MERGE
1294+ from .import_dsc import DistributionBranch, DistributionBranchSet
1295+ from .util import (
1296+ MissingChangelogError,
1297+ debuild_config,
1298+ find_changelog,
1299+ suite_to_distribution,
1300+ )
1301+
1302+ config = debuild_config(tree, subpath=subpath)
1303+ try:
1304+ (changelog, top_level) = find_changelog(
1305+ tree, subpath=subpath, merge=(config.build_type == BUILD_TYPE_MERGE)
1306+ )
1307+ except MissingChangelogError:
1308+ # Not a debian package
1309+ return None
1310+ if changelog.distributions == "UNRELEASED":
1311+ # The changelog still targets 'UNRELEASED', so apparently hasn't been
1312+ # uploaded. XXX: Give a warning of some sort here?
1313+ return None
1314+ if vendor is None:
1315+ vendor = suite_to_distribution(changelog.distributions)
1316+ # TODO(jelmer): Default to local vendor?
1317+ db = DistributionBranch(branch, None)
1318+ dbs = DistributionBranchSet()
1319+ dbs.add_branch(db)
1320+ return db.tag_name(changelog.version, vendor)
1321+
1322+
1323+def debian_tag_name(branch, revid):
1324+ subpath = ""
1325+ t = branch.repository.revision_tree(revid)
1326+ return tree_debian_tag_name(t, branch, subpath, vendor=None)
1327+
1328+
1329+def pre_merge_fix_ancestry(merger):
1330+ from ...workingtree import WorkingTree
1331+ from .config import BUILD_TYPE_NATIVE
1332+ from .merge_package import fix_ancestry_as_needed
1333+ from .util import debuild_config
1334+
1335+ if not isinstance(merger.this_tree, WorkingTree):
1336+ return
1337+ if getattr(merger, "other_branch", None) is None:
1338+ return
1339+ # This only works for packages that live in the root. That seems fine,
1340+ # though?
1341+ if not merger.this_tree.is_versioned(
1342+ "debian/changelog"
1343+ ) or not merger.other_tree.is_versioned("debian/changelog"):
1344+ return
1345+ this_config = debuild_config(merger.this_tree, "")
1346+ other_config = debuild_config(merger.other_tree, "")
1347+ if not (
1348+ this_config.build_type == BUILD_TYPE_NATIVE
1349+ or other_config.build_type == BUILD_TYPE_NATIVE
1350+ ):
1351+ from .upstream import PackageVersionNotPresent
1352+
1353+ try:
1354+ fix_ancestry_as_needed(
1355+ merger.this_tree,
1356+ merger.other_branch,
1357+ source_revid=merger.other_tree.get_revision_id(),
1358+ )
1359+ except PackageVersionNotPresent as e:
1360+ trace.warning(
1361+ gettext(
1362+ "Not attempting to fix packaging branch ancestry, "
1363+ "missing pristine tar data for version %s."
1364+ ),
1365+ e.version,
1366+ )
1367+
1368+
1369+install_lazy_named_hook(
1370+ "breezy.msgeditor",
1371+ "hooks",
1372+ "commit_message_template",
1373+ debian_changelog_commit_message,
1374+ "Use changes documented in debian/changelog to suggest " "the commit message",
1375+)
1376+install_lazy_named_hook(
1377+ "breezy.merge",
1378+ "Merger.hooks",
1379+ "merge_file_content",
1380+ changelog_merge_hook_factory,
1381+ "Debian Changelog file merge",
1382+)
1383+install_lazy_named_hook(
1384+ "breezy.branch",
1385+ "Branch.hooks",
1386+ "automatic_tag_name",
1387+ debian_tag_name,
1388+ "Automatically determine tag names from Debian version",
1389+)
1390+install_lazy_named_hook(
1391+ "breezy.merge",
1392+ "Merger.hooks",
1393+ "pre_merge_fix_ancestry",
1394+ pre_merge_fix_ancestry,
1395+ "Debian ancestry fixing",
1396+)
1397+
1398+
1399+def load_tests(loader, basic_tests, pattern):
1400+ basic_tests.addTest(loader.loadTestsFromModuleNames([__name__ + ".tests"]))
1401+ return basic_tests
1402
1403=== added file 'breezy/plugins/debian/apt_repo.py'
1404--- breezy/plugins/debian/apt_repo.py 1970-01-01 00:00:00 +0000
1405+++ breezy/plugins/debian/apt_repo.py 2024-02-18 23:22:42 +0000
1406@@ -0,0 +1,280 @@
1407+#!/usr/bin/python3
1408+# Copyright (C) 2018 Jelmer Vernooij <jelmer@jelmer.uk>
1409+#
1410+# This program is free software; you can redistribute it and/or modify
1411+# it under the terms of the GNU General Public License as published by
1412+# the Free Software Foundation; either version 2 of the License, or
1413+# (at your option) any later version.
1414+#
1415+# This program is distributed in the hope that it will be useful,
1416+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1417+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1418+# GNU General Public License for more details.
1419+#
1420+# You should have received a copy of the GNU General Public License
1421+# along with this program; if not, write to the Free Software
1422+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1423+
1424+import errno
1425+import os
1426+import pwd
1427+import shutil
1428+import subprocess
1429+import tempfile
1430+from threading import Semaphore
1431+from typing import Optional
1432+
1433+from debian.deb822 import Deb822, Dsc
1434+
1435+from breezy.errors import DependencyNotPresent
1436+
1437+
1438+class NoAptSources(Exception):
1439+ """No apt sources were configured."""
1440+
1441+
1442+class AptSourceError(Exception):
1443+ """An error occured while running 'apt source'."""
1444+
1445+ def __init__(self, reason):
1446+ self.reason = reason
1447+
1448+
1449+def _convert_apt_pkg_error(e):
1450+ if "28: No space left on device":
1451+ return OSError(errno.ENOSPC, str(e))
1452+ return e
1453+
1454+
1455+class Apt:
1456+ def __enter__(self):
1457+ raise NotImplementedError(self.__enter__)
1458+
1459+ def __exit__(self, exc_tp, exc_val, exc_tb):
1460+ raise NotImplementedError(self.__exit__)
1461+
1462+ def iter_source_by_name(self, source_name):
1463+ for source in self.iter_sources():
1464+ if source["Package"] == source_name:
1465+ yield source
1466+
1467+ def iter_sources(self):
1468+ raise NotImplementedError(self.iter_sources)
1469+
1470+ def iter_binaries(self):
1471+ raise NotImplementedError(self.iter_binaries)
1472+
1473+ def iter_binary_by_name(self, binary_name):
1474+ for binary in self.iter_binaries():
1475+ if binary["Package"] == binary_name:
1476+ yield binary
1477+
1478+ def retrieve_orig(self, source_name, target_directory, orig_version=None):
1479+ raise NotImplementedError(self.retrieve_orig)
1480+
1481+ def retrieve_source(self, source_name, target_directory, source_version=None):
1482+ raise NotImplementedError(self.retrieve_source)
1483+
1484+
1485+_apt_semaphore = Semaphore()
1486+
1487+
1488+class LocalApt(Apt):
1489+ def __init__(self, rootdir=None):
1490+ self.apt_pkg = None
1491+ self._rootdir = rootdir
1492+
1493+ def __repr__(self):
1494+ return f"{type(self).__name__}({self._rootdir!r})"
1495+
1496+ def __enter__(self):
1497+ try:
1498+ import apt_pkg
1499+ except ImportError as e:
1500+ raise DependencyNotPresent("apt_pkg", e) from e
1501+ import apt
1502+
1503+ self.apt_pkg = apt_pkg
1504+ self.apt_pkg.init()
1505+ try:
1506+ self.cache = apt.Cache(rootdir=self._rootdir)
1507+ except apt_pkg.Error as e:
1508+ raise _convert_apt_pkg_error(e) from e
1509+ return self
1510+
1511+ def _set_dir(self):
1512+ if self._rootdir is not None:
1513+ self.apt_pkg.config.set("Dir", self._rootdir)
1514+ else:
1515+ self.apt_pkg.config.set("Dir", "/")
1516+
1517+ def __exit__(self, exc_tp, exc_val, exc_tb):
1518+ return False
1519+
1520+ def iter_sources(self):
1521+ with _apt_semaphore:
1522+ self._set_dir()
1523+ try:
1524+ sources = self.apt_pkg.SourceRecords()
1525+ except SystemError as e:
1526+ raise NoAptSources() from e
1527+
1528+ sources.restart()
1529+ while sources.step():
1530+ yield Dsc(sources.record)
1531+
1532+ def iter_source_by_name(self, source_name):
1533+ with _apt_semaphore:
1534+ self._set_dir()
1535+ try:
1536+ sources = self.apt_pkg.SourceRecords()
1537+ except SystemError as e:
1538+ raise NoAptSources() from e
1539+
1540+ sources.restart()
1541+ while sources.lookup(source_name):
1542+ yield Dsc(sources.record)
1543+
1544+ def iter_binaries(self):
1545+ with _apt_semaphore:
1546+ self._set_dir()
1547+
1548+ for pkg in self.cache:
1549+ for version in pkg.versions:
1550+ yield Deb822(version._records.record)
1551+
1552+ def iter_binary_by_name(self, binary_name):
1553+ with _apt_semaphore:
1554+ self._set_dir()
1555+
1556+ try:
1557+ pkg = self.cache[binary_name]
1558+ except KeyError:
1559+ pass
1560+ else:
1561+ for version in pkg.versions:
1562+ yield Deb822(version._records.record)
1563+
1564+ def retrieve_source(
1565+ self, package_name, target, source_version=None, tar_only=False
1566+ ):
1567+ self._run_apt_source(package_name, target, source_version, tar_only=tar_only)
1568+
1569+ def _get_command(self, package, version_str=None, tar_only=False):
1570+ args = ["apt", "source", "-d"]
1571+ if self._rootdir is not None:
1572+ args.append("-oDir=%s" % self._rootdir)
1573+ if tar_only:
1574+ args.append("--tar-only")
1575+ args.extend(
1576+ [
1577+ "-y",
1578+ "--only-source",
1579+ (f"{package}={version_str}") if version_str is not None else package,
1580+ ]
1581+ )
1582+ return args
1583+
1584+ def _run_apt_source(
1585+ self,
1586+ package: str,
1587+ target_dir,
1588+ version_str: Optional[str] = None,
1589+ tar_only: bool = False,
1590+ ):
1591+ command = self._get_command(package, version_str, tar_only=tar_only)
1592+ try:
1593+ subprocess.run(command, cwd=target_dir, capture_output=True, check=True)
1594+ except subprocess.CalledProcessError as e:
1595+ stderr = e.stderr.splitlines()
1596+ if stderr[-1] == (
1597+ b"E: You must put some 'source' URIs in your sources.list"
1598+ ):
1599+ raise NoAptSources() from e
1600+ CS = b"\x1b[1;31mE: \x1b[0m"
1601+ CE = b"\x1b[0m"
1602+ if stderr[-1] == (
1603+ CS + b"You must put some 'deb-src' URIs in your sources.list" + CE
1604+ ):
1605+ raise NoAptSources() from e
1606+ if stderr[-1].startswith(b"E: "):
1607+ raise AptSourceError(stderr[-1][3:].decode()) from e
1608+ if stderr[-1].startswith(CS):
1609+ raise AptSourceError(stderr[-1][len(CS) : -len(CE)].decode()) from e
1610+ raise AptSourceError(
1611+ [line.decode("utf-8", "surrogateescape") for line in stderr]
1612+ ) from e
1613+
1614+
1615+class RemoteApt(LocalApt):
1616+ def __init__(self, mirror_uri, distribution=None, components=None, key_path=None):
1617+ super().__init__()
1618+ self.mirror_uri = mirror_uri
1619+ self.distribution = distribution
1620+ self.components = components
1621+ self.key_path = key_path
1622+ self._rootdir = None
1623+
1624+ def __repr__(self):
1625+ return "{}({!r}, distribution={!r}, components={!r}, key_path={!r})".format(
1626+ type(self).__name__,
1627+ self.mirror_uri,
1628+ self.distribution,
1629+ self.components,
1630+ self.key_path,
1631+ )
1632+
1633+ def __enter__(self):
1634+ self._rootdir = tempfile.mkdtemp()
1635+ aptdir = os.path.join(self._rootdir, "etc", "apt")
1636+ os.makedirs(aptdir)
1637+ if self.key_path:
1638+ tag = "[signed-by=%s]" % self.key_path
1639+ else:
1640+ tag = "[trusted=yes]"
1641+ with open(os.path.join(aptdir, "sources.list"), "w") as f:
1642+ f.write(
1643+ "deb {} {} {} {}\n".format(
1644+ tag, self.mirror_uri, self.distribution, " ".join(self.components)
1645+ )
1646+ )
1647+ f.write(
1648+ "deb-src {} {} {} {}\n".format(
1649+ tag, self.mirror_uri, self.distribution, " ".join(self.components)
1650+ )
1651+ )
1652+ try:
1653+ import apt
1654+ except ImportError as e:
1655+ raise DependencyNotPresent("apt", e) from e
1656+ try:
1657+ import apt_pkg
1658+ except ImportError as e:
1659+ raise DependencyNotPresent("apt_pkg", e) from e
1660+ self.apt_pkg = apt_pkg
1661+ self.apt_pkg.init()
1662+ try:
1663+ self.cache = apt.Cache(rootdir=self._rootdir)
1664+ except apt_pkg.Error as e:
1665+ raise _convert_apt_pkg_error(e) from e
1666+ self._set_dir()
1667+ self.cache.update()
1668+ return self
1669+
1670+ def _set_dir(self):
1671+ try:
1672+ username = pwd.getpwuid(os.getuid()).pw_name
1673+ except KeyError:
1674+ pass
1675+ else:
1676+ self.apt_pkg.config.set("APT::Sandbox::User", username)
1677+ self.apt_pkg.config.set("Dir", self._rootdir)
1678+
1679+ def __exit__(self, exc_tp, exc_val, exc_tb):
1680+ shutil.rmtree(self._rootdir)
1681+ return False
1682+
1683+ @classmethod
1684+ def from_string(cls, text, key_path=None):
1685+ (mirror_uri, distribution, rest) = text.split(" ", 2)
1686+ return cls(mirror_uri, distribution, rest.split(), key_path=key_path)
1687
1688=== added file 'breezy/plugins/debian/builder.py'
1689--- breezy/plugins/debian/builder.py 1970-01-01 00:00:00 +0000
1690+++ breezy/plugins/debian/builder.py 2024-02-18 23:22:42 +0000
1691@@ -0,0 +1,142 @@
1692+# builder.py -- Classes for building packages
1693+# Copyright (C) 2006, 2007 James Westby <jw+debian@jameswestby.net>
1694+#
1695+# This file is part of breezy-debian.
1696+#
1697+# bzr-builddeb is free software; you can redistribute it and/or modify
1698+# it under the terms of the GNU General Public License as published by
1699+# the Free Software Foundation; either version 2 of the License, or
1700+# (at your option) any later version.
1701+#
1702+# bzr-builddeb is distributed in the hope that it will be useful,
1703+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1704+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1705+# GNU General Public License for more details.
1706+#
1707+# You should have received a copy of the GNU General Public License
1708+# along with bzr-builddeb; if not, write to the Free Software
1709+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1710+#
1711+
1712+import os
1713+import shutil
1714+import subprocess
1715+import tempfile
1716+
1717+from ...errors import BzrError
1718+from ...trace import note
1719+from .hooks import run_hook
1720+from .util import (
1721+ dget_changes,
1722+ find_changes_files,
1723+ get_parent_dir,
1724+ subprocess_setup,
1725+)
1726+
1727+
1728+class ChangesFileMissing(BzrError):
1729+ _fmt = "Missing changes file."
1730+
1731+
1732+class NoSourceDirError(BzrError):
1733+ _fmt = (
1734+ "There is no existing source directory to use. Use "
1735+ "--export-only or --dont-purge to get one that can be used"
1736+ )
1737+
1738+
1739+class BuildFailedError(BzrError):
1740+ _fmt = "The build failed."
1741+
1742+
1743+class DebBuild:
1744+ """The object that does the building work."""
1745+
1746+ def __init__(self, distiller, target_dir, builder, use_existing=False):
1747+ """Create a builder.
1748+
1749+ :param distiller: the SourceDistiller that will get the source to
1750+ build.
1751+ :param target_dir: the directory in which to do all the work.
1752+ :param builder: the build command to use.
1753+ :param use_existing: whether to re-use the target_dir if it exists.
1754+ """
1755+ self.distiller = distiller
1756+ self.target_dir = target_dir
1757+ self.builder = builder
1758+ self.use_existing = use_existing
1759+
1760+ def prepare(self):
1761+ """Do any preparatory steps that should be run before the build.
1762+
1763+ It checks that everything is well, and that some needed dirs are
1764+ created.
1765+ """
1766+ parent_dir = get_parent_dir(self.target_dir)
1767+ if parent_dir != "" and not os.path.exists(parent_dir):
1768+ os.makedirs(parent_dir)
1769+ if os.path.exists(self.target_dir):
1770+ if not self.use_existing:
1771+ note("Purging the build dir: %s", self.target_dir)
1772+ shutil.rmtree(self.target_dir)
1773+ else:
1774+ note("Not purging build dir as requested: %s", self.target_dir)
1775+ else:
1776+ if self.use_existing:
1777+ raise NoSourceDirError
1778+
1779+ def export(self):
1780+ self.distiller.distill(self.target_dir)
1781+
1782+ def before_build(self):
1783+ subprocess.check_call(
1784+ ["dpkg-source", "--before-build", self.target_dir], # noqa: S607
1785+ preexec_fn=subprocess_setup,
1786+ )
1787+
1788+ def after_build(self):
1789+ subprocess.check_call(
1790+ ["dpkg-source", "--after-build", self.target_dir], # noqa: S607
1791+ preexec_fn=subprocess_setup,
1792+ )
1793+
1794+ def build(self):
1795+ """This builds the package using the supplied command."""
1796+ note("Building the package in %s, using %s", self.target_dir, self.builder)
1797+ proc = subprocess.Popen(
1798+ self.builder, shell=True, cwd=self.target_dir, preexec_fn=subprocess_setup
1799+ )
1800+ proc.wait()
1801+ if proc.returncode != 0:
1802+ raise BuildFailedError
1803+
1804+ def clean(self):
1805+ """This removes the build directory."""
1806+ note("Cleaning build dir: %s", self.target_dir)
1807+ shutil.rmtree(self.target_dir)
1808+
1809+
1810+def do_build(
1811+ package_name, version, distiller, local_tree, config, build_command, target_dir=None
1812+):
1813+ """Actually run a build."""
1814+ with tempfile.TemporaryDirectory() as bd:
1815+ build_source_dir = os.path.join(
1816+ bd, package_name + "-" + version.upstream_version
1817+ )
1818+ builder = DebBuild(
1819+ distiller, build_source_dir, build_command, use_existing=False
1820+ )
1821+ builder.prepare()
1822+ run_hook(local_tree, "pre-export", config)
1823+ builder.export()
1824+ run_hook(local_tree, "pre-build", config, wd=build_source_dir)
1825+ builder.build()
1826+ run_hook(local_tree, "post-build", config, wd=build_source_dir)
1827+ if target_dir is not None:
1828+ ret = {}
1829+ for kind, entry in find_changes_files(bd, package_name, version):
1830+ ret[kind] = dget_changes(entry.path, target_dir)
1831+ if not ret:
1832+ raise ChangesFileMissing()
1833+ return ret
1834
1835=== added file 'breezy/plugins/debian/byov.conf'
1836--- breezy/plugins/debian/byov.conf 1970-01-01 00:00:00 +0000
1837+++ breezy/plugins/debian/byov.conf 2024-02-18 23:22:42 +0000
1838@@ -0,0 +1,21 @@
1839+# Use lxd containers by default
1840+vm.class = lxd
1841+# Start with an up to date system by default
1842+vm.update = True
1843+# External sources dependencies, packages are not recent enough
1844+dulwich.clone = (git clone git://jelmer.uk/dulwich ../dulwich.git)
1845+dulwich.install = (cd ../dulwich.git && ./setup.py install --user)
1846+dulwich3.install = (cd ../dulwich.git && python3 ./setup.py install --user)
1847+
1848+[brz-plugin-debian]
1849+vm.release = xenial
1850+brz.build_deps = gcc, debhelper, python, python-all-dev, python3-all-dev, python-configobj, python3-configobj, python-docutils, python3-docutils, python-paramiko, python3-paramiko, python-subunit, python3-subunit, python-testtools, python3-testtools, subunit, cython, cython3, python-fastimport, python-dulwich
1851+debian.build_deps = python-debian, python-apt, dpkg-dev, fakeroot, devscripts, patchutils, pristine-tar, quilt, python-lzma, libalgorithm-merge-perl, python-yaml, python-distro-info, python3-distro-info, python3-apt, python3-yaml, python3-debian
1852+vm.packages = {brz.build_deps}, {debian.build_deps}, {debian.test_deps}, bzr, python-debian, python-junitxml
1853+brz.branch = (bzr branch lp:brz ../brz-trunk)
1854+brz.make = (cd ../brz-trunk && make)
1855+byoci.setup.command = ({dulwich.clone} && {dulwich.install} && {brz.branch} && {brz.make})
1856+byoci.tests.command = bash -o pipefail -c "bzr log -l2 && (BRZ_PLUGINS_AT=debian@`pwd` BRZ_PLUGIN_PATH=-site:-user python2 ../brz-trunk/brz selftest -v --parallel=fork --subunit2 | subunit2junitxml -o ../results.xml -f | subunit2pyunit)"
1857+[brz-plugin-debian-py3]
1858+byoci.setup.command = ({dulwich.clone} && {dulwich3.install} && {brz.branch} && {brz.make})
1859+byoci.tests.command = bash -o pipefail -c "bzr log -l2 && (BRZ_PLUGINS_AT=debian@`pwd` BRZ_PLUGIN_PATH=-site:-user python3 ../brz-trunk/brz selftest -v --parallel=fork --subunit2 | subunit2junitxml -o ../results.xml -f | subunit2pyunit)"
1860
1861=== added file 'breezy/plugins/debian/bzrtools_import.py'
1862--- breezy/plugins/debian/bzrtools_import.py 1970-01-01 00:00:00 +0000
1863+++ breezy/plugins/debian/bzrtools_import.py 2024-02-18 23:22:42 +0000
1864@@ -0,0 +1,241 @@
1865+# This file is a modified copy of bzrtools' upstream_import.py, last changed in
1866+# bzrtools 1.14.0.
1867+
1868+"""Import upstream source into a branch."""
1869+
1870+import tarfile
1871+from contextlib import ExitStack
1872+from io import BytesIO
1873+
1874+from ...bzr import generate_ids
1875+from ...errors import BzrError
1876+from ...osutils import (
1877+ basename,
1878+ file_iterator,
1879+ is_inside_any,
1880+ normpath,
1881+ splitpath,
1882+)
1883+from ...trace import warning
1884+from ...transform import resolve_conflicts
1885+from ...upstream_import import (
1886+ DirWrapper,
1887+ add_implied_parents,
1888+ common_directory,
1889+ do_directory,
1890+ names_of_files,
1891+)
1892+from ...workingtree import WorkingTree
1893+
1894+
1895+class UnknownType(BzrError):
1896+ _fmt = 'Cannot extract "%(path)s" from archive as it is an unknown type.'
1897+
1898+ def __init__(self, path):
1899+ BzrError.__init__(self, path=path)
1900+
1901+
1902+files_to_ignore = {".shelf", ".bzr", ".bzr.backup", ".bzrtags", ".bzr-builddeb"}
1903+
1904+
1905+def should_ignore(relative_path: str) -> bool:
1906+ parts = splitpath(relative_path)
1907+ if not parts:
1908+ return False
1909+ for part in parts:
1910+ if part in files_to_ignore:
1911+ return True
1912+ if part.endswith(",v"):
1913+ return True
1914+ return False
1915+
1916+
1917+def import_dir(
1918+ tree: WorkingTree, dir: str, file_ids_from=None, target_tree=None, exclude=None
1919+):
1920+ dir_input = BytesIO(dir.encode("utf-8"))
1921+ dir_input.seek(0)
1922+ dir_file = DirWrapper(dir_input)
1923+ if file_ids_from is None:
1924+ file_ids_from = []
1925+ with ExitStack() as es:
1926+ for other_tree in file_ids_from:
1927+ es.enter_context(other_tree.lock_read())
1928+ return _import_archive(
1929+ tree,
1930+ dir_file, # type: ignore
1931+ file_ids_from,
1932+ target_tree=target_tree,
1933+ exclude=exclude, # type: ignore
1934+ )
1935+
1936+
1937+def _get_paths_to_process(
1938+ archive_file: tarfile.TarFile, prefix, implied_parents, exclude=None
1939+):
1940+ to_process = set()
1941+ for member in archive_file.getmembers(): # type: ignore
1942+ if member.type == "g":
1943+ # type 'g' is a header
1944+ continue
1945+ relative_path = member.name
1946+ relative_path = normpath(relative_path)
1947+ relative_path = relative_path.lstrip("/")
1948+ if prefix is not None:
1949+ relative_path = relative_path[len(prefix) + 1 :]
1950+ relative_path = relative_path.rstrip("/")
1951+ if relative_path == "" or relative_path == ".":
1952+ continue
1953+ if should_ignore(relative_path):
1954+ continue
1955+ if exclude and is_inside_any(exclude, relative_path):
1956+ continue
1957+ add_implied_parents(implied_parents, relative_path)
1958+ to_process.add((relative_path, member))
1959+ return to_process
1960+
1961+
1962+def _import_archive(
1963+ tree: WorkingTree,
1964+ archive_file: tarfile.TarFile,
1965+ file_ids_from,
1966+ target_tree=None,
1967+ exclude=None,
1968+):
1969+ prefix = common_directory(names_of_files(archive_file))
1970+ with tree.transform() as tt:
1971+ removed = set()
1972+ for path, entry in tree.iter_entries_by_dir():
1973+ if entry.parent_id is None:
1974+ continue
1975+ trans_id = tt.trans_id_tree_path(path)
1976+ tt.delete_contents(trans_id)
1977+ removed.add(path)
1978+
1979+ added = set()
1980+ implied_parents: set[str] = set()
1981+ seen = set()
1982+ to_process = _get_paths_to_process(
1983+ archive_file, prefix, implied_parents, exclude=exclude
1984+ )
1985+ renames = {}
1986+
1987+ if not tree.supports_setting_file_ids():
1988+ file_ids_from = []
1989+
1990+ # First we find the renames
1991+ other_trees = file_ids_from[:]
1992+ if target_tree is not None and tree.supports_setting_file_ids():
1993+ other_trees.insert(0, target_tree)
1994+ for other_tree in other_trees:
1995+ for relative_path, _member in to_process:
1996+ trans_id = tt.trans_id_tree_path(relative_path)
1997+ existing_file_id = tt.tree_file_id(trans_id)
1998+ target_id = other_tree.path2id(relative_path)
1999+ if (
2000+ target_id is not None
2001+ and target_id != existing_file_id
2002+ and target_id not in renames
2003+ ):
2004+ renames[target_id] = relative_path
2005+
2006+ # The we do the work
2007+ for relative_path, member in to_process:
2008+ trans_id = tt.trans_id_tree_path(relative_path)
2009+ added.add(relative_path.rstrip("/"))
2010+ # To handle renames, we need to not use the preserved file id,
2011+ # rather we need to lookup the file id in target_tree, if there is
2012+ # one. If there isn't, we should use the one in the current tree,
2013+ # and failing that we will allocate one. In this importer we want
2014+ # the target_tree to be authoritative about id2path, which is why
2015+ # we consult it first.
2016+ if tree.supports_setting_file_ids():
2017+ existing_file_id = tt.tree_file_id(trans_id)
2018+ # If we find an id that we know we are going to assign to
2019+ # different path as it has been renamed in one of the
2020+ # file_ids_from trees then we ignore the one in this tree.
2021+ if existing_file_id in renames:
2022+ if relative_path != renames[existing_file_id]:
2023+ existing_file_id = None
2024+ found_file_id = None
2025+ if target_tree is not None:
2026+ found_file_id = target_tree.path2id(relative_path)
2027+ if found_file_id in renames:
2028+ if renames[found_file_id] != relative_path:
2029+ found_file_id = None
2030+ if found_file_id is None and existing_file_id is None:
2031+ for other_tree in file_ids_from:
2032+ found_file_id = other_tree.path2id(relative_path)
2033+ if found_file_id is not None:
2034+ if found_file_id in renames:
2035+ if renames[found_file_id] != relative_path:
2036+ found_file_id = None
2037+ continue
2038+ break
2039+ if found_file_id is not None and found_file_id != existing_file_id:
2040+ # Found a specific file id in one of the source trees
2041+ tt.version_file(trans_id=trans_id, file_id=found_file_id)
2042+ if existing_file_id is not None:
2043+ # We need to remove the existing file so it can be
2044+ # replaced by the file (and file id) from the
2045+ # file_ids_from tree.
2046+ tt.delete_versioned(trans_id)
2047+ trans_id = tt.trans_id_file_id(found_file_id)
2048+ if not found_file_id and not existing_file_id:
2049+ # No file_id in any of the source trees and no file id in
2050+ # the base tree.
2051+ name = basename(member.name.rstrip("/"))
2052+ file_id = generate_ids.gen_file_id(name)
2053+ tt.version_file(file_id=file_id, trans_id=trans_id)
2054+ else:
2055+ tt.version_file(trans_id=trans_id)
2056+
2057+ path = tree.abspath(relative_path)
2058+ if member.name in seen:
2059+ if tt.final_kind(trans_id) == "file":
2060+ tt.set_executability(None, trans_id)
2061+ tt.cancel_creation(trans_id)
2062+ seen.add(member.name)
2063+ if member.isreg():
2064+ tt.create_file(
2065+ file_iterator(archive_file.extractfile(member)), trans_id
2066+ )
2067+ executable = (member.mode & 0o111) != 0
2068+ tt.set_executability(executable, trans_id)
2069+ elif member.isdir():
2070+ do_directory(tt, trans_id, tree, relative_path, path)
2071+ elif member.issym():
2072+ tt.create_symlink(member.linkname, trans_id)
2073+ else:
2074+ raise UnknownType(relative_path)
2075+
2076+ for relative_path in implied_parents.difference(added):
2077+ if relative_path == "":
2078+ continue
2079+ trans_id = tt.trans_id_tree_path(relative_path)
2080+ path = tree.abspath(relative_path)
2081+ do_directory(tt, trans_id, tree, relative_path, path)
2082+ if tt.tree_file_id(trans_id) is None:
2083+ found = False
2084+ for other_tree in file_ids_from:
2085+ with other_tree.lock_read():
2086+ if other_tree.has_filename(relative_path):
2087+ file_id = other_tree.path2id(relative_path)
2088+ if file_id is not None:
2089+ tt.version_file(trans_id=trans_id, file_id=file_id)
2090+ found = True
2091+ break
2092+ if not found:
2093+ # Should this really use the trans_id as the
2094+ # file_id?
2095+ tt.version_file(trans_id=trans_id, file_id=trans_id)
2096+ added.add(relative_path)
2097+
2098+ for path in removed.difference(added):
2099+ tt.unversion_file(tt.trans_id_tree_path(path))
2100+
2101+ conflicts = tt.cook_conflicts(resolve_conflicts(tt))
2102+
2103+ for conflict in conflicts:
2104+ warning("%s", conflict)
2105+ tt.apply()
2106
2107=== added file 'breezy/plugins/debian/changelog.py'
2108--- breezy/plugins/debian/changelog.py 1970-01-01 00:00:00 +0000
2109+++ breezy/plugins/debian/changelog.py 2024-02-18 23:22:42 +0000
2110@@ -0,0 +1,124 @@
2111+# __init__.py -- The plugin for bzr
2112+# Copyright (C) 2009-2018 Jelmer Vernooij <jelmer@jelmer.uk
2113+#
2114+# This file is part of brz-debian.
2115+#
2116+# brz-debian is free software; you can redistribute it and/or modify
2117+# it under the terms of the GNU General Public License as published by
2118+# the Free Software Foundation; either version 2 of the License, or
2119+# (at your option) any later version.
2120+#
2121+# brz-debian is distributed in the hope that it will be useful,
2122+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2123+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2124+# GNU General Public License for more details.
2125+#
2126+# You should have received a copy of the GNU General Public License
2127+# along with brz-debian; if not, write to the Free Software
2128+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2129+#
2130+
2131+import posixpath
2132+from typing import Optional
2133+
2134+from debian.changelog import Changelog
2135+from debmutate.changelog import new_changelog_entries, strip_changelog_message
2136+
2137+from breezy.errors import BzrError
2138+from breezy.tree import Tree
2139+
2140+from . import tree_debian_tag_name
2141+
2142+
2143+class UnreleasedChanges(BzrError):
2144+ _fmt = "%(path)s says it's UNRELEASED."
2145+
2146+ def __init__(self, path):
2147+ BzrError.__init__(self)
2148+ self.path = path
2149+
2150+
2151+def changelog_changes(
2152+ tree: Tree, basis_tree: Tree, cl_path: str = "debian/changelog"
2153+) -> Optional[list[str]]:
2154+ changes = []
2155+ for change in tree.iter_changes(basis_tree, specific_files=[cl_path]):
2156+ paths = change.path
2157+ changed_content = change.changed_content
2158+ versioned = change.versioned
2159+ kind = change.kind
2160+ # Content not changed
2161+ if not changed_content:
2162+ return None
2163+ # Not versioned in new tree
2164+ if not versioned[1]:
2165+ return None
2166+ # Not a file in one tree
2167+ if kind[0] != "file" or kind[1] != "file":
2168+ return None
2169+
2170+ old_text = basis_tree.get_file_lines(paths[0])
2171+ new_text = tree.get_file_lines(paths[1])
2172+ changes.extend(new_changelog_entries(old_text, new_text))
2173+ return changes
2174+
2175+
2176+def changelog_commit_message(
2177+ tree: Tree, basis_tree: Tree, path: str = "debian/changelog"
2178+) -> Optional[str]:
2179+ changes = changelog_changes(tree, basis_tree, path)
2180+ if not changes:
2181+ return None
2182+
2183+ return "".join(strip_changelog_message(changes))
2184+
2185+
2186+def debcommit(
2187+ tree, committer=None, subpath="", paths=None, reporter=None, message=None
2188+):
2189+ """Create a git commit with message based on the new entries in changelog.
2190+
2191+ Args:
2192+ tree: Tree to commit in
2193+ committer: Optional committer identity
2194+ subpath: subpath to commit in
2195+ paths: specifics paths to commit, if any
2196+ reporter: CommitReporter to use
2197+ message: Override commit message
2198+ Returns:
2199+ Created revision id
2200+ """
2201+ if message is None:
2202+ message = changelog_commit_message(
2203+ tree, tree.basis_tree(), path=posixpath.join(subpath, "debian/changelog")
2204+ )
2205+ if paths:
2206+ specific_files = [posixpath.join(subpath, p) for p in paths]
2207+ elif subpath:
2208+ specific_files = [subpath]
2209+ else:
2210+ specific_files = None
2211+ return tree.commit(
2212+ committer=committer,
2213+ message=message,
2214+ specific_files=specific_files,
2215+ reporter=reporter,
2216+ )
2217+
2218+
2219+def debcommit_release(tree, committer=None, subpath="", message=None, vendor=None):
2220+ cl_path = posixpath.join(subpath, "debian/changelog")
2221+ if message is None or vendor is None:
2222+ cl = Changelog(tree.get_file(cl_path), max_blocks=1)
2223+ if message is None:
2224+ message = f"releasing package {cl[0].package} version {cl[0].version}"
2225+ if vendor is None:
2226+ from .util import suite_to_distribution
2227+
2228+ vendor = suite_to_distribution(cl[0].distributions)
2229+ tag_name = tree_debian_tag_name(tree, tree.branch, subpath=subpath, vendor=vendor)
2230+ if tag_name is None:
2231+ raise UnreleasedChanges(cl_path)
2232+ revid = tree.commit(committer=committer, message=message)
2233+ tree.branch.tags.set_tag(tag_name, revid)
2234+ return tag_name
2235
2236=== added file 'breezy/plugins/debian/cmds.py'
2237--- breezy/plugins/debian/cmds.py 1970-01-01 00:00:00 +0000
2238+++ breezy/plugins/debian/cmds.py 2024-02-18 23:22:42 +0000
2239@@ -0,0 +1,2021 @@
2240+# __init__.py -- The plugin for bzr
2241+# Copyright (C) 2005 Jamie Wilkinson <jaq@debian.org>
2242+# 2006, 2007 James Westby <jw+debian@jameswestby.net>
2243+# 2007 Reinhard Tartler <siretart@tauware.de>
2244+# 2008-2011 Canonical Ltd.
2245+#
2246+# This file is part of breezy-debian.
2247+#
2248+# bzr-builddeb is free software; you can redistribute it and/or modify
2249+# it under the terms of the GNU General Public License as published by
2250+# the Free Software Foundation; either version 2 of the License, or
2251+# (at your option) any later version.
2252+#
2253+# bzr-builddeb is distributed in the hope that it will be useful,
2254+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2255+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2256+# GNU General Public License for more details.
2257+#
2258+# You should have received a copy of the GNU General Public License
2259+# along with bzr-builddeb; if not, write to the Free Software
2260+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2261+#
2262+
2263+import os
2264+import shutil
2265+import tempfile
2266+from typing import Callable, Optional
2267+
2268+from ... import (
2269+ urlutils,
2270+)
2271+from ...branch import Branch
2272+from ...commands import Command
2273+from ...controldir import (
2274+ ControlDir,
2275+ NoColocatedBranchSupport,
2276+)
2277+from ...errors import (
2278+ BzrCommandError,
2279+ NotBranchError,
2280+ NotLocalUrl,
2281+ NoWorkingTree,
2282+)
2283+from ...option import Option
2284+from ...trace import mutter, note, warning
2285+from ...transport import (
2286+ FileExists,
2287+ NoSuchFile,
2288+ get_transport,
2289+)
2290+from ...workingtree import WorkingTree
2291+from . import (
2292+ default_build_dir,
2293+ default_orig_dir,
2294+ default_result_dir,
2295+ gettext,
2296+)
2297+from .config import (
2298+ BUILD_TYPE_MERGE,
2299+ BUILD_TYPE_NATIVE,
2300+ BUILD_TYPE_SPLIT,
2301+)
2302+from .util import (
2303+ debuild_config,
2304+)
2305+
2306+dont_purge_opt = Option(
2307+ "dont-purge", help="Don't purge the build directory after building."
2308+)
2309+result_opt = Option(
2310+ "result-dir",
2311+ help="Directory in which to place the resulting package files.",
2312+ type=str,
2313+ argname="DIRECTORY",
2314+)
2315+builder_opt = Option(
2316+ "builder", help="Command to build the package.", type=str, argname="BUILDER"
2317+)
2318+merge_opt = Option(
2319+ "merge", help="Merge the debian part of the source in to the upstream tarball."
2320+)
2321+split_opt = Option(
2322+ "split", help="Automatically create an .orig.tar.gz from a full source branch."
2323+)
2324+build_dir_opt = Option("build-dir", help="The dir to use for building.", type=str)
2325+orig_dir_opt = Option(
2326+ "orig-dir",
2327+ help="Directory containing the .orig.tar.gz files. For use when only "
2328+ "debian/ is versioned.",
2329+ type=str,
2330+ argname="DIRECTORY",
2331+)
2332+native_opt = Option("native", help="Build a native package.")
2333+export_upstream_opt = Option(
2334+ "export-upstream",
2335+ help="Create the .orig.tar.gz from specified bzr branch before building.",
2336+ type=str,
2337+ argname="BRANCH",
2338+)
2339+export_upstream_revision_opt = Option(
2340+ "export-upstream-revision",
2341+ help="Select the upstream revision that will be exported.",
2342+ type=str,
2343+ argname="REVISION",
2344+)
2345+apt_repository_opts = [
2346+ Option("apt-repository", help="Apt repository to attempt to fetch from", type=str),
2347+ Option(
2348+ "apt-repository-key", help="Apt repository key to use for validation", type=str
2349+ ),
2350+]
2351+
2352+
2353+class StrictBuildFailed(BzrCommandError):
2354+ _fmt = (
2355+ "Build refused because there are unknown files in the tree. "
2356+ "To list all known files, run 'bzr unknowns'."
2357+ )
2358+
2359+
2360+def _check_tree(tree, subpath, strict=False):
2361+ if strict:
2362+ for _unknown in tree.unknowns():
2363+ raise StrictBuildFailed()
2364+
2365+ if len(tree.conflicts()) > 0:
2366+ raise BzrCommandError(
2367+ "There are conflicts in the working tree. "
2368+ "You must resolve these before building."
2369+ )
2370+
2371+
2372+def _check_uncommitted(tree, subpath):
2373+ if tree.changes_from(tree.basis_tree()).has_changed():
2374+ raise BzrCommandError(
2375+ gettext(
2376+ "There are uncommitted "
2377+ "changes in the working tree. You must commit "
2378+ "before using this command"
2379+ )
2380+ )
2381+
2382+
2383+def _get_changelog_info(
2384+ tree, subpath, last_version=None, package=None, distribution=None
2385+):
2386+ from .util import (
2387+ MissingChangelogError,
2388+ find_changelog,
2389+ find_last_distribution,
2390+ lookup_distribution,
2391+ )
2392+
2393+ DEFAULT_FALLBACK_DISTRIBUTION = "debian"
2394+ current_version = last_version
2395+ try:
2396+ (changelog, top_level) = find_changelog(
2397+ tree, subpath, merge=False, max_blocks=2
2398+ )
2399+ except MissingChangelogError:
2400+ top_level = False
2401+ changelog = None
2402+ if distribution is None:
2403+ distribution = DEFAULT_FALLBACK_DISTRIBUTION
2404+ note(
2405+ gettext(
2406+ "No distribution specified, and no changelog, " "assuming '%s'"
2407+ ),
2408+ distribution,
2409+ )
2410+ else:
2411+ if last_version is None:
2412+ current_version = changelog.version.upstream_version
2413+ if package is None:
2414+ package = changelog.package
2415+ if distribution is None:
2416+ distribution = find_last_distribution(changelog)
2417+ if distribution is not None:
2418+ note(gettext("Using distribution %s") % distribution)
2419+ else:
2420+ distribution = DEFAULT_FALLBACK_DISTRIBUTION
2421+ note(
2422+ gettext(
2423+ "No distribution specified, and no previous "
2424+ "distribution in changelog. Assuming '%s'"
2425+ ),
2426+ distribution,
2427+ )
2428+ distribution = distribution.lower()
2429+ distribution_name = lookup_distribution(distribution)
2430+ if distribution_name is None:
2431+ raise BzrCommandError(gettext("Unknown target distribution: %s") % distribution)
2432+ return (
2433+ current_version,
2434+ package,
2435+ distribution,
2436+ distribution_name,
2437+ changelog,
2438+ top_level,
2439+ )
2440+
2441+
2442+def _get_upstream_branch_source(
2443+ export_upstream,
2444+ export_upstream_revision,
2445+ config,
2446+ version,
2447+ other_repository=None,
2448+ guess_upstream_url=None,
2449+):
2450+ if export_upstream is None and config.upstream_branch:
2451+ export_upstream = config.upstream_branch
2452+ if export_upstream is None:
2453+ if guess_upstream_url is None:
2454+ return None
2455+ export_upstream = guess_upstream_url
2456+ from .upstream.branch import (
2457+ LazyUpstreamBranchSource,
2458+ )
2459+
2460+ upstream_revision_map = {}
2461+ if export_upstream_revision:
2462+ upstream_revision_map[version] = export_upstream_revision
2463+ return LazyUpstreamBranchSource(
2464+ export_upstream,
2465+ config=config,
2466+ upstream_revision_map=upstream_revision_map,
2467+ other_repository=other_repository,
2468+ )
2469+
2470+
2471+def _get_upstream_sources(
2472+ local_tree,
2473+ subpath,
2474+ packaging_branch,
2475+ build_type,
2476+ config,
2477+ upstream_version,
2478+ top_level,
2479+ export_upstream=None,
2480+ export_upstream_revision=None,
2481+ trust_package=True,
2482+ guess_upstream_branch_url=False,
2483+ apt=None,
2484+ skip_signatures=False,
2485+):
2486+ from .upstream import (
2487+ AptSource,
2488+ DirectoryScanSource,
2489+ SelfSplitSource,
2490+ )
2491+ from .upstream.pristinetar import (
2492+ get_pristine_tar_source,
2493+ )
2494+ from .upstream.uscan import (
2495+ NoWatchFile,
2496+ UScanSource,
2497+ )
2498+
2499+ yield AptSource(apt=apt)
2500+ yield get_pristine_tar_source(local_tree, packaging_branch)
2501+ try:
2502+ yield UScanSource.from_tree(
2503+ local_tree, subpath, top_level, skip_signatures=skip_signatures
2504+ )
2505+ except NoWatchFile:
2506+ pass
2507+
2508+ if guess_upstream_branch_url:
2509+ try:
2510+ from upstream_ontologist.guess import (
2511+ guess_upstream_metadata,
2512+ )
2513+ except ModuleNotFoundError:
2514+ guess_upstream_url = None
2515+ else:
2516+
2517+ def guess_upstream_url():
2518+ guessed_upstream_metadata = guess_upstream_metadata(
2519+ local_tree.abspath(subpath),
2520+ trust_package=trust_package,
2521+ net_access=True,
2522+ consult_external_directory=False,
2523+ )
2524+ return guessed_upstream_metadata.get("Repository")
2525+ else:
2526+ guess_upstream_url = None
2527+
2528+ upstream_branch_source = _get_upstream_branch_source(
2529+ export_upstream,
2530+ export_upstream_revision,
2531+ config,
2532+ upstream_version,
2533+ other_repository=packaging_branch.repository,
2534+ guess_upstream_url=guess_upstream_url,
2535+ )
2536+ if upstream_branch_source:
2537+ yield upstream_branch_source
2538+
2539+ if build_type == BUILD_TYPE_SPLIT:
2540+ yield SelfSplitSource(local_tree)
2541+
2542+ yield DirectoryScanSource("..")
2543+
2544+
2545+def _get_distiller(
2546+ tree,
2547+ subpath,
2548+ packaging_branch,
2549+ changelog,
2550+ build_type,
2551+ config,
2552+ contains_upstream_source=True,
2553+ top_level=False,
2554+ orig_dir=default_orig_dir,
2555+ use_existing=False,
2556+ export_upstream=None,
2557+ export_upstream_revision=None,
2558+ guess_upstream_branch_url=False,
2559+ apt=None,
2560+ skip_signatures=False,
2561+):
2562+ from .source_distiller import (
2563+ DebcargoDistiller,
2564+ FullSourceDistiller,
2565+ MergeModeDistiller,
2566+ NativeSourceDistiller,
2567+ )
2568+ from .upstream import (
2569+ UpstreamProvider,
2570+ )
2571+ from .util import (
2572+ guess_build_type,
2573+ )
2574+
2575+ if build_type is None:
2576+ build_type = config.build_type
2577+ if build_type is None:
2578+ build_type = guess_build_type(
2579+ tree, changelog.version, subpath, contains_upstream_source
2580+ )
2581+
2582+ note(gettext("Building package in %s mode") % build_type)
2583+
2584+ upstream_sources = list(
2585+ _get_upstream_sources(
2586+ tree,
2587+ subpath,
2588+ packaging_branch,
2589+ build_type=build_type,
2590+ config=config,
2591+ upstream_version=changelog.version.upstream_version,
2592+ top_level=top_level,
2593+ export_upstream=export_upstream,
2594+ export_upstream_revision=export_upstream_revision,
2595+ guess_upstream_branch_url=guess_upstream_branch_url,
2596+ apt=apt,
2597+ skip_signatures=skip_signatures,
2598+ )
2599+ )
2600+
2601+ upstream_provider = UpstreamProvider(
2602+ changelog.package,
2603+ changelog.version.upstream_version,
2604+ orig_dir,
2605+ upstream_sources,
2606+ )
2607+
2608+ # Turn this into a build type?
2609+ if tree.has_filename(os.path.join(subpath, "debian/debcargo.toml")):
2610+ return DebcargoDistiller(
2611+ tree, subpath, top_level=top_level, use_existing=use_existing
2612+ )
2613+ if build_type == BUILD_TYPE_MERGE:
2614+ return MergeModeDistiller(
2615+ tree,
2616+ subpath,
2617+ upstream_provider,
2618+ top_level=top_level,
2619+ use_existing=use_existing,
2620+ )
2621+ elif build_type == BUILD_TYPE_NATIVE:
2622+ return NativeSourceDistiller(tree, subpath, use_existing=use_existing)
2623+ else:
2624+ return FullSourceDistiller(
2625+ tree, subpath, upstream_provider, use_existing=use_existing
2626+ )
2627+
2628+
2629+class cmd_builddeb(Command):
2630+ """Builds a Debian package from a branch.
2631+
2632+ If BRANCH is specified it is assumed that the branch you wish to build is
2633+ located there. If it is not specified then the current directory is used.
2634+
2635+ By default, if a working tree is found, it is used to build. Otherwise the
2636+ last committed revision found in the branch is used. To force building the
2637+ last committed revision use --revision -1. You can also specify any other
2638+ revision with the --revision option.
2639+
2640+ If you only wish to export the package, and not build it (especially useful
2641+ for merge mode), use --export-only.
2642+
2643+ To leave the build directory when the build is completed use --dont-purge.
2644+
2645+ Specify the command to use when building using the --builder option, by
2646+ default "debuild" is used. It can be overriden by setting the "builder"
2647+ variable in you configuration. You can specify extra options to build with
2648+ by adding them to the end of the command, after using "--" to indicate the
2649+ end of the options to builddeb itself. The builder that you specify must
2650+ accept the options you provide at the end of its command line.
2651+
2652+ You can also specify directories to use for different things. --build-dir
2653+ is the directory to build the packages beneath, which defaults to
2654+ '../build-area'. '--orig-dir' specifies the directory that contains the
2655+ .orig.tar.gz files , which defaults to '..'. '--result-dir' specifies where
2656+ the resulting package files should be placed, which defaults to '..'.
2657+ --result-dir will have problems if you use a build command that places
2658+ the results in a different directory.
2659+
2660+ The --reuse option will be useful if you are in merge mode, and the
2661+ upstream tarball is very large. It attempts to reuse a build directory from
2662+ an earlier build. It will fail if one doesn't exist, but you can create one
2663+ by using --export-only.
2664+
2665+ --quick allows you to define a quick-builder in your configuration files,
2666+ which will be used when this option is passed. It defaults to 'fakeroot
2667+ debian/rules binary'. It is overriden if --builder is passed. Using this
2668+ and --reuse allows for fast rebuilds.
2669+ """
2670+
2671+ export_only_opt = Option(
2672+ "export-only", help="Export only, don't build.", short_name="e"
2673+ )
2674+ use_existing_opt = Option("use-existing", help="Use an existing build directory.")
2675+ quick_opt = Option(
2676+ "quick",
2677+ help="Quickly build the package, uses "
2678+ 'quick-builder, which defaults to "fakeroot '
2679+ 'debian/rules binary".',
2680+ )
2681+ reuse_opt = Option(
2682+ "reuse",
2683+ help="Try to avoid exporting too much on each "
2684+ "build. Only works in merge mode; it saves unpacking "
2685+ "the upstream tarball each time. Implies --dont-purge "
2686+ "and --use-existing.",
2687+ )
2688+ source_opt = Option("source", help="Build a source package.", short_name="S")
2689+ strict_opt = Option(
2690+ "strict",
2691+ help="Refuse to build if there are unknown files in"
2692+ " the working tree, --no-strict disables the check.",
2693+ )
2694+ package_merge_opt = Option(
2695+ "package-merge",
2696+ help="Build using the "
2697+ "appropriate -v and -sa options for merging in the changes from "
2698+ "another source.",
2699+ )
2700+ guess_upstream_branch_url_opt = Option(
2701+ "guess-upstream-branch-url",
2702+ help=("Guess upstream branch URL if unknown " "(requires upstream-ontologist)"),
2703+ )
2704+ takes_args = ["branch_or_build_options*"]
2705+ aliases = ["bd", "debuild"]
2706+ takes_options = [ # type: ignore
2707+ export_only_opt,
2708+ dont_purge_opt,
2709+ use_existing_opt,
2710+ result_opt,
2711+ builder_opt,
2712+ merge_opt,
2713+ build_dir_opt,
2714+ orig_dir_opt,
2715+ split_opt,
2716+ export_upstream_opt,
2717+ export_upstream_revision_opt,
2718+ quick_opt,
2719+ reuse_opt,
2720+ native_opt,
2721+ source_opt,
2722+ "revision",
2723+ strict_opt,
2724+ package_merge_opt,
2725+ guess_upstream_branch_url_opt,
2726+ ] + apt_repository_opts
2727+
2728+ def _get_tree_and_branch(self, location):
2729+ if location is None:
2730+ location = "."
2731+ transport = get_transport(location)
2732+ try:
2733+ transport.local_abspath(".")
2734+ except NotLocalUrl:
2735+ is_local = False
2736+ else:
2737+ is_local = True
2738+ controldir, relpath = ControlDir.open_containing_from_transport(transport)
2739+ tree, branch = controldir._get_tree_branch()
2740+ return tree, branch, is_local, controldir.user_url, relpath
2741+
2742+ def _get_build_tree(self, revision, tree, branch):
2743+ if revision is None and tree is not None:
2744+ note(gettext("Building using working tree"))
2745+ else:
2746+ if revision is None:
2747+ revid = branch.last_revision()
2748+ elif len(revision) == 1:
2749+ revid = revision[0].in_history(branch).rev_id
2750+ else:
2751+ raise BzrCommandError(
2752+ gettext(
2753+ "bzr builddeb --revision takes exactly one "
2754+ "revision specifier."
2755+ )
2756+ )
2757+ note(gettext("Building branch from revision %s"), revid)
2758+ tree = branch.repository.revision_tree(revid)
2759+ return tree
2760+
2761+ def _build_type(self, merge, native, split):
2762+ if merge:
2763+ return BUILD_TYPE_MERGE
2764+ if native:
2765+ return BUILD_TYPE_NATIVE
2766+ if split:
2767+ return BUILD_TYPE_SPLIT
2768+ return None
2769+
2770+ def _get_build_command(self, config, builder, quick, build_options):
2771+ if builder is None:
2772+ if quick:
2773+ builder = config.quick_builder
2774+ if builder is None:
2775+ builder = "fakeroot debian/rules binary"
2776+ else:
2777+ builder = config.builder
2778+ if builder is None:
2779+ builder = "debuild"
2780+ if build_options:
2781+ builder += " " + " ".join(build_options)
2782+ return builder
2783+
2784+ def _get_dirs(self, config, location, is_local, result_dir, build_dir, orig_dir):
2785+ def _get_dir(supplied, if_local, if_not):
2786+ if supplied is None:
2787+ if is_local:
2788+ supplied = if_local
2789+ else:
2790+ supplied = if_not
2791+ if supplied is not None:
2792+ if is_local:
2793+ supplied = os.path.join(
2794+ urlutils.local_path_from_url(location), supplied
2795+ )
2796+ supplied = os.path.realpath(supplied)
2797+ return supplied
2798+
2799+ result_dir = _get_dir(result_dir, config.result_dir, config.user_result_dir)
2800+ build_dir = _get_dir(
2801+ build_dir,
2802+ config.build_dir or default_build_dir,
2803+ config.user_build_dir or "build-area",
2804+ )
2805+ orig_dir = _get_dir(
2806+ orig_dir,
2807+ config.orig_dir or default_orig_dir,
2808+ config.user_orig_dir or "build-area",
2809+ )
2810+ return result_dir, build_dir, orig_dir
2811+
2812+ def _branch_and_build_options(self, branch_or_build_options_list, source=False):
2813+ branch = None
2814+ build_options = []
2815+ source_opt = False
2816+ if branch_or_build_options_list is not None:
2817+ for opt in branch_or_build_options_list:
2818+ if opt.startswith("-") or branch is not None:
2819+ build_options.append(opt)
2820+ if opt == "-S" or opt == "--source":
2821+ source_opt = True
2822+ else:
2823+ branch = opt
2824+ if source and not source_opt:
2825+ build_options.append("-S")
2826+ if source_opt:
2827+ source = True
2828+ return branch, build_options, source
2829+
2830+ def run(
2831+ self,
2832+ branch_or_build_options_list=None,
2833+ verbose=False,
2834+ export_only=False,
2835+ dont_purge=False,
2836+ use_existing=False,
2837+ result_dir=None,
2838+ builder=None,
2839+ merge=None,
2840+ build_dir=None,
2841+ export_upstream=None,
2842+ export_upstream_revision=None,
2843+ orig_dir=None,
2844+ split=None,
2845+ quick=False,
2846+ reuse=False,
2847+ native=None,
2848+ source=False,
2849+ revision=None,
2850+ package_merge=None,
2851+ strict=False,
2852+ guess_upstream_branch_url=False,
2853+ apt_repository=None,
2854+ apt_repository_key=None,
2855+ ):
2856+ from debian.changelog import ChangelogParseError
2857+
2858+ from .builder import DebBuild
2859+ from .config import UpstreamMetadataSyntaxError
2860+ from .hooks import run_hook
2861+ from .source_distiller import DebcargoError
2862+ from .util import (
2863+ NoPreviousUpload,
2864+ dget_changes,
2865+ find_changelog,
2866+ find_changes_files,
2867+ find_previous_upload,
2868+ tree_contains_upstream_source,
2869+ )
2870+
2871+ location, build_options, source = self._branch_and_build_options(
2872+ branch_or_build_options_list, source
2873+ )
2874+ tree, branch, is_local, location, subpath = self._get_tree_and_branch(location)
2875+ tree = self._get_build_tree(revision, tree, branch)
2876+ _check_tree(tree, subpath, strict=strict)
2877+
2878+ if apt_repository is not None:
2879+ from .apt_repo import RemoteApt
2880+
2881+ apt = RemoteApt.from_string(apt_repository, apt_repository_key)
2882+ else:
2883+ apt = None
2884+
2885+ with tree.lock_read():
2886+ try:
2887+ config = debuild_config(tree, subpath)
2888+ except UpstreamMetadataSyntaxError as e:
2889+ raise BzrCommandError(
2890+ gettext("Unable to parse upstream metadata file %s: %s")
2891+ % (e.path, e.error)
2892+ ) from e
2893+ if reuse:
2894+ note(gettext("Reusing existing build dir"))
2895+ dont_purge = True
2896+ use_existing = True
2897+ build_type = self._build_type(merge, native, split)
2898+
2899+ contains_upstream_source = tree_contains_upstream_source(tree, subpath)
2900+ try:
2901+ (changelog, top_level) = find_changelog(
2902+ tree, subpath, merge=not contains_upstream_source
2903+ )
2904+ except ChangelogParseError as e:
2905+ raise BzrCommandError(
2906+ gettext("Unable to parse changelog: %s") % e
2907+ ) from e
2908+
2909+ if package_merge:
2910+ try:
2911+ prev_version = find_previous_upload(
2912+ tree, subpath, not contains_upstream_source
2913+ )
2914+ except NoPreviousUpload:
2915+ prev_version = None
2916+ if prev_version is None:
2917+ build_options.extend(["-sa", "-v0"])
2918+ else:
2919+ build_options.append("-v%s" % str(prev_version))
2920+ if (
2921+ prev_version.upstream_version
2922+ != changelog.version.upstream_version
2923+ or prev_version.epoch != changelog.version.epoch
2924+ ):
2925+ build_options.append("-sa")
2926+ build_cmd = self._get_build_command(config, builder, quick, build_options)
2927+ result_dir, build_dir, orig_dir = self._get_dirs(
2928+ config, location or ".", is_local, result_dir, build_dir, orig_dir
2929+ )
2930+
2931+ distiller = _get_distiller(
2932+ tree,
2933+ subpath,
2934+ branch,
2935+ build_type=build_type,
2936+ config=config,
2937+ changelog=changelog,
2938+ contains_upstream_source=contains_upstream_source,
2939+ orig_dir=orig_dir,
2940+ use_existing=use_existing,
2941+ top_level=top_level,
2942+ export_upstream=export_upstream,
2943+ export_upstream_revision=export_upstream_revision,
2944+ guess_upstream_branch_url=guess_upstream_branch_url,
2945+ apt=apt,
2946+ )
2947+
2948+ build_source_dir = os.path.join(
2949+ build_dir,
2950+ f"{changelog.package}-{changelog.version.upstream_version}",
2951+ )
2952+
2953+ builder = DebBuild(
2954+ distiller, build_source_dir, build_cmd, use_existing=use_existing
2955+ )
2956+ builder.prepare()
2957+ run_hook(tree, "pre-export", config)
2958+ try:
2959+ builder.export()
2960+ except DebcargoError as e:
2961+ raise BzrCommandError(str(e)) from e
2962+ if not export_only:
2963+ run_hook(tree, "pre-build", config, wd=build_source_dir)
2964+ builder.build()
2965+ run_hook(tree, "post-build", config, wd=build_source_dir)
2966+ if not dont_purge:
2967+ builder.clean()
2968+ changes_paths = []
2969+ for _kind, entry in find_changes_files(
2970+ build_dir, changelog.package, changelog.version
2971+ ):
2972+ changes_paths.append(entry.path)
2973+ if not changes_paths:
2974+ if result_dir is not None:
2975+ raise BzrCommandError(
2976+ "Could not find the .changes "
2977+ "file from the build: %s" % build_dir
2978+ )
2979+ return
2980+ if is_local:
2981+ target_dir = result_dir or default_result_dir
2982+ target_dir = os.path.join(
2983+ urlutils.local_path_from_url(location), target_dir
2984+ )
2985+ else:
2986+ target_dir = "."
2987+ if not os.path.exists(target_dir):
2988+ os.makedirs(target_dir)
2989+ for changes_path in changes_paths:
2990+ dget_changes(changes_path, target_dir)
2991+
2992+
2993+class cmd_get_orig_source(Command):
2994+ """Gets the upstream tar file for the packaging branch."""
2995+
2996+ directory_opt = Option(
2997+ "directory",
2998+ help="Directory from which to retrieve the packaging data",
2999+ short_name="d",
3000+ type=str,
3001+ )
3002+
3003+ takes_options = [directory_opt] + apt_repository_opts # type: ignore
3004+ takes_args = ["version?"]
3005+
3006+ def run(
3007+ self, directory=".", version=None, apt_repository=None, apt_repository_key=None
3008+ ):
3009+ from .upstream import (
3010+ AptSource,
3011+ UpstreamProvider,
3012+ )
3013+ from .upstream.pristinetar import (
3014+ get_pristine_tar_source,
3015+ )
3016+ from .upstream.uscan import (
3017+ NoWatchFile,
3018+ UScanSource,
3019+ )
3020+ from .util import (
3021+ find_changelog,
3022+ )
3023+
3024+ tree, subpath = WorkingTree.open_containing(directory)
3025+ config = debuild_config(tree, subpath)
3026+
3027+ (changelog, larstiq) = find_changelog(tree, subpath, merge=True)
3028+ orig_dir = config.orig_dir
3029+ if orig_dir is None:
3030+ orig_dir = default_orig_dir
3031+
3032+ if version is None:
3033+ version = changelog.version.upstream_version
3034+
3035+ if apt_repository is not None:
3036+ from .apt_repo import RemoteApt
3037+
3038+ apt = RemoteApt.from_string(apt_repository, apt_repository_key)
3039+ else:
3040+ apt = None
3041+
3042+ upstream_sources = [get_pristine_tar_source(tree, tree.branch), AptSource(apt)]
3043+ try:
3044+ uscan_source = UScanSource.from_tree(tree, subpath, larstiq)
3045+ except NoWatchFile:
3046+ pass
3047+ else:
3048+ upstream_sources.append(uscan_source)
3049+
3050+ upstream_provider = UpstreamProvider(
3051+ changelog.package, str(version), orig_dir, upstream_sources
3052+ )
3053+
3054+ result = upstream_provider.provide(orig_dir)
3055+ for tar, _component in result:
3056+ note(gettext("Tar now in %s") % tar)
3057+
3058+
3059+class cmd_merge_upstream(Command):
3060+ """Merges a new upstream version into the current branch.
3061+
3062+ Takes a new upstream version and merges it in to your branch, so that your
3063+ packaging changes are applied to the new version.
3064+
3065+ You must supply the source to import from, and in some cases
3066+ the version number of the new release. The source can be a .tar.gz, .tar,
3067+ .tar.bz2, .tar.xz, .tgz or .zip archive, a directory or a branch. The
3068+ source may also be a remote file described by a URL.
3069+
3070+ In most situations the version can be guessed from the upstream source.
3071+ If the upstream version can not be guessed or if it is guessed
3072+ incorrectly then the version number can be specified with --version.
3073+
3074+ The distribution this version is targetted at can be specified with
3075+ --distribution. This will be used to guess the version number suffix
3076+ that you want, but you can always correct it in the resulting
3077+ debian/changelog.
3078+
3079+ If there is no debian changelog in the branch to retrieve the package
3080+ name from then you must pass the --package option. If this version
3081+ will change the name of the source package then you can use this option
3082+ to set the new name.
3083+
3084+ examples::
3085+
3086+ bzr merge-upstream --version 0.2 \
3087+ http://example.org/releases/scruff-0.2.tar.gz
3088+
3089+ If you are merging a branch as well as the tarball then you can
3090+ specify the branch after the tarball, along with -r to specify the
3091+ revision of that branch to take::
3092+
3093+ bzr merge-upstream --version 0.2 \
3094+ http://example.org/releases/scruff-0.2.tar.gz \
3095+ http://scruff.org/bzr/scruff.dev -r tag:0.2
3096+
3097+ If there is no upstream release tarball, and you want bzr-builddeb to
3098+ create the tarball for you::
3099+
3100+ bzr merge-upstream --version 0.2 http://scruff.org/bzr/scruff.dev
3101+
3102+ Note that the created tarball is just the same as the contents of
3103+ the branch at the specified revision. If you wish to have something
3104+ different, for instance the results of running "make dist", then you
3105+ should create the tarball first, and pass it to the command as in
3106+ the second example.
3107+ """
3108+
3109+ takes_args = ["location?", "upstream_branch?"]
3110+ aliases = ["mu"]
3111+
3112+ package_opt = Option("package", help="The name of the source package.", type=str)
3113+ version_opt = Option(
3114+ "version",
3115+ help="The upstream version number of this release, for example " '"0.2".',
3116+ type=str,
3117+ )
3118+ distribution_opt = Option(
3119+ "distribution",
3120+ help="The distribution that " "this release is targetted at.",
3121+ type=str,
3122+ )
3123+ directory_opt = Option(
3124+ "directory", help="Working tree into which to merge.", short_name="d", type=str
3125+ )
3126+ last_version_opt = Option(
3127+ "last-version",
3128+ help="The full version of the last time " "upstream was merged.",
3129+ type=str,
3130+ )
3131+ force_opt = Option(
3132+ "force", help=("Force a merge even if the upstream branch " "has not changed.")
3133+ )
3134+ snapshot_opt = Option(
3135+ "snapshot",
3136+ help="Merge a snapshot from the "
3137+ "upstream branch rather than a new upstream release.",
3138+ )
3139+
3140+ release_opt = Option("release", help="Merge a release from the upstream branch.")
3141+
3142+ force_pristine_tar_opt = Option(
3143+ "force-pristine-tar",
3144+ help=(
3145+ "Force the use of pristine-tar, even if no " "pristine-tar branch exists"
3146+ ),
3147+ )
3148+
3149+ dist_command_opt = Option(
3150+ "dist-command",
3151+ type=str,
3152+ help="Command to run for creating an upstream tarball from a " "VCS snapshot.",
3153+ )
3154+
3155+ guess_upstream_branch_url_opt = Option(
3156+ "guess-upstream-branch-url",
3157+ help=("Guess upstream branch URL if unknown " "(requires upstream-ontologist)"),
3158+ )
3159+
3160+ takes_options = [
3161+ package_opt,
3162+ version_opt,
3163+ distribution_opt,
3164+ directory_opt,
3165+ last_version_opt,
3166+ force_opt,
3167+ "revision",
3168+ "merge-type",
3169+ snapshot_opt,
3170+ force_pristine_tar_opt,
3171+ dist_command_opt,
3172+ guess_upstream_branch_url_opt,
3173+ release_opt,
3174+ Option(
3175+ "skip-signatures",
3176+ help=("Allow signatures for e.g. upstream tarball " "to be missing"),
3177+ ),
3178+ ]
3179+
3180+ def run(
3181+ self,
3182+ location: Optional[str] = None,
3183+ upstream_branch: Optional[str] = None,
3184+ version: Optional[str] = None,
3185+ distribution: Optional[str] = None,
3186+ package: Optional[str] = None,
3187+ directory: str = ".",
3188+ revision=None,
3189+ merge_type=None,
3190+ last_version: Optional[str] = None,
3191+ force: Optional[bool] = None,
3192+ snapshot: Optional[bool] = None,
3193+ release: Optional[bool] = None,
3194+ force_pristine_tar: bool = False,
3195+ dist_command: Optional[str] = None,
3196+ guess_upstream_branch_url: bool = False,
3197+ skip_signatures: bool = False,
3198+ ):
3199+ from debian.changelog import Version
3200+
3201+ from .hooks import run_hook
3202+ from .merge_upstream import (
3203+ changelog_add_new_version,
3204+ do_merge,
3205+ get_tarballs,
3206+ )
3207+ from .upstream import (
3208+ PackageVersionNotPresent,
3209+ TarfileSource,
3210+ )
3211+ from .upstream.branch import (
3212+ PreviousVersionTagMissing,
3213+ UpstreamBranchSource,
3214+ run_dist_command,
3215+ )
3216+ from .upstream.uscan import (
3217+ NoWatchFile,
3218+ UScanSource,
3219+ )
3220+ from .util import (
3221+ detect_version_kind,
3222+ get_files_excluded,
3223+ guess_build_type,
3224+ tree_contains_upstream_source,
3225+ )
3226+
3227+ tree, subpath = WorkingTree.open_containing(directory)
3228+ with tree.lock_write():
3229+ _check_uncommitted(tree, subpath)
3230+ config = debuild_config(tree, subpath)
3231+ (
3232+ current_version,
3233+ package,
3234+ distribution,
3235+ distribution_name,
3236+ changelog,
3237+ top_level,
3238+ ) = _get_changelog_info(tree, subpath, last_version, package, distribution)
3239+ if package is None:
3240+ raise BzrCommandError(
3241+ "You did not specify --package, and "
3242+ "there is no changelog from which to determine the "
3243+ "package name, which is needed to know the name to "
3244+ "give the .orig.tar.gz. Please specify --package."
3245+ )
3246+
3247+ if snapshot is None and release is None:
3248+ if current_version is not None:
3249+ version_kind = detect_version_kind(current_version)
3250+ else:
3251+ version_kind = None
3252+ elif snapshot is not None and release is not None:
3253+ raise BzrCommandError("--release and --snapshot are incompatible")
3254+ elif snapshot:
3255+ version_kind = "snapshot"
3256+ elif release:
3257+ version_kind = "release"
3258+
3259+ if version_kind is None:
3260+ version_kind = "release"
3261+
3262+ try:
3263+ files_excluded = get_files_excluded(tree, subpath, top_level)
3264+ except NoSuchFile as e:
3265+ mutter("Copyright file not found: %s", e)
3266+ files_excluded = []
3267+ contains_upstream_source = tree_contains_upstream_source(tree, subpath)
3268+ if changelog is None:
3269+ changelog_version = None
3270+ else:
3271+ changelog_version = changelog.version
3272+ build_type = config.build_type
3273+ if build_type is None:
3274+ build_type = guess_build_type(
3275+ tree, changelog_version, subpath, contains_upstream_source
3276+ )
3277+ need_upstream_tarball = build_type != BUILD_TYPE_MERGE
3278+ if build_type == BUILD_TYPE_NATIVE:
3279+ raise BzrCommandError(
3280+ gettext("Merge upstream in native mode is not supported.")
3281+ )
3282+
3283+ if upstream_branch is not None:
3284+ upstream_branch = Branch.open(upstream_branch)
3285+ elif location is not None and not os.path.isfile(location):
3286+ try:
3287+ upstream_branch = Branch.open(location)
3288+ except NotBranchError:
3289+ upstream_branch = None
3290+ elif upstream_branch is None and config.upstream_branch is not None:
3291+ note(
3292+ gettext("Using upstream branch %s (from configuration)"),
3293+ config.upstream_branch,
3294+ )
3295+ upstream_branch = Branch.open(config.upstream_branch)
3296+ elif upstream_branch is None and guess_upstream_branch_url:
3297+ try:
3298+ from upstream_ontologist.guess import (
3299+ guess_upstream_metadata,
3300+ )
3301+ except ModuleNotFoundError:
3302+ warning(
3303+ "upstream-ontologist not available, "
3304+ "not guess upstream branch URL"
3305+ )
3306+ upstream_branch = None
3307+ else:
3308+ guessed_upstream_metadata = guess_upstream_metadata(
3309+ tree.abspath(subpath),
3310+ trust_package=False,
3311+ net_access=True,
3312+ consult_external_directory=False,
3313+ )
3314+ guessed_repo = guessed_upstream_metadata.get("Repository")
3315+ if guessed_repo:
3316+ note(
3317+ "Opening upstream-ontologist provided branch %s",
3318+ guessed_repo,
3319+ )
3320+ upstream_branch = Branch.open(guessed_repo)
3321+ else:
3322+ upstream_branch = None
3323+
3324+ create_dist: Optional[Callable[[str, str, str, str, str], str]]
3325+ if dist_command:
3326+
3327+ def create_dist(tree, package, version, target_dir, subpath=""):
3328+ return run_dist_command(
3329+ tree,
3330+ package,
3331+ version,
3332+ target_dir,
3333+ dist_command,
3334+ subpath=subpath,
3335+ )
3336+ else:
3337+ create_dist = None
3338+
3339+ if upstream_branch is not None:
3340+ upstream_branch_source = UpstreamBranchSource.from_branch(
3341+ upstream_branch,
3342+ config=config,
3343+ local_dir=tree.controldir,
3344+ create_dist=create_dist,
3345+ version_kind=version_kind,
3346+ )
3347+ else:
3348+ upstream_branch_source = None
3349+
3350+ if location is not None:
3351+ try:
3352+ primary_upstream_source = UpstreamBranchSource.from_branch(
3353+ Branch.open(location),
3354+ config=config,
3355+ local_dir=tree.controldir,
3356+ create_dist=create_dist,
3357+ version_kind=version_kind,
3358+ )
3359+ except NotBranchError:
3360+ primary_upstream_source = TarfileSource(location, version)
3361+ else:
3362+ if snapshot:
3363+ if upstream_branch_source is None:
3364+ raise BzrCommandError(
3365+ gettext("--snapshot requires an upstream branch source")
3366+ )
3367+ primary_upstream_source = upstream_branch_source
3368+ else:
3369+ try:
3370+ primary_upstream_source = UScanSource.from_tree(
3371+ tree, subpath, top_level, skip_signatures=skip_signatures
3372+ )
3373+ except NoWatchFile as e:
3374+ if upstream_branch_source is None:
3375+ raise BzrCommandError(
3376+ gettext(
3377+ "no upstream source location known; "
3378+ "add watch file or specify "
3379+ "upstream repository?"
3380+ )
3381+ ) from e
3382+ primary_upstream_source = upstream_branch_source
3383+
3384+ if revision is not None:
3385+ if upstream_branch is None:
3386+ raise BzrCommandError(
3387+ gettext(
3388+ "--revision can only be "
3389+ "used with a valid upstream branch"
3390+ )
3391+ )
3392+ if len(revision) > 1:
3393+ raise BzrCommandError(
3394+ gettext("merge-upstream takes only a single --revision")
3395+ )
3396+ upstream_revspec = revision[0]
3397+ upstream_revisions = {
3398+ None: (upstream_revspec.as_revision_id(upstream_branch), subpath)
3399+ }
3400+ else:
3401+ upstream_revisions = None
3402+
3403+ if version is None and upstream_revisions is not None:
3404+ # Look up the version from the upstream revision
3405+ unmangled_version, version = upstream_branch_source.get_version(
3406+ package, current_version, upstream_revisions[None][0]
3407+ )
3408+ elif version is None and primary_upstream_source is not None:
3409+ unmangled_version, version = primary_upstream_source.get_latest_version(
3410+ package, current_version
3411+ )
3412+ if version is None:
3413+ if upstream_branch_source is not None:
3414+ raise BzrCommandError(
3415+ gettext(
3416+ "You must specify "
3417+ "the version number using --version or specify "
3418+ "--snapshot to merge a snapshot from the upstream "
3419+ "branch."
3420+ )
3421+ )
3422+ else:
3423+ raise BzrCommandError(
3424+ gettext(
3425+ "You must specify the " "version number using --version."
3426+ )
3427+ )
3428+ note(gettext("Using version string %s."), version)
3429+ # Look up the revision id from the version string
3430+ if upstream_revisions is None and upstream_branch_source is not None:
3431+ try:
3432+ upstream_revisions = upstream_branch_source.version_as_revisions(
3433+ package, version
3434+ )
3435+ except PackageVersionNotPresent as e:
3436+ raise BzrCommandError(
3437+ "Version {} can not be found in upstream branch {!r}. "
3438+ "Specify the revision manually using --revision or "
3439+ "adjust 'export-upstream-revision' in the "
3440+ "configuration.".format(version, upstream_branch_source)
3441+ ) from e
3442+ if need_upstream_tarball:
3443+ target_dir = self.enter_context(tempfile.TemporaryDirectory())
3444+ try:
3445+ locations = primary_upstream_source.fetch_tarballs(
3446+ package, version, target_dir, components=[None]
3447+ )
3448+ except PackageVersionNotPresent:
3449+ if upstream_revisions is not None:
3450+ locations = upstream_branch_source.fetch_tarballs(
3451+ package,
3452+ version,
3453+ target_dir,
3454+ components=[None],
3455+ revisions=upstream_revisions,
3456+ )
3457+ else:
3458+ raise
3459+ orig_dir = config.orig_dir or default_orig_dir
3460+ try:
3461+ tarball_filenames = get_tarballs(
3462+ orig_dir, tree, package, version, locations
3463+ )
3464+ except FileExists as e:
3465+ raise BzrCommandError(
3466+ "The target file %s already exists, and is either "
3467+ "different to the new upstream tarball, or they "
3468+ "are of different formats. Either delete the target "
3469+ "file, or use it as the argument to import." % e.path
3470+ ) from e
3471+ try:
3472+ conflicts, imported_revids = do_merge(
3473+ tree,
3474+ tarball_filenames,
3475+ package,
3476+ version,
3477+ current_version,
3478+ upstream_branch,
3479+ upstream_revisions,
3480+ merge_type,
3481+ force=force,
3482+ force_pristine_tar=force_pristine_tar,
3483+ files_excluded=files_excluded,
3484+ )
3485+ except PreviousVersionTagMissing as e:
3486+ raise BzrCommandError(str(e)) from e
3487+ if current_version is not None and Version(current_version) >= Version(
3488+ version
3489+ ):
3490+ raise BzrCommandError(
3491+ gettext("Upstream version %s has already been merged.") % version
3492+ )
3493+ changelog_add_new_version(
3494+ tree, subpath, version, distribution_name, changelog, package
3495+ )
3496+ run_hook(tree, "merge-upstream", config)
3497+ if not need_upstream_tarball:
3498+ note(
3499+ gettext(
3500+ "An entry for the new upstream version has been "
3501+ "added to the changelog."
3502+ )
3503+ )
3504+ else:
3505+ note(gettext("The new upstream version has been imported."))
3506+ if conflicts:
3507+ note(
3508+ gettext(
3509+ "You should now resolve the conflicts, review "
3510+ "the changes, and then commit."
3511+ )
3512+ )
3513+ else:
3514+ note(gettext("You should now review the changes and " "then commit."))
3515+
3516+
3517+class cmd_import_dsc(Command):
3518+ """Import a series of source packages.
3519+
3520+ Provide a number of source packages (.dsc files), and they will
3521+ be imported to create a branch with history that reflects those
3522+ packages.
3523+
3524+ The first argument is the distribution that these source packages
3525+ were uploaded to, one of "debian" or "ubuntu". It can also
3526+ be the target distribution from the changelog, e.g. "unstable",
3527+ which will be resolved to the correct distribution.
3528+
3529+ You can also specify a file (possibly remote) that contains a
3530+ list of source packages (.dsc files) to import using the --file
3531+ option. Each line is taken to be a URI or path to import. The
3532+ sources specified in the file are used in addition to those
3533+ specified on the command line.
3534+
3535+ If you have an existing branch containing packaging and you want to
3536+ import a .dsc from an upload done from outside the version control
3537+ system you can use this command.
3538+ """
3539+
3540+ takes_args = ["files*"]
3541+
3542+ filename_opt = Option(
3543+ "file",
3544+ help="File containing URIs of source " "packages to import.",
3545+ type=str,
3546+ short_name="F",
3547+ )
3548+
3549+ takes_options = [filename_opt]
3550+
3551+ def import_many(self, db, files_list, orig_target):
3552+ from .import_dsc import (
3553+ DscCache,
3554+ DscComp,
3555+ )
3556+ from .util import (
3557+ open_file_via_transport,
3558+ )
3559+
3560+ cache = DscCache()
3561+ files_list.sort(key=DscComp(cache).key)
3562+ if not os.path.exists(orig_target):
3563+ os.makedirs(orig_target)
3564+ for dscname in files_list:
3565+ dsc = cache.get_dsc(dscname)
3566+
3567+ def get_dsc_part(from_transport, filename):
3568+ from_f = open_file_via_transport(filename, from_transport)
3569+ contents = from_f.read()
3570+ with open(os.path.join(orig_target, filename), "wb") as to_f:
3571+ to_f.write(contents)
3572+
3573+ base, filename = urlutils.split(dscname)
3574+ from_transport = cache.get_transport(dscname)
3575+ get_dsc_part(from_transport, filename)
3576+ for file_details in dsc["files"]:
3577+ name = file_details["name"]
3578+ get_dsc_part(from_transport, name)
3579+ db.import_package(os.path.join(orig_target, filename))
3580+
3581+ def run(self, files_list, file=None):
3582+ from .import_dsc import (
3583+ DistributionBranch,
3584+ DistributionBranchSet,
3585+ )
3586+ from .util import (
3587+ MissingChangelogError,
3588+ find_changelog,
3589+ open_file,
3590+ )
3591+
3592+ try:
3593+ tree, subpath = WorkingTree.open_containing(".")
3594+ except NotBranchError as e:
3595+ raise BzrCommandError(
3596+ gettext("There is no tree to import the packages in to")
3597+ ) from e
3598+ with tree.lock_write():
3599+ _check_uncommitted(tree, subpath)
3600+ if files_list is None:
3601+ files_list = []
3602+ if file is not None:
3603+ if isinstance(file, str):
3604+ file = file.encode("utf-8")
3605+ sources_file = open_file(file)
3606+ for line in sources_file:
3607+ line = line.strip()
3608+ if len(line) > 0:
3609+ files_list.append(line)
3610+ if len(files_list) < 1:
3611+ raise BzrCommandError(
3612+ gettext(
3613+ "You must give the location of "
3614+ "at least one source package to install, or use the "
3615+ "--file option."
3616+ )
3617+ )
3618+ config = debuild_config(tree, subpath)
3619+ if config.build_type == BUILD_TYPE_MERGE:
3620+ raise BzrCommandError(
3621+ gettext("import-dsc in merge mode is not yet supported.")
3622+ )
3623+ orig_target = os.path.join(tree.basedir, default_orig_dir)
3624+ db = DistributionBranch(tree.branch, tree.branch, tree=tree)
3625+ dbs = DistributionBranchSet()
3626+ dbs.add_branch(db)
3627+ try:
3628+ (changelog, top_level) = find_changelog(tree, subpath, merge=False)
3629+ last_version = changelog.version
3630+ except MissingChangelogError:
3631+ last_version = None
3632+ with tempfile.TemporaryDirectory(
3633+ dir=os.path.join(tree.basedir, "..")
3634+ ) as tempdir:
3635+ if last_version is not None:
3636+ if not db.pristine_upstream_source.has_version(
3637+ changelog.package, last_version.upstream_version
3638+ ):
3639+ raise BzrCommandError(
3640+ gettext(
3641+ "Unable to find the tag "
3642+ "for the previous upstream version (%(version)s) "
3643+ "in the branch. Consider importing it via "
3644+ "import-upstream. If it is already present in the "
3645+ "branch please make sure it is tagged as %(tag)r."
3646+ )
3647+ % {
3648+ "version": last_version,
3649+ "tag": db.pristine_upstream_source.tag_name(
3650+ last_version.upstream_version
3651+ ),
3652+ }
3653+ )
3654+ upstream_tips = db.pristine_upstream_source.version_as_revisions(
3655+ changelog.package, last_version.upstream_version
3656+ )
3657+ db.extract_upstream_tree(upstream_tips, tempdir)
3658+ else:
3659+ db.create_empty_upstream_tree(tempdir)
3660+ self.import_many(db, files_list, orig_target)
3661+
3662+
3663+class cmd_import_upstream(Command):
3664+ """Imports an upstream tarball.
3665+
3666+ This will import an upstream tarball in to your branch, but not modify the
3667+ working tree. Use merge-upstream if you wish to directly merge the new
3668+ upstream version in to your tree.
3669+
3670+ The imported revision can be accessed using the tag name that will be
3671+ reported at the end of a successful operation. The revision will include
3672+ the pristine-tar data that will allow other commands to recreate the
3673+ tarball when needed.
3674+
3675+ For instance::
3676+
3677+ $ bzr import-upstream 1.2.3 ../package_1.2.3.orig.tar.gz
3678+
3679+ If upstream is packaged in bzr, you should provide the upstream branch
3680+ whose tip commit is the closest match to the tarball::
3681+
3682+ $ bzr import-upstream 1.2.3 ../package_1.2.3.orig.tar.gz ../upstream
3683+
3684+ After doing this, commands that assume there is an upstream tarball, like
3685+ 'bzr builddeb' will be able to recreate the one provided at import-upstream
3686+ time, meaning that you don't need to distribute the tarball in addition to
3687+ the branch.
3688+
3689+ If you want to manually merge with the imported upstream, you can do::
3690+
3691+ $ bzr merge . -r tag:upstream-1.2.3
3692+
3693+ The imported revision will have file ids taken from your branch, the
3694+ upstream branch, or previous tarball imports as necessary. In addition
3695+ the parents of the new revision will be the previous upstream tarball
3696+ import and the tip of the upstream branch if you supply one.
3697+ """
3698+
3699+ takes_options = [
3700+ "revision",
3701+ Option(
3702+ "force-pristine-tar",
3703+ help=(
3704+ "Force creation of a new "
3705+ "pristine-tar branch, even if one does not exist."
3706+ ),
3707+ ),
3708+ ]
3709+
3710+ takes_args = ["version", "location", "upstream_branch?"]
3711+
3712+ def run(
3713+ self,
3714+ version,
3715+ location,
3716+ upstream_branch=None,
3717+ revision=None,
3718+ force_pristine_tar=False,
3719+ ):
3720+ from debian.changelog import Version
3721+
3722+ from .import_dsc import (
3723+ DistributionBranch,
3724+ DistributionBranchSet,
3725+ )
3726+ from .util import (
3727+ md5sum_filename,
3728+ )
3729+
3730+ # TODO: search for similarity etc.
3731+ branch, subpath = Branch.open_containing(".")
3732+ if upstream_branch is None:
3733+ upstream = None
3734+ upstream_subpath = ""
3735+ else:
3736+ upstream, upstream_subpath = Branch.open_containing(upstream_branch)
3737+ self.add_cleanup(branch.lock_write().unlock)
3738+ tempdir = self.enter_context(
3739+ tempfile.TemporaryDirectory(
3740+ dir=branch.controldir.root_transport.clone("..").local_abspath(".")
3741+ )
3742+ )
3743+ db = DistributionBranch(branch, pristine_upstream_branch=branch)
3744+ if db.pristine_upstream_source.has_version(None, version):
3745+ raise BzrCommandError(gettext("Version %s is already present.") % version)
3746+ tagged_versions = {}
3747+ for tversion, tcomponents in db.pristine_upstream_source.iter_versions():
3748+ tagged_versions[Version(tversion)] = tcomponents
3749+ tag_order = sorted(tagged_versions.keys())
3750+ if tag_order:
3751+ base_revisions = tagged_versions[tag_order[-1]]
3752+ else:
3753+ base_revisions = {}
3754+ if base_revisions:
3755+ if upstream is not None:
3756+ # See bug lp:309682
3757+ for parent in base_revisions.values():
3758+ upstream.repository.fetch(branch.repository, parent)
3759+ db.extract_upstream_tree(
3760+ {comp: (revid, subpath) for comp, revid in base_revisions.items()},
3761+ tempdir,
3762+ )
3763+ parents = {}
3764+ for name, base_revid in base_revisions.items():
3765+ parents[name] = [(base_revid, subpath)]
3766+ else:
3767+ parents = {}
3768+ db.create_empty_upstream_tree(tempdir)
3769+ tree = db.branch.basis_tree()
3770+ tree.lock_read()
3771+ dbs = DistributionBranchSet()
3772+ dbs.add_branch(db)
3773+ if revision is None:
3774+ upstream_revid = None
3775+ elif len(revision) == 1:
3776+ upstream_revid = revision[0].in_history(upstream).rev_id
3777+ else:
3778+ raise BzrCommandError(
3779+ gettext(
3780+ "bzr import-upstream --revision takes exactly"
3781+ " one revision specifier."
3782+ )
3783+ )
3784+ tarballs = [(location, None, md5sum_filename(location))]
3785+ for (
3786+ component,
3787+ tag_name,
3788+ _revid,
3789+ _pristine_tar_imported,
3790+ _subpath,
3791+ ) in db.import_upstream_tarballs(
3792+ tarballs,
3793+ None,
3794+ version,
3795+ parents,
3796+ upstream_branch=upstream,
3797+ upstream_revisions={None: (upstream_revid, upstream_subpath)},
3798+ force_pristine_tar=force_pristine_tar,
3799+ ):
3800+ if component is None:
3801+ self.outf.write(
3802+ gettext("Imported %(location)s as tag:%(tag)s.\n")
3803+ % {"location": location, "tag": tag_name}
3804+ )
3805+ else:
3806+ self.outf.write(
3807+ gettext("Imported %(location)s (%(component)s) as tag:%(tag)s.\n")
3808+ % {"location": location, "component": component, "tag": tag_name}
3809+ )
3810+
3811+
3812+class cmd_builddeb_do(Command):
3813+ """Run a command in an exported package, copying the result back.
3814+
3815+ For a merge mode package the full source is not available, making some
3816+ operations difficult. This command allows you to run any command in an
3817+ exported source directory, copying the resulting debian/ directory back
3818+ to your branch if the command is successful.
3819+
3820+ For instance:
3821+
3822+ bzr builddeb-do
3823+
3824+ will run a shell in the unpacked source. Any changes you make in the
3825+ ``debian/`` directory (and only those made in that directory) will be
3826+ copied back to the branch. If you exit with a non-zero exit code (e.g.
3827+ "exit 1"), then the changes will not be copied back.
3828+
3829+ You can also specify single commands to be run, e.g.
3830+
3831+ bzr builddeb-do "dpatch-edit-patch 01-fix-build"
3832+
3833+ Note that only the first argument is used as the command, and so the above
3834+ example had to be quoted.
3835+ """
3836+
3837+ takes_args = ["command*"]
3838+ takes_options = [ # type: ignore
3839+ Option("no-preparation", help="Don't apply/unapply patches."),
3840+ ] + apt_repository_opts
3841+ aliases = ["bd-do"]
3842+
3843+ def run(
3844+ self,
3845+ command_list=None,
3846+ no_preparation=False,
3847+ apt_repository=None,
3848+ apt_repository_key=None,
3849+ ):
3850+ import subprocess
3851+
3852+ from .builder import (
3853+ BuildFailedError,
3854+ DebBuild,
3855+ )
3856+ from .hooks import run_hook
3857+ from .source_distiller import (
3858+ MergeModeDistiller,
3859+ )
3860+ from .upstream import (
3861+ AptSource,
3862+ UpstreamProvider,
3863+ )
3864+ from .upstream.pristinetar import (
3865+ get_pristine_tar_source,
3866+ )
3867+ from .upstream.uscan import (
3868+ UScanSource,
3869+ )
3870+ from .util import (
3871+ find_changelog,
3872+ guess_build_type,
3873+ tree_contains_upstream_source,
3874+ )
3875+
3876+ t, subpath = WorkingTree.open_containing(".")
3877+ self.add_cleanup(t.lock_read().unlock)
3878+ config = debuild_config(t, subpath)
3879+ (changelog, top_level) = find_changelog(t, subpath, merge=False, max_blocks=2)
3880+
3881+ contains_upstream_source = tree_contains_upstream_source(t, subpath)
3882+ if changelog is None:
3883+ changelog_version = None
3884+ else:
3885+ changelog_version = changelog.version
3886+ build_type = config.build_type
3887+ if build_type is None:
3888+ build_type = guess_build_type(
3889+ t, changelog_version, subpath, contains_upstream_source
3890+ )
3891+
3892+ if build_type != BUILD_TYPE_MERGE:
3893+ raise BzrCommandError(
3894+ gettext(
3895+ "This command only works for merge "
3896+ "mode packages. See /usr/share/doc/bzr-builddeb"
3897+ "/user_manual/merge.html for more information."
3898+ )
3899+ )
3900+
3901+ give_instruction = False
3902+ if command_list is None:
3903+ try:
3904+ command_list = [os.environ["SHELL"]]
3905+ except KeyError:
3906+ command_list = ["/bin/sh"]
3907+ give_instruction = True
3908+ build_dir = config.build_dir
3909+ if build_dir is None:
3910+ build_dir = default_build_dir
3911+ orig_dir = config.orig_dir
3912+ if orig_dir is None:
3913+ orig_dir = default_orig_dir
3914+
3915+ if apt_repository is not None:
3916+ from .apt_repo import RemoteApt
3917+
3918+ apt = RemoteApt.from_string(apt_repository, apt_repository_key)
3919+ else:
3920+ apt = None
3921+
3922+ upstream_provider = UpstreamProvider(
3923+ changelog.package,
3924+ changelog.version.upstream_version,
3925+ orig_dir,
3926+ [
3927+ get_pristine_tar_source(t, t.branch),
3928+ AptSource(apt=apt),
3929+ UScanSource(t, subpath, top_level),
3930+ ],
3931+ )
3932+
3933+ distiller = MergeModeDistiller(
3934+ t, subpath, upstream_provider, top_level=top_level
3935+ )
3936+
3937+ build_source_dir = os.path.join(
3938+ build_dir, changelog.package + "-" + changelog.version.upstream_version
3939+ )
3940+
3941+ command = " ".join(command_list)
3942+
3943+ builder = DebBuild(distiller, build_source_dir, command)
3944+ builder.prepare()
3945+ run_hook(t, "pre-export", config)
3946+ builder.export()
3947+ note(gettext('Running "%s" in the exported directory.') % (command))
3948+ if give_instruction:
3949+ note(
3950+ gettext(
3951+ "If you want to cancel your changes then exit "
3952+ 'with a non-zero exit code, e.g. run "exit 1".'
3953+ )
3954+ )
3955+ if not no_preparation:
3956+ builder.before_build()
3957+ try:
3958+ builder.build()
3959+ except BuildFailedError as e:
3960+ raise BzrCommandError(
3961+ gettext("Not updating the working tree as the command failed.")
3962+ ) from e
3963+ finally:
3964+ if not no_preparation:
3965+ try:
3966+ builder.after_build()
3967+ except subprocess.CalledProcessError as e:
3968+ raise BzrCommandError(
3969+ gettext("After build processing failed. Aborting.")
3970+ ) from e
3971+ note(gettext("Copying debian/ back"))
3972+ if top_level:
3973+ destination = ""
3974+ else:
3975+ destination = "debian/"
3976+ destination = os.path.join(t.basedir, destination)
3977+ source_debian = os.path.join(build_source_dir, "debian")
3978+ for filename in os.listdir(source_debian):
3979+ proc = subprocess.Popen(
3980+ f'cp -apf "{os.path.join(source_debian, filename)}" "{destination}"',
3981+ shell=True,
3982+ )
3983+ proc.wait()
3984+ if proc.returncode != 0:
3985+ raise BzrCommandError(gettext("Copying back debian/ failed"))
3986+ builder.clean()
3987+ note(
3988+ gettext(
3989+ "If any files were added or removed you should run "
3990+ '"bzr add" or "bzr rm" as appropriate.'
3991+ )
3992+ )
3993+
3994+
3995+class cmd_dep3_patch(Command):
3996+ r"""Format the changes in a branch as a DEP-3 patch.
3997+
3998+ This will generate a patch file containing as much information
3999+ specified by DEP-3 (http://dep.debian.net/deps/dep3/) as possible.
4000+
4001+ The patch will contain all changes that are not merged into
4002+ the current branch (either that in the current working directory
4003+ or specified by --directory) but are present and committed
4004+ in the branch at the specified location.
4005+
4006+ To generate the "Status" header, this command will check the
4007+ upstream branch to verify if the change has made it upstream,
4008+ unless --no-upstream-check was specified.
4009+
4010+ examples::
4011+
4012+ bzr dep3-patch lp:~user/project/feature-branch > \\
4013+ debian/patches/01_feature
4014+ """
4015+
4016+ takes_args = ["location?"]
4017+
4018+ directory_opt = Option(
4019+ "directory",
4020+ help="Packaging tree for which to generate patch.",
4021+ short_name="d",
4022+ type=str,
4023+ )
4024+
4025+ no_upstream_check_opt = Option(
4026+ "no-upstream-check", help="Don't check whether patch has been merged upstream."
4027+ )
4028+
4029+ takes_options = [directory_opt, "revision", "change", no_upstream_check_opt]
4030+
4031+ def run(self, location=".", directory=".", revision=None, no_upstream_check=False):
4032+ from .dep3 import (
4033+ describe_origin,
4034+ determine_applied_upstream,
4035+ determine_forwarded,
4036+ gather_bugs_and_authors,
4037+ write_dep3_patch,
4038+ )
4039+
4040+ (packaging_tree, packaging_branch) = ControlDir.open_containing_tree_or_branch(
4041+ directory
4042+ )[:2]
4043+ self.add_cleanup(packaging_branch.lock_read().unlock)
4044+ tree, branch = ControlDir.open_containing_tree_or_branch(location)[:2]
4045+ self.add_cleanup(branch.lock_read().unlock)
4046+ if revision is not None and len(revision) >= 1:
4047+ revision_id = revision[-1].as_revision_id(branch)
4048+ else:
4049+ revision_id = None
4050+ if revision_id is None:
4051+ revision_id = branch.last_revision()
4052+ graph = branch.repository.get_graph(packaging_branch.repository)
4053+ if revision is not None and len(revision) == 2:
4054+ base_revid = revision[0].as_revision_id(branch)
4055+ else:
4056+ base_revid = graph.find_unique_lca(
4057+ revision_id, packaging_branch.last_revision()
4058+ )
4059+ interesting_revision_ids = graph.find_unique_ancestors(
4060+ revision_id, [base_revid]
4061+ )
4062+ if len(interesting_revision_ids) == 0:
4063+ raise BzrCommandError(gettext("No unmerged revisions"))
4064+ (bugs, authors, last_update) = gather_bugs_and_authors(
4065+ branch.repository, interesting_revision_ids
4066+ )
4067+ config = branch.get_config()
4068+ description = config.get_user_option("description")
4069+ if description is None:
4070+ # if there's just one revision in the mainline history, use
4071+ # that revisions commits message
4072+ lhs_history = graph.iter_lefthand_ancestry(revision_id, [base_revid])
4073+ rev = branch.repository.get_revision(next(lhs_history))
4074+ try:
4075+ next(lhs_history)
4076+ except StopIteration:
4077+ description = rev.message
4078+ origin = describe_origin(branch, revision_id)
4079+ if packaging_tree is None:
4080+ packaging_tree = packaging_branch.basis_tree()
4081+ builddeb_config = debuild_config(packaging_tree, "")
4082+ if not no_upstream_check and builddeb_config.upstream_branch:
4083+ upstream_branch = Branch.open(builddeb_config.upstream_branch)
4084+ applied_upstream = determine_applied_upstream(
4085+ upstream_branch, branch, revision_id
4086+ )
4087+ forwarded = determine_forwarded(upstream_branch, branch, revision_id)
4088+ else:
4089+ applied_upstream = None
4090+ forwarded = None
4091+ write_dep3_patch(
4092+ self.outf,
4093+ branch,
4094+ base_revid,
4095+ revision_id,
4096+ bugs=bugs,
4097+ authors=authors,
4098+ origin=origin,
4099+ forwarded=forwarded,
4100+ applied_upstream=applied_upstream,
4101+ description=description,
4102+ last_update=last_update,
4103+ )
4104+
4105+
4106+class LocalTree:
4107+ def __init__(self, branch):
4108+ self.branch = branch
4109+ self._td = None
4110+
4111+ def __enter__(self):
4112+ try:
4113+ return self.branch.controldir.open_workingtree()
4114+ except (NoWorkingTree, NotLocalUrl):
4115+ pass
4116+ # Remote, inaccessible
4117+ self._td = tempfile.mkdtemp()
4118+ to_dir = self.branch.controldir.sprout(
4119+ get_transport(self._td).base,
4120+ None,
4121+ create_tree_if_local=True,
4122+ source_branch=self.branch,
4123+ )
4124+ try:
4125+ pristine_tar_branch = self.branch.controldir.open_branch(
4126+ name="pristine-tar"
4127+ )
4128+ except (NotBranchError, NoColocatedBranchSupport):
4129+ pass
4130+ else:
4131+ pristine_tar_branch.push(to_dir.create_branch("pristine-tar"))
4132+ return to_dir.open_workingtree()
4133+
4134+ def __exit__(self, exc_type, exc_val, exc_tb):
4135+ if self._td is not None:
4136+ shutil.rmtree(self._td)
4137+ return False
4138+
4139+
4140+def _build_helper(
4141+ local_tree,
4142+ subpath,
4143+ packaging_branch,
4144+ target_dir,
4145+ builder,
4146+ guess_upstream_branch_url=False,
4147+ apt=None,
4148+):
4149+ # TODO(jelmer): Integrate this with cmd_builddeb
4150+ from .builder import (
4151+ do_build,
4152+ )
4153+ from .util import (
4154+ find_changelog,
4155+ tree_contains_upstream_source,
4156+ )
4157+
4158+ (changelog, top_level) = find_changelog(
4159+ local_tree, subpath, merge=False, max_blocks=2
4160+ )
4161+
4162+ config = debuild_config(local_tree, subpath)
4163+ contains_upstream_source = tree_contains_upstream_source(local_tree, subpath)
4164+
4165+ distiller = _get_distiller(
4166+ local_tree,
4167+ subpath,
4168+ packaging_branch,
4169+ build_type=None,
4170+ config=config,
4171+ changelog=changelog,
4172+ contains_upstream_source=contains_upstream_source,
4173+ top_level=top_level,
4174+ guess_upstream_branch_url=guess_upstream_branch_url,
4175+ apt=apt,
4176+ )
4177+
4178+ return do_build(
4179+ changelog.package,
4180+ changelog.version,
4181+ distiller,
4182+ local_tree,
4183+ config,
4184+ builder,
4185+ target_dir,
4186+ )
4187+
4188+
4189+DEFAULT_BUILDER = "sbuild --source --source-only-changes --no-clean-source"
4190+
4191+
4192+class cmd_debrelease(Command):
4193+ """Release a new version of a package.
4194+
4195+ This will update the latest distribution in the changelog,
4196+ build the package and upload.
4197+
4198+ Location can be remote.
4199+ """
4200+
4201+ strict_opt = Option(
4202+ "strict",
4203+ help="Refuse to build if there are unknown files in"
4204+ " the working tree, --no-strict disables the check.",
4205+ )
4206+
4207+ takes_args = ["location?"]
4208+ takes_options = [ # type: ignore
4209+ strict_opt,
4210+ Option("skip-upload", help="Skip upload."),
4211+ builder_opt,
4212+ ] + apt_repository_opts
4213+
4214+ def run(
4215+ self,
4216+ location=".",
4217+ strict=True,
4218+ skip_upload=False,
4219+ builder=DEFAULT_BUILDER,
4220+ apt_repository=None,
4221+ apt_repository_key=None,
4222+ ):
4223+ from .release import SuccessReleaseMarker
4224+ from .util import (
4225+ dput_changes,
4226+ )
4227+
4228+ branch, subpath = Branch.open_containing(location)
4229+
4230+ if apt_repository is not None:
4231+ from .apt_repo import RemoteApt
4232+
4233+ apt = RemoteApt.from_string(apt_repository, apt_repository_key)
4234+ else:
4235+ apt = None
4236+
4237+ # preserve whatever source format we have.
4238+ # TODO(jelmer): Use the local tree if there is one, but check it's
4239+ # clean.
4240+ with LocalTree(branch) as local_tree:
4241+ _check_tree(local_tree, subpath, strict)
4242+ with tempfile.TemporaryDirectory() as td:
4243+ with SuccessReleaseMarker(local_tree, subpath):
4244+ changes_files = _build_helper(
4245+ local_tree,
4246+ subpath,
4247+ local_tree.branch,
4248+ target_dir=(td if not skip_upload else None),
4249+ builder=builder,
4250+ apt=apt,
4251+ )
4252+ if not skip_upload:
4253+ try:
4254+ source_path = changes_files["source"]
4255+ except KeyError as e:
4256+ raise BzrCommandError(
4257+ "No source package was created by build command"
4258+ ) from e
4259+ dput_changes(source_path)
4260+ local_tree.branch.push(branch)
4261
4262=== added file 'breezy/plugins/debian/config.py'
4263--- breezy/plugins/debian/config.py 1970-01-01 00:00:00 +0000
4264+++ breezy/plugins/debian/config.py 2024-02-18 23:22:42 +0000
4265@@ -0,0 +1,406 @@
4266+# config.py -- Configuration of bzr-builddeb from files
4267+# Copyright (C) 2006 James Westby <jw+debian@jameswestby.net>
4268+#
4269+# This file is part of breezy-debian.
4270+#
4271+# bzr-builddeb is free software; you can redistribute it and/or modify
4272+# it under the terms of the GNU General Public License as published by
4273+# the Free Software Foundation; either version 2 of the License, or
4274+# (at your option) any later version.
4275+#
4276+# bzr-builddeb is distributed in the hope that it will be useful,
4277+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4278+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4279+# GNU General Public License for more details.
4280+#
4281+# You should have received a copy of the GNU General Public License
4282+# along with bzr-builddeb; if not, write to the Free Software
4283+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4284+#
4285+
4286+import yaml
4287+
4288+from breezy.transport import NoSuchFile
4289+
4290+from ...config import (
4291+ ConfigObj,
4292+ TreeConfig,
4293+ configobj,
4294+)
4295+from ...errors import BzrError
4296+from ...trace import mutter, warning
4297+
4298+BUILD_TYPE_NORMAL = "normal"
4299+BUILD_TYPE_NATIVE = "native"
4300+BUILD_TYPE_MERGE = "merge"
4301+BUILD_TYPE_SPLIT = "split"
4302+
4303+
4304+class SvnBuildPackageMappedConfig:
4305+ """Config object that provides a bzr-builddeb configuration
4306+ based on a svn-buildpackage configuration.
4307+ """
4308+
4309+ def __init__(self, bp_config):
4310+ self.bp_config = bp_config
4311+
4312+ def get_option(self, option, section=None):
4313+ """Retrieve the contents of an option, mapped from the equivalent
4314+ svn-buildpackage option.
4315+ """
4316+ if section == "BUILDDEB":
4317+ if option == "merge":
4318+ return self.bp_config.get_merge_with_upstream()
4319+ elif option == "orig-dir":
4320+ return self.bp_config.get("origDir")
4321+ elif option == "build-dir":
4322+ return self.bp_config.get("buildArea")
4323+ return None
4324+
4325+
4326+class UpstreamMetadataSyntaxError(BzrError):
4327+ """There is a syntax error in the debian/upstream/metadata file."""
4328+
4329+ _fmt = "Unable to parse upstream metadata file %(path)s: %(error)s"
4330+
4331+ def __init__(self, path, error):
4332+ self.path = path
4333+ self.error = error
4334+
4335+
4336+class UpstreamMetadataConfig:
4337+ """Config object that represents debian/upstream/metadata."""
4338+
4339+ filename = "debian/upstream/metadata"
4340+
4341+ def __init__(self, text):
4342+ try:
4343+ self.metadata = yaml.safe_load(text)
4344+ except yaml.composer.ComposerError as e:
4345+ all_metadata = [x for x in yaml.safe_load_all(text) if x is not None]
4346+ if len(all_metadata) != 1:
4347+ raise UpstreamMetadataSyntaxError(
4348+ "debian/upstream/metadata", Exception("multiple documents found")
4349+ ) from e
4350+ warning("ignoring empty extra documents in debian/upstream/metadata")
4351+ self.metadata = all_metadata[0]
4352+ except (
4353+ yaml.scanner.ScannerError,
4354+ yaml.parser.ParserError,
4355+ ) as e:
4356+ raise UpstreamMetadataSyntaxError("debian/upstream/metadata", e) from e
4357+ if isinstance(self.metadata, str):
4358+ raise UpstreamMetadataSyntaxError(
4359+ "debian/upstream/metadata", TypeError(self.metadata)
4360+ )
4361+ if isinstance(self.metadata, list):
4362+ raise UpstreamMetadataSyntaxError(
4363+ "debian/upstream/metadata", TypeError(self.metadata)
4364+ )
4365+
4366+ def get_value(self, section, option):
4367+ if section == "BUILDDEB":
4368+ if option == "upstream-branch":
4369+ return self.metadata.get("Repository")
4370+ if option == "export-upstream-revision":
4371+ tag_prefix = self.metadata.get("Repository-Tag-Prefix")
4372+ if tag_prefix is not None:
4373+ return "tag:" + tag_prefix + "$UPSTREAM_VERSION"
4374+ raise KeyError
4375+
4376+ def __getitem__(self, key):
4377+ return self.get_value(key, "BUILDDEB")
4378+
4379+ def get_bool(self, section, option):
4380+ raise KeyError
4381+
4382+ def as_bool(self, option):
4383+ raise KeyError
4384+
4385+
4386+class DebBuildConfig:
4387+ """Holds the configuration settings for builddeb. These are taken from
4388+ a hierarchy of config files. .bzr-builddeb/local.conf then
4389+ debian/bzr-builddeb.conf.local,
4390+ ~/.bazaar/builddeb.conf, debian/bzr-builddeb.conf,
4391+ finally .bzr-builddeb/default.conf. The value is
4392+ taken from the first file in which it is specified.
4393+ """
4394+
4395+ section = "BUILDDEB"
4396+
4397+ def __init__(self, files, branch=None, tree=None):
4398+ """Creates a config to read from config files in a hierarchy.
4399+
4400+ Pass it a list of tuples (file, secure) where file is the location of a
4401+ config file (that doesn't have to exist, and trusted is True or false,
4402+ and states whether the file can be trusted for sensitive values.
4403+
4404+ The value will be returned from the first in the list that has it,
4405+ unless that key is marked as needing a trusted file and the file isn't
4406+ trusted.
4407+
4408+ If branch is not None then it will be used in preference to all others.
4409+ It will not be considered trusted.
4410+
4411+ The sample files used in this test are included in the builddeb source
4412+ tree.
4413+
4414+ >>> import os
4415+ >>> import breezy.plugins.debian
4416+ >>> d = os.path.dirname(breezy.plugins.debian.__file__) + '/'
4417+ >>> c = DebBuildConfig([
4418+ ... (d + 'local.conf', False),
4419+ ... (d + 'user.conf', True),
4420+ ... (d + 'default.conf', False)])
4421+ >>> print(c.orig_dir)
4422+ None
4423+ >>> print(c.merge)
4424+ True
4425+ >>> print(c.build_dir)
4426+ defaultbuild
4427+ >>> print(c.result_dir)
4428+ userresult
4429+ >>> print(c.builder)
4430+ userbuild
4431+ """
4432+ self._config_files = []
4433+ for input in files:
4434+ try:
4435+ config = ConfigObj(input[0])
4436+ except configobj.ParseError as e:
4437+ if len(input) > 2:
4438+ content = input[2]
4439+ else:
4440+ content = input[0]
4441+ warning("There was an error parsing '%s': %s", content, e.msg)
4442+ continue
4443+ if len(input) > 2:
4444+ config.filename = input[2]
4445+ self._config_files.append((config, input[1]))
4446+ if branch is not None:
4447+ self._branch_config = TreeConfig(branch)
4448+ else:
4449+ self._branch_config = None
4450+ self._tree_config = None
4451+ if tree is not None:
4452+ try:
4453+ # Imported here, since not everybody will have bzr-svn
4454+ # installed
4455+ from ..svn.config import (
4456+ NoSubversionBuildPackageConfig,
4457+ SubversionBuildPackageConfig,
4458+ )
4459+
4460+ try:
4461+ self._tree_config = SvnBuildPackageMappedConfig(
4462+ SubversionBuildPackageConfig(tree)
4463+ )
4464+ except NoSubversionBuildPackageConfig:
4465+ pass # Not a svn tree
4466+ except ImportError:
4467+ pass # No svn, apparently
4468+ try:
4469+ try:
4470+ upstream_metadata_text = tree.get_file_text(
4471+ UpstreamMetadataConfig.filename
4472+ )
4473+ except IsADirectoryError:
4474+ upstream_metadata_text = tree.get_file_text("debian/upstream")
4475+ except NoSuchFile:
4476+ pass
4477+ else:
4478+ try:
4479+ self._config_files.append(
4480+ (UpstreamMetadataConfig(upstream_metadata_text), False)
4481+ )
4482+ except UpstreamMetadataSyntaxError as e:
4483+ warning("Ignoring upstream metadata due to %s", e)
4484+ self.user_config = None
4485+
4486+ def set_user_config(self, user_conf):
4487+ if user_conf is not None:
4488+ self.user_config = ConfigObj(user_conf)
4489+
4490+ def _user_config_value(self, key):
4491+ if self.user_config is not None:
4492+ try:
4493+ return self.user_config.get_value(self.section, key)
4494+ except KeyError:
4495+ pass
4496+ return None
4497+
4498+ def _get_opt(self, config, key, section=None):
4499+ """Returns the value for key from config, of None if it is not defined
4500+ in the file.
4501+ """
4502+ if section is None:
4503+ section = self.section
4504+ try:
4505+ return config.get_value(section, key)
4506+ except KeyError:
4507+ pass
4508+ if config.filename is not None:
4509+ try:
4510+ config[key]
4511+ warning(
4512+ "'{}' defines a value for '{}', but it is not in a '{}' "
4513+ "section, so it is ignored".format(config.filename, key, section)
4514+ )
4515+ except KeyError:
4516+ pass
4517+ return None
4518+
4519+ def _get_best_opt(self, key, trusted=False, section=None):
4520+ """Returns the value for key, obeying precedence.
4521+
4522+ Returns the value for the key from the first file in which it is
4523+ defined, or None if none of the files define it.
4524+
4525+ If trusted is True then the the value will only be taken from a file
4526+ marked as trusted.
4527+
4528+ """
4529+ if section is None:
4530+ section = self.section
4531+ if not trusted:
4532+ if self._branch_config is not None:
4533+ value = self._branch_config.get_option(key, section=self.section)
4534+ if value is not None:
4535+ mutter("Using %s for %s, taken from the branch", value, key)
4536+ return value
4537+ if self._tree_config is not None:
4538+ value = self._tree_config.get_option(key, section=self.section)
4539+ if value is not None:
4540+ mutter("Using %s for %s, taken from the tree", value, key)
4541+ return value
4542+ for config_file in self._config_files:
4543+ if not trusted or config_file[1]:
4544+ value = self._get_opt(config_file[0], key, section=section)
4545+ if value is not None:
4546+ mutter(
4547+ "Using %s for %s, taken from %s",
4548+ value,
4549+ key,
4550+ config_file[0].filename,
4551+ )
4552+ return value
4553+ return None
4554+
4555+ def get_hook(self, hook_name):
4556+ return self._get_best_opt(hook_name, section="HOOKS")
4557+
4558+ def _get_bool(self, config, key):
4559+ try:
4560+ return True, config.get_bool("BUILDDEB", key)
4561+ except KeyError:
4562+ pass
4563+ if config.filename is not None:
4564+ try:
4565+ config.as_bool(key)
4566+ warning(
4567+ "'{}' defines a value for '{}', but it is not in a "
4568+ "'BUILDDEB' section, so it is ignored".format(config.filename, key)
4569+ )
4570+ except KeyError:
4571+ pass
4572+ return False, False
4573+
4574+ def _get_best_bool(self, key, trusted=False, default=False):
4575+ """Returns the value of key, obeying precedence.
4576+
4577+ Returns the value for the key from the first file in which it is
4578+ defined, or default if none of the files define it.
4579+
4580+ If trusted is True then the the value will only be taken from a file
4581+ marked as trusted.
4582+
4583+ """
4584+ if not trusted:
4585+ if self._branch_config is not None:
4586+ value = self._branch_config.get_option(key, section=self.section)
4587+ if value is not None:
4588+ mutter("Using %s for %s, taken from the branch", value, key)
4589+ return value
4590+ if self._tree_config is not None:
4591+ value = self._tree_config.get_option(key, section=self.section)
4592+ if value is not None:
4593+ mutter("Using %s for %s, taken from the tree", value, key)
4594+ return value
4595+ for config_file in self._config_files:
4596+ if not trusted or config_file[1]:
4597+ (found, value) = self._get_bool(config_file[0], key)
4598+ if found:
4599+ mutter(
4600+ "Using %s for %s, taken from %s",
4601+ str(value),
4602+ key,
4603+ config_file[0].filename,
4604+ )
4605+ return value
4606+ return default
4607+
4608+ @staticmethod
4609+ def _opt_property(name: str, help=None, trusted=False) -> property:
4610+ return property(
4611+ lambda self: self._get_best_opt(name, trusted), None, None, help
4612+ )
4613+
4614+ @staticmethod
4615+ def _bool_property(name, help=None, trusted=False, default=False) -> property:
4616+ return property(
4617+ lambda self: self._get_best_bool(name, trusted, default), None, None, help
4618+ )
4619+
4620+ build_dir = _opt_property("build-dir", "The dir to build in")
4621+
4622+ user_build_dir = property(lambda self: self._user_config_value("build-dir"))
4623+
4624+ orig_dir = _opt_property("orig-dir", "The dir to get upstream tarballs from")
4625+
4626+ user_orig_dir = property(lambda self: self._user_config_value("orig-dir"))
4627+
4628+ builder = _opt_property("builder", "The command to build with", True)
4629+
4630+ result_dir = _opt_property("result-dir", "The dir to put the results in")
4631+
4632+ user_result_dir = property(lambda self: self._user_config_value("result-dir"))
4633+
4634+ merge = _bool_property("merge", "Run in merge mode")
4635+
4636+ @property
4637+ def build_type(self):
4638+ if self.merge:
4639+ return BUILD_TYPE_MERGE
4640+ elif self.native:
4641+ return BUILD_TYPE_NATIVE
4642+ elif self.split:
4643+ return BUILD_TYPE_SPLIT
4644+ else:
4645+ return None
4646+
4647+ quick_builder = _opt_property(
4648+ "quick-builder", "A quick command to build with", True
4649+ )
4650+
4651+ native = _bool_property("native", "Build a native package")
4652+
4653+ split = _bool_property("split", "Split a full source package")
4654+
4655+ upstream_branch = _opt_property(
4656+ "upstream-branch", "The upstream branch to merge from"
4657+ )
4658+
4659+ export_upstream_revision = _opt_property(
4660+ "export-upstream-revision", "The revision of the upstream source to use."
4661+ )
4662+
4663+
4664+def _test():
4665+ import doctest
4666+
4667+ doctest.testmod()
4668+
4669+
4670+if __name__ == "__main__":
4671+ _test()
4672
4673=== added file 'breezy/plugins/debian/default.conf'
4674--- breezy/plugins/debian/default.conf 1970-01-01 00:00:00 +0000
4675+++ breezy/plugins/debian/default.conf 2024-02-18 23:22:42 +0000
4676@@ -0,0 +1,6 @@
4677+[BUILDDEB]
4678+builder = defaultexport
4679+result-dir = defaultresult
4680+build-dir = defaultbuild
4681+merge = True
4682+
4683
4684=== added file 'breezy/plugins/debian/dep3.py'
4685--- breezy/plugins/debian/dep3.py 1970-01-01 00:00:00 +0000
4686+++ breezy/plugins/debian/dep3.py 2024-02-18 23:22:42 +0000
4687@@ -0,0 +1,255 @@
4688+# dep3.py -- DEP-3 compatible patch formatting
4689+# Copyright (C) 2011 Canonical Ltd.
4690+#
4691+# This file is part of bzr-builddeb.
4692+#
4693+# bzr-builddeb is free software; you can redistribute it and/or modify
4694+# it under the terms of the GNU General Public License as published by
4695+# the Free Software Foundation; either version 2 of the License, or
4696+# (at your option) any later version.
4697+#
4698+# bzr-builddeb is distributed in the hope that it will be useful,
4699+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4700+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4701+# GNU General Public License for more details.
4702+#
4703+# You should have received a copy of the GNU General Public License
4704+# along with bzr-builddeb; if not, write to the Free Software
4705+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4706+#
4707+
4708+"""DEP-3 style patch formatting."""
4709+
4710+import time
4711+from email.message import Message
4712+from io import BytesIO
4713+
4714+from breezy.foreign import foreign_vcs_registry
4715+
4716+from ... import (
4717+ diff,
4718+ errors,
4719+)
4720+
4721+
4722+def write_dep3_bug_line(message, bug_url, status):
4723+ """Write a DEP-3 compatible line with a bug link.
4724+
4725+ :param message: Message object to udpate
4726+ :param bug_url: Bug URL
4727+ :param status: Bug status (e.g. "fixed")
4728+ """
4729+ # For the moment, we only care about fixed bugs
4730+ if status != "fixed":
4731+ return
4732+ if bug_url.startswith("http://bugs.debian.org/"):
4733+ message.add_header("Bug-Debian", bug_url)
4734+ else:
4735+ # FIXME: Filter out Ubuntu bugs on Launchpad
4736+ message.add_header("Bug", bug_url)
4737+
4738+
4739+def write_dep3_patch_header(
4740+ f,
4741+ description=None,
4742+ origin=None,
4743+ forwarded=None,
4744+ bugs=None,
4745+ authors=None,
4746+ revision_id=None,
4747+ last_update=None,
4748+ applied_upstream=None,
4749+):
4750+ """Write a DEP3 patch header.
4751+
4752+ :param f: File-like object to write to
4753+ :param description: Description of the patch
4754+ :param origin: Single line describing the origin of the patch
4755+ :param forwarded: Single line describing whether and how the patch was
4756+ forwarded
4757+ :param bugs: Set of bugs fixed in this patch
4758+ :param authors: Authors of the patch
4759+ :param revision_id: Relevant bzr revision id
4760+ :param last_update: Last update timestamp
4761+ :param applied_upstream: If the patch is applied upstream,
4762+ an informal string describing where it was merged
4763+ """
4764+ header = Message()
4765+ if description is not None:
4766+ description = description.strip("\n")
4767+ description = description.replace("\n\n", "\n.\n")
4768+ description = description.replace("\n", "\n ")
4769+ header["Description"] = description
4770+ if origin is not None:
4771+ header.add_header("Origin", origin)
4772+ if forwarded is not None:
4773+ header.add_header("Forwarded", forwarded)
4774+ if authors is not None:
4775+ for author in authors:
4776+ header.add_header("Author", author)
4777+ if bugs is not None:
4778+ for bug_url, status in bugs:
4779+ write_dep3_bug_line(header, bug_url, status)
4780+ if last_update is not None:
4781+ header.add_header(
4782+ "Last-Update", time.strftime("%Y-%m-%d", time.gmtime(last_update))
4783+ )
4784+ if applied_upstream is not None:
4785+ header.add_header("Applied-Upstream", applied_upstream)
4786+ if revision_id is not None:
4787+ try:
4788+ (foreign_revid, mapping) = foreign_vcs_registry.parse_revision_id(
4789+ revision_id
4790+ )
4791+ except errors.InvalidRevisionId:
4792+ header.add_header("X-Bzr-Revision-Id", revision_id.decode("utf-8"))
4793+ else:
4794+ if mapping.vcs.abbreviation == "git":
4795+ header.add_header("X-Git-Commit", foreign_revid.decode("utf-8"))
4796+ f.write(str(header))
4797+
4798+
4799+def gather_bugs_and_authors(repository, interesting_revision_ids):
4800+ """Gather bug and author information from revisions.
4801+
4802+ :param interesting_revision_ids: Iterable of revision ids to check
4803+ :return: Tuple of bugs, authors and highest found commit timestamp
4804+ """
4805+ authors = set()
4806+ bugs = set()
4807+ last_update = -0.0
4808+ for rev in repository.get_revisions(interesting_revision_ids):
4809+ last_update = max(rev.timestamp, last_update)
4810+ authors.update(rev.get_apparent_authors())
4811+ from breezy.revision import iter_bugs
4812+
4813+ extra_bugs = iter_bugs(rev)
4814+ bugs.update(extra_bugs)
4815+ if last_update == -0.0:
4816+ last_update = None
4817+ return (bugs, authors, last_update)
4818+
4819+
4820+def determine_applied_upstream(upstream_branch, feature_branch, feature_revid=None):
4821+ """Check if a particular revision has been merged upstream.
4822+
4823+ :param upstream_branch: Upstream branch object
4824+ :param feature_branch: Feature branch
4825+ :param feature_revid: Revision id in feature branch to check,
4826+ defaults to feature_branch tip.
4827+ :return: String that can be used for Applied-Upstream field
4828+ """
4829+ if feature_revid is None:
4830+ feature_revid = feature_branch.last_revision()
4831+ upstream_graph = feature_branch.repository.get_graph(upstream_branch.repository)
4832+ merger = upstream_graph.find_lefthand_merger(
4833+ feature_revid, upstream_branch.last_revision()
4834+ )
4835+ if merger is not None:
4836+ try:
4837+ (foreign_revid, mapping) = foreign_vcs_registry.parse_revision_id(merger)
4838+ except errors.InvalidRevisionId:
4839+ pass
4840+ else:
4841+ if mapping.vcs.abbreviation == "git":
4842+ return "merged in commit {}".format(foreign_revid.decode("ascii")[:7])
4843+ return "merged in revision {}".format(
4844+ ".".join(
4845+ str(x) for x in upstream_branch.revision_id_to_dotted_revno(merger)
4846+ )
4847+ )
4848+ else:
4849+ return "no"
4850+
4851+
4852+def determine_forwarded(upstream_branch, feature_branch, feature_revid):
4853+ """See if a branch has been forwarded to upstream.
4854+
4855+ :param upstream_branch: Upstream branch object
4856+ :param feature_branch: Feature branch
4857+ :param feature_revid: Revision id in feature branch to check
4858+ :return: String that can be used for Applied-Upstream field
4859+ """
4860+ # FIXME: Check for Launchpad merge proposals from feature_branch (or its
4861+ # public_branch) to upstream_branch
4862+
4863+ # Are there any other ways to see that a patch has been forwarded upstream?
4864+ return None
4865+
4866+
4867+def describe_origin(branch, revid):
4868+ """Describe a tree for use in the origin field.
4869+
4870+ :param branch: Branch to retrieve the revision from
4871+ :param revid: Revision id
4872+ """
4873+ public_branch_url = branch.get_public_branch()
4874+ if public_branch_url is not None:
4875+ try:
4876+ (foreign_revid, mapping) = foreign_vcs_registry.parse_revision_id(revid)
4877+ except errors.InvalidRevisionId:
4878+ pass
4879+ else:
4880+ if mapping.vcs.abbreviation == "git":
4881+ return "commit, {}, commit: {}".format(
4882+ public_branch_url, foreign_revid.decode("ascii")[:7]
4883+ )
4884+ return "commit, {}, revision: {}".format(
4885+ public_branch_url,
4886+ ".".join(str(x) for x in branch.revision_id_to_dotted_revno(revid)),
4887+ )
4888+ else:
4889+ try:
4890+ (foreign_revid, mapping) = foreign_vcs_registry.parse_revision_id(revid)
4891+ except errors.InvalidRevisionId:
4892+ pass
4893+ else:
4894+ if mapping.vcs.abbreviation == "git":
4895+ return "commit: {}".format(foreign_revid.decode("ascii")[:7])
4896+ return "commit, revision id: %s" % revid.decode("utf-8")
4897+
4898+
4899+def write_dep3_patch(
4900+ f,
4901+ branch,
4902+ base_revid,
4903+ target_revid,
4904+ description=None,
4905+ origin=None,
4906+ forwarded=None,
4907+ applied_upstream=None,
4908+ bugs=None,
4909+ authors=None,
4910+ last_update=None,
4911+):
4912+ """Write a DEP-3 compliant patch.
4913+
4914+ :param f: File-like object to write to
4915+ :param repository: Repository to retrieve revisions from
4916+ :param base_revid: Base revision id
4917+ :param target_revid: Target revision id
4918+ :param description: Optional description
4919+ :param forwarded: Optional information on if/how the patch was forwarded
4920+ :param applied_upstream: Optional information on how whether the patch
4921+ was merged upstream
4922+ :param bugs: Sequence of bug reports related to this patch
4923+ :param authors: Sequence of authors of this patch
4924+ :param last_update: Timestamp for last time this patch was updated
4925+ """
4926+ write_dep3_patch_header(
4927+ f,
4928+ bugs=bugs,
4929+ authors=authors,
4930+ last_update=last_update,
4931+ description=description,
4932+ revision_id=target_revid,
4933+ origin=origin,
4934+ applied_upstream=applied_upstream,
4935+ forwarded=forwarded,
4936+ )
4937+ old_tree = branch.repository.revision_tree(base_revid)
4938+ new_tree = branch.repository.revision_tree(target_revid)
4939+ bf = BytesIO()
4940+ diff.show_diff_trees(old_tree, new_tree, bf, old_label="old/", new_label="new/")
4941+ # TODO(jelmer)
4942+ f.write(bf.getvalue().decode("utf-8"))
4943
4944=== added file 'breezy/plugins/debian/directory.py'
4945--- breezy/plugins/debian/directory.py 1970-01-01 00:00:00 +0000
4946+++ breezy/plugins/debian/directory.py 2024-02-18 23:22:42 +0000
4947@@ -0,0 +1,266 @@
4948+# directory.py -- Directory service that uses Debian Vcs-* fields
4949+# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
4950+#
4951+# This file is part of bzr-builddeb.
4952+#
4953+# bzr-builddeb is free software; you can redistribute it and/or modify
4954+# it under the terms of the GNU General Public License as published by
4955+# the Free Software Foundation; either version 2 of the License, or
4956+# (at your option) any later version.
4957+#
4958+# bzr-builddeb is distributed in the hope that it will be useful,
4959+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4960+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4961+# GNU General Public License for more details.
4962+#
4963+# You should have received a copy of the GNU General Public License
4964+# along with bzr-builddeb; if not, write to the Free Software
4965+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4966+#
4967+
4968+from debian.changelog import Version
4969+from debian.deb822 import Deb822
4970+from debmutate.vcs import source_package_vcs, split_vcs_url
4971+
4972+from ... import urlutils
4973+from ...directory_service import directories
4974+from ...errors import DependencyNotPresent
4975+from ...trace import note, warning
4976+
4977+
4978+def fixup_broken_git_url(url):
4979+ """Attempt to fix up broken Git URLs.
4980+
4981+ A common misspelling is to add an extra ":" after the hostname
4982+ """
4983+ (scheme, netloc, path, params, query, fragment) = urlutils.urlparse.urlparse(
4984+ url, allow_fragments=False
4985+ )
4986+ if "@" in netloc:
4987+ credentials, host = netloc.rsplit("@", 1)
4988+ else:
4989+ credentials = None
4990+ host = netloc
4991+
4992+ if ":" in host and not (host[0] == "[" and host[-1] == "]"):
4993+ # there *is* port
4994+ host, port = host.rsplit(":", 1)
4995+ if not port or port.isdigit():
4996+ return url
4997+ else:
4998+ port = None
4999+
5000+ if host in ("salsa.debian.org", "github.com"):
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches