pax_global_header00006660000000000000000000000064137222655010014515gustar00rootroot0000000000000052 comment=b9123ffae961bdb1a0e9c9a64c57ebd3d15c4ebf rcm-1.3.4/000077500000000000000000000000001372226550100123035ustar00rootroot00000000000000rcm-1.3.4/.gitignore000066400000000000000000000011041372226550100142670ustar00rootroot00000000000000# autotools related files Makefile Makefile.in */Makefile */Makefile.in aclocal.m4 autom4te.cache autoscan.log config.log config.status configure configure.scan install-sh missing depcomp # Make targets debian/rcm debian/rcm.debhelper.log share/rcm.sh arch/git-PKGBIULD bin/lsrc bin/mkrc bin/rcup bin/rcdn *deb NEWS.md rcm-*.tar.gz arch/git-PKGBUILD # Sub-repositories for release gh-pages homebrew-formulae release-arch deb-build rcm-* # Files generated for or during testing test-driver *.t.err *.t.trs *.t.log test-suite.log # Other generated files man/rcm.7 maint/release rcm-1.3.4/.mailmap000066400000000000000000000010561372226550100137260ustar00rootroot00000000000000George Brocklehurst George Brocklehurst Javier López Melissa Xie Mike Burns Pablo Olmos de Aguilera Corradini Patrick Brisbin Martin Frost David Alexander rcm-1.3.4/CODE_OF_CONDUCT.md000066400000000000000000000002511372226550100151000ustar00rootroot00000000000000# Code of conduct By participating in this project, you agree to abide by the [thoughtbot code of conduct][1]. [1]: https://thoughtbot.com/open-source-code-of-conduct rcm-1.3.4/CONTRIBUTING.md000066400000000000000000000113131372226550100145330ustar00rootroot00000000000000Contributing ============ Overview -------- - Make your changes. - Update `NEWS.md.in`. - Update `.mailmap` if necessary. - Write a test covering your feature or fix. - Ensure existing and new tests are passing. - Submit a pull request on GitHub. Explanation ----------- Consider updating `NEWS.md.in`. The topmost section is for the upcoming release. Bugfixes should be marked with `BUGFIX`. Small things (typos, code style) should be grouped but with multiple authors (`Documentation updates thanks to Dan Croak and Roberto Pedroso`). We use your name and email address as produced by `git-shortlog(1)`. You can change how this is formatted by modifying `.mailmap`. More details on that file can be found in the git [Documentation/mailmap.txt][mailmap]. It is mandatory to include tests with pull requests. You must ensure that the existing test suite passes with any changes you make. Also, any attempts to add or extend tests will increase the chances of your pull request being merged. Submit a pull request using GitHub. If there is a relevant bug, mention it in the commit message (`Fixes #42.`). We love pull requests from everyone. By participating in this project, you agree to abide by the thoughtbot [code of conduct]. [mailmap]: https://github.com/git/git/blob/master/Documentation/mailmap.txt [code of conduct]: https://thoughtbot.com/open-source-code-of-conduct Setup ----- 1. Fork the repo. 2. Install dependencies - Cram is used for tests: `pip install cram` - The mustache gem for building the HTML pages: `gem install mustache` 3. Prepare the build system: `./autogen.sh`. (This depends on GNU autoconf and GNU automake.) 4. Configure the package: `./configure`. 5. Make sure the tests pass: `make check`. 6. Start hacking Testing ------- The test suite uses [cram][]. It is an integration suite, meaning the programs are exercised from the outside and assertions are made only on their output or effects. The test suite requires Perl with the `Cwd` module. It expects to find Perl as `perl` in `$PATH`. All tests can be run like so: $ make check Individual tests can be run like so: $ env TESTS=test/lsrc-dotfiles-dirs.t make -e check If you intend to write a new test: 1. Add your test at `test/subcommand-something-meaningful.t`. 2. Add the relative name to the `TESTS` variable in `Makefile.am`. 3. Source `test/helper.sh` as the first line of your test. 4. When in doubt, use existing tests as a guide. [cram]: https://bitheap.org/cram/ Governance ========== Your interaction with this project can be divided into three sections: you as a contributor, you as a committer, and how to become a committer. Commenter and meta-contributor ------------------------------ Those commenting and triaging issues and pull reports are expected to adhere to our [code of conduct]. Contributor ----------- This is a slow-moving project. The maintainers' goal is to provide a yearly release. As a contributor, you can expect a maintainer to add a GitHub label to your pull request or issue within two weeks. This indicates that a maintainer has seen your contribution and quickly triaged it. If a maintainer believe that your feature request will not be merged, they will tell you as much during the triage step. Bug reports, either as issues or as pull requests, get the maintainers' priority. The maintainers consider documentation bugs to be as important as code bugs. Feature contributions (that is, a pull request that add a new feature) get lower priority. A maintainer will evaluate the patch carefully for maintainability and to ensure the test coverage is high. Feature requests without a patch will be closed. A maintainer will try to provide a description of how to write your patch while we close the request, though they cannot guarantee this. Interactions outside of GitHub Issues and Pull Requests are not considered contributing. For example, tweeting about a bug in rcm is not contributing to rcm, and therefore we can make no guarantees or promises about such an action. You are expected to adhere to our [code of conduct]. Committer --------- As a committer, you can merge at any time. The maintainers encourage you to have the code reviewed by someone beforehand. Those in the thoughtbot team can ping the `@thoughtbot/shell` group. You are expected to adhere to our [code of conduct]. Maintainer ---------- A maintainer acts as a project manager and, as such, has final say and responsibility. All maintainers must adhere to our [code of conduct]. Promotion --------- All current thoughtbot employees are committers to rcm. Contributors with two merged patches are welcome to request committer access by emailing support@thoughtbot.com. Existing contributors become a maintainer by taking on more work and responsibility. rcm-1.3.4/DEVELOPERS.md000066400000000000000000000044241372226550100143010ustar00rootroot00000000000000Developers ========== Making a release ---------------- 1. Bump the version within the `AC_INIT` macro call in `configure.ac`. 2. Update the build system by running: `./autogen.sh`. 3. Build the trivial packages: This all depends on a `gh-pages` branch: git branch gh-pages origin/gh-pages First build the distribution: ./configure make distcheck On any system you can build the tarball and tag: ./maint/release build tarball rcm-*.tar.gz ./maint/release build tag rcm-*.tar.gz You need mdocml to tranform the manpages into HTML: ./maint/release build man_html rcm-*.tar.gz Once built, you can push it live: ./maint/release push tarball rcm-*.tar.gz ./maint/release push tag rcm-*.tar.gz ./maint/release push man_html rcm-*.tar.gz And once pushed, you should clean up ./maint/release clean tarball rcm-*.tar.gz ./maint/release clean tag rcm-*.tar.gz ./maint/release clean man_html rcm-*.tar.gz 4. Contact package maintainers: | OS | Name | Email | PGP keyid | | -------- | -------------------------- | ----------------------------- | ------------------ | | Alpine | Hiroshi Kajisha | | ? | | Arch | Max Falk | | 0x9cbdc83ba3753845 | | Debian | Eric Collins | | 0x7BEB44E2771AB877 | | Fedora | Carl van Tonder | | 0xa478c47bcb683786 | | Gentoo | Florian Tham | | 0x7286dc0e62941423 | | Korora | Carl van Tonder | | 0xb55275fbcbe8383c | | Homebrew | Stephen Groat | | 0x3FEA0C7A20399F68 | | MacPorts | Aljaž Srebrnič | | 0xe140e1eea54ee677 | | OpenBSD | Mike Burns | | 0x3E6761F72846B014 | | openSUSE | Andrei Dziahel | | 0x58BA3FA4A49D76C2 | | Ubuntu | Martin Frost | | 0x4609D1E5ECA538E6 | | Void | maxice8 | | 0xffaeeb9ca1c95204 | rcm-1.3.4/INSTALL000066400000000000000000000132201372226550100133320ustar00rootroot00000000000000This is a generic INSTALL file for utilities distributions. If this package does not come with, e.g., installable documentation or data files, please ignore the references to them below. To compile this package: 1. Configure the package for your system. In the directory that this file is in, type `./configure'. If you're using `csh' on an old version of System V, you might need to type `sh configure' instead to prevent `csh' from trying to execute `configure' itself. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation, and creates the Makefile(s) (one in each subdirectory of the source directory). In some packages it creates a C header file containing system-dependent definitions. It also creates a file `config.status' that you can run in the future to recreate the current configuration. Running `configure' takes a minute or two. While it is running, it prints some messages that tell what it is doing. If you don't want to see the messages, run `configure' with its standard output redirected to `/dev/null'; for example, `./configure >/dev/null'. To compile the package in a different directory from the one containing the source code, you must use a version of `make' that supports the VPATH variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run `configure'. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If for some reason `configure' is not in the source code directory that you are configuring, then it will report that it can't find the source code. In that case, run `configure' with the option `--srcdir=DIR', where DIR is the directory that contains the source code. By default, `make install' will install the package's files in /usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify an installation prefix other than /usr/local by giving `configure' the option `--prefix=PATH'. Alternately, you can do so by consistently giving a value for the `prefix' variable when you run `make', e.g., make prefix=/usr/gnu make prefix=/usr/gnu install You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH' or set the `make' variable `exec_prefix' to PATH, the package will use PATH as the prefix for installing programs and libraries. Data files and documentation will still use the regular prefix. Normally, all files are installed using the regular prefix. Another `configure' option is useful mainly in `Makefile' rules for updating `config.status' and `Makefile'. The `--no-create' option figures out the configuration for your system and records it in `config.status', without actually configuring the package (creating `Makefile's and perhaps a configuration header file). Later, you can run `./config.status' to actually configure the package. You can also give `config.status' the `--recheck' option, which makes it re-run `configure' with the same arguments you used before. This option is useful if you change `configure'. Some packages pay attention to `--with-PACKAGE' options to `configure', where PACKAGE is something like `gnu-libc' or `x' (for the X Window System). The README should mention any --with- options that the package recognizes. `configure' ignores any other arguments that you give it. If your system requires unusual options for compilation or linking that `configure' doesn't know about, you can give `configure' initial values for some variables by setting them in the environment. In Bourne-compatible shells, you can do that on the command line like this: CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure The `make' variables that you might want to override with environment variables when running `configure' are: (For these variables, any value given in the environment overrides the value that `configure' would choose:) CC C compiler program. Default is `cc', or `gcc' if `gcc' is in your PATH. INSTALL Program to use to install files. Default is `install' if you have it, `cp' otherwise. (For these variables, any value given in the environment is added to the value that `configure' chooses:) DEFS Configuration options, in the form `-Dfoo -Dbar ...' Do not use this variable in packages that create a configuration header file. LIBS Libraries to link with, in the form `-lfoo -lbar ...' If you need to do unusual things to compile the package, we encourage you to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the README so we can include them in the next release. 2. Type `make' to compile the package. If you want, you can override the `make' variables CFLAGS and LDFLAGS like this: make CFLAGS=-O2 LDFLAGS=-s 3. If the package comes with self-tests and you want to run them, type `make check'. If you're not sure whether there are any, try it; if `make' responds with something like make: *** No way to make target `check'. Stop. then the package does not come with self-tests. 4. Type `make install' to install programs, data files, and documentation. 5. You can remove the program binaries and object files from the source directory by typing `make clean'. To also remove the Makefile(s), the header file containing system-dependent definitions (if the package uses one), and `config.status' (all the files that `configure' created), type `make distclean'. The file `configure.in' is used as a template to create `configure' by a program called `autoconf'. You will only need it if you want to regenerate `configure' using a newer version of `autoconf'. rcm-1.3.4/LICENSE000066400000000000000000000027711372226550100133170ustar00rootroot00000000000000Copyright (c) 2013, Mike Burns Copyright (c) 2014, thoughtbot All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Mike Burns nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rcm-1.3.4/Makefile.am000066400000000000000000000026301372226550100143400ustar00rootroot00000000000000AUTOMAKE_OPTIONS = foreign EXTRA_DIST = LICENSE README.md NEWS.md dist_bin_SCRIPTS = bin/lsrc bin/mkrc bin/rcup bin/rcdn # When changing this you must also change maint/release.in . dist_man_MANS = man/lsrc.1 man/mkrc.1 man/rcdn.1 man/rcup.1 man/rcrc.5 man/rcm.7 dist_pkgdata_DATA = share/rcm.sh TESTS = \ test/lsrc-dotfiles-dirs.t \ test/lsrc-excludes.t \ test/lsrc-hostname.t \ test/lsrc-sigils.t \ test/lsrc.t \ test/lsrc-symlink-dirs.t \ test/lsrc-spaces.t \ test/lsrc-tags.t \ test/lsrc-usage.t \ test/lsrc-undotted.t \ test/lsrc-undotted-star.t \ test/lsrc-host-tags-default.t \ test/lsrc-globs.t \ test/mkrc-alternate-dotfiles-dir.t \ test/mkrc-copy-file.t \ test/mkrc-host-file.t \ test/mkrc-hostname.t \ test/mkrc-no-symlinks.t \ test/mkrc-simple-output.t \ test/mkrc-spaces.t \ test/mkrc-symlink-dirs.t \ test/mkrc-tagged-file.t \ test/mkrc-usage.t \ test/mkrc-undotted.t \ test/rcrc-custom.t \ test/rcrc-tilde.t \ test/rcrc-hostname.t \ test/rcrc.t \ test/rcup-link-files.t \ test/rcup-hostname.t \ test/rcup-standalone.t \ test/rcup-symlink-dirs.t \ test/rcup-symlink-existing.t \ test/rcup-usage.t \ test/rcdn-hooks.t \ test/rcdn-hooks-run-in-situ.t \ test/rcdn-hooks-run-in-order.t \ test/rcup-hooks.t \ test/rcup-hooks-run-in-situ.t \ test/rcup-hooks-run-in-order.t \ test/rcup-spaces.t dist_check_SCRIPTS = $(TESTS) dist_check_DATA = test/helper.sh LOG_COMPILER = cram rcm-1.3.4/NEWS.md.in000066400000000000000000000144361372226550100140160ustar00rootroot00000000000000rcm (@PACKAGE_VERSION@) unstable; urgency=low * BUGFIX: Globs no longer expand permanently (Edd Salkield). * BUGFIX: Show $ for symlinked dirs in `lsrc -F` (Mathias Michel). * Feature: All symlinks in input are rejected (Mat M). * Packaging improvements (Stephen Groat, Martin Frost, Link Dupont). -- Mike Burns Fri, 13 Jul 2018 14:12:00 -0500 rcm (1.3.3) unstable; urgency=low * Feature: Expand ~ in DOTFILES_DIR hooks (Eric Collins). -- Mike Burns Fri, 13 Jul 2018 14:12:00 -0500 rcm (1.3.2) unstable; urgency=low * BUGFIX: Use =, not ==, in test(1) (Florian Tham). * BUGFIX: Directories with spaces in rcup(1) (Florian Tham). * BUGFIX: Fallback the LOGNAME from whoami (AJ Villalobos, Mike Burns). * BUGFIX: Fix cd for paths beginning with hyphen (-) (Christian Höltje). * Feature: Expand ~ in DOTFILES_DIR (Rebecca Meritz). * Documentation improvements (Alan Yee, Eric Collins, Florian Tham, kajisha, Matthew Horan, maxice8, Mike Burns, Rebecca Meritz, Scott Stevenson, Tyson Gach, Yota Toyama). -- Mike Burns Fri, 06 Jul 2018 11:00:00 -0500 rcm (1.3.1) unstable; urgency=low * BUGFIX: Handle dotfile names with spaces in them (Eric Collins, Mike Burns). * BUGFIX: Relative exclude globs now work (Eric Collins, Mike Burns). * BUGFIX: Use $LOGNAME instead of $USER for compatibility (Mike Burns). * BUGFIX: rcdn(1) stops at DEST_DIR (Kyle Cook, Mike Burns). * BUGFIX: Symlink existing files, even when identical (Graham Bennett). * BUGFIX: Sort hooks by filename before execution instead of arbitrary order (David Alexander). * Documentation improvements (Nick Novitski, Ben Stephens, Casey Rodarmor). -- Mike Burns Sat, 26 Dec 2016 17:00:00 -0500 rcm (1.3.0) unstable; urgency=low * BUGFIX: Control whether hooks should run in rcdn(1) with the -K and -k flags (Ben Turrubiates, Christopher Koch, Mike Burns, Mikkel Fahnøe Jørgensen). * Massive documentation fixes and updates (Christopher Koch, David Alexander, Jason Daniel Augustine Gilliland, Martin Frost, Melissa Xie, Mike Burns, Scott Stevenson, Jarkko Kniivilä, Blake Williams, Carl van Tonder, Teo Ljungberg, Zach Latta, Devraj Mehta, Vlad GURDIGA, Joe Ferris). * Host-specific files take priority, then tags, then default (Christian Höltje). * Run hooks in the directory in which they are located (Jarkko Kniivilä). * Generate a minimal standalone rcup(1) script with the -g flag (Mike Burns). * Support rc files without leading dots via the -U and -u flags in lsrc(1), rcup(1), and rcdn(1), and the UNDOTTED setting in rcrc(5) (Christopher Koch). * Improved Solaris support (Jarkko Kniivilä). * Override `SYMLINK_DIRS` or -S with -s (Mike Burns). * Show usage information when given bad arguments (Mike Burns). -- Mike Burns Thu, 08 Jan 2015 14:50:00 +0200 rcm (1.2.3) unstable; urgency=low * BUGFIX: Allow files with the same prefix name in the same directory (Javier López). * BUGFIX: Pick up hooks that are executable by the user or by the group, instead of only files that are 777 (Christian Höltje). * Allow running mkrc on a relative file and preserve the path (Pablo Olmos de Aguilera Corradini). * A flag (-B), and a variable for rcrc(5) (HOSTNAME), for changing the hostname as rcm sees it. This is highly recommended under OS X (Mike Burns). * Transfer copyright to thoughtbot, under the same license (Mike Burns). -- Mike Burns Fri, 09 May 2014 14:17:49 +0200 rcm (1.2.2) unstable; urgency=low * BUGFIX: Cygwin now executes hooks (Daniel Watson). * BUGFIX: Support -v option on OpenBSD (Javier López). * BUGFIX: Use a POSIX shell on Solaris (Mike Burns). * Documentation fixes (John Axel Eriksson, Mike Burns). * Packaging improvements (Mike Burns, Andrei Dziahel). -- Mike Burns Mon, 03 Feb 2014 16:58:33 +0200 rcm (1.2.1) unstable; urgency=low * BUGFIX: Support multiple -d options when given relative paths (Mike Burns). * BUGFIX: Cygwin compatibility for hostname (Mike Burns). * Handle more files with spaces in their filename (Caleb Land, Pat Brisbin, Mike Burns). * Hooks in directories instead of just single executables (Pablo Olmos de Aguilera Corradini, Mike Burns, Pat Brisbin). * Option to force some directories to be symlinks, as documented under SYMLINK_DIRS in rcrc(5) and -S for lsrc(1) (Pablo Olmos de Aguilera Corradini). * Improved packaging process (Mike Burns). * Documentation fixes and updates (Jordan Eldredge, Anton Ilin, Mike Burns). -- Mike Burns Mon, 03 Feb 2014 16:58:33 +0200 rcm (1.2.0) unstable; urgency=low * Transfer ownership to thoughtbot. * BUGFIX: Run hooks by default. Thanks to Patrick Brisbin. * BUGFIX: Unset CDPATH when starting. Thanks to Geoff Harcourt. * Override .rcrc location using RCRC environment variable. Thanks to Patrick Brisbin. * Upgrade to automake 1.14. * Improve mkrc verbose mode. Thanks to Pablo Olmos de Aguilera Corradini. * Use the thoughtbot/formulae Homebrew tap. Thanks to George Brocklehurst. * Manpage fixes thanks to Dan Croak and Roberto Pedroso. -- Mike Burns Mon, 03 Feb 2014 16:58:33 +0200 rcm (1.1.0) unstable; urgency=low * BUGFIX: use a consistent method for computing hostname everywhere. Thanks to George Brocklehurst. * Exclusion and inclusion with -x and -I. * Copy instead of symlink with -C. * Always copy the files listed in COPY_ALWAYS. * Show whether the file is a copy or symlink using lsrc -F. * Add hooks for pre-up, post-up, pre-down, and post-down. * rcup -K and rcdn -K to ignore these hooks. -- Mike Burns Mon, 05 Aug 2013 16:43:33 +0200 rcm (1.0.0) unstable; urgency=low * Improved Debian handling. * Introduce mkrc -o to install host-specific dotfiles. * Add rcdn(1) to remove rc files. * Add rcup -f and -i to force overwrites/prompt for overwrites. -- Mike Burns Tue, 01 Aug 2013 16:43:33 +0200 rcm (0.0.2) unstable; urgency=low * Tutorial in rcm(7). * mkrc supports -d . * -d supports relative dotfile dirs. -- Mike Burns Tue, 23 Jul 2013 16:43:33 +0200 rcm-1.3.4/README.md000066400000000000000000000072221372226550100135650ustar00rootroot00000000000000rcm === This is a management suite for dotfiles. **See [the tutorial][rcm7] to get started quickly.** It assumes that you have a separate dotfiles directory, or are interested in creating one. The programs provided are [rcup(1)][rcup1], [mkrc(1)][mkrc1], [rcdn(1)][rcdn1], and [lsrc(1)][lsrc1]. They are explained in [the tutorial][rcm7] and configured using [rcrc(5)][rcrc5]. Installation ------------ Alpine Linux: sudo apk add rcm Arch Linux: https://aur.archlinux.org/packages/rcm/ Debian (see further down for Ubuntu): wget -qO - https://apt.thoughtbot.com/thoughtbot.gpg.key | sudo apt-key add - echo "deb https://apt.thoughtbot.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/thoughtbot.list sudo apt-get update sudo apt-get install rcm Fedora: sudo dnf install rcm FreeBSD: sudo pkg install rcm Gentoo: emerge app-admin/rcm Korora: 64-bit Korora 23: sudo dnf copr enable seeitcoming/rcm fedora-23-x86_64 sudo dnf install rcm Korora is similar to Fedora but with [an additional version and architecture specification][copr-fedora-korora]. Replace `fedora-23-x86_64` as appropriate. [copr-fedora-korora]: https://kororaproject.org/about/news/when-adding-a-copr-repo-to-korora-fails macOS with Homebrew: brew install rcm macOS with MacPorts: port install rcm OpenBSD: doas pkg_add rcm openSUSE/RHEL/CentOS: [instructions](http://software.opensuse.org/download.html?project=utilities&package=rcm) Ubuntu (19.04 or later): sudo apt update sudo apt install rcm Ubuntu (12.04, 14.04, 16.04, 18.04, or 18.10): sudo apt-get install software-properties-common sudo add-apt-repository ppa:martin-frost/thoughtbot-rcm sudo apt-get update sudo apt-get install rcm Void Linux: sudo xbps-install -S rcm Elsewhere: This uses the standard GNU autotools, so it's the normal dance: curl -LO https://thoughtbot.github.io/rcm/dist/rcm-1.3.3.tar.gz && sha=$(sha256 rcm-1.3.3.tar.gz | cut -f1 -d' ') && [ "$sha" = "935524456f2291afa36ef815e68f1ab4a37a4ed6f0f144b7de7fb270733e13af" ] && tar -xvf rcm-1.3.3.tar.gz && cd rcm-1.3.3 && ./configure && make && sudo make install For more, see `INSTALL`. Programs -------- * [rcup(1)][rcup1] is the main program. It is used to install and update dotfiles, with support for tags, host-specific files, and multiple source directories. * [rcdn(1)][rcdn1] is the opposite of [rcup(1)][rcup1]. * [mkrc(1)][mkrc1] is for introducing a dotfile into your dotfiles directory, with support for tags and multiple source directories. * [lsrc(1)][lsrc1] shows you all your dotfiles and where they would be symlinked to. It is used by [rcup(1)][rcup1] but is provided for your own use, too. [rcup1]: http://thoughtbot.github.io/rcm/rcup.1.html [mkrc1]: http://thoughtbot.github.io/rcm/mkrc.1.html [rcdn1]: http://thoughtbot.github.io/rcm/rcdn.1.html [lsrc1]: http://thoughtbot.github.io/rcm/lsrc.1.html [rcm7]: http://thoughtbot.github.io/rcm/rcm.7.html [rcrc5]: http://thoughtbot.github.io/rcm/rcrc.5.html Support ------- Pull requests welcome; see `CONTRIBUTING.md`. License ------- Copyright 2013 Mike Burns. BSD license. Copyright 2014-2015 thoughtbot. BSD license. ## About thoughtbot ![thoughtbot](http://presskit.thoughtbot.com/images/thoughtbot-logo-for-readmes.svg) RCM is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc. We adore open source software. See [our other projects][community]. We are [available for hire][hire]. [community]: https://thoughtbot.com/community?utm_source=github [hire]: https://thoughtbot.com/hire-us?utm_source=github rcm-1.3.4/arch/000077500000000000000000000000001372226550100132205ustar00rootroot00000000000000rcm-1.3.4/arch/PKGBUILD.in000066400000000000000000000011531372226550100147510ustar00rootroot00000000000000# Maintainer: Pat Brisbin pkgname='@PACKAGE@' pkgver=@PACKAGE_VERSION@ pkgrel=2 pkgdesc="rc file (dotfile) management" arch=('any') url="http://thoughtbot.github.io/@PACKAGE@/" license=('BSD') depends=('') source=("http://thoughtbot.github.io/@PACKAGE@/dist/@DIST_ARCHIVES@") sha256sums=('@DIST_SHA@') build() { cd "$srcdir/$pkgname-$pkgver" ./configure \ --disable-silent-rules \ --prefix=/usr make } package() { cd "$srcdir/$pkgname-$pkgver" make DESTDIR="$pkgdir/" install install -Dm644 LICENSE "$pkgdir/usr/share/licenses/${pkgname}/LICENSE" } # vim:set ts=2 sw=2 et: rcm-1.3.4/arch/git-PKGBUILD.in000066400000000000000000000014331372226550100155330ustar00rootroot00000000000000# Maintainer: Pat Brisbin _gitname='@PACKAGE@' pkgname=$_gitname-git pkgver=v1.2.3.r6.gdb0be68 pkgrel=4 pkgdesc="rc file (dotfile) management" arch=('any') url="http://thoughtbot.github.io/@PACKAGE@/" license=('BSD') conflicts=('@PACKAGE@') makedepends=('git' 'ruby-mustache') source=('git://github.com/thoughtbot/@PACKAGE@') md5sums=('SKIP') pkgver() { cd "$srcdir/$_gitname" git describe --long | sed -r 's/([^-]*-g)/r\1/;s/-/./g' } prepare() { cd "$srcdir/$_gitname" ./autogen.sh } build() { cd "$srcdir/$_gitname" ./configure \ --disable-silent-rules \ --prefix=/usr make } package() { cd "$srcdir/$_gitname" make DESTDIR="$pkgdir/" install install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$_gitname/LICENSE" } # vim:set ts=2 sw=2 et: rcm-1.3.4/autogen.sh000077500000000000000000000001601372226550100143010ustar00rootroot00000000000000#!/bin/sh aclocal && autoconf && automake --add-missing --copy && ./maint/autocontrib man/rcm.7.mustache rcm-1.3.4/bin/000077500000000000000000000000001372226550100130535ustar00rootroot00000000000000rcm-1.3.4/bin/lsrc.in000077500000000000000000000250601372226550100143540ustar00rootroot00000000000000#!@SHELL@ : ${RCM_LIB:=$(dirname "$0")/../share/rcm} . "$RCM_LIB/rcm.sh" pushdir() { DIR_STACK="$DIR_STACK:$PWD/$1" $DEBUG "cd'ing to $1 from $PWD with stack $DIR_STACK" cd -- "$1" } popdir() { current="$(echo "$DIR_STACK" | sed -e 's/.*://g')" prior="$(echo "$DIR_STACK" | sed -e "s|:$current$||" | sed -e 's/.*://g')" DIR_STACK="$(echo "$DIR_STACK" | sed -e 's/:[^:]*$//')" $DEBUG "cd'ing to $prior from $PWD with stack $DIR_STACK" cd -- "$prior" } build_path() { local dest="$1" local file="$2" local dotted=$3 if [ $dotted -eq 1 ]; then echo "$dest/$file" else echo "$dest/.$file" fi } file_join() { local result= for file; do if [ "x$file" != "x." ]; then if [ "x$result" = "x" ]; then result="$file" else result="$result/$file" fi fi done echo "$result" } show_dir() { local dir="$1" local dest_dir="$2" local dotfiles_dir="$3" local dotfiles_subdir="$4" local dotted=$5 local exclude_file_globs="$6" local include_file_globs="$7" local symlink_dirs_file_globs="$8" local mk_dirs_file_globs="$9" local dest_path="$(build_path "$dest_dir" "$dir" $dotted)" $DEBUG "show_dir $1 $2 $3 $4 $5 $6 $7 $8 $9" $VERBOSE "recurring on $dest_path" pushdir "$dir" for f in *; do $DEBUG "handling the file $f" next_dir="$(file_join "$dotfiles_subdir" "$dir")" handle_file "$f" "$dest_path" "$dotfiles_dir" "$next_dir" 1 "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" "$mk_dirs_file_globs" done popdir } sigil_for() { local file="$1" local symlink_dirs_file_globs="$2" local copy_always=0 local symlink_dirs=0 for copy_file in $COPY_ALWAYS; do $DEBUG "copy_file: $copy_file" $DEBUG "file: $file" case "$file" in $copy_file) copy_always=1 break ;; esac done if [ -n "$symlink_dirs_file_globs" ]; then symlink_dirs=1 fi if [ $copy_always -eq 1 ]; then echo 'X' elif [ $symlink_dirs -eq 1 ]; then echo '$' else echo '@' fi } show_file() { local file="$1" local dest_dir="$2" local dotfiles_dir="$3" local dotfiles_subdir="$4" local dotted=$5 local symlink_dirs_file_globs="$6" local dest_file="$(build_path "$dest_dir" "$file" $dotted)" local src_file="$(file_join "$dotfiles_subdir" "$file")" local abs_src_file="$(file_join "$dotfiles_dir" "$src_file")" local output="$dest_file:$abs_src_file" if [ $SHOW_SIGILS -eq 1 ]; then sigil="$(sigil_for "$src_file" "$symlink_dirs_file_globs")" output="$output:$sigil" fi if echo "$DEST_STACK:" | grep -v ":$dest_file:" >/dev/null; then DEST_STACK="$DEST_STACK:$dest_file" $PRINT "$output" else $VERBOSE "skipping hidden file $output" fi } handle_file() { local file="$1" local dest_dir="$2" local dotfiles_dir="$3" local dotfiles_subdir="$4" local dotted=$5 local exclude_file_globs="$6" local include_file_globs="$7" local symlink_dirs_file_globs="$8" local mk_dirs_file_globs="$9" $DEBUG "handle_file $1 $2 $3 $4 $5 $6 $7 $8" "$9" if [ ! -e "$file" ]; then $VERBOSE "skipping non-existent file $file" elif is_excluded "$dotfiles_subdir/$file" "$exclude_file_globs" "$include_file_globs"; then $VERBOSE "skipping excluded file $file" elif [ -d "$file" ] && is_excluded "$dotfiles_subdir/$file" "$symlink_dirs_file_globs" "$mk_dirs_file_globs"; then show_file "$file" "$dest_dir" "$dotfiles_dir" "$dotfiles_subdir" $dotted "$symlink_dirs_file_globs" elif [ -d "$file" ]; then show_dir "$file" "$dest_dir" "$dotfiles_dir" "$dotfiles_subdir" $dotted "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" "$mk_dirs_file_globs" else show_file "$file" "$dest_dir" "$dotfiles_dir" "$dotfiles_subdir" $dotted fi } is_metafile() { host_portion="$(echo "$1" | sed -e 's/host-.*/host-/')" tag_portion="$(echo "$1" | sed -e 's/tag-.*/tag-/')" [ "x$host_portion" = 'xhost-' -o "x$tag_portion" = 'xtag-' -o "x$1" = "xhooks" ] } dotfiles_dir_excludes() { local dotfiles_dir="$1" local excludes="$2" $DEBUG "dotfiles_dir_excludes $dotfiles_dir" $DEBUG " with excludes: $excludes" for exclude in "$excludes"; do if echo "$exclude" | grep ':' >/dev/null; then dotfiles_dir_pat="$(echo "$exclude" | sed 's/:.*//')" file_glob="$(echo "$exclude" | sed 's/.*://')" if [ "x$dotfiles_dir_pat" != "x*" ] && is_relative "$dotfiles_dir_pat"; then dotfiles_dir_pat="$PWD/$dotfiles_dir_pat" fi if [ "x$dotfiles_dir_pat" = "x*" -o "x$dotfiles_dir_pat" = "x$dotfiles_dir" ]; then echo "$file_glob" fi else echo "$exclude" fi done } is_excluded() { local file="$1" local exclude_file_globs="$2" local include_file_globs="$3" local base_file="$(basename "$file")" $DEBUG "is_excluded $file $exclude_file_globs $include_file_globs" for exclude_file_glob in $exclude_file_globs; do $DEBUG "file: $file" $DEBUG "exclude_file_glob: $exclude_file_glob" is_single_excluded "$file" "$exclude_file_glob" "$include_file_globs" ret=$? if [ $ret -eq 0 -o $ret -eq 1 ]; then return $ret fi is_single_excluded "$base_file" "$exclude_file_glob" "$include_file_globs" ret=$? if [ $ret -eq 0 -o $ret -eq 1 ]; then return $ret fi done return 1 } is_single_excluded() { local file="$1" local exclude_file_glob="$2" local include_file_globs="$3" case "$file" in $exclude_file_glob) for include_file_glob in $include_file_globs; do case "$file" in $include_file_glob) return 1;; esac done return 0 ;; esac return 2 } show_help() { local exit_code=${1:-0} $PRINT "Usage: lsrc [-FhqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT]" $PRINT "see lsrc(1) and rcm(7) for more details" exit $exit_code } handle_command_line() { local arg_tags= local verbosity=0 local version=0 local show_sigils=0 local dotfiles_dirs= local excludes= local includes= local symlink_dirs= local never_symlink_dirs= local hostname= local undotted= local never_undotted= while getopts :FVqvhI:x:B:S:s:U:u:t:d: opt; do case "$opt" in F) show_sigils=1;; h) show_help ;; I) includes="$(append_variable "$includes" "$OPTARG")" ;; t) arg_tags="$(append_variable "$arg_tags" "$OPTARG")" ;; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; d) dotfiles_dirs="$(append_variable "$dotfiles_dirs" "$OPTARG")" ;; V) version=1;; x) excludes="$(append_variable "$excludes" "$OPTARG")" ;; S) symlink_dirs="$(append_variable "$symlink_dirs" "$OPTARG")" ;; s) never_symlink_dirs="$(append_variable "$never_symlink_dirs" "$OPTARG")" ;; U) undotted="$(append_variable "$undotted" "$OPTARG")" ;; u) never_undotted="$(append_variable "$never_undotted" "$OPTARG")" ;; B) hostname="$OPTARG";; ?) show_help 64 ;; esac done shift $(($OPTIND-1)) handle_common_flags lsrc $version $verbosity HOSTNAME="$(determine_hostname "$hostname")" SHOW_SIGILS=$show_sigils TAGS="${arg_tags:-$TAGS}" DOTFILES_DIRS="${dotfiles_dirs:-$DOTFILES_DIRS}" EXCLUDES="${excludes:-$EXCLUDES}" INCLUDES="${includes:-$INCLUDES}" SYMLINK_DIRS="${symlink_dirs:-$SYMLINK_DIRS}" MK_DIRS="${never_symlink_dirs:-$MK_DIRS}" UNDOTTED="${undotted:-$UNDOTTED}" NEVER_UNDOTTED="${never_undotted:-$NEVER_UNDOTTED}" FILES="$@" $DEBUG "TAGS: $TAGS" $DEBUG "DOTFILES_DIRS: $DOTFILES_DIRS" } DEST_STACK= handle_command_line "$@" : ${DOTFILES_DIRS:=$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR} $DEBUG "DOTFILES_DIRS: $DOTFILES_DIRS" : ${COPY_ALWAYS:=""} $DEBUG "COPY_ALWAYS: $COPY_ALWAYS" : ${SYMLINK_DIRS:=""} $DEBUG "SYMLINK_DIRS: $SYMLINK_DIRS" : ${MK_DIRS:=""} $DEBUG "MK_DIRS: $MK_DIRS" : ${UNDOTTED:=""} $DEBUG "UNDOTTED: $UNDOTTED" : ${NEVER_UNDOTTED:=""} $DEBUG "NEVER_UNDOTTED: $NEVER_UNDOTTED" relative_root_dir="$PWD" for DOTFILES_DIR in $DOTFILES_DIRS; do cd -- "$relative_root_dir" DOTFILES_DIR="$(eval echo "$DOTFILES_DIR")" if is_relative $DOTFILES_DIR; then DOTFILES_DIR="$PWD/$DOTFILES_DIR" fi if [ ! -d "$DOTFILES_DIR" ]; then $VERBOSE "skipping non-existent directory: $DOTFILES_DIR" continue fi exclude_file_globs="$(dotfiles_dir_excludes "$DOTFILES_DIR" "$EXCLUDES")" $DEBUG "exclude_file_globs: $exclude_file_globs" include_file_globs="$(dotfiles_dir_excludes "$DOTFILES_DIR" "$INCLUDES")" symlink_dirs_file_globs="$(dotfiles_dir_excludes "$DOTFILES_DIR" "$SYMLINK_DIRS")" $DEBUG "symlink_dirs_file_globs: $symlink_dirs_file_globs" mk_dirs_file_globs="$(dotfiles_dir_excludes "$DOTFILES_DIR" "$MK_DIRS")" $DEBUG "mk_dirs_file_globs: $mk_dirs_file_globs" undotted_file_globs="$(dotfiles_dir_excludes "$DOTFILES_DIR" "$UNDOTTED")" $DEBUG "undotted_file_globs: $undotted_file_globs" never_undotted_file_globs="$(dotfiles_dir_excludes "$DOTFILES_DIR" "$NEVER_UNDOTTED")" $DEBUG "never_undotted_file_globs: $never_undotted_file_globs" cd -- "$DOTFILES_DIR" DIR_STACK=":$DOTFILES_DIR" host_files="$DOTFILES_DIR/host-$HOSTNAME" if [ -d "$host_files" ]; then pushdir "$(basename "$host_files")" for escaped_file in ${FILES:-*}; do file="$(decode "$escaped_file")" dotted=0 if is_excluded "$file" "$undotted_file_globs" "$never_undotted_file_globs"; then dotted=1 fi handle_file "$file" "$DEST_DIR" "$host_files" . "$dotted" "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" "$mk_dirs_file_globs" done popdir fi cd -- "$DOTFILES_DIR" for tag in $TAGS; do if [ -d "tag-$tag" ]; then pushdir "$(basename "tag-$tag")" for escaped_file in ${FILES:-*}; do file="$(decode "$escaped_file")" $DEBUG "TAG: $tag, exclude_file_globs: $exclude_file_globs" dotted=0 if is_excluded "$file" "$undotted_file_globs" "$never_undotted_file_globs"; then dotted=1 fi handle_file "$file" "$DEST_DIR" "$DOTFILES_DIR/tag-$tag" . "$dotted" "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" "$mk_dirs_file_globs" done popdir fi done cd -- "$DOTFILES_DIR" for escaped_file in ${FILES:-*}; do file="$(decode "$escaped_file")" dotted=0 if is_metafile "$file"; then continue fi if is_excluded "$file" "$undotted_file_globs" "$never_undotted_file_globs"; then dotted=1 fi handle_file "$file" "$DEST_DIR" "$DOTFILES_DIR" . "$dotted" "$exclude_file_globs" "$include_file_globs" "$symlink_dirs_file_globs" "$mk_dirs_file_globs" done done rcm-1.3.4/bin/mkrc.in000077500000000000000000000062521372226550100143470ustar00rootroot00000000000000#!@SHELL@ : ${RCM_LIB:=$(dirname "$0")/../share/rcm} . "$RCM_LIB/rcm.sh" destination() { local dotfiles_dir="$1" local dotless="$2" local in_host="$3" local tag="$4" $DEBUG "destination $dotfiles_dir $dotless $in_host $tag" if [ "x$tag" != "x" ]; then echo "$dotfiles_dir/tag-$tag" elif [ $in_host = 1 ]; then echo "$dotfiles_dir/host-$HOSTNAME" else echo "$dotfiles_dir" fi } exit_if_dangerous() { local file="$1" if [ -L "$file" ]; then $ERROR 1 "'$file' is a symlink. Cannot process file." elif is_nested "$file"; then # Remove DEST_DIR in case $HOME is under a symlink saved_ifs="$IFS" IFS=/ set -- $(dirname "$file" | sed "s|$DEST_DIR/||") IFS="$saved_ifs" built_dir="$DEST_DIR" for dir in $@; do built_dir="$built_dir/$dir" if [ -L "$built_dir" ]; then $ERROR 1 "'$file' path contains a symlink ($dir). Cannot process file." fi done fi } show_help() { local exit_code=${1:-0} $PRINT "Usage: mkrc [-ChSsUuVvqo] [-t TAG] [-d DIR] [-B HOSTNAME] FILES ..." $PRINT "see mkrc(1) and rcm(7) for more details" exit $exit_code } if [ $# -eq 0 ]; then show_help 64 fi for DOTFILES_DIR in $DOTFILES_DIRS $DEFAULT_DOTFILES_DIR; do break done tag= hostname= verbosity=0 in_host=0 version=0 always_copy=0 force_symlink=50 undotted=50 install_args= while getopts :ChSsUuVvqot:d:B: opt; do case "$opt" in C) always_copy=1 ;; h) show_help ;; t) tag="$OPTARG" ;; v) verbosity=$(($verbosity + 1)) ;; q) verbosity=$(($verbosity - 1)) ;; o) in_host=1 ;; d) DOTFILES_DIR="$OPTARG" ;; V) version=1 ;; S) force_symlink=1 ;; s) force_symlink=0 ;; U) undotted=1 ;; u) undotted=0 ;; B) in_host=1 hostname="$OPTARG" install_args=$(append_variable "$install_args" "-B $hostname") ;; ?) show_help 64 ;; esac done shift $(($OPTIND-1)) handle_common_flags mkrc $version $verbosity HOSTNAME="$(determine_hostname "$hostname")" if [ $in_host -eq 1 -a "x$tag" != "x" ]; then $ERROR 1 "Cannot specify both -o and -t" fi if [ $always_copy -eq 1 ]; then INSTALL="$INSTALL -C" fi files="" for i; do exit_if_dangerous "$i" files="$(printf "$files\n$i")" done if [ $force_symlink -eq 1 ]; then for file in $files; do dedotted="$(de_dot "$file")" INSTALL="$INSTALL -S $dedotted" done elif [ $force_symlink -eq 0 ]; then for file in $files; do dedotted="$(de_dot "$file")" INSTALL="$INSTALL -s $dedotted" done fi if [ $undotted -eq 1 ]; then for file in $files; do dedotted="$(de_dot "$file")" INSTALL="$INSTALL -U $dedotted" done elif [ $undotted -eq 0 ]; then for file in $files; do dedotted="$(de_dot "$file")" INSTALL="$INSTALL -u $dedotted" done fi saved_IFS="$IFS" IFS=' ' for file in $files; do IFS="$saved_IFS" case "$file" in /*) : ;; *) [ -e "$PWD/$file" ] && file="$PWD/$file" ;; esac dotless="$(de_dot "$file")" dest="$(destination "$DOTFILES_DIR" "$dotless" $in_host "$tag")" mkdir -p "$dest/$(dirname "$dotless")" $VERBOSE "Moving..." mv_v "$file" "$dest/$dotless" $VERBOSE "Linking..." $INSTALL -d "$DOTFILES_DIR" -t "${tag:--}" $install_args "$dotless" done rcm-1.3.4/bin/rcdn.in000077500000000000000000000063161372226550100143420ustar00rootroot00000000000000#!@SHELL@ : ${RCM_LIB:=$(dirname "$0")/../share/rcm} . "$RCM_LIB/rcm.sh" remove_link() { local dest="$1" local original="$2" local sigil="$3" $DEBUG "remove_link $1 $2 $3" if [ "x$dest" = "x/" -o "x$dest" = "x$DEST_DIR" ]; then $VERBOSE "not a symlink, skipping: $original" elif [ -L "$dest" -o "x$sigil" = "xX" ]; then rm_v -rf "$dest" rmdir -p "$(dirname "$original")" 2>/dev/null else remove_link "$(dirname "$dest")" "$original" fi } show_help() { local exit_code=${1:-0} $PRINT "Usage: rcdn [-hqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT]" $PRINT "see rcdn(1) and rcm(7) for more details" exit $exit_code } handle_command_line() { local arg_tags= local verbosity=0 local version=0 local run_hooks=1 local dotfiles_dirs= local files= local excludes= local includes= local symlink_dirs= local never_symlink_dirs= local undotted= local never_undotted= local hostname= while getopts :VqvhIKk:x:S:s:U:u:t:d:B: opt; do case "$opt" in h) show_help ;; B) hostname="$OPTARG" ;; I) includes="$(append_variable "$includes" "$OPTARG")" ;; k) run_hooks=1 ;; K) run_hooks=0 ;; t) arg_tags="$(append_variable "$arg_tags" "$OPTARG")" ;; S) symlink_dirs="$(append_variable "$symlink_dirs" "$OPTARG")" ;; s) never_symlink_dirs="$(append_variable "$never_symlink_dirs" "$OPTARG")" ;; U) undotted="$(append_variable "$undotted" "$OPTARG")" ;; u) never_undotted="$(append_variable "$never_undotted" "$OPTARG")";; v) verbosity=$(($verbosity + 1));; q) verbosity=$(($verbosity - 1));; d) dotfiles_dirs="$(append_variable "$dotfiles_dirs" "$OPTARG")" ;; V) version=1 ;; x) excludes="$(append_variable "$excludes" "$OPTARG")" ;; ?) show_help 64 ;; esac done shift $(($OPTIND-1)) handle_common_flags rcup $version $verbosity hostname="$(determine_hostname "$hostname")" tags="${arg_tags:-$TAGS}" dotfiles_dirs="${dotfiles_dirs:-$DOTFILES_DIRS}" files="$@" RUN_HOOKS="$run_hooks" for tag in "$tags"; do LS_ARGS="$LS_ARGS -t \"$tag\"" done for dotfiles_dir in "$dotfiles_dirs"; do LS_ARGS="$LS_ARGS -d \"$dotfiles_dir\"" done for exclude in "$excludes"; do LS_ARGS="$LS_ARGS -x \"$exclude\"" done for include in "$includes"; do LS_ARGS="$LS_ARGS -I \"$include\"" done for symlink_dir in "$symlink_dirs"; do LS_ARGS="$LS_ARGS -S \"$symlink_dir\"" done for never_symlink_dir in "$symlink_dirs"; do LS_ARGS="$LS_ARGS -s \"$never_symlink_dir\"" done for undot in "$undotted"; do LS_ARGS="$LS_ARGS -U \"$undot\"" done for never_undot in "$never_undotted"; do LS_ARGS="$LS_ARGS -u \"$never_undot\"" done LS_ARGS="$LS_ARGS -B \"$hostname\" $files" $DEBUG "LS_ARGS: $LS_ARGS" } LS_ARGS=-F handle_command_line "$@" : ${DOTFILES_DIRS:=$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR} run_hooks pre down dests_and_srcs="$(eval "lsrc $LS_ARGS")" saved_ifs="$IFS" IFS=' ' for dest_and_src in $dests_and_srcs; do IFS=: set -- $dest_and_src IFS="$saved_ifs" dest="$1" sigil="$3" remove_link "$dest" "$dest" "$sigil" done IFS="$saved_ifs" run_hooks post down rcm-1.3.4/bin/rcup.in000077500000000000000000000145671372226550100143740ustar00rootroot00000000000000#!@SHELL@ : ${RCM_LIB:=$(dirname "$0")/../share/rcm} . "$RCM_LIB/rcm.sh" print_ln_v() { $PRINT "handle_file_ln \"$1\" \"$2\"" } print_cp_v() { $PRINT "handle_file_cp \"$1\" \"$2\"" } print_rm_v() { : } link_or_copy() { $DEBUG "link_or_copy $1" local sigil="$1" if [ "x$sigil" = "xX" ]; then echo "$CP" else echo "$LN" fi } print_generated_preface() { cat < '\$2'" \$MKDIR -p "\$(\$DIRNAME "\$2")" \$CP -R "\$1" "\$2" } handle_file_ln() { if [ -e "\$2" ]; then printf "%s " "overwrite \$2? [yN]" read overwrite case "\$overwrite" in y) \$RM -rf "\$2" ;; *) echo "skipping \$2" return ;; esac fi verbose "'\$1' -> '\$2'" \$MKDIR -p "\$(\$DIRNAME "\$2")" \$LN -sf "\$1" "\$2" } PREFACE } link_file() { local src="$1" local dest="$2" local sigil="$3" if [ -h "$dest" ]; then $RM -f "$dest" fi action="$(link_or_copy "$sigil")" $DEBUG "$action $src $dest" $action "$src" "$dest" } replace_file() { local src="$1" local dest="$2" local sigil="$3" $DEBUG replace_file "$1" "$2" $3 $RM -rf "$dest" link_file "$src" "$dest" "$sigil" } is_identical() { diff -c "$1" "$2" > /dev/null 2>&1 } is_linked() { local src="$1" local dest="$2" if [ -h "$dest" ]; then local link_dest=$(readlink $dest) [ "$link_dest" = "$src" ] else return 1 fi } handle_dir() { local dest="$1" $DEBUG "handle_dir $dest" $MKDIR -p "$(dirname "$dest")" } handle_file() { local generate="$1" local src="$2" local dest="$3" local sigil="$4" $DEBUG "handle_file $1 $2 $3 $4" if [ "$generate" -ne 1 -a -e "$dest" ]; then if is_identical "$src" "$dest"; then if [ "x$sigil" != "xX" ] && ! is_linked "$src" "$dest"; then $VERBOSE "replacing identical but unlinked $dest" replace_file "$src" "$dest" "$sigil" else $VERBOSE "identical $dest" fi elif [ $REPLACE_ALL -eq 1 ]; then replace_file "$src" "$dest" "$sigil" else $PROMPT "overwrite ${dest}? [ynaq]" read overwrite case "$overwrite" in a) REPLACE_ALL=1 replace_file "$src" "$dest" "$sigil" ;; y) replace_file "$src" "$dest" "$sigil" ;; q) exit 1 ;; *) $VERBOSE "skipping $dest" ;; esac fi else link_file "$src" "$dest" "$sigil" fi } show_help() { local exit_code=${1:-0} $PRINT "Usage: rcup [-CfhiKkqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT]" $PRINT "see rcup(1) and rcm(7) for more details" exit $exit_code } handle_command_line() { local arg_tags= local verbosity=0 local version=0 local run_hooks=1 local dotfiles_dirs= local files= local excludes= local includes= local always_copy=0 local symlink_dirs= local never_symlink_dirs= local hostname= local generate=0 local args="$*" local undotted= local never_undotted= REPLACE_ALL=0 GENERATE= while getopts :CVqvfghikKI:x:S:s:U:u:t:d:B: opt; do case "$opt" in B) hostname="$OPTARG" ;; C) always_copy=1 ;; d) dotfiles_dirs="$(append_variable "$dotfiles_dirs" "$OPTARG")" ;; f) REPLACE_ALL=1 ;; g) generate=1 ;; h) show_help ;; i) REPLACE_ALL=0 ;; I) includes="$(append_variable "$includes" "$OPTARG")" ;; k) run_hooks=1 ;; K) run_hooks=0 ;; q) verbosity=$(($verbosity - 1)) ;; t) arg_tags="$(append_variable "$arg_tags" "$OPTARG")" ;; S) symlink_dirs="$(append_variable "$symlink_dirs" "$OPTARG")" ;; s) never_symlink_dirs="$(append_variable "$never_symlink_dirs" "$OPTARG")";; U) undotted="$(append_variable "$undotted" "$OPTARG")" ;; u) never_undotted="$(append_variable "$never_undotted" "$OPTARG")" ;; v) verbosity=$(($verbosity + 1)) ;; V) version=1 ;; x) excludes="$(append_variable "$excludes" "$OPTARG")" ;; ?) show_help 64 ;; esac done shift $(($OPTIND-1)) LN="ln_v" CP="cp_v" RM="rm_v" if [ $always_copy -eq 1 ]; then LN="$CP" fi if [ "$generate" -eq 1 ]; then LN="print_ln_v" CP="print_cp_v" RM="print_rm_v" print_generated_preface $args fi GENERATE="$generate" handle_common_flags rcup $version $verbosity hostname="$(determine_hostname "$hostname")" tags="${arg_tags:-$TAGS}" DOTFILES_DIRS="${dotfiles_dirs:-$DOTFILES_DIRS}" RUN_HOOKS=$run_hooks files= for file; do files="$files $(encode "$file")" done for tag in $tags; do LS_ARGS="$LS_ARGS -t \"$tag\"" done for dotfiles_dir in "$DOTFILES_DIRS"; do LS_ARGS="$LS_ARGS -d \"$dotfiles_dir\"" done for exclude in "$excludes"; do LS_ARGS="$LS_ARGS -x \"$exclude\"" done for include in "$includes"; do LS_ARGS="$LS_ARGS -I \"$include\"" done for symlink_dir in "$symlink_dirs"; do LS_ARGS="$LS_ARGS -S \"$symlink_dir\"" done for never_symlink_dir in "$never_symlink_dirs"; do LS_ARGS="$LS_ARGS -s \"$never_symlink_dir\"" done for undot in "$undotted"; do LS_ARGS="$LS_ARGS -U \"$undot\"" done for never_undot in "$never_undotted"; do LS_ARGS="$LS_ARGS -u \"$never_undot\"" done LS_ARGS="$LS_ARGS -B \"$hostname\" $files" $DEBUG "LS_ARGS: $LS_ARGS" } LS_ARGS=-F handle_command_line "$@" : ${DOTFILES_DIRS:=$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR} run_hooks pre up dests_and_srcs="$(eval "lsrc $LS_ARGS")" saved_ifs="$IFS" IFS=' ' for dest_and_src in $dests_and_srcs; do IFS=: set -- $dest_and_src IFS="$saved_ifs" dest="$1" src="$2" sigil="$3" if is_nested "$dest"; then handle_dir "$dest" fi handle_file "$GENERATE" "$src" "$dest" "$sigil" done IFS="$saved_ifs" run_hooks post up rcm-1.3.4/configure.ac000066400000000000000000000006211372226550100145700ustar00rootroot00000000000000AC_PREREQ([2.69]) AC_INIT(rcm, 1.3.4, mburns@thoughtbot.com) AM_INIT_AUTOMAKE([subdir-objects]) # /bin/sh on Solaris is not POSIX, so try to find another one. case "$host_os" in solaris*) AC_PATH_PROGS(POSIX_SHELL, [ksh93 ksh sh]) SHELL="$POSIX_SHELL" ;; esac AC_SUBST([SHELL]) AC_OUTPUT(Makefile share/rcm.sh arch/git-PKGBUILD NEWS.md bin/lsrc bin/mkrc bin/rcdn bin/rcup maint/release) rcm-1.3.4/debian/000077500000000000000000000000001372226550100135255ustar00rootroot00000000000000rcm-1.3.4/debian/changelog000066400000000000000000000017621372226550100154050ustar00rootroot00000000000000rcm (1.2.3-1) unstable; urgency=medium * New upstream release -- Mike Burns Fri, 09 May 2014 14:30:57 +0200 rcm (1.2.2-2) unstable; urgency=medium * New upstream release -- Mike Burns Fri, 28 Mar 2014 16:25:24 +0100 rcm (1.2.1-2) unstable; urgency=medium * Re-visit the Debian packaging. * New upstream release -- Mike Burns Fri, 07 Mar 2014 16:27:57 +0100 rcm (1.2.0-1) unstable; urgency=medium * New upstream release -- Mike Burns Mon, 03 Feb 2014 16:58:33 +0200 rcm (1.1.0-1) unstable; urgency=medium * New upstream release. -- Mike Burns Mon, 05 Aug 2013 16:43:33 +0200 rcm (1.0.0-1) unstable; urgency=medium * New upstream release. -- Mike Burns Tue, 01 Aug 2013 16:43:33 +0200 rcm (0.0.2-1) unstable; urgency=medium * New upstream release. -- Mike Burns Tue, 23 Jul 2013 16:43:33 +0200 rcm-1.3.4/debian/compat000066400000000000000000000000021372226550100147230ustar00rootroot000000000000009 rcm-1.3.4/debian/control000066400000000000000000000013201372226550100151240ustar00rootroot00000000000000Source: rcm Section: utils Priority: optional Maintainer: Mike Burns Build-Depends: debhelper (>= 9) Standards-Version: 3.9.4 Homepage: http://thoughtbot.github.io/rcm Vcs-Git: git://github.com/thoughtbot/rcm.git Vcs-Browser: http://github.com/thoughtbot/rcm Package: rcm Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends} Description: management suite for dotfiles You have dotfiles. Maybe you have them in a repo that you share; maybe you have them in a privately-backed up directory; or maybe you just have them scattered about your homedir. Regardless, this package provides a suite of programs that will help manage an existing dotfiles collection and also start a new one. rcm-1.3.4/debian/copyright000066400000000000000000000032421372226550100154610ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: rcm Source: git@github.com:thoughtbot/rcm.git Files: * Copyright: 2013 Mike Burns License: BSD-3 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Mike Burns nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rcm-1.3.4/debian/rules000077500000000000000000000013221372226550100146030ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # # Modified to make a template file for a multi-binary package with separated # build-arch and build-indep targets by Bill Allombert 2001 # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 # This has to be exported to make some magic below work. export DH_OPTIONS %: dh $@ override_dh_installchangelogs: dh_installchangelogs NEWS.md rcm-1.3.4/debian/source/000077500000000000000000000000001372226550100150255ustar00rootroot00000000000000rcm-1.3.4/debian/source/format000066400000000000000000000000141372226550100162330ustar00rootroot000000000000003.0 (quilt) rcm-1.3.4/homebrew/000077500000000000000000000000001372226550100141135ustar00rootroot00000000000000rcm-1.3.4/homebrew/rcm.rb.in000066400000000000000000000006401372226550100156260ustar00rootroot00000000000000class Rcm < Formula desc "management suite for dotfiles" homepage "https://thoughtbot.github.io/rcm" url "https://thoughtbot.github.io/@PACKAGE@/dist/@DIST_ARCHIVES@" sha256 "@DIST_SHA@" def install system "./configure", "--disable-debug", "--disable-dependency-tracking", "--prefix=#{prefix}" system "make", "install" end test do system "#{bin}/lsrc" end end rcm-1.3.4/maint/000077500000000000000000000000001372226550100134135ustar00rootroot00000000000000rcm-1.3.4/maint/autocontrib000077500000000000000000000016471372226550100157020ustar00rootroot00000000000000#!/usr/bin/env ruby begin require 'mustache' rescue LoadError $stderr.puts <<-HERE Error: This project requires the mustache Ruby gem in order to finish the maintainer setup. Please install it and re-run autocontrib. The mustache gem can be installed using gem: gem install mustache HERE exit 1 end class ContributorView < Mustache def contributors @_contributors ||= raw_contributors end private def raw_contributors shortlog.map do |contributor_line| if contributor_line =~ /\d+\s+(.+)\s+<(.+)>/ { :name => $1, :email => $2 } end end.compact end def shortlog `git shortlog -es`.split("\n") end end contributor_view = ContributorView.new ARGV.each do |template_filename| output_filename = template_filename.sub(/\.mustache$/, '') contributor_view.template_file = template_filename output = contributor_view.render File.write(output_filename, output) end rcm-1.3.4/maint/release.in000077500000000000000000000075511372226550100153760ustar00rootroot00000000000000#!/bin/sh ORIGIN_URL=$(git config --get remote.origin.url) CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) PACKAGE='@PACKAGE@' PACKAGE_VERSION='@PACKAGE_VERSION@' abs_srcdir='@abs_srcdir@' srcdir='@srcdir@' abs_top_builddir='@abs_top_builddir@' dist_man_MANS='lsrc.1 mkrc.1 rcdn.1 rcup.1 rcrc.5 rcm.7' edit_package() { sed \ -e "s|@PACKAGE[@]|$PACKAGE|g" \ -e "s|@PACKAGE_VERSION[@]|$PACKAGE_VERSION|g" \ -e "s|@DIST_ARCHIVES[@]|$DIST_ARCHIVES|g" \ -e "s|@DIST_SHA[@]|$DIST_SHA|g" \ "$1" } # Tarball release_build_tarball() { ([ -d gh-pages ] || git clone --branch gh-pages . gh-pages) && \ ([ -d gh-pages/dist ] || mkdir gh-pages/dist) && \ cp $DIST_ARCHIVES gh-pages/dist && \ cd gh-pages && \ git add dist/$DIST_ARCHIVES && \ git commit -m "Release version $PACKAGE_VERSION tarball" } release_push_tarball() { cd gh-pages && \ git push } release_clean_tarball() { rm -rf gh-pages rm -rf $DIST_ARCHIVES } # Arch release_build_arch() { ([ -d gh-pages ] || git clone --branch gh-pages . gh-pages) && \ ([ -d gh-pages/arch ] || mkdir gh-pages/arch) && \ generate_dist_sha && \ edit_package arch/PKGBUILD.in > gh-pages/arch/PKGBUILD &&\ cd gh-pages &&\ git add arch/PKGBUILD &&\ git commit -m "Release version $PACKAGE_VERSION Arch package" } release_push_arch() { cd gh-pages && \ git push } release_clean_arch() { rm -rf gh-pages rm -rf $DIST_ARCHIVES } # Deb release_build_deb() { mkdir deb-build && \ cp ${DIST_ARCHIVES} deb-build/${PACKAGE}_${PACKAGE_VERSION}.orig.tar.gz && \ tar -C deb-build -xf deb-build/${PACKAGE}_${PACKAGE_VERSION}.orig.tar.gz && \ cp -R debian deb-build/${PACKAGE}-${PACKAGE_VERSION} && \ cd deb-build/${PACKAGE}-${PACKAGE_VERSION} && \ dch -d "New upstream release" && dch -r "" && \ debuild --prepend-path=/usr/local/bin -F && \ cd ${abs_top_builddir} && \ ([ -d gh-pages ] || git clone --branch gh-pages ${ORIGIN_URL} gh-pages) && \ mkdir gh-pages/debs && \ mkdir gh-pages/deb-src && \ cp deb-build/${PACKAGE}_${PACKAGE_VERSION}*.deb gh-pages/debs && \ cp deb-build/${PACKAGE}_${PACKAGE_VERSION}*.dsc gh-pages/deb-src && \ cp deb-build/${PACKAGE}_${PACKAGE_VERSION}*.orig.tar.?z gh-pages/deb-src && \ cp deb-build/${PACKAGE}_${PACKAGE_VERSION}*.debian.tar.?z gh-pages/deb-src && \ cd gh-pages && \ git add debs/${PACKAGE}_${PACKAGE_VERSION}*deb && \ git add deb-src/${PACKAGE}_${PACKAGE_VERSION}*dsc && \ git add deb-src/${PACKAGE}_${PACKAGE_VERSION}*orig.tar.?z && \ git add deb-src/${PACKAGE}_${PACKAGE_VERSION}*debian.tar.?z && \ git commit -m "Release version ${PACKAGE_VERSION} for Debian" -- debs/${PACKAGE}_${PACKAGE_VERSION}*deb } release_push_deb() { cd gh-pages && \ git push } release_clean_deb() { rm -rf gh-pages rm -rf deb-build rm -rf $DIST_ARCHIVES } # Tag release_build_tag() { git tag -s v$PACKAGE_VERSION -m "Release $PACKAGE_VERSION" } release_push_tag() { git push origin --tags } release_clean_tag() { : } generate_dist_sha() { export DIST_SHA=$(openssl sha256 $srcdir/$DIST_ARCHIVES | cut -d' ' -f2) } # manpages as HTML release_build_man_html() { ([ -d gh-pages ] || git clone --branch gh-pages . gh-pages) && \ for i in $dist_man_MANS; do \ mandoc -Thtml -Oman=%N.%S.html man/$i > $abs_top_builddir/gh-pages/$i.html ; \ done && \ cd $abs_top_builddir/gh-pages && \ cp rcm.7.html index.html && \ git add -A && \ git commit -m "HTML documentation for $PACKAGE_VERSION" } release_push_man_html() { cd $abs_top_builddir/gh-pages && \ git push -f $ORIGIN_URL gh-pages } release_clean_man_html() { rm -rf $abs_top_builddir/gh-pages } # Main: if [ $# -lt 3 ]; then echo "Usage: release (build|push|clean) (tarball|arch|deb|tag|man_html) DIST_ARCHIVES" >&2 exit 64 fi verb="$1" noun="$2" DIST_ARCHIVES="$3" cmd="release_${verb}_${noun}" ${cmd} rcm-1.3.4/man/000077500000000000000000000000001372226550100130565ustar00rootroot00000000000000rcm-1.3.4/man/lsrc.1000066400000000000000000000112011372226550100140760ustar00rootroot00000000000000.Dd December 23, 2016 .Dt LSRC 1 .Os .Sh NAME .Nm lsrc .Nd show dotfiles files managed by rcm .Sh SYNOPSIS .Nm lsrc .Op Fl FhqVv .Op Fl B Ar hostname .Op Fl d Ar dir .Op Fl I Ar excl_pat .Op Fl S Ar excl_pat .Op Fl s Ar excl_pat .Op Fl t Ar tag .Op Fl U Ar excl_pat .Op Fl u Ar excl_pat .Op Fl x Ar excl_pat .Op files ... .Sh DESCRIPTION This program lists all configuration files, both the sources in the dotfiles directories and the destinations in your home directory. . See .Xr rcup 1 , the .Sx DIRECTORY LAYOUT section, for details on the directory layout. . It supports these options: . .Bl -tag -width "-I excl_pat" .It Fl B Ar HOSTNAME treat .Pa host-HOSTNAME as the host-specific directory instead of computing it based on the computer's hostname .It Fl d Ar DIR list dotfiles from the DIR. This can be specified multiple times. . .It Fl F show symbols next to each file indicating status information. Supported symbols are .Li @ which indicates that the file is a symlink, .Li $ which indicates it's a symlinked directory, and .Li X to indicate that the file is a copy. More details on copied files and symlinked directories can be found in .Xr rcrc 5 under the documentation on .Va COPY_ALWAYS and .Va SYMLINK_DIRS , respectively. . .It Fl h show usage instructions. . .It Fl I Ar excl_pat include the files that match the given pattern. This is applied after any .Fl x options. It uses the same pattern language as .Fl x ; more details are in the .Sx EXCLUDE PATTERN section. Note that you may have to quote the exclude pattern so the shell does not evaluate the glob. . .It Fl S Ar excl_pat symlink the directories that match the given pattern. See .Sx EXCLUDE PATTERN for more details. This option can be repeated. You may need to quote the pattern to prevent the shell from swallowing the glob. . .It Fl s Ar excl_pat if a directory matches the given pattern, recur inside of it instead of symlinking. See .Sx EXCLUDE PATTERN for more details. This is the opposite of the .Fl S option, and can be used to undo it or the .Va SYMLINK_DIRS setting in your .Xr rcrc 5 configuration. It can be repeated, and the pattern may need to be quoted to protect it from your shell. . .It Fl t Ar TAG list dotfiles according to TAG . .It Fl U Ar excl_pat the rc files or directories matching this pattern will not be symlinked or created with a leading dot. See .Sx EXCLUDE PATTERN for more details. This option can be repeated. You may need to quote the pattern to prevent the shell from swallowing the glob. . .It Fl u Ar excl_pat if an rc file or directory matches the given pattern, it must be dotted. See .Sx EXCLUDE PATTERN for more details. This is the opposite of the .Fl U option, and can be used to undo it or the .Va UNDOTTED setting in your .Xr rcrc 5 configuration. This option can be repeated. You may need to quote the pattern to prevent the shell from swallowing the glob. . .It Fl V show the version number. . .It Fl v increase verbosity. This can be repeated for extra verbosity. . .It Fl q decrease verbosity . .It Fl x Ar excl_pat exclude the files that match the given pattern. See .Sx EXCLUDE PATTERN for more details. This option can be repeated. Quote the pattern if it contains a valid shell glob. . .It Ar files ... only list the specified file(s) .El .Sh EXCLUDE PATTERN The exclude pattern specifies a colon-separated pair of dotfiles directory and file glob. The dotfiles directory is optional and, if omitted, defaults to .Li * , which is a special token that matches any dotfiles directory. The file glob is relative to the dotfiles directory, ignoring meta directories. A colon combines them. . .Pp For example, to ignore all emacs-related items from the .Pa thoughtbot-dotfiles directory, use the exclude pattern: .Pp .Dl thoughtbot-dotfiles:*emacs* .Pp To ignore any .Pa bash_profile file, use the pattern: .Pp .Dl *:bash_profile .Pp Or more simply: .Pp .Dl bash_profile .Pp . Since exclude patterns are often valid shell globs, be sure to quote them. See the caveats noted in .Sx BUGS when using an exclude pattern. .Sh ENVIRONMENT .Bl -tag -width ".Ev RCRC" .It Ev RCRC User configuration file. Defaults to .Pa ~/.rcrc . .El .Sh FILES .Pa ~/.dotfiles .Pa ~/.rcrc .Sh SEE ALSO .Xr mkrc 1 , .Xr rcdn 1 , .Xr rcup 1 , .Xr rcrc 5 , .Xr rcm 7 .Sh AUTHORS .Nm is maintained by .An "Mike Burns" Aq Mt mburns@thoughtbot.com and .Lk http://thoughtbot.se thoughtbot .Sh BUGS For macOS systems, we strongly encourage the use of the .Va HOSTNAME variable in your .Xr rcrc 5 . We use the .Xr hostname 1 program to determine the unique identifier for the host. This program is not specified by POSIX and can vary by system. On macOS the hostname is unpredictable, and can even change as part of the DHCP handshake. rcm-1.3.4/man/mkrc.1000066400000000000000000000036421372226550100141010ustar00rootroot00000000000000.Dd July 28, 2013 .Dt MKRC 1 .Os .Sh NAME .Nm mkrc .Nd bless files into a dotfile managed by rcm .Sh SYNOPSIS .Nm mkrc .Op Fl ChoqSsVvUu .Op Fl t Ar tag .Op Fl d Ar dir .Op Fl B Ar hostname .Ar files ... .Sh DESCRIPTION This program adds files to your dotfiles directory then installs it back into your home directory. It can install files under a tag or different source directory. . It supports these options: . .Bl -tag -width "-d DIR" .It Fl B Ar HOSTNAME use the supplied hostname instead of computing one. Implies .Fl o . .It Fl C copy instead of symlinking when installing the rc file back into your home directory .It Fl d Ar DIR install dotfiles under the specified directory. This can be specified multiple times. .It Fl h show usage instructions. .It Fl o install dotfiles into the host-specific directory .It Fl q decrease verbosity .It Fl S treat the specified rc files as files to be symlinked, even if they are directories .It Fl s if the rc file is a file, symlink it; otherwise, make a directory structure as described in .Xr rcup 1 in the section .Sx ALGORITHM . This is the default. .It Fl t Ar TAG install dotfiles according to tag .It Fl U the specified files or directories are to be installed without a leading dot. .It Fl u the specified files or directories are to be installed with a leading dot. This is the default. .It Fl v increase verbosity. This can be repeated for extra verbosity. .It Fl V show the version number. .El .Sh ENVIRONMENT .Bl -tag -width ".Ev RCRC" .It Ev RCRC User configuration file. Defaults to .Pa ~/.rcrc . .El .Sh FILES .Pa ~/.dotfiles .Pa ~/.rcrc .Sh EXAMPLES .Dl mkrc ~/.vimrc .Dl mkrc -t zsh -d company-dotfiles ~/.zshrc ~/.zlogin .Dl mkrc -o ~/.rcrc .Dl mkrc -C .ssh .Dl mkrc -S .zpretzo .Dl mkrc -U bin .Sh SEE ALSO .Xr lsrc 1 , .Xr rcdn 1 , .Xr rcup 1 , .Xr rcrc 5 , .Xr rcm 7 .Sh AUTHORS .Nm is maintained by .An "Mike Burns" Aq Mt mburns@thoughtbot.com and .Lk http://thoughtbot.se thoughtbot rcm-1.3.4/man/rcdn.1000066400000000000000000000072501372226550100140720ustar00rootroot00000000000000.Dd August 2, 2013 .Dt RCDN 1 .Os .Sh NAME .Nm rcdn .Nd remove dotfiles as managed by rcm .Sh SYNOPSIS .Nm rcdn .Op Fl hKkqVv .Op Fl B Ar hostname .Op Fl d Ar dir .Op Fl I Ar excl_pat .Op Fl S Ar excl_pat .Op Fl s Ar excl_pat .Op Fl t Ar tag .Op Fl U Ar excl_pat .Op Fl u Ar excl_pat .Op Fl x Ar excl_pat .Op Ar files ... .Sh DESCRIPTION This program will remove all the rc files that the .Xr rcm 7 suite knows about. This can be further controlled with the .Fl t and .Fl d flags. .Pp The files that are removed are symlinks. However, the .Va COPY_ALWAYS setting in .Xr rcrc 5 modifies this. If a rc file is not a symlink but an ancestor directory is, that directory is removed. If a rc file is not a symlink but is listed in .Va COPY_ALWAYS the file is removed. .Pp The .Nm program will run hooks before and after removing files, if these hooks exist. Hooks are executable programs inside the dotfiles directory, with the following names: .Pa hooks/pre-down and .Pa hooks/post-down . These hooks are run each time .Nm is run and therefore must be idempotent. .Pp Hooks will be executed one at a time, sorted alphabetically. For instance, .Pa hooks/pre-down/animals will run before .Pa hooks/pre-down/aquariums , and .Pa hooks/pre-down/4-eyes will run before .Pa hooks/post-down/2-u-nothing-compares . .Bl -tag -width "-I EXCL_PAT" .It Fl B Ar HOSTNAME treat .Pa host-HOSTNAME as the host-specific directory instead of computing it .It Fl d Ar DIR remove rc files from the .Ar DIR . This can be specified multiple times. .It Fl h show usage instructions. .It Fl I Ar EXCL_PAT remove rc files that match .Ar EXCL_PAT despite being excluded by the .Fl x flag or a setting in .Xr rcrc 5 . This can be repeated with additional patterns. See .Xr lsrc 1 , .Sx EXCLUDE PATTERN , for more details. .It Fl K skip pre- and post-hooks .It Fl k run pre- and post-hooks. This is the default. .It Fl q decrease verbosity .It Fl S Ar EXCL_PAT when removing dotfiles, any file that matches .Ar EXCL_PAT should be treated as a file that was symlinked, even if it is a directory. This can be repeated. .It Fl s Ar EXCL_PAT when removing dotfiles, any directory that matches .Ar EXCL_PAT should be recurred upon like normal. This is the default, and is the opposite of .Fl S . This can be repeated. .It Fl t Ar TAG remove dotfiles according to .Ar TAG .It Fl U Ar EXCL_PAT any rc file or directory that matches .Ar EXCL_PAT is considered to have been installed without a leading dot when removing them. Must be specified for rc files or directories that were indeed installed without a leading dot. This can be repeated. See the documentation of the .Fl U option in .Xr lsrc 1 for more information. .It Fl u Ar EXCL_PAT any rc file or directory that matches .Ar EXCL_PAT is considered to have been installed with a leading dot when removing them. This is the default, and is the opposite of .Fl U . This can be repeated. See the documentation of the .Fl u option in .Xr lsrc 1 for more information. .It Fl v increase verbosity. This can be repeated for extra verbosity. .It Fl V show the version number. .It Fl x Ar EXCL_PAT do not remove rc files that match .Ar EXCL_PAT . This can be repeated with additional patterns. See .Xr lsrc 1 , .Sx EXCLUDE PATTERN , for more details. .It Ar files only remove the specified file(s) .El . .Sh ENVIRONMENT .Bl -tag -width ".Ev RCRC" .It Ev RCRC User configuration file. Defaults to .Pa ~/.rcrc . .El .Sh FILES .Pa ~/.rcrc .Sh EXAMPLES .Dl rcdn -v .Dl rcdn zshrc .Dl rcdn -t python .Dl rcdn -d ~/corporate-dotfiles .Dl rcdn -x '*:.zshrc' .Sh SEE ALSO .Xr lsrc 1 , .Xr mkrc 1 , .Xr rcup 1 , .Xr rcrc 5 , .Xr rcm 7 .Sh AUTHORS .Nm is maintained by .An "Mike Burns" Aq Mt mburns@thoughtbot.com and .Lk http://thoughtbot.se thoughtbot rcm-1.3.4/man/rcm.7.mustache000066400000000000000000000172241372226550100155450ustar00rootroot00000000000000.Dd July 28, 2013 .Dt RCM 7 .Os .Sh NAME .Nm rcm .Nd dotfile management .Sh SYNOPSIS .Nm lsrc .Nm mkrc .Nm rcdn .Nm rcup .Sh DESCRIPTION The rcm suite of tools is for managing dotfiles directories. This is a directory containing all the .Li .*rc files in your home directory .Sm off .Po .Pa .zshrc , .Sm on .Pa .vimrc , and so on .Pc . These files have gone by many names in history, such as .Do rc files .Dc because they typically end in .Li rc or .Do dotfiles .Dc because they begin with a period. .Pp This suite is useful for committing your rc files to a central repository to share, but it also scales to a more complex situation such as multiple source directories shared between computers with some host-specific or task-specific files. .Pp This guide serves as a tutorial motivating the suite. For a list of quick reference documentation see the .Sx SEE ALSO section below. . .Sh QUICK START FOR EXISTING DOTFILES DIRECTORIES This section is for those who already have an existing dotfiles directory; this directory is .Pa ~/.dotfiles ; the directory only contains rc files; and these rc filenames do not begin with a period. See the caveats below if this is not you. .Bl -enum .It Dry run with .Xr lsrc 1 . Look for anything unexpected in here, such as .Pa ~/.install or .Pa ~/.Makefile , or an empty list of dotfiles. .Pp .Dl lsrc .It Update any symlinks with .Xr rcup 1 . This is likely to do nothing, since your dotfiles already exist. .Pp .Dl rcup -v .It When necessary, add new rc files to the dotfiles directory with .Xr mkrc 1 . .Pp .Dl mkrc ~/.tigrc .Pp In the other direction, you can use .Xr rcup 1 to create the symlinks from .Pa ~/.dotfiles to your home directory. .Pp .Dl rcup tigrc .El .Ss COMMON PROBLEM: EXISTING INSTALL SCRIPTS Many existing dotfile directories have scripts named .Pa install or .Pa Makefile in the directory. This will cause a .Pa ~/.install or .Pa ~/.Makefile symlink to be created in your home directory. Use an exclusion pattern to ignore these. .Pp .Dl rcup -x install -x Rakefile -x Makefile -x install.sh .Ss COMMON PROBLEM: DOTTED FILENAMES IN DOTFILES DIRECTORY A less common situation is for all the filenames in your dotfiles directory to be prefixed with a period. These files are skipped by the rcm suite, and thus would result in nothing happening. The only option in this case is to rename all the files, for example by using a shell command like the following. .Pp .Dl find ~/.dotfiles -name '.*' -exec echo mv {} `echo {} | sed 's/\.//'` \; .Pp Note that this will break any existing symlinks. Those can be safely removed using the .Xr rcdn 1 command. .Pp .Dl rcdn -v .Ss COMMON PROBLEM: DOTFILES DIRECTORY NOT IN Pa ~/.dotfiles This all assumes that your dotfiles directory is .Pa ~/.dotfiles . If it is elsewhere and you do not want to move it you can use the .Fl d Ar DIR option to .Xr rcup 1 or modify .Ev DOTFILES_DIRS in .Xr rcrc 5 . .Pp .Dl rcup -d configs -v . .Ss COMMON PROBLEM: CONFIGURATION FILES/DIRECTORIES WITHOUT DOTS By default, the rcm suite will prefix every file and directory it manages with a dot. If that is not desired, for example in the case of .Pa ~/bin or .Pa ~/texmf , you can add that file or directory to .Ev UNDOTTED in .Xr rcrc 5 or use the .Fl U option. For example: .Pp .Dl mkrc -U bin . .Sh QUICK START FOR EMPTY DOTFILES DIRECTORIES This section is for those who do not have an existing dotfiles directory and whose dotfiles are standard. .Bl -enum .It Add your rc files to a dotfiles directory with .Xr mkrc 1 . .Pp .Dl mkrc .zshrc .gitconfig .tigrc .It Synchronize your home directory with .Xr rcup 1 .Pp .Dl rcup -v .El .Pp This will give you a directory named .Pa ~/.dotfiles with your dotfiles in it. Your original dotfiles will be symlinks into this directory. For example, .Pa ~/.zshrc will be a symlink to .Pa ~/.dotfiles/zshrc . . .Sh TAGGED DOTFILES This suite becomes more powerful if you share your dotfiles directory between computers, either because multiple people share the same directory or because you have multiple computers. .Pp If you share the dotfiles directory between people, you may end up with some irrelevant or even incorrect rc files. For example, you may have a .Pa .zshrc while your other contributor has a .Pa .bashrc . This situation can be handled with tags. .Bl -enum .It A tag is a directory under the dotfiles directory that starts with the letters .Li tag- . We can handle the competing shell example by making a .Pa tag-zsh directory and moving the .Pa .zshrc file into it using .Xr mkrc 1 and passing the .Fl t option. .Pp .Dl mkrc -t zsh .zshrc .It When updating with .Xr rcup 1 you can pass the .Fl t option to include the tags you want. This can also be set in the .Xr rcrc 5 configuration file with the .Ev TAGS variable. .Pp .Dl rcup -t zsh .El . .Sh MULTIPLE DOTFILE DIRECTORIES Another common situation is combining multiple dotfiles directories that people have shared with you. For this we have the .Fl d flag or the .Ev DOTFILES_DIRS option in .Pa .rcrc . .Pp The following rcup invocation will go in sequence through the three dotfiles directories, updating any symlinks as needed. Any overlapping rc files will use the first result, not the last; that is, .Pa .dotfiles/vimrc will take precedence over .Pa marriage-dotfiles/vimrc . .Pp .Dl rcup -d .dotfiles -d marriage-dotfiles -d thoughtbot-dotfiles .Pp An exclusion pattern can be tied to a specific dotfiles directory. .Pp .Dl rcup -d .dotfiles -d work-dotfiles -x 'work-dotfiles:powrc' . .Sh HOST-SPECIFIC DOTFILES You can also mark host-specific files. This will go by the hostname. The .Xr rcrc 5 configuration file is a popular candidate for a host-specific file, since the tags and dotfile directories listed in there are often specific to a single machine. .Pp .Dl mkrc -o .rcrc .Pp If your hostname is difficult to compute, or you otherwise want to use a different hostname, you can use the .Fl B flag. .Pp .Dl mkrc -B eggplant .rcrc .Pp macOS users should see the .Sx BUGS section for more details. . .Sh STANDALONE INSTALLATION SCRIPT . The .Xr rcup 1 tool can be used to generate a portable shell script. Instead of running a command such as .Xr ln 1 or .Xr rm 1 , it will print the command to .Li stdout . This is controlled with the .Fl g flag. Note that this will generate a script to create an exact replica of the synchronization, including tags, host-specific files, and dotfiles directories. .Pp .Dl env RCRC=/dev/null rcup -B 0 -g > install.sh .Pp Using the above command, you can now run .Li install.sh to install (or re-install) your rc files. The .Li install.sh script can be stored in your dotfiles directory, copied between computers, and so on. . .Sh RATIONALE The rcm suite was built as an abstraction over the shell, Ruby, Python, and make scripts people were writing and sharing. It is intended to run on any unix system and support the range from simple to complex dotfile directories. .Pp As such, this suite is useful as a common base. Through this we can share tools and develop this further as a first-class entity. It is also our hope that a common set of tools will encourage others to share their dotfiles, too. .Sh FILES .Pa ~/.dotfiles .Pa ~/.rcrc .Sh SEE ALSO .Xr lsrc 1 , .Xr mkrc 1 , .Xr rcdn 1 , .Xr rcup 1 , .Xr rcrc 5 .Sh AUTHORS .Nm is maintained by .An "Mike Burns" Aq Mt mburns@thoughtbot.com and .Lk http://thoughtbot.se thoughtbot .Sh BUGS For macOS systems, we strongly encourage the use of the .Va HOSTNAME variable in your .Xr rcrc 5 . We use the .Xr hostname 1 program to determine the unique identifier for the host. This program is not specified by POSIX and can vary by system. On macOS, the hostname is unpredictable, and can even change as part of the DHCP handshake. .Sh CONTRIBUTORS .An -split {{#contributors}} .An "{{{name}}}" Aq Mt {{{email}}} {{/contributors}} rcm-1.3.4/man/rcrc.5000066400000000000000000000046311372226550100141010ustar00rootroot00000000000000.Dd July 28, 2013 .Dt RCRC 5 .Os .Sh NAME .Nm rcrc .Nd configuration for rcm .Sh SYNOPSIS .Sm off .Ns Ev X .Ns = .Ns Qo .Va a\ \& .Va b\ \& .Va c .Qc .Sm on .Sh DESCRIPTION The rcm dotfile manager can be configured using a .Pa .rcrc file in your home directory. This location can be changed by setting the .Pa RCRC environment variable. The format is POSIX shell. It is sourced in by the .Xr lsrc 1 , .Xr mkrc 1 , .Xr rcdn 1 , and .Xr rcup 1 programs. .Pp It supports these variables: .Bl -tag -width "DOTFILES_DIRS" .It Va COPY_ALWAYS always copy files that match the listed globs, never symlink them. . .It Va DOTFILES_DIRS the source directories for dotfiles. The first in the list is the source to which dotfiles created using .Xr mkrc 1 are installed. The default value is .Pa ~/.dotfiles . .It Va EXCLUDES a space-separated list of exclude patterns. Exclude patterns are explained in detail in .Xr lsrc 1 under the section .Sx EXCLUDE PATTERN . . .It Va HOSTNAME the hostname for this computer. This is normally computed using the .Xr hostname 1 command, but this command is non-standard and can prove unreliable. The .Va HOSTNAME variable forces a known hostname. .It Va TAGS the default tags. . .It Va SYMLINK_DIRS a space-separated list of patterns. Directories matching a pattern are symlinked instead of descended. Patterns are explained in detail in .Xr lsrc 1 under the section .Sx EXCLUDE PATTERN . . .It Va UNDOTTED a space separated list of patterns. Files matching this pattern will be symlinked without a leading dot. If a file is also in .Va SYMLINK_DIRS , then the directory will be symlinked without a leading dot. Patterns are explained in detail in .Xr lsrc 1 under the section .Sx EXCLUDE PATTERN . . .El .Sh FILES .Pa ~/.rcrc .Sh EXAMPLES .Dl COPY_ALWAYS="ssh/id_* weechat/* netrc" .Dl COPY_ALWAYS="*" .Dl DOTFILES_DIRS="/home/mike/.dotfiles /usr/share/dotfiles" .Dl EXCLUDES="irbrc *:*emacs* dotfiles:python*" .Dl HOSTNAME="eggplant" .Dl TAGS="freebsd development email git laptop gmail notmuch" .Dl SYMLINK_DIRS="zprezto texmf" .Dl UNDOTTED="texmf" .Sh SEE ALSO .Xr lsrc 1 , .Xr mkrc 1 , .Xr rcdn 1 , .Xr rcup 1 , .Xr rcm 7 .Sh AUTHORS .Nm is maintained by .An "Mike Burns" Aq Mt mburns@thoughtbot.com and .Lk http://thoughtbot.se thoughtbot .Sh BUGS We only expand tilde inside .Va DOTFILES_DIRS and not inside any patterns. For more notes on the caution you should exercise around patterns, see the BUGS section of .Xr lsrc 1 . rcm-1.3.4/man/rcup.1000066400000000000000000000140271372226550100141150ustar00rootroot00000000000000.Dd July 28, 2013 .Dt RCUP 1 .Os .Sh NAME .Nm rcup .Nd update and install dotfiles managed by rcm .Sh SYNOPSIS .Nm rcup .Op Fl CfhiKkqVv .Op Fl B Ar hostname .Op Fl d Ar dir .Op Fl g .Op Fl I Ar excl_pat .Op Fl S Ar excl_pat .Op Fl s Ar excl_pat .Op Fl t Ar tag .Op Fl U Ar excl_pat .Op Fl u Ar excl_pat .Op Fl x Ar excl_pat .Op Ar files ... .Sh DESCRIPTION This is a program to update and install personal dotfiles. These dotfiles are managed in a separate directory. Use .Nm rcup to install files from your dotfiles directories or from host- or tag-specific directories within. .Pp See .Sx DIRECTORY LAYOUT for details on the directory layout. .Pp It supports these options: .Bl -tag -width "-x EXCL_PAT" .It Fl B Ar HOSTNAME treat .Pa host-HOSTNAME as the host-specific directory instead of computing it .It Fl C copy the files instead of symlinking them .It Fl d Ar DIR install dotfiles from the .Ar DIR . This can be specified multiple times. .It Fl f if the rc file already exists in your home directory but does not match the file in your dotfiles directory, remove the rc file then create the symlink .It Fl g print to .Li stdout a standalone shell script that will run the .Nm command as specified. Nothing on your filesystem will be modified by .Nm when this flag is passed. .It Fl h show usage instructions. .It Fl I Ar EXCL_PAT install rc files that match .Ar EXCL_PAT despite being excluded by the .Fl x flag or a setting in .Xr rcrc 5 . This can be repeated with additional patterns. See .Xr lsrc 1 , .Sx EXCLUDE PATTERN , for more details. .It Fl i if the rc file already exists in your home directory but does not match the file in your dotfiles directory, prompt for how to handle it. This is the default .It Fl K skip pre- and post-hooks .It Fl k run pre- and post-hooks (see .Sx DIRECTORY LAYOUT for more details on hooks). This is the default. .It Fl S Ar EXCL_PAT any rc file that matches .Ar EXCL_PAT is installed as if it were a file (using a symlink) instead of as if it were a directory (by making a directory). This option can be repeated. .It Fl s Ar EXCL_PAT any file that matches .Ar EXCL_PAT is installed as normal, in accordance with the .Sx ALGORITHM section below. This is the opposite of .Fl S . This option can be repeated. .It Fl t Ar TAG install dotfiles according to .Ar TAG .It Fl U Ar EXCL_PAT any rc file that matches .Ar EXCL_PAT is installed without a leading dot. This option can be repeated. See the documentation of the .Fl U option in .Xr lsrc 1 for more information. .It Fl u Ar EXCL_PAT any rc file that matches .Ar EXCL_PAT is installed with a leading dot. This is the opposite of .Fl U . This option can be repeated. This is the default. See the documentation of the .Fl u option in .Xr lsrc 1 for more information. .It Fl q decrease verbosity .It Fl V show the version number. .It Fl v increase verbosity. This can be repeated for extra verbosity. Verbose messages are printed to .Li stderr . .It Fl x Ar EXCL_PAT do not install rc files that match .Ar EXCL_PAT . This can be repeated with additional patterns. See .Xr lsrc 1 , .Sx EXCLUDE PATTERN , for more details. .It Ar files only install the specified file(s) .El .Sh DIRECTORY LAYOUT Any non-dot non-meta file or directory under your dotfiles directory will be installed as a dotfile. For example, .Pa .dotfiles/zshrc will be installed into .Pa ~/.zshrc \&. .Pp Files are installed as symlinks. Directories are installed by making directories. The .Fl C flag causes files to be installed as copies instead of symlinks. The .Va COPY_ALWAYS option in .Xr rcrc 5 can be used to list files that must only be copied. .Pp Three meta files are supported: host-specific files, tagged files, hooks. .Pp Host-specific files go in a directory named for the host, prefixed with .Pa host- . For example, .Pa .dotfiles/host-scarlett contains files specific to the computer with hostname .Pa scarlett , and these files will only be installed on the computer with hostname .Pa scarlett . .Pp Tagged files go in a directory named for the tag, prefixed with .Li tag- . Therefore, files under .Pa .dotfiles/tag-git are only installed when installing using the .Li git tag. .Pp Hooks go in a directory named .Pa hooks . Two hooks are supported by .Nm rcup : pre-up and post-up. These go in files or directories with predictable filenames: .Pa .dotfiles/hooks/pre-up and .Pa .dotfiles/hooks/post-up , or .Pa .dotfiles/hooks/pre-up/* and .Pa .dotfiles/hooks/post-up/* . These files must be executable. They are run every time .Nm is run, and therefore must be idempotent. .Pp Hooks will be executed one at a time, sorted alphabetically. For instance, .Pa hooks/pre-up/animals will run before .Pa hooks/pre-up/aquariums , and .Pa hooks/pre-up/4-eyes will run before .Pa hooks/post-up/2-u-nothing-compares . .Sh ALGORITHM It is instructive to understand the process .Nm rcup uses when synchronizing your rc files: .Bl -enum .It The pre-up hook is run. . .It All non-host, non-tag files without a dot prefix are symlinked to the dotted filename in your home directory. So, .Pa .dotfiles/tigrc is symlinked to .Pa ~/.tigrc . . .It All non-host, non-tag directories have their structure copied to your home directory, then a non-dotted symlink is created within. So for example, .Pa .dotfiles/vim/autoload/haskell.vim causes the .Pa ~/.vim/autoload directory to be created, then .Pa haskell.vim is symlinked within. . .It Steps (2) and (3) are applied to host-specific files. These are files under a directory named .Sm off .Pa host- Va $HOSTNAME . .Sm on . .It Steps (2) and (3) are applied to tag-specific files. These are files under directories named .Sm off .Pa tag- Va $TAG_NAME , .Sm on where .Va $TAG_NAME is the name of each specified tag in turn, taken from the command line or from .Xr rcrc 5 . . .It The post-up hook is run. .El . .Sh ENVIRONMENT .Bl -tag -width ".Ev RCRC" .It Ev RCRC User configuration file. Defaults to .Pa ~/.rcrc . .El .Sh FILES .Pa ~/.dotfiles .Pa ~/.rcrc .Sh SEE ALSO .Xr lsrc 1 , .Xr mkrc 1 , .Xr rcdn 1 , .Xr rcrc 5 , .Xr rcm 7 .Sh AUTHORS .Nm is maintained by .An "Mike Burns" Aq Mt mburns@thoughtbot.com and .Lk http://thoughtbot.se thoughtbot rcm-1.3.4/share/000077500000000000000000000000001372226550100134055ustar00rootroot00000000000000rcm-1.3.4/share/rcm.sh.in000066400000000000000000000063661372226550100151420ustar00rootroot00000000000000VERSION="@PACKAGE_VERSION@" #set -x DEBUG=: DEST_DIR="$HOME" PRINT=echo PROMPT=echo_n ERROR=echo_error VERBOSE=: DEFAULT_DOTFILES_DIR="$HOME/.dotfiles" MKDIR=mkdir INSTALL=rcup ROOT_DIR="$HOME" if [ -z "$LOGNAME" ]; then LOGNAME=$(whoami) fi ln_v() { $VERBOSE "'$1' -> '$2'" ln -s "$1" "$2" } cp_v() { $VERBOSE "'$1' -> '$2'" cp -R "$1" "$2" } rm_v() { $VERBOSE "removed '$2'" rm $1 "$2" } mv_v() { $VERBOSE "'$1' -> '$2'" mv "$1" "$2" } unset CDPATH echo_n() { printf "%s " "$*" } echo_error() { local exit_status=$1 shift echo "$*" >&2 exit $exit_status } echo_stderr() { echo "$*" >&2 } is_relative() { echo "$1" | grep -v '^/' >/dev/null } is_nested() { echo "$1" | sed "s|$DEST_DIR/||" | grep '/' >/dev/null } version() { cat << EOV $1 (rcm) $VERSION Copyright (C) 2013 Mike Burns Copyright (C) 2014 thoughtbot License BSD: BSD 3-clause license Written by Mike Burns. EOV } handle_common_flags() { local prog_name="$1" local version="$2" local verbosity=$3 if [ $version -eq 1 ]; then version "$prog_name" exit 0 elif [ $verbosity -ge 2 ]; then DEBUG=echo_stderr VERBOSE=echo PRINT=echo INSTALL="$INSTALL -vv" elif [ $verbosity -eq 1 ]; then DEBUG=: VERBOSE=echo PRINT=echo INSTALL="$INSTALL -v" elif [ $verbosity -eq 0 ]; then DEBUG=: VERBOSE=: PRINT=echo else DEBUG=: VERBOSE=: PRINT=: INSTALL="$INSTALL -q" fi } determine_hostname() { local name="$1" if [ -n "$name" ]; then echo "$name" elif [ -n "$HOSTNAME" ]; then echo "$HOSTNAME" else echo "$(hostname | sed -e 's/\..*//')" fi } run_hooks() { $DEBUG "run_hooks $1 $2" $DEBUG " with DOTFILES_DIRS: $DOTFILES_DIRS" local when="$1" local direction="$2" local hook_file local find_opts= if [ $RUN_HOOKS -eq 1 ]; then for dotfiles_dir in $DOTFILES_DIRS; do dotfiles_dir=$(eval echo "$dotfiles_dir") hook_file="$dotfiles_dir/hooks/$when-$direction" if [ -e "$hook_file" ]; then $VERBOSE "running $when-$direction hooks for $dotfiles_dir" if [ x$DEBUG != x: ]; then find_opts=-print fi # Emulate the non-POSIX-compliant `-execdir` action with `-exec` and a shell one-liner. # The former is however a bit better when it comes to security. On the other hand # running these hooks imply some level of trust; surely one doesn't clone somebody # else's dotfiles repository without reviewing the hooks before doing an `rcup`? find "$hook_file" -type f \( \( -user $LOGNAME -perm -100 \) -o -perm -001 \) \ | sort | while read file; do sh -c 'cd -- "`dirname $1`" && ./"`basename $1`"' arg0 "$file" done else $DEBUG "no $when-$direction hook present for $dotfiles_dir, skipping" fi done fi } de_dot() { $DEBUG "de_dot $1" $DEBUG " with DEST_DIR: $DEST_DIR" echo "$1" | sed -e "s|$DEST_DIR/||" | sed -e 's/^\.//' } DELIMITER="\a" encode() { local file="$1" echo "$file" | tr " " "$DELIMITER" } decode() { local file="$1" echo "$file" | tr "$DELIMITER" " " } append_variable() { if [ -z "$1" ]; then echo "$2" else echo "$1 $2" fi } : ${RCRC:=$HOME/.rcrc} if [ -r "$RCRC" ]; then . "$RCRC" fi rcm-1.3.4/test/000077500000000000000000000000001372226550100132625ustar00rootroot00000000000000rcm-1.3.4/test/helper.sh000066400000000000000000000015511372226550100150770ustar00rootroot00000000000000for bin in lsrc mkrc rcup rcdn; do chmod +x "$TESTDIR/../bin"/$bin done export HOME="$PWD" export PATH="$TESTDIR/../bin:$PATH" export RCRC="$HOME/.rcrc" export RCM_LIB="$TESTDIR/../share" mkdir .dotfiles hostname() { if [ -n "$HOSTNAME" ]; then echo "$HOSTNAME" else command hostname | sed -e 's/\..*//' fi } assert() { local msg="$1"; shift test "$@" || echo "Failed assertion: $msg" return 0 } refute() { local msg="$1"; shift test "$@" && echo "Failed assertion: $msg" return 0 } resolved_path() { local original_path="$1" perl -e \ "use Cwd realpath; print realpath(\"$original_path\") . \"\\n\";" } assert_linked() { local from="$1" to="$2" local resolved="$(resolved_path "$from")" assert "$from should be a symlink" -h "$from" assert "$from should resolve to $to, resolved to $resolved" "$resolved" = "$to" } rcm-1.3.4/test/lsrc-dotfiles-dirs.t000066400000000000000000000005631372226550100171640ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should include all the dotfiles $ touch .dotfiles/example > mkdir .second-dotfiles/ > touch .second-dotfiles/s-example > mkdir .third-dotfiles/ > touch .third-dotfiles/t-example $ lsrc -d .second-dotfiles -d .third-dotfiles /*/.s-example:/*/.second-dotfiles/s-example (glob) /*/.t-example:/*/.third-dotfiles/t-example (glob) rcm-1.3.4/test/lsrc-excludes.t000066400000000000000000000015711372226550100162300ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should exclude items with -x $ touch .dotfiles/example > touch .dotfiles/excluded $ lsrc -x excluded /*/.example:/*/.dotfiles/example (glob) Should accept directory:file syntax $ mkdir .other-dotfiles > touch .other-dotfiles/included > touch .other-dotfiles/excluded $ lsrc -d .dotfiles -d .other-dotfiles -x other-dotfiles:excluded /*/.example:/*/.dotfiles/example (glob) /*/.excluded:/*/.dotfiles/excluded (glob) /*/.included:/*/.other-dotfiles/included (glob) Should handle excludes with globs $ mkdir -p fresh/hola/chao > touch fresh/hola/chao/wo > touch fresh/hola/chao/nemo > touch fresh/hola/tossala > touch fresh/hola/s > touch fresh/s $ lsrc -d fresh -x 'hola/chao/*' -x s /*/.hola/tossala:/*/fresh/hola/tossala (glob) $ lsrc -d fresh -x 'hola/chao' -x s /*/.hola/tossala:/*/fresh/hola/tossala (glob) rcm-1.3.4/test/lsrc-globs.t000066400000000000000000000002321372226550100155130ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Keeps globs as globs $ mkdir vimulator > lsrc -vvv -x '*vim*' 2>&1 | grep exclude_file_globs exclude_file_globs: *vim* rcm-1.3.4/test/lsrc-host-tags-default.t000066400000000000000000000011271372226550100177440ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Hosts override tags override defaults $ touch .dotfiles/host-example > touch .dotfiles/tag-example > touch .dotfiles/default-example > mkdir .dotfiles/tag-firetruck > touch .dotfiles/tag-firetruck/host-example > touch .dotfiles/tag-firetruck/tag-example > mkdir .dotfiles/host-eggplant > touch .dotfiles/host-eggplant/host-example $ lsrc -B eggplant -t firetruck /*/.host-example:/*/.dotfiles/host-eggplant/host-example (glob) /*/.tag-example:/*/.dotfiles/tag-firetruck/tag-example (glob) /*/.default-example:/*/.dotfiles/default-example (glob) rcm-1.3.4/test/lsrc-hostname.t000066400000000000000000000007631372226550100162340ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should include entries that match hostname $ touch .dotfiles/example > mkdir .dotfiles/host-$(hostname) > touch .dotfiles/host-$(hostname)/h-example > mkdir .dotfiles/host-not-hostname > touch .dotfiles/host-not-hostname/nh-example $ lsrc /*/.h-example:/*/.dotfiles/host-*/h-example (glob) /*/.example:/*/.dotfiles/example (glob) $ lsrc -B not-hostname /*/.nh-example:/*/.dotfiles/host-*/nh-example (glob) /*/.example:/*/.dotfiles/example (glob) rcm-1.3.4/test/lsrc-sigils.t000066400000000000000000000010541372226550100157020ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should print @ for links $ touch .dotfiles/example $ lsrc -F /*/.example:/*/.dotfiles/example:@ (glob) Should print X for files in COPY_ALWAYS $ touch .dotfiles/copy $ COPY_ALWAYS=copy lsrc -F /*/.copy:/*/.dotfiles/copy:X (glob) /*/.example:/*/.dotfiles/example:@ (glob) Should print $ for directory links $ mkdir .dotfiles/folder $ SYMLINK_DIRS=folder COPY_ALWAYS=copy lsrc -F /*/.copy:/*/.dotfiles/copy:X (glob) /*/.example:/*/.dotfiles/example:@ (glob) /*/.folder:/*/.dotfiles/folder:$ (glob) rcm-1.3.4/test/lsrc-spaces.t000066400000000000000000000002751372226550100156720ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should handle dotfiles with spaces $ touch ".dotfiles/sublame text 3.config" $ lsrc /*/.sublame text 3.config:/*/.dotfiles/sublame text 3.config (glob) rcm-1.3.4/test/lsrc-symlink-dirs.t000066400000000000000000000011101372226550100170260ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Overrides SYMLINK_DIRS with -s $ mkdir -p .dotfiles/eggplant_firetruck/lampshade > touch .dotfiles/eggplant_firetruck/lampshade/bottle $ echo 'SYMLINK_DIRS="eggplant_firetruck"' > $HOME/.rcrc $ lsrc /*/.eggplant_firetruck:/*/.dotfiles/eggplant_firetruck (glob) $ lsrc -s eggplant_firetruck /*/.eggplant_firetruck/lampshade/bottle:/*/.dotfiles/eggplant_firetruck/lampshade/bottle (glob) $ lsrc -S eggplant_firetruck -s eggplant_firetruck /*/.eggplant_firetruck/lampshade/bottle:/*/.dotfiles/eggplant_firetruck/lampshade/bottle (glob) rcm-1.3.4/test/lsrc-tags.t000066400000000000000000000006311372226550100153460ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should include entries that match passed tags $ touch .dotfiles/example > mkdir .dotfiles/tag-foo > touch .dotfiles/tag-foo/f-example > mkdir .dotfiles/tag-bar > touch .dotfiles/tag-bar/b-example $ lsrc -t foo -t bar /*/.f-example:/*/.dotfiles/tag-foo/f-example (glob) /*/.b-example:/*/.dotfiles/tag-bar/b-example (glob) /*/.example:/*/.dotfiles/example (glob) rcm-1.3.4/test/lsrc-undotted-star.t000066400000000000000000000005361372226550100172110ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should undot files with -U, with wildcard * expansion $ touch .dotfiles/example > touch .dotfiles/undotted $ lsrc -v -U '*' /*/example:/*/.dotfiles/example (glob) /*/undotted:/*/.dotfiles/undotted (glob) $ lsrc -v -U '*:*' /*/example:/*/.dotfiles/example (glob) /*/undotted:/*/.dotfiles/undotted (glob) rcm-1.3.4/test/lsrc-undotted.t000066400000000000000000000003351372226550100162370ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should undot files with -U $ touch .dotfiles/example > touch .dotfiles/undotted $ lsrc -U undotted /*/.example:/*/.dotfiles/example (glob) /*/undotted:/*/.dotfiles/undotted (glob) rcm-1.3.4/test/lsrc-usage.t000066400000000000000000000010531372226550100155130ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" -h should output usage information and exit 0 $ lsrc -h Usage: lsrc [-FhqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT] see lsrc(1) and rcm(7) for more details Unsupported options should output usage information and exit EX_USAGE $ lsrc --version Usage: lsrc [-FhqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT] see lsrc(1) and rcm(7) for more details [64] rcm-1.3.4/test/lsrc.t000066400000000000000000000006351372226550100144160ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should list the contents of ~/.dotfiles $ touch .dotfiles/example > mkdir .dotfiles/nested > touch .dotfiles/nested/example > mkdir .dotfiles/nested/deeply > touch .dotfiles/nested/deeply/example $ lsrc /*/.example:/*/.dotfiles/example (glob) /*/.nested/deeply/example:/*/.dotfiles/nested/deeply/example (glob) /*/.nested/example:/*/.dotfiles/nested/example (glob) rcm-1.3.4/test/mkrc-alternate-dotfiles-dir.t000066400000000000000000000003661372226550100207500ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" > mkdir .other-dotfiles Passing -d should specify alternate dotfiles location $ touch .example $ mkrc -d .other-dotfiles .example >/dev/null $ assert_linked "$HOME/.example" "$HOME/.other-dotfiles/example" rcm-1.3.4/test/mkrc-copy-file.t000066400000000000000000000004011372226550100162630ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Passing -C should copy the file $ echo 'Content' > .example $ mkrc -C .example >/dev/null $ refute "should not be a symlink" -h $HOME/.example $ cat $HOME/.example Content $ cat $HOME/.dotfiles/example Content rcm-1.3.4/test/mkrc-host-file.t000066400000000000000000000003031372226550100162670ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Passing -o should put it in a host $ touch .example $ mkrc -o .example >/dev/null $ assert_linked "$HOME/.example" "$HOME/.dotfiles/host-$(hostname)/example" rcm-1.3.4/test/mkrc-hostname.t000066400000000000000000000003161372226550100162170ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Able to override the hostname $ touch .example $ mkrc -B another_thing .example >/dev/null $ assert_linked "$HOME/.example" "$HOME/.dotfiles/host-another_thing/example" rcm-1.3.4/test/mkrc-no-symlinks.t000066400000000000000000000012561372226550100166700ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Passing a linked file is rejected. We need a second path not under what will be $HOME $ EXTDIR="${CRAMTMP}2" > mkdir -p "$EXTDIR" > echo 'Content' > "$EXTDIR/example" > ln -s "$EXTDIR/example" "$HOME/.example" $ mkrc .example '.example' is a symlink. Cannot process file. [1] $ refute "is a symlink" -h $HOME/.dotfiles/.example Passing a file in one linked dir is rejected $ mkdir "$HOME/.config" > ln -s "$EXTDIR/" "$HOME/.config/tmpdir" $ mkrc -v .config/tmpdir/example '.config/tmpdir/example' path contains a symlink (tmpdir). Cannot process file. [1] $ refute "is a symlink" -h "$HOME/.dotfiles/config/tmpdir/example" rcm-1.3.4/test/mkrc-simple-output.t000066400000000000000000000037211372226550100172330ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Making an rc file should move it into dotfiles and create a symlink $ touch .example $ mkrc -v .example Moving... '*/.example' -> '*/.dotfiles/example' (glob) Linking... '*/.dotfiles/example' -> '*/.example' (glob) $ assert_linked "$HOME/.example" "$HOME/.dotfiles/example" Making an rc file in a sub-directory should create the directories then create a symlink $ mkdir .nested > touch .nested/example $ mkrc -v .nested/example Moving... '*/.nested/example' -> '*/.dotfiles/nested/example' (glob) Linking... '*/.dotfiles/nested/example' -> '*/.nested/example' (glob) $ assert_linked "$HOME/.nested/example" "$HOME/.dotfiles/nested/example" Making an rc file in a deeply nested sub-directory should create all of the required directories then create a symlink $ mkdir .nested/deeply > touch .nested/deeply/example $ mkrc -v .nested/deeply/example Moving... '*/.nested/deeply/example' -> '*/.dotfiles/nested/deeply/example' (glob) Linking... '*/.dotfiles/nested/deeply/example' -> '*/.nested/deeply/example' (glob) $ assert_linked "$HOME/.nested/deeply/example" "$HOME/.dotfiles/nested/deeply/example" Making a relative rc file being in a sub-directory should move into dotfiles preserving the full path then symlink $ touch .nested/deeply/another_example > cd .nested/deeply $ mkrc -v another_example > cd ../.. Moving... '*/.nested/deeply/another_example' -> '*/.dotfiles/nested/deeply/another_example' (glob) Linking... '*/.dotfiles/nested/deeply/another_example' -> '*/.nested/deeply/another_example' (glob) $ assert_linked "$HOME/.nested/deeply/another_example" "$HOME/.dotfiles/nested/deeply/another_example" Making an absolute rc file $ touch .an_example $ mkrc -v $PWD/.an_example Moving... '*/.an_example' -> '*/.dotfiles/an_example' (glob) Linking... '*/.dotfiles/an_example' -> '*/.an_example' (glob) $ assert_linked "$HOME/.an_example" "$HOME/.dotfiles/an_example" rcm-1.3.4/test/mkrc-spaces.t000066400000000000000000000021021372226550100156520ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should handle dotfiles with spaces $ touch ".sublime text 3.config" .example $ touch .some\ other.config $ mkrc ".sublime text 3.config" .example .some\ other.config $ assert_linked "$HOME/.sublime text 3.config" "$HOME/.dotfiles/sublime text 3.config" > assert_linked "$HOME/.example" "$HOME/.dotfiles/example" > assert_linked "$HOME/.some other.config" "$HOME/.dotfiles/some other.config" Should handle hostnamed dotfiles with spaces $ touch ".sublime text 4.config" .example2 $ mkrc -o ".sublime text 4.config" .example2 $ assert_linked "$HOME/.sublime text 4.config" "$HOME/.dotfiles/host-$(hostname)/sublime text 4.config" > assert_linked "$HOME/.example2" "$HOME/.dotfiles/host-$(hostname)/example2" Should handle tagged dotfiles with spaces $ touch ".sublime text 5.config" .example3 $ mkrc -t whatever ".sublime text 5.config" .example3 $ assert_linked "$HOME/.sublime text 5.config" "$HOME/.dotfiles/tag-whatever/sublime text 5.config" > assert_linked "$HOME/.example3" "$HOME/.dotfiles/tag-whatever/example3" rcm-1.3.4/test/mkrc-symlink-dirs.t000066400000000000000000000012521372226550100170260ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Overrides SYMLINK_DIRS with -s $ mkdir -p .eggplant_firetruck/lampshade > touch .eggplant_firetruck/lampshade/bottle $ mkdir -p .boxing_card > touch .boxing_card/fragrance $ echo 'SYMLINK_DIRS="eggplant_firetruck boxing_card"' > $HOME/.rcrc $ mkrc -v .boxing_card Moving... '/*/.boxing_card' -> '/*/.dotfiles/boxing_card' (glob) Linking... '/*/.dotfiles/boxing_card' -> '/*/.boxing_card' (glob) $ mkrc -vs .eggplant_firetruck Moving... '/*/.eggplant_firetruck' -> '/*/.dotfiles/eggplant_firetruck' (glob) Linking... '/*/.dotfiles/eggplant_firetruck/lampshade/bottle' -> '/*/.eggplant_firetruck/lampshade/bottle' (glob) rcm-1.3.4/test/mkrc-tagged-file.t000066400000000000000000000002751372226550100165550ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Passing -t should put it in a tag $ touch .example $ mkrc -t foo .example >/dev/null $ assert_linked "$HOME/.example" "$HOME/.dotfiles/tag-foo/example" rcm-1.3.4/test/mkrc-undotted.t000066400000000000000000000003221372226550100162240ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" > touch random-dotfile Passing -U should make a file be undotted $ mkrc -U random-dotfile >/dev/null $ assert_linked "$HOME/random-dotfile" "$HOME/.dotfiles/random-dotfile" rcm-1.3.4/test/mkrc-usage.t000066400000000000000000000011321372226550100155020ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" no arguments should output usage information and exit EX_USAGE $ mkrc Usage: mkrc [-ChSsUuVvqo] [-t TAG] [-d DIR] [-B HOSTNAME] FILES ... see mkrc(1) and rcm(7) for more details [64] -h should output usage information and exit 0 $ mkrc -h Usage: mkrc [-ChSsUuVvqo] [-t TAG] [-d DIR] [-B HOSTNAME] FILES ... see mkrc(1) and rcm(7) for more details Unsupported options should output usage information and exit EX_USAGE $ mkrc --version Usage: mkrc [-ChSsUuVvqo] [-t TAG] [-d DIR] [-B HOSTNAME] FILES ... see mkrc(1) and rcm(7) for more details [64] rcm-1.3.4/test/rcdn-hooks-run-in-order.t000066400000000000000000000020401372226550100200310ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Pre-down and post-down hooks should run in order according to their name $ mkdir -p .dotfiles/hooks/pre-down .dotfiles/hooks/post-down > printf "#!/bin/sh\necho '1'\n" > .dotfiles/hooks/pre-down/00-test.sh > printf "#!/bin/sh\necho '2'\n" > .dotfiles/hooks/pre-down/01-test.sh > printf "#!/bin/sh\necho '3'\n" > .dotfiles/hooks/pre-down/02-test.sh > printf "#!/bin/sh\necho '4'\n" > .dotfiles/hooks/post-down/00-test.sh > printf "#!/bin/sh\necho '5'\n" > .dotfiles/hooks/post-down/01-test.sh > printf "#!/bin/sh\necho '6'\n" > .dotfiles/hooks/post-down/02-test.sh $ chmod +x .dotfiles/hooks/pre-down/00-test.sh > chmod +x .dotfiles/hooks/pre-down/01-test.sh > chmod +x .dotfiles/hooks/pre-down/02-test.sh > chmod +x .dotfiles/hooks/post-down/00-test.sh > chmod +x .dotfiles/hooks/post-down/01-test.sh > chmod +x .dotfiles/hooks/post-down/02-test.sh $ rcdn 1 2 3 4 5 6 Ensure that hooks run when output of lsrc is non-empty $ touch .dotfiles/testrc > rcdn 1 2 3 4 5 6 rcm-1.3.4/test/rcdn-hooks-run-in-situ.t000066400000000000000000000023331372226550100177070ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Use a pre-generated UUID in a filename to make sure the filename is unique to this test and also that the pre-down hook has found the right directory having found this file. $ uniquish_file_prefix='test-hooks-run-in-situ-' > uuid='5b811e03-5977-40e6-80ef-dd6c35013e56' > uniquish_file=${uniquish_file_prefix}${uuid} Pre-down and post-down hooks should run by default. More importantly the hooks\' cwd should be the directory where they are situated. We test this by trying to find $uniquish_file. $ touch .dotfiles/$uniquish_file > mkdir -p .dotfiles/hooks/pre-down .dotfiles/hooks/post-down > touch .dotfiles/hooks/pre-down/00-test.sh .dotfiles/hooks/post-down/00-test.sh > chmod +x .dotfiles/hooks/pre-down/00-test.sh .dotfiles/hooks/post-down/00-test.sh $ echo "echo ../../${uniquish_file_prefix}* > /tmp/test-$uuid" > .dotfiles/hooks/pre-down/00-test.sh > echo "cat /tmp/test-$uuid; rm /tmp/test-$uuid" > .dotfiles/hooks/post-down/00-test.sh $ rcdn ../../test-hooks-run-in-situ-5b811e03-5977-40e6-80ef-dd6c35013e56 Ensure that hooks run when output of lsrc is non-empty $ touch .dotfiles/testrc > rcup > rcdn ../../test-hooks-run-in-situ-5b811e03-5977-40e6-80ef-dd6c35013e56 rcm-1.3.4/test/rcdn-hooks.t000066400000000000000000000007621372226550100155230ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Pre-down and post-down hooks should run by default $ mkdir -p .dotfiles/hooks > touch .dotfiles/hooks/pre-down .dotfiles/hooks/post-down > chmod +x .dotfiles/hooks/pre-down .dotfiles/hooks/post-down $ echo 'echo "example" > /tmp/test' > .dotfiles/hooks/pre-down > echo 'cat /tmp/test; rm /tmp/test' > .dotfiles/hooks/post-down $ rcdn example Ensure that hooks run when output of lsrc is non-empty $ touch .dotfiles/testrc > rcup > rcdn example rcm-1.3.4/test/rcrc-custom.t000066400000000000000000000006251372226550100157130ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" mkrc should accept a custom rcrc $ touch .example > mkdir .other-dotfiles $ echo 'DOTFILES_DIRS="$HOME/.other-dotfiles"' > alt-rcrc $ RCRC=./alt-rcrc mkrc -v .example Moving... '*/.example' -> '*/.other-dotfiles/example' (glob) Linking... '*/.other-dotfiles/example' -> '*/.example' (glob) $ assert_linked "$HOME/.example" "$HOME/.other-dotfiles/example" rcm-1.3.4/test/rcrc-hostname.t000066400000000000000000000012541372226550100162160ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" The hostname can be set in ~/.rcrc $ touch .dotfiles/example > mkdir .dotfiles/host-$(hostname) > touch .dotfiles/host-$(hostname)/h-example > mkdir .dotfiles/host-eggplant_firetruck > touch .dotfiles/host-eggplant_firetruck/nh-example > mkdir .dotfiles/host-haircut_hammer > touch .dotfiles/host-haircut_hammer/nh-example $ echo 'HOSTNAME="eggplant_firetruck"' > $HOME/.rcrc $ lsrc /*/.nh-example:/*/.dotfiles/host-eggplant_firetruck/nh-example (glob) /*/.example:/*/.dotfiles/example (glob) $ lsrc -B haircut_hammer /*/.nh-example:/*/.dotfiles/host-haircut_hammer/nh-example (glob) /*/.example:/*/.dotfiles/example (glob) rcm-1.3.4/test/rcrc-tilde.t000066400000000000000000000010111372226550100154700ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" rcrc should accept a DOTFILES_DIR with a ~ instead of $HOME $ mkdir ~/.other-dotfiles > touch ~/.other-dotfiles/o-example $ echo 'DOTFILES_DIRS="~/.other-dotfiles"' > alt-rcrc $ RCRC=./alt-rcrc lsrc /*/.o-example:/*/.other-dotfiles/o-example (glob) rcrc should run hooks with ~ instead of $HOME $ mkdir ~/.other-dotfiles/hooks -p > printf "#!/bin/sh\necho 'ran'\n" > ~/.other-dotfiles/hooks/post-up > chmod +x ~/.other-dotfiles/hooks/post-up > RCRC=./alt-rcrc rcup ran rcm-1.3.4/test/rcrc.t000066400000000000000000000006321372226550100144010ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Information should be read from ~/.rcrc by default $ touch .example > mkdir .other-dotfiles $ echo 'DOTFILES_DIRS="$HOME/.other-dotfiles"' > $HOME/.rcrc $ mkrc -v .example Moving... '*/.example' -> '*/.other-dotfiles/example' (glob) Linking... '*/.other-dotfiles/example' -> '*/.example' (glob) $ assert_linked "$HOME/.example" "$HOME/.other-dotfiles/example" rcm-1.3.4/test/rcup-hooks-run-in-order.t000066400000000000000000000017641372226550100200700ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Pre-up hooks should run in order according to their name $ mkdir -p .dotfiles/hooks/pre-up .dotfiles/hooks/post-up > printf "#!/bin/sh\necho '1'\n" > .dotfiles/hooks/pre-up/00-test.sh > printf "#!/bin/sh\necho '2'\n" > .dotfiles/hooks/pre-up/01-test.sh > printf "#!/bin/sh\necho '3'\n" > .dotfiles/hooks/pre-up/02-test.sh > printf "#!/bin/sh\necho '4'\n" > .dotfiles/hooks/post-up/00-test.sh > printf "#!/bin/sh\necho '5'\n" > .dotfiles/hooks/post-up/01-test.sh > printf "#!/bin/sh\necho '6'\n" > .dotfiles/hooks/post-up/02-test.sh $ chmod +x .dotfiles/hooks/pre-up/00-test.sh > chmod +x .dotfiles/hooks/pre-up/01-test.sh > chmod +x .dotfiles/hooks/pre-up/02-test.sh > chmod +x .dotfiles/hooks/post-up/00-test.sh > chmod +x .dotfiles/hooks/post-up/01-test.sh > chmod +x .dotfiles/hooks/post-up/02-test.sh $ rcup 1 2 3 4 5 6 Ensure that hooks run when output of lsrc is non-empty $ touch .dotfiles/testrc > rcup 1 2 3 4 5 6 rcm-1.3.4/test/rcup-hooks-run-in-situ.t000066400000000000000000000022741372226550100177360ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Use a pre-generated UUID in a filename to make sure the filename is unique to this test and also that the pre-up hook has found the right directory having found this file. $ uniquish_file_prefix='test-hooks-run-in-situ-' > uuid='820a557b-1acb-4e86-8c5b-feb2536b5777' > uniquish_file=${uniquish_file_prefix}${uuid} Pre-up and post-up hooks should run by default. More importantly the hooks\' cwd should be the directory where they are situated. We test this by trying to find $uniquish_file. $ touch .dotfiles/$uniquish_file > mkdir -p .dotfiles/hooks/pre-up .dotfiles/hooks/post-up > touch .dotfiles/hooks/pre-up/00-test.sh .dotfiles/hooks/post-up/00-test.sh > chmod +x .dotfiles/hooks/pre-up/00-test.sh .dotfiles/hooks/post-up/00-test.sh $ echo "echo ../../${uniquish_file_prefix}* > /tmp/test-$uuid" > .dotfiles/hooks/pre-up/00-test.sh > echo "cat /tmp/test-$uuid; rm /tmp/test-$uuid" > .dotfiles/hooks/post-up/00-test.sh $ rcup ../../test-hooks-run-in-situ-820a557b-1acb-4e86-8c5b-feb2536b5777 Ensure that hooks run when output of lsrc is non-empty $ touch .dotfiles/testrc > rcup ../../test-hooks-run-in-situ-820a557b-1acb-4e86-8c5b-feb2536b5777 rcm-1.3.4/test/rcup-hooks.t000066400000000000000000000011551372226550100155430ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Pre-up and post-up hooks should run by default $ mkdir -p .dotfiles/hooks > touch .dotfiles/hooks/pre-up .dotfiles/hooks/post-up > chmod +x .dotfiles/hooks/pre-up .dotfiles/hooks/post-up $ echo 'echo "example" > /tmp/test' > .dotfiles/hooks/pre-up > echo 'cat /tmp/test; rm /tmp/test' > .dotfiles/hooks/post-up $ /usr/bin/env -i PATH="$PATH" HOME="$HOME" RCRC="$RCRC" RCM_LIB="$RCM_LIB" rcup example Ensure that hooks run when output of lsrc is non-empty $ touch .dotfiles/testrc $ /usr/bin/env -i PATH="$PATH" HOME="$HOME" RCRC="$RCRC" RCM_LIB="$RCM_LIB" rcup example rcm-1.3.4/test/rcup-hostname.t000066400000000000000000000007311372226550100162350ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should create symlinks for files and directories in the hostname $ touch .dotfiles/example > mkdir .dotfiles/host-awesome_host/ > touch .dotfiles/host-awesome_host/example2 > mkdir .dotfiles/host-$(hostname)/ > touch .dotfiles/host-$(hostname)/example3 $ rcup -B awesome_host > /dev/null $ assert_linked "$HOME/.example" "$HOME/.dotfiles/example" $ assert_linked "$HOME/.example2" "$HOME/.dotfiles/host-awesome_host/example2" rcm-1.3.4/test/rcup-link-files.t000066400000000000000000000007541372226550100164610ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should create symlinks for files and directories $ touch .dotfiles/example > mkdir .dotfiles/nested/ > touch .dotfiles/nested/example > mkdir .dotfiles/nested/deeply > touch .dotfiles/nested/deeply/example $ rcup >/dev/null $ assert_linked "$HOME/.example" "$HOME/.dotfiles/example" $ assert_linked "$HOME/.nested/example" "$HOME/.dotfiles/nested/example" $ assert_linked "$HOME/.nested/deeply/example" "$HOME/.dotfiles/nested/deeply/example" rcm-1.3.4/test/rcup-spaces.t000066400000000000000000000004211372226550100156710ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Should create symlinks for files in directories with whitespace in their names $ mkdir .dotfiles/sub\ dir > touch .dotfiles/sub\ dir/example $ rcup >/dev/null $ assert_linked "$HOME/.sub dir/example" "$HOME/.dotfiles/sub dir/example" rcm-1.3.4/test/rcup-standalone.t000066400000000000000000000027311372226550100165510ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" -g generates a script $ mkdir -p .dotfiles/eggplant_firetruck/lampshade > touch .dotfiles/eggplant_firetruck/lampshade/bottle $ rcup -g #!/bin/sh # # Usage: # # sh install.sh # # Environment variables: VERBOSE, CP, LN, MKDIR, RM, DIRNAME. # # env VERBOSE=1 sh install.sh # # DO NOT EDIT THIS FILE # # This file is generated by rcm(7) as: # # rcup -g # # To update it, re-run the above command. # : ${VERBOSE:=0} : ${CP:=/bin/cp} : ${LN:=/bin/ln} : ${MKDIR:=/bin/mkdir} : ${RM:=/bin/rm} : ${DIRNAME:=/usr/bin/dirname} verbose() { if [ "$VERBOSE" -gt 0 ]; then echo "$@" fi } handle_file_cp() { if [ -e "$2" ]; then printf "%s " "overwrite $2? [yN]" read overwrite case "$overwrite" in y) $RM -rf "$2" ;; *) echo "skipping $2" return ;; esac fi verbose "'$1' -> '$2'" $MKDIR -p "$($DIRNAME "$2")" $CP -R "$1" "$2" } handle_file_ln() { if [ -e "$2" ]; then printf "%s " "overwrite $2? [yN]" read overwrite case "$overwrite" in y) $RM -rf "$2" ;; *) echo "skipping $2" return ;; esac fi verbose "'$1' -> '$2'" $MKDIR -p "$($DIRNAME "$2")" $LN -sf "$1" "$2" } handle_file_ln "*eggplant_firetruck/lampshade/bottle" "*.eggplant_firetruck/lampshade/bottle" (glob) rcm-1.3.4/test/rcup-symlink-dirs.t000066400000000000000000000005711372226550100170460ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Overrides SYMLINK_DIRS with -s $ mkdir -p .dotfiles/eggplant_firetruck/lampshade > touch .dotfiles/eggplant_firetruck/lampshade/bottle $ echo 'SYMLINK_DIRS="eggplant_firetruck"' > $HOME/.rcrc $ rcup -s eggplant_firetruck $ assert_linked "$HOME/.eggplant_firetruck/lampshade/bottle" "$HOME/.dotfiles/eggplant_firetruck/lampshade/bottle" rcm-1.3.4/test/rcup-symlink-existing.t000066400000000000000000000003421372226550100177330ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" Symlinks files even if they are identical $ mkdir -p .dotfiles > echo find-me > "$HOME/.door" > echo find-me > .dotfiles/door $ rcup > assert_linked "$HOME/.door" "$HOME/.dotfiles/door" rcm-1.3.4/test/rcup-usage.t000066400000000000000000000010631372226550100155220ustar00rootroot00000000000000 $ . "$TESTDIR/helper.sh" -h should output usage information and exit 0 $ rcup -h Usage: rcup [-CfhiKkqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT] see rcup(1) and rcm(7) for more details Unsupported options should output usage information and exit EX_USAGE $ rcup --version Usage: rcup [-CfhiKkqVv] [-B HOSTNAME] [-d DOT_DIR] [-I EXCL_PAT] [-S EXCL_PAT] [-s EXCL_PAT] [-t TAG] [-U EXCL_PAT] [-u EXCL_PAT] [-x EXCL_PAT] see rcup(1) and rcm(7) for more details [64]