help-stow
[Top][All Lists]
Advanced

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

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


From: Adam Spiers
Subject: Re: [Help-stow] A tip, a question, and feature request ...
Date: Wed, 10 Apr 2013 12:54:53 +0100
User-agent: Mutt/1.5.21 (2010-09-15)

On Tue, Apr 09, 2013 at 03:45:17PM -0400, Magnus Thor Torfason wrote:
> Dear Adam (and others),
> 
> I recently came across stow, and it is a real life-saver. Thank you!

Great to hear!  May I ask what your use case is?  These days, most
people install system-wide packages using a more conventional modern
package manager such as rpm or dpkg, so IMHO the most typically useful
use cases which Stow targets has shifted a bit in the last decade.
For example I use it for tracking files within my home directory,
where use of a conventional package manager is too heavyweight and
impractical.

More comments inline below ...

> 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?"

Cute trick!  I really like this idea :-) 

It's not for everyone, however; for example, it doesn't work when the
target directory is /usr rather than /usr/local, since it would be far
too invasive to adopt the whole of /usr.  Similarly for /opt in many
cases.  But it does offer a really nice workaround when trying to
build stow installation images for packages which don't natively
support setting the install-time target to be something different than
the compile-time target.

The first part of the trick should also please any Stow purists who
like the idea of their target directory only containing symlinks owned
by Stow.

> 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.

Yup.

>    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).

Probably better to let the caller decide whether they want to call it
with an empty or absent package directory.

>  - Update stow and chkstow so that they correctly handle alien symlinks.

Agreed.

>    This would apply to the following commands at least:
>      > stow --adopt <package>

stow --adopt should currently ignore alien symlinks.  If it doesn't,
that's a bug.  I'm not sure what changes you are proposing to this
behaviour?

>      > stow --adopt-all <package>

Right, although adopting alien symlinks which are relative rather than
absolute could be tricky, since the target of the original alien
symlink is relative to its location within the stow target directory,
and this target would need to be rewritten during adoption to be
relative to its location within the stow package directory.

>      > 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.

Agreed, although in the absence of a --dir parameter, the presence of
a `.stow' file in the stow directory might be sufficient.

> 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)

Yup - my previous comment applies here too.

>   - 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 <...>

This all sounds reasonable.

> 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.

Absolutely!  Great suggestions; many thanks :-)  Sadly it is very
unlikely that I will have time to implement any of these any time
soon; however I would be delighted to review and accept pull requests
as long as they adhere to these guidelines ...

http://blog.adamspiers.org/2012/11/10/7-principles-for-contributing-patches-to-software-projects/

Cheers,
Adam



reply via email to

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