From 08298507dc55c157a4b7062194084f815b8033da Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Fri, 24 Jan 2014 15:09:14 +0400 Subject: [PATCH 01/19] Fix https://github.com/e-dard/flask-s3/issues/16 Trim EOL whitespace and other PEP8 issue by autopep8 Use tqdm for progress bar if log level=INFO --- flask_s3.py | 89 ++++++++++++++++++++++++++++++++++------------------- setup.py | 1 + 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/flask_s3.py b/flask_s3.py index 20637bc..e44e7f7 100644 --- a/flask_s3.py +++ b/flask_s3.py @@ -7,6 +7,7 @@ from boto.s3.connection import S3Connection from boto.exception import S3CreateError from boto.s3.key import Key +from tqdm import tqdm logger = logging.getLogger('flask_s3') @@ -15,14 +16,14 @@ def url_for(endpoint, **values): """ Generates a URL to the given endpoint. - If the endpoint is for a static resource then an Amazon S3 URL is + If the endpoint is for a static resource then an Amazon S3 URL is generated, otherwise the call is passed on to `flask.url_for`. - Because this function is set as a jinja environment variable when - `FlaskS3.init_app` is invoked, this function replaces + Because this function is set as a jinja environment variable when + `FlaskS3.init_app` is invoked, this function replaces `flask.url_for` in templates automatically. It is unlikely that this - function will need to be directly called from within your - application code, unless you need to refer to static assets outside + function will need to be directly called from within your + application code, unless you need to refer to static assets outside of your templates. """ app = current_app @@ -57,13 +58,14 @@ def _gather_files(app, hidden): dirs.extend([bp_details(x) for x in blueprints if x.static_folder]) valid_files = defaultdict(list) - for static_folder, static_url_loc in dirs: + + for static_folder, static_url_loc in dirs: if not os.path.isdir(static_folder): logger.warning("WARNING - [%s does not exist]" % static_folder) else: logger.debug("Checking static folder: %s" % static_folder) for root, _, files in os.walk(static_folder): - files = [os.path.join(root, x) \ + files = [os.path.join(root, x) for x in files if hidden or x[0] != '.'] if files: valid_files[(static_folder, static_url_loc)].extend(files) @@ -76,14 +78,14 @@ def _path_to_relative_url(path): def _static_folder_path(static_url, static_folder, static_asset): - """ - Returns a path to a file based on the static folder, and not on the + """ + Returns a path to a file based on the static folder, and not on the filesystem holding the file. Returns a path relative to static_url for static_asset """ - # first get the asset path relative to the static folder. - # static_asset is not simply a filename because it could be + # first get the asset path relative to the static folder. + # static_asset is not simply a filename because it could be # sub-directory then file etc. if not static_asset.startswith(static_folder): raise ValueError("%s startic asset must be under %s static folder" % @@ -96,6 +98,10 @@ def _static_folder_path(static_url, static_folder, static_asset): def _write_files(app, static_url_loc, static_folder, files, bucket, ex_keys=None): """ Writes all the files inside a static folder to S3. """ + + if logger.level == logging.INFO: + files = tqdm(files, desc='Uploading from %s to %s' % (static_url_loc, bucket.name)) + for file_path in files: asset_loc = _path_to_relative_url(file_path) key_name = _static_folder_path(static_url_loc, static_folder, @@ -118,15 +124,33 @@ def _upload_files(app, files_, bucket): _write_files(app, static_url, static_folder, names, bucket) +def _get_or_create_bucket(conn, bucket_name, location): + """Helper for :function:`create_all`. Returns bucket object by name, + if not existing create and return it. + + :internal: + """ + bucket = conn.lookup(bucket_name, validate=False) + if bucket: + return bucket + try: + bucket = conn.create_bucket(bucket_name, location=location) + bucket.make_public(recursive=False) + except S3CreateError as e: + raise e + + return bucket + + def create_all(app, user=None, password=None, bucket_name=None, location='', include_hidden=False): """ - Uploads of the static assets associated with a Flask application to + Uploads of the static assets associated with a Flask application to Amazon S3. - All static assets are identified on the local filesystem, including - any static assets associated with *registered* blueprints. In turn, - each asset is uploaded to the bucket described by `bucket_name`. If + All static assets are identified on the local filesystem, including + any static assets associated with *registered* blueprints. In turn, + each asset is uploaded to the bucket described by `bucket_name`. If the bucket does not exist then it is created. Flask-S3 creates the same relative static asset folder structure on @@ -143,22 +167,22 @@ def create_all(app, user=None, password=None, bucket_name=None, :type user: `basestring` or None :param password: an AWS Secret Access Key. You can find this key in - the Security Credentials section of your AWS + the Security Credentials section of your AWS account. :type password: `basestring` or None - + :param bucket_name: the name of the bucket you wish to server your - static assets from. **Note**: while a valid - character, it is recommended that you do not - include periods in bucket_name if you wish to + static assets from. **Note**: while a valid + character, it is recommended that you do not + include periods in bucket_name if you wish to serve over HTTPS. See Amazon's `bucket restrictions`_ for more details. :type bucket_name: `basestring` or None :param location: the AWS region to host the bucket in; an empty string indicates the default region should be used, - which is the US Standard region. Possible location - values include: `'DEFAULT'`, `'EU'`, `'USWest'`, + which is the US Standard region. Possible location + values include: `'DEFAULT'`, `'EU'`, `'USWest'`, `'APSoutheast'` :type location: `basestring` or None @@ -178,30 +202,31 @@ def create_all(app, user=None, password=None, bucket_name=None, bucket_name = app.config['S3_BUCKET_NAME'] if not bucket_name: raise ValueError("No bucket name provided.") + # build list of static files all_files = _gather_files(app, include_hidden) - logger.debug("All valid files: %s" % all_files) - conn = S3Connection(user, password) # connect to s3 + for (static_folder, static_url_loc), files in all_files.iteritems(): + logger.debug('%s valid files in folder "%s" with local url "%s"', len(files), static_folder, static_url_loc) + # connect to s3 + conn = S3Connection(user, password) # get_or_create bucket - try: - bucket = conn.create_bucket(bucket_name, location=location) - bucket.make_public(recursive=True) - except S3CreateError as e: - raise e + bucket = _get_or_create_bucket(conn, bucket_name, location) _upload_files(app, all_files, bucket) class FlaskS3(object): + """ The FlaskS3 object allows your application to use Flask-S3. - When initialising a FlaskS3 object you may optionally provide your - :class:`flask.Flask` application object if it is ready. Otherwise, + When initialising a FlaskS3 object you may optionally provide your + :class:`flask.Flask` application object if it is ready. Otherwise, you may provide it later by using the :meth:`init_app` method. :param app: optional :class:`flask.Flask` application object :type app: :class:`flask.Flask` or None """ + def __init__(self, app=None): if app is not None: self.init_app(app) @@ -209,7 +234,7 @@ def __init__(self, app=None): def init_app(self, app): """ An alternative way to pass your :class:`flask.Flask` application - object to Flask-S3. :meth:`init_app` also takes care of some + object to Flask-S3. :meth:`init_app` also takes care of some default `settings`_. :param app: the :class:`flask.Flask` application object. diff --git a/setup.py b/setup.py index 2625bc4..8150771 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,7 @@ install_requires=[ 'Flask', 'Boto>=2.5.2' + 'tqdm' ], tests_require=['nose', 'mock'], classifiers=[ From c0da7c44a068658d9a4f53bbe7945c9b5f1e6c71 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Fri, 24 Jan 2014 15:09:51 +0400 Subject: [PATCH 02/19] fix by autopep8 --- example/example/app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/example/example/app.py b/example/example/app.py index 8abcfeb..f02512a 100644 --- a/example/example/app.py +++ b/example/example/app.py @@ -8,13 +8,15 @@ s3 = FlaskS3(app) + @app.route('/') def index(): template_str = """{{ url_for('static', filename="foo.js") }}""" return render_template_string(template_str) + def upload_all(): create_all(app, user='MY_AWS_ID', password='MY_AWS_SECRET') if __name__ == '__main__': - app.run(debug=True) \ No newline at end of file + app.run(debug=True) From ec9fa6f60ac5ae77b58a71393dfcbca7df3eb5a7 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 18:09:16 +0400 Subject: [PATCH 03/19] Setup.py changes --- flask_s3.py | 4 ++-- setup.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/flask_s3.py b/flask_s3.py index e44e7f7..6be9718 100644 --- a/flask_s3.py +++ b/flask_s3.py @@ -100,7 +100,7 @@ def _write_files(app, static_url_loc, static_folder, files, bucket, """ Writes all the files inside a static folder to S3. """ if logger.level == logging.INFO: - files = tqdm(files, desc='Uploading from %s to %s' % (static_url_loc, bucket.name)) + files = tqdm(files, desc='Uploading from %s to %s' % (static_url_loc, bucket.name)) for file_path in files: asset_loc = _path_to_relative_url(file_path) @@ -125,7 +125,7 @@ def _upload_files(app, files_, bucket): def _get_or_create_bucket(conn, bucket_name, location): - """Helper for :function:`create_all`. Returns bucket object by name, + """Helper for :function:`create_all`. Returns bucket object by name, if not existing create and return it. :internal: diff --git a/setup.py b/setup.py index 8150771..3457a72 100644 --- a/setup.py +++ b/setup.py @@ -17,15 +17,17 @@ description='Seamlessly serve the static files of your Flask app from Amazon S3', long_description=__doc__, py_modules=['flask_s3'], + keywords=['Flask', 'AWS', 'S3'], zip_safe=False, include_package_data=True, platforms='any', install_requires=[ 'Flask', - 'Boto>=2.5.2' + 'Boto>=2.5.2', 'tqdm' ], - tests_require=['nose', 'mock'], + tests_require=['nose2', 'mock'], + test_suite='nose2.collector.collector', classifiers=[ 'Environment :: Web Environment', 'Intended Audience :: Developers', From 5bf59ae651602a5c0e9ed8be9f022c6a6faafc42 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 19:06:03 +0400 Subject: [PATCH 04/19] Use nose2 for run tests --- nose2.cfg | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 nose2.cfg diff --git a/nose2.cfg b/nose2.cfg new file mode 100644 index 0000000..6d8eeea --- /dev/null +++ b/nose2.cfg @@ -0,0 +1,5 @@ +[unittest] +start-dir = tests +code-directories = '.' +test-file-pattern = test_*.py +test-method-prefix = test From 571e8f6058eab6e14983395622be607dd90b48cf Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 19:14:58 +0400 Subject: [PATCH 05/19] Converts old string formatting code to new .format() style. Converts statements of the form '%s' % foo to statements of the form '{0}'.format(foo) This completes removal of code necessary for Python 2.5 support; Flask no longer support Python 2.5. --- flask_s3.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/flask_s3.py b/flask_s3.py index 6be9718..341a7fd 100644 --- a/flask_s3.py +++ b/flask_s3.py @@ -34,10 +34,10 @@ def url_for(endpoint, **values): scheme = 'http' if app.config['S3_USE_HTTPS']: scheme = 'https' - bucket_path = '%s.%s' % (app.config['S3_BUCKET_NAME'], - app.config['S3_BUCKET_DOMAIN']) + bucket_path = '{0}.{1}'.format(app.config['S3_BUCKET_NAME'], + app.config['S3_BUCKET_DOMAIN']) if app.config['S3_CDN_DOMAIN']: - bucket_path = '%s' % app.config['S3_CDN_DOMAIN'] + bucket_path = '{0}'.format(app.config['S3_CDN_DOMAIN']) urls = app.url_map.bind(bucket_path, url_scheme=scheme) return urls.build(endpoint, values=values, force_external=True) return flask_url_for(endpoint, **values) @@ -45,7 +45,7 @@ def url_for(endpoint, **values): def _bp_static_url(blueprint): """ builds the absolute url path for a blueprint's static folder """ - u = u'%s%s' % (blueprint.url_prefix or '', blueprint.static_url_path or '') + u = u'{0}{1}'.format(blueprint.url_prefix or '', blueprint.static_url_path or '') return u @@ -61,9 +61,9 @@ def _gather_files(app, hidden): for static_folder, static_url_loc in dirs: if not os.path.isdir(static_folder): - logger.warning("WARNING - [%s does not exist]" % static_folder) + logger.warning("WARNING - [{0} does not exist]".format(static_folder)) else: - logger.debug("Checking static folder: %s" % static_folder) + logger.debug("Checking static folder: {0}".format(static_folder)) for root, _, files in os.walk(static_folder): files = [os.path.join(root, x) for x in files if hidden or x[0] != '.'] @@ -88,11 +88,11 @@ def _static_folder_path(static_url, static_folder, static_asset): # static_asset is not simply a filename because it could be # sub-directory then file etc. if not static_asset.startswith(static_folder): - raise ValueError("%s startic asset must be under %s static folder" % - (static_asset, static_folder)) + raise ValueError("{0} startic asset must be under {1} static folder".format(static_asset, + static_folder)) rel_asset = static_asset[len(static_folder):] # Now bolt the static url path and the relative asset location together - return u'%s/%s' % (static_url.rstrip('/'), rel_asset.lstrip('/')) + return u'{0}/{1}'.format(static_url.rstrip('/'), rel_asset.lstrip('/')) def _write_files(app, static_url_loc, static_folder, files, bucket, @@ -100,16 +100,16 @@ def _write_files(app, static_url_loc, static_folder, files, bucket, """ Writes all the files inside a static folder to S3. """ if logger.level == logging.INFO: - files = tqdm(files, desc='Uploading from %s to %s' % (static_url_loc, bucket.name)) + files = tqdm(files, desc='Uploading from {0} to {1}'.format(static_url_loc, bucket.name)) for file_path in files: asset_loc = _path_to_relative_url(file_path) key_name = _static_folder_path(static_url_loc, static_folder, asset_loc) - msg = "Uploading %s to %s as %s" % (file_path, bucket, key_name) + msg = "Uploading {0} to {1} as {2}".format(file_path, bucket, key_name) logger.debug(msg) if ex_keys and key_name in ex_keys: - logger.debug("%s excluded from upload" % key_name) + logger.debug("{0} excluded from upload".format(key_name)) else: k = Key(bucket=bucket, name=key_name) # Set custom headers @@ -206,7 +206,7 @@ def create_all(app, user=None, password=None, bucket_name=None, # build list of static files all_files = _gather_files(app, include_hidden) for (static_folder, static_url_loc), files in all_files.iteritems(): - logger.debug('%s valid files in folder "%s" with local url "%s"', len(files), static_folder, static_url_loc) + logger.debug('{0} valid files in folder "{1}" with local url "{2}"'.format(len(files), static_folder, static_url_loc)) # connect to s3 conn = S3Connection(user, password) # get_or_create bucket From 4e9b98df3fcba5a18a311603d5d02726bb8e47e5 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 19:32:36 +0400 Subject: [PATCH 06/19] Fix https://github.com/e-dard/flask-s3/issues/17 --- tests/test_flask_static.py | 58 ++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/tests/test_flask_static.py b/tests/test_flask_static.py index b1831db..aed1652 100644 --- a/tests/test_flask_static.py +++ b/tests/test_flask_static.py @@ -18,12 +18,11 @@ def a(url_for_string): def test_jinja_url_for(self): """ Tests that the jinja global gets assigned correctly. """ - self.assertNotEqual(self.app.jinja_env.globals['url_for'], - flask_s3.url_for) + assert self.app.jinja_env.globals['url_for'] != flask_s3.url_for + # then we initialise the extension FlaskS3(self.app) - self.assertEquals(self.app.jinja_env.globals['url_for'], - flask_s3.url_for) + assert self.app.jinja_env.globals['url_for'] == flask_s3.url_for def test_config(self): """ Tests configuration vars exist. """ @@ -32,7 +31,7 @@ def test_config(self): 'S3_BUCKET_DOMAIN', 'S3_CDN_DOMAIN', 'S3_USE_CACHE_CONTROL', 'S3_HEADERS') for default in defaults: - self.assertIn(default, self.app.config) + assert default in self.app.config class UrlTests(unittest.TestCase): @@ -62,7 +61,7 @@ def c(): def client_get(self, ufs): FlaskS3(self.app) client = self.app.test_client() - return client.get('/%s' % ufs) + return client.get('/{0}'.format(ufs)) def test_required_config(self): """ @@ -77,18 +76,21 @@ def test_required_config(self): self.client_get(ufs) except ValueError: raises = True - self.assertTrue(raises) + + assert raises + def test_url_for(self): """ Tests that correct url formed for static asset in self.app. """ # non static endpoint url_for in template - self.assertEquals(self.client_get('').data, '/') + assert self.client_get('').data == '/' + # static endpoint url_for in template ufs = "{{url_for('static', filename='bah.js')}}" exp = 'https://foo.s3.amazonaws.com/static/bah.js' - self.assertEquals(self.client_get(ufs).data, exp) + assert self.client_get(ufs).data == exp def test_url_for_debug(self): """Tests Flask-S3 behaviour in debug mode.""" @@ -96,7 +98,8 @@ def test_url_for_debug(self): # static endpoint url_for in template ufs = "{{url_for('static', filename='bah.js')}}" exp = '/static/bah.js' - self.assertEquals(self.client_get(ufs).data, exp) + + assert self.client_get(ufs).data == exp def test_url_for_debug_override(self): """Tests Flask-S3 behavior in debug mode with USE_S3_DEBUG turned on.""" @@ -104,7 +107,8 @@ def test_url_for_debug_override(self): self.app.config['USE_S3_DEBUG'] = True ufs = "{{url_for('static', filename='bah.js')}}" exp = 'https://foo.s3.amazonaws.com/static/bah.js' - self.assertEquals(self.client_get(ufs).data, exp) + + assert self.client_get(ufs).data == exp def test_url_for_blueprint(self): """ @@ -113,13 +117,15 @@ def test_url_for_blueprint(self): # static endpoint url_for in template ufs = "{{url_for('admin.static', filename='bah.js')}}" exp = 'https://foo.s3.amazonaws.com/admin-static/bah.js' - self.assertEquals(self.client_get(ufs).data, exp) + + assert self.client_get(ufs).data == exp def test_url_for_cdn_domain(self): self.app.config['S3_CDN_DOMAIN'] = 'foo.cloudfront.net' ufs = "{{url_for('static', filename='bah.js')}}" exp = 'https://foo.cloudfront.net/static/bah.js' - self.assertEquals(self.client_get(ufs).data, exp) + + assert self.client_get(ufs).data == exp @@ -143,7 +149,9 @@ def test__bp_static_url(self): Mock(static_url_path='/b/bar', url_prefix='/pref'), Mock(static_url_path=None, url_prefix=None)] expected = [u'/foo', u'/pref', u'/pref/b/bar', u''] - self.assertEquals(expected, [flask_s3._bp_static_url(x) for x in bps]) + + assert expected == [flask_s3._bp_static_url(x) for x in bps] + @patch('os.walk') @patch('os.path.isdir') @@ -171,11 +179,13 @@ def test__gather_files(self, path_mock, os_mock): '/home/zoo/foo/d', '/home/zoo/foo/e']} actual = flask_s3._gather_files(self.app, False) - self.assertEqual(expected, actual) + + assert expected == actual expected[('/home', u'/static')] = ['/home/.a'] actual = flask_s3._gather_files(self.app, True) - self.assertEqual(expected, actual) + + assert expected == actual @patch('os.walk') @patch('os.path.isdir') @@ -190,7 +200,8 @@ def test__gather_files_no_blueprints_no_files(self, path_mock, os_mock): path_mock.return_value = True actual = flask_s3._gather_files(self.app, False) - self.assertEqual({}, actual) + assert {} == actual + @patch('os.walk') @patch('os.path.isdir') @@ -204,7 +215,7 @@ def test__gather_files_bad_folder(self, path_mock, os_mock): path_mock.return_value = False actual = flask_s3._gather_files(self.app, False) - self.assertEqual({}, actual) + assert {} == actual @patch('os.path.splitdrive', side_effect=ntpath.splitdrive) @patch('os.path.join', side_effect=ntpath.join) @@ -215,7 +226,7 @@ def test__path_to_relative_url_win(self, join_mock, split_mock): expected = ['/foo/bar/baz.css', '/foo/bar.css', '/foo/bar.css'] for in_, exp in zip(input_, expected): actual = flask_s3._path_to_relative_url(in_) - self.assertEquals(exp, actual) + assert exp == actual @patch('flask_s3.Key') def test__write_files(self, key_mock): @@ -232,7 +243,9 @@ def test__write_files(self, key_mock): call().set_contents_from_filename('/home/z/bar.css')] flask_s3._write_files(self.app, static_url_loc, static_folder, assets, None, exclude) - self.assertLessEqual(expected, key_mock.mock_calls) + + assert expected < key_mock.mock_calls + def test_static_folder_path(self): """ Tests _static_folder_path """ @@ -242,7 +255,4 @@ def test_static_folder_path(self): expected = [u'/static/foo.css', u'/foo/static/a/b.css', u'/bar/s/a/b.css'] for i, e in zip(inputs, expected): - self.assertEquals(e, flask_s3._static_folder_path(*i)) - -if __name__ == '__main__': - unittest.main() + assert e == flask_s3._static_folder_path(*i) From f52c2f31f1a8bf2f72429566021671f3a4b7ad1a Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 19:48:55 +0400 Subject: [PATCH 07/19] Improvement utilities --- .gitignore | 21 ++++++++++++++++++--- .travis.yml | 8 ++++---- docs/requirements.txt | 5 ----- requirements-test.txt | 2 ++ requirements.txt | 3 +++ 5 files changed, 27 insertions(+), 12 deletions(-) delete mode 100644 docs/requirements.txt create mode 100644 requirements-test.txt create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 5672901..4612445 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,22 @@ *.pyc + +# coverage files +*.coverage +htmlcov +cover + +# temporary files +*~ + +# mac os x .DS_Store -*.egg + +# build artifacts from python setup.py build or python setup.py install +build/ +dist/ *.egg-info -dist +*egg*/ +docs/_build + +# idea project file /.idea -_build diff --git a/.travis.yml b/.travis.yml index 102e309..f774338 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: + - "2.6" - "2.7" -# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors -install: pip install -r docs/requirements.txt --use-mirrors -# command to run tests, e.g. python setup.py test -script: nosetests + - "3.3" + - "pypy" +script: python setup.py test \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 0abe570..0000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -Flask==0.9 -Jinja2==2.6 -Werkzeug==0.8.3 -boto==2.5.2 -wsgiref==0.1.2 diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 0000000..e550576 --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,2 @@ +-r requirements.txt +nose2 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..95be133 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +flask>=0.9 +boto>=2.5.2 +tqdm==1.0 From 1517bc6461619e85b79e443fbd38bda6df3cfc1d Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 20:44:42 +0400 Subject: [PATCH 08/19] Forgot deps Tox Fix log-capture --- nose2.cfg | 4 ++++ requirements-test.txt | 1 + tox.ini | 6 ++++++ 3 files changed, 11 insertions(+) create mode 100644 tox.ini diff --git a/nose2.cfg b/nose2.cfg index 6d8eeea..f78df58 100644 --- a/nose2.cfg +++ b/nose2.cfg @@ -3,3 +3,7 @@ start-dir = tests code-directories = '.' test-file-pattern = test_*.py test-method-prefix = test + +[log-capture] +always-on = True +clear-handlers = True \ No newline at end of file diff --git a/requirements-test.txt b/requirements-test.txt index e550576..326f4f1 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,2 +1,3 @@ -r requirements.txt +mock nose2 \ No newline at end of file diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..32078a3 --- /dev/null +++ b/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist=py27 + +[testenv] +deps=-r{toxinidir}/requirements-test.txt +commands=nose2 \ No newline at end of file From 7bd73f71cea33385589f6cdc80df04d9fc8efe7c Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 20:47:07 +0400 Subject: [PATCH 09/19] Boto not support py3 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f774338..8dfb226 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,5 @@ language: python python: - "2.6" - "2.7" - - "3.3" - "pypy" script: python setup.py test \ No newline at end of file From 6bb597a1429909f40910440997ee5dabea3f4c28 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 20:48:34 +0400 Subject: [PATCH 10/19] Add me to contributers --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index e7de847..01de587 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -5,3 +5,4 @@ Contributors * Rehan Dalal (rehandalal) * Hannes Ljungberg (hannseman) * Erik Taubeneck (eriktaubeneck) +* Mike Klimin (klinkin) From 658bf361eb81ef8540b403eb2418162f831ef6a2 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 28 Jan 2014 20:59:05 +0400 Subject: [PATCH 11/19] Remove the dependency on unittest2 --- tests/test_flask_static.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_flask_static.py b/tests/test_flask_static.py index aed1652..fec8383 100644 --- a/tests/test_flask_static.py +++ b/tests/test_flask_static.py @@ -1,4 +1,3 @@ -import unittest import ntpath from mock import Mock, patch, call @@ -8,7 +7,7 @@ from flask_s3 import FlaskS3 -class FlaskStaticTest(unittest.TestCase): +class TestStatic(object): def setUp(self): self.app = Flask(__name__) self.app.testing = True @@ -34,7 +33,7 @@ def test_config(self): assert default in self.app.config -class UrlTests(unittest.TestCase): +class TestUrls(object): def setUp(self): self.app = Flask(__name__) self.app.testing = True @@ -129,7 +128,7 @@ def test_url_for_cdn_domain(self): -class S3Tests(unittest.TestCase): +class TestS3(object): def setUp(self): self.app = Flask(__name__) From 64d8cde4559dbb8504d7ea1a40eb3b6fa4381480 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Thu, 30 Jan 2014 17:12:18 +0400 Subject: [PATCH 12/19] Fix bug --- flask_s3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flask_s3.py b/flask_s3.py index 341a7fd..ab86a58 100644 --- a/flask_s3.py +++ b/flask_s3.py @@ -130,7 +130,7 @@ def _get_or_create_bucket(conn, bucket_name, location): :internal: """ - bucket = conn.lookup(bucket_name, validate=False) + bucket = conn.lookup(bucket_name, validate=True) if bucket: return bucket try: From a2c4fc582459a3e3e40973b48368365202b751c2 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 11 Feb 2014 02:39:30 +0400 Subject: [PATCH 13/19] Revert "Fix https://github.com/e-dard/flask-s3/issues/17" This reverts commit 4e9b98df3fcba5a18a311603d5d02726bb8e47e5. --- tests/test_flask_static.py | 58 ++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/tests/test_flask_static.py b/tests/test_flask_static.py index fec8383..cf787fa 100644 --- a/tests/test_flask_static.py +++ b/tests/test_flask_static.py @@ -17,11 +17,12 @@ def a(url_for_string): def test_jinja_url_for(self): """ Tests that the jinja global gets assigned correctly. """ - assert self.app.jinja_env.globals['url_for'] != flask_s3.url_for - + self.assertNotEqual(self.app.jinja_env.globals['url_for'], + flask_s3.url_for) # then we initialise the extension FlaskS3(self.app) - assert self.app.jinja_env.globals['url_for'] == flask_s3.url_for + self.assertEquals(self.app.jinja_env.globals['url_for'], + flask_s3.url_for) def test_config(self): """ Tests configuration vars exist. """ @@ -30,7 +31,7 @@ def test_config(self): 'S3_BUCKET_DOMAIN', 'S3_CDN_DOMAIN', 'S3_USE_CACHE_CONTROL', 'S3_HEADERS') for default in defaults: - assert default in self.app.config + self.assertIn(default, self.app.config) class TestUrls(object): @@ -60,7 +61,7 @@ def c(): def client_get(self, ufs): FlaskS3(self.app) client = self.app.test_client() - return client.get('/{0}'.format(ufs)) + return client.get('/%s' % ufs) def test_required_config(self): """ @@ -75,21 +76,18 @@ def test_required_config(self): self.client_get(ufs) except ValueError: raises = True - - assert raises - + self.assertTrue(raises) def test_url_for(self): """ Tests that correct url formed for static asset in self.app. """ # non static endpoint url_for in template - assert self.client_get('').data == '/' - + self.assertEquals(self.client_get('').data, '/') # static endpoint url_for in template ufs = "{{url_for('static', filename='bah.js')}}" exp = 'https://foo.s3.amazonaws.com/static/bah.js' - assert self.client_get(ufs).data == exp + self.assertEquals(self.client_get(ufs).data, exp) def test_url_for_debug(self): """Tests Flask-S3 behaviour in debug mode.""" @@ -97,8 +95,7 @@ def test_url_for_debug(self): # static endpoint url_for in template ufs = "{{url_for('static', filename='bah.js')}}" exp = '/static/bah.js' - - assert self.client_get(ufs).data == exp + self.assertEquals(self.client_get(ufs).data, exp) def test_url_for_debug_override(self): """Tests Flask-S3 behavior in debug mode with USE_S3_DEBUG turned on.""" @@ -106,8 +103,7 @@ def test_url_for_debug_override(self): self.app.config['USE_S3_DEBUG'] = True ufs = "{{url_for('static', filename='bah.js')}}" exp = 'https://foo.s3.amazonaws.com/static/bah.js' - - assert self.client_get(ufs).data == exp + self.assertEquals(self.client_get(ufs).data, exp) def test_url_for_blueprint(self): """ @@ -116,15 +112,13 @@ def test_url_for_blueprint(self): # static endpoint url_for in template ufs = "{{url_for('admin.static', filename='bah.js')}}" exp = 'https://foo.s3.amazonaws.com/admin-static/bah.js' - - assert self.client_get(ufs).data == exp + self.assertEquals(self.client_get(ufs).data, exp) def test_url_for_cdn_domain(self): self.app.config['S3_CDN_DOMAIN'] = 'foo.cloudfront.net' ufs = "{{url_for('static', filename='bah.js')}}" exp = 'https://foo.cloudfront.net/static/bah.js' - - assert self.client_get(ufs).data == exp + self.assertEquals(self.client_get(ufs).data, exp) @@ -148,9 +142,7 @@ def test__bp_static_url(self): Mock(static_url_path='/b/bar', url_prefix='/pref'), Mock(static_url_path=None, url_prefix=None)] expected = [u'/foo', u'/pref', u'/pref/b/bar', u''] - - assert expected == [flask_s3._bp_static_url(x) for x in bps] - + self.assertEquals(expected, [flask_s3._bp_static_url(x) for x in bps]) @patch('os.walk') @patch('os.path.isdir') @@ -178,13 +170,11 @@ def test__gather_files(self, path_mock, os_mock): '/home/zoo/foo/d', '/home/zoo/foo/e']} actual = flask_s3._gather_files(self.app, False) - - assert expected == actual + self.assertEqual(expected, actual) expected[('/home', u'/static')] = ['/home/.a'] actual = flask_s3._gather_files(self.app, True) - - assert expected == actual + self.assertEqual(expected, actual) @patch('os.walk') @patch('os.path.isdir') @@ -199,8 +189,7 @@ def test__gather_files_no_blueprints_no_files(self, path_mock, os_mock): path_mock.return_value = True actual = flask_s3._gather_files(self.app, False) - assert {} == actual - + self.assertEqual({}, actual) @patch('os.walk') @patch('os.path.isdir') @@ -214,7 +203,7 @@ def test__gather_files_bad_folder(self, path_mock, os_mock): path_mock.return_value = False actual = flask_s3._gather_files(self.app, False) - assert {} == actual + self.assertEqual({}, actual) @patch('os.path.splitdrive', side_effect=ntpath.splitdrive) @patch('os.path.join', side_effect=ntpath.join) @@ -225,7 +214,7 @@ def test__path_to_relative_url_win(self, join_mock, split_mock): expected = ['/foo/bar/baz.css', '/foo/bar.css', '/foo/bar.css'] for in_, exp in zip(input_, expected): actual = flask_s3._path_to_relative_url(in_) - assert exp == actual + self.assertEquals(exp, actual) @patch('flask_s3.Key') def test__write_files(self, key_mock): @@ -242,9 +231,7 @@ def test__write_files(self, key_mock): call().set_contents_from_filename('/home/z/bar.css')] flask_s3._write_files(self.app, static_url_loc, static_folder, assets, None, exclude) - - assert expected < key_mock.mock_calls - + self.assertLessEqual(expected, key_mock.mock_calls) def test_static_folder_path(self): """ Tests _static_folder_path """ @@ -254,4 +241,7 @@ def test_static_folder_path(self): expected = [u'/static/foo.css', u'/foo/static/a/b.css', u'/bar/s/a/b.css'] for i, e in zip(inputs, expected): - assert e == flask_s3._static_folder_path(*i) + self.assertEquals(e, flask_s3._static_folder_path(*i)) + +if __name__ == '__main__': + unittest.main() From c72e2f54119efd4f83b07587f8baffd438c8348b Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 11 Feb 2014 02:54:37 +0400 Subject: [PATCH 14/19] Pep8 fix: trim lines to 80 symbols in each line Revert using unittest --- flask_s3.py | 23 +++++++++++++++++------ tests/test_flask_static.py | 20 ++++++++++++-------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/flask_s3.py b/flask_s3.py index ab86a58..1b5e6bd 100644 --- a/flask_s3.py +++ b/flask_s3.py @@ -45,7 +45,9 @@ def url_for(endpoint, **values): def _bp_static_url(blueprint): """ builds the absolute url path for a blueprint's static folder """ - u = u'{0}{1}'.format(blueprint.url_prefix or '', blueprint.static_url_path or '') + u = u'{0}{1}'.format( + blueprint.url_prefix or '', + blueprint.static_url_path or '') return u @@ -61,7 +63,8 @@ def _gather_files(app, hidden): for static_folder, static_url_loc in dirs: if not os.path.isdir(static_folder): - logger.warning("WARNING - [{0} does not exist]".format(static_folder)) + logger.warning( + "WARNING - [{0} does not exist]".format(static_folder)) else: logger.debug("Checking static folder: {0}".format(static_folder)) for root, _, files in os.walk(static_folder): @@ -88,8 +91,9 @@ def _static_folder_path(static_url, static_folder, static_asset): # static_asset is not simply a filename because it could be # sub-directory then file etc. if not static_asset.startswith(static_folder): - raise ValueError("{0} startic asset must be under {1} static folder".format(static_asset, - static_folder)) + raise ValueError( + "{0} startic asset must be under {1} static folder".format(static_asset, + static_folder)) rel_asset = static_asset[len(static_folder):] # Now bolt the static url path and the relative asset location together return u'{0}/{1}'.format(static_url.rstrip('/'), rel_asset.lstrip('/')) @@ -100,7 +104,11 @@ def _write_files(app, static_url_loc, static_folder, files, bucket, """ Writes all the files inside a static folder to S3. """ if logger.level == logging.INFO: - files = tqdm(files, desc='Uploading from {0} to {1}'.format(static_url_loc, bucket.name)) + files = tqdm( + files, + desc='Uploading from {0} to {1}'.format( + static_url_loc, + bucket.name)) for file_path in files: asset_loc = _path_to_relative_url(file_path) @@ -206,7 +214,10 @@ def create_all(app, user=None, password=None, bucket_name=None, # build list of static files all_files = _gather_files(app, include_hidden) for (static_folder, static_url_loc), files in all_files.iteritems(): - logger.debug('{0} valid files in folder "{1}" with local url "{2}"'.format(len(files), static_folder, static_url_loc)) + logger.debug( + '{0} valid files in folder "{1}" with local url "{2}"'.format(len(files), + static_folder, + static_url_loc)) # connect to s3 conn = S3Connection(user, password) # get_or_create bucket diff --git a/tests/test_flask_static.py b/tests/test_flask_static.py index cf787fa..fbe29b4 100644 --- a/tests/test_flask_static.py +++ b/tests/test_flask_static.py @@ -6,11 +6,18 @@ import flask_s3 from flask_s3 import FlaskS3 +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class TestStatic(unittest.TestCase): -class TestStatic(object): def setUp(self): self.app = Flask(__name__) self.app.testing = True + @self.app.route('/') def a(url_for_string): return render_template_string(url_for_string) @@ -34,7 +41,8 @@ def test_config(self): self.assertIn(default, self.app.config) -class TestUrls(object): +class TestUrls(unittest.TestCase): + def setUp(self): self.app = Flask(__name__) self.app.testing = True @@ -52,12 +60,12 @@ def b(): return render_template_string("{{url_for('b')}}") bp = Blueprint('admin', __name__, static_folder='admin-static') + @bp.route('/') def c(): return render_template_string("{{url_for('b')}}") self.app.register_blueprint(bp) - def client_get(self, ufs): FlaskS3(self.app) client = self.app.test_client() @@ -121,8 +129,7 @@ def test_url_for_cdn_domain(self): self.assertEquals(self.client_get(ufs).data, exp) - -class TestS3(object): +class TestS3(unittest.TestCase): def setUp(self): self.app = Flask(__name__) @@ -242,6 +249,3 @@ def test_static_folder_path(self): u'/bar/s/a/b.css'] for i, e in zip(inputs, expected): self.assertEquals(e, flask_s3._static_folder_path(*i)) - -if __name__ == '__main__': - unittest.main() From 3d85d57743673cb76fcd3831379243a044d702a1 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 11 Feb 2014 03:18:56 +0400 Subject: [PATCH 15/19] WIP --- requirements-test.txt | 1 - tox.ini | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-test.txt b/requirements-test.txt index 326f4f1..a35e6a0 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,3 +1,2 @@ --r requirements.txt mock nose2 \ No newline at end of file diff --git a/tox.ini b/tox.ini index 32078a3..8825813 100644 --- a/tox.ini +++ b/tox.ini @@ -2,5 +2,6 @@ envlist=py27 [testenv] -deps=-r{toxinidir}/requirements-test.txt -commands=nose2 \ No newline at end of file +deps=-r{toxinidir}/requirements.txt + -r{toxinidir}/requirements-test.txt +commands=python setup.py test \ No newline at end of file From a1bb7eb3e254d66b80c9b9d4d5b8f38e20b0ede0 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 11 Feb 2014 03:53:40 +0400 Subject: [PATCH 16/19] Change setup.py Revert from nose2 to nose --- .travis.yml | 11 ++++++++++- flask_s3.py | 7 +++++++ nose2.cfg | 9 --------- requirements-test.txt | 4 +++- setup.py | 29 +++++++++++++++++++++++++---- tests/test_flask_static.py | 1 + tox.ini | 9 +++++---- 7 files changed, 51 insertions(+), 19 deletions(-) delete mode 100644 nose2.cfg diff --git a/.travis.yml b/.travis.yml index 8dfb226..6d4b38e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,13 @@ python: - "2.6" - "2.7" - "pypy" -script: python setup.py test \ No newline at end of file + +install: + - pip install . + - pip install -r requirements.txt + - pip install -r requirements-test.txt + +script: nosetests --with-coverage --cover-erase --cover-package=flask_s3 --cover-html + +after_success: + coveralls diff --git a/flask_s3.py b/flask_s3.py index 1b5e6bd..bc6aa92 100644 --- a/flask_s3.py +++ b/flask_s3.py @@ -1,3 +1,10 @@ +# -*- coding: utf-8 -*- + +__version__ = '0.1.6' +__author__ = 'Edward Robinson' +__license__ = 'WTFPL' + + import os import logging from collections import defaultdict diff --git a/nose2.cfg b/nose2.cfg deleted file mode 100644 index f78df58..0000000 --- a/nose2.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[unittest] -start-dir = tests -code-directories = '.' -test-file-pattern = test_*.py -test-method-prefix = test - -[log-capture] -always-on = True -clear-handlers = True \ No newline at end of file diff --git a/requirements-test.txt b/requirements-test.txt index a35e6a0..0054391 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,2 +1,4 @@ mock -nose2 \ No newline at end of file +nose +coverage +coveralls diff --git a/setup.py b/setup.py index 3457a72..ebcbc61 100644 --- a/setup.py +++ b/setup.py @@ -4,15 +4,36 @@ Easily serve your static files from Amazon S3. """ +import re +import os + from setuptools import setup +def fpath(name): + return os.path.join(os.path.dirname(__file__), name) + + +def read(fname): + return open(fpath(fname)).read() + + +file_text = read(fpath('flask_s3.py')) +def grep(attrname): + pattern = r"{0}\W*=\W*'([^']+)'".format(attrname) + strval, = re.findall(pattern, file_text) + return strval + + +def strip_comments(l): + return l.split('#', 1)[0].strip() + setup( name='Flask-S3', - version='0.1.6', + version=grep('__version__'), + license=grep('__license__'), + author=grep('__author__'), url='http://github.com/e-dard/flask-s3', - license='WTFPL', - author='Edward Robinson', author_email='hi@edd.io', description='Seamlessly serve the static files of your Flask app from Amazon S3', long_description=__doc__, @@ -27,7 +48,7 @@ 'tqdm' ], tests_require=['nose2', 'mock'], - test_suite='nose2.collector.collector', + test_suite='nose.collector', classifiers=[ 'Environment :: Web Environment', 'Intended Audience :: Developers', diff --git a/tests/test_flask_static.py b/tests/test_flask_static.py index fbe29b4..246f9d2 100644 --- a/tests/test_flask_static.py +++ b/tests/test_flask_static.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import ntpath from mock import Mock, patch, call diff --git a/tox.ini b/tox.ini index 8825813..c067cc3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,8 @@ [tox] -envlist=py27 +envlist = py27 [testenv] -deps=-r{toxinidir}/requirements.txt - -r{toxinidir}/requirements-test.txt -commands=python setup.py test \ No newline at end of file +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/requirements-test.txt + +commands = nosetests -xs From 0f3992a0d7daaa0514b212dd6fb181fe453c5ebd Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 11 Feb 2014 04:12:10 +0400 Subject: [PATCH 17/19] Support python 2.6 --- tests/test_flask_static.py | 21 ++++++++++++++++++--- tox.ini | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/test_flask_static.py b/tests/test_flask_static.py index 246f9d2..3496287 100644 --- a/tests/test_flask_static.py +++ b/tests/test_flask_static.py @@ -13,7 +13,22 @@ import unittest -class TestStatic(unittest.TestCase): +class BaseTestCase(unittest.TestCase): + + def assertIn(self, member, container, msg=None): + if hasattr(unittest.TestCase, 'assertIn'): + return unittest.TestCase.assertIn(self, member, container, msg) + + return self.assertTrue(member in container) + + + def assertLessEqual(self, a, b, msg=None): + if hasattr(unittest.TestCase, 'assertIn'): + return unittest.TestCase.assertLessEqual(self, a, b, msg) + + return self.assertTrue(a <= b) + +class TestStatic(BaseTestCase): def setUp(self): self.app = Flask(__name__) @@ -42,7 +57,7 @@ def test_config(self): self.assertIn(default, self.app.config) -class TestUrls(unittest.TestCase): +class TestUrls(BaseTestCase): def setUp(self): self.app = Flask(__name__) @@ -130,7 +145,7 @@ def test_url_for_cdn_domain(self): self.assertEquals(self.client_get(ufs).data, exp) -class TestS3(unittest.TestCase): +class TestS3(BaseTestCase): def setUp(self): self.app = Flask(__name__) diff --git a/tox.ini b/tox.ini index c067cc3..4d749f1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27 +envlist = py26, py27 [testenv] deps = -r{toxinidir}/requirements.txt From 389a82a1e5944d781e4d5682a94507be5261925c Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 11 Feb 2014 04:43:24 +0400 Subject: [PATCH 18/19] Nose and coverage settings --- .travis.yml | 10 +++++++--- setup.cfg | 7 +++++++ 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 setup.cfg diff --git a/.travis.yml b/.travis.yml index 6d4b38e..8c44a4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,11 @@ install: - pip install -r requirements.txt - pip install -r requirements-test.txt -script: nosetests --with-coverage --cover-erase --cover-package=flask_s3 --cover-html +script: + - coverage run --source=flask_s3.py setup.py test + - coverage report -m -after_success: - coveralls +after_script: + coveralls --verbose + + \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..5d4a35e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,7 @@ +[nosetests] +nocapture = 1 +with-coverage = 1 +cover-package = flask_s3 +cover-erase = 1 +cover-tests = 1 +cover-inclusive = 1 \ No newline at end of file From 78af090b588750f7454e6aa0322d832f3d7dd719 Mon Sep 17 00:00:00 2001 From: Klimin Mike Date: Tue, 11 Feb 2014 04:43:24 +0400 Subject: [PATCH 19/19] Nose and coverage settings --- .travis.yml | 10 +++++++--- setup.cfg | 7 +++++++ setup.py | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 setup.cfg diff --git a/.travis.yml b/.travis.yml index 6d4b38e..8c44a4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,11 @@ install: - pip install -r requirements.txt - pip install -r requirements-test.txt -script: nosetests --with-coverage --cover-erase --cover-package=flask_s3 --cover-html +script: + - coverage run --source=flask_s3.py setup.py test + - coverage report -m -after_success: - coveralls +after_script: + coveralls --verbose + + \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..5d4a35e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,7 @@ +[nosetests] +nocapture = 1 +with-coverage = 1 +cover-package = flask_s3 +cover-erase = 1 +cover-tests = 1 +cover-inclusive = 1 \ No newline at end of file diff --git a/setup.py b/setup.py index ebcbc61..8098d20 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ def strip_comments(l): 'Boto>=2.5.2', 'tqdm' ], - tests_require=['nose2', 'mock'], + tests_require=['nose', 'mock'], test_suite='nose.collector', classifiers=[ 'Environment :: Web Environment',