1
0
mirror of https://github.com/deadc0de6/dotdrop.git synced 2026-02-06 20:05:39 +00:00

add chmod to import command

This commit is contained in:
deadc0de6
2020-11-09 13:36:48 +01:00
parent fc53ea23ce
commit fc9c12c1b0
6 changed files with 72 additions and 13 deletions

View File

@@ -149,27 +149,28 @@ class CfgAggregator:
"""remove this dotfile from this profile"""
return self.cfgyaml.del_dotfile_from_profile(dotfile.key, profile.key)
def _create_new_dotfile(self, src, dst, link):
def _create_new_dotfile(self, src, dst, link, chmod=None):
"""create a new dotfile"""
# get a new dotfile with a unique key
key = self._get_new_dotfile_key(dst)
if self.debug:
self.log.dbg('new dotfile key: {}'.format(key))
# add the dotfile
self.cfgyaml.add_dotfile(key, src, dst, link)
self.cfgyaml.add_dotfile(key, src, dst, link, chmod=chmod)
return Dotfile(key, dst, src)
def new(self, src, dst, link):
def new(self, src, dst, link, chmod=None):
"""
import a new dotfile
@src: path in dotpath
@dst: path in FS
@link: LinkType
@chmod: file permission
"""
dst = self.path_to_dotfile_dst(dst)
dotfile = self.get_dotfile_by_src_dst(src, dst)
if not dotfile:
dotfile = self._create_new_dotfile(src, dst, link)
dotfile = self._create_new_dotfile(src, dst, link, chmod=chmod)
key = dotfile.key
ret = self.cfgyaml.add_dotfile_to_profile(key, self.profile_key)

View File

@@ -58,6 +58,7 @@ class CfgYaml:
key_dotfile_actions = 'actions'
key_dotfile_noempty = 'ignoreempty'
key_dotfile_template = 'template'
key_dotfile_chmod = 'chmod'
# profile
key_profile_dotfiles = 'dotfiles'
@@ -316,7 +317,7 @@ class CfgYaml:
"""return all existing dotfile keys"""
return self.dotfiles.keys()
def add_dotfile(self, key, src, dst, link):
def add_dotfile(self, key, src, dst, link, chmod=None):
"""add a new dotfile"""
if key in self.dotfiles.keys():
return False
@@ -324,14 +325,23 @@ class CfgYaml:
self._dbg('adding new dotfile: {}'.format(key))
self._dbg('new dotfile src: {}'.format(src))
self._dbg('new dotfile dst: {}'.format(dst))
self._dbg('new dotfile link: {}'.format(link))
if chmod:
self._dbg('new dotfile chmod: {}'.format(chmod))
df_dict = {
self.key_dotfile_src: src,
self.key_dotfile_dst: dst,
}
# link
dfl = self.settings[self.key_settings_link_dotfile_default]
if str(link) != dfl:
df_dict[self.key_dotfile_link] = str(link)
# chmod
if chmod:
df_dict[self.key_dotfile_chmod] = format(chmod, 'o')
# add to global dict
self._yaml_dict[self.key_dotfiles][key] = df_dict
self._dirty = True
@@ -623,6 +633,25 @@ class CfgYaml:
if self.key_dotfile_template not in v:
val = self.settings.get(self.key_settings_template, True)
v[self.key_dotfile_template] = val
# validate value of chmod if defined
if self.key_dotfile_chmod in v:
val = v[self.key_dotfile_chmod]
if len(val) < 3:
err = 'bad format for chmod: {}'.format(val)
self._log.err(err)
raise YamlException('dotfile chmod error: {}'.format(err))
try:
int(val)
except Exception:
err = 'bad format for chmod: {}'.format(val)
self._log.err(err)
raise YamlException('dotfile chmod error: {}'.format(err))
for x in val:
y = int(x)
if y < 0 or y > 7:
err = 'bad format for chmod: {}'.format(val)
self._log.err(err)
raise YamlException('dotfile chmod error: {}'.format(err))
return new

View File

@@ -19,7 +19,7 @@ from dotdrop.installer import Installer
from dotdrop.updater import Updater
from dotdrop.comparator import Comparator
from dotdrop.utils import get_tmpdir, removepath, strip_home, \
uniq_list, patch_ignores, dependencies_met
uniq_list, patch_ignores, dependencies_met, get_file_perm
from dotdrop.linktypes import LinkTypes
from dotdrop.exceptions import YamlException, UndefinedException
@@ -426,6 +426,9 @@ def cmd_importer(o):
strip = os.sep
src = src.lstrip(strip)
# get the permission
perm = get_file_perm(dst)
# set the link attribute
linktype = o.import_link
if linktype == LinkTypes.LINK_CHILDREN and \
@@ -485,16 +488,23 @@ def cmd_importer(o):
LOG.err('importing \"{}\" failed!'.format(path))
ret = False
continue
if o.dry:
LOG.dry('would copy {} to {}'.format(dst, srcf))
else:
# copy the file to the dotpath
if os.path.isdir(dst):
if os.path.exists(srcf):
shutil.rmtree(srcf)
shutil.copytree(dst, srcf)
else:
shutil.copy2(dst, srcf)
retconf = o.conf.new(src, dst, linktype)
chmod = None
if o.import_mode or perm&o.umask:
# insert chmod
chmod = perm
retconf = o.conf.new(src, dst, linktype, chmod=chmod)
if retconf:
LOG.sub('\"{}\" imported'.format(path))
cnt += 1

View File

@@ -22,7 +22,7 @@ class Dotfile(DictParser):
actions=[], trans_r=None, trans_w=None,
link=LinkTypes.NOLINK, noempty=False,
cmpignore=[], upignore=[],
instignore=[], template=True):
instignore=[], template=True, chmod=None):
"""
constructor
@key: dotfile key
@@ -37,6 +37,7 @@ class Dotfile(DictParser):
@cmpignore: patterns to ignore when comparing
@instignore: patterns to ignore when installing
@template: template this dotfile
@chmod: file permission
"""
self.actions = actions
self.dst = dst
@@ -50,6 +51,7 @@ class Dotfile(DictParser):
self.cmpignore = cmpignore
self.instignore = instignore
self.template = template
self.chmod = chmod
if self.link != LinkTypes.NOLINK and \
(
@@ -113,6 +115,7 @@ class Dotfile(DictParser):
msg += ', dst:\"{}\"'.format(self.dst)
msg += ', link:\"{}\"'.format(str(self.link))
msg += ', template:{}'.format(self.template)
msg += ', chmod:{}'.format(self.chmod)
return msg
def prt(self):
@@ -123,6 +126,7 @@ class Dotfile(DictParser):
out += '\n{}dst: \"{}\"'.format(indent, self.dst)
out += '\n{}link: \"{}\"'.format(indent, str(self.link))
out += '\n{}template: \"{}\"'.format(indent, str(self.template))
out += '\n{}chmod: \"{}\"'.format(indent, str(self.chmod))
out += '\n{}pre-action:'.format(indent)
some = self.get_pre_actions()

View File

@@ -16,7 +16,7 @@ from dotdrop.linktypes import LinkTypes
from dotdrop.logger import Logger
from dotdrop.cfg_aggregator import CfgAggregator as Cfg
from dotdrop.action import Action
from dotdrop.utils import uniq_list
from dotdrop.utils import uniq_list, get_umask
from dotdrop.exceptions import YamlException
ENV_PROFILE = 'DOTDROP_PROFILE'
@@ -54,7 +54,7 @@ USAGE = """
Usage:
dotdrop install [-VbtfndDa] [-c <path>] [-p <profile>]
[-w <nb>] [<key>...]
dotdrop import [-Vbdf] [-c <path>] [-p <profile>] [-s <path>]
dotdrop import [-Vbdfm] [-c <path>] [-p <profile>] [-s <path>]
[-l <link>] <path>...
dotdrop compare [-LVb] [-c <path>] [-p <profile>]
[-C <file>...] [-i <pattern>...]
@@ -73,15 +73,16 @@ Options:
-c --cfg=<path> Path to the config.
-C --file=<path> Path of dotfile to compare.
-d --dry Dry run.
-l --link=<link> Link option (nolink|link|link_children).
-L --file-only Do not show diff but only the files that differ.
-p --profile=<profile> Specify the profile to use [default: {}].
-D --showdiff Show a diff before overwriting.
-f --force Do not ask user confirmation for anything.
-G --grepable Grepable output.
-i --ignore=<pattern> Pattern to ignore.
-k --key Treat <path> as a dotfile key.
-l --link=<link> Link option (nolink|link|link_children).
-L --file-only Do not show diff but only the files that differ.
-m --preserve-mode Insert a chmod entry in the dotfile with its permissions.
-n --nodiff Do not diff when installing.
-p --profile=<profile> Specify the profile to use [default: {}].
-P --show-patch Provide a one-liner to manually patch template.
-s --as=<path> Import as a different path from actual path.
-t --temp Install to a temporary directory for review.
@@ -121,6 +122,7 @@ class Options(AttrMonitor):
self.log = Logger()
self.debug = self.args['--verbose'] or ENV_DEBUG in os.environ
self.dry = self.args['--dry']
self.umask = get_umask()
if ENV_NODEBUG in os.environ:
# force disabling debugs
self.debug = False
@@ -261,6 +263,7 @@ class Options(AttrMonitor):
# "import" specifics
self.import_path = self.args['<path>']
self.import_as = self.args['--as']
self.import_mode = self.args['--preserve-mode']
# "update" specifics
self.update_path = self.args['<path>']

View File

@@ -302,3 +302,15 @@ def mirror_file_rights(src, dst):
"""mirror file rights of src to dst (can rise exc)"""
rights = os.stat(src).st_mode
os.chmod(dst, rights)
def get_umask():
"""return current umask value"""
cur = os.umask(0)
os.umask(cur)
return 0o777-cur
def get_file_perm(path):
"""return file permission"""
return os.stat(path).st_mode & 0o777