NAME=r2pm -H R2PM_OFFLINE
FILE=-
CMDS=%R2PM_OFFLINE=1;!r2pm -H R2PM_OFFLINE
EXPECT=<<EOF
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm r2 platform is available by default
FILE=-
CMDS=<<EOF
rmrf /tmp/r2pm-platform-r2r
mkdir -p /tmp/r2pm-platform-r2r
!printf 'R2PM_BEGIN\nR2PM_DESC "portable r2"\nR2PM_INSTALL_R2() {\n:\n}\nR2PM_END\n' > /tmp/r2pm-platform-r2r/r2only
%R2PM_DBDIR=/tmp/r2pm-platform-r2r
%R2PM_OFFLINE=1
%R2PM_PLATFORM=
r2pm -qs r2only
%R2PM_PLATFORM=windows
r2pm -Aqs r2only
rmrf /tmp/r2pm-platform-r2r
EOF
EXPECT=<<EOF
r2only              portable r2
r2only              [unsupported] portable r2
EOF
EXPECT_ERR=
RUN

NAME=r2pm r2 platform json
FILE=-
CMDS=<<EOF
rmrf /tmp/r2pm-platform-json-r2r
mkdir -p /tmp/r2pm-platform-json-r2r
!printf 'R2PM_BEGIN\nR2PM_DESC "portable r2"\nR2PM_INSTALL_R2() {\n:\n}\nR2PM_END\n' > /tmp/r2pm-platform-json-r2r/r2only
%R2PM_DBDIR=/tmp/r2pm-platform-json-r2r
%R2PM_OFFLINE=1
%R2PM_PLATFORM=r2
r2pm -qjs r2only
rmrf /tmp/r2pm-platform-json-r2r
EOF
EXPECT=[{"name":"r2only","desc":"portable r2","platforms":["r2"],"binary":false,"supported":true}]
EXPECT_ERR=
RUN

NAME=r2pm r2 platform install and uninstall
FILE=-
CMDS=<<EOF
rmrf /tmp/r2pm-platform-install-r2r
mkdir -p /tmp/r2pm-platform-install-r2r/db
mkdir -p /tmp/r2pm-platform-install-r2r/git/radare2-pm
!printf 'R2PM_BEGIN\nR2PM_DESC "r2 installer smoke"\nR2PM_INSTALL_R2() {\n?e R2PM_R2_INSTALL_OK\n}\nR2PM_UNINSTALL_R2() {\n?e R2PM_R2_UNINSTALL_OK\n}\nR2PM_END\n' > /tmp/r2pm-platform-install-r2r/db/r2smoke
%R2PM_DBDIR=/tmp/r2pm-platform-install-r2r/db
%R2PM_GITDIR=/tmp/r2pm-platform-install-r2r/git
%R2PM_OFFLINE=1
%XDG_DATA_HOME=/tmp/r2pm-platform-install-r2r/data
%R2_LOG_LEVEL=1
r2pm -qi r2smoke
r2pm -qu r2smoke
r2pm -qI
rmrf /tmp/r2pm-platform-install-r2r
EOF
EXPECT=<<EOF
R2PM_R2_INSTALL_OK
R2PM_R2_UNINSTALL_OK
Installed 0 packages of 1 in database
EOF
EXPECT_ERR=
RUN

NAME=r2pm Windows source install registers only on success
REQUIRE=windows
FILE=-
CMDS=<<EOF
rmrf r2pm-win-register-r2r
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=r2pm-win-register-r2r/git
%XDG_DATA_HOME=r2pm-win-register-r2r/data
%R2PM_OFFLINE=1
%R2_LOG_LEVEL=1
%R2_DEBUG_ASSERT=1
r2pm -qi winregister-ok
r2pm -ql
r2pm -qi winregister-fail
r2pm -ql
rmrf r2pm-win-register-r2r
EOF
EXPECT=<<EOF
winregister-ok
winregister-ok
EOF
EXPECT_ERR=
RUN

NAME=r2pm Windows source install keeps set variables across lines
REQUIRE=windows
FILE=-
CMDS=<<EOF
rmrf r2pm-win-env-r2r
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=r2pm-win-env-r2r/git
%XDG_DATA_HOME=r2pm-win-env-r2r/data
%R2PM_OFFLINE=1
%R2_LOG_LEVEL=1
%R2PM_TEST_VALUE=
r2pm -qi winenv
r2pm -ql
rmrf r2pm-win-env-r2r
EOF
EXPECT=<<EOF
env-persisted
winenv
EOF
EXPECT_ERR=
RUN

NAME=r2pm Windows installs binary-only packages and rejects unix-only ones
REQUIRE=windows
FILE=-
CMDS=<<EOF
rmrf r2pm-win-fallback-r2r
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=r2pm-win-fallback-r2r/git
%XDG_DATA_HOME=r2pm-win-fallback-r2r/data
%R2PM_OFFLINE=1
%R2_LOG_LEVEL=1
r2pm -qi winbinary
r2pm -qi winnone
r2pm -ql
rmrf r2pm-win-fallback-r2r
EOF
EXPECT=<<EOF
binary-0
winbinary
EOF
EXPECT_ERR=<<EOF
ERROR: winnone cannot be installed on Windows
EOF
RUN

NAME=r2pm -H R2PM_GITDIR
FILE=-
CMDS=%R2PM_GITDIR=test;r2pm -H R2PM_GITDIR
EXPECT=<<EOF
test
EOF
EXPECT_ERR=
RUN

NAME=r2pm -H R2PM_GITDIR
FILE=-
CMDS=%R2PM_GITDIR=test;!r2pm -H R2PM_GITDIR
EXPECT=<<EOF
test
EOF
EXPECT_ERR=
RUN

NAME=r2pm global plugin directory follows R2_PREFIX
FILE=-
CMDS=<<EOF
%R2_PREFIX=/r2pm-relocated
r2pm -gH R2PM_UNUSED
env R2PM_PLUGDIR~^/r2pm-relocated~?
EOF
EXPECT=<<EOF
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm global environment is also available without install
FILE=-
CMDS=<<EOF
%SUDO=r2pm-test-sudo
r2pm -gH GLOBAL
r2pm -gH R2PM_GLOBAL
r2pm -gH R2PM_SUDO
r2pm -H GLOBAL
r2pm -H R2PM_GLOBAL
r2pm -H R2PM_SUDO
EOF
EXPECT=<<EOF
1
1
r2pm-test-sudo
0
0
EOF
EXPECT_ERR=
RUN

NAME=r2pm -r status code
FILE=-
CMDS='!!r2pm -r false; echo $?
EXPECT=<<EOF
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm -r preserves argument boundaries
FILE=-
CMDS=r2pm -r rax2 -S "one two" "" "a\"b" "C:\\one two\\"
EXPECT=<<EOF
6f6e652074776f

612262
433a5c6f6e652074776f5c
EOF
EXPECT_ERR=
RUN

NAME=r2pm -r preserves a shell command string
REQUIRE=unix
FILE=-
CMDS=r2pm -r "rax2 -S 'one two' | rax2 -s"
EXPECT=one two
EXPECT_ERR=
RUN

NAME=r2pm -r executable path with spaces
REQUIRE=unix
FILE=-
CMDS=<<EOF
r2pm -r "./scripts/r2pm/run probe" "one two" "" "a\"b" "C:\\one two\\"
r2pm -r "./scripts/r2pm/run probe"
EOF
EXPECT=<<EOF
argc=4
<one two>
<>
<a\"b>
<C:\\one two\\>
argc=0
EOF
EXPECT_ERR=
RUN

NAME=r2pm -r preserves child exit status
REQUIRE=unix
FILE=-
CMDS=<<EOF
r2pm -r sh -c "exit 7"
?vi $?
r2pm -r "exit 9"
?vi $?
EOF
EXPECT=<<EOF
7
9
EOF
EXPECT_ERR=
RUN

NAME=r2pm -e requires package
FILE=-
CMDS=!r2pm -e
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-e' requires one or more packages
EOF
RUN

NAME=r2pm -r requires command
FILE=-
CMDS=!r2pm -r
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-r' requires a command to run
EOF
RUN

NAME=r2pm -j requires action
FILE=-
CMDS=!r2pm -j
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-j' requires an action
EOF
RUN

NAME=r2pm -i requires package
FILE=-
CMDS=!r2pm -i
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-i' requires one or more packages
EOF
RUN

NAME=r2pm -u requires package
FILE=-
CMDS=!r2pm -u
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-u' requires one or more packages
EOF
RUN

NAME=r2pm -b requires install
FILE=-
CMDS=r2pm -b
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-b' requires -i
EOF
RUN

NAME=r2pm -bi requires package
FILE=-
CMDS=r2pm -bi
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-i' requires one or more packages
EOF
RUN

NAME=r2pm binary mode rejects source upgrade
FILE=-
CMDS=r2pm -biUU r2frida
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-b' cannot be combined with '-UU'
EOF
RUN

NAME=r2pm binary package versions are independent and scoped
BROKEN=1
FILE=-
CMDS=<<EOF
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=scripts/r2pm
%R2PM_OFFLINE=1
%XDG_DATA_HOME=/tmp/r2pm-versions-r2r
%R2_LOG_LEVEL=1
%R2V=6.2.4
%R2PM_VERSION=
%R2PM_TEST_FAIL=
r2pm -qbi independent spaced unversioned
r2pm -H R2PM_VERSION
%R2V=6.2.2
r2pm -qbi independent spaced
%R2V=6.2.6
r2pm -qbi independent spaced
%R2V=6.2.8
r2pm -qbi independent
r2pm -qbi empty
%R2V=6.2.4
r2pm -qbi invalid
r2pm -qbi commas
r2pm -qbi unterminated
%R2PM_VERSION=9.8.7
r2pm -qbi independent unversioned
r2pm -H R2PM_VERSION
%R2PM_VERSION=
%R2PM_TEST_FAIL=1
r2pm -qbi independent
%R2PM_TEST_FAIL=
r2pm -H R2PM_VERSION
r2pm -qbi unversioned
r2pm -H R2V
rmrf /tmp/r2pm-versions-r2r
EOF
EXPECT=<<EOF
1.2.3 6.2.4
1.1.5 6.2.4
6.2.4 6.2.4
1.1.0 6.2.2
1.1.2 6.2.2
1.2.3 6.2.6
1.1.5 6.2.6
9.8.7 6.2.4
9.8.7 6.2.4
1.2.3 6.2.4
6.2.4 6.2.4
9.8.7
6.2.4
EOF
EXPECT_ERR=<<EOF
ERROR: No binary release for 'independent' matching radare2 6.2.8 in R2PM_VERSION_MAP
ERROR: No binary release for 'empty' matching radare2 6.2.8 in R2PM_VERSION_MAP
ERROR: Invalid R2PM_VERSION_MAP entry for 'invalid': expected r2-version:package-version
ERROR: Invalid R2PM_VERSION_MAP entry for 'commas': expected r2-version:package-version
ERROR: Cannot find end of block
ERROR: Binary install failed for 'independent'; re-run without -b to build from source
EOF
RUN

NAME=r2pm metadata values share quoted and heredoc parsing
BROKEN=1
FILE=-
CMDS=<<EOF
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=scripts/r2pm
%R2PM_OFFLINE=1
r2pm -qd independent spaced unversioned empty
EOF
EXPECT=<<EOF
inline documentation
quoted documentation
with "embedded quotes"
heredoc documentation

EOF
EXPECT_ERR=
RUN

NAME=r2pm -d requires package
FILE=-
CMDS=!r2pm -d
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-d' requires one or more packages
EOF
RUN

NAME=r2pm -R requires package
FILE=-
CMDS=!r2pm -R
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-R' requires one or more packages
EOF
RUN

NAME=r2pm -c requires package or -cp
FILE=-
CMDS=!r2pm -c
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-c' requires one or more packages or -cp
EOF
RUN

NAME=r2pm -f requires action
FILE=-
CMDS=!r2pm -f
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-f' requires an action
EOF
RUN

NAME=r2pm -g requires action
FILE=-
CMDS=!r2pm -g
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-g' requires an action
EOF
RUN

NAME=r2pm -q requires action
FILE=-
CMDS=!r2pm -q
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-q' requires an action
EOF
RUN

NAME=r2pm -t requires action
FILE=-
CMDS=!r2pm -t 2024-01-01
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Option '-t' requires an action
EOF
RUN

NAME=r2pm -e missing package status code
FILE=-
CMDS='!!r2pm -e >/dev/null 2>/dev/null; echo $?
EXPECT=<<EOF
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm -r missing command status code
FILE=-
CMDS='!!r2pm -r >/dev/null 2>/dev/null; echo $?
EXPECT=<<EOF
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm -j missing action status code
FILE=-
CMDS='!!r2pm -j >/dev/null 2>/dev/null; echo $?
EXPECT=<<EOF
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm portable newlines
FILE=-
CMDS=<<EOF
!!rm -rf /tmp/r2pm-newlines-r2r
!!mkdir -p /tmp/r2pm-newlines-r2r
!!printf '#!/bin/sh\nR2PM_DESC "portable unix"\nR2PM_INSTALL() {\n:\n}\nR2PM_DOC="\nunix doc\n"\n' > /tmp/r2pm-newlines-r2r/unix
!!printf '#!/bin/sh\rR2PM_DESC "portable classic"\rR2PM_INSTALL() {\r:\r}\rR2PM_DOC="\rclassic doc\r"\r' > /tmp/r2pm-newlines-r2r/classic
!!printf '#!/bin/sh\r\nR2PM_DESC "portable dos"\r\nR2PM_INSTALL() {\r\n:\r\n}\r\nR2PM_DOC="\r\ndos doc\r\n"\r\n' > /tmp/r2pm-newlines-r2r/dos
!!printf '#!/bin/sh\n\rR2PM_DESC "portable lfcr"\n\rR2PM_INSTALL() {\n\r:\n\r}\n\rR2PM_DOC="\n\rlfcr doc\n\r"\n\r' > /tmp/r2pm-newlines-r2r/lfcr
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 R2PM_PLATFORM=any r2pm -qs unix
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 R2PM_PLATFORM=any r2pm -qs classic
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 R2PM_PLATFORM=any r2pm -qs dos
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 R2PM_PLATFORM=any r2pm -qs lfcr
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 r2pm -qd unix
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 r2pm -qd classic
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 r2pm -qd dos
!!env R2PM_DBDIR=/tmp/r2pm-newlines-r2r R2PM_OFFLINE=1 r2pm -qd lfcr
!!rm -rf /tmp/r2pm-newlines-r2r
EOF
EXPECT=<<EOF
unix                portable unix
classic             portable classic
dos                 portable dos
lfcr                portable lfcr
unix doc
classic doc
dos doc
lfcr doc
EOF
EXPECT_ERR=
RUN

NAME=r2pm -UU preserves package modes and global environments
FILE=-
CMDS=<<EOF
rmrf /tmp/r2pm-upgrade-r2r
mkdir -p /tmp/r2pm-upgrade-r2r/git/radare2-pm
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=/tmp/r2pm-upgrade-r2r/git
%XDG_DATA_HOME=/tmp/r2pm-upgrade-r2r/data
%R2PM_OFFLINE=1
%R2PM_TEST_FAIL=
%R2_LOG_LEVEL=1
r2pm -qi upgrade-source
r2pm -qgbi upgrade-binary
r2pm -qUU 2>/dev/null
?vi
cat /tmp/r2pm-upgrade-r2r/data/radare2/r2pm/pkg/upgrade-source~!InstallationDate:
cat /tmp/r2pm-upgrade-r2r/data/radare2/r2pm/pkg/upgrade-binary~!InstallationDate:
r2pm -qgi upgrade-source
r2pm -qbi upgrade-binary
r2pm -qUU 2>/dev/null
?vi
cat /tmp/r2pm-upgrade-r2r/data/radare2/r2pm/pkg/upgrade-source~!InstallationDate:
cat /tmp/r2pm-upgrade-r2r/data/radare2/r2pm/pkg/upgrade-binary~!InstallationDate:
rmrf /tmp/r2pm-upgrade-r2r
EOF
EXPECT=<<EOF
source-0
binary-1
source-0
binary-1
0
Global: false
Binary: false
Global: true
Binary: true
source-1
binary-0
source-1
binary-0
0
Global: true
Binary: false
Global: false
Binary: true
EOF
EXPECT_ERR=
RUN

NAME=r2pm -UU reports failure and continues other package groups
FILE=-
CMDS=<<EOF
rmrf /tmp/r2pm-upgrade-fail-r2r
mkdir -p /tmp/r2pm-upgrade-fail-r2r/git/radare2-pm
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=/tmp/r2pm-upgrade-fail-r2r/git
%XDG_DATA_HOME=/tmp/r2pm-upgrade-fail-r2r/data
%R2PM_OFFLINE=1
%R2PM_TEST_FAIL=
%R2_LOG_LEVEL=1
r2pm -qi upgrade-source
r2pm -qbi upgrade-binary
%R2PM_TEST_FAIL=1
r2pm -qUU 2>/dev/null
?vi
rmrf /tmp/r2pm-upgrade-fail-r2r
EOF
EXPECT=<<EOF
source-0
binary-0
source-0
binary-0
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm -UU succeeds without registered packages
FILE=-
CMDS=<<EOF
rmrf /tmp/r2pm-upgrade-empty-r2r
mkdir -p /tmp/r2pm-upgrade-empty-r2r/git/radare2-pm
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=/tmp/r2pm-upgrade-empty-r2r/git
%XDG_DATA_HOME=/tmp/r2pm-upgrade-empty-r2r/data
%R2PM_OFFLINE=1
%R2_LOG_LEVEL=1
r2pm -qUU 2>/dev/null
?vi
mkdir -p /tmp/r2pm-upgrade-empty-r2r/data/radare2/r2pm/pkg/.hidden
mkdir -p /tmp/r2pm-upgrade-empty-r2r/data/radare2/r2pm/pkg/not-a-package
r2pm -qUU 2>/dev/null
?vi
rmrf /tmp/r2pm-upgrade-empty-r2r
EOF
EXPECT=<<EOF
0
0
EOF
EXPECT_ERR=
RUN

NAME=r2pm -U reports database update failures
REQUIRE=unix
FILE=-
CMDS=<<EOF
rmrf /tmp/r2pm-update-fail-r2r
mkdir -p /tmp/r2pm-update-fail-r2r/bin
mkdir -p /tmp/r2pm-update-fail-r2r/git/radare2-pm
!!printf '#!/bin/sh\nexit 1\n' > /tmp/r2pm-update-fail-r2r/bin/git && chmod +x /tmp/r2pm-update-fail-r2r/bin/git
%R2PM_GITDIR=/tmp/r2pm-update-fail-r2r/git
%XDG_DATA_HOME=/tmp/r2pm-update-fail-r2r/data
%PATH=/tmp/r2pm-update-fail-r2r/bin
%R2_LOG_LEVEL=1
r2pm -qU 2>/dev/null
?vi
rmrf /tmp/r2pm-update-fail-r2r
EOF
EXPECT=<<EOF
1
EOF
EXPECT_ERR=
RUN

NAME=r2pm installs missing dependencies and stops when one fails
REQUIRE=unix
FILE=-
CMDS=<<EOF
rmrf r2pm-deps-r2r
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=r2pm-deps-r2r/git
%XDG_DATA_HOME=r2pm-deps-r2r/data
%R2PM_OFFLINE=1
%R2_LOG_LEVEL=1
r2pm -qi depapp
r2pm -qi depapp
r2pm -qi depbroken
r2pm -ql
rmrf r2pm-deps-r2r
EOF
EXPECT=<<EOF
install-depok-0
install-depapp-0
install-depapp-0
install-depfail-0
depapp
depok
EOF
EXPECT_ERR=<<EOF
ERROR: Cannot install depfail, required by depbroken
EOF
RUN

NAME=r2pm installs dependencies globally with the package
REQUIRE=unix
FILE=-
CMDS=<<EOF
rmrf r2pm-deps-global-r2r
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=r2pm-deps-global-r2r/git
%XDG_DATA_HOME=r2pm-deps-global-r2r/data
%R2PM_OFFLINE=1
%R2_LOG_LEVEL=1
%SUDO=true
r2pm -qgi depapp
rmrf r2pm-deps-global-r2r
EOF
EXPECT=<<EOF
install-depok-1
install-depapp-1
EOF
EXPECT_ERR=
RUN

NAME=r2pm Unix source hooks respect R2PM_DIR
REQUIRE=unix
FILE=-
CMDS=<<EOF
rmrf r2pm-subdir-r2r
%R2PM_DBDIR=scripts/r2pm/radare2-pm/db
%R2PM_GITDIR=scripts/r2pm/git
%XDG_DATA_HOME=r2pm-subdir-r2r/data
%R2PM_OFFLINE=1
%R2_LOG_LEVEL=1
r2pm -qi subdir
r2pm -qu subdir
r2pm -ql
rmrf r2pm-subdir-r2r
EOF
EXPECT=<<EOF
install-subdir
uninstall-subdir
EOF
EXPECT_ERR=
RUN
