Merge lp:~jelmer/brz/join-debian into lp:brz
- join-debian
- Merge into trunk
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 |
Related bugs: |
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
The Breezy Bot (the-breezy-bot) wrote : | # |
Attempt to merge into lp:brz failed due to conflicts:
text conflict in tarmac.conf
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-
The Breezy Bot (the-breezy-bot) wrote : | # |
Attempt to merge into lp:brz failed due to conflicts:
text conflict in tarmac.conf
The Breezy Bot (the-breezy-bot) wrote : | # |
Attempt to merge into lp:brz failed due to conflicts:
text conflict in tarmac.conf
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
...
The Breezy Bot (the-breezy-bot) wrote : | # |
Attempt to merge into lp:brz failed due to conflicts:
text conflict in Cargo.lock
The Breezy Bot (the-breezy-bot) wrote : | # |
Attempt to merge into lp:brz failed due to conflicts:
text conflict in Cargo.lock
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.
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.
Using cached setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Using cached testtools-
Collecting testscenarios
Using cached testscenarios-
Collecting python-subunit
Using cached python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Using cached docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Using cached sphinx-
Collecting sphinx-epytext
Using cached sphinx_
Collecting fastimport
Using cached fastimport-
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
Requirement already satisfied: httplib2 in /usr/lib/
Requirement already satisfied: lazr.restfulcli
Requirement already satisfied:...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=46.1 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
R...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5
Downloading testtools-
Collecting testscenarios
Downloading testscenarios-
Collecting python-subunit
Downloading python_
Collecting cython>=0.29
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx
Downloading sphinx-
Collecting sphinx-epytext
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport
Downloading fastimport-
━━
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: launchpadlib>=1.6.3 in /usr/lib/
Requirement already satisfied: paramiko>=1.6.2 in /usr/local/
Requirement already satisfied: gpg in /usr/lib/
...
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/
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5 (from breezy==3.4.0.dev0)
Downloading testtools-
Collecting testscenarios (from breezy==3.4.0.dev0)
Downloading testscenarios-
Collecting python-subunit (from breezy==3.4.0.dev0)
Downloading python_
Collecting cython>=0.29 (from breezy==3.4.0.dev0)
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils (from breezy==3.4.0.dev0)
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx (from breezy==3.4.0.dev0)
Downloading sphinx-
Collecting sphinx-epytext (from breezy==3.4.0.dev0)
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport (from breezy==3.4.0.dev0)
Downloading fastimport-
━━━...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5 (from breezy==3.4.0.dev0)
Downloading testtools-
Collecting testscenarios (from breezy==3.4.0.dev0)
Downloading testscenarios-
Collecting python-subunit (from breezy==3.4.0.dev0)
Downloading python_
Collecting cython>=0.29 (from breezy==3.4.0.dev0)
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Collecting docutils (from breezy==3.4.0.dev0)
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx (from breezy==3.4.0.dev0)
Downloading sphinx-
Collecting sphinx-epytext (from breezy==3.4.0.dev0)
Downloading sphinx-
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Collecting fastimport (from breezy==3.4.0.dev0)
Downloading fastimport-
━━━...
The Breezy Bot (the-breezy-bot) wrote : | # |
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_
Requirement already satisfied: setuptools>=60.8 in ./lib/python3.
Downloading setuptools_
Installing collected packages: setuptools-gettext
Successfully installed setuptools-
Obtaining file://
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/
Requirement already satisfied: fastbencode in /usr/lib/
Requirement already satisfied: patiencediff in /usr/lib/
Requirement already satisfied: merge3 in /usr/lib/
Requirement already satisfied: dulwich>=0.21.6 in /usr/lib/
Requirement already satisfied: urllib3>=1.24.1 in /usr/lib/
Requirement already satisfied: pyyaml in /usr/lib/
Collecting testtools>=0.9.5 (from breezy==3.4.0.dev0)
Downloading testtools-
Collecting testscenarios (from breezy==3.4.0.dev0)
Downloading testscenarios-
Collecting python-subunit (from breezy==3.4.0.dev0)
Downloading python_
Collecting cython>=0.29 (from breezy==3.4.0.dev0)
Using cached Cython-
Requirement already satisfied: ruff in /usr/local/
Requirement already satisfied: types-paramiko in /usr/lib/
Requirement already satisfied: types-PyYAML in /usr/lib/
Collecting docutils (from breezy==3.4.0.dev0)
Downloading docutils-
Requirement already satisfied: setuptools in ./lib/python3.
Collecting sphinx (from breezy==3.4.0.dev0)
Downloading sphinx-
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
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"): |
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