mirror of https://github.com/mitsuhiko/flask.git
David Lord
7 years ago
committed by
GitHub
67 changed files with 486 additions and 705 deletions
@ -1,40 +1,12 @@ |
|||||||
Flask is written and maintained by Armin Ronacher and |
Flask is developed and maintained by the Pallets team and community |
||||||
various contributors: |
contributors. It was created by Armin Ronacher. The core maintainers |
||||||
|
are: |
||||||
|
|
||||||
Development Lead |
- David Lord (davidism) |
||||||
```````````````` |
- Adrian Mönnich (ThiefMaster) |
||||||
|
- Armin Ronacher (mitsuhiko) |
||||||
|
- Marcus Unterwaditzer (untitaker) |
||||||
|
|
||||||
- Armin Ronacher <armin.ronacher@active-4.com> |
A full list of contributors is available from git with:: |
||||||
|
|
||||||
Patches and Suggestions |
git shortlog -sne |
||||||
``````````````````````` |
|
||||||
|
|
||||||
- Adam Byrtek |
|
||||||
- Adam Zapletal |
|
||||||
- Ali Afshar |
|
||||||
- Chris Edgemon |
|
||||||
- Chris Grindstaff |
|
||||||
- Christopher Grebs |
|
||||||
- Daniel Neuhäuser |
|
||||||
- Dan Sully |
|
||||||
- David Lord @davidism |
|
||||||
- Edmond Burnett |
|
||||||
- Florent Xicluna |
|
||||||
- Georg Brandl |
|
||||||
- Hsiaoming Yang @lepture |
|
||||||
- Jeff Widman @jeffwidman |
|
||||||
- Joshua Bronson @jab |
|
||||||
- Justin Quick |
|
||||||
- Kenneth Reitz |
|
||||||
- Keyan Pishdadian |
|
||||||
- Marian Sigler |
|
||||||
- Martijn Pieters |
|
||||||
- Matt Campell |
|
||||||
- Matthew Frazier |
|
||||||
- Michael van Tellingen |
|
||||||
- Ron DuPlain |
|
||||||
- Sebastien Estienne |
|
||||||
- Simon Sapin |
|
||||||
- Stephane Wirtel |
|
||||||
- Thomas Schranz |
|
||||||
- Zhao Xiaohong |
|
||||||
|
@ -1,33 +1,31 @@ |
|||||||
Copyright (c) 2015 by Armin Ronacher and contributors. See AUTHORS |
Copyright © 2010 by the Pallets team. |
||||||
for more details. |
|
||||||
|
|
||||||
Some rights reserved. |
Some rights reserved. |
||||||
|
|
||||||
Redistribution and use in source and binary forms of the software as well |
Redistribution and use in source and binary forms of the software as |
||||||
as documentation, with or without modification, are permitted provided |
well as documentation, with or without modification, are permitted |
||||||
that the following conditions are met: |
provided that the following conditions are met: |
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright |
* Redistributions of source code must retain the above copyright notice, |
||||||
notice, this list of conditions and the following disclaimer. |
this list of conditions and the following disclaimer. |
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above |
* Redistributions in binary form must reproduce the above copyright |
||||||
copyright notice, this list of conditions and the following |
notice, this list of conditions and the following disclaimer in the |
||||||
disclaimer in the documentation and/or other materials provided |
documentation and/or other materials provided with the distribution. |
||||||
with the distribution. |
|
||||||
|
|
||||||
* The names of the contributors may not be used to endorse or |
* Neither the name of the copyright holder nor the names of its |
||||||
promote products derived from this software without specific |
contributors may be used to endorse or promote products derived from |
||||||
prior written permission. |
this software without specific prior written permission. |
||||||
|
|
||||||
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT |
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, |
||||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER |
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
||||||
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF |
||||||
DAMAGE. |
SUCH DAMAGE. |
||||||
|
@ -1,49 +0,0 @@ |
|||||||
|
|
||||||
|
|
||||||
// Flask // |
|
||||||
|
|
||||||
web development, one drop at a time |
|
||||||
|
|
||||||
|
|
||||||
~ What is Flask? |
|
||||||
|
|
||||||
Flask is a microframework for Python based on Werkzeug |
|
||||||
and Jinja2. It's intended for getting started very quickly |
|
||||||
and was developed with best intentions in mind. |
|
||||||
|
|
||||||
~ Is it ready? |
|
||||||
|
|
||||||
It's still not 1.0 but it's shaping up nicely and is |
|
||||||
already widely used. Consider the API to slightly |
|
||||||
improve over time but we don't plan on breaking it. |
|
||||||
|
|
||||||
~ What do I need? |
|
||||||
|
|
||||||
All dependencies are installed by using `pip install Flask`. |
|
||||||
We encourage you to use a virtualenv. Check the docs for |
|
||||||
complete installation and usage instructions. |
|
||||||
|
|
||||||
~ Where are the docs? |
|
||||||
|
|
||||||
Go to http://flask.pocoo.org/docs/ for a prebuilt version |
|
||||||
of the current documentation. Otherwise build them yourself |
|
||||||
from the sphinx sources in the docs folder. |
|
||||||
|
|
||||||
~ Where are the tests? |
|
||||||
|
|
||||||
Good that you're asking. The tests are in the |
|
||||||
tests/ folder. To run the tests use the |
|
||||||
`pytest` testing tool: |
|
||||||
|
|
||||||
$ pytest |
|
||||||
|
|
||||||
Details on contributing can be found in CONTRIBUTING.rst |
|
||||||
|
|
||||||
~ Where can I get help? |
|
||||||
|
|
||||||
Either use the #pocoo IRC channel on irc.freenode.net or |
|
||||||
ask on the mailinglist: http://flask.pocoo.org/mailinglist/ |
|
||||||
|
|
||||||
See http://flask.pocoo.org/community/ for more resources. |
|
||||||
|
|
||||||
|
|
@ -0,0 +1,62 @@ |
|||||||
|
Flask |
||||||
|
===== |
||||||
|
|
||||||
|
Flask is a lightweight `WSGI`_ web application framework. It is designed |
||||||
|
to make getting started quick and easy, with the ability to scale up to |
||||||
|
complex applications. It began as a simple wrapper around `Werkzeug`_ |
||||||
|
and `Jinja`_ and has become one of the most popular Python web |
||||||
|
application frameworks. |
||||||
|
|
||||||
|
Flask offers suggestions, but doesn't enforce any dependencies or |
||||||
|
project layout. It is up to the developer to choose the tools and |
||||||
|
libraries they want to use. There are many extensions provided by the |
||||||
|
community that make adding new functionality easy. |
||||||
|
|
||||||
|
|
||||||
|
Installing |
||||||
|
---------- |
||||||
|
|
||||||
|
Install and update using `pip`_: |
||||||
|
|
||||||
|
.. code-block:: text |
||||||
|
|
||||||
|
pip install -U Flask |
||||||
|
|
||||||
|
|
||||||
|
A Simple Example |
||||||
|
---------------- |
||||||
|
|
||||||
|
.. code-block:: python |
||||||
|
|
||||||
|
from flask import Flask |
||||||
|
|
||||||
|
app = Flask(__name__) |
||||||
|
|
||||||
|
@app.route('/') |
||||||
|
def hello(): |
||||||
|
return 'Hello, World!' |
||||||
|
|
||||||
|
.. code-block:: none |
||||||
|
|
||||||
|
$ FLASK_APP=hello.py flask run |
||||||
|
* Running on http://localhost:5000/ |
||||||
|
|
||||||
|
|
||||||
|
Links |
||||||
|
----- |
||||||
|
|
||||||
|
* Website: https://www.palletsprojects.com/p/flask/ |
||||||
|
* Releases: https://pypi.org/project/Flask/ |
||||||
|
* Code: https://github.com/pallets/flask |
||||||
|
* Issue tracker: https://github.com/pallets/flask/issues |
||||||
|
* Test status: |
||||||
|
|
||||||
|
* Linux, Mac: https://travis-ci.org/pallets/flask |
||||||
|
* Windows: https://ci.appveyor.com/project/pallets/flask |
||||||
|
|
||||||
|
* Test coverage: https://codecov.io/gh/pallets/flask |
||||||
|
|
||||||
|
.. _WSGI: https://wsgi.readthedocs.io |
||||||
|
.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/ |
||||||
|
.. _Jinja: https://www.palletsprojects.com/p/jinja/ |
||||||
|
.. _pip: https://pip.pypa.io/en/stable/quickstart/ |
@ -1,309 +0,0 @@ |
|||||||
# -*- coding: utf-8 -*- |
|
||||||
""" |
|
||||||
Flask Extension Tests |
|
||||||
~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
|
|
||||||
Tests the Flask extensions. |
|
||||||
|
|
||||||
:copyright: (c) 2015 by Ali Afshar. |
|
||||||
:license: BSD, see LICENSE for more details. |
|
||||||
""" |
|
||||||
|
|
||||||
import os |
|
||||||
import sys |
|
||||||
import shutil |
|
||||||
import urllib2 |
|
||||||
import tempfile |
|
||||||
import subprocess |
|
||||||
import argparse |
|
||||||
|
|
||||||
from flask import json |
|
||||||
|
|
||||||
from setuptools.package_index import PackageIndex |
|
||||||
from setuptools.archive_util import unpack_archive |
|
||||||
|
|
||||||
flask_svc_url = 'http://flask.pocoo.org/extensions/' |
|
||||||
|
|
||||||
|
|
||||||
# OS X has awful paths when using mkstemp or gettempdir(). I don't |
|
||||||
# care about security or clashes here, so pick something that is |
|
||||||
# actually memorable. |
|
||||||
if sys.platform == 'darwin': |
|
||||||
_tempdir = '/private/tmp' |
|
||||||
else: |
|
||||||
_tempdir = tempfile.gettempdir() |
|
||||||
tdir = _tempdir + '/flaskext-test' |
|
||||||
flaskdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) |
|
||||||
|
|
||||||
|
|
||||||
# virtualenv hack *cough* |
|
||||||
os.environ['PYTHONDONTWRITEBYTECODE'] = '' |
|
||||||
|
|
||||||
|
|
||||||
RESULT_TEMPATE = u'''\ |
|
||||||
<!doctype html> |
|
||||||
<title>Flask-Extension Test Results</title> |
|
||||||
<style type=text/css> |
|
||||||
body { font-family: 'Georgia', serif; font-size: 17px; color: #000; } |
|
||||||
a { color: #004B6B; } |
|
||||||
a:hover { color: #6D4100; } |
|
||||||
h1, h2, h3 { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; } |
|
||||||
h1 { font-size: 30px; margin: 15px 0 5px 0; } |
|
||||||
h2 { font-size: 24px; margin: 15px 0 5px 0; } |
|
||||||
h3 { font-size: 19px; margin: 15px 0 5px 0; } |
|
||||||
textarea, code, |
|
||||||
pre { font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', |
|
||||||
'Bitstream Vera Sans Mono', monospace!important; font-size: 15px; |
|
||||||
background: #eee; } |
|
||||||
pre { padding: 7px 15px; line-height: 1.3; } |
|
||||||
p { line-height: 1.4; } |
|
||||||
table { border: 1px solid black; border-collapse: collapse; |
|
||||||
margin: 15px 0; } |
|
||||||
td, th { border: 1px solid black; padding: 4px 10px; |
|
||||||
text-align: left; } |
|
||||||
th { background: #eee; font-weight: normal; } |
|
||||||
tr.success { background: #D3F5CC; } |
|
||||||
tr.failed { background: #F5D2CB; } |
|
||||||
</style> |
|
||||||
<h1>Flask-Extension Test Results</h1> |
|
||||||
<p> |
|
||||||
This page contains the detailed test results for the test run of |
|
||||||
all {{ 'approved' if approved }} Flask extensions. |
|
||||||
<h2>Summary</h2> |
|
||||||
<table class=results> |
|
||||||
<thead> |
|
||||||
<tr> |
|
||||||
<th>Extension |
|
||||||
<th>Version |
|
||||||
<th>Author |
|
||||||
<th>License |
|
||||||
<th>Outcome |
|
||||||
{%- for iptr, _ in results[0].logs|dictsort %} |
|
||||||
<th>{{ iptr }} |
|
||||||
{%- endfor %} |
|
||||||
</tr> |
|
||||||
</thead> |
|
||||||
<tbody> |
|
||||||
{%- for result in results %} |
|
||||||
{% set outcome = 'success' if result.success else 'failed' %} |
|
||||||
<tr class={{ outcome }}> |
|
||||||
<th>{{ result.name }} |
|
||||||
<td>{{ result.version }} |
|
||||||
<td>{{ result.author }} |
|
||||||
<td>{{ result.license }} |
|
||||||
<td>{{ outcome }} |
|
||||||
{%- for iptr, _ in result.logs|dictsort %} |
|
||||||
<td><a href="#{{ result.name }}-{{ iptr }}">see log</a> |
|
||||||
{%- endfor %} |
|
||||||
</tr> |
|
||||||
{%- endfor %} |
|
||||||
</tbody> |
|
||||||
</table> |
|
||||||
<h2>Test Logs</h2> |
|
||||||
<p>Detailed test logs for all tests on all platforms: |
|
||||||
{%- for result in results %} |
|
||||||
{%- for iptr, log in result.logs|dictsort %} |
|
||||||
<h3 id="{{ result.name }}-{{ iptr }}"> |
|
||||||
{{ result.name }} - {{ result.version }} [{{ iptr }}]</h3> |
|
||||||
<pre>{{ log }}</pre> |
|
||||||
{%- endfor %} |
|
||||||
{%- endfor %} |
|
||||||
''' |
|
||||||
|
|
||||||
|
|
||||||
def log(msg, *args): |
|
||||||
print('[EXTTEST] ' + (msg % args)) |
|
||||||
|
|
||||||
|
|
||||||
class TestResult(object): |
|
||||||
|
|
||||||
def __init__(self, name, folder, statuscode, interpreters): |
|
||||||
intrptr = os.path.join(folder, '.tox/%s/bin/python' |
|
||||||
% interpreters[0]) |
|
||||||
self.statuscode = statuscode |
|
||||||
self.folder = folder |
|
||||||
self.success = statuscode == 0 |
|
||||||
|
|
||||||
def fetch(field): |
|
||||||
try: |
|
||||||
c = subprocess.Popen([intrptr, 'setup.py', |
|
||||||
'--' + field], cwd=folder, |
|
||||||
stdout=subprocess.PIPE) |
|
||||||
return c.communicate()[0].strip() |
|
||||||
except OSError: |
|
||||||
return '?' |
|
||||||
self.name = name |
|
||||||
self.license = fetch('license') |
|
||||||
self.author = fetch('author') |
|
||||||
self.version = fetch('version') |
|
||||||
|
|
||||||
self.logs = {} |
|
||||||
for interpreter in interpreters: |
|
||||||
logfile = os.path.join(folder, '.tox/%s/log/test.log' |
|
||||||
% interpreter) |
|
||||||
if os.path.isfile(logfile): |
|
||||||
self.logs[interpreter] = open(logfile).read() |
|
||||||
else: |
|
||||||
self.logs[interpreter] = '' |
|
||||||
|
|
||||||
|
|
||||||
def create_tdir(): |
|
||||||
try: |
|
||||||
shutil.rmtree(tdir) |
|
||||||
except Exception: |
|
||||||
pass |
|
||||||
os.mkdir(tdir) |
|
||||||
|
|
||||||
|
|
||||||
def package_flask(): |
|
||||||
distfolder = tdir + '/.flask-dist' |
|
||||||
c = subprocess.Popen(['python', 'setup.py', 'sdist', '--formats=gztar', |
|
||||||
'--dist', distfolder], cwd=flaskdir) |
|
||||||
c.wait() |
|
||||||
return os.path.join(distfolder, os.listdir(distfolder)[0]) |
|
||||||
|
|
||||||
|
|
||||||
def get_test_command(checkout_dir): |
|
||||||
if os.path.isfile(checkout_dir + '/Makefile'): |
|
||||||
return 'make test' |
|
||||||
return 'python setup.py test' |
|
||||||
|
|
||||||
|
|
||||||
def fetch_extensions_list(): |
|
||||||
req = urllib2.Request(flask_svc_url, headers={'accept':'application/json'}) |
|
||||||
d = urllib2.urlopen(req).read() |
|
||||||
data = json.loads(d) |
|
||||||
for ext in data['extensions']: |
|
||||||
yield ext |
|
||||||
|
|
||||||
|
|
||||||
def checkout_extension(name): |
|
||||||
log('Downloading extension %s to temporary folder', name) |
|
||||||
root = os.path.join(tdir, name) |
|
||||||
os.mkdir(root) |
|
||||||
checkout_path = PackageIndex().download(name, root) |
|
||||||
|
|
||||||
unpack_archive(checkout_path, root) |
|
||||||
path = None |
|
||||||
for fn in os.listdir(root): |
|
||||||
path = os.path.join(root, fn) |
|
||||||
if os.path.isdir(path): |
|
||||||
break |
|
||||||
log('Downloaded to %s', path) |
|
||||||
return path |
|
||||||
|
|
||||||
|
|
||||||
tox_template = """[tox] |
|
||||||
envlist=%(env)s |
|
||||||
|
|
||||||
[testenv] |
|
||||||
deps= |
|
||||||
%(deps)s |
|
||||||
distribute |
|
||||||
py |
|
||||||
commands=bash flaskext-runtest.sh {envlogdir}/test.log |
|
||||||
downloadcache=%(cache)s |
|
||||||
""" |
|
||||||
|
|
||||||
|
|
||||||
def create_tox_ini(checkout_path, interpreters, flask_dep): |
|
||||||
tox_path = os.path.join(checkout_path, 'tox-flask-test.ini') |
|
||||||
if not os.path.exists(tox_path): |
|
||||||
with open(tox_path, 'w') as f: |
|
||||||
f.write(tox_template % { |
|
||||||
'env': ','.join(interpreters), |
|
||||||
'cache': tdir, |
|
||||||
'deps': flask_dep |
|
||||||
}) |
|
||||||
return tox_path |
|
||||||
|
|
||||||
|
|
||||||
def iter_extensions(only_approved=True): |
|
||||||
for ext in fetch_extensions_list(): |
|
||||||
if ext['approved'] or not only_approved: |
|
||||||
yield ext['name'] |
|
||||||
|
|
||||||
|
|
||||||
def test_extension(name, interpreters, flask_dep): |
|
||||||
checkout_path = checkout_extension(name) |
|
||||||
log('Running tests with tox in %s', checkout_path) |
|
||||||
|
|
||||||
# figure out the test command and write a wrapper script. We |
|
||||||
# can't write that directly into the tox ini because tox does |
|
||||||
# not invoke the command from the shell so we have no chance |
|
||||||
# to pipe the output into a logfile. The /dev/null hack is |
|
||||||
# to trick py.test (if used) into not guessing widths from the |
|
||||||
# invoking terminal. |
|
||||||
test_command = get_test_command(checkout_path) |
|
||||||
log('Test command: %s', test_command) |
|
||||||
f = open(checkout_path + '/flaskext-runtest.sh', 'w') |
|
||||||
f.write(test_command + ' &> "$1" < /dev/null\n') |
|
||||||
f.close() |
|
||||||
|
|
||||||
# if there is a tox.ini, remove it, it will cause troubles |
|
||||||
# for us. Remove it if present, we are running tox ourselves |
|
||||||
# afterall. |
|
||||||
|
|
||||||
create_tox_ini(checkout_path, interpreters, flask_dep) |
|
||||||
rv = subprocess.call(['tox', '-c', 'tox-flask-test.ini'], cwd=checkout_path) |
|
||||||
return TestResult(name, checkout_path, rv, interpreters) |
|
||||||
|
|
||||||
|
|
||||||
def run_tests(extensions, interpreters): |
|
||||||
results = {} |
|
||||||
create_tdir() |
|
||||||
log('Packaging Flask') |
|
||||||
flask_dep = package_flask() |
|
||||||
log('Running extension tests') |
|
||||||
log('Temporary Environment: %s', tdir) |
|
||||||
for name in extensions: |
|
||||||
log('Testing %s', name) |
|
||||||
result = test_extension(name, interpreters, flask_dep) |
|
||||||
if result.success: |
|
||||||
log('Extension test succeeded') |
|
||||||
else: |
|
||||||
log('Extension test failed') |
|
||||||
results[name] = result |
|
||||||
return results |
|
||||||
|
|
||||||
|
|
||||||
def render_results(results, approved): |
|
||||||
from jinja2 import Template |
|
||||||
items = results.values() |
|
||||||
items.sort(key=lambda x: x.name.lower()) |
|
||||||
rv = Template(RESULT_TEMPATE, autoescape=True).render(results=items, |
|
||||||
approved=approved) |
|
||||||
fd, filename = tempfile.mkstemp(suffix='.html') |
|
||||||
os.fdopen(fd, 'w').write(rv.encode('utf-8') + '\n') |
|
||||||
return filename |
|
||||||
|
|
||||||
|
|
||||||
def main(): |
|
||||||
parser = argparse.ArgumentParser(description='Runs Flask extension tests') |
|
||||||
parser.add_argument('--all', dest='all', action='store_true', |
|
||||||
help='run against all extensions, not just approved') |
|
||||||
parser.add_argument('--browse', dest='browse', action='store_true', |
|
||||||
help='show browser with the result summary') |
|
||||||
parser.add_argument('--env', dest='env', default='py25,py26,py27', |
|
||||||
help='the tox environments to run against') |
|
||||||
parser.add_argument('--extension=', dest='extension', default=None, |
|
||||||
help='tests a single extension') |
|
||||||
args = parser.parse_args() |
|
||||||
|
|
||||||
if args.extension is not None: |
|
||||||
only_approved = False |
|
||||||
extensions = [args.extension] |
|
||||||
else: |
|
||||||
only_approved = not args.all |
|
||||||
extensions = iter_extensions(only_approved) |
|
||||||
|
|
||||||
results = run_tests(extensions, [x.strip() for x in args.env.split(',')]) |
|
||||||
filename = render_results(results, only_approved) |
|
||||||
if args.browse: |
|
||||||
import webbrowser |
|
||||||
webbrowser.open('file:///' + filename.lstrip('/')) |
|
||||||
print('Results written to {}'.format(filename)) |
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__': |
|
||||||
main() |
|
Loading…
Reference in new issue