Opened 6 years ago

Closed 7 months ago

#55673 closed defect (fixed)

destroot.keepdirs should behave better if specified path is not in destroot

Reported by: ryandesign (Ryan Carsten Schmidt) Owned by: jmroot (Joshua Root)
Priority: Normal Milestone:
Component: base Version: 2.4.2
Keywords: Cc: jdberry
Port:

Description

The purpose of destroot.keepdirs is to prevent MacPorts from deleting what would otherwise be an empty directory during the cleanup that happens after the destroot phase. The cleanup only affects the contents of ${destroot} so there's no need to use destroot.keepdirs for anything that's outside of ${destroot}.

Yet portfile authors are prone to forget this and accidentally specify a path to destroot.keepdirs that does not begin with ${destroot}. A few recent examples are #55670, #55671, #55672, but this is an ancient problem; see #21414/#21422.

As a consequence, MacPorts dutifully installs the .turd_${subport} file outside of the destroot. Not only is this pointless, but this file is not registered to the port and is not removed when the port is deactivated, which is not desired. And if the portfile author wants to correct their error later, they have to jump through hoops with a custom pre-activate block to remove the unregistered file, to prevent the activation failure that would otherwise occur.

Since it serves no purpose to call destroot.keepdirs with a path that does not begin with ${destroot}, destroot.keepdirs should ensure that that is the case, and should exit with an error if it is not. (An error, rather than a warning, will ensure that someone fixes that port, rather than sweeping the problem under the rug as often happens with other warnings such as reinplace calls that didn't change anything.) We should reword the body of a ticket like #55670 into a wiki page or integrate it into the section on destroot.keepdirs in the guide and print that URL in the error message so the portfile author knows how to fix it.

Or we could try to silently fix it in MacPorts base. destroot.keepdirs could automatically prepend ${destroot} if it's not there already. And MacPorts could silently ignore activation conflicts that involve only .turd_${subport} files. However we might not want to do this, because if we created a binary archive of the port, then it would not contain the directory that was supposed to have been kept, and that might cause the software the port installed to misbehave. (For example, a port might be creating a log directory with particular ownership so that a daemon running as that user could write into it. If the port didn't specify the destroot.keepdirs path beginning with ${destroot}, then the directory wouldn't be part of the binary archive. When the user then installs the port from the binary archive, the directory won't be there on their system, and the daemon might not have anticipated that situation and might fail to run, or at minimum would fail to create the log file it was supposed to create.)

It looks like having the paths not be specified beginning with ${destroot} was considered when the feature was originally implemented in #2366 but no discussion followed. And the original intent, and what was originally committed in [1d95c8bfb3f384335707c87a4d547a5fe8982b1f/macports-base] (r9176), was for destroot.keepdirs to make .turd files unnecessary. But apparently some ports manually created their own .turd files anyway, and in response to that, code to create .turd files was added to base in [4efd37e340db73ac7f6c3c8bcfb381346326585a/macports-base] (r9335). Some ports were cleaned up in [26f4bb60eab4a91d9cbfbeca7df4498483a0915d/macports-ports] (r9340).

I'm still unclear why we went back to .turd files. James, do you remember?

Change History (2)

comment:1 in reply to:  description Changed 7 months ago by jmroot (Joshua Root)

Replying to ryandesign:

I'm still unclear why we went back to .turd files. James, do you remember?

Installed directories are not recorded in the registry, only files (one reason being that multiple ports may cause a given directory to be created). So you need a way to both ensure that otherwise empty directories that need to keep existing are not deleted when uninstalling other ports that had files in those directories, and that those directories are deleted when all ports that need them are uninstalled.

comment:2 Changed 7 months ago by jmroot (Joshua Root)

Owner: set to jmroot
Resolution: fixed
Status: newclosed

In 8db11c80a859bbe0a91d9162d56fec3bef88f511/macports-base (master):

Keep destroot.keepdirs inside of $destroot

Closes: #55673

Note: See TracTickets for help on using tickets.