feat: Add prefix: 'string'
option to linking when glob: true
.
Allows one to store files in a directory or git-repo without the leading `.`, as in: ``` dotconf: ├── README.md ├── bin │ ├── dotbot │ ├── look │ ├── pbfile │ └── ... ├── dot │ ├── bashrc │ ├── gitconfig │ ├── gitignore │ ├── gorc │ ├── login │ ├── ... │ ├── zshrc │ └── zshenv ``` Can take a many-line dotbot.yml listing **each** file in `dotconf/dot`, reducing it to five lines: ``` - link: ~/: path: dotconf/dot/* glob: true prefix: '.' ``` FIXES: #259
This commit is contained in:
parent
aa9335089b
commit
6c044208fa
3 changed files with 45 additions and 7 deletions
24
README.md
24
README.md
|
@ -181,16 +181,22 @@ mapped to extended configuration dictionaries.
|
||||||
| `force` | Force removes the old target, file or folder, and forces a new link (default: false) |
|
| `force` | Force removes the old target, file or folder, and forces a new link (default: false) |
|
||||||
| `relative` | Use a relative path to the source when creating the symlink (default: false, absolute links) |
|
| `relative` | Use a relative path to the source when creating the symlink (default: false, absolute links) |
|
||||||
| `canonicalize` | Resolve any symbolic links encountered in the source to symlink to the canonical path (default: true, real paths) |
|
| `canonicalize` | Resolve any symbolic links encountered in the source to symlink to the canonical path (default: true, real paths) |
|
||||||
| `glob` | Treat a `*` character as a wildcard, and perform link operations on all of those matches (default: false) |
|
|
||||||
| `if` | Execute this in your `$SHELL` and only link if it is successful. |
|
| `if` | Execute this in your `$SHELL` and only link if it is successful. |
|
||||||
| `ignore-missing` | Do not fail if the source is missing and create the link anyway (default: false) |
|
| `ignore-missing` | Do not fail if the source is missing and create the link anyway (default: false) |
|
||||||
| `exclude` | Array of paths to remove from glob matches. Uses same syntax as `path`. Ignored if `glob` is `false`. (default: empty, keep all matches) |
|
| `glob` | Treat `path` as a glob pattern, expanding patterns referenced below, linking all *files** matched. (default: false) |
|
||||||
|
| `exclude` | Array of glob patterns to remove from glob matches. Uses same syntax as `path`. Ignored if `glob` is `false`. (default: empty, keep all matches) |
|
||||||
|
| `prefix` | Prepend prefix prefix to basename of each file when linked, when `glob` is `true`. (default: '') |
|
||||||
|
|
||||||
Dotbot uses [glob.glob](https://docs.python.org/3/library/glob.html#glob.glob)
|
When `glob: True`, Dotbot uses [glob.glob](https://docs.python.org/3/library/glob.html#glob.glob) to resolve glob paths, expanding Unix shell-style wildcards, which are **not** the same as regular expressions; Only the following are expanded:
|
||||||
to resolve glob paths. However, due to its design, using a glob path such as
|
|
||||||
`config/*` for example, will not match items that begin with `.`. To
|
| Pattern | Meaning |
|
||||||
specifically capture items that begin with `.`, you will need to use a path
|
|:---------|:-------------------------------------------------------|
|
||||||
like this: `config/.*`.
|
| `*` | matches anything |
|
||||||
|
| `?` | matches any single character |
|
||||||
|
| `[seq]` | matches any character in `seq` |
|
||||||
|
| `[!seq]` | matches any character not in `seq` |
|
||||||
|
|
||||||
|
However, due to the design of `glob.glob`, using a glob pattern such as `config/*`, will **not** match items that being with `.`. To specifically capture items that being with `.`, you will need to include the `.` in the pattern, like this: `config/.*`.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
|
@ -209,6 +215,10 @@ like this: `config/.*`.
|
||||||
~/.hammerspoon:
|
~/.hammerspoon:
|
||||||
if: '[ `uname` = Darwin ]'
|
if: '[ `uname` = Darwin ]'
|
||||||
path: hammerspoon
|
path: hammerspoon
|
||||||
|
~/:
|
||||||
|
glob: true
|
||||||
|
path: dotconf/*
|
||||||
|
prefix: '.'
|
||||||
```
|
```
|
||||||
|
|
||||||
If the source location is omitted or set to `null`, Dotbot will use the
|
If the source location is omitted or set to `null`, Dotbot will use the
|
||||||
|
|
|
@ -33,6 +33,7 @@ class Link(dotbot.Plugin):
|
||||||
relink = defaults.get('relink', False)
|
relink = defaults.get('relink', False)
|
||||||
create = defaults.get('create', False)
|
create = defaults.get('create', False)
|
||||||
use_glob = defaults.get('glob', False)
|
use_glob = defaults.get('glob', False)
|
||||||
|
base_prefix = defaults.get('prefix', '')
|
||||||
test = defaults.get('if', None)
|
test = defaults.get('if', None)
|
||||||
ignore_missing = defaults.get('ignore-missing', False)
|
ignore_missing = defaults.get('ignore-missing', False)
|
||||||
exclude_paths = defaults.get('exclude', [])
|
exclude_paths = defaults.get('exclude', [])
|
||||||
|
@ -45,6 +46,7 @@ class Link(dotbot.Plugin):
|
||||||
relink = source.get('relink', relink)
|
relink = source.get('relink', relink)
|
||||||
create = source.get('create', create)
|
create = source.get('create', create)
|
||||||
use_glob = source.get('glob', use_glob)
|
use_glob = source.get('glob', use_glob)
|
||||||
|
base_prefix = source.get('prefix', base_prefix)
|
||||||
ignore_missing = source.get('ignore-missing', ignore_missing)
|
ignore_missing = source.get('ignore-missing', ignore_missing)
|
||||||
exclude_paths = source.get('exclude', exclude_paths)
|
exclude_paths = source.get('exclude', exclude_paths)
|
||||||
path = self._default_source(destination, source.get('path'))
|
path = self._default_source(destination, source.get('path'))
|
||||||
|
@ -80,6 +82,9 @@ class Link(dotbot.Plugin):
|
||||||
# Find common dirname between pattern and the item:
|
# Find common dirname between pattern and the item:
|
||||||
glob_dirname = os.path.dirname(os.path.commonprefix([path, glob_full_item]))
|
glob_dirname = os.path.dirname(os.path.commonprefix([path, glob_full_item]))
|
||||||
glob_item = (glob_full_item if len(glob_dirname) == 0 else glob_full_item[len(glob_dirname) + 1:])
|
glob_item = (glob_full_item if len(glob_dirname) == 0 else glob_full_item[len(glob_dirname) + 1:])
|
||||||
|
# Add prefix to basepath, if provided
|
||||||
|
if base_prefix:
|
||||||
|
glob_item = base_prefix + glob_item
|
||||||
# where is it going
|
# where is it going
|
||||||
glob_link_destination = os.path.join(destination, glob_item)
|
glob_link_destination = os.path.join(destination, glob_item)
|
||||||
if create:
|
if create:
|
||||||
|
|
23
test/tests/link-prefix.bash
Normal file
23
test/tests/link-prefix.bash
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
test_description='link prefix'
|
||||||
|
. '../test-lib.bash'
|
||||||
|
|
||||||
|
test_expect_success 'setup' '
|
||||||
|
mkdir ${DOTFILES}/conf &&
|
||||||
|
echo "apple" > ${DOTFILES}/conf/a &&
|
||||||
|
echo "banana" > ${DOTFILES}/conf/b &&
|
||||||
|
echo "cherry" > ${DOTFILES}/conf/c
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'test glob w/ prefix' '
|
||||||
|
run_dotbot -v <<EOF
|
||||||
|
- link:
|
||||||
|
~/:
|
||||||
|
glob: true
|
||||||
|
path: conf/*
|
||||||
|
prefix: '.'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
grep "apple" ~/.a &&
|
||||||
|
grep "banana" ~/.b &&
|
||||||
|
grep "cherry" ~/.c
|
||||||
|
'
|
Loading…
Reference in a new issue