aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Jon Bernard <jbernard@jbernard.io> 2020-01-24 14:48:18 -0500
committerGravatar Jon Bernard <jbernard@jbernard.io> 2020-01-24 14:48:18 -0500
commitaf77d1d02891533476ccb57d07b45fe1697a86f5 (patch)
tree3525a2607e1be00dbd96a21895413e67ef35efbb
parenta67f9a98e73c09c134e515f66bdae9cf5f450bd3 (diff)
downloaddotfiles-af77d1d02891533476ccb57d07b45fe1697a86f5.tar.gz
dotfiles-af77d1d02891533476ccb57d07b45fe1697a86f5.tar.bz2
dotfiles-af77d1d02891533476ccb57d07b45fe1697a86f5.zip
-rw-r--r--dotfiles/cli.py3
-rw-r--r--dotfiles/dotfile.py14
-rw-r--r--dotfiles/exceptions.py5
-rw-r--r--dotfiles/repository.py28
4 files changed, 44 insertions, 6 deletions
diff --git a/dotfiles/cli.py b/dotfiles/cli.py
index c58b40f..2748d51 100644
--- a/dotfiles/cli.py
+++ b/dotfiles/cli.py
@@ -25,6 +25,7 @@ def confirm(method, files, repo):
"""
if files:
# user has specified specific files, so we are not assuming all
+ # FIXME: this may be a directory that requires expansion
return files
# no files provided, so we assume all files after confirmation
message = 'Are you sure you want to %s all dotfiles?' % method
@@ -84,6 +85,8 @@ def cli(ctx, repos):
ctx.obj = Repositories(repos)
except FileNotFoundError as e:
raise click.ClickException('Directory not found: %s' % e)
+ except DotfileException as e:
+ raise click.ClickException(e)
@cli.command()
diff --git a/dotfiles/dotfile.py b/dotfiles/dotfile.py
index d81e585..64bfabb 100644
--- a/dotfiles/dotfile.py
+++ b/dotfiles/dotfile.py
@@ -31,6 +31,16 @@ class Dotfile(object):
def __repr__(self):
return '<Dotfile %r>' % self.name
+ def __hash__(self):
+ return hash((self.name, self.target))
+
+ def __eq__(self, othr):
+ return ((self.name, self.target) ==
+ (othr.name, othr.target))
+
+ def __lt__(self, othr):
+ return self.name < othr.name
+
def _ensure_dirs(self, debug):
"""Ensure the directories for both name and target are in place.
@@ -145,9 +155,11 @@ class Dotfile(object):
if copy:
raise NotImplementedError()
if self.name.exists():
- raise Exists(self.name)
+ # nothing to do
+ return
if not self.target.exists():
raise TargetMissing(self.name)
+ import pdb; pdb.set_trace()
self._ensure_dirs(debug)
self._link(debug, home)
diff --git a/dotfiles/exceptions.py b/dotfiles/exceptions.py
index cb6021c..7f9b5c6 100644
--- a/dotfiles/exceptions.py
+++ b/dotfiles/exceptions.py
@@ -8,6 +8,11 @@ class DotfileException(Exception):
return 'ERROR: %s' % self.message
+class RepositoryNotFound(DotfileException):
+ def __init__(self, path):
+ DotfileException.__init__(self, path, 'repository not found')
+
+
class IsDirectory(DotfileException):
def __init__(self, path):
DotfileException.__init__(self, path, 'is a directory')
diff --git a/dotfiles/repository.py b/dotfiles/repository.py
index 8d118cf..c231a55 100644
--- a/dotfiles/repository.py
+++ b/dotfiles/repository.py
@@ -6,6 +6,7 @@ from fnmatch import fnmatch
from operator import attrgetter
from .dotfile import Dotfile
+from .exceptions import RepositoryNotFound
from .exceptions import DotfileException, TargetIgnored
from .exceptions import NotRootedInHome, InRepository, IsDirectory
@@ -26,6 +27,7 @@ class Repositories(object):
class Repository(object):
"""A repository is a directory that contains dotfiles."""
+ CREATE_REPOSITORY = False
REMOVE_LEADING_DOT = True
IGNORE_PATTERNS = ['.git/*', '.gitignore', 'README*', '*~']
@@ -34,8 +36,11 @@ class Repository(object):
self.home = Path(home).expanduser().resolve()
if not self.path.exists():
- echo('Creating new repository: %s' % self.path)
- self.path.mkdir(parents=True, exist_ok=True)
+ if self.CREATE_REPOSITORY:
+ self.path.mkdir(parents=True, exist_ok=True)
+ echo('Created new repository: %s' % self.path)
+ else:
+ raise RepositoryNotFound(self.path)
if not self.home.exists():
raise FileNotFoundError(self.home)
@@ -83,6 +88,7 @@ class Repository(object):
if not fnmatch(str(path), '%s/*' % self.home):
raise NotRootedInHome(path)
if fnmatch(str(path), '%s/*' % self.path):
+ print('oh no')
raise InRepository(path)
if self._ignore(target):
raise TargetIgnored(path)
@@ -98,12 +104,15 @@ class Repository(object):
return [x for x in dir.rglob('*') if not skip(x)]
- def contents(self):
+ def contents(self, subdir=None):
"""Return dotfile objects for each file in the repository."""
def construct(target):
return Dotfile(self._dotfile_path(target), target)
- contents = self._contents(self.path)
+ path = subdir if subdir else self.path
+ path.relative_to(self.path)
+
+ contents = self._contents(path)
return sorted(map(construct, contents), key=attrgetter('name'))
def dotfiles(self, paths):
@@ -116,9 +125,14 @@ class Repository(object):
dotfiles is returned to the caller.
"""
paths = [Path(x).expanduser().absolute() for x in paths]
+ dotfiles = []
+
+ # if dir doesn't exist, this breaks
+ # need to get entire list and compare each one as a subset
for path in paths:
if path.is_dir():
+ dotfiles.extend(self.contents(self._dotfile_target(path)))
paths.extend(self._contents(path))
paths.remove(path)
@@ -129,7 +143,11 @@ class Repository(object):
echo(err)
return None
- return [d for d in map(construct, paths) if d is not None]
+ # return [d for d in map(construct, paths) if d is not None]
+
+ dotfiles.extend([d for d in map(construct, paths) if d])
+ return sorted(set(dotfiles))
+
def prune(self, debug=False):
"""Remove any empty directories in the repository.