Skip to content

Instantly share code, notes, and snippets.

@diyan
Created October 27, 2011 17:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save diyan/1320287 to your computer and use it in GitHub Desktop.
Save diyan/1320287 to your computer and use it in GitHub Desktop.
Buld script for Python project (virtualenv, pip with requirement file, pylint, py.test, coverage, Jenkins CI) which could be executed from both system and virtual environment
import os
import sys
# One or several build tasks could be executed from Jenkins CI as following:
# #!/bin/bash
# cd $WORKSPACE/release_system/src/build/
# python -c 'from build_tasks import *; code_analysis(); run_tests()'
class BuildEnvironment(object):
def __init__(self):
self.project_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))
self.source_dir = os.path.join(self.project_dir, 'src')
self.root_init_path = os.path.join(self.source_dir, '__init__.py')
self.virtualenv_dir = os.path.join(self.project_dir, 'env')
self.coverage_config_path = os.path.join(self.project_dir, 'src/build/coverage_config.ini')
self.build_report_dir = os.path.join(self.project_dir, 'build_output/reports')
self.test_report_path = os.path.join(self.build_report_dir, 'test_report.xml')
self.pylint_report_path = os.path.join(self.build_report_dir, 'pylint_report.txt')
self.pylint_suppress_csv = 'C0111,R0903,W0232,R0201,W0511'
build_env = BuildEnvironment()
def setup_virtual_environment_win32():
"""Create Python virtual environment if it not exists or re-create if outdated."""
if not os.path.exists(build_env.virtualenv_dir):
os.chdir(build_env.project_dir)
os.system('virtualenv env --no-site-packages')
activate_virtual_environment()
os.system('pip install --requirement=pip_requires.txt --download-cache=pip_download_cache')
def activate_virtual_environment():
""" Activates virtual environment in the same way as activate.bat or activate.sh from virtualenv package """
if not hasattr(sys, 'real_prefix') or 'VIRTUAL_ENV' not in os.environ:
activate_this = '{0}/env/bin/activate_this.py'.format(build_env.project_dir)
virtual_env_path = '{0}/env/bin:'.format(build_env.project_dir)
if os.name == 'nt':
activate_this = '{0}/env/Scripts/activate_this.py'.format(build_env.project_dir)
virtual_env_path = '{0}\env\Scripts;'.format(build_env.project_dir)
execfile(activate_this, dict(__file__=activate_this))
path = os.environ['PATH']
os.environ['PATH'] = virtual_env_path + path
def code_analysis():
"""
Runs PyLint code analysis tool and suppress it's error code with simple echo printing.
Otherwise each build will be failed because of code style issues.
"""
activate_virtual_environment()
if not os.path.exists(build_env.build_report_dir):
os.makedirs(build_env.build_report_dir)
os.chdir(build_env.source_dir)
os.system('pylint --max-line-length=120 --output-format=parseable --disable={0} {1} >> {2}'.format(
build_env.pylint_suppress_csv,
build_env.source_dir,
build_env.pylint_report_path))
print('pylint code analysis was completed')
def run_tests():
"""
Runs unit tests with enabled code coverage.
Produces JUnit-compatible test run report and two coverage reports - Cobertura-compatible xml and Html report
"""
activate_virtual_environment()
if not os.path.exists(build_env.build_report_dir):
os.makedirs(build_env.build_report_dir)
os.chdir(build_env.source_dir)
# NOTE that PyLint requires __init__.py file in project root BUT py.test must be executed without this file.
# Root module's init file must be renamed before running test; otherwise ImportError occurs because
# all modules will have names like 'src.common', 'src.data_access' instead of just 'common', 'data_access'.
root_init_temp_path = build_env.root_init_path + '.tmp'
os.rename(build_env.root_init_path, root_init_temp_path)
os.system('py.test . --cov=. --cov-report=xml --cov-report=html --junitxml={0} --cov-config={1}'.format(
build_env.test_report_path,
build_env.coverage_config_path))
os.rename(root_init_temp_path, build_env.root_init_path)
if __name__ == '__main__':
run_tests()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment