Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #28 from PolicyStat/issue_28
Browse files Browse the repository at this point in the history
Add command to restore backup
  • Loading branch information
kylegibson committed Mar 25, 2013
2 parents 2ac9c63 + f2c8733 commit 5267989
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 23 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ If `testenv` is an already existing environment, it will replace it with a fresh
source testenv/bin/activate
terrarium install test_requirements.txt

The old environment can be restored using `terrarium revert`.

When a virtualenv is already activated, the --target option defaults to
the activated environment. Terrarium will replace the activated
environment (`testenv`) with a fresh environment defined by `test_requirements.txt`.
Expand Down
66 changes: 46 additions & 20 deletions terrarium/terrarium.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,49 @@ def requirements(self):
self._requirements = sorted(lines)
return self._requirements

def restore_previously_backed_up_environment(self):
backup = self.get_backup_location()
if not self.environment_exists(backup):
logger.info(
'Failed to restore backup. It doesn\'t appear to exist at %s',
backup,
)
return 1

target = self.get_target_location()
if os.path.isdir(target):
logger.info('Deleting environment at %s', target)
rmtree(target)

logger.info('Renaming %s to %s', backup, target)
os.rename(backup, target)
return 0

def get_target_location(self):
return os.path.abspath(self.args.target)

def get_backup_location(self, target=None):
if target is None:
target = self.get_target_location()
return ''.join([target, self.args.backup_suffix])

def environment_exists(self, env):
return os.path.exists(os.path.join(
env,
'bin',
'activate',
))

def install(self):
logger.debug('Running install')

old_target = os.path.abspath(self.args.target)
old_target = self.get_target_location()
old_target_backup = self.get_backup_location()
new_target = old_target
prompt = os.path.basename(new_target)

# Are we building a new environment, or replacing an existing one?
old_target_exists = os.path.exists(os.path.join(
old_target,
'bin',
'activate',
))
old_target_exists = self.environment_exists(old_target)
if old_target_exists:
new_target = tempfile.mkdtemp(
prefix='%s.' % os.path.basename(old_target),
Expand Down Expand Up @@ -193,7 +223,6 @@ def install(self):
if self.args.upload:
self.upload(new_target)

old_target_backup = '%s%s' % (old_target, self.args.backup_suffix)
if old_target_exists:
logger.info('Moving old environment out of the way')
if os.path.exists(old_target_backup):
Expand Down Expand Up @@ -730,19 +759,19 @@ def parse_args():
'key',
help='Display remote key for current requirement set and platform',
),
'exists': subparsers.add_parser(
'exists',
help='''
Return exit code 0 if environment matches requirement set
''',
),
'install': subparsers.add_parser(
'install',
help='''
Replace current environment with the one given by the
requirement set.
''',
),
'revert': subparsers.add_parser(
'revert',
help='''
Restore the most recent backed-up virtualenv, if it exists.
''',
),
}

for command in commands.values():
Expand All @@ -759,7 +788,6 @@ def parse_args():

return args


def main():
args = parse_args()

Expand All @@ -771,19 +799,17 @@ def main():

terrarium = Terrarium(args)

r = 0
if args.command == 'hash':
sys.stdout.write('%s\n' % terrarium.digest)
if args.command == 'key':
key = terrarium.make_remote_key()
sys.stdout.write('%s\n' % key)
elif args.command == 'check':
if terrarium.is_clean():
sys.exit(0)
else:
sys.exit(1)
elif args.command == 'install':
r = terrarium.install()
sys.exit(r)
elif args.command == 'revert':
r = terrarium.restore_previously_backed_up_environment()
sys.exit(r)

if __name__ == '__main__':
main()
31 changes: 28 additions & 3 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ def _terrarium(self, command='', call_using_python=False, **kwargs):
return output, return_code

def _install(self, call_using_python=False, **kwargs):
command = '-t %s install %s' % (
self.target,
command = 'install %s' % (
self.requirements,
)
output, return_code = self._terrarium(
command,
target=self.target,
call_using_python=call_using_python,
**kwargs
)
Expand Down Expand Up @@ -287,10 +287,11 @@ def test_install_replace_backup_exists(self):
self.assertInstall()
self.assertExists('%s.bak' % self.target)

def test_install_replace_backup_removed(self):
def test_install_no_backup(self):
# Verify that --no-backup deletes the backup when replacing an existing
# environment
self.assertInstall()
self.assertInstall(no_backup=True)
self.assertNotExists('%s.bak' % self.target)

def test_install_replace_old_backup_removed(self):
Expand Down Expand Up @@ -534,6 +535,30 @@ def test_sensitive_arguments_are_sensitive(self):
'do_not_show_me' not in output[1]
)

def test_restore_previously_backed_up_environment(self):
output, return_code = self._terrarium(
'revert',
target=self.target,
)
self.assertEqual(return_code, 1)

self._add_test_requirement()
self.assertInstall()
with open(os.path.join(self.target, 'foo'), 'w') as f:
f.write('bar')
self.assertInstall()
with open(os.path.join(self.target, 'moo'), 'w') as f:
f.write('cow')
self.assertExists('%s.bak' % self.target)
output, return_code = self._terrarium(
'revert',
target=self.target,
)
self.assertEqual(return_code, 0)
self.assertNotExists('%s.bak' % self.target)
self.assertExists(os.path.join(self.target, 'foo'))
self.assertNotExists(os.path.join(self.target, 'moo'))

def test_require_download(self):
self._add_test_requirement()

Expand Down

0 comments on commit 5267989

Please sign in to comment.