Support DOTFILEMANAGER_HOSTNAME environment variable.
Fix bug with relative paths: always convert paths retrieved from the command line args or from reading a link to absolute paths and expand ~'s. Silence some print statements unless doing the report action. Delete an unnecessary `path = os.path.join(to_dir,filename)` line.
This commit is contained in:
parent
e2fce1a2fb
commit
24c0732753
@ -40,7 +40,7 @@ linked to. On other hosts _muttrc will be linked to.
|
|||||||
(To discover the hostname of your machine run `uname -n`.)
|
(To discover the hostname of your machine run `uname -n`.)
|
||||||
|
|
||||||
`dotfilemanager tidy` will remove any dangling symlinks in FROM_DIR, and
|
`dotfilemanager tidy` will remove any dangling symlinks in FROM_DIR, and
|
||||||
`dotfilemanager report` will just report on what link or tidy would do
|
`dotfilemanager report` will just report on what link and tidy would do
|
||||||
without actually making any changes to the filesystem.
|
without actually making any changes to the filesystem.
|
||||||
|
|
||||||
Tip: handle directories like ~/.config separately
|
Tip: handle directories like ~/.config separately
|
||||||
@ -65,21 +65,25 @@ commands:
|
|||||||
dotfilemanager.py link ~ ~/.dotfiles
|
dotfilemanager.py link ~ ~/.dotfiles
|
||||||
dotfilemanager.py link ~/.config ~/config
|
dotfilemanager.py link ~/.config ~/config
|
||||||
|
|
||||||
TODO
|
Tip: override hostname with DOTFILEMANAGER_HOSTNAME environment variable
|
||||||
----
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
Support hostname as a command-line argument, overriding the system
|
If the DOTFILEMANAGER_HOSTNAME environment variable is set then it is used
|
||||||
hostname. This might be useful for accounts on networked systems where
|
instead of your real hostname to resolve hostname-specific files in TO_DIR.
|
||||||
you login to the same user account from different computers, the system
|
This is useful for accounts on networked systems where you login to the same
|
||||||
hostname will be different each time you switch computers but you want
|
user account from different computers, the system hostname will be different
|
||||||
to use the same config files whenever you login to this account. So just
|
each time you switch computers but you want to use the same config files
|
||||||
make up a name for the account and pass it as a command-line argument
|
whenever you login to this account. So just make up a name for the account and
|
||||||
overriding the system hostname.
|
set it as the value of DOTFILEMANAGER_HOSTNAME.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import os,sys,platform
|
import os,sys,platform
|
||||||
|
|
||||||
HOSTNAME = platform.node()
|
# TODO: allow setting hostname as a command-line argument also?
|
||||||
|
try:
|
||||||
|
HOSTNAME = os.environ['DOTFILEMANAGER_HOSTNAME']
|
||||||
|
except KeyError:
|
||||||
|
HOSTNAME = platform.node()
|
||||||
HOSTNAME_SEPARATOR = '__'
|
HOSTNAME_SEPARATOR = '__'
|
||||||
|
|
||||||
def tidy(d,report=False):
|
def tidy(d,report=False):
|
||||||
@ -97,9 +101,7 @@ def tidy(d,report=False):
|
|||||||
path = os.path.join(d,f)
|
path = os.path.join(d,f)
|
||||||
if os.path.islink(path):
|
if os.path.islink(path):
|
||||||
target_path = os.readlink(path)
|
target_path = os.readlink(path)
|
||||||
if not os.path.isabs(target_path):
|
target_path = os.path.abspath(os.path.expanduser(target_path))
|
||||||
# This is a relative symlink, resolve it.
|
|
||||||
target_path = os.path.join(os.path.dirname(path),target_path)
|
|
||||||
if not os.path.exists(target_path):
|
if not os.path.exists(target_path):
|
||||||
# This is a broken symlink.
|
# This is a broken symlink.
|
||||||
if report:
|
if report:
|
||||||
@ -108,7 +110,7 @@ def tidy(d,report=False):
|
|||||||
print 'Deleting broken symlink: %s->%s' % (path,target_path)
|
print 'Deleting broken symlink: %s->%s' % (path,target_path)
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|
||||||
def get_target_paths(to_dir):
|
def get_target_paths(to_dir,report=False):
|
||||||
"""Return the list of absolute paths to link to for a given to_dir.
|
"""Return the list of absolute paths to link to for a given to_dir.
|
||||||
|
|
||||||
This handles skipping various types of filename in to_dir and
|
This handles skipping various types of filename in to_dir and
|
||||||
@ -120,12 +122,15 @@ def get_target_paths(to_dir):
|
|||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
path = os.path.join(to_dir,filename)
|
path = os.path.join(to_dir,filename)
|
||||||
if filename.endswith('~'):
|
if filename.endswith('~'):
|
||||||
|
if report:
|
||||||
print 'Skipping %s' % filename
|
print 'Skipping %s' % filename
|
||||||
continue
|
continue
|
||||||
elif (not os.path.isfile(path)) and (not os.path.isdir(path)):
|
elif (not os.path.isfile(path)) and (not os.path.isdir(path)):
|
||||||
|
if report:
|
||||||
print 'Skipping %s (not a file or directory)' % filename
|
print 'Skipping %s (not a file or directory)' % filename
|
||||||
continue
|
continue
|
||||||
elif filename.startswith('.'):
|
elif filename.startswith('.'):
|
||||||
|
if report:
|
||||||
print 'Skipping %s (filename has a leading dot)' % filename
|
print 'Skipping %s (filename has a leading dot)' % filename
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@ -136,15 +141,16 @@ def get_target_paths(to_dir):
|
|||||||
# link to it.
|
# link to it.
|
||||||
hostname = filename.split(HOSTNAME_SEPARATOR)[-1]
|
hostname = filename.split(HOSTNAME_SEPARATOR)[-1]
|
||||||
if hostname == HOSTNAME:
|
if hostname == HOSTNAME:
|
||||||
path = os.path.join(to_dir,filename)
|
|
||||||
paths.append(path)
|
paths.append(path)
|
||||||
else:
|
else:
|
||||||
|
if report:
|
||||||
print 'Skipping %s (different hostname)' % filename
|
print 'Skipping %s (different hostname)' % filename
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
# This appears to be a filename without a trailing
|
# This appears to be a filename without a trailing
|
||||||
# hostname.
|
# hostname.
|
||||||
if filename + HOSTNAME_SEPARATOR + HOSTNAME in filenames:
|
if filename + HOSTNAME_SEPARATOR + HOSTNAME in filenames:
|
||||||
|
if report:
|
||||||
print 'Skipping %s (there is a host-specific version of this file for this host)' % filename
|
print 'Skipping %s (there is a host-specific version of this file for this host)' % filename
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@ -170,7 +176,7 @@ def link(from_dir,to_dir,report=False):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
# The paths in to_dir that we will be symlinking to.
|
# The paths in to_dir that we will be symlinking to.
|
||||||
to_paths = get_target_paths(to_dir)
|
to_paths = get_target_paths(to_dir,report)
|
||||||
|
|
||||||
# Dictionary of symlinks we will be creating, from_path->to_path
|
# Dictionary of symlinks we will be creating, from_path->to_path
|
||||||
symlinks = {}
|
symlinks = {}
|
||||||
@ -194,6 +200,7 @@ def link(from_dir,to_dir,report=False):
|
|||||||
if os.path.islink(from_path):
|
if os.path.islink(from_path):
|
||||||
# A link already exists.
|
# A link already exists.
|
||||||
existing_to_path = os.readlink(from_path)
|
existing_to_path = os.readlink(from_path)
|
||||||
|
existing_to_path = os.path.abspath(os.path.expanduser(existing_to_path))
|
||||||
if existing_to_path == to_path:
|
if existing_to_path == to_path:
|
||||||
# It's already a link to the intended target. All is
|
# It's already a link to the intended target. All is
|
||||||
# well.
|
# well.
|
||||||
@ -237,7 +244,7 @@ if __name__ == "__main__":
|
|||||||
try:
|
try:
|
||||||
FROM_DIR = sys.argv[2]
|
FROM_DIR = sys.argv[2]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
FROM_DIR = os.path.expanduser('~')
|
FROM_DIR = '~'
|
||||||
if not os.path.isdir(FROM_DIR):
|
if not os.path.isdir(FROM_DIR):
|
||||||
print "FROM_DIR %s is not a directory!" % FROM_DIR
|
print "FROM_DIR %s is not a directory!" % FROM_DIR
|
||||||
print usage()
|
print usage()
|
||||||
@ -245,12 +252,15 @@ if __name__ == "__main__":
|
|||||||
try:
|
try:
|
||||||
TO_DIR = sys.argv[3]
|
TO_DIR = sys.argv[3]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
TO_DIR = os.path.join(os.path.expanduser('~'),'.dotfiles')
|
TO_DIR = os.path.join('~','.dotfiles')
|
||||||
if not os.path.isdir(TO_DIR):
|
if not os.path.isdir(TO_DIR):
|
||||||
print "TO_DIR %s is not a directory!" % TO_DIR
|
print "TO_DIR %s is not a directory!" % TO_DIR
|
||||||
print usage()
|
print usage()
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
|
TO_DIR = os.path.abspath(os.path.expanduser(TO_DIR))
|
||||||
|
FROM_DIR = os.path.abspath(os.path.expanduser(FROM_DIR))
|
||||||
|
|
||||||
if ACTION == 'link':
|
if ACTION == 'link':
|
||||||
link(FROM_DIR,TO_DIR)
|
link(FROM_DIR,TO_DIR)
|
||||||
elif ACTION == 'tidy':
|
elif ACTION == 'tidy':
|
||||||
|
Loading…
Reference in New Issue
Block a user