Skip to content

Conversation

@classabbyamp
Copy link
Member

@classabbyamp classabbyamp commented Dec 31, 2025

replaces isn't honoured if the package to be replaced is currently being installed. This fixes a corner case where a transitional package could be installed along with its replacement, when it should be "ignored" and only the new package installed.

This requires transaction commits to not fail if a replaced package isn't installed when it should be "removed".

Also, indicate to the user that a package is being replaced, with details about what replaced what shown in verbose output, not just debug output.

fixes: #667

both installed at once:

xbps-install -R /tmp/reproducer -r /tmp/reproducer/root -v B
Found B-1.0_1 in repository /tmp/reproducer
Found A-1.0_1 in repository /tmp/reproducer
Package `B-1.0_1' will be replaced by `A-1.0_1'

Name Action    Version           New version            Download size
A    install   -                 1.0_1                  - 
B    replaced  -                 -                      - 

Space available on disk:        26GB

Do you want to continue? [Y/n] 

[*] Verifying package integrity
A-1.0_1: verifying SHA256 hash...

[*] Collecting package files
A-1.0_1: collecting files...

[*] Unpacking packages
A-1.0_1: unpacking ...
A-1.0_1: unpacked file `./file' (0 bytes)

[*] Configuring unpacked packages
A-1.0_1: configuring ...
A-1.0_1: installed successfully.

0 downloaded, 1 installed, 0 updated, 1 configured, 1 removed, 0 on hold.

updating to transitional:

xbps-install -R /tmp/reproducer -r /tmp/repro2/root -v B    
Found B-1.0_1 in repository /tmp/reproducer
Found A-1.0_1 in repository /tmp/reproducer
Package `B-1.0_1' will be replaced by `A-1.0_1'

Name Action    Version           New version            Download size
A    install   -                 1.0_1                  - 
B    replaced  0.1_1             -                      - 

Space available on disk:        26GB

Do you want to continue? [Y/n] 

[*] Verifying package integrity
A-1.0_1: verifying SHA256 hash...

[*] Collecting package files
A-1.0_1: collecting files...
B-0.1_1: collecting files...

[*] Unpacking packages
A-1.0_1: unpacking ...
B-1.0_1: removing ...
B-1.0_1: removed successfully.

[*] Configuring unpacked packages
A-1.0_1: configuring ...
A-1.0_1: installed successfully.

0 downloaded, 1 installed, 0 updated, 1 configured, 1 removed, 0 on hold.

@classabbyamp classabbyamp marked this pull request as draft December 31, 2025 03:33
…tion

replaces isn't honoured if the package to be replaced is currently being installed.
This fixes a corner case where a transitional package could be installed
along with its replacement, when it should be "ignored" and only the new
package installed.

This requires transaction commits to not fail if a replaced package
isn't installed when it should be "removed".

Also, indicate to the user that a package is being replaced, with
details about what replaced what shown in verbose output, not just debug output.

fixes: void-linux#667
@classabbyamp classabbyamp changed the title support replacing packages on initial install lib: handle replaces if replaced pkg is installed in the same transaction Dec 31, 2025
@classabbyamp classabbyamp marked this pull request as ready for review December 31, 2025 06:11
@Chocimier
Copy link
Member

Another test case (passing) for pair replacing each other, like zfs & zfs-lts.

diff --git a/tests/xbps/libxbps/shell/replace_test.sh b/tests/xbps/libxbps/shell/replace_test.sh
index 0efbbfd0..741f379e 100644
--- a/tests/xbps/libxbps/shell/replace_test.sh
+++ b/tests/xbps/libxbps/shell/replace_test.sh
@@ -421,6 +421,32 @@ replace_transitional_pkg_automatically_installed3_body() {
 
 atf_test_case replace_transitional_pkg_during_install
 
+dont_replace_alternative_pkg_during_install_head() {
+	atf_set "descr" "Tests for package replace: install a package that has a pair replacing each other"
+}
+
+dont_replace_alternative_pkg_during_install_body() {
+	mkdir some_repo root
+	mkdir -p pkg_A/usr/bin empty
+	echo "A-1.0_1" > pkg_A/usr/bin/foo
+	cd some_repo
+	xbps-create -A noarch -n A-1.0_1 -s "A pkg" --replaces "B>=0" ../pkg_A
+	atf_check_equal $? 0
+	xbps-create -A noarch -n B-1.0_1 -s "B pkg" --replaces "A>=0" ../pkg_A
+	atf_check_equal $? 0
+	xbps-rindex -d -a $PWD/*.xbps
+	atf_check_equal $? 0
+	cd ..
+	xbps-install -C xbps.d -r root --repository=$PWD/some_repo -yd B
+	atf_check_equal $? 0
+	result=$(xbps-query -r root -l | wc -l)
+	atf_check_equal $result 1
+	atf_check_equal $(xbps-query -C xbps.d -r root -p state A) ""
+	atf_check_equal $(xbps-query -C xbps.d -r root -p state B) installed
+}
+
+atf_test_case replace_transitional_pkg_during_install
+
 replace_transitional_pkg_during_install_head() {
 	atf_set "descr" "Tests for package replace: install a transitional package and replace it during the transaction"
 }
@@ -627,6 +653,7 @@ atf_init_test_cases() {
 	atf_add_test_case replace_transitional_pkg_automatically_installed2
 	atf_add_test_case replace_transitional_pkg_automatically_installed3
 	atf_add_test_case replace_transitional_pkg_during_install
+	atf_add_test_case dont_replace_alternative_pkg_during_install
 	atf_add_test_case replace_automatically_installed_dep
 	atf_add_test_case replace_automatically_installed_dep2
 	atf_add_test_case replace_automatically_installed_dep3

@classabbyamp
Copy link
Member Author

shouldn't that test try installing A and B at once?

@Chocimier
Copy link
Member

That's another case, add it if you wish. I meant to make sure A won't replace B as they have replaces=, but aren't transitional.

@classabbyamp
Copy link
Member Author

hmm, looks like on the latest release, xbps-install zfs zfs-lts tries to install both. with this change, it sees that zfs replaces zfs-lts and vice versa and installs neither.

not sure how that would be best solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

replaces does not affect the transaction installing the replaced package

2 participants