A “package” would be something that has ./bin
, ./lib
, ./opt
directories.
These names are optional and are only used here to help us know what’s what.
They could have been ‘foo’ and ‘bar’ but I refuse to use such identifiers.
/Users/pcarphin/storage/AnApplication/
├── bin
│ └── an_application_bin
├── lib
│ └── liban_application.so
└── opt
└── an_application_sh.sh
We want to make it look like ~/.local/
is AnApplication
in that
~/.local/bin/
will contain a file named an_application_bin
.
/Users/pcarphin/.local/
├── bin
│ └── an_application_bin
├── lib
│ └── liban_application.so
└── opt
└── an_application_sh.sh
And then we will do this with multiple packages.
/Users/pcarphin/.local
├── bin
│ ├── an_application_bin
│ └── other_application
├── lib
│ ├── liban_application.so
│ └── libother_application.so
└── opt
├── an_application_sh.sh
└── other_application_opt.sh
By using symlinks, GNU stow
makes this happen.
If there is nothing in ~/.local
, then stow
will just create links
pointing to the directories of AnApplication
stow -t /Users/pcarphin/.local -d /Users/pcarphin/ApplicationStorage -S AnApplication
/Users/pcarphin/.local/
├── bin -> ../storage/AnApplication/bin
├── lib -> ../storage/AnApplication/lib
└── opt -> ../storage/AnApplication/opt
But once you start needing to stow something else, stow will take care of things:
stow -t /Users/pcarphin/.local -d /Users/pcarphin/ApplicationStorage -S OtherApplication
/Users/pcarphin/.local
├── bin
│ ├── an_application_bin -> ../../storage/AnApplication/bin/an_application_bin
│ └── other_application -> ../../storage/OtherApplication/bin/other_application
├── lib
│ ├── liban_application.so -> ../../storage/AnApplication/lib/liban_application.so
│ └── libother_application.so -> ../../storage/OtherApplication/lib/libother_application.so
└── opt
├── an_application_sh.sh -> ../../storage/AnApplication/opt/an_application_sh.sh
└── other_application_opt.sh -> ../../storage/OtherApplication/opt/other_application_opt.sh
We can override previously stowed things if they come from the same storage.
The bin
, lib
and opt
directories of the package link_collision
contain
files with the same names as those of AnApplication
.
stow -t /Users/pcarphin/.local -d /Users/pcarphin/ApplicationStorage -S AnApplication
stow -t /Users/pcarphin/.local -d /Users/pcarphin/ApplicationStorage -S link_collision --override='.*'
/Users/pcarphin/.local
├── bin
│ └── an_application_bin -> ../../storage/link_collision/bin/an_application_bin
├── lib
│ └── liban_application.so -> ../../storage/link_collision/lib/liban_application.so
└── opt
└── an_application_sh.sh -> ../../storage/link_collision/opt/an_application_sh.sh
We could not do this if the two packages were in different storage locations.
We could not do this to override files that are not owned by the storage location of the current command.
The reason we don’t have
stow -t $install_site -S $storage_dir/AnApplication
is because GNU stow
wants to have a concept of ownership. This
stow -t $install_site -d $storage_dir -S AnApplication
allows stow
to be safe about not messing with things that are owned by another storage.
If .local
was empty before the stow
command, it would look like this after.
/Users/pcarphin/.local/
├── bin -> ../storage/AnApplication/bin
├── lib -> ../storage/AnApplication/lib
└── opt -> ../storage/AnApplication/opt
Now, bin
is a link to something in storage
.
When we do this command
stow -t $install_site -d $other_storage_dir -S OtherApplication
stow
will want to replace bin
with a directory containing links. But since
right now we’re stow
-ing from $other_storage_dir
, stow
will refuse to
delete the bin
links that are already there.
There are ways around this. The simplest one being to create empty bin
,
lib
, opt
directories in .local
before doing anything. This would make the
previously discussed case work:
/Users/pcarphin/.local
├── bin
│ ├── an_application_bin -> ../../storage/AnApplication/bin/an_application_bin
│ └── other_application -> ../../other-storage/OtherApplication/bin/other_application
├── lib
│ ├── liban_application.so -> ../../storage/AnApplication/lib/liban_application.so
│ └── libother_application.so -> ../../other-storage/OtherApplication/lib/libother_application.so
└── opt
├── an_application_sh.sh -> ../../storage/AnApplication/opt/an_application_sh.sh
└── other_application_opt.sh -> ../../other-storage/OtherApplication/opt/other_application_opt.sh
Files beginning with '.'
are ignored.
Should we want to ignore other things of our choosing we can do it like this.
stow -t $install_site -d $storage_dir -S AnApplication --ignore '.*_internal'
Note that the options --override
and --ignore
take regular expressions and
not globs. For instance, to match anything you cannot use '*'
, that’s a glob. You need to use '.*'
.