From fa62ffeef7afddcb6a8963270e799b223add0439 Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 09:50:57 +0100 Subject: [PATCH 01/14] adding transformations in config and dotfiles --- dotdrop/config.py | 16 +++++++++++++++- dotdrop/dotfile.py | 5 ++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/dotdrop/config.py b/dotdrop/config.py index ff0ff04..9d0d2ad 100644 --- a/dotdrop/config.py +++ b/dotdrop/config.py @@ -18,6 +18,7 @@ class Cfg: key_config = 'config' key_dotfiles = 'dotfiles' key_actions = 'actions' + key_trans = 'trans' key_dotpath = 'dotpath' key_profiles = 'profiles' key_profiles_dots = 'dotfiles' @@ -26,6 +27,7 @@ class Cfg: key_dotfiles_dst = 'dst' key_dotfiles_link = 'link' key_dotfiles_actions = 'actions' + key_dotfiles_trans = 'trans' def __init__(self, cfgpath): if not os.path.exists(cfgpath): @@ -41,6 +43,8 @@ class Cfg: # not linked to content self.actions = {} # not linked to content + self.trans = {} + # not linked to content self.prodots = {} if not self._load_file(): raise ValueError('config is not valid') @@ -94,6 +98,12 @@ class Cfg: for k, v in self.content[self.key_actions].items(): self.actions[k] = Action(k, v) + # parse all transformations + if self.key_trans in self.content: + if self.content[self.key_trans] is not None: + for k, v in self.content[self.key_trans].items(): + self.trans[k] = Action(k, v) + # parse the profiles self.profiles = self.content[self.key_profiles] if self.profiles is None: @@ -117,8 +127,12 @@ class Cfg: entries = v[self.key_dotfiles_actions] if \ self.key_dotfiles_actions in v else [] actions = self._parse_actions(self.actions, entries) + entries = v[self.key_dotfiles_trans] if \ + self.key_dotfiles_trans in v else [] + trans = self._parse_actions(self.trans, entries) self.dotfiles[k] = Dotfile(k, dst, src, - link=link, actions=actions) + link=link, actions=actions + trans=trans) # assign dotfiles to each profile for k, v in self.profiles.items(): diff --git a/dotdrop/dotfile.py b/dotdrop/dotfile.py index 3a3c75b..657385b 100644 --- a/dotdrop/dotfile.py +++ b/dotdrop/dotfile.py @@ -7,7 +7,8 @@ represents a dotfile in dotdrop class Dotfile: - def __init__(self, key, dst, src, actions=[], link=False): + def __init__(self, key, dst, src, + actions=[], trans=[], link=False): # key of dotfile in the config self.key = key # where to install this dotfile @@ -18,6 +19,8 @@ class Dotfile: self.link = link # list of actions self.actions = actions + # list of transformations + self.trans = trans def __str__(self): return 'key:%s, src: %s, dst: %s, link: %s' % (self.key, self.src, From ef1fffd1a1d75d0e21063189161d5f58f43c1096 Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 10:21:15 +0100 Subject: [PATCH 02/14] transformations first steps --- dotdrop/action.py | 12 ++++++++++++ dotdrop/config.py | 9 +++++++-- dotdrop/dotdrop.py | 5 +++++ dotdrop/utils.py | 4 ++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/dotdrop/action.py b/dotdrop/action.py index e463f4d..51676cd 100644 --- a/dotdrop/action.py +++ b/dotdrop/action.py @@ -24,6 +24,18 @@ class Action: except KeyboardInterrupt: self.log.warn('action interrupted') + def transform(self, arg0, arg1): + '''execute transformation with {0} and {1} + where {0} is the file to transform and + {1} is the result file''' + cmd = self.action.format(arg0, arg1) + self.log.sub('transforming with \"%s\"' % (cmd)) + try: + subprocess.call(cmd, shell=True) + except KeyboardInterrupt: + self.log.warn('action interrupted') + return arg1 + def __str__(self): return 'key:%s -> \"%s\"' % (self.key, self.action) diff --git a/dotdrop/config.py b/dotdrop/config.py index 9d0d2ad..29a5c20 100644 --- a/dotdrop/config.py +++ b/dotdrop/config.py @@ -130,8 +130,13 @@ class Cfg: entries = v[self.key_dotfiles_trans] if \ self.key_dotfiles_trans in v else [] trans = self._parse_actions(self.trans, entries) - self.dotfiles[k] = Dotfile(k, dst, src, - link=link, actions=actions + if len(trans) > 0 and link: + msg = 'transformations disabled for \"%s\"' % (dst) + msg += ' as link is True' % (dst) + self.log.warn(msg) + trans = [] + self.dotfiles[k] = Dotfile(k, dst, src, link=link, + actions=actions, trans=trans) # assign dotfiles to each profile diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py index 6840bcf..a506a22 100644 --- a/dotdrop/dotdrop.py +++ b/dotdrop/dotdrop.py @@ -101,6 +101,11 @@ def install(opts, conf): if hasattr(dotfile, 'link') and dotfile.link: r = inst.link(dotfile.src, dotfile.dst) else: + if dotfile.trans: + # TODO + tmp = get_tmpfile() + for trans in dotfile.trans: + pass r = inst.install(t, opts['profile'], dotfile.src, dotfile.dst) if len(r) > 0 and len(dotfile.actions) > 0: # execute action diff --git a/dotdrop/utils.py b/dotdrop/utils.py index 45765d5..844a37c 100644 --- a/dotdrop/utils.py +++ b/dotdrop/utils.py @@ -38,6 +38,10 @@ def get_tmpdir(): return tempfile.mkdtemp(prefix='dotdrop-') +def get_tmpfile(): + return tempfile.mkstemp(prefix='dotdrop-') + + def remove(path): ''' Remove a file / directory / symlink ''' if not os.path.exists(path): From 6f4148c8626a51555004a9b4e3a928bdb9e679c2 Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 16:11:29 +0100 Subject: [PATCH 03/14] fix return value --- dotdrop/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dotdrop/utils.py b/dotdrop/utils.py index 844a37c..c07eada 100644 --- a/dotdrop/utils.py +++ b/dotdrop/utils.py @@ -39,7 +39,8 @@ def get_tmpdir(): def get_tmpfile(): - return tempfile.mkstemp(prefix='dotdrop-') + (fd, path) = tempfile.mkstemp(prefix='dotdrop-') + return path def remove(path): From 69f04cdc00bdffbbd860e10530c58e3e863d587e Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 16:11:46 +0100 Subject: [PATCH 04/14] improve transformation --- dotdrop/action.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/dotdrop/action.py b/dotdrop/action.py index 51676cd..809fd1c 100644 --- a/dotdrop/action.py +++ b/dotdrop/action.py @@ -5,6 +5,7 @@ Represent an action in dotdrop """ import subprocess +import os # local imports from dotdrop.logger import Logger @@ -12,29 +13,37 @@ from dotdrop.logger import Logger class Action: + def __init__(self, key, action): self.key = key self.action = action self.log = Logger() def execute(self): + ret = 1 self.log.sub('executing \"%s\"' % (self.action)) try: - subprocess.call(self.action, shell=True) + ret = subprocess.call(self.action, shell=True) except KeyboardInterrupt: self.log.warn('action interrupted') + return ret == 0 def transform(self, arg0, arg1): '''execute transformation with {0} and {1} where {0} is the file to transform and {1} is the result file''' + if os.path.exists(arg1): + msg = 'transformation destination exists: %s' + self.log.warn(msg % (arg1)) + return False + ret = 1 cmd = self.action.format(arg0, arg1) self.log.sub('transforming with \"%s\"' % (cmd)) try: - subprocess.call(cmd, shell=True) + ret = subprocess.call(cmd, shell=True) except KeyboardInterrupt: self.log.warn('action interrupted') - return arg1 + return ret == 0 def __str__(self): return 'key:%s -> \"%s\"' % (self.key, self.action) From 7c9d488fb31a99a76cbe2be0d1d69ec7d657a610 Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 16:38:03 +0100 Subject: [PATCH 05/14] implement transformations --- dotdrop/dotdrop.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/dotdrop/dotdrop.py b/dotdrop/dotdrop.py index a506a22..2711444 100644 --- a/dotdrop/dotdrop.py +++ b/dotdrop/dotdrop.py @@ -45,6 +45,7 @@ CUR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) LOG = Logger() HOSTNAME = os.uname()[1] TILD = '~' +TRANS_SUFFIX = 'trans' BANNER = """ _ _ _ __| | ___ | |_ __| |_ __ ___ _ __ @@ -101,12 +102,29 @@ def install(opts, conf): if hasattr(dotfile, 'link') and dotfile.link: r = inst.link(dotfile.src, dotfile.dst) else: + src = dotfile.src + tmp = None if dotfile.trans: - # TODO - tmp = get_tmpfile() + tmp = '%s.%s' % (src, TRANS_SUFFIX) + err = False for trans in dotfile.trans: - pass - r = inst.install(t, opts['profile'], dotfile.src, dotfile.dst) + s = os.path.join(opts['dotpath'], src) + temp = os.path.join(opts['dotpath'], tmp) + if not trans.transform(s, temp): + msg = 'transformation \"%s\" failed for %s' + LOG.err(msg % (trans.key, dotfile.key)) + err = True + break + if err: + if tmp and os.path.exists(tmp): + remove(tmp) + continue + src = tmp + r = inst.install(t, opts['profile'], src, dotfile.dst) + if tmp: + tmp = os.path.join(opts['dotpath'], tmp) + if os.path.exists(tmp): + remove(tmp) if len(r) > 0 and len(dotfile.actions) > 0: # execute action for action in dotfile.actions: @@ -145,6 +163,10 @@ def compare(opts, conf, tmp, focus=None): return ret for dotfile in selected: + if dotfile.trans: + msg = 'ignore %s as it uses transformation(s)' + LOG.log(msg % (dotfile.key)) + continue same, diff = inst.compare(t, tmp, opts['profile'], dotfile.src, dotfile.dst, opts=opts['dopts']) From e85235c44f7aab9f9f5a8e69294d79ec1fc270aa Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 16:38:13 +0100 Subject: [PATCH 06/14] document transformations --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/README.md b/README.md index 6b25e6a..5f33c95 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,8 @@ why dotdrop rocks. * [Include dotfiles from another profile](#include-dotfiles-from-another-profile) * [Update dotdrop](#update-dotdrop) * [Update dotfiles](#update-dotfiles) + * [Storing sensitive dotfiles](#storing-sensitive-dotfiles) + * [Transformations](#transformations) * [Template](#template) * [Example](#example) @@ -247,6 +249,8 @@ the following entries: link: actions: - + trans: + - ``` * **profiles** entry: a list of profiles with the different dotfiles that @@ -271,6 +275,11 @@ the following entries: : ``` +* **trans** entry: a list of transformations +``` + : +``` + ## Installing dotfiles Simply run @@ -437,6 +446,39 @@ There are two cases: $ dotdrop.sh update ~/.vimrc ``` +## Storing sensitive dotfiles + +Two solutions exist, the first one using an unversioned file (see [Environment variables](#Environment variables)) +and the second using transformation actions (see [Transformations](#transformations)). + +## Transformations + +Transformation actions are used to transform a dotfile before it is +installed. They work like actions but have two arguments: + +* **{0}** will be replaced with the dotfile to process +* **{1}** will be replaced with a temporary file to store the result + +A typical use-case for transformations is when the dotfile needs to be +stored encrypted. + +For example: + +the transformation and the dotfile in `config.yaml`: +``` +dotfiles: + f_secret: + dst: ~/.secret + src: secret + trans: + - gpg +trans: + gpg: gpg2 -q --for-your-eyes-only --no-tty -d {0} > {1} +``` + +The above config allows to store the dotfile `~/.secret` encrypted in the *dotfiles* +directory. + # Template Dotdrop leverage the power of [jinja2](http://jinja.pocoo.org/) to handle the From 6b9606b920696bc6eb3ea654265a91803e70cf4e Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 16:49:33 +0100 Subject: [PATCH 07/14] refactor readme --- README.md | 270 +++++++++++++++++++++++++++--------------------------- 1 file changed, 136 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index 5f33c95..aba56ff 100644 --- a/README.md +++ b/README.md @@ -58,20 +58,20 @@ why dotdrop rocks. **Table of Contents** * [Installation](#installation) +* [Config](#config) * [Usage](#usage) +* How to - * [Installing dotfiles](#installing-dotfiles) - * [Diffing your local dotfiles with dotdrop](#diffing-your-local-dotfiles-with-dotdrop) - * [Import new dotfiles](#import-new-dotfiles) - * [List the available profiles](#list-the-available-profiles) - * [List configured dotfiles](#list-configured-dotfiles) - * [Execute an action when deploying a dotfile](#execute-an-action-when-deploying-a-dotfile) - * [All dotfiles for a profile](#all-dotfiles-for-a-profile) - * [Include dotfiles from another profile](#include-dotfiles-from-another-profile) + * [Install dotfiles](#install-dotfiles) + * [Compare dotfiles](#compare-dotfiles) + * [Import dotfiles](#import-dotfiles) + * [List profiles](#list-profiles) + * [List dotfiles](#list-dotfiles) + * [Use actions](#use-actions) + * [Use transformations](#use-transformations) * [Update dotdrop](#update-dotdrop) * [Update dotfiles](#update-dotfiles) - * [Storing sensitive dotfiles](#storing-sensitive-dotfiles) - * [Transformations](#transformations) + * [Store sensitive dotfiles](#store-sensitive-dotfiles) * [Template](#template) * [Example](#example) @@ -136,6 +136,103 @@ by `dotdrop` if using the pypi solution. Finally import your dotfiles as described [below](#usage). +# Config + +The config file (defaults to *config.yaml*) is a yaml file containing +the following entries: + +* **config** entry: contains settings for the deployment + * `backup`: create a backup of the dotfile in case it differs from the + one that will be installed by dotdrop + * `create`: create directory hierarchy when installing dotfiles if + it doesn't exist + * `dotpath`: path to the directory containing the dotfiles to be managed + by dotdrop (absolute path or relative to the config file location) + +* **dotfiles** entry: a list of dotfiles + * When `link` is true, dotdrop will create a symlink instead of copying. Template generation (as in [template](#template)) is not supported when `link` is true. + * `actions` contains a list of action keys that need to be defined in the **actions** entry below. +``` + : + dst: + src: + # Optional + link: + actions: + - + trans: + - +``` + +* **profiles** entry: a list of profiles with the different dotfiles that + need to be managed + * `dotfiles`: the dotfiles associated to this profile + * `include`: include all dotfiles from another profile (optional) + +``` + : + dotfiles: + - + - + - ... + # Optional + include: + - + - ... +``` + +* **actions** entry: a list of action +``` + : +``` + +* **trans** entry: a list of transformations +``` + : +``` + +## All dotfiles for a profile + +To use all defined dotfiles for a profile, simply use +the keyword `ALL`. + +For example: +```yaml +dotfiles: + f_xinitrc: + dst: ~/.xinitrc + src: xinitrc + f_vimrc: + dst: ~/.vimrc + src: vimrc +profiles: + host1: + dotfiles: + - ALL + host2: + dotfiles: + - f_vimrc +``` + +## Include dotfiles from another profile + +If one profile is using the entire set of another profile, one can use +the `include` entry to avoid redundancy. + +For example: +```yaml +profiles: + host1: + dotfiles: + - f_xinitrc + include: + - host2 + host2: + dotfiles: + - f_vimrc +``` +Here profile *host1* contains all the dotfiles defined for *host2* plus `f_xinitrc`. + # Usage If starting fresh, the `import` command of dotdrop @@ -225,62 +322,7 @@ Options: For easy deployment the default profile used by dotdrop reflects the hostname of the host on which it runs. -## Config file details - -The config file (defaults to *config.yaml*) is a yaml file containing -the following entries: - -* **config** entry: contains settings for the deployment - * `backup`: create a backup of the dotfile in case it differs from the - one that will be installed by dotdrop - * `create`: create directory hierarchy when installing dotfiles if - it doesn't exist - * `dotpath`: path to the directory containing the dotfiles to be managed - by dotdrop (absolute path or relative to the config file location) - -* **dotfiles** entry: a list of dotfiles - * When `link` is true, dotdrop will create a symlink instead of copying. Template generation (as in [template](#template)) is not supported when `link` is true. - * `actions` contains a list of action keys that need to be defined in the **actions** entry below. -``` - : - dst: - src: - # Optional - link: - actions: - - - trans: - - -``` - -* **profiles** entry: a list of profiles with the different dotfiles that - need to be managed - * `dotfiles`: the dotfiles associated to this profile - * `include`: include all dotfiles from another profile (optional) - -``` - : - dotfiles: - - - - - - ... - # Optional - include: - - - - ... -``` - -* **actions** entry: a list of action -``` - : -``` - -* **trans** entry: a list of transformations -``` - : -``` - -## Installing dotfiles +## Install dotfiles Simply run ```bash @@ -290,7 +332,7 @@ $ dotdrop.sh install Use the `--profile` switch to specify a profile if not using the host's hostname. -## Diffing your local dotfiles with dotdrop +## Compare dotfiles Compare local dotfiles with dotdrop's defined ones: ```bash @@ -300,7 +342,7 @@ $ dotdrop.sh compare The diffing is done by diff in the backend, one can provide specific options to diff using the `-o` switch. -## Import new dotfiles +## Import dotfiles Dotdrop allows to import dotfiles directly from the filesystem. It will copy the dotfile and update the @@ -312,7 +354,7 @@ $ dotdrop.sh import ~/.xinitrc ``` -## List the available profiles +## List profiles ```bash $ dotdrop.sh list @@ -322,7 +364,7 @@ Dotdrop allows to choose which profile to use with the *--profile* switch if you use something else than the default (the hostname). -## List configured dotfiles +## List dotfiles The following command lists the different dotfiles configured for a specific profile: @@ -341,7 +383,7 @@ f_dunstrc (file: "config/dunst/dunstrc", link: False) -> ~/.config/dunst/dunstrc ``` -## Execute an action when deploying a dotfile +## Use actions It is sometimes useful to execute some kind of action when deploying a dotfile. For example let's consider @@ -373,47 +415,35 @@ Thus when `f_vimrc` is installed, the command `vim +VundleClean! +VundleInstall +VundleInstall! +qall` will be executed. -## All dotfiles for a profile +## Use transformations -To use all defined dotfiles for a profile, simply use -the keyword `ALL`. +Transformation actions are used to transform a dotfile before it is +installed. They work like [actions](#use-actions) but have two arguments: + +* **{0}** will be replaced with the dotfile to process +* **{1}** will be replaced with a temporary file to store the result + +A typical use-case for transformations is when the dotfile needs to be +stored encrypted. For example: -```yaml + +the transformation and the dotfile in `config.yaml`: +``` dotfiles: - f_xinitrc: - dst: ~/.xinitrc - src: xinitrc - f_vimrc: - dst: ~/.vimrc - src: vimrc -profiles: - host1: - dotfiles: - - ALL - host2: - dotfiles: - - f_vimrc + f_secret: + dst: ~/.secret + src: secret + trans: + - gpg +trans: + gpg: gpg2 -q --for-your-eyes-only --no-tty -d {0} > {1} ``` -## Include dotfiles from another profile +The above config allows to store the dotfile `~/.secret` encrypted in the *dotfiles* +directory and uses gpg to decrypt it when install is run. -If one profile is using the entire set of another profile, one can use -the `include` entry to avoid redundancy. -For example: -```yaml -profiles: - host1: - dotfiles: - - f_xinitrc - include: - - host2 - host2: - dotfiles: - - f_vimrc -``` -Here profile *host1* contains all the dotfiles defined for *host2* plus `f_xinitrc`. ## Update dotdrop @@ -446,39 +476,11 @@ There are two cases: $ dotdrop.sh update ~/.vimrc ``` -## Storing sensitive dotfiles +## Store sensitive dotfiles -Two solutions exist, the first one using an unversioned file (see [Environment variables](#Environment variables)) +Two solutions exist, the first one using an unversioned file (see [Environment variables](#environment-variables)) and the second using transformation actions (see [Transformations](#transformations)). -## Transformations - -Transformation actions are used to transform a dotfile before it is -installed. They work like actions but have two arguments: - -* **{0}** will be replaced with the dotfile to process -* **{1}** will be replaced with a temporary file to store the result - -A typical use-case for transformations is when the dotfile needs to be -stored encrypted. - -For example: - -the transformation and the dotfile in `config.yaml`: -``` -dotfiles: - f_secret: - dst: ~/.secret - src: secret - trans: - - gpg -trans: - gpg: gpg2 -q --for-your-eyes-only --no-tty -d {0} > {1} -``` - -The above config allows to store the dotfile `~/.secret` encrypted in the *dotfiles* -directory. - # Template Dotdrop leverage the power of [jinja2](http://jinja.pocoo.org/) to handle the From 97b1346a7f4e6b24aa57820ab6045943707ab5f7 Mon Sep 17 00:00:00 2001 From: deadc0de Date: Wed, 7 Feb 2018 16:54:50 +0100 Subject: [PATCH 08/14] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index aba56ff..28a17e0 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ the following entries: * **dotfiles** entry: a list of dotfiles * When `link` is true, dotdrop will create a symlink instead of copying. Template generation (as in [template](#template)) is not supported when `link` is true. * `actions` contains a list of action keys that need to be defined in the **actions** entry below. + * `trans` contains a list of transformation keys that need to be defined in the **trans** entry below. ``` : dst: From a331e5388f486f4a7c5a00d535ea3474a508da24 Mon Sep 17 00:00:00 2001 From: deadc0de Date: Wed, 7 Feb 2018 16:55:58 +0100 Subject: [PATCH 09/14] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 28a17e0..fde368b 100644 --- a/README.md +++ b/README.md @@ -444,8 +444,6 @@ trans: The above config allows to store the dotfile `~/.secret` encrypted in the *dotfiles* directory and uses gpg to decrypt it when install is run. - - ## Update dotdrop If used as a submodule, update it with @@ -480,7 +478,7 @@ $ dotdrop.sh update ~/.vimrc ## Store sensitive dotfiles Two solutions exist, the first one using an unversioned file (see [Environment variables](#environment-variables)) -and the second using transformation actions (see [Transformations](#transformations)). +and the second using transformations (see [Transformations](#use-transformations)). # Template From 62cd1b417163c7b3b78f5407fdf7f43a701c4d77 Mon Sep 17 00:00:00 2001 From: deadc0de Date: Wed, 7 Feb 2018 17:00:23 +0100 Subject: [PATCH 10/14] Update README.md --- README.md | 208 +++++++++++++++++++++++++++--------------------------- 1 file changed, 103 insertions(+), 105 deletions(-) diff --git a/README.md b/README.md index fde368b..43e40fc 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,6 @@ why dotdrop rocks. **Table of Contents** * [Installation](#installation) -* [Config](#config) * [Usage](#usage) * How to @@ -73,6 +72,7 @@ why dotdrop rocks. * [Update dotfiles](#update-dotfiles) * [Store sensitive dotfiles](#store-sensitive-dotfiles) +* [Config](#config) * [Template](#template) * [Example](#example) * [People using dotdrop](#people-using-dotdrop) @@ -136,104 +136,6 @@ by `dotdrop` if using the pypi solution. Finally import your dotfiles as described [below](#usage). -# Config - -The config file (defaults to *config.yaml*) is a yaml file containing -the following entries: - -* **config** entry: contains settings for the deployment - * `backup`: create a backup of the dotfile in case it differs from the - one that will be installed by dotdrop - * `create`: create directory hierarchy when installing dotfiles if - it doesn't exist - * `dotpath`: path to the directory containing the dotfiles to be managed - by dotdrop (absolute path or relative to the config file location) - -* **dotfiles** entry: a list of dotfiles - * When `link` is true, dotdrop will create a symlink instead of copying. Template generation (as in [template](#template)) is not supported when `link` is true. - * `actions` contains a list of action keys that need to be defined in the **actions** entry below. - * `trans` contains a list of transformation keys that need to be defined in the **trans** entry below. -``` - : - dst: - src: - # Optional - link: - actions: - - - trans: - - -``` - -* **profiles** entry: a list of profiles with the different dotfiles that - need to be managed - * `dotfiles`: the dotfiles associated to this profile - * `include`: include all dotfiles from another profile (optional) - -``` - : - dotfiles: - - - - - - ... - # Optional - include: - - - - ... -``` - -* **actions** entry: a list of action -``` - : -``` - -* **trans** entry: a list of transformations -``` - : -``` - -## All dotfiles for a profile - -To use all defined dotfiles for a profile, simply use -the keyword `ALL`. - -For example: -```yaml -dotfiles: - f_xinitrc: - dst: ~/.xinitrc - src: xinitrc - f_vimrc: - dst: ~/.vimrc - src: vimrc -profiles: - host1: - dotfiles: - - ALL - host2: - dotfiles: - - f_vimrc -``` - -## Include dotfiles from another profile - -If one profile is using the entire set of another profile, one can use -the `include` entry to avoid redundancy. - -For example: -```yaml -profiles: - host1: - dotfiles: - - f_xinitrc - include: - - host2 - host2: - dotfiles: - - f_vimrc -``` -Here profile *host1* contains all the dotfiles defined for *host2* plus `f_xinitrc`. - # Usage If starting fresh, the `import` command of dotdrop @@ -480,6 +382,104 @@ $ dotdrop.sh update ~/.vimrc Two solutions exist, the first one using an unversioned file (see [Environment variables](#environment-variables)) and the second using transformations (see [Transformations](#use-transformations)). +# Config + +The config file (defaults to *config.yaml*) is a yaml file containing +the following entries: + +* **config** entry: contains settings for the deployment + * `backup`: create a backup of the dotfile in case it differs from the + one that will be installed by dotdrop + * `create`: create directory hierarchy when installing dotfiles if + it doesn't exist + * `dotpath`: path to the directory containing the dotfiles to be managed + by dotdrop (absolute path or relative to the config file location) + +* **dotfiles** entry: a list of dotfiles + * When `link` is true, dotdrop will create a symlink instead of copying. Template generation (as in [template](#template)) is not supported when `link` is true. + * `actions` contains a list of action keys that need to be defined in the **actions** entry below. + * `trans` contains a list of transformation keys that need to be defined in the **trans** entry below. +``` + : + dst: + src: + # Optional + link: + actions: + - + trans: + - +``` + +* **profiles** entry: a list of profiles with the different dotfiles that + need to be managed + * `dotfiles`: the dotfiles associated to this profile + * `include`: include all dotfiles from another profile (optional) + +``` + : + dotfiles: + - + - + - ... + # Optional + include: + - + - ... +``` + +* **actions** entry: a list of action +``` + : +``` + +* **trans** entry: a list of transformations +``` + : +``` + +## All dotfiles for a profile + +To use all defined dotfiles for a profile, simply use +the keyword `ALL`. + +For example: +```yaml +dotfiles: + f_xinitrc: + dst: ~/.xinitrc + src: xinitrc + f_vimrc: + dst: ~/.vimrc + src: vimrc +profiles: + host1: + dotfiles: + - ALL + host2: + dotfiles: + - f_vimrc +``` + +## Include dotfiles from another profile + +If one profile is using the entire set of another profile, one can use +the `include` entry to avoid redundancy. + +For example: +```yaml +profiles: + host1: + dotfiles: + - f_xinitrc + include: + - host2 + host2: + dotfiles: + - f_vimrc +``` +Here profile *host1* contains all the dotfiles defined for *host2* plus `f_xinitrc`. + # Template Dotdrop leverage the power of [jinja2](http://jinja.pocoo.org/) to handle the @@ -498,11 +498,10 @@ Note that dotdrop uses different delimiters than ## Available variables -### Profile +* `{{@@ profile @@}}` contains the profile provided to dotdrop. +* `{{@@ env['MY_VAR'] @@}}` contains environment variables (see [Environment variables](#environment-variables)) -`{{@@ profile @@}}` contains the profile provided to dotdrop. Below example shows how it is used. - -### Environment variables +## Environment variables It's possible to access environment variables inside the templates. This feature can be used like this: @@ -524,7 +523,6 @@ pass="verysecurepassword" ``` Of course, this file should not be tracked by git (put it in your `.gitignore`). - Then you can invoke dotdrop with the help of an alias like that: ``` ## when using dotdrop as a submodule @@ -664,7 +662,7 @@ $ git push ``` Otherwise, simply install it from pypi as explained [above](#with-pypi) -and get rid of the submodule: +and get rid of the submodule as shown below: * move to the dotfiles directory where dotdrop is used as a submodule ```bash From 047ab1bd929adc96250af63a9459660c12ba639d Mon Sep 17 00:00:00 2001 From: deadc0de Date: Wed, 7 Feb 2018 17:02:08 +0100 Subject: [PATCH 11/14] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 43e40fc..d8ecf2d 100644 --- a/README.md +++ b/README.md @@ -80,11 +80,13 @@ why dotdrop rocks. # Installation There's two ways of installing and using dotdrop, either [as a submodule](#as-a-submodule) -to your dotfiles git tree or system-wide [through pypi](#with-pypi). +to your dotfiles git tree or system-wide [with pypi](#with-pypi). Having dotdrop as a submodule guarantees that anywhere your are cloning your dotfiles git tree from you'll have dotdrop shipped with it. It is the recommended way. +Dotdrop is also available on aur: https://aur.archlinux.org/packages/dotdrop/ + ## As a submodule The following will create a repository for your dotfiles and From 298c6a549e071b67864892efeeadb7f009c315c1 Mon Sep 17 00:00:00 2001 From: deadc0de Date: Wed, 7 Feb 2018 17:08:38 +0100 Subject: [PATCH 12/14] Update README.md --- README.md | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d8ecf2d..0b804e6 100644 --- a/README.md +++ b/README.md @@ -323,17 +323,18 @@ be executed. ## Use transformations Transformation actions are used to transform a dotfile before it is -installed. They work like [actions](#use-actions) but have two arguments: +installed. They work like [actions](#use-actions) but are executed before the +dotfile is installed to transform the source. + +Transformation commands have two arguments: * **{0}** will be replaced with the dotfile to process -* **{1}** will be replaced with a temporary file to store the result +* **{1}** will be replaced with a temporary file to store the result of the transformation A typical use-case for transformations is when the dotfile needs to be stored encrypted. -For example: - -the transformation and the dotfile in `config.yaml`: +Here's an example of part of a config file to use gpg encrypted dotfiles: ``` dotfiles: f_secret: @@ -348,6 +349,23 @@ trans: The above config allows to store the dotfile `~/.secret` encrypted in the *dotfiles* directory and uses gpg to decrypt it when install is run. +Here's how to deploy the above solution: + +* import the clear dotfile (creates the entries in the config) +``` +./dotdrop.sh import ~/.secret +``` +* encrypt it and +``` + ~/.secret +``` +* overwrite the dotfile +``` +cp dotfiles/secret +``` +* edit the config file and add the transformation to the dotfile +* commit and push changes + ## Update dotdrop If used as a submodule, update it with From bc80b2626b9a7e27c55605cc469aacfffd9d2128 Mon Sep 17 00:00:00 2001 From: deadc0de Date: Wed, 7 Feb 2018 17:11:08 +0100 Subject: [PATCH 13/14] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0b804e6..efa2ae2 100644 --- a/README.md +++ b/README.md @@ -256,7 +256,6 @@ config file automatically. For example to import `~/.xinitrc` ```bash $ dotdrop.sh import ~/.xinitrc - ``` ## List profiles @@ -351,20 +350,20 @@ directory and uses gpg to decrypt it when install is run. Here's how to deploy the above solution: -* import the clear dotfile (creates the entries in the config) +* import the clear dotfile (creates the correct entries in the config file) ``` ./dotdrop.sh import ~/.secret ``` -* encrypt it and +* encrypt the original dotfile ``` ~/.secret ``` -* overwrite the dotfile +* overwrite the dotfile with the encrypted version ``` cp dotfiles/secret ``` * edit the config file and add the transformation to the dotfile -* commit and push changes +* commit and push the changes ## Update dotdrop @@ -381,7 +380,6 @@ Through pypi: $ sudo pip3 install dotdrop --upgrade ``` - ## Update dotfiles Dotfiles managed by dotdrop can be updated using the `update` command. From 4ff0a0dad52968a411b5f4b67ea3e5d16492d64c Mon Sep 17 00:00:00 2001 From: deadc0de6 Date: Wed, 7 Feb 2018 17:10:28 +0100 Subject: [PATCH 14/14] fix pep8 --- dotdrop/action.py | 1 - 1 file changed, 1 deletion(-) diff --git a/dotdrop/action.py b/dotdrop/action.py index 809fd1c..387cc1c 100644 --- a/dotdrop/action.py +++ b/dotdrop/action.py @@ -13,7 +13,6 @@ from dotdrop.logger import Logger class Action: - def __init__(self, key, action): self.key = key self.action = action