Skip to content
This repository has been archived by the owner on Oct 3, 2019. It is now read-only.

Commit

Permalink
Create files when calling update_file
Browse files Browse the repository at this point in the history
  • Loading branch information
jacebrowning committed Jul 19, 2015
1 parent d55f9d3 commit fdd4157
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 22 deletions.
2 changes: 1 addition & 1 deletion yorm/__init__.py
Expand Up @@ -3,7 +3,7 @@
import sys

__project__ = 'YORM'
__version__ = '0.5.a1'
__version__ = '0.5.a2'

VERSION = __project__ + '-' + __version__

Expand Down
2 changes: 1 addition & 1 deletion yorm/exceptions.py
Expand Up @@ -35,6 +35,6 @@ class ConversionError(Error, ValueError):
"""Value could not be converted to the specified type."""


class UseageError(Error):
class MappingError(Error):

"""The API was called incorrectly."""
25 changes: 19 additions & 6 deletions yorm/test/test_utilities.py
Expand Up @@ -88,7 +88,7 @@ def test_with_attrs(self):
def test_multiple(self):
"""Verify mapping cannot be enabled twice."""
sample = utilities.sync(self.Sample(), "sample.yml")
with pytest.raises(exceptions.UseageError):
with pytest.raises(exceptions.MappingError):
utilities.sync(sample, "sample.yml")

@patch('os.path.isfile', Mock(return_value=True))
Expand Down Expand Up @@ -333,7 +333,7 @@ def test_update_wrong_base(self):
"""Verify an exception is raised with the wrong base."""
instance = Mock()

with pytest.raises(exceptions.UseageError):
with pytest.raises(exceptions.MappingError):
utilities.update(instance)


Expand All @@ -355,7 +355,7 @@ def test_update_wrong_base(self):
"""Verify an exception is raised with the wrong base."""
instance = Mock()

with pytest.raises(exceptions.UseageError):
with pytest.raises(exceptions.MappingError):
utilities.update_object(instance)


Expand All @@ -370,14 +370,15 @@ def test_update(self):

utilities.update_file(instance)

assert not instance.yorm_mapper.fetch.called
assert instance.yorm_mapper.store.called
assert False is instance.yorm_mapper.fetch.called
assert False is instance.yorm_mapper.create.called
assert True is instance.yorm_mapper.store.called

def test_update_wrong_base(self):
"""Verify an exception is raised with the wrong base."""
instance = Mock()

with pytest.raises(exceptions.UseageError):
with pytest.raises(exceptions.MappingError):
utilities.update_file(instance)

def test_store_not_called_with_auto_off(self):
Expand All @@ -388,8 +389,20 @@ def test_store_not_called_with_auto_off(self):
utilities.update_file(instance, force=False)

assert False is instance.yorm_mapper.fetch.called
assert False is instance.yorm_mapper.create.called
assert False is instance.yorm_mapper.store.called

def test_create_called_if_the_file_is_missing(self):
instance = MockMappable()
instance.yorm_mapper.reset_mock()
instance.yorm_mapper.exists = False

utilities.update_file(instance)

assert False is instance.yorm_mapper.fetch.called
assert True is instance.yorm_mapper.create.called
assert True is instance.yorm_mapper.store.called


if __name__ == '__main__':
pytest.main()
43 changes: 29 additions & 14 deletions yorm/utilities.py
Expand Up @@ -47,24 +47,18 @@ class Mapped(Mappable, instance.__class__):

"""Original class with `Mappable` as the base."""

mapper = set_mapper(instance, path, attrs, auto=auto)
instance.__class__ = Mapped

if existing is True:
if not mapper.exists:
raise exceptions.FileMissingError
elif existing is False:
if mapper.exists:
raise exceptions.FileAlreadyExistsError
mapper = set_mapper(instance, path, attrs, auto=auto)
_check_existance(mapper, existing)

if mapper.auto:
if not mapper.exists:
mapper.create()
mapper.store()
mapper.fetch()

instance.__class__ = Mapped
log.info("mapped %r to '%s'", instance, path)

return instance


Expand Down Expand Up @@ -148,40 +142,61 @@ def update(instance, fetch=True, force=True, store=True):
update_object(instance, force=force)


def update_object(instance, force=True):
def update_object(instance, existing=True, force=True):
"""Synchronize changes into a mapped object from its file.
:param instance: object with patched YAML mapping behavior
:param existing: indicate if file is expected to exist or not
:param force: update the object even if the file appears unchanged
"""
log.info("manually updating %r from file...", instance)
_check_base(instance, mappable=True)

mapper = get_mapper(instance)
_check_existance(mapper, existing)

if mapper.modified or force:
mapper.fetch()


def update_file(instance, force=True):
def update_file(instance, existing=None, force=True):
"""Synchronize changes into a mapped object's file.
:param instance: object with patched YAML mapping behavior
:param existing: indicate if file is expected to exist or not
:param force: update the file even if automatic sync is off
"""
log.info("manually saving %r to file...", instance)
_check_base(instance, mappable=True)

mapper = get_mapper(instance)
print(mapper.auto)
_check_existance(mapper, existing)

if mapper.auto or force:
if not mapper.exists:
mapper.create()
mapper.store()


def _check_base(obj, mappable=True):
"""Confirm an object's base class is `Mappable` as required."""
if mappable and not isinstance(obj, Mappable):
raise exceptions.UseageError("{} is not mapped".format(repr(obj)))
raise exceptions.MappingError("{} is not mapped".format(repr(obj)))
if not mappable and isinstance(obj, Mappable):
raise exceptions.UseageError("{} is already mapped".format(repr(obj)))
raise exceptions.MappingError("{} is already mapped".format(repr(obj)))


def _check_existance(mapper, existing=None):
"""Confirm the expected state of the file.
:param existing: indicate if file is expected to exist or not
"""
if existing is True:
if not mapper.exists:
raise exceptions.FileMissingError
elif existing is False:
if mapper.exists:
raise exceptions.FileAlreadyExistsError

0 comments on commit fdd4157

Please sign in to comment.