diff options
| author | Julian Andres Klode <jak@debian.org> | 2021-04-23 12:54:46 +0000 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2021-04-23 12:54:46 +0000 |
| commit | 64376abd263aa3ea684c4d8debaec2b321306b47 (patch) | |
| tree | 1c7bd0e0fd4c51f1d5a40e65de90535db9ed4a39 /test/integration/test-apt-cli-json-hooks | |
| parent | 6970632b35890238da97db8b7ec4a28298911051 (diff) | |
| parent | 64127478630b676838735b509fec5cdfa36874c8 (diff) | |
Merge branch 'pu/json-hooks-21.04' into 'main'
JSON Hooks 0.2
See merge request apt-team/apt!166
Diffstat (limited to 'test/integration/test-apt-cli-json-hooks')
| -rwxr-xr-x | test/integration/test-apt-cli-json-hooks | 169 |
1 files changed, 148 insertions, 21 deletions
diff --git a/test/integration/test-apt-cli-json-hooks b/test/integration/test-apt-cli-json-hooks index 298fae072..3ec470284 100755 --- a/test/integration/test-apt-cli-json-hooks +++ b/test/integration/test-apt-cli-json-hooks @@ -4,6 +4,10 @@ set -e TESTDIR="$(readlink -f "$(dirname "$0")")" . "$TESTDIR/framework" +getoriginfromsuite() { echo 'Oranges'; } +getlabelfromsuite() { echo 'Lemons'; } +getversionfromsuite() { echo 'Volkamer'; } + setupenvironment configarchitecture "i386" @@ -14,10 +18,13 @@ insertpackage 'unstable' 'foo' 'all' '1.0' '' '' "$DESCR . and paragraphs and everything." insertpackage 'testing' 'bar' 'i386' '2.0' '' '' "$DESCR2" +insertpackage 'testing' 'upgrade' 'i386' '2.0' +insertinstalledpackage 'upgrade' 'i386' '1.0' setupaptarchive APTARCHIVE="$(readlink -f ./aptarchive)" +export TEST_HOOK_VERSION=0.2 cat >> json-hook.sh << EOF #!/bin/bash @@ -28,7 +35,7 @@ while true; do if echo "\$request" | grep -q ".hello"; then echo "HOOK: HELLO" - printf '{"jsonrpc": "2.0", "result": {"version": "0.1"}, "id": 0}\n\n' >&\$APT_HOOK_SOCKET + printf '{"jsonrpc": "2.0", "result": {"version": "'\$TEST_HOOK_VERSION'"}, "id": 0}\n\n' >&\$APT_HOOK_SOCKET fi if echo "\$request" | grep -q ".bye"; then @@ -48,13 +55,14 @@ HOOK="$(readlink -f ./json-hook.sh)" # Setup all hooks cat >> rootdir/etc/apt/apt.conf.d/99-json-hooks << EOF AptCli::Hooks::Install:: "$HOOK"; + AptCli::Hooks::Upgrade:: "$HOOK"; AptCli::Hooks::Search:: "$HOOK"; EOF ############################# Success search ####################### testsuccessequal 'HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.pre","params":{"command":"search","search-terms":["foo"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -65,7 +73,7 @@ foo/unstable 1.0 all Some description that has a unusual word xxyyzz and aabbcc and a UPPERCASE HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.post","params":{"command":"search","search-terms":["foo"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -73,7 +81,7 @@ HOOK: BYE' apt search foo ############################# Failed search ####################### testsuccessequal 'HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.pre","params":{"command":"search","search-terms":["foox"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -81,7 +89,7 @@ HOOK: BYE Sorting... Full Text Search... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.search.fail","params":{"command":"search","search-terms":["foox"],"unknown-packages":[],"packages":[]}} HOOK: empty @@ -93,7 +101,7 @@ HOOK: BYE' apt search foox testfailureequal 'Reading package lists... Building dependency tree... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.fail","params":{"command":"install","search-terms":["foxxx"],"unknown-packages":["foxxx"],"packages":[]}} HOOK: empty @@ -105,23 +113,142 @@ E: Unable to locate package foxxx' apt install foxxx testsuccessequal 'Reading package lists... Building dependency tree... HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":1,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"1.0","architecture":"all","pin":500},"install":{"id":1,"version":"1.0","architecture":"all","pin":500}}}]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} HOOK: empty HOOK: BYE The following NEW packages will be installed: foo -0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. -Inst foo (1.0 unstable [all]) -Conf foo (1.0 unstable [all]) HOOK: HELLO -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1"]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.package-list","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} +HOOK: empty +HOOK: BYE +0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.statistics","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} +HOOK: empty +HOOK: BYE +Inst foo (1.0 Lemons:unstable [all]) +Conf foo (1.0 Lemons:unstable [all]) +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} HOOK: empty -HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":1,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"1.0","architecture":"all","pin":500},"install":{"id":1,"version":"1.0","architecture":"all","pin":500}}}]}} +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post","params":{"command":"install","search-terms":["foo"],"unknown-packages":[],"packages":[{"id":2,"name":"foo","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":2,"version":"1.0","architecture":"all","pin":500,"origins":[{"archive":"unstable","codename":"sid","origin":"Oranges","label":"Lemons","site":""}]}}}]}} HOOK: empty HOOK: BYE' apt install foo -s +############################# Failed dist-upgrade ####################### + +testfailureequal 'Reading package lists... +Building dependency tree... +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.fail","params":{"command":"dist-upgrade","search-terms":["foxxx"],"unknown-packages":["foxxx"],"packages":[]}} +HOOK: empty +HOOK: BYE +E: Unable to locate package foxxx' apt dist-upgrade foxxx + +############################# Success install ####################### + +testsuccessequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +The following packages will be upgraded: + upgrade +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.package-list","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.statistics","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +Inst upgrade [1.0] (2.0 Lemons:testing [i386]) +Conf upgrade (2.0 Lemons:testing [i386]) +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"upgrade","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE' apt dist-upgrade -s + + +################## version 0.1 ######################### +TEST_HOOK_VERSION=0.1 + +testequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.pre-prompt","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +The following packages will be upgraded: + upgrade +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.package-list","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.statistics","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +Inst upgrade [1.0] (2.0 Lemons:testing [i386]) +Conf upgrade (2.0 Lemons:testing [i386]) +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.install.post","params":{"command":"dist-upgrade","search-terms":[],"unknown-packages":[],"packages":[{"id":1,"name":"upgrade","architecture":"i386","mode":"install","automatic":false,"versions":{"candidate":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"install":{"id":1,"version":"2.0","architecture":"i386","pin":500,"origins":[{"archive":"testing","codename":"testing","origin":"Oranges","label":"Lemons","site":""}]},"current":{"id":4,"version":"1.0","architecture":"i386","pin":100,"origins":[]}}}]}} +HOOK: empty +HOOK: BYE +W: Hook '$HOOK' uses deprecated 0.1 protocol +W: Hook '$HOOK' uses deprecated 0.1 protocol +W: Hook '$HOOK' uses deprecated 0.1 protocol +W: Hook '$HOOK' uses deprecated 0.1 protocol' apt dist-upgrade -s + + +################## Wrong version ######################### +TEST_HOOK_VERSION=42 + +testfailureequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +HOOK: HELLO +HOOK: request {"jsonrpc":"2.0","method":"org.debian.apt.hooks.hello","id":0,"params":{"versions":["0.1","0.2"]}} +HOOK: empty +E: Unknown hook version in handshake from hook '$HOOK': {"jsonrpc": "2.0", "result": {"version": "42"}, "id": 0} +E: Sub-process '$HOOK' returned an error code (1) +E: Failure running hook '$HOOK' +E: Unknown hook version in handshake from hook '$HOOK': {"jsonrpc": "2.0", "result": {"version": "42"}, "id": 0} +E: Sub-process '$HOOK' returned an error code (1) +E: Failure running hook '$HOOK'' apt dist-upgrade -s ################## Error in hello response ######################### cat > json-hook.sh << EOF @@ -133,7 +260,7 @@ while true; do read empty <&\$APT_HOOK_SOCKET if echo "\$request" | grep -q ".hello"; then - printf '{"jsonrpc": "2.0", "error": {"version": "0.1"}, "id": 0}\n\n' >&\$APT_HOOK_SOCKET + printf '{"jsonrpc": "2.0", "error": {"version": "0.2"}, "id": 0}\n\n' >&\$APT_HOOK_SOCKET break fi done @@ -143,8 +270,8 @@ EOF testfailureequal 'Reading package lists... Building dependency tree... -E: Hook '$HOOK' reported an error during hello: {"jsonrpc": "2.0", "error": {"version": "0.1"}, "id": 0} -E: Hook '$HOOK' reported an error during hello: {"jsonrpc": "2.0", "error": {"version": "0.1"}, "id": 0}' apt install foo -s +E: Hook '$HOOK' reported an error during hello: {"jsonrpc": "2.0", "error": {"version": "0.2"}, "id": 0} +E: Hook '$HOOK' reported an error during hello: {"jsonrpc": "2.0", "error": {"version": "0.2"}, "id": 0}' apt install foo -s ################## Missing separator line ######################### cat > json-hook.sh << EOF @@ -156,7 +283,7 @@ while true; do read empty <&\$APT_HOOK_SOCKET if echo "\$request" | grep -q ".hello"; then - printf '{"jsonrpc": "2.0", "result": {"version": "0.1"}, "id": 0}\n' >&\$APT_HOOK_SOCKET + printf '{"jsonrpc": "2.0", "result": {"version": "0.2"}, "id": 0}\n' >&\$APT_HOOK_SOCKET break fi done @@ -179,7 +306,7 @@ while true; do read empty <&\$APT_HOOK_SOCKET if echo "\$request" | grep -q ".hello"; then - printf '{"jsonrpc": "2.0", "result": {"version": "0.1"}, "id": 0}\nXX' >&\$APT_HOOK_SOCKET + printf '{"jsonrpc": "2.0", "result": {"version": "0.2"}, "id": 0}\nXX' >&\$APT_HOOK_SOCKET break fi done @@ -202,9 +329,9 @@ testsuccessequal 'Reading package lists... Building dependency tree... The following NEW packages will be installed: foo -0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. -Inst foo (1.0 unstable [all]) -Conf foo (1.0 unstable [all])' apt install foo -s +0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +Inst foo (1.0 Lemons:unstable [all]) +Conf foo (1.0 Lemons:unstable [all])' apt install foo -s |
