Commit c1d69d4c authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Add the subcommand dump, mysql to the script run.

parent 3fb5b7a0
......@@ -8,19 +8,52 @@
DESCRIPTION
The command has to be run in the scripts directory
It can execute tree subcommands 'loop', 'script' and 'pytest'.
It can execute the subcommands 'dump', 'loop', 'mysql', 'script'
and 'pytest'.
The script subcommand runs a given script in the application
context (model, modules and database are available).
The same software can serve several applications with only differ
by their databases. the subcommand can be applies to one of the
applications or to all of them.
The loop subcommand is similar the script one but it loops
over applications. They are defined by the DBURIS dictionary
located in models/_db_pro.py.
The 'script' subcommand runs a python script in the application
context (model, modules and database are available). By default
the application is the current one.
The pytest subcommand runs python tests within the pytest
framework and the application context.
The python tests are located in the directory myapplication/tests.
The path of the test are relative to that directory.
> cd ... track_publications/scripts
> ./run script my_script.py
When the same software serves several applications, it is possible
to select one of the application:
> cd ... track_publications/scripts
> ./run -S my_application_2 script my_script.py
The `loop` subcommand allows to execute the same script on all
applicatons. It used the DBURIS dictionary located in models/_db_pro.py.
For each application a confirmation is required before executing the
python script:
> cd ... track_publications/scripts
> ./run loop ../models/_db_pro.py my_script.py
The 'mysql' subcommand allows to execute a sql script on all databases.
It used the DBURIS dictionary to connect to them. For each application
a confirmation is required before excetuting the sql script.
> cd ... track_publications/scripts
> ./run mysql ../models/_db_pro.py my_script.sql
The 'dump' subcommand dumps the content of all databases. It used the
DBURIS dictionary to connect to them and the command mysqldump. For
each application a confirmation is required before the dump.
> cd ... track_publications/scripts
> ./run dump ../models/_db_pro.py
The 'pytest' subcommand runs python tests within the pytest framework
and the application context. The python tests are located in the
directory myapplication/tests. The path of the tests is relative to
that directory.
OPTIONS
-h, --help
......@@ -37,10 +70,16 @@
> ./run -h
> ./run script -h
> ./run script fix_report_number.py
> ./run script my_script.py
> ./run loop -h
> ./run loop ../models/_db_pro.py fix_report_number.py
> ./run loop ../models/_db_pro.py my_script.py
> ./run mysql -h
> ./run mysql ../models/_db_pro.py my_script.sql
> ./run dump -h
> ./run dump ../models/_db_pro.py
> ./run pytest -h
> ./run pytest
......@@ -52,13 +91,20 @@
R. Le Gac
"""
import datetime
import os
import pytest
import re
import subprocess
import sys
MSG_DUMP = '\nDump the database of "%s" [y/N]: '
MSG_SCRIPT = '\nExecute "%s" on "%s" [y/N]: '
MYSQL = '/usr/bin/mysql'
MYSQLDUMP = '/usr/bin/mysqldump'
PYTEST_SCRIPT = '_run_pytest.py'
REG_MYSQL = re.compile(r"mysql://(\w+):(\w+)@([\w\.]+)/(\w+)")
TEST_DIR = 'tests'
WEB2PY_DIR = '../../web2py'
WEB2PY = os.path.join(WEB2PY_DIR, 'web2py.py')
......@@ -77,11 +123,64 @@ def get_application():
return os.getcwd().split(os.sep)[-2]
def mysql(dburi, script):
"""Exceute the script on the mysql database.
Args:
dburi (str): mysql database identifier used by web2py.
script (str): file name of the script
"""
match = REG_MYSQL.match(dburi)
if not match:
print "Can't decode the URIs !!!"
return
cmd = [MYSQL,
"-h", match.group(3),
"-u", match.group(1),
"-p%s" % match.group(2),
match.group(4),
"< ", script]
ret = subprocess.call(" ".join(cmd), shell=True)
if ret == 0:
print "Database modified."
def mysqldump(dburi):
"""Dump the mysql database into an sql file.
Args:
dburi (str): mysql database identifier used by web2py.
"""
match = REG_MYSQL.match(dburi)
if not match:
print "Can't decode the URIs !!!"
return
dbname = match.group(4)
now = datetime.datetime.now()
fnsql = "%s_%s.sql" % (dbname, now.strftime("%Y-%m-%d"))
cmd = [MYSQLDUMP,
"-h", match.group(3),
"-u", match.group(1),
"-p%s" % match.group(2),
dbname,
"> ", fnsql]
ret = subprocess.call(" ".join(cmd), shell=True)
if ret == 0:
print "Database dumped in %s." % fnsql
def process(application, script, args):
"""Process the script within the framework of the application
Args:
application (str): the name of the application
script (str): filename for the script
args (str): optional argument to be passed to the script
......@@ -104,27 +203,76 @@ def process(application, script, args):
return subprocess.call(cmd)
def run_dump(args):
"""Dump the content of databases defined in the DBURIS dictionary.
It used the command mysqldump.
Args:
args
"""
# instantiate the DBURIS dictionary
execfile(args.dburis)
# loop over databases
for app, dburi in locals()['DBURIS'].iteritems():
msg = MSG_DUMP % app
rep = raw_input(msg)
if rep != "y":
print "Skip..."
continue
mysqldump(dburi)
def run_loop(args):
"""Run the python script on several applications.
Args:
args
"""
# instantiate the DBURIS dictionary
execfile(args.dburis)
# loop over applications
for application in locals()['DBURIS']:
msg = MSG_SCRIPT % (args.filename, application)
for app in locals()['DBURIS']:
msg = MSG_SCRIPT % (args.filename, app)
rep = raw_input(msg)
if rep != "y":
print "Skip..."
continue
process(app, args.filename, args.args)
def run_mysql(args):
"""Run a sql script on all the databases defined in the DBURIS dictionary.
Args:
args
"""
# instantiate the DBURIS dictionary
execfile(args.dburis)
# loop over databases
for app, dburi in locals()['DBURIS'].iteritems():
msg = MSG_SCRIPT % (args.filename, app)
rep = raw_input(msg)
if rep != "y":
print "Skip..."
continue
process(application, args.filename, args.args)
mysql(dburi, args.filename)
def run_pytest(args):
"""Run python test.
Args:
args
"""
cmd = ""
......@@ -155,6 +303,9 @@ def run_pytest(args):
def run_script(args):
"""Run the given script.
Args:
args
"""
return_code = process(args.shell, args.filename, args.args)
sys.exit(return_code)
......@@ -183,63 +334,85 @@ if __name__ == "__main__":
SUBPARSERS = PARSER.add_subparsers(title="subcommands",
description="valid subcommands",
help="additional help")
# parser for the dump subcommand
CDM1 = SUBPARSERS.add_parser("dump",
help="dump database contents in files")
# parser for the pytest subcommand
PYTEST = SUBPARSERS.add_parser("pytest",
help="run python unitary tests.")
CDM1.add_argument("dburis",
help="path to the python file containing the "
"DBURIS dictionary.")
PYTEST.add_argument("-q", "--quiet",
action="store_true",
help="minimal output.")
CDM1.set_defaults(func=run_dump)
PYTEST.add_argument("--capture",
choices=["fd", "sys", "no"],
help="per-test capturing method: one of fd|sys|no.")
# parser for the loop subcommand
CDM2 = SUBPARSERS.add_parser("loop",
help="run the python script "
"over applications.")
PYTEST.add_argument("-x" , "--exitfirst",
action="store_true",
help='stop after first failure.')
CDM2.add_argument("dburis",
help="path to the python file containing the "
"DBURIS dictionary.")
PYTEST.add_argument("-v", "--verbose",
action="store_true",
help="verbose mode.")
CDM2.add_argument("filename",
help="the name of the python script.")
PYTEST.add_argument("path",
nargs="?",
help="test path relative to the test directory.")
CDM2.add_argument("args",
nargs="?",
help="additional arguments to be passed to the script.")
PYTEST.set_defaults(func=run_pytest)
CDM2.set_defaults(func=run_loop)
# parser for the script subcommand
SCRIPT = SUBPARSERS.add_parser("script",
help="run dedicated python script.")
# parser for the mysql subcommand
CDM3 = SUBPARSERS.add_parser("mysql",
help="run the sql script over applications.")
SCRIPT.add_argument("filename",
help="the name of the python script.")
CDM3.add_argument("dburis",
help="path to the python file containing the "
"DBURIS dictionary.")
SCRIPT.add_argument("args",
nargs="?",
help="additional arguments to be passed to the script.")
CDM3.add_argument("filename",
help="the name of the sql script.")
SCRIPT.set_defaults(func=run_script)
CDM3.set_defaults(func=run_mysql)
# parser for the loop subcommand
LOOP = SUBPARSERS.add_parser("loop",
help="run the python script "
"over applications.")
# parser for the pytest subcommand
CDM4 = SUBPARSERS.add_parser("pytest",
help="run python unitary tests.")
LOOP.add_argument("dburis",
help="path to the python file containing the "
"DBURIS dictionary.")
CDM4.add_argument("-q", "--quiet",
action="store_true",
help="minimal output.")
LOOP.add_argument("filename",
help="the name of the python script.")
CDM4.add_argument("--capture",
choices=["fd", "sys", "no"],
help="per-test capturing method: one of fd|sys|no.")
CDM4.add_argument("-x" , "--exitfirst",
action="store_true",
help='stop after first failure.')
CDM4.add_argument("-v", "--verbose",
action="store_true",
help="verbose mode.")
CDM4.add_argument("path",
nargs="?",
help="test path relative to the test directory.")
CDM4.set_defaults(func=run_pytest)
# parser for the script subcommand
CDM5 = SUBPARSERS.add_parser("script",
help="run dedicated python script.")
CDM5.add_argument("filename",
help="the name of the python script.")
LOOP.add_argument("args",
CDM5.add_argument("args",
nargs="?",
help="additional arguments to be passed to the script.")
LOOP.set_defaults(func=run_loop)
CDM5.set_defaults(func=run_script)
# parse the command line and run the selected command
ARGS = PARSER.parse_args()
......
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