Commit 6daada26 authored by Thomas Larrieu's avatar Thomas Larrieu

Modified cleanup feature : now it takes prefix into account to determine if a path is valid or not.

parent 10beede5
...@@ -228,45 +228,57 @@ class Recipe(object): ...@@ -228,45 +228,57 @@ class Recipe(object):
log.error('Command failed: %s: %s' % (e, cmd)) log.error('Command failed: %s: %s' % (e, cmd))
raise zc.buildout.UserError('System error') raise zc.buildout.UserError('System error')
def clean(self, cleanup_list):
""" def _return_if_exists_in_prefix(self, path, prefix):
Basically, this method does not do much, appart from removing relpath = os.path.relpath(path, prefix)
what it is told to, as a list passed in args abspath = os.path.join(prefix, relpath)
""" if os.path.exists(abspath):
import glob if relpath.startswith('..'):
def build_working_iterator(cleanup_list): raise IOError(prefix + " does not contain " + path)
current_dir = os.getcwd()
for pattern in cleanup_list:
# if current pattern contains wildcards, we search for all matching
# files/directories
if pattern.find('*') > -1 or pattern.find('?') > -1 or pattern.find('[') > -1:
g = glob.glob(pattern)
if g:
for x in g:
yield x
else: else:
raise IOError("Pattern " + pattern + " did not match anything") return path
elif os.path.exists(pattern): else:
if os.path.relpath(pattern).startswith('..'): raise IOError(path + " does not exist")
raise IOError(current_dir + " does not contain " + pattern)
def _is_pattern(self, pattern):
if pattern.find('*') > -1 or pattern.find('?') > -1 or pattern.find('[') > -1:
return True
return False
def _build_iterator(self, cleanup_list, prefix):
import glob
# First, expand eventual wildcards
for entry in [os.path.join(prefix, x) for x in cleanup_list]:
if self._is_pattern(entry):
paths = glob.glob(entry)
if paths:
for path in paths:
yield self._return_if_exists_in_prefix(path, prefix)
else:
raise IOError("Pattern " + entry + " did not match anything")
else: else:
yield pattern yield self._return_if_exists_in_prefix(entry, prefix)
else:
raise IOError(pattern + " does not exist") def clean(self, cleanup_list):
# As build_working_iterator is a generator and since we want to first """
# check every file (raising exceptions when necessary) BEFORE removing Basically, this method does not do much, appart from removing
# anything from the file system, we enforce full lookup by build a tuple what it is told to, as a list passed in args
# out of it """
for x in tuple(build_working_iterator(cleanup_list)): # As build_working_iterator is a generator and since we want to first
# This first condition is mandatory as we might have removed an entire # check every file (raising exceptions when necessary) BEFORE removing
# tree during a previous iteration, possibly leading to a case where # anything from the file system, we enforce full lookup by build a tuple
# some items are still to be removed but do not exist anymore # out of it
if os.path.exists(x): print self.options['prefix']
if os.path.isdir(x): for x in tuple(self._build_iterator(cleanup_list, self.options['prefix'])):
shutil.rmtree(x) # This first condition is mandatory as we might have removed an entire
else: # tree during a previous iteration, possibly leading to a case where
os.remove(x) # some items are still to be removed but do not exist anymore
logging.getLogger(self.name).info('%s has been successfully removed', x) if os.path.exists(x):
if os.path.isdir(x):
shutil.rmtree(x)
else:
os.remove(x)
logging.getLogger(self.name).info('%s has been successfully removed', x)
......
...@@ -7,6 +7,7 @@ import shutil ...@@ -7,6 +7,7 @@ import shutil
import stat import stat
import tarfile import tarfile
import tempfile import tempfile
import glob
from time import sleep from time import sleep
import zc.buildout import zc.buildout
import zc.buildout.testing import zc.buildout.testing
...@@ -317,7 +318,8 @@ class NonInformativeTests(unittest.TestCase): ...@@ -317,7 +318,8 @@ class NonInformativeTests(unittest.TestCase):
'cleanup': 'foo\nbar' 'cleanup': 'foo\nbar'
} }
) )
os.chdir(self.dir) os.mkdir(recipe.options.get('prefix'))
os.chdir(recipe.options.get('prefix'))
tmp = open('foo', 'a') tmp = open('foo', 'a')
tmp = open('bar', 'a') tmp = open('bar', 'a')
self.assertTrue(os.path.exists('foo')) self.assertTrue(os.path.exists('foo'))
...@@ -326,7 +328,28 @@ class NonInformativeTests(unittest.TestCase): ...@@ -326,7 +328,28 @@ class NonInformativeTests(unittest.TestCase):
self.assertFalse(os.path.exists('foo')) self.assertFalse(os.path.exists('foo'))
self.assertFalse(os.path.exists('bar')) self.assertFalse(os.path.exists('bar'))
def test_cleanup_succeeds_when_glob_is_valid(self):
recipe = self.make_recipe(
{},
'test',
{
'url': 'file://%s/testdata/package-0.0.0.tar.gz' % os.path.dirname(__file__),
'cleanup': 'foo/*'
}
)
os.mkdir(recipe.options.get('prefix'))
os.chdir(recipe.options.get('prefix'))
os.mkdir('foo')
tmp = open('foo/bar', 'a')
tmp = open('foo/barz', 'a')
self.assertTrue(os.path.exists('foo/bar'))
self.assertTrue(os.path.exists('foo/barz'))
recipe.install()
self.assertFalse(os.path.exists('foo/bar'))
self.assertFalse(os.path.exists('foo/barz'))
def test_cleanup_fails_when_file_does_not_exist(self): def test_cleanup_fails_when_file_does_not_exist(self):
os.chdir(self.dir)
recipe = self.make_recipe( recipe = self.make_recipe(
{}, {},
'test', 'test',
...@@ -335,12 +358,12 @@ class NonInformativeTests(unittest.TestCase): ...@@ -335,12 +358,12 @@ class NonInformativeTests(unittest.TestCase):
'cleanup': 'foo' 'cleanup': 'foo'
} }
) )
os.chdir(self.dir) self.assertFalse(os.path.exists(os.path.join(self.dir, 'foo')))
self.assertFalse(os.path.exists('foo'))
with self.assertRaises(IOError): with self.assertRaises(IOError):
recipe.install() recipe.install()
def test_cleanup_fails_when_file_is_out_of_reach(self): def test_cleanup_fails_when_file_is_out_of_reach(self):
os.chdir(self.dir)
recipe = self.make_recipe( recipe = self.make_recipe(
{}, {},
'test', 'test',
...@@ -349,11 +372,23 @@ class NonInformativeTests(unittest.TestCase): ...@@ -349,11 +372,23 @@ class NonInformativeTests(unittest.TestCase):
'cleanup': '/tmp/foo' 'cleanup': '/tmp/foo'
} }
) )
os.chdir(self.dir)
open('/tmp/foo', 'a') open('/tmp/foo', 'a')
self.assertTrue(os.path.exists('/tmp/foo')) self.assertTrue(os.path.exists('/tmp/foo'))
with self.assertRaises(IOError): with self.assertRaises(IOError):
recipe.install() recipe.install()
def test_cleanup_fails_when_unmatched_glob(self):
os.chdir(self.dir)
pattern = '/tmp/foo/trololol*'
recipe = self.make_recipe({}, 'test',
{
'url': 'file://%s/testdata/package-0.0.0.tar.gz' % os.path.dirname(__file__),
'cleanup': pattern
}
)
self.assertEqual(glob.glob(pattern), [])
with self.assertRaises(IOError):
recipe.install()
def test_suite(): def test_suite():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment