stow.in 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. #!@PERL@
  2. # GNU Stow - manage farms of symbolic links
  3. # Copyright (C) 1993, 1994, 1995, 1996 by Bob Glickstein
  4. # Copyright (C) 2000, 2001 Guillaume Morin
  5. # Copyright (C) 2007 Kahlil Hodgson
  6. # Copyright (C) 2011 Adam Spiers
  7. #
  8. # This file is part of GNU Stow.
  9. #
  10. # GNU Stow is free software: you can redistribute it and/or modify it
  11. # under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation, either version 3 of the License, or
  13. # (at your option) any later version.
  14. #
  15. # GNU Stow is distributed in the hope that it will be useful, but
  16. # WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. # General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this program. If not, see https://www.gnu.org/licenses/.
  22. =head1 NAME
  23. stow - manage farms of symbolic links
  24. =head1 SYNOPSIS
  25. stow [ options ] package ...
  26. =head1 DESCRIPTION
  27. This manual page describes GNU Stow @VERSION@. This is not the
  28. definitive documentation for Stow; for that, see the accompanying info
  29. manual, e.g. by typing C<info stow>.
  30. Stow is a symlink farm manager which takes distinct sets of software
  31. and/or data located in separate directories on the filesystem, and
  32. makes them all appear to be installed in a single directory tree.
  33. Originally Stow was born to address the need to administer, upgrade,
  34. install, and remove files in independent software packages without
  35. confusing them with other files sharing the same file system space.
  36. For instance, many years ago it used to be common to compile programs
  37. such as Perl and Emacs from source. By using Stow, F</usr/local/bin>
  38. could contain symlinks to files within F</usr/local/stow/emacs/bin>,
  39. F</usr/local/stow/perl/bin> etc., and likewise recursively for any
  40. other subdirectories such as F<.../share>, F<.../man>, and so on.
  41. While this is useful for keeping track of system-wide and per-user
  42. installations of software built from source, in more recent times
  43. software packages are often managed by more sophisticated package
  44. management software such as rpm, dpkg, and Nix / GNU Guix, or
  45. language-native package managers such as Ruby's gem, Python's pip,
  46. Javascript's npm, and so on.
  47. However Stow is still used not only for software package management,
  48. but also for other purposes, such as facilitating a more controlled
  49. approach to management of configuration files in the user's home
  50. directory, especially when coupled with version control systems.
  51. Stow was inspired by Carnegie Mellon's Depot program, but is
  52. substantially simpler and safer. Whereas Depot required database files
  53. to keep things in sync, Stow stores no extra state between runs, so
  54. there's no danger (as there was in Depot) of mangling directories when
  55. file hierarchies don't match the database. Also unlike Depot, Stow
  56. will never delete any files, directories, or links that appear in a
  57. Stow directory (e.g., F</usr/local/stow/emacs>), so it's always
  58. possible to rebuild the target tree (e.g., F</usr/local>).
  59. Stow is implemented as a combination of a Perl script providing a CLI
  60. interface, and a backend Perl module which does most of the work.
  61. =head1 TERMINOLOGY
  62. A "package" is a related collection of files and directories that
  63. you wish to administer as a unit -- e.g., Perl or Emacs -- and that
  64. needs to be installed in a particular directory structure -- e.g.,
  65. with F<bin>, F<lib>, and F<man> subdirectories.
  66. A "target directory" is the root of a tree in which one or more
  67. packages wish to B<appear> to be installed. A common, but by no means
  68. the only such location is F</usr/local>. The examples in this manual
  69. page will use F</usr/local> as the target directory.
  70. A "stow directory" is the root of a tree containing separate
  71. packages in private subtrees. When Stow runs, it uses the current
  72. directory as the default stow directory. The examples in this manual
  73. page will use F</usr/local/stow> as the stow directory, so that
  74. individual packages will be, for example, F</usr/local/stow/perl> and
  75. F</usr/local/stow/emacs>.
  76. An "installation image" is the layout of files and directories
  77. required by a package, relative to the target directory. Thus, the
  78. installation image for Perl includes: a F<bin> directory containing
  79. F<perl> and F<a2p> (among others); an F<info> directory containing
  80. Texinfo documentation; a F<lib/perl> directory containing Perl
  81. libraries; and a F<man/man1> directory containing man pages.
  82. A "package directory" is the root of a tree containing the
  83. installation image for a particular package. Each package directory
  84. must reside in a stow directory -- e.g., the package directory
  85. F</usr/local/stow/perl> must reside in the stow directory
  86. F</usr/local/stow>. The "name" of a package is the name of its
  87. directory within the stow directory -- e.g., F<perl>.
  88. Thus, the Perl executable might reside in
  89. F</usr/local/stow/perl/bin/perl>, where F</usr/local> is the target
  90. directory, F</usr/local/stow> is the stow directory,
  91. F</usr/local/stow/perl> is the package directory, and F<bin/perl>
  92. within is part of the installation image.
  93. A "symlink" is a symbolic link. A symlink can be "relative" or
  94. "absolute". An absolute symlink names a full path; that is, one
  95. starting from F</>. A relative symlink names a relative path; that
  96. is, one not starting from F</>. The target of a relative symlink is
  97. computed starting from the symlink's own directory. Stow only creates
  98. relative symlinks.
  99. =head1 OPTIONS
  100. The stow directory is assumed to be the value of the C<STOW_DIR>
  101. environment variable or if unset the current directory, and the target
  102. directory is assumed to be the parent of the current directory (so it
  103. is typical to execute F<stow> from the directory F</usr/local/stow>).
  104. Each F<package> given on the command line is the name of a package in
  105. the stow directory (e.g., F<perl>). By default, they are installed
  106. into the target directory (but they can be deleted instead using
  107. C<-D>).
  108. =over 4
  109. =item -n
  110. =item --no
  111. Do not perform any operations that modify the filesystem; merely show
  112. what would happen.
  113. =item -d DIR
  114. =item --dir=DIR
  115. Set the stow directory to C<DIR> instead of the current directory.
  116. This also has the effect of making the default target directory be the
  117. parent of C<DIR>.
  118. =item -t DIR
  119. =item --target=DIR
  120. Set the target directory to C<DIR> instead of the parent of the stow
  121. directory.
  122. =item -v
  123. =item --verbose[=N]
  124. Send verbose output to standard error describing what Stow is
  125. doing. Verbosity levels are from 0 to 5; 0 is the default.
  126. Using C<-v> or C<--verbose> increases the verbosity by one; using
  127. `--verbose=N' sets it to N.
  128. =item -S
  129. =item --stow
  130. Stow the packages that follow this option into the target directory.
  131. This is the default action and so can be omitted if you are only
  132. stowing packages rather than performing a mixture of
  133. stow/delete/restow actions.
  134. =item -D
  135. =item --delete
  136. Unstow the packages that follow this option from the target directory rather
  137. than installing them.
  138. =item -R
  139. =item --restow
  140. Restow packages (first unstow, then stow again). This is useful
  141. for pruning obsolete symlinks from the target tree after updating
  142. the software in a package.
  143. =item --adopt
  144. B<Warning!> This behaviour is specifically intended to alter the
  145. contents of your stow directory. If you do not want that, this option
  146. is not for you.
  147. When stowing, if a target is encountered which already exists but is a
  148. plain file (and hence not owned by any existing stow package), then
  149. normally Stow will register this as a conflict and refuse to proceed.
  150. This option changes that behaviour so that the file is moved to the
  151. same relative place within the package's installation image within the
  152. stow directory, and then stowing proceeds as before. So effectively,
  153. the file becomes adopted by the stow package, without its contents
  154. changing.
  155. =item --no-folding
  156. Disable folding of newly stowed directories when stowing, and
  157. refolding of newly foldable directories when unstowing.
  158. =item --absolute
  159. =item -a
  160. Use absolute paths
  161. =item --ignore=REGEX
  162. Ignore files ending in this Perl regex.
  163. =item --defer=REGEX
  164. Don't stow files beginning with this Perl regex if the file is already
  165. stowed to another package.
  166. =item --override=REGEX
  167. Force stowing files beginning with this Perl regex if the file is
  168. already stowed to another package.
  169. =item --dotfiles
  170. Enable special handling for "dotfiles" (files or folders whose name
  171. begins with a period) in the package directory. If this option is
  172. enabled, Stow will add a preprocessing step for each file or folder
  173. whose name begins with "dot-", and replace the "dot-" prefix in the
  174. name by a period (.). This is useful when Stow is used to manage
  175. collections of dotfiles, to avoid having a package directory full of
  176. hidden files.
  177. For example, suppose we have a package containing two files,
  178. F<stow/dot-bashrc> and F<stow/dot-emacs.d/init.el>. With this option,
  179. Stow will create symlinks from F<.bashrc> to F<stow/dot-bashrc> and
  180. from F<.emacs.d/init.el> to F<stow/dot-emacs.d/init.el>. Any other
  181. files, whose name does not begin with "dot-", will be processed as usual.
  182. =item -V
  183. =item --version
  184. Show Stow version number, and exit.
  185. =item -h
  186. =item --help
  187. Show Stow command syntax, and exit.
  188. =back
  189. =head1 INSTALLING PACKAGES
  190. The default action of Stow is to install a package. This means
  191. creating symlinks in the target tree that point into the package tree.
  192. Stow attempts to do this with as few symlinks as possible; in other
  193. words, if Stow can create a single symlink that points to an entire
  194. subtree within the package tree, it will choose to do that rather than
  195. create a directory in the target tree and populate it with symlinks.
  196. For example, suppose that no packages have yet been installed in
  197. F</usr/local>; it's completely empty (except for the F<stow>
  198. subdirectory, of course). Now suppose the Perl package is installed.
  199. Recall that it includes the following directories in its installation
  200. image: F<bin>; F<info>; F<lib/perl>; F<man/man1>. Rather than
  201. creating the directory F</usr/local/bin> and populating it with
  202. symlinks to F<../stow/perl/bin/perl> and F<../stow/perl/bin/a2p> (and
  203. so on), Stow will create a single symlink, F</usr/local/bin>, which
  204. points to F<stow/perl/bin>. In this way, it still works to refer to
  205. F</usr/local/bin/perl> and F</usr/local/bin/a2p>, and fewer symlinks
  206. have been created. This is called "tree folding", since an entire
  207. subtree is "folded" into a single symlink.
  208. To complete this example, Stow will also create the symlink
  209. F</usr/local/info> pointing to F<stow/perl/info>; the symlink
  210. F</usr/local/lib> pointing to F<stow/perl/lib>; and the symlink
  211. F</usr/local/man> pointing to F<stow/perl/man>.
  212. Now suppose that instead of installing the Perl package into an empty
  213. target tree, the target tree is not empty to begin with. Instead, it
  214. contains several files and directories installed under a different
  215. system-administration philosophy. In particular, F</usr/local/bin>
  216. already exists and is a directory, as are F</usr/local/lib> and
  217. F</usr/local/man/man1>. In this case, Stow will descend into
  218. F</usr/local/bin> and create symlinks to F<../stow/perl/bin/perl> and
  219. F<../stow/perl/bin/a2p> (etc.), and it will descend into
  220. F</usr/local/lib> and create the tree-folding symlink F<perl> pointing
  221. to F<../stow/perl/lib/perl>, and so on. As a rule, Stow only descends
  222. as far as necessary into the target tree when it can create a
  223. tree-folding symlink.
  224. The time often comes when a tree-folding symlink has to be undone
  225. because another package uses one or more of the folded subdirectories
  226. in its installation image. This operation is called "splitting open"
  227. a folded tree. It involves removing the original symlink from the
  228. target tree, creating a true directory in its place, and then
  229. populating the new directory with symlinks to the newly-installed
  230. package B<and> to the old package that used the old symlink. For
  231. example, suppose that after installing Perl into an empty
  232. F</usr/local>, we wish to install Emacs. Emacs's installation image
  233. includes a F<bin> directory containing the F<emacs> and F<etags>
  234. executables, among others. Stow must make these files appear to be
  235. installed in F</usr/local/bin>, but presently F</usr/local/bin> is a
  236. symlink to F<stow/perl/bin>. Stow therefore takes the following
  237. steps: the symlink F</usr/local/bin> is deleted; the directory
  238. F</usr/local/bin> is created; links are made from F</usr/local/bin> to
  239. F<../stow/emacs/bin/emacs> and F<../stow/emacs/bin/etags>; and links
  240. are made from F</usr/local/bin> to F<../stow/perl/bin/perl> and
  241. F<../stow/perl/bin/a2p>.
  242. When splitting open a folded tree, Stow makes sure that the symlink
  243. it is about to remove points inside a valid package in the current stow
  244. directory.
  245. =head2 Stow will never delete anything that it doesn't own.
  246. Stow "owns" everything living in the target tree that points into a
  247. package in the stow directory. Anything Stow owns, it can recompute if
  248. lost. Note that by this definition, Stow doesn't "own" anything
  249. B<in> the stow directory or in any of the packages.
  250. If Stow needs to create a directory or a symlink in the target tree
  251. and it cannot because that name is already in use and is not owned by
  252. Stow, then a conflict has arisen. See the "Conflicts" section in the
  253. info manual.
  254. =head1 DELETING PACKAGES
  255. When the C<-D> option is given, the action of Stow is to delete a
  256. package from the target tree. Note that Stow will not delete anything
  257. it doesn't "own". Deleting a package does B<not> mean removing it from
  258. the stow directory or discarding the package tree.
  259. To delete a package, Stow recursively scans the target tree, skipping
  260. over the stow directory (since that is usually a subdirectory of the
  261. target tree) and any other stow directories it encounters (see
  262. "Multiple stow directories" in the info manual). Any symlink it
  263. finds that points into the package being deleted is removed. Any
  264. directory that contained only symlinks to the package being deleted is
  265. removed. Any directory that, after removing symlinks and empty
  266. subdirectories, contains only symlinks to a single other package, is
  267. considered to be a previously "folded" tree that was "split open."
  268. Stow will re-fold the tree by removing the symlinks to the surviving
  269. package, removing the directory, then linking the directory back to
  270. the surviving package.
  271. =head1 RESOURCE FILES
  272. F<Stow> searches for default command line options at F<.stowrc> (current
  273. directory) and F<~/.stowrc> (home directory) in that order. If both
  274. locations are present, the files are effectively appended together.
  275. The effect of options in the resource file is similar to simply prepending
  276. the options to the command line. For options that provide a single value,
  277. such as F<--target> or F<--dir>, the command line option will overwrite any
  278. options in the resource file. For options that can be given more than once,
  279. F<--ignore> for example, command line options and resource options are
  280. appended together.
  281. Environment variables and the tilde character (F<~>) will be expanded for
  282. options that take a file path.
  283. The options F<-D>, F<-R>, F<-S>, and any packages listed in the resource
  284. file are ignored.
  285. See the info manual for more information on how stow handles resource
  286. file.
  287. =head1 SEE ALSO
  288. The full documentation for F<stow> is maintained as a Texinfo manual.
  289. If the F<info> and F<stow> programs are properly installed at your site, the command
  290. info stow
  291. should give you access to the complete manual.
  292. =head1 BUGS
  293. Please report bugs in Stow using the Debian bug tracking system.
  294. Currently known bugs include:
  295. =over 4
  296. =item * The empty-directory problem.
  297. If package F<foo> includes an empty directory -- say, F<foo/bar> --
  298. then if no other package has a F<bar> subdirectory, everything's fine.
  299. If another stowed package F<quux>, has a F<bar> subdirectory, then
  300. when stowing, F<targetdir/bar> will be "split open" and the contents
  301. of F<quux/bar> will be individually stowed. So far, so good. But when
  302. unstowing F<quux>, F<targetdir/bar> will be removed, even though
  303. F<foo/bar> needs it to remain. A workaround for this problem is to
  304. create a file in F<foo/bar> as a placeholder. If you name that file
  305. F<.placeholder>, it will be easy to find and remove such files when
  306. this bug is fixed.
  307. =item *
  308. When using multiple stow directories (see "Multiple stow directories"
  309. in the info manual), Stow fails to "split open" tree-folding symlinks
  310. (see "Installing packages" in the info manual) that point into a stow
  311. directory which is not the one in use by the current Stow
  312. command. Before failing, it should search the target of the link to
  313. see whether any element of the path contains a F<.stow> file. If it
  314. finds one, it can "learn" about the cooperating stow directory to
  315. short-circuit the F<.stow> search the next time it encounters a
  316. tree-folding symlink.
  317. =back
  318. =head1 AUTHOR
  319. This man page was originally constructed by Charles Briscoe-Smith from
  320. parts of Stow's info manual, and then converted to POD format by Adam
  321. Spiers. The info manual contains the following notice, which, as it
  322. says, applies to this manual page, too. The text of the section
  323. entitled "GNU General Public License" can be found in the file
  324. F</usr/share/common-licenses/GPL> on any Debian GNU/Linux system. If
  325. you don't have access to a Debian system, or the GPL is not there,
  326. write to the Free Software Foundation, Inc., 59 Temple Place, Suite
  327. 330, Boston, MA, 02111-1307, USA.
  328. =head1 COPYRIGHT
  329. Copyright (C)
  330. 1993, 1994, 1995, 1996 by Bob Glickstein <bobg+stow@zanshin.com>;
  331. 2000, 2001 by Guillaume Morin;
  332. 2007 by Kahlil Hodgson;
  333. 2011 by Adam Spiers;
  334. and others.
  335. Permission is granted to make and distribute verbatim copies of this
  336. manual provided the copyright notice and this permission notice are
  337. preserved on all copies.
  338. Permission is granted to copy and distribute modified versions of this
  339. manual under the conditions for verbatim copying, provided also that
  340. the section entitled "GNU General Public License" is included with the
  341. modified manual, and provided that the entire resulting derived work
  342. is distributed under the terms of a permission notice identical to
  343. this one.
  344. Permission is granted to copy and distribute translations of this
  345. manual into another language, under the above conditions for modified
  346. versions, except that this permission notice may be stated in a
  347. translation approved by the Free Software Foundation.
  348. =cut
  349. use strict;
  350. use warnings;
  351. require 5.006_001;
  352. use POSIX qw(getcwd);
  353. use Getopt::Long qw(GetOptionsFromArray);
  354. use Scalar::Util qw(reftype);
  355. @USE_LIB_PMDIR@
  356. use Stow;
  357. use Stow::Util qw(parent error);
  358. my $ProgramName = $0;
  359. $ProgramName =~ s{.*/}{};
  360. main() unless caller();
  361. sub main {
  362. my ($options, $pkgs_to_unstow, $pkgs_to_stow) = process_options();
  363. my $stow = new Stow(%$options);
  364. # current dir is now the target directory
  365. $stow->plan_unstow(@$pkgs_to_unstow);
  366. $stow->plan_stow (@$pkgs_to_stow);
  367. my %conflicts = $stow->get_conflicts;
  368. if (%conflicts) {
  369. foreach my $action ('unstow', 'stow') {
  370. next unless $conflicts{$action};
  371. foreach my $package (sort keys %{ $conflicts{$action} }) {
  372. warn "WARNING! ${action}ing $package would cause conflicts:\n";
  373. #if $stow->get_action_count > 1;
  374. foreach my $message (sort @{ $conflicts{$action}{$package} }) {
  375. warn " * $message\n";
  376. }
  377. }
  378. }
  379. warn "All operations aborted.\n";
  380. exit 1;
  381. }
  382. else {
  383. if ($options->{simulate}) {
  384. warn "WARNING: in simulation mode so not modifying filesystem.\n";
  385. return;
  386. }
  387. $stow->process_tasks();
  388. }
  389. }
  390. #===== SUBROUTINE ===========================================================
  391. # Name : process_options()
  392. # Purpose : Parse and process command line and .stowrc file options
  393. # Parameters: none
  394. # Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow)
  395. # Throws : a fatal error if a bad option is given
  396. # Comments : checks @ARGV for valid package names
  397. #============================================================================
  398. sub process_options {
  399. # Get cli options.
  400. my ($cli_options,
  401. $pkgs_to_unstow,
  402. $pkgs_to_stow) = parse_options(@ARGV);
  403. # Get the .stowrc options.
  404. # Note that rc_pkgs_to_unstow and rc_pkgs_to_stow are ignored.
  405. my ($rc_options,
  406. $rc_pkgs_to_unstow,
  407. $rc_pkgs_to_stow) = get_config_file_options();
  408. # Merge .stowrc and command line options.
  409. # Preference is given to cli options.
  410. my %options = %$rc_options;
  411. foreach my $option (keys %$cli_options) {
  412. my $rc_value = $rc_options->{$option};
  413. my $cli_value = $cli_options->{$option};
  414. my $type = reftype($cli_value);
  415. if (defined $type && $type eq 'ARRAY' && defined $rc_value) {
  416. # rc options come first in merged arrays.
  417. $options{$option} = [@{$rc_value}, @{$cli_value}];
  418. } else {
  419. # cli options overwrite conflicting rc options.
  420. $options{$option} = $cli_value;
  421. }
  422. }
  423. # Run checks on the merged options.
  424. sanitize_path_options(\%options);
  425. check_packages($pkgs_to_unstow, $pkgs_to_stow);
  426. # Return merged and processed options.
  427. return (\%options, $pkgs_to_unstow, $pkgs_to_stow);
  428. }
  429. #===== SUBROUTINE ===========================================================
  430. # Name : parse_options()
  431. # Purpose : parse command line options
  432. # Parameters: @arg_array => array of options to parse
  433. # Example: parse_options(@ARGV)
  434. # Returns : (\%options, \@pkgs_to_unstow, \@pkgs_to_stow)
  435. # Throws : a fatal error if a bad command line option is given
  436. # Comments : Used for parsing both command line options and rc file. Used
  437. # for parsing only. Sanity checks and post-processing belong in
  438. # process_options().
  439. #============================================================================
  440. sub parse_options {
  441. my %options = ();
  442. my @pkgs_to_unstow = ();
  443. my @pkgs_to_stow = ();
  444. my $action = 'stow';
  445. #$,="\n"; print @_,"\n"; # for debugging rc file
  446. Getopt::Long::config('no_ignore_case', 'bundling', 'permute');
  447. GetOptionsFromArray(
  448. \@_,
  449. \%options,
  450. 'verbose|v:+', 'help|h', 'simulate|n|no',
  451. 'version|V', 'compat|p', 'dir|d=s', 'target|t=s',
  452. 'adopt', 'no-folding', 'dotfiles', 'absolute|a',
  453. # clean and pre-compile any regex's at parse time
  454. 'ignore=s' =>
  455. sub {
  456. my $regex = $_[1];
  457. push @{$options{ignore}}, qr($regex\z);
  458. },
  459. 'override=s' =>
  460. sub {
  461. my $regex = $_[1];
  462. push @{$options{override}}, qr(\A$regex);
  463. },
  464. 'defer=s' =>
  465. sub {
  466. my $regex = $_[1];
  467. push @{$options{defer}}, qr(\A$regex);
  468. },
  469. # a little craziness so we can do different actions on the same line:
  470. # a -D, -S, or -R changes the action that will be performed on the
  471. # package arguments that follow it.
  472. 'D|delete' => sub { $action = 'unstow' },
  473. 'S|stow' => sub { $action = 'stow' },
  474. 'R|restow' => sub { $action = 'restow' },
  475. # Handler for non-option arguments
  476. '<>' =>
  477. sub {
  478. if ($action eq 'restow') {
  479. push @pkgs_to_unstow, $_[0];
  480. push @pkgs_to_stow, $_[0];
  481. }
  482. elsif ($action eq 'unstow') {
  483. push @pkgs_to_unstow, $_[0];
  484. }
  485. else {
  486. push @pkgs_to_stow, $_[0];
  487. }
  488. },
  489. ) or usage('');
  490. usage() if $options{help};
  491. version() if $options{version};
  492. return (\%options, \@pkgs_to_unstow, \@pkgs_to_stow);
  493. }
  494. sub sanitize_path_options {
  495. my ($options) = @_;
  496. unless (exists $options->{dir}) {
  497. $options->{dir} = length $ENV{STOW_DIR} ? $ENV{STOW_DIR} : getcwd();
  498. }
  499. usage("--dir value '$options->{dir}' is not a valid directory")
  500. unless -d $options->{dir};
  501. if (exists $options->{target}) {
  502. usage("--target value '$options->{target}' is not a valid directory")
  503. unless -d $options->{target};
  504. }
  505. else {
  506. $options->{target} = parent($options->{dir}) || '.';
  507. }
  508. }
  509. sub check_packages {
  510. my ($pkgs_to_stow, $pkgs_to_unstow) = @_;
  511. if (not @$pkgs_to_stow and not @$pkgs_to_unstow) {
  512. usage("No packages to stow or unstow");
  513. }
  514. # check package arguments
  515. for my $package (@$pkgs_to_stow, @$pkgs_to_unstow) {
  516. $package =~ s{/+$}{}; # delete trailing slashes
  517. if ($package =~ m{/}) {
  518. error("Slashes are not permitted in package names");
  519. }
  520. }
  521. }
  522. #===== SUBROUTINE ============================================================
  523. # Name : get_config_file_options()
  524. # Purpose : search for default settings in any .stowrc files
  525. # Parameters: none
  526. # Returns : (\%rc_options, \@rc_pkgs_to_unstow, \@rc_pkgs_to_stow)
  527. # Throws : a fatal error if a bad option is given
  528. # Comments : Parses the contents of '~/.stowrc' and '.stowrc' with the same
  529. # parser as the command line options. Additionally expands any
  530. # environment variables or ~ character in --target or --dir
  531. # options.
  532. #=============================================================================
  533. sub get_config_file_options {
  534. my @defaults = ();
  535. my @dirlist = ('.stowrc');
  536. if (defined($ENV{HOME})) {
  537. unshift(@dirlist, "$ENV{HOME}/.stowrc");
  538. }
  539. for my $file (@dirlist) {
  540. if (-r $file) {
  541. open my $FILE, '<', $file
  542. or die "Could not open $file for reading\n";
  543. while (my $line = <$FILE>){
  544. chomp $line;
  545. push @defaults, split " ", $line;
  546. }
  547. close $FILE or die "Could not close open file: $file\n";
  548. }
  549. }
  550. # Parse the options
  551. my ($rc_options, $rc_pkgs_to_unstow, $rc_pkgs_to_stow) = parse_options(@defaults);
  552. # Expand environment variables and glob characters.
  553. if (exists $rc_options->{target}) {
  554. $rc_options->{target} =
  555. expand_filepath($rc_options->{target}, '--target option');
  556. }
  557. if (exists $rc_options->{dir}) {
  558. $rc_options->{dir} =
  559. expand_filepath($rc_options->{dir}, '--dir option');
  560. }
  561. return ($rc_options, $rc_pkgs_to_unstow, $rc_pkgs_to_stow);
  562. }
  563. #===== SUBROUTINE ============================================================
  564. # Name : expand_filepath()
  565. # Purpose : Handles expansions that need to be applied to
  566. # : file paths. Currently expands environment
  567. # : variables and the tilde.
  568. # Parameters: $path => string to perform expansion on.
  569. # : $source => where the string came from
  570. # Returns : String with replacements performed.
  571. # Throws : n/a
  572. # Comments : n/a
  573. #=============================================================================
  574. sub expand_filepath {
  575. my ($path, $source) = @_;
  576. $path = expand_environment($path, $source);
  577. $path = expand_tilde($path);
  578. return $path;
  579. }
  580. #===== SUBROUTINE ============================================================
  581. # Name : expand_environment()
  582. # Purpose : Expands evironment variables.
  583. # Parameters: $path => string to perform expansion on.
  584. # : $source => where the string came from
  585. # Returns : String with replacements performed.
  586. # Throws : n/a
  587. # Comments : Variable replacement mostly based on SO answer
  588. # : http://stackoverflow.com/a/24675093/558820
  589. #=============================================================================
  590. sub expand_environment {
  591. my ($path, $source) = @_;
  592. # Replace non-escaped $VAR and ${VAR} with $ENV{VAR}
  593. # If $ENV{VAR} does not exist, perl will raise a warning
  594. # and then happily treat it as an empty string.
  595. $path =~ s/(?<!\\)\$\{((?:\w|\s)+)\}/
  596. _safe_expand_env_var($1, $source)
  597. /ge;
  598. $path =~ s/(?<!\\)\$(\w+)/
  599. _safe_expand_env_var($1, $source)
  600. /ge;
  601. # Remove \$ escapes.
  602. $path =~ s/\\\$/\$/g;
  603. return $path;
  604. }
  605. sub _safe_expand_env_var {
  606. my ($var, $source) = @_;
  607. unless (exists $ENV{$var}) {
  608. die "$source references undefined environment variable \$$var; " .
  609. "aborting!\n";
  610. }
  611. return $ENV{$var};
  612. }
  613. #===== SUBROUTINE ============================================================
  614. # Name : expand_tilde()
  615. # Purpose : Expands tilde to user's home directory path.
  616. # Parameters: $path => string to perform expansion on.
  617. # Returns : String with replacements performed.
  618. # Throws : n/a
  619. # Comments : http://docstore.mik.ua/orelly/perl4/cook/ch07_04.htm
  620. #=============================================================================
  621. sub expand_tilde {
  622. my ($path) = @_;
  623. # Replace tilde with home path.
  624. $path =~ s{ ^ ~ ( [^/]* ) }
  625. { $1
  626. ? (getpwnam($1))[7]
  627. : ( $ENV{HOME} || $ENV{LOGDIR}
  628. || (getpwuid($<))[7]
  629. )
  630. }ex;
  631. # Replace espaced tilde with regular tilde.
  632. $path =~ s/\\~/~/g;
  633. return $path
  634. }
  635. #===== SUBROUTINE ===========================================================
  636. # Name : usage()
  637. # Purpose : print program usage message and exit
  638. # Parameters: $msg => string to prepend to the usage message
  639. # Returns : n/a
  640. # Throws : n/a
  641. # Comments : if 'msg' is given, then exit with non-zero status
  642. #============================================================================
  643. sub usage {
  644. my ($msg) = @_;
  645. if ($msg) {
  646. warn "$ProgramName: $msg\n\n";
  647. }
  648. print <<"EOT";
  649. $ProgramName (GNU Stow) version $Stow::VERSION
  650. SYNOPSIS:
  651. $ProgramName [OPTION ...] [-D|-S|-R] PACKAGE ... [-D|-S|-R] PACKAGE ...
  652. OPTIONS:
  653. -d DIR, --dir=DIR Set stow dir to DIR (default is current dir)
  654. -t DIR, --target=DIR Set target to DIR (default is parent of stow dir)
  655. -S, --stow Stow the package names that follow this option
  656. -D, --delete Unstow the package names that follow this option
  657. -R, --restow Restow (like stow -D followed by stow -S)
  658. -a, --absolute Use absolute paths
  659. --dotfiles Convert filenames starting with `dot-' to `.'
  660. --no-folding Disable folding of newly stowed directories when stowing,
  661. and refolding of newly foldable directories when unstowing.
  662. --ignore=REGEX Ignore files ending in this Perl regex
  663. --defer=REGEX Don't stow files beginning with this Perl regex
  664. if the file is already stowed to another package
  665. --override=REGEX Force stowing files beginning with this Perl regex
  666. if the file is already stowed to another package
  667. --adopt (Use with care!) Import existing files into stow package
  668. from target. Please read docs before using.
  669. -p, --compat Use legacy algorithm for unstowing
  670. -n, --no, --simulate Do not actually make any filesystem changes
  671. -v, --verbose[=N] Increase verbosity (levels are from 0 to 5;
  672. -v or --verbose adds 1; --verbose=N sets level)
  673. -V, --version Show stow version number
  674. -h, --help Show this help
  675. Report bugs to: bug-stow\@gnu.org
  676. Stow home page: <http://www.gnu.org/software/stow/>
  677. General help using GNU software: <http://www.gnu.org/gethelp/>
  678. EOT
  679. exit defined $msg ? 1 : 0;
  680. }
  681. sub version {
  682. print "$ProgramName (GNU Stow) version $Stow::VERSION\n";
  683. exit 0;
  684. }
  685. 1; # This file is required by t/stow.t
  686. # Local variables:
  687. # mode: perl
  688. # cperl-indent-level: 4
  689. # end:
  690. # vim: ft=perl