help-stow
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-stow] A tip, a question, and feature request ...


From: Magnus Thor Torfason
Subject: [Help-stow] A tip, a question, and feature request ...
Date: Tue, 09 Apr 2013 15:45:17 -0400
User-agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20130328 Thunderbird/17.0.5

Dear Adam (and others),

I recently came across stow, and it is a real life-saver. Thank you!

So, I guess this mail is part tip, part question, and part feature request. So here goes ...


THE TIP

In the documentation, there is some discussion about the issues with compiling software for a different location than it is eventually going to be installed with (Section 12, Compile-time vs Install-time). But it seems to me that instead of waiting for emacs and others to individually fix this, it is better to just make stow work with the programs as they function today. Here's how:

We assume that we want to use /usr/local for the target directory and /opt/stow for the stow directory. First, we initialize stow by cleaning out any old crud that already exists in /usr/local using the following command:

  > stow --adopt-all orphans

We now have a stow package (in /opt/stow/orphans) containing all the crud, and /usr/local is clean. When we want to install a new package, say, the moe text editor, we first make sure that there is definitely no crud in /usr/local (and it should all be gone now):

  > chkstow -a

and then we type:

  > cd src
  > wget http://ftp.gnu.org/gnu/moe/moe-1.5.tar.gz
  > tar zxvf moe-1.5.tar.gz
  > cd moe-1.5
  > ./configure
  > make
  > make install

Whoa! This installed moe into /usr/local, not stow. That's OK, though, because now we are going to do this:

  > stow --adopt-all moe-1.5

Boom, we are done, now we have a stow package for moe in /opt/stow/moe-1.5 and we can uninstall, reinstall or upgrade moe whenever we want.


QUESTION

Is there any reason one should not follow this approach?


ANSWER (*)

Why, yes there is a good reason: stow does not accept the --adopt-all switch! Which is why I actually do this instead:

  > stow.adopt.all moe-1.5

Where stow.adopt.all is a bash function:
stow.adopt.all ()
{
    if [ "$1" == "" ] || [ "$2" != "" ]; then
echo "Incorrect number of arguments to stow.adopt.all (expected exactly one).";
        return 1;
    fi;
    DIR=/opt/stow;
    TARGET=/usr/local;
    PACKAGE="$1";
chkstow -t $TARGET -a | sed "s+^Unstowed file: $TARGET+$DIR/$PACKAGE+" | xargs -l mktouch;
    stow --adopt -vv $PACKAGE
}

This requires mktouch, which is a shell script:
#!/bin/sh

if [ "$1" == "" ] || [ "$2" != "" ];  then
    echo "Incorrect number of arguments to mktouch (expected exactly one)."
    exit 1
fi

mkdir -p "$(dirname "$1")"
touch "$1"
# end of mktouch

So the deal here? Find all aliens in /usr/local and touch their equivalent in the stow package directory of choice, because "stow --adopt" (the real one, that currently exists) will only adopt files if it is trying to install those specific files. Only after creating the structure (of empty files) within the package directory do we run "stow --adopt", which then replaces all these empty files with the recently installed files.

This takes care of most of the work, but there are two more caveats. First, for this to work, one must not use the (awesome) folding feature of stow, because if there are directory symlinks in /usr/local, "make install" will probably end up installing stuff into the stow package directories, which will screw everything up. So my .stowrc looks like this (I've elected to keep my stow packages in /opt/stow instead of /usr/local/stow partly because of personal preference, but also because it makes some of my workarounds simpler, since I can then assume that there should be absolutely nothing inside /usr/local apart from symlinks that point to .../opt/stow/...). So again, here is my .stowrc:

-d /opt/stow
-t /usr/local
--no-folding

Now we are 95% there. The only other issue is that "stow --adopt" (and "chkstow -a") does not correctly handle alien symlinks. For example, mc-4.6.1 installs the following symlinks in bin: "mcedit -> mc" and "mcview -> mc". Stow will not detect these as aliens. So I have one more addition in my profile:

alias stow.aliens='find /usr/local -type f -o -type l | xargs ls -l | grep -v "opt/stow"'

I have not implemented this into my stow.adopt.all function, so I need to manually run this after any installation to make sure that there are no symlinks, and if there are I have to manually move them from the stow directory, and then reinstall the package.

Now, this takes me to my actual question: "If we had a 'stow --adopt-all <package>' command, would this then not be a pretty good way to do stow installations?"


FEATURE REQUEST

And finally, assuming that the answer to my last question is yes, here are some feature requests that, if implemented, would make this a robust usage pattern:

 - Add a --adopt-all switch to stow, which would cause stow to adopt
   any alien file in the target directory. In this case, one might
   even imagine that the existence of a corresponding file in the
   stow/package directory would be perceived to be a conflict (I
   would expect the actual use case for this switch to always or
   almost always be executed with an empty or (even better) absent
   stow/package directory).

 - Update stow and chkstow so that they correctly handle alien symlinks.
   This would apply to the following commands at least:
     > stow --adopt <package>
     > stow --adopt-all <package>
     > chkstow -a
   It seems to me that chkstow -a would have to be aware of the
   location of the stow directory to be able to do this,
   probably by adding a --dir param to chkstow.

And then a few other, lower priority, feature requests
while I am at it:

  - Update chkstow -l so that it works with a custom stow
    directory location (this would also require awareness of
    stow directory location)

  - It would be very nice if chkstow had the same default
    options for target dir as stow does, and perhaps if
    it could even have a .chkstowrc file?

  - And even nicer would be if ther was a --rcfile param
    to stow, maybe even for chkstow as well:
      > stow --rcfile=~/my-stowrc-for-homedir <...>
      > stow --rcfile=~/my-stowrc-for-usrlocal <...>
      > chkstow --rcfile=~/my-chkstowrc-for-homedir <...>
      > chkstow --rcfile=~/my-chkstowrc-for-usrlocal <...>

Well, that's asking for a lot, I know! But please take this and use as an input to future development in whatever way you want. I think that this would be a neat way to get out of the dependency on programs playing nice with different compile and install locations, and so increase the number of situations where stow could be used. Also, since the default install location (/usr/local) is typically simpler to configure in any randomly downloaded source package, it would make compilation even easier.

I hope you find these thoughts and suggestions useful.

Best,
Magnus




reply via email to

[Prev in Thread] Current Thread [Next in Thread]