Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions cpp_coveralls/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import print_function

__author__ = 'Lei Xu <[email protected]>'
__version__ = '0.4.2'
__version__ = '0.4.3'

__classifiers__ = [
'Development Status :: 3 - Alpha',
Expand Down Expand Up @@ -73,9 +73,9 @@ def run():
# use environment COVERALLS_REPO_TOKEN as a fallback
args.repo_token = os.environ.get('COVERALLS_REPO_TOKEN')


# try get service name from yaml first
args.service_name = yml.get('service_name', '')
if not args.service_name:
args.service_name = yml.get('service_name', '')
if not args.service_name:
# use environment COVERALLS_SERVICE_NAME as a fallback
args.service_name = os.environ.get('COVERALLS_SERVICE_NAME')
Expand All @@ -94,21 +94,29 @@ def run():
args.include.extend(yml.get('include', []))
args.exclude_lines_pattern.extend(yml.get('exclude_lines_pattern', []))

args.service_job_id = os.environ.get('TRAVIS_JOB_ID', '')
if args.service_job_id is None:
args.service_job_id = os.environ.get('TRAVIS_JOB_ID', '')

if not args.parallel:
args.parallel = os.getenv('COVERALLS_PARALLEL', False)

if args.repo_token == '' and args.service_job_id == '':
raise ValueError("\nno coveralls.io token specified and no travis job id found\n"
"see --help for examples on how to specify a token\n")

if not args.no_gcov:
coverage.run_gcov(args)
cov_report = coverage.collect(args)
if args.verbose:
print(cov_report)
if args.dryrun:
return 0
if args.dump:
args.dump.write(json.dumps(cov_report))
return 0

return report.post_report(cov_report, args)
if args.action == 'report':
if not args.no_gcov:
coverage.run_gcov(args)
cov_report = coverage.collect(args)
if args.verbose:
print(cov_report)
if args.dryrun:
return 0
if args.dump:
args.dump.write(json.dumps(cov_report))
return 0
return report.post_report(cov_report, args)
elif args.action == 'finish-report':
return report.finish_report(args)
else:
raise ValueError("Not supported action")
49 changes: 34 additions & 15 deletions cpp_coveralls/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ def create_args(params):
help='skip ssl certificate verification when '
'communicating with the coveralls server',
action='store_true', default=False)
parser.add_argument('--service-name', type=str, default=None, help="The CI service or other environment in which the test suite was run. This can be anything, but certain services have special features (travis-ci, travis-pro, or coveralls-ruby).")
parser.add_argument('--service-job-id', type=str, default=None, help="A unique identifier of the job on the service specified by service_name.")
parser.add_argument('--service-build-number', type=str, default=None, help="The build number. Will default to chronological numbering from builds on repo.")
parser.add_argument('--parallel', action='store_true', help="Send a few reports and merge")
parser.add_argument('action', type=str, default='report', nargs='?', choices=['report', 'finish-report'], help="If the --parallel reports were used, the reports has to be finalized with a 'finish-report' action.")

return parser.parse_args(params)

Expand Down Expand Up @@ -225,16 +230,18 @@ def run_gcov(args):
gcov_files.append(files)
if re.search(r".*\.c.*", basename):
path = os.path.abspath(os.path.join(root, basename + '.o'))
subprocess.call(
'cd "%s" && %s %s%s "%s"' % (
gcov_root, args.gcov, args.gcov_options, local_gcov_options, path),
shell=True)
cmd = 'cd "%s" && %s %s%s "%s"' % (gcov_root, args.gcov, args.gcov_options, local_gcov_options, path)
if args.verbose:
print(cmd)

subprocess.call(cmd, shell=True)
else:
path = os.path.abspath(os.path.join(root, basename))
subprocess.call(
'cd "%s" && %s %s%s "%s"' % (
gcov_root, args.gcov, args.gcov_options, local_gcov_options, filepath),
shell=True)
cmd = 'cd "%s" && %s %s%s "%s"' % (gcov_root, args.gcov, args.gcov_options, local_gcov_options, filepath)
if args.verbose:
print(cmd)

subprocess.call(cmd, shell=True)
# If gcov was run in the build root move the resulting gcov
# file to the same directory as the .o file.
if custom_gcov_root:
Expand Down Expand Up @@ -276,23 +283,32 @@ def parse_gcov_file(args, fobj, filename):
sys.stderr.write("Warning: %s:%d: LCOV_EXCL_STOP is the "
"correct keyword\n" % (filename, line_num))
ignoring = False
if cov_num == '-':

line_num -= 1
while len(coverage) <= line_num:
coverage.append(None)

if cov_num == '-':
if coverage[line_num] is None:
coverage[line_num] = None
elif cov_num == '#####':
# Avoid false positives.
if (
ignoring or
any([re.search(pattern, text) for pattern in args.exclude_lines_pattern])
):
coverage.append(None)
if coverage[line_num] is None:
coverage[line_num] = None
else:
coverage.append(0)
if coverage[line_num] is None:
coverage[line_num] = 0
elif cov_num == '=====':
# This is indicitive of a gcov output parse
# error.
coverage.append(0)
if coverage[line_num] is None:
coverage[line_num] = 0
else:
coverage.append(int(cov_num.rstrip('*')))
coverage[line_num] = int(cov_num.rstrip('*'))
return coverage


Expand Down Expand Up @@ -382,8 +398,11 @@ def collect(args):
report['service_name'] = args.service_name
report['service_job_id'] = args.service_job_id

if os.getenv('COVERALLS_PARALLEL', False):
report['parallel'] = 'true'
if args.service_build_number:
report['service_number'] = args.service_build_number

if args.parallel:
report['parallel'] = args.parallel

args.exclude_lines_pattern.extend([
r'\bLCOV_EXCL_LINE\b',
Expand Down
17 changes: 15 additions & 2 deletions cpp_coveralls/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
import json
import os

URL = os.getenv('COVERALLS_ENDPOINT', 'https://coveralls.io') + "/api/v1/jobs"
ENDPOINT = os.getenv('COVERALLS_ENDPOINT', 'https://coveralls.io')

def post_report(coverage, args):
"""Post coverage report to coveralls.io."""
response = requests.post(URL, files={'json_file': json.dumps(coverage)},
api_endpoint = f'{ENDPOINT}/api/v1/jobs'
response = requests.post(api_endpoint, files={'json_file': json.dumps(coverage)},
verify=(not args.skip_ssl_verify))
try:
result = response.json()
Expand All @@ -22,3 +23,15 @@ def post_report(coverage, args):
if 'error' in result:
return result['error']
return 0

def finish_report(args):
"""Finish a parallel reporting: https://docs.coveralls.io/parallel-build-webhook"""
api_endpoint = f'{ENDPOINT}/webhook?repo_token={args.repo_token}'
data = {'payload[build_num]': args.service_build_number, 'payload[status]':'done'}
response = requests.post(api_endpoint, data=data,
verify=(not args.skip_ssl_verify))

if response.status_code != 200:
return response.status_code, response.reason, data
else:
return 0