Follow the layout and idioms of the dpkg-source completion, using the
bash-completion 2.12 API.  Complete option names, and values for the
options that take one: build types, rules targets, architectures via
dpkg-architecture --list-known, build profiles, OpenPGP backends,
compression parameters, hook and other command arguments, pathname
arguments, and the positional .dsc filename or source directory.
Unlike dpkg-source, split the words on "=" and complete the long options
in that spelling, as many of them only accept a value in that form.

The options taking a comma-separated list (--build, --rules-target and
--build-profiles) are completed element per element, and the ones taking
an optional value only in the "=" form (--jobs and friends,
--diff-ignore and --tar-ignore) offer both spellings.

The --buildinfo-id, -E and -W options, which are accepted but without
effect, are intentionally not completed.

Closes: #1061450
---
 debian/copyright                          |   1 +
 debian/dpkg-dev.install                   |   1 +
 scripts/Makefile.am                       |   1 +
 scripts/completion/bash/dpkg-buildpackage | 170 ++++++++++++++++++++++
 4 files changed, 173 insertions(+)
 create mode 100644 scripts/completion/bash/dpkg-buildpackage

diff --git a/debian/copyright b/debian/copyright
index d8a445fd1..7ddcf9e6c 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -87,6 +87,7 @@ Copyright:
  Copyright © 2018 Uwe Storbeck <[email protected]>
  Copyright © 2021-2024 Koichi Murase <[email protected]>
  Copyright © 2024 Arnaud Rebillout <[email protected]>
+ Copyright © 2026 Cheng Li <[email protected]>
  Copyright © 2026 Guillem Jover <[email protected]>
 License: GPL-2+
 
diff --git a/debian/dpkg-dev.install b/debian/dpkg-dev.install
index 3d87080cc..4a509496a 100644
--- a/debian/dpkg-dev.install
+++ b/debian/dpkg-dev.install
@@ -21,6 +21,7 @@ usr/bin/dpkg-scansources
 usr/bin/dpkg-shlibdeps
 usr/bin/dpkg-source
 usr/bin/dpkg-vendor
+usr/share/bash-completion/completions/dpkg-buildpackage
 usr/share/bash-completion/completions/dpkg-source
 usr/share/dpkg/*.mk
 usr/share/zsh/vendor-completions/_dpkg-parsechangelog
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 0fa3165bf..4d91e602c 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -155,6 +155,7 @@ CLEANFILES += \
        # EOL
 
 dist_bashcompletions_DATA = \
+       completion/bash/dpkg-buildpackage \
        completion/bash/dpkg-source \
        # EOL
 
diff --git a/scripts/completion/bash/dpkg-buildpackage 
b/scripts/completion/bash/dpkg-buildpackage
new file mode 100644
index 000000000..3497e309a
--- /dev/null
+++ b/scripts/completion/bash/dpkg-buildpackage
@@ -0,0 +1,170 @@
+#!/bin/bash
+# dpkg-buildpackage(1) bash completion
+#
+# Copyright © 2026 Cheng Li <[email protected]>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+_comp_cmd_dpkg_buildpackage()
+{
+  # shellcheck disable=SC2034
+  local cur prev words cword was_split comp_args
+  _comp_initialize -s -- "$@" || return
+
+  local -a options buildtypes rulestargets hookopts sourceopts
+  local hook
+
+  buildtypes=(
+    source
+    any
+    all
+    binary
+    full
+  )
+  rulestargets=(
+    clean
+    build
+    build-arch
+    build-indep
+    binary
+    binary-arch
+    binary-indep
+  )
+  hookopts=()
+  for hook in preinit init preclean source build binary buildinfo \
+              changes postclean check sign 'done'; do
+    hookopts+=("--hook-$hook=")
+  done
+  sourceopts=(
+    -si -sa -sd
+    -sn -ss -sA -sk -su -sr -sK -sU -sR
+    -i --diff-ignore --diff-ignore=
+    -I --tar-ignore --tar-ignore=
+    -z --compression-level=
+    -Z --compression=
+    --source-option=
+  )
+  options=(
+    --help --version
+    --admindir=
+    --build=
+    -b -B -A -S -G -g -F
+    -T --target= --rules-target=
+    --as-root
+    --rules-requires-root
+    -R --rules-file=
+    --pre-clean -nc --no-pre-clean
+    -tc --post-clean --no-post-clean
+    --sanitize-env
+    -d -D --check-builddeps --no-check-builddeps
+    --ignore-builtin-builddeps
+    -j -J --jobs --jobs= --jobs-try --jobs-try= --jobs-force --jobs-force=
+    -a --host-arch=
+    -t --host-type=
+    --target-arch= --target-type=
+    -P --build-profiles=
+    -v -C
+    -m --source-by= --build-by=
+    -e --changed-by= --release-by=
+    --changes-option= --changes-file=
+    --buildinfo-option= --buildinfo-file=
+    --check-command= --check-option=
+    -r --root-command=
+    --sign-backend=
+    -p --sign-command=
+    --sign-keyfile=
+    -k --sign-keyid=
+    --sign-key=
+    --force-sign --no-sign
+    -us --unsigned-source
+    -ui --unsigned-buildinfo
+    -uc --unsigned-changes
+    -ap --sign-pause
+    "${hookopts[@]}"
+    "${sourceopts[@]}"
+  )
+
+  case $prev in
+  --admindir)
+    _comp_compgen_filedir -d
+    return
+    ;;
+  --build)
+    _comp_delimited , -W "${buildtypes[*]}"
+    return
+    ;;
+  -T | --target | --rules-target)
+    _comp_delimited , -W "${rulestargets[*]}"
+    return
+    ;;
+  -a | --host-arch | --target-arch)
+    _comp_compgen_split -- "$(command dpkg-architecture --list-known 
2>/dev/null)"
+    return
+    ;;
+  --build-profiles)
+    # Complete the registered common profiles.
+    _comp_delimited , -W 'cross nocheck nodoc noinsttest nopython noudeb
+      stage1 stage2'
+    return
+    ;;
+  --rules-file | --sign-keyfile | --buildinfo-file | --changes-file)
+    _comp_compgen_filedir
+    return
+    ;;
+  --root-command | --sign-command | --check-command | --hook-*)
+    _comp_compgen_commands
+    return
+    ;;
+  --sign-backend)
+    _comp_compgen -- -W 'auto gpg sq sop'
+    return
+    ;;
+  --compression)
+    _comp_compgen -- -W 'gzip xz bzip2 lzma'
+    return
+    ;;
+  --compression-level)
+    _comp_compgen -- -W '{0..9}'
+    return
+    ;;
+  --jobs | --jobs-try | --jobs-force)
+    # These options accept an optional value only in the = form.
+    [[ $was_split ]] || return
+    _comp_compgen -- -W 'auto'
+    return
+    ;;
+  -t | --host-type | --target-type)
+    # GNU system types, no sensible completion.
+    return
+    ;;
+  --source-by | --build-by | --changed-by | --release-by | \
+  --sign-key | --sign-keyid | --source-option | --changes-option | \
+  --buildinfo-option | --check-option)
+    # Free-form values, no sensible completion.
+    return
+    ;;
+  esac
+
+  # A value glued to a long option with "=" was already handled above.
+  [[ $was_split ]] && return
+
+  if [[ $cur == -* ]]; then
+    _comp_compgen -- -W "${options[*]}"
+    [[ ${COMPREPLY-} == *= ]] && compopt -o nospace
+    return
+  fi
+
+  # The optional positional argument is a .dsc file or a source directory.
+  _comp_compgen_filedir 'dsc'
+} && complete -F _comp_cmd_dpkg_buildpackage dpkg-buildpackage
-- 
2.47.3

Reply via email to