diff options
author | Jon Bernard <jbernard@tuxion.com> | 2015-12-29 09:44:10 -0500 |
---|---|---|
committer | Jon Bernard <jbernard@tuxion.com> | 2015-12-29 09:47:55 -0500 |
commit | ee8a42ee6707d514bc0a4989a018db0561b4e6e9 (patch) | |
tree | 71fb78452266b8462866b97a466fb329839e23a0 | |
parent | 20079411b5acfbf533892b942227c7b0690acf32 (diff) | |
download | dotfiles-ee8a42ee6707d514bc0a4989a018db0561b4e6e9.tar.gz dotfiles-ee8a42ee6707d514bc0a4989a018db0561b4e6e9.tar.bz2 dotfiles-ee8a42ee6707d514bc0a4989a018db0561b4e6e9.zip |
Add dotfile class rework
This version of the dotfile class uses py.path.local and removes much of
the cruft of using os.path and it's associated requirements.
There are still a few things missing, namely dry_run mode where commands
are printed instead of executed and force sync. They will be included
as required.
-rw-r--r-- | dotfiles/dotfile.py | 43 | ||||
-rw-r--r-- | tests/test_dotfile.py | 112 |
2 files changed, 155 insertions, 0 deletions
diff --git a/dotfiles/dotfile.py b/dotfiles/dotfile.py new file mode 100644 index 0000000..ed0b2cb --- /dev/null +++ b/dotfiles/dotfile.py @@ -0,0 +1,43 @@ +import errno + + +class Dotfile: + """ + This class implements the 'dotfile' abstraction. + + A dotfile has two primary attributes: + + name -- name of dotfile in the home directory (~/.vimrc) + target -- target the dotfile should point to (~/Dotfiles/vimrc) + + The above attributes are both py.path.local objects. + + The goal is for there to be no special logic or stored global state. Only + the implementation of three operations made available to the caller: + + add -- moves a dotfile into the repository and replaces it with a symlink + remove -- the opposite of add + sync -- ensure that each repository file has a corresponding symlink + + This is where most filesystem operaitons (link, delete, etc) should be + called, and not in the layers above. + """ + + def __init__(self, name, target): + self.name = name + self.target = target + + def add(self): + if self.target.check(exists=1): + raise OSError(errno.EEXIST, self.target) + self.name.move(self.target) + self.sync() + + def remove(self): + if self.target.check(exists=0): + raise OSError(errno.ENOENT, self.target) + self.name.remove() + self.target.move(self.name) + + def sync(self): + self.name.mksymlinkto(self.target) diff --git a/tests/test_dotfile.py b/tests/test_dotfile.py new file mode 100644 index 0000000..b854859 --- /dev/null +++ b/tests/test_dotfile.py @@ -0,0 +1,112 @@ +import pytest +import py.error +from dotfiles.dotfile import Dotfile + + +class TestAdd: + + def test_add(self, tmpdir): + + repo = tmpdir.ensure("Dotfiles", dir=1) + name = tmpdir.ensure(".vimrc") + target = repo.join("vimrc") + + dotfile = Dotfile(name, target) + dotfile.add() + + assert target.check(file=1, link=0) + assert name.check(file=1, link=1) + assert name.samefile(target) + + def test_add_twice(self, tmpdir): + + repo = tmpdir.ensure("Dotfiles", dir=1) + name = tmpdir.ensure(".vimrc") + target = repo.join("vimrc") + + dotfile = Dotfile(name, target) + dotfile.add() + + assert target.check(file=1, link=0) + assert name.check(file=1, link=1) + assert name.samefile(target) + + with pytest.raises(OSError): + dotfile.add() + + assert target.check(file=1, link=0) + assert name.check(file=1, link=1) + assert name.samefile(target) + + +class TestRemove: + + def test_remove(self, tmpdir): + + repo = tmpdir.ensure("Dotfiles", dir=1) + name = tmpdir.join(".vimrc") + target = repo.ensure("vimrc") + + name.mksymlinkto(target) + + dotfile = Dotfile(name, target) + dotfile.remove() + + assert False == target.check() + assert name.check(file=1, link=0) + + def test_remove_twice(self, tmpdir): + + repo = tmpdir.ensure("Dotfiles", dir=1) + name = tmpdir.join(".vimrc") + target = repo.ensure("vimrc") + + name.mksymlinkto(target) + + dotfile = Dotfile(name, target) + dotfile.remove() + + assert False == target.check() + assert name.check(file=1, link=0) + + with pytest.raises(OSError): + dotfile.remove() + + assert False == target.check() + assert name.check(file=1, link=0) + + +class TestSync: + + def test_sync(self, tmpdir): + + repo = tmpdir.ensure("Dotfiles", dir=1) + name = tmpdir.join(".vimrc") + target = repo.ensure("vimrc") + + dotfile = Dotfile(name, target) + dotfile.sync() + + assert target.check(file=1, link=0) + assert name.check(file=1, link=1) + assert name.samefile(target) + + def test_sync_twice(self, tmpdir): + + repo = tmpdir.ensure("Dotfiles", dir=1) + name = tmpdir.join(".vimrc") + target = repo.ensure("vimrc") + + dotfile = Dotfile(name, target) + dotfile.sync() + + assert target.check(file=1, link=0) + assert name.check(file=1, link=1) + assert name.samefile(target) + + with pytest.raises(py.error.EEXIST): + dotfile.sync() + + assert target.check(file=1, link=0) + assert name.check(file=1, link=1) + assert name.samefile(target) |