how to implement uninstall & Logging paths of installed files?

On 9/16/06, Isaac Jones
wrote: "Johan Tibell"
writes: I'm trying to write a module that logs all files installed by Cabal to a file. I've looked through parts of the source and conclude that some of the information (the one used to generate prefixes) needed to construct absolute file paths for installed files exists in Distribution.Simple.LocalBuildInfo. Where does the actual copying take place and is there a way to list the files being copied or am I better of trying to list all files in the dist/ dir and prepend the prefixes myself? What code decides how files are laid out in dist/?
Hi all, FWIW, Johan is still interested in this. I would look especially at the "copy" and "install" commands. Look at Distribution.Simple.Utils, lots of "copy" related functions in there. Look especially at the "prefix" type parameters. The Distribution.Simple.Install.install function also implements the "copy" command; so "install" is more general, the prefix is all that changes, so look especially at this function. Look at the copydest parameter. Someone (else?) was looking into writing an "uninstall" feature, which would log the files installed so that it could remove them later. I think that logging & uninstall could be implemented quite effectively by tweaking the "install" target so that it first copies stuff into a temporary location, then uses a "find" type algorithm to discover all of the files that are meant to be installed. The find algorithm would create this list of files and dump it to a log. It would then use a recursive copy algorithm to copy all of these files into place. (The copy command would do pretty much the same, but skip the copy-in-place step.) The recursive copy function would have to not freak out if the directories already exist, of course. Install should also install this "log" of files somplace (where?), for the sake of uninstall. How's that sound? peace, isaac

I think that logging & uninstall could be implemented quite effectively by tweaking the "install" target so that it first copies stuff into a temporary location, then uses a "find" type algorithm to discover all of the files that are meant to be installed.
I have essentially already implemented the find algorithm under the assumption that files that would be copied to for example /usr/bin will be but in /my/tmp/dir/usr/bin during the build. I've also written a piece of code that removes the files again given a log file with paths. The files are removed in a way that will also remove empty directories. I was thinking of putting a timestamp on the files as well. I also added a dry-run feature. Perhaps storing the log files somewhere under Cabal's install dir would be a good idea? Cheers, Johan

"Johan Tibell"
I think that logging & uninstall could be implemented quite effectively by tweaking the "install" target so that it first copies stuff into a temporary location, then uses a "find" type algorithm to discover all of the files that are meant to be installed.
I have essentially already implemented the find algorithm under the assumption that files that would be copied to for example /usr/bin will be but in /my/tmp/dir/usr/bin during the build.
I don't think I understand your assumption. What do you mean "during the build"? I think the only way to make sure that your paths are correct is to do a "fake" install into a temp directory and then do a recursive copy. For instance, I think we have dist/build/foo/foo.exe (or something) would get installed in /usr/bin/foo.exe, and dist/doc/foo.html would be installed in /usr/share/doc/foo/foo.html. So the install paths aren't correct at build time, only at install time.
I've also written a piece of code that removes the files again given a log file with paths.
Cool!
The files are removed in a way that will also remove empty directories. I was thinking of putting a timestamp on the files as well.
And maybe a sha1 sum?
I also added a dry-run feature. Perhaps storing the log files somewhere under Cabal's install dir would be a good idea?
Yeah :) peace, isaac

I have essentially already implemented the find algorithm under the assumption that files that would be copied to for example /usr/bin will be but in /my/tmp/dir/usr/bin during the build.
I don't think I understand your assumption. What do you mean "during the build"? I think the only way to make sure that your paths are correct is to do a "fake" install into a temp directory and then do a recursive copy.
For instance, I think we have dist/build/foo/foo.exe (or something) would get installed in /usr/bin/foo.exe, and dist/doc/foo.html would be installed in /usr/share/doc/foo/foo.html. So the install paths aren't correct at build time, only at install time.
Sorry for being a bit unclear. My algorithm takes a directory prefix such as /tmp and recursively creates a list of absolute paths with the prefix removed. Example: Actuall files and dirs: /tmp/usr/bin/foo.exe /tmp/usr/share/doc/doc.txt The log file I create would look like this when run with /tmp as prefix: /usr/bin/foo.exe _SHA-1_or_something_ /usr/share/doc/doc.txt _SHA-1_or_something_ I have a function: -- | @writeInstallLog file dir@ creates a file @file@ that contains a list of -- all directories and files in @dir@ with the prefix @dir@ removed and / -- prepended. writeInstallLog :: FilePath -> FilePath -> IO ()
The files are removed in a way that will also remove empty directories. I was thinking of putting a timestamp on the files as well.
And maybe a sha1 sum?
Perhaps it would be a good idea to come up with things that could go wrong during an uninstall. Here are some: * File missing (deleted by user). * File modified. * File shared with some other Cabal package. * Configuration file (may not be removed). - Johan
participants (2)
-
Isaac Jones
-
Johan Tibell