Since changing portmaster to support flavors, it sometimes gratuitously removes ports; it seems when a new one is a prefix of an existing one. For example, with the following installed ports, gcc-ecj-4.5 gcc6-6.4.0_3 gccmakedep-1.0.3 executing 'portmaster lang/gcc' results in gcc-ecj-4.5 being removed and gcc-6 being installed. The correct operation would have been to just install gcc-6 and leave gcc-ecj-4.5 unchanged. --- That said, many thanks to all who worked hard to keep portmaster usable even with the very intrusive flavor changes. For a while (when portmaster did not work anymore due to flavors) I developed my own upgrade script, so I know pretty well all the pitfalls of FLAVORS and FLAVOR and determining the flavor of old ports which don't have one yet etc.
I have tried to reproduce the reported problem, but on my system portmaster does exactly what has been requested (see build log below). Please set the shebang line to "#!/bin/sh -x" and send the resulting trace to my mail address, if you can reproduce the problem on your system. Without such a trace I cannot work on this PR and I'll close it as "Unable to reproduce". # pkg info | grep gcc gcc-6 Meta-port for the default version of the GNU Compiler Collection gcc-ecj-4.5 Eclipse Java Compiler used to build GCC Java gcc5-5.5.0_1 GNU Compiler Collection 5 gcc6-6.4.0_3 GNU Compiler Collection 6 gccmakedep-1.0.3 Create dependencies in makefiles using 'gcc -M' # portmaster lang/gcc ===>>> Currently installed version: gcc-6 ===>>> Port directory: /usr/svn/ports/head/lang/gcc ===>>> Gathering distinfo list for installed ports ===>>> Gathering dependency list for lang/gcc from ports ===>>> Initial dependency check complete for lang/gcc ===>>> Starting build for lang/gcc <<<=== ===>>> All dependencies are up to date ===> Cleaning for gcc-6 /!\ gcc-6: Makefile warnings, please consider fixing /!\ Please set LICENSE for this port ===> gcc-6 depends on file: /usr/local/sbin/pkg - found ===> Fetching all distfiles required by gcc-6 for building ===> Extracting for gcc-6 ===> Patching for gcc-6 ===> Configuring for gcc-6 ===> Staging for gcc-6 ===> Generating temporary packing list /bin/ln -s gfortran6 work/stage/usr/local/bin/gfortran /bin/ln -s g++6 work/stage/usr/local/bin/g++ /bin/ln -s gcc6 work/stage/usr/local/bin/gcc ====> Compressing man pages (compress-man) ====> Running Q/A tests (stage-qa) ===>>> Creating a backup package for old version gcc-6 Creating package for gcc-6 Updating database digests format: . done Checking integrity... done (0 conflicting) Deinstallation has been requested for the following 1 packages (of 0 packages in the universe): Installed packages to be REMOVED: gcc-6 Number of packages to be removed: 1 [1/1] Deinstalling gcc-6... [1/1] Deleting files for gcc-6: ... done ===> Installing for gcc-6 ===> Checking if gcc already installed ===> Registering installation for gcc-6 Installing gcc-6... ===>>> Waiting for background 'make clean' processes to finish ===>>> Re-installation of gcc-6 complete
Created attachment 190126 [details] script(1) of running 'sh -x /usr/local/sbin/portmaster lang/gcc' No problem to reproduce. I just ran 'pkg delete gcc-6' and then 'sh -x /usr/local/sbin/portmaster lang/gcc' using script(1). The resulting output is attached, it is easy to see where gcc-ecj-4.5 get deinstalled. By the way, the same issue has happened several times before with other ports - that a similar sounding port was removed, and a 'strange' upgrade log message printed.
Looking at the log I now see what is wrong: The line pkg info -x '^gcc-[^-]*' is not specific enough.
I am wondering why a wildcard search is being done there at all. For an upgrade, the invariant should be the port directory; with flavors, probably modified by the flavor. But it should not be necessary to do a wildcard search for a possible old port to upgrade. What is the rationale behind this search?
By the way, in your example lang/gcc seems to already have been installed from the outset. Try rerunning after first deleting it.
A commit references this bug: Author: se Date: Mon Jan 29 12:22:04 UTC 2018 New revision: 460294 URL: https://svnweb.freebsd.org/changeset/ports/460294 Log: Fix a problem that could result in de-installation of a port that shares a prefix of the package name with a new port to be installed. The cause of this bug was that a pattern was applied without anchor at the end. Testing revealed that "pkg info -x" ignores an anchor at the end of the pattern (which might be a bug in pkg), therefore the output of the query is now additionally filtered with egrep to obtain the desired result. PR: 225496 Reported by: Martin Birgmeier Approved by: antoine (implicit) Changes: head/ports-mgmt/portmaster/Makefile head/ports-mgmt/portmaster/files/patch-portmaster
Thank you very much for creating the trace and the correct diagnosis! Please test portmaster-3.19_4, which is expected to work correctly ...
Hi Stefan, I guess it will work now, unfortunately I don't have the time to test it now. However, the original pattern was simply missing the '$' at the end, so maybe it is not necessary to construct the pattern in a separate variable. On another note, I noted this change: @@ -181,7 +181,7 @@ pm_v "===>>> Removing empty directories from WRKDIRPREFIX" [ -n "$needws" ] && echo '' || pm_v - find $PM_WRKDIRPREFIX -depth -mindepth 1 -type d -empty -delete 2>/dev/null + find $PM_WRKDIRPREFIX -depth -mindepth 1 maxdepth 2 -type d -empty -delete 2>/dev/null fi case "$DISPLAY_LIST" in It seems wrong to me - at least there should be a dash in front of "maxdepth". -- Martin
Yes, there was a typo in the find parameter list. Thanks for reporting! Regarding the pattern in the fix for this PR: The $ anchor at the end of the pattern did not work. After committing r460294 I performed a few more tests and I found, that this pattern is applied to the package name with and without the package version appended (i.e. the result of "pkg query %n" and "pkg query %n-%v") and the fix is simply to use a pattern that does not try to match the version, i.e. '^$pkgname$'. That pattern can only match the "%n" case, which is just what I need (but I had assumed that a pattern match was only attempted against "%n-%v", requiring a more complex RE).