deadc0de6 / dotdrop

Save your dotfiles once, deploy them everywhere
https://dotdrop.readthedocs.io
GNU General Public License v3.0
1.79k stars 105 forks source link

[bug] Cannot use `cmpignore` to ignore all but a single file in a directory #327

Closed jwodder closed 3 years ago

jwodder commented 3 years ago

Dotdrop version: v1.7.1 Using dotdrop: from PyPI

Consider a repo with the following config.yaml:

config:
  create: true
  dotpath: dotfiles
  force_chmod: true

dotfiles:
  d_dir:
    src: dir
    dst: ~/dir
    cmpignore:
      - '*'
      - '!file'

profiles:
  base:
    dotfiles:
      - d_dir

and where dir/ contains exactly one file, file. If I install this repo with dotdrop, edit ~/dir/file, create a file ~/dir/extra, and then run dotdrop compare -p base, I expect to see a diff for dir/file and no information about dir/extra. However, I instead get no information about any differences between dotfiles. This remains true regardless of whether '!file' is changed to '!*/file' or '!*/dir/file' and regardless of whether it's placed before or after the '*'.

Output from dotdrop compare -p base --verbose:

[DEBUG][dotdrop.options.__init__] #################################################
[DEBUG][dotdrop.options.__init__] #################### DOTDROP ####################
[DEBUG][dotdrop.options.__init__] #################################################
[DEBUG][dotdrop.options.__init__] version: 1.7.1
[DEBUG][dotdrop.options.__init__] command: /usr/local/bin/dotdrop compare -p base --verbose
[DEBUG][dotdrop.options.__init__] config file: config.yaml
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] ----------start:/root/dotdrop/config.yaml----------
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] 
config:
  create: true
  dotpath: dotfiles
  force_chmod: true

dotfiles:
  d_dir:
    src: dir
    dst: ~/dir
    cmpignore:
      - '*'
      - '!file'

profiles:
  base:
    dotfiles:
      - d_dir
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] ----------end:/root/dotdrop/config.yaml----------
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] normalizing relative to cfg: dotfiles -> /root/dotdrop/dotfiles
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] settings block::
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "backup": None
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "banner": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "create": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "dotpath": /root/dotdrop/dotfiles
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "ignoreempty": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "keepdot": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "link_dotfile_default": nolink
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "link_on_import": nolink
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "longkey": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "showdiff": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "workdir": /root/.config/dotdrop
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "minversion": None
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "diff_command": diff -r -u {0} {1}
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "template_dotfile_default": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "ignore_missing_in_dotdrop": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "force_chmod": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "default_actions": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "import_actions": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "import_configs": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "import_variables": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "cmpignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "upignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "instignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "impignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "func_file": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "filter_file": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] variables block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] dynvariables block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] current variables defined:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "profile": base
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_dotpath": /root/dotdrop/dotfiles
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_cfgpath": /root/dotdrop/config.yaml
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_workdir": /root/.config/dotdrop
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] profiles block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "base": ordereddict([('dotfiles', ['d_dir'])])
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] current variables defined:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "profile": base
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_dotpath": /root/dotdrop/dotfiles
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_cfgpath": /root/dotdrop/config.yaml
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_workdir": /root/.config/dotdrop
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] current variables defined:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "profile": base
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_dotpath": /root/dotdrop/dotfiles
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_cfgpath": /root/dotdrop/config.yaml
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_workdir": /root/.config/dotdrop
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] dotfiles block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "d_dir": ordereddict([('src', 'dir'), ('dst', '~/dir'), ('cmpignore', ['*', '!file']), ('link', 'nolink'), ('ignoreempty', False), ('template', True)])
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] actions block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] trans_r block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] trans_w block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] templating dotfiles entries
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] uservariables block:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] ########### final config ###########
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] Current entries
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] entry settings:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "backup": None
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "banner": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "create": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "dotpath": /root/dotdrop/dotfiles
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "ignoreempty": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "keepdot": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "link_dotfile_default": nolink
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "link_on_import": nolink
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "longkey": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "showdiff": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "workdir": /root/.config/dotdrop
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "minversion": None
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "diff_command": diff -r -u {0} {1}
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "template_dotfile_default": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "ignore_missing_in_dotdrop": False
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "force_chmod": True
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "default_actions": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "import_actions": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "import_configs": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "import_variables": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "cmpignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "upignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "instignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "impignore": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "func_file": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "filter_file": []
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] entry dotfiles:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "d_dir": ordereddict([('src', '/root/dotdrop/dotfiles/dir'), ('dst', '/root/dir'), ('cmpignore', ['*', '!file']), ('link', 'nolink'), ('ignoreempty', False), ('template', True)])
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] entry profiles:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "base": ordereddict([('dotfiles', ['d_dir'])])
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] entry actions:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] entry trans_r:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] entry trans_w:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml] entry variables:
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "profile": base
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_dotpath": /root/dotdrop/dotfiles
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_cfgpath": /root/dotdrop/config.yaml
[DEBUG][dotdrop.cfg_yaml._dbg] [config.yaml]    - "_dotdrop_workdir": /root/.config/dotdrop
[DEBUG][dotdrop.cfg_aggregator._patch_keys_to_objs] patching dotfiles ...
[DEBUG][dotdrop.cfg_aggregator._patch_keys_to_objs] patching actions ...
[DEBUG][dotdrop.cfg_aggregator._patch_keys_to_objs] patching actions ...
[DEBUG][dotdrop.cfg_aggregator._patch_keys_to_objs] patching default_actions ...
[DEBUG][dotdrop.cfg_aggregator._load] default actions: []
[DEBUG][dotdrop.cfg_aggregator._patch_keys_to_objs] patching trans_r ...
[DEBUG][dotdrop.cfg_aggregator._patch_keys_to_objs] patching trans_w ...
[DEBUG][dotdrop.options._debug_attr] effective options:
[DEBUG][dotdrop.options._debug_attr] -> backup: None
[DEBUG][dotdrop.options._debug_attr] -> banner: True
[DEBUG][dotdrop.options._debug_attr] -> cmd_compare: True
[DEBUG][dotdrop.options._debug_attr] -> cmd_detail: False
[DEBUG][dotdrop.options._debug_attr] -> cmd_files: False
[DEBUG][dotdrop.options._debug_attr] -> cmd_import: False
[DEBUG][dotdrop.options._debug_attr] -> cmd_install: False
[DEBUG][dotdrop.options._debug_attr] -> cmd_profiles: False
[DEBUG][dotdrop.options._debug_attr] -> cmd_remove: False
[DEBUG][dotdrop.options._debug_attr] -> cmd_update: False
[DEBUG][dotdrop.options._debug_attr] -> compare_fileonly: False
[DEBUG][dotdrop.options._debug_attr] -> conf: <dotdrop.cfg_aggregator.CfgAggregator object at 0x7f655d23da30>
[DEBUG][dotdrop.options._debug_attr] -> confpath: config.yaml
[DEBUG][dotdrop.options._debug_attr] -> create: True
[DEBUG][dotdrop.options._debug_attr] -> debug: True
[DEBUG][dotdrop.options._debug_attr] -> diff_command: diff -r -u {0} {1}
[DEBUG][dotdrop.options._debug_attr] -> dotpath: /root/dotdrop/dotfiles
[DEBUG][dotdrop.options._debug_attr] -> dry: False
[DEBUG][dotdrop.options._debug_attr] -> files_grepable: False
[DEBUG][dotdrop.options._debug_attr] -> files_templateonly: False
[DEBUG][dotdrop.options._debug_attr] -> force_chmod: True
[DEBUG][dotdrop.options._debug_attr] -> ignore_missing_in_dotdrop: False
[DEBUG][dotdrop.options._debug_attr] -> ignoreempty: False
[DEBUG][dotdrop.options._debug_attr] -> import_as: None
[DEBUG][dotdrop.options._debug_attr] -> import_link: nolink
[DEBUG][dotdrop.options._debug_attr] -> import_mode: False
[DEBUG][dotdrop.options._debug_attr] -> install_backup_suffix: .dotdropbak
[DEBUG][dotdrop.options._debug_attr] -> install_diff: True
[DEBUG][dotdrop.options._debug_attr] -> install_force_action: False
[DEBUG][dotdrop.options._debug_attr] -> install_force_chmod: True
[DEBUG][dotdrop.options._debug_attr] -> install_showdiff: False
[DEBUG][dotdrop.options._debug_attr] -> install_temporary: False
[DEBUG][dotdrop.options._debug_attr] -> keepdot: False
[DEBUG][dotdrop.options._debug_attr] -> link_dotfile_default: nolink
[DEBUG][dotdrop.options._debug_attr] -> link_on_import: nolink
[DEBUG][dotdrop.options._debug_attr] -> log: <dotdrop.logger.Logger object at 0x7f655d2c3760>
[DEBUG][dotdrop.options._debug_attr] -> longkey: False
[DEBUG][dotdrop.options._debug_attr] -> minversion: None
[DEBUG][dotdrop.options._debug_attr] -> profile: base
[DEBUG][dotdrop.options._debug_attr] -> profiles_grepable: False
[DEBUG][dotdrop.options._debug_attr] -> remove_iskey: False
[DEBUG][dotdrop.options._debug_attr] -> safe: True
[DEBUG][dotdrop.options._debug_attr] -> showdiff: False
[DEBUG][dotdrop.options._debug_attr] -> template_dotfile_default: True
[DEBUG][dotdrop.options._debug_attr] -> update_iskey: False
[DEBUG][dotdrop.options._debug_attr] -> update_showpatch: False
[DEBUG][dotdrop.options._debug_attr] -> workdir: /root/.config/dotdrop
[DEBUG][dotdrop.options._debug_attr] -> workers: 1
[DEBUG][dotdrop.dotdrop.main] 

[DEBUG][dotdrop.dotdrop._exec_command] running cmd: compare
[DEBUG][dotdrop.templategen.__init__] load global functions:
[DEBUG][dotdrop.templategen._load_funcs_to_dic] load function "basename"
[DEBUG][dotdrop.templategen._load_funcs_to_dic] load function "dirname"
[DEBUG][dotdrop.templategen._load_funcs_to_dic] load function "exists"
[DEBUG][dotdrop.templategen._load_funcs_to_dic] load function "exists_in_path"
[DEBUG][dotdrop.templategen._debug_dict] template additional variables:
[DEBUG][dotdrop.templategen._debug_dict]   - "profile": base
[DEBUG][dotdrop.templategen._debug_dict]   - "_dotdrop_dotpath": /root/dotdrop/dotfiles
[DEBUG][dotdrop.templategen._debug_dict]   - "_dotdrop_cfgpath": /root/dotdrop/config.yaml
[DEBUG][dotdrop.templategen._debug_dict]   - "_dotdrop_workdir": /root/.config/dotdrop
[DEBUG][dotdrop.dotdrop._dotfile_compare] comparing key:"d_dir", src:"/root/dotdrop/dotfiles/dir", dst:"/root/dir", link:"nolink", template:True
[DEBUG][dotdrop.utils.patch_ignores] ignores before patching: ['!file', '*', '*.dotdropbak']
[DEBUG][dotdrop.utils.patch_ignores] ignores after patching: ['!/root/dir/file', '*', '*.dotdropbak']
[DEBUG][dotdrop.comparator.compare] comparing /root/dotdrop/dotfiles/dir and /root/dir
[DEBUG][dotdrop.comparator.compare] ignore pattern(s): ['!/root/dir/file', '*', '*.dotdropbak']
[DEBUG][dotdrop.comparator.compare] /root/dotdrop/dotfiles/dir is a directory
[DEBUG][dotdrop.comparator._comp_dir] compare directory /root/dotdrop/dotfiles/dir with /root/dir
[DEBUG][dotdrop.utils.must_ignore] must ignore? "['/root/dotdrop/dotfiles/dir', '/root/dir']" against ['!/root/dir/file', '*', '*.dotdropbak']
[DEBUG][dotdrop.utils.must_ignore] ignore "*" match: /root/dotdrop/dotfiles/dir
[DEBUG][dotdrop.comparator._comp_dir] ignoring diff /root/dotdrop/dotfiles/dir and /root/dir
[DEBUG][dotdrop.dotdrop._dotfile_compare] => compare d_dir: diffing with "/root/dir"
[DEBUG][dotdrop.dotdrop._dotfile_compare] same file
[DEBUG][dotdrop.dotdrop.main] done executing command "compare"
[DEBUG][dotdrop.dotdrop.main] options loaded in 0.29489946365356445
[DEBUG][dotdrop.dotdrop.main] command executed in 0.04354381561279297
[DEBUG][dotdrop.dotdrop.main] return True
     _       _      _
  __| | ___ | |_ __| |_ __ ___  _ __
 / _` |/ _ \| __/ _` | '__/ _ \| '_ |
 \__,_|\___/ \__\__,_|_|  \___/| .__/  v1.7.1
                               |_|

1 dotfile(s) compared.
deadc0de6 commented 3 years ago

Thanks for submitting this. Well when using * everything is ignored (no exceptions).

One way of solving your issue is to use a a pattern like this:

    cmpignore:
      - '!file'
      - '[a-zA-Z0-9]*'

Which translates to ignore everything starting with a to z and so on except file (the !file).

deadc0de6 commented 3 years ago

I'll add this to the doc

jwodder commented 3 years ago

@deadc0de6 That solution works, thanks!