mirror of
https://github.com/deadc0de6/dotdrop.git
synced 2026-02-12 18:45:13 +00:00
Merge branch 'master' of https://github.com/deadc0de6/dotdrop
This commit is contained in:
123
README.md
123
README.md
@@ -83,6 +83,7 @@ why [dotdrop](https://github.com/deadc0de6/dotdrop) rocks.
|
|||||||
* [Available variables](#available-variables)
|
* [Available variables](#available-variables)
|
||||||
* [Available methods](#available-methods)
|
* [Available methods](#available-methods)
|
||||||
* [Dynamic dotfile paths](#dynamic-dotfile-paths)
|
* [Dynamic dotfile paths](#dynamic-dotfile-paths)
|
||||||
|
* [Dynamic actions](#dynamic-actions)
|
||||||
* [Dotdrop header](#dotdrop-header)
|
* [Dotdrop header](#dotdrop-header)
|
||||||
* [Example](#example)
|
* [Example](#example)
|
||||||
* [User tricks](#user-tricks)
|
* [User tricks](#user-tricks)
|
||||||
@@ -198,7 +199,7 @@ $ dotdrop install
|
|||||||
|
|
||||||
## Compare dotfiles
|
## Compare dotfiles
|
||||||
|
|
||||||
Compare local dotfiles with dotdrop's defined ones:
|
Compare local dotfiles with the ones stored in dotdrop:
|
||||||
```bash
|
```bash
|
||||||
$ dotdrop compare
|
$ dotdrop compare
|
||||||
```
|
```
|
||||||
@@ -209,8 +210,7 @@ options to diff using the `-o` switch.
|
|||||||
It is possible to add patterns to ignore when using `compare` for example
|
It is possible to add patterns to ignore when using `compare` for example
|
||||||
when a directory is managed by dotdrop and might contain temporary files
|
when a directory is managed by dotdrop and might contain temporary files
|
||||||
that don't need to appear in the output of compare.
|
that don't need to appear in the output of compare.
|
||||||
|
Either use the command line switch `-i --ignore` or add a line in the dotfile
|
||||||
Either use the command line switch `-i --ignore` or add an entry in the dotfile
|
|
||||||
directly in the `cmpignore` entry (see [Config](#config)).
|
directly in the `cmpignore` entry (see [Config](#config)).
|
||||||
The ignore pattern must follow Unix shell-style wildcards like for example `*/path/file`.
|
The ignore pattern must follow Unix shell-style wildcards like for example `*/path/file`.
|
||||||
Make sure to quote those when using wildcards in the config file.
|
Make sure to quote those when using wildcards in the config file.
|
||||||
@@ -235,8 +235,8 @@ with the option `longkey` (per default to *false*).
|
|||||||
|
|
||||||
Two formats are available:
|
Two formats are available:
|
||||||
|
|
||||||
* short format (default): take the shortest unique path
|
* *short format* (default): take the shortest unique path
|
||||||
* long format: take the full path
|
* *long format*: take the full path
|
||||||
|
|
||||||
For example `~/.config/awesome/rc.lua` gives
|
For example `~/.config/awesome/rc.lua` gives
|
||||||
|
|
||||||
@@ -273,20 +273,24 @@ $ dotdrop listfiles --profile=<some-profile>
|
|||||||
For example:
|
For example:
|
||||||
```
|
```
|
||||||
Dotfile(s) for profile "some-profile":
|
Dotfile(s) for profile "some-profile":
|
||||||
|
f_vimrc (file: "vimrc", link: nolink)
|
||||||
f_vimrc (file: "vimrc", link: False)
|
|
||||||
-> ~/.vimrc
|
-> ~/.vimrc
|
||||||
f_dunstrc (file: "config/dunst/dunstrc", link: False)
|
f_dunstrc (file: "config/dunst/dunstrc", link: nolink)
|
||||||
-> ~/.config/dunst/dunstrc
|
-> ~/.config/dunst/dunstrc
|
||||||
```
|
```
|
||||||
|
|
||||||
By using the `-T --template` switch, only the dotfiles that
|
By using the `-T --template` switch, only the dotfiles that
|
||||||
are using jinja2 directives are listed.
|
are using [jinja2](http://jinja.pocoo.org/) directives are listed.
|
||||||
|
|
||||||
It is also possible to list all files related to each dotfile entries
|
It is also possible to list all files related to each dotfile entries
|
||||||
by invoking the `detail` command, for example:
|
by invoking the `detail` command, for example:
|
||||||
```bash
|
```bash
|
||||||
$ dotdrop detail
|
$ dotdrop detail
|
||||||
|
dotfiles details for profile "some-profile":
|
||||||
|
f_tmux.conf (dst: "~/.tmux.conf", link: nolink)
|
||||||
|
-> /home/user/dotfiles/tmux.conf (template:no)
|
||||||
|
f_vimrc (dst: "~/.vimrc", link: nolink)
|
||||||
|
-> /home/user/dotfiles/vimrc (template:no)
|
||||||
```
|
```
|
||||||
|
|
||||||
This is especially useful when the dotfile entry is a directory
|
This is especially useful when the dotfile entry is a directory
|
||||||
@@ -474,7 +478,7 @@ $ dotdrop update ~/.vimrc
|
|||||||
$ dotdrop update --key f_vimrc
|
$ dotdrop update --key f_vimrc
|
||||||
```
|
```
|
||||||
|
|
||||||
It is possible to ignore files to update using unix pattern by providing those
|
It is possible to ignore files to update using unix patterns by providing those
|
||||||
either through the switch `-i --ignore` or as part of the dotfile under the
|
either through the switch `-i --ignore` or as part of the dotfile under the
|
||||||
key `upignore` (see [Config](#config)).
|
key `upignore` (see [Config](#config)).
|
||||||
The ignore pattern must follow Unix shell-style wildcards like for example `*/path/file`.
|
The ignore pattern must follow Unix shell-style wildcards like for example `*/path/file`.
|
||||||
@@ -539,64 +543,64 @@ Dotdrop offers two ways to symlink dotfiles. The first simply links `dst` to
|
|||||||
`src`. To enable it, simply set `link: true` under the dotfile entry in the
|
`src`. To enable it, simply set `link: true` under the dotfile entry in the
|
||||||
config file.
|
config file.
|
||||||
|
|
||||||
The second symlink method is a little more complicated. It creates a symlink in
|
The second symlink method allows to have every files/directories under `src` to
|
||||||
`dst` for every file/directory in `src`.
|
be symlinked in `dst`. It is enabled by setting `link_children: true`.
|
||||||
|
|
||||||
### Why would I use `link_children`?
|
### Link children
|
||||||
|
|
||||||
This feature can be very useful for dotfiles such as vim where you may not want
|
This feature can be very useful for dotfiles when you don't want the entire
|
||||||
plugins cluttering your dotfiles repository. First, the simpler `link: true` is
|
directory to be symlink but still want to keep a clean config files (with a
|
||||||
shown for comparison. With the `config.yaml` entry shown below, `~/.vim` gets
|
limited number of entries).
|
||||||
symlinked to `~/.dotfiles/vim/`. This means that using vim will now pollute the
|
|
||||||
dotfiles repository. `plugged` (if using
|
|
||||||
[vim-plug](https://github.com/junegunn/vim-plug)), `spell`, and `swap`
|
|
||||||
directories will appear `~/.dotfiles/vim/`.
|
|
||||||
|
|
||||||
```yml
|
A good example of its use is when managing `~/.vim` with dotdrop.
|
||||||
|
|
||||||
|
Here's what it looks like when using the basic `link: true`. The top
|
||||||
|
directory `~/.vim` is symlinked to the *dotpath* location (here `~/.dotfiles/vim`):
|
||||||
|
```yaml
|
||||||
vim:
|
vim:
|
||||||
dst: ~/.vim/
|
dst: ~/.vim/
|
||||||
src: ./vim/
|
src: vim
|
||||||
actions:
|
|
||||||
- vim-plug-install
|
|
||||||
- vim-plug
|
|
||||||
link: true
|
link: true
|
||||||
```
|
```
|
||||||
```
|
|
||||||
|
```bash
|
||||||
$ readlink ~/.vim
|
$ readlink ~/.vim
|
||||||
~/.dotfiles/vim/
|
~/.dotfiles/vim/
|
||||||
$ ls ~/.dotfiles/vim/
|
$ ls ~/.dotfiles/vim/
|
||||||
after autoload plugged plugin snippets spell swap vimrc
|
after autoload plugged plugin snippets spell swap vimrc
|
||||||
```
|
```
|
||||||
Let's say we just want to store `after`, `plugin`, `snippets`, and `vimrc` in
|
|
||||||
our `~/.dotfiles` repository. This is where `link_children` comes in. Using the
|
As a result, all files under `~/.vim` will be managed by
|
||||||
configuration below, `~/.vim/` is a normal directory and only the children of
|
dotdrop (including unwanted directories like `spell`, `swap`, etc).
|
||||||
`~/.dotfiles/vim` are symlinked into it.
|
|
||||||
```yml
|
A cleaner solution is to use `link_children` which allows to only symlink specific
|
||||||
|
files under the dotfile directory. Let's say only `after`, `plugin`, `snippets`, and `vimrc`
|
||||||
|
need to be managed in dotdrop. `~/.vim` is imported in dotdrop, cleaned off all unwanted
|
||||||
|
files and directories and then the `link_children` entry is set to `true` in the config file.
|
||||||
|
|
||||||
|
Now all children of the `vim` dotfile's directory in the *dotpath* will be symlinked under `~/.vim/`
|
||||||
|
without affecting the rest of the local files, keeping the config file clean
|
||||||
|
and all unwanted files only on the local system.
|
||||||
|
```yaml
|
||||||
vim:
|
vim:
|
||||||
dst: ~/.vim/
|
dst: ~/.vim/
|
||||||
src: ./vim/
|
src: vim
|
||||||
actions:
|
|
||||||
- vim-plug-install
|
|
||||||
- vim-plug
|
|
||||||
link_children: true
|
link_children: true
|
||||||
```
|
```
|
||||||
|
|
||||||
As can be seen below, `~/.vim/` is a normal directory, not a symlink. Also, the
|
```bash
|
||||||
files/directories `after`, `plugin`, `snippets`, and `vimrc` are symlinked to
|
|
||||||
`~/.dotfiles/vim/`.
|
|
||||||
```
|
|
||||||
$ readlink -f ~/.vim
|
$ readlink -f ~/.vim
|
||||||
~/.vim
|
~/.vim
|
||||||
$ tree -L 1 ~/.vim
|
$ tree -L 1 ~/.vim
|
||||||
~/.vim
|
~/.vim
|
||||||
├── after -> /.dotfiles/./vim/after
|
├── after -> ~/.dotfiles/vim/after
|
||||||
├── autoload
|
├── autoload
|
||||||
├── plugged
|
├── plugged
|
||||||
├── plugin -> /.dotfiles/./vim/plugin
|
├── plugin -> ~/.dotfiles/vim/plugin
|
||||||
├── snippets -> /.dotfiles/./vim/snippets
|
├── snippets -> ~/.dotfiles/vim/snippets
|
||||||
├── spell
|
├── spell
|
||||||
├── swap
|
├── swap
|
||||||
└── vimrc -> /.dotfiles/./vim/vimrc
|
└── vimrc -> ~/.dotfiles/vim/vimrc
|
||||||
```
|
```
|
||||||
|
|
||||||
### Templating symlinked dotfiles
|
### Templating symlinked dotfiles
|
||||||
@@ -614,7 +618,7 @@ For example
|
|||||||
/home/user/.xyz -> /home/user/.config/dotdrop/.xyz
|
/home/user/.xyz -> /home/user/.config/dotdrop/.xyz
|
||||||
|
|
||||||
# without template
|
# without template
|
||||||
/home/user/.xyz -> /home/user/dotdrop/dotfiles/xyz
|
/home/user/.xyz -> /home/user/dotfiles/xyz
|
||||||
```
|
```
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
@@ -642,6 +646,7 @@ the following entries:
|
|||||||
* `dst`: where this dotfile needs to be deployed (can use `variables` and `dynvariables`, make sure to quote).
|
* `dst`: where this dotfile needs to be deployed (can use `variables` and `dynvariables`, make sure to quote).
|
||||||
* `src`: dotfile path within the `dotpath` (can use `variables` and `dynvariables`, make sure to quote).
|
* `src`: dotfile path within the `dotpath` (can use `variables` and `dynvariables`, make sure to quote).
|
||||||
* `link`: if true dotdrop will create a symlink instead of copying (default *false*).
|
* `link`: if true dotdrop will create a symlink instead of copying (default *false*).
|
||||||
|
* `link_children`: if true dotdrop will create a symlink for each file under `src` (default *false*).
|
||||||
* `cmpignore`: list of pattern to ignore when comparing (enclose in quotes when using wildcards).
|
* `cmpignore`: list of pattern to ignore when comparing (enclose in quotes when using wildcards).
|
||||||
* `upignore`: list of pattern to ignore when updating (enclose in quotes when using wildcards).
|
* `upignore`: list of pattern to ignore when updating (enclose in quotes when using wildcards).
|
||||||
* `actions`: list of action keys that need to be defined in the **actions** entry below.
|
* `actions`: list of action keys that need to be defined in the **actions** entry below.
|
||||||
@@ -654,7 +659,7 @@ the following entries:
|
|||||||
dst: <where-this-file-is-deployed>
|
dst: <where-this-file-is-deployed>
|
||||||
src: <filename-within-the-dotpath>
|
src: <filename-within-the-dotpath>
|
||||||
# Optional
|
# Optional
|
||||||
link: <true|false>
|
(link|link_children): <true|false>
|
||||||
ignoreempty: <true|false>
|
ignoreempty: <true|false>
|
||||||
cmpignore:
|
cmpignore:
|
||||||
- "<ignore-pattern>"
|
- "<ignore-pattern>"
|
||||||
@@ -795,7 +800,7 @@ Following template variables are available:
|
|||||||
* interpreted variables (see [Interpreted variables](#interpreted-variables))
|
* interpreted variables (see [Interpreted variables](#interpreted-variables))
|
||||||
|
|
||||||
All variables are recursively evaluated what means that
|
All variables are recursively evaluated what means that
|
||||||
a config similar to:
|
a config like the below
|
||||||
```yaml
|
```yaml
|
||||||
variables:
|
variables:
|
||||||
var1: "var1"
|
var1: "var1"
|
||||||
@@ -809,7 +814,7 @@ dynvariables:
|
|||||||
dvar4: "echo {{@@ var3 @@}}"
|
dvar4: "echo {{@@ var3 @@}}"
|
||||||
```
|
```
|
||||||
|
|
||||||
will result in
|
will result in the following available variables
|
||||||
* var3: `var1 var2 var3`
|
* var3: `var1 var2 var3`
|
||||||
* dvar3: `dvar1 dvar2 dvar3`
|
* dvar3: `dvar1 dvar2 dvar3`
|
||||||
* var4: `echo var1 var2 var3`
|
* var4: `echo var1 var2 var3`
|
||||||
@@ -943,6 +948,24 @@ profiles:
|
|||||||
|
|
||||||
Make sure to quote the path in the config file.
|
Make sure to quote the path in the config file.
|
||||||
|
|
||||||
|
## Dynamic actions
|
||||||
|
|
||||||
|
Variables (`variables` and `dynvariables`) can be used
|
||||||
|
in actions for more advanced use-cases:
|
||||||
|
|
||||||
|
For example
|
||||||
|
```yaml
|
||||||
|
dynvariables:
|
||||||
|
trizen_itself_available: (command -v trizen>/dev/null || cd /tmp; git clone https://aur.archlinux.org/trizen.git; cd trizen; makepkg -si)
|
||||||
|
trizen_package_install: {{@@ trizen_itself_available @@}} && trizen -S --needed
|
||||||
|
|
||||||
|
actions:
|
||||||
|
trizen_install: {{@@ trizen_package_install @@}} {0}
|
||||||
|
pre:
|
||||||
|
pip_install: {{@@ trizen_package_install @@}} python-pip && pip install {0}
|
||||||
|
yarn_install: {{@@ trizen_package_install @@}} yarn && yarn global add {0}
|
||||||
|
```
|
||||||
|
|
||||||
## Dotdrop header
|
## Dotdrop header
|
||||||
|
|
||||||
Dotdrop is able to insert a header in the generated dotfiles. This allows
|
Dotdrop is able to insert a header in the generated dotfiles. This allows
|
||||||
@@ -953,13 +976,13 @@ Here's what it looks like:
|
|||||||
This dotfile is managed using dotdrop
|
This dotfile is managed using dotdrop
|
||||||
```
|
```
|
||||||
|
|
||||||
The header can be automatically added using jinja2 directive:
|
The header can be automatically added using [jinja2](http://jinja.pocoo.org/) directive:
|
||||||
```
|
```
|
||||||
{{@@ header() @@}}
|
{{@@ header() @@}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Properly commenting the header in templates is the responsability of the user
|
Properly commenting the header in templates is the responsability of the user
|
||||||
as jinja2 has no way of knowing what is the proper char(s) used for comments.
|
as [jinja2](http://jinja.pocoo.org/) has no way of knowing what is the proper char(s) used for comments.
|
||||||
Either prepend the directive with the commenting char(s) used in the dotfile (for example `# {{@@ header() @@}}`)
|
Either prepend the directive with the commenting char(s) used in the dotfile (for example `# {{@@ header() @@}}`)
|
||||||
or provide it as an argument `{{@@ header('# ') @@}}`. The result is equivalent.
|
or provide it as an argument `{{@@ header('# ') @@}}`. The result is equivalent.
|
||||||
|
|
||||||
@@ -986,7 +1009,7 @@ Dotdrop allows to store only one single *.xinitrc* but
|
|||||||
to deploy different versions depending on where it is run from.
|
to deploy different versions depending on where it is run from.
|
||||||
|
|
||||||
The following file is the dotfile stored in dotdrop containing
|
The following file is the dotfile stored in dotdrop containing
|
||||||
jinja2 directives for the deployment based on the profile used.
|
[jinja2](http://jinja.pocoo.org/) directives for the deployment based on the profile used.
|
||||||
|
|
||||||
Dotfile `<dotpath>/xinitrc`:
|
Dotfile `<dotpath>/xinitrc`:
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -119,11 +119,20 @@ class Cfg:
|
|||||||
raise ValueError('config is not valid')
|
raise ValueError('config is not valid')
|
||||||
|
|
||||||
def eval_dotfiles(self, profile, debug=False):
|
def eval_dotfiles(self, profile, debug=False):
|
||||||
"""resolve dotfiles src/dst templating for this profile"""
|
"""resolve dotfiles src/dst/actions templating for this profile"""
|
||||||
t = Templategen(variables=self.get_variables(profile, debug=debug))
|
t = Templategen(variables=self.get_variables(profile, debug=debug))
|
||||||
for d in self.get_dotfiles(profile):
|
for d in self.get_dotfiles(profile):
|
||||||
|
# src and dst path
|
||||||
d.src = t.generate_string(d.src)
|
d.src = t.generate_string(d.src)
|
||||||
d.dst = t.generate_string(d.dst)
|
d.dst = t.generate_string(d.dst)
|
||||||
|
# pre actions
|
||||||
|
if self.key_actions_pre in d.actions:
|
||||||
|
for action in d.actions[self.key_actions_pre]:
|
||||||
|
action.action = t.generate_string(action.action)
|
||||||
|
# post actions
|
||||||
|
if self.key_actions_post in d.actions:
|
||||||
|
for action in d.actions[self.key_actions_post]:
|
||||||
|
action.action = t.generate_string(action.action)
|
||||||
|
|
||||||
def _load_file(self):
|
def _load_file(self):
|
||||||
"""load the yaml file"""
|
"""load the yaml file"""
|
||||||
|
|||||||
@@ -216,15 +216,15 @@ def cmd_compare(opts, conf, tmp, focus=[], ignore=[]):
|
|||||||
def cmd_update(opts, conf, paths, iskey=False, ignore=[]):
|
def cmd_update(opts, conf, paths, iskey=False, ignore=[]):
|
||||||
"""update the dotfile(s) from path(s) or key(s)"""
|
"""update the dotfile(s) from path(s) or key(s)"""
|
||||||
ret = True
|
ret = True
|
||||||
updater = Updater(conf, opts['dotpath'], opts['dry'],
|
updater = Updater(conf, opts['dotpath'], opts['profile'],
|
||||||
opts['safe'], iskey=iskey,
|
opts['dry'], opts['safe'], iskey=iskey,
|
||||||
debug=opts['debug'], ignore=[])
|
debug=opts['debug'], ignore=[])
|
||||||
if not iskey:
|
if not iskey:
|
||||||
# update paths
|
# update paths
|
||||||
if opts['debug']:
|
if opts['debug']:
|
||||||
LOG.dbg('update by paths: {}'.format(paths))
|
LOG.dbg('update by paths: {}'.format(paths))
|
||||||
for path in paths:
|
for path in paths:
|
||||||
if not updater.update_path(path, opts['profile']):
|
if not updater.update_path(path):
|
||||||
ret = False
|
ret = False
|
||||||
else:
|
else:
|
||||||
# update keys
|
# update keys
|
||||||
@@ -235,7 +235,7 @@ def cmd_update(opts, conf, paths, iskey=False, ignore=[]):
|
|||||||
if opts['debug']:
|
if opts['debug']:
|
||||||
LOG.dbg('update by keys: {}'.format(keys))
|
LOG.dbg('update by keys: {}'.format(keys))
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if not updater.update_key(key, opts['profile']):
|
if not updater.update_key(key):
|
||||||
ret = False
|
ret = False
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@@ -332,7 +332,7 @@ def cmd_list_files(opts, conf, templateonly=False):
|
|||||||
if not Templategen.is_template(src):
|
if not Templategen.is_template(src):
|
||||||
continue
|
continue
|
||||||
LOG.log('{} (src: \"{}\", link: {})'.format(dotfile.key, dotfile.src,
|
LOG.log('{} (src: \"{}\", link: {})'.format(dotfile.key, dotfile.src,
|
||||||
dotfile.link))
|
dotfile.link.name.lower()))
|
||||||
LOG.sub('{}'.format(dotfile.dst))
|
LOG.sub('{}'.format(dotfile.dst))
|
||||||
LOG.log('')
|
LOG.log('')
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ def cmd_detail(opts, conf, keys=None):
|
|||||||
def _detail(dotpath, dotfile):
|
def _detail(dotpath, dotfile):
|
||||||
"""print details on all files under a dotfile entry"""
|
"""print details on all files under a dotfile entry"""
|
||||||
LOG.log('{} (dst: \"{}\", link: {})'.format(dotfile.key, dotfile.dst,
|
LOG.log('{} (dst: \"{}\", link: {})'.format(dotfile.key, dotfile.dst,
|
||||||
dotfile.link))
|
dotfile.link.name.lower()))
|
||||||
path = os.path.join(dotpath, os.path.expanduser(dotfile.src))
|
path = os.path.join(dotpath, os.path.expanduser(dotfile.src))
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
template = 'no'
|
template = 'no'
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class Dotfile:
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = 'key:\"{}\", src:\"{}\", dst:\"{}\", link:\"{}\"'
|
msg = 'key:\"{}\", src:\"{}\", dst:\"{}\", link:\"{}\"'
|
||||||
return msg.format(self.key, self.src, self.dst, self.link.name)
|
return msg.format(self.key, self.src, self.dst, self.link.name.lower())
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.__dict__ == other.__dict__
|
return self.__dict__ == other.__dict__
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ class Installer:
|
|||||||
if self.debug:
|
if self.debug:
|
||||||
self.log.dbg('link {} to {}'.format(src, dst))
|
self.log.dbg('link {} to {}'.format(src, dst))
|
||||||
self.action_executed = False
|
self.action_executed = False
|
||||||
src = os.path.join(self.base, os.path.expanduser(src))
|
src = os.path.normpath(os.path.join(self.base,
|
||||||
|
os.path.expanduser(src)))
|
||||||
if not os.path.exists(src):
|
if not os.path.exists(src):
|
||||||
self.log.err('source dotfile does not exist: {}'.format(src))
|
self.log.err('source dotfile does not exist: {}'.format(src))
|
||||||
return []
|
return []
|
||||||
@@ -124,8 +125,10 @@ class Installer:
|
|||||||
os.mkdir(dst)
|
os.mkdir(dst)
|
||||||
|
|
||||||
children = os.listdir(parent)
|
children = os.listdir(parent)
|
||||||
srcs = [os.path.join(parent, child) for child in children]
|
srcs = [os.path.normpath(os.path.join(parent, child))
|
||||||
dsts = [os.path.join(dst, child) for child in children]
|
for child in children]
|
||||||
|
dsts = [os.path.normpath(os.path.join(dst, child))
|
||||||
|
for child in children]
|
||||||
|
|
||||||
for i in range(len(children)):
|
for i in range(len(children)):
|
||||||
src = srcs[i]
|
src = srcs[i]
|
||||||
|
|||||||
@@ -20,10 +20,11 @@ TILD = '~'
|
|||||||
|
|
||||||
class Updater:
|
class Updater:
|
||||||
|
|
||||||
def __init__(self, conf, dotpath, dry, safe,
|
def __init__(self, conf, dotpath, profile, dry, safe,
|
||||||
iskey=False, debug=False, ignore=[]):
|
iskey=False, debug=False, ignore=[]):
|
||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.dotpath = dotpath
|
self.dotpath = dotpath
|
||||||
|
self.profile = profile
|
||||||
self.dry = dry
|
self.dry = dry
|
||||||
self.safe = safe
|
self.safe = safe
|
||||||
self.iskey = iskey
|
self.iskey = iskey
|
||||||
@@ -31,13 +32,13 @@ class Updater:
|
|||||||
self.ignore = ignore
|
self.ignore = ignore
|
||||||
self.log = Logger()
|
self.log = Logger()
|
||||||
|
|
||||||
def update_path(self, path, profile):
|
def update_path(self, path):
|
||||||
"""update the dotfile installed on path"""
|
"""update the dotfile installed on path"""
|
||||||
if not os.path.lexists(path):
|
if not os.path.lexists(path):
|
||||||
self.log.err('\"{}\" does not exist!'.format(path))
|
self.log.err('\"{}\" does not exist!'.format(path))
|
||||||
return False
|
return False
|
||||||
path = self._normalize(path)
|
path = self._normalize(path)
|
||||||
dotfile = self._get_dotfile_by_path(path, profile)
|
dotfile = self._get_dotfile_by_path(path)
|
||||||
if not dotfile:
|
if not dotfile:
|
||||||
return False
|
return False
|
||||||
path = os.path.expanduser(path)
|
path = os.path.expanduser(path)
|
||||||
@@ -45,9 +46,9 @@ class Updater:
|
|||||||
self.log.dbg('updating {} from path \"{}\"'.format(dotfile, path))
|
self.log.dbg('updating {} from path \"{}\"'.format(dotfile, path))
|
||||||
return self._update(path, dotfile)
|
return self._update(path, dotfile)
|
||||||
|
|
||||||
def update_key(self, key, profile):
|
def update_key(self, key):
|
||||||
"""update the dotfile referenced by key"""
|
"""update the dotfile referenced by key"""
|
||||||
dotfile = self._get_dotfile_by_key(key, profile)
|
dotfile = self._get_dotfile_by_key(key)
|
||||||
if not dotfile:
|
if not dotfile:
|
||||||
return False
|
return False
|
||||||
if self.debug:
|
if self.debug:
|
||||||
@@ -111,9 +112,9 @@ class Updater:
|
|||||||
path = os.path.join(TILD, path)
|
path = os.path.join(TILD, path)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def _get_dotfile_by_key(self, key, profile):
|
def _get_dotfile_by_key(self, key):
|
||||||
"""get the dotfile matching this key"""
|
"""get the dotfile matching this key"""
|
||||||
dotfiles = self.conf.get_dotfiles(profile)
|
dotfiles = self.conf.get_dotfiles(self.profile)
|
||||||
subs = [d for d in dotfiles if d.key == key]
|
subs = [d for d in dotfiles if d.key == key]
|
||||||
if not subs:
|
if not subs:
|
||||||
self.log.err('key \"{}\" not found!'.format(key))
|
self.log.err('key \"{}\" not found!'.format(key))
|
||||||
@@ -124,9 +125,9 @@ class Updater:
|
|||||||
return None
|
return None
|
||||||
return subs[0]
|
return subs[0]
|
||||||
|
|
||||||
def _get_dotfile_by_path(self, path, profile):
|
def _get_dotfile_by_path(self, path):
|
||||||
"""get the dotfile matching this path"""
|
"""get the dotfile matching this path"""
|
||||||
dotfiles = self.conf.get_dotfiles(profile)
|
dotfiles = self.conf.get_dotfiles(self.profile)
|
||||||
subs = [d for d in dotfiles if d.dst == path]
|
subs = [d for d in dotfiles if d.dst == path]
|
||||||
if not subs:
|
if not subs:
|
||||||
self.log.err('\"{}\" is not managed!'.format(path))
|
self.log.err('\"{}\" is not managed!'.format(path))
|
||||||
|
|||||||
126
tests-ng/dynactions.sh
Executable file
126
tests-ng/dynactions.sh
Executable file
@@ -0,0 +1,126 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# author: deadc0de6 (https://github.com/deadc0de6)
|
||||||
|
# Copyright (c) 2017, deadc0de6
|
||||||
|
#
|
||||||
|
# test dynamic actions
|
||||||
|
# returns 1 in case of error
|
||||||
|
#
|
||||||
|
|
||||||
|
# exit on first error
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# all this crap to get current path
|
||||||
|
rl="readlink -f"
|
||||||
|
if ! ${rl} "${0}" >/dev/null 2>&1; then
|
||||||
|
rl="realpath"
|
||||||
|
|
||||||
|
if ! hash ${rl}; then
|
||||||
|
echo "\"${rl}\" not found !" && exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
cur=$(dirname "$(${rl} "${0}")")
|
||||||
|
|
||||||
|
#hash dotdrop >/dev/null 2>&1
|
||||||
|
#[ "$?" != "0" ] && echo "install dotdrop to run tests" && exit 1
|
||||||
|
|
||||||
|
#echo "called with ${1}"
|
||||||
|
|
||||||
|
# dotdrop path can be pass as argument
|
||||||
|
ddpath="${cur}/../"
|
||||||
|
[ "${1}" != "" ] && ddpath="${1}"
|
||||||
|
[ ! -d ${ddpath} ] && echo "ddpath \"${ddpath}\" is not a directory" && exit 1
|
||||||
|
|
||||||
|
export PYTHONPATH="${ddpath}:${PYTHONPATH}"
|
||||||
|
bin="python3 -m dotdrop.dotdrop"
|
||||||
|
|
||||||
|
echo "dotdrop path: ${ddpath}"
|
||||||
|
echo "pythonpath: ${PYTHONPATH}"
|
||||||
|
|
||||||
|
# get the helpers
|
||||||
|
source ${cur}/helpers
|
||||||
|
|
||||||
|
echo -e "\e[96m\e[1m==> RUNNING $(basename $BASH_SOURCE) <==\e[0m"
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# this is the test
|
||||||
|
################################################################
|
||||||
|
|
||||||
|
# the action temp
|
||||||
|
tmpa=`mktemp -d`
|
||||||
|
# the dotfile source
|
||||||
|
tmps=`mktemp -d`
|
||||||
|
mkdir -p ${tmps}/dotfiles
|
||||||
|
# the dotfile destination
|
||||||
|
tmpd=`mktemp -d`
|
||||||
|
|
||||||
|
# create the config file
|
||||||
|
cfg="${tmps}/config.yaml"
|
||||||
|
|
||||||
|
cat > ${cfg} << _EOF
|
||||||
|
variables:
|
||||||
|
var1: "var1"
|
||||||
|
var2: "{{@@ var1 @@}} var2"
|
||||||
|
var3: "{{@@ var2 @@}} var3"
|
||||||
|
var4: "{{@@ dvar4 @@}}"
|
||||||
|
dynvariables:
|
||||||
|
dvar1: "echo dvar1"
|
||||||
|
dvar2: "{{@@ dvar1 @@}} dvar2"
|
||||||
|
dvar3: "{{@@ dvar2 @@}} dvar3"
|
||||||
|
dvar4: "echo {{@@ var3 @@}}"
|
||||||
|
actions:
|
||||||
|
pre:
|
||||||
|
preaction1: "echo {{@@ var3 @@}} > ${tmpa}/preaction1"
|
||||||
|
preaction2: "echo {{@@ dvar3 @@}} > ${tmpa}/preaction2"
|
||||||
|
post:
|
||||||
|
postaction1: "echo {{@@ var3 @@}} > ${tmpa}/postaction1"
|
||||||
|
postaction2: "echo {{@@ dvar3 @@}} > ${tmpa}/postaction2"
|
||||||
|
naked1: "echo {{@@ var3 @@}} > ${tmpa}/naked1"
|
||||||
|
naked2: "echo {{@@ dvar3 @@}} > ${tmpa}/naked2"
|
||||||
|
config:
|
||||||
|
backup: true
|
||||||
|
create: true
|
||||||
|
dotpath: dotfiles
|
||||||
|
dotfiles:
|
||||||
|
f_abc:
|
||||||
|
dst: ${tmpd}/abc
|
||||||
|
src: abc
|
||||||
|
actions:
|
||||||
|
- preaction1
|
||||||
|
- preaction2
|
||||||
|
- postaction1
|
||||||
|
- postaction2
|
||||||
|
- naked1
|
||||||
|
- naked2
|
||||||
|
profiles:
|
||||||
|
p1:
|
||||||
|
dotfiles:
|
||||||
|
- f_abc
|
||||||
|
_EOF
|
||||||
|
cat ${cfg}
|
||||||
|
|
||||||
|
# create the dotfile
|
||||||
|
echo "test" > ${tmps}/dotfiles/abc
|
||||||
|
|
||||||
|
# install
|
||||||
|
cd ${ddpath} | ${bin} install -f -c ${cfg} -p p1 --verbose
|
||||||
|
|
||||||
|
# checks
|
||||||
|
[ ! -e ${tmpa}/preaction1 ] && exit 1
|
||||||
|
[ ! -e ${tmpa}/preaction2 ] && exit 1
|
||||||
|
[ ! -e ${tmpa}/postaction1 ] && exit 1
|
||||||
|
[ ! -e ${tmpa}/postaction2 ] && exit 1
|
||||||
|
[ ! -e ${tmpa}/naked1 ] && exit 1
|
||||||
|
[ ! -e ${tmpa}/naked2 ] && exit 1
|
||||||
|
|
||||||
|
grep 'var1 var2 var3' ${tmpa}/preaction1 >/dev/null
|
||||||
|
grep 'dvar1 dvar2 dvar3' ${tmpa}/preaction2 >/dev/null
|
||||||
|
grep 'var1 var2 var3' ${tmpa}/postaction1 >/dev/null
|
||||||
|
grep 'dvar1 dvar2 dvar3' ${tmpa}/postaction2 >/dev/null
|
||||||
|
grep 'var1 var2 var3' ${tmpa}/naked1 >/dev/null
|
||||||
|
grep 'dvar1 dvar2 dvar3' ${tmpa}/naked2 >/dev/null
|
||||||
|
|
||||||
|
## CLEANING
|
||||||
|
rm -rf ${tmps} ${tmpd} ${tmpa}
|
||||||
|
|
||||||
|
echo "OK"
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user