From 41767c4af67a451ef3eeb78252ebbd3f5d295dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Sun, 6 Sep 2015 14:42:20 +0100 Subject: [PATCH 01/33] refactor to pip package --- .gitignore | 102 ++++++++++++++++++++++++++++++++++++++++++++- DESCRIPTION.rst | 13 ++++++ README.md | 39 +++++++++++++++-- __init__.py | 106 +++++++++++++++++++++++++++++++++++++++++++++++ codacycov.py | 55 ------------------------ requirements.txt | 1 - setup.cfg | 5 +++ setup.py | 57 +++++++++++++++++++++++++ 8 files changed, 317 insertions(+), 61 deletions(-) create mode 100644 DESCRIPTION.rst create mode 100755 __init__.py delete mode 100644 codacycov.py delete mode 100644 requirements.txt create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/.gitignore b/.gitignore index ecb2893..527f6bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,105 @@ -*.py[cdo] +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ build/ +develop-eggs/ dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ *.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ .coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties diff --git a/DESCRIPTION.rst b/DESCRIPTION.rst new file mode 100644 index 0000000..68b3a57 --- /dev/null +++ b/DESCRIPTION.rst @@ -0,0 +1,13 @@ +A sample Python project +======================= + +This is the description file for the project. + +The file should use UTF-8 encoding and be written using ReStructured Text. It +will be used to generate the project webpage on PyPI, and should be written for +that purpose. + +Typical contents for this file would include an overview of the project, basic +usage examples, etc. Generally, including the project changelog in here is not +a good idea, although a simple "What's New" section for the most recent version +may be appropriate. diff --git a/README.md b/README.md index ccead75..c329098 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,37 @@ -# python-codacycov +# python-coverage-coverage +[![Build Status](https://circleci.com/gh/codacy/python-codacy-coverage.png?style=shield&circle-token=:circle-token)](https://circleci.com/gh/codacy/python-codacy-coverage) +[![Codacy Badge](https://www.codacy.com/project/badge/1c524e61cd8640e79b80d406eda8754b)](https://www.codacy.com/app/Codacy/python-codacy-coverage-) -Submit Python `coverage` report to [Codacy](https://www.codacy.com/). +Python coverage reporter for Codacy https://www.codacy.com -DISCLAIMER: This is an unofficial project, and is not endorsed by or -associated with Codacy in any way. +## Setup + +Codacy assumes that coverage is previously configured for your project. + +You can install the coverage reporter by running: + +### [Install jpm](https://www.jpm4j.org/#!/md/install) +``` +curl http://www.jpm4j.org/install/script | sh +``` + +### Install codacy-coverage-reporter +``` +jpm install com.codacy:codacy-coverage-reporter +``` + +## Updating Codacy + +To update Codacy, you will need your project API token. You can find the token in Project -> Settings -> Integrations -> Project API. + +Then set it in your terminal, replacing %Project_Token% with your own token: + +``` +export CODACY_PROJECT_TOKEN=%Project_Token% +``` + +Next, simply run the Codacy reporter. It will find the current commit and send all details to your project dashboard: + +``` +python-codacy-coverage -f coverage.xml +``` diff --git a/__init__.py b/__init__.py new file mode 100755 index 0000000..3867d8e --- /dev/null +++ b/__init__.py @@ -0,0 +1,106 @@ +"""Codacy coverage reporter for Python""" + +import argparse +import json +import logging +import os +from xml.dom import minidom + +import requests + +logging.basicConfig(level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s') + +CODACY_PROJECT_TOKEN = os.getenv('CODACY_PROJECT_TOKEN') +CODACY_BASE_API_URL = os.getenv('CODACY_BASE_API_URL', 'https://api.codacy.com') +URL = CODACY_BASE_API_URL + '/2.0/coverage/{commit}/python' +DEFAULT_REPORT_FILE = 'coverage.xml' + + +def get_git_revision_hash(): + import subprocess + + return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip() + + +def parse_report_file(report_file): + # Convert decimal string to floored int percent value + percent = lambda s: int(float(s) * 100) + + # Parse the XML into the format expected by the API + report_xml = minidom.parse(report_file) + + report = { + 'language': "python", + 'total': percent(report_xml.getElementsByTagName('coverage')[0].attributes['line-rate'].value), + 'fileReports': [], + } + + classes = report_xml.getElementsByTagName('class') + for cls in classes: + file_report = { + 'filename': cls.attributes['filename'].value, + 'total': percent(cls.attributes['line-rate'].value), + 'coverage': {}, + } + lines = cls.getElementsByTagName('line') + for line in lines: + hits = int(line.attributes['hits'].value) + if hits >= 1: + # The API assumes 0 if a line is missing + file_report['coverage'][line.attributes['number'].value] = hits + report['fileReports'] += [file_report] + + return report + + +def upload_report(report, token, commit): + # Try to send the data, raise an exception if we fail + url = URL.format(commit=commit) + data = json.dumps(report) + headers = { + "project_token": token, + "Content-Type": "application/json" + } + + logging.debug(data) + + r = requests.post(url, data=data, headers=headers, allow_redirects=True) + + logging.debug(r.content) + logging.debug(r.status_code) + r.raise_for_status() + + message = json.loads(r.content)['success'] + logging.info(message) + + +def main(report_file, token, commit): + """Parse XML file and POST it to the Codacy API""" + + logging.info("Parsing report file...") + report = parse_report_file(report_file) + + logging.info("Uploading report...") + upload_report(report, token, commit) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Codacy coverage reporter for Python.') + parser.add_argument("-r", "--report", type=str, help="coverage report file", default=DEFAULT_REPORT_FILE) + parser.add_argument("-c", "--commit", type=str, help="coverage report file") + parser.add_argument("-v", "--verbose", help="coverage report file", action="store_true") + + args = parser.parse_args() + + if args.verbose: + logging.setLevel(logging.DEBUG) + + if not CODACY_PROJECT_TOKEN: + logging.error("environment variable CODACY_PROJECT_TOKEN is not defined.") + exit(1) + + if not args.commit: + args.commit = get_git_revision_hash() + + main(args.report, CODACY_PROJECT_TOKEN, args.commit) diff --git a/codacycov.py b/codacycov.py deleted file mode 100644 index f10facf..0000000 --- a/codacycov.py +++ /dev/null @@ -1,55 +0,0 @@ -"""Submit Python coverage report to Codacy.""" - -import sys -from xml.dom import minidom - -import requests - - -XML_DOC = 'coverage.xml' -URL = 'https://www.codacy.com/api/coverage/{token}/{commit}' - - -def main(token, commit, xml_file=XML_DOC): - """Parse XML file and POST it to the Codacy API""" - - # Convert decimal string to floored int percent value - percent = lambda s: int(float(s)*100) - - # Parse the XML into the format expected by the API - xmldoc = minidom.parse(xml_file) - - data = { - 'total': percent(xmldoc.getElementsByTagName('coverage')[0].attributes['line-rate'].value), - 'fileReports': [], - } - - classes = xmldoc.getElementsByTagName('class') - for cls in classes: - file_report = { - 'filename': cls.attributes['filename'].value, - 'total': percent(cls.attributes['line-rate'].value), - 'coverage': {}, - } - lines = cls.getElementsByTagName('line') - for line in lines: - hits = int(line.attributes['hits'].value) - if hits >= 1: - # The API assumes 0 if a line is missing - file_report['coverage'][line.attributes['number'].value] = hits - data['fileReports'] += [file_report] - - # Try to send the data, raise an exception if we fail - r = requests.post(URL.format(token=token, commit=commit), data=data) - r.raise_for_status() - - -if __name__ == '__main__': - argc = len(sys.argv) - if argc < 3: - print("usage: codacycov.py TOKEN COMMIT [COVERAGE_XML]") - print("if COVERAGE_XML is not specified, default is coverage.xml") - elif argc < 4: - main(sys.argv[1], sys.argv[2]) - else: - main(sys.argv[1], sys.argv[2], sys.argv[3]) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index f229360..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..c34b498 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[bdist_wheel] +# This flag says that the code is written to work on both Python 2 and Python +# 3. If at all possible, it is good practice to do this. If you cannot, you +# will need to generate wheels for each Python version that you support. +universal=1 \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..9dd3393 --- /dev/null +++ b/setup.py @@ -0,0 +1,57 @@ +# Always prefer setuptools over distutils +from setuptools import setup, find_packages +# To use a consistent encoding +from codecs import open +from os import path + +here = path.abspath(path.dirname(__file__)) + +# Get the long description from the relevant file +with open(path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f: + long_description = f.read() + +setup( + name='python-codacy-coverage', + + version='1.0.0', + + description='Codacy coverage reporter for Python', + long_description=long_description, + + url='https://github.com/codacy/python-codacy-coverage', + + author='Codacy', + author_email='team@codacy.com', + + license='MIT', + + # See https://pypi.python.org/pypi?%3Aaction=list_classifiers + classifiers=[ + 'Development Status :: 5 - Production/Stable', + + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Build Tools', + + 'License :: OSI Approved :: MIT License', + + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + ], + + keywords='development coverage', + + packages=find_packages(exclude=['contrib', 'docs', 'tests*']), + + install_requires=['requests'], + + extras_require={ + 'dev': ['check-manifest'], + 'test': ['coverage'], + }, + + entry_points={ + 'console_scripts': [ + 'sample=main', + ], + }, +) From a4844e6fe12faeb4eeb84d3ad0e2c1cb8d8d8332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Sun, 6 Sep 2015 14:47:00 +0100 Subject: [PATCH 02/33] update README --- README.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c329098..30edc3d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # python-coverage-coverage [![Build Status](https://circleci.com/gh/codacy/python-codacy-coverage.png?style=shield&circle-token=:circle-token)](https://circleci.com/gh/codacy/python-codacy-coverage) -[![Codacy Badge](https://www.codacy.com/project/badge/1c524e61cd8640e79b80d406eda8754b)](https://www.codacy.com/app/Codacy/python-codacy-coverage-) +[![Codacy Badge](https://www.codacy.com/project/badge/3a8cf06a9db94d0ab3d55e0357bc8f9d)](https://www.codacy.com/app/Codacy/python-codacy-coverage) Python coverage reporter for Codacy https://www.codacy.com @@ -10,14 +10,9 @@ Codacy assumes that coverage is previously configured for your project. You can install the coverage reporter by running: -### [Install jpm](https://www.jpm4j.org/#!/md/install) +### Install python-codacy-coverage ``` -curl http://www.jpm4j.org/install/script | sh -``` - -### Install codacy-coverage-reporter -``` -jpm install com.codacy:codacy-coverage-reporter +pip install python-codacy-coverage ``` ## Updating Codacy From a3c09f8ce1cd96ba96a522e8707b7f35579eaa8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Sun, 6 Sep 2015 15:11:14 +0100 Subject: [PATCH 03/33] fix entrypoint --- DESCRIPTION.rst | 13 ------------- README.md | 5 +++-- setup.py | 7 ++++--- src/codacy/__init__.py | 5 +++++ __init__.py => src/codacy/reporter.py | 5 ++--- 5 files changed, 14 insertions(+), 21 deletions(-) delete mode 100644 DESCRIPTION.rst create mode 100644 src/codacy/__init__.py rename __init__.py => src/codacy/reporter.py (96%) diff --git a/DESCRIPTION.rst b/DESCRIPTION.rst deleted file mode 100644 index 68b3a57..0000000 --- a/DESCRIPTION.rst +++ /dev/null @@ -1,13 +0,0 @@ -A sample Python project -======================= - -This is the description file for the project. - -The file should use UTF-8 encoding and be written using ReStructured Text. It -will be used to generate the project webpage on PyPI, and should be written for -that purpose. - -Typical contents for this file would include an overview of the project, basic -usage examples, etc. Generally, including the project changelog in here is not -a good idea, although a simple "What's New" section for the most recent version -may be appropriate. diff --git a/README.md b/README.md index 30edc3d..e09486f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # python-coverage-coverage + +Credits to Ryan for creating this! Python coverage reporter for Codacy https://www.codacy.com + [![Build Status](https://circleci.com/gh/codacy/python-codacy-coverage.png?style=shield&circle-token=:circle-token)](https://circleci.com/gh/codacy/python-codacy-coverage) [![Codacy Badge](https://www.codacy.com/project/badge/3a8cf06a9db94d0ab3d55e0357bc8f9d)](https://www.codacy.com/app/Codacy/python-codacy-coverage) -Python coverage reporter for Codacy https://www.codacy.com - ## Setup Codacy assumes that coverage is previously configured for your project. diff --git a/setup.py b/setup.py index 9dd3393..98e2f1a 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ here = path.abspath(path.dirname(__file__)) # Get the long description from the relevant file -with open(path.join(here, 'DESCRIPTION.rst'), encoding='utf-8') as f: +with open(path.join(here, 'README.md'), encoding='utf-8') as f: long_description = f.read() setup( @@ -40,7 +40,8 @@ keywords='development coverage', - packages=find_packages(exclude=['contrib', 'docs', 'tests*']), + packages=find_packages('src'), + package_dir={'': 'src'}, include_package_data=True, install_requires=['requests'], @@ -51,7 +52,7 @@ entry_points={ 'console_scripts': [ - 'sample=main', + 'python-codacy-coverage=codacy:main', ], }, ) diff --git a/src/codacy/__init__.py b/src/codacy/__init__.py new file mode 100644 index 0000000..acf3dc3 --- /dev/null +++ b/src/codacy/__init__.py @@ -0,0 +1,5 @@ +import reporter + + +def main(): + return reporter.run() diff --git a/__init__.py b/src/codacy/reporter.py similarity index 96% rename from __init__.py rename to src/codacy/reporter.py index 3867d8e..a3741af 100755 --- a/__init__.py +++ b/src/codacy/reporter.py @@ -68,7 +68,6 @@ def upload_report(report, token, commit): r = requests.post(url, data=data, headers=headers, allow_redirects=True) logging.debug(r.content) - logging.debug(r.status_code) r.raise_for_status() message = json.loads(r.content)['success'] @@ -85,7 +84,7 @@ def main(report_file, token, commit): upload_report(report, token, commit) -if __name__ == '__main__': +def run(): parser = argparse.ArgumentParser(description='Codacy coverage reporter for Python.') parser.add_argument("-r", "--report", type=str, help="coverage report file", default=DEFAULT_REPORT_FILE) parser.add_argument("-c", "--commit", type=str, help="coverage report file") @@ -94,7 +93,7 @@ def main(report_file, token, commit): args = parser.parse_args() if args.verbose: - logging.setLevel(logging.DEBUG) + logging.Logger.setLevel(logging.getLogger(), logging.DEBUG) if not CODACY_PROJECT_TOKEN: logging.error("environment variable CODACY_PROJECT_TOKEN is not defined.") From b8fbf7715c2c6eff4d3278a6c556fdf91cc785a0 Mon Sep 17 00:00:00 2001 From: rshipp Date: Sun, 6 Sep 2015 10:43:49 -0600 Subject: [PATCH 04/33] Rename package to codacy-coverage --- README.md | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e09486f..96fc223 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ You can install the coverage reporter by running: ### Install python-codacy-coverage ``` -pip install python-codacy-coverage +pip install codacy-coverage ``` ## Updating Codacy diff --git a/setup.py b/setup.py index 98e2f1a..7412de0 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ long_description = f.read() setup( - name='python-codacy-coverage', + name='codacy-coverage', version='1.0.0', From efec83d25003418db6dab4bc161511398b06d0af Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 17:22:58 -0600 Subject: [PATCH 05/33] Correct README usage example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 96fc223..36439f2 100644 --- a/README.md +++ b/README.md @@ -29,5 +29,5 @@ export CODACY_PROJECT_TOKEN=%Project_Token% Next, simply run the Codacy reporter. It will find the current commit and send all details to your project dashboard: ``` -python-codacy-coverage -f coverage.xml +python-codacy-coverage -r coverage.xml ``` From 3e36bbc6455718d418e927b2405cab44fc556836 Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 17:24:27 -0600 Subject: [PATCH 06/33] Use docstrings where appropriate --- src/codacy/reporter.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index a3741af..75b3dc6 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -24,6 +24,8 @@ def get_git_revision_hash(): def parse_report_file(report_file): + """Parse XML file and POST it to the Codacy API""" + # Convert decimal string to floored int percent value percent = lambda s: int(float(s) * 100) @@ -55,7 +57,7 @@ def parse_report_file(report_file): def upload_report(report, token, commit): - # Try to send the data, raise an exception if we fail + """Try to send the data, raise an exception if we fail""" url = URL.format(commit=commit) data = json.dumps(report) headers = { From 9007a5f7c29a1108c7930e0e32d188eb28bcd7ac Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 17:24:56 -0600 Subject: [PATCH 07/33] Correct argparse help strings --- src/codacy/reporter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index 75b3dc6..5280e34 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -89,8 +89,8 @@ def main(report_file, token, commit): def run(): parser = argparse.ArgumentParser(description='Codacy coverage reporter for Python.') parser.add_argument("-r", "--report", type=str, help="coverage report file", default=DEFAULT_REPORT_FILE) - parser.add_argument("-c", "--commit", type=str, help="coverage report file") - parser.add_argument("-v", "--verbose", help="coverage report file", action="store_true") + parser.add_argument("-c", "--commit", type=str, help="git commit hash") + parser.add_argument("-v", "--verbose", help="show debug information", action="store_true") args = parser.parse_args() From 97f572f111898a1e23aa38dca3215379a8310885 Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 17:25:20 -0600 Subject: [PATCH 08/33] Refactor out reporter.main function --- src/codacy/reporter.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index 5280e34..5ca8469 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -76,16 +76,6 @@ def upload_report(report, token, commit): logging.info(message) -def main(report_file, token, commit): - """Parse XML file and POST it to the Codacy API""" - - logging.info("Parsing report file...") - report = parse_report_file(report_file) - - logging.info("Uploading report...") - upload_report(report, token, commit) - - def run(): parser = argparse.ArgumentParser(description='Codacy coverage reporter for Python.') parser.add_argument("-r", "--report", type=str, help="coverage report file", default=DEFAULT_REPORT_FILE) @@ -104,4 +94,8 @@ def run(): if not args.commit: args.commit = get_git_revision_hash() - main(args.report, CODACY_PROJECT_TOKEN, args.commit) + logging.info("Parsing report file...") + report = parse_report_file(args.report) + + logging.info("Uploading report...") + upload_report(report, CODACY_PROJECT_TOKEN, args.commit) From 6069cec91db665c78eb170470f8672efd2bb0a79 Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 17:28:34 -0600 Subject: [PATCH 09/33] Add instructions for generating coverage.xml to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 36439f2..6aebcad 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ Credits to Ryan for creating this! Python coverage reporter for Codacy https://w Codacy assumes that coverage is previously configured for your project. +To generate the required coverage XML file, calculate coverage for your project as normal, then run + +``` +coverage xml +``` + You can install the coverage reporter by running: ### Install python-codacy-coverage From 085df54093dd6db32aa5869cdc431b6e79a044c3 Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 17:44:54 -0600 Subject: [PATCH 10/33] Modify README, convert to RST RST renders properly on PyPi. --- README.md => README.rst | 37 +++++++++++++++++++------------------ setup.py | 2 +- 2 files changed, 20 insertions(+), 19 deletions(-) rename README.md => README.rst (50%) diff --git a/README.md b/README.rst similarity index 50% rename from README.md rename to README.rst index 6aebcad..a925ae5 100644 --- a/README.md +++ b/README.rst @@ -1,39 +1,40 @@ -# python-coverage-coverage +python-coverage-coverage +======================== Credits to Ryan for creating this! Python coverage reporter for Codacy https://www.codacy.com -[![Build Status](https://circleci.com/gh/codacy/python-codacy-coverage.png?style=shield&circle-token=:circle-token)](https://circleci.com/gh/codacy/python-codacy-coverage) -[![Codacy Badge](https://www.codacy.com/project/badge/3a8cf06a9db94d0ab3d55e0357bc8f9d)](https://www.codacy.com/app/Codacy/python-codacy-coverage) +.. image:: https://circleci.com/gh/codacy/python-codacy-coverage.png?style=shield&circle-token=:circle-token + :target: https://circleci.com/gh/codacy/python-codacy-coverage + :alt: Build Status +.. image:: https://www.codacy.com/project/badge/3a8cf06a9db94d0ab3d55e0357bc8f9d + :target: https://www.codacy.com/app/Codacy/python-codacy-coverage + :alt: Codacy Badge -## Setup +Setup +----- Codacy assumes that coverage is previously configured for your project. To generate the required coverage XML file, calculate coverage for your project as normal, then run -``` -coverage xml -``` +``coverage xml``` + +Install codacy-coverage +~~~~~~~~~~~~~~~~~~~~~~~ You can install the coverage reporter by running: -### Install python-codacy-coverage -``` -pip install codacy-coverage -``` +``pip install codacy-coverage`` -## Updating Codacy +Updating Codacy +--------------- To update Codacy, you will need your project API token. You can find the token in Project -> Settings -> Integrations -> Project API. Then set it in your terminal, replacing %Project_Token% with your own token: -``` -export CODACY_PROJECT_TOKEN=%Project_Token% -``` +``export CODACY_PROJECT_TOKEN=%Project_Token%`` Next, simply run the Codacy reporter. It will find the current commit and send all details to your project dashboard: -``` -python-codacy-coverage -r coverage.xml -``` +``python-codacy-coverage -r coverage.xml`` diff --git a/setup.py b/setup.py index 7412de0..1e4f22f 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ here = path.abspath(path.dirname(__file__)) # Get the long description from the relevant file -with open(path.join(here, 'README.md'), encoding='utf-8') as f: +with open(path.join(here, 'README.rst'), encoding='utf-8') as f: long_description = f.read() setup( From 0e479e04c729cc36a41b0574e1aabe8beab05c4d Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 17:46:06 -0600 Subject: [PATCH 11/33] Fix typo in README --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index a925ae5..36c0932 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -python-coverage-coverage -======================== +python-codacy-coverage +====================== Credits to Ryan for creating this! Python coverage reporter for Codacy https://www.codacy.com From 9b2b2d5e75eecd8d05bee393b40a6884a5b05eb9 Mon Sep 17 00:00:00 2001 From: rshipp Date: Tue, 8 Sep 2015 18:03:41 -0600 Subject: [PATCH 12/33] Fix small typo in README --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 36c0932..b499b51 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ Codacy assumes that coverage is previously configured for your project. To generate the required coverage XML file, calculate coverage for your project as normal, then run -``coverage xml``` +``coverage xml`` Install codacy-coverage ~~~~~~~~~~~~~~~~~~~~~~~ From 658c96da0f650d1335349b2e6de12cd35e5e7e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 9 Sep 2015 10:57:21 +0100 Subject: [PATCH 13/33] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index b499b51..34a53b1 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ Setup Codacy assumes that coverage is previously configured for your project. -To generate the required coverage XML file, calculate coverage for your project as normal, then run +To generate the required coverage XML file, calculate coverage for your project as normal, by running: ``coverage xml`` From e0d7094081689dea2a456378f9b01465d0379b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 9 Sep 2015 12:19:43 +0100 Subject: [PATCH 14/33] some minor improvements --- Makefile | 21 +++++++++++++++++++++ setup.cfg | 5 ++++- setup.py | 2 +- src/codacy/reporter.py | 7 ++++++- 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8d14a2d --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +all: build test install + +build: + python setup.py build + +install: build + python setup.py develop + +test: pep8 pyflakes + +# requires "pip install pep8" +pep8: + @git ls-files | grep \\.py$ | xargs pep8 + +# requires "pip install pyflakes" +pyflakes: + @export PYFLAKES_NODOCTEST=1 && \ + git ls-files | grep \\.py$ | xargs pyflakes + +upload: + python setup.py sdist bdist_wheel upload diff --git a/setup.cfg b/setup.cfg index c34b498..9b303f5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,4 +2,7 @@ # This flag says that the code is written to work on both Python 2 and Python # 3. If at all possible, it is good practice to do this. If you cannot, you # will need to generate wheels for each Python version that you support. -universal=1 \ No newline at end of file +universal=1 + +[pep8] +max_line_length = 120 diff --git a/setup.py b/setup.py index 1e4f22f..5f84b20 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name='codacy-coverage', - version='1.0.0', + version='1.0.1', description='Codacy coverage reporter for Python', long_description=long_description, diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index 5ca8469..1ac917a 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -27,7 +27,8 @@ def parse_report_file(report_file): """Parse XML file and POST it to the Codacy API""" # Convert decimal string to floored int percent value - percent = lambda s: int(float(s) * 100) + def percent(s): + float(s) * 100 # Parse the XML into the format expected by the API report_xml = minidom.parse(report_file) @@ -94,6 +95,10 @@ def run(): if not args.commit: args.commit = get_git_revision_hash() + if not os.path.isfile(args.report): + logging.error("Coverage report " + args.report + " not found.") + exit(1) + logging.info("Parsing report file...") report = parse_report_file(args.report) From c84be7acb36110724b665247e33283f375254d19 Mon Sep 17 00:00:00 2001 From: Nick Mohoric Date: Wed, 30 Sep 2015 13:13:43 -0400 Subject: [PATCH 15/33] Returning computed value from percent --- src/codacy/reporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index 1ac917a..d1956df 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -28,7 +28,7 @@ def parse_report_file(report_file): # Convert decimal string to floored int percent value def percent(s): - float(s) * 100 + return float(s) * 100 # Parse the XML into the format expected by the API report_xml = minidom.parse(report_file) From c10612e5d4a3ad3d19e7b419644b45794fd2bb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 30 Sep 2015 19:03:40 +0100 Subject: [PATCH 16/33] Test generated json report --- Makefile | 1 + setup.py | 3 ++- tests.py | 19 +++++++++++++++++++ tests/cobertura.xml | 31 +++++++++++++++++++++++++++++++ tests/coverage.json | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests.py create mode 100644 tests/cobertura.xml create mode 100644 tests/coverage.json diff --git a/Makefile b/Makefile index 8d14a2d..7fc4494 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ install: build python setup.py develop test: pep8 pyflakes + python setup.py test # requires "pip install pep8" pep8: diff --git a/setup.py b/setup.py index 5f84b20..e109d4b 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ extras_require={ 'dev': ['check-manifest'], - 'test': ['coverage'], + 'test': ['nosetests', 'coverage'], }, entry_points={ @@ -55,4 +55,5 @@ 'python-codacy-coverage=codacy:main', ], }, + test_suite='tests' ) diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..ec3e153 --- /dev/null +++ b/tests.py @@ -0,0 +1,19 @@ +import unittest +import codacy.reporter +import json + +class ReporterTests(unittest.TestCase): + + def test_parser(self): + def file_get_contents(filename): + with open(filename) as f: + return f.read() + + jsonContent = file_get_contents('tests/coverage.json') + expected = json.loads(jsonContent) + + generated = codacy.reporter.parse_report_file('tests/cobertura.xml') + self.assertEqual(generated, expected) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/cobertura.xml b/tests/cobertura.xml new file mode 100644 index 0000000..015adc2 --- /dev/null +++ b/tests/cobertura.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/coverage.json b/tests/coverage.json new file mode 100644 index 0000000..606f92f --- /dev/null +++ b/tests/coverage.json @@ -0,0 +1,32 @@ +{ + "total":87, + "fileReports":[ + { + "total":87, + "coverage":{ + "5":1, + "4":1, + "6":2 + }, + "filename":"src/test/resources/TestSourceFile.scala" + }, + { + "total":87, + "coverage":{ + "9":1, + "10":1 + }, + "filename":"src/test/resources/TestSourceFile.scala" + }, + { + "total":87, + "coverage":{ + "1":1, + "3":1, + "2":1 + }, + "filename":"src/test/resources/TestSourceFile2.scala" + } + ], + "language":"python" +} From 302aa9e75e2b61ae423be409202e0ed2aa48d5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 30 Sep 2015 19:09:24 +0100 Subject: [PATCH 17/33] Release 1.1.0 --- setup.py | 2 +- tests.py | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index e109d4b..84a4178 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ setup( name='codacy-coverage', - version='1.0.1', + version='1.1.0', description='Codacy coverage reporter for Python', long_description=long_description, diff --git a/tests.py b/tests.py index ec3e153..390f5e1 100644 --- a/tests.py +++ b/tests.py @@ -2,18 +2,19 @@ import codacy.reporter import json + class ReporterTests(unittest.TestCase): - def test_parser(self): - def file_get_contents(filename): - with open(filename) as f: - return f.read() + def test_parser(self): + def file_get_contents(filename): + with open(filename) as f: + return f.read() - jsonContent = file_get_contents('tests/coverage.json') - expected = json.loads(jsonContent) + jsonContent = file_get_contents('tests/coverage.json') + expected = json.loads(jsonContent) - generated = codacy.reporter.parse_report_file('tests/cobertura.xml') - self.assertEqual(generated, expected) + generated = codacy.reporter.parse_report_file('tests/cobertura.xml') + self.assertEqual(generated, expected) if __name__ == '__main__': unittest.main() From 7a1be374d4a635ae9b8fc2c726235088f508e9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Tue, 3 Nov 2015 11:44:35 +0000 Subject: [PATCH 18/33] Add support fo coverage 4 and relative git file paths --- Makefile | 6 ++ src/codacy/reporter.py | 40 ++++++++++++- tests.py | 26 +++++++-- tests/coverage.json | 32 ----------- tests/{ => coverage3}/cobertura.xml | 0 tests/coverage3/coverage.json | 32 +++++++++++ tests/coverage4/cobertura.xml | 86 ++++++++++++++++++++++++++++ tests/coverage4/coverage.json | 49 ++++++++++++++++ tests/filepath/cobertura.xml | 87 +++++++++++++++++++++++++++++ tests/filepath/coverage.json | 49 ++++++++++++++++ 10 files changed, 367 insertions(+), 40 deletions(-) delete mode 100644 tests/coverage.json rename tests/{ => coverage3}/cobertura.xml (100%) create mode 100644 tests/coverage3/coverage.json create mode 100644 tests/coverage4/cobertura.xml create mode 100644 tests/coverage4/coverage.json create mode 100644 tests/filepath/cobertura.xml create mode 100644 tests/filepath/coverage.json diff --git a/Makefile b/Makefile index 7fc4494..7ee3d18 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,12 @@ install: build test: pep8 pyflakes python setup.py test +coverage: + rm coverage.xml + coverage run --source src/codacy/ setup.py test + coverage xml + python-codacy-coverage -r coverage.xml + # requires "pip install pep8" pep8: @git ls-files | grep \\.py$ | xargs pep8 diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index d1956df..369ce59 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -5,7 +5,6 @@ import logging import os from xml.dom import minidom - import requests logging.basicConfig(level=logging.INFO, @@ -23,8 +22,42 @@ def get_git_revision_hash(): return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip() +def get_git_directory(): + import subprocess + + return subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).strip() + + +def file_exists(rootdir, filename): + for root, subFolders, files in os.walk(rootdir): + if filename in files: + return True + else: + for subFolder in subFolders: + return file_exists(subFolder, filename) + return False + + +def generate_filename(sources, filename): + def strip_prefix(line, prefix): + if line.startswith(prefix): + return line[len(prefix):] + else: + return line + + git_directory = get_git_directory() + + for source in sources: + if file_exists(source, filename): + return strip_prefix(source, git_directory).strip("/") + "/" + filename.strip("/") + + return filename + + def parse_report_file(report_file): - """Parse XML file and POST it to the Codacy API""" + """Parse XML file and POST it to the Codacy API + :param report_file: + """ # Convert decimal string to floored int percent value def percent(s): @@ -39,10 +72,11 @@ def percent(s): 'fileReports': [], } + sources = map(lambda x: x.firstChild.nodeValue, report_xml.getElementsByTagName('source')) classes = report_xml.getElementsByTagName('class') for cls in classes: file_report = { - 'filename': cls.attributes['filename'].value, + 'filename': generate_filename(sources, cls.attributes['filename'].value), 'total': percent(cls.attributes['line-rate'].value), 'coverage': {}, } diff --git a/tests.py b/tests.py index 390f5e1..a1f14c7 100644 --- a/tests.py +++ b/tests.py @@ -4,17 +4,33 @@ class ReporterTests(unittest.TestCase): - - def test_parser(self): + def compare_parse_result(self, generated_filename, expected_filename): def file_get_contents(filename): with open(filename) as f: return f.read() - jsonContent = file_get_contents('tests/coverage.json') - expected = json.loads(jsonContent) + generated = codacy.reporter.parse_report_file(generated_filename) + + json_content = file_get_contents(expected_filename) + expected = json.loads(json_content) - generated = codacy.reporter.parse_report_file('tests/cobertura.xml') self.assertEqual(generated, expected) + def test_parser_coverage3(self): + self.maxDiff = None + + self.compare_parse_result('tests/coverage3/cobertura.xml', 'tests/coverage3/coverage.json') + + def test_parser_coverage4(self): + self.maxDiff = None + + self.compare_parse_result('tests/coverage4/cobertura.xml', 'tests/coverage4/coverage.json') + + def test_parser_git_filepath(self): + self.maxDiff = None + + self.compare_parse_result('tests/filepath/cobertura.xml', 'tests/filepath/coverage.json') + + if __name__ == '__main__': unittest.main() diff --git a/tests/coverage.json b/tests/coverage.json deleted file mode 100644 index 606f92f..0000000 --- a/tests/coverage.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "total":87, - "fileReports":[ - { - "total":87, - "coverage":{ - "5":1, - "4":1, - "6":2 - }, - "filename":"src/test/resources/TestSourceFile.scala" - }, - { - "total":87, - "coverage":{ - "9":1, - "10":1 - }, - "filename":"src/test/resources/TestSourceFile.scala" - }, - { - "total":87, - "coverage":{ - "1":1, - "3":1, - "2":1 - }, - "filename":"src/test/resources/TestSourceFile2.scala" - } - ], - "language":"python" -} diff --git a/tests/cobertura.xml b/tests/coverage3/cobertura.xml similarity index 100% rename from tests/cobertura.xml rename to tests/coverage3/cobertura.xml diff --git a/tests/coverage3/coverage.json b/tests/coverage3/coverage.json new file mode 100644 index 0000000..b94ec68 --- /dev/null +++ b/tests/coverage3/coverage.json @@ -0,0 +1,32 @@ +{ + "total": 87, + "fileReports": [ + { + "total": 87, + "coverage": { + "5": 1, + "4": 1, + "6": 2 + }, + "filename": "src/test/resources/TestSourceFile.scala" + }, + { + "total": 87, + "coverage": { + "9": 1, + "10": 1 + }, + "filename": "src/test/resources/TestSourceFile.scala" + }, + { + "total": 87, + "coverage": { + "1": 1, + "3": 1, + "2": 1 + }, + "filename": "src/test/resources/TestSourceFile2.scala" + } + ], + "language": "python" +} diff --git a/tests/coverage4/cobertura.xml b/tests/coverage4/cobertura.xml new file mode 100644 index 0000000..0e71e5d --- /dev/null +++ b/tests/coverage4/cobertura.xml @@ -0,0 +1,86 @@ + + + + + + /Users/rafaelcortes/Documents/qamine/python-codacycov + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/coverage4/coverage.json b/tests/coverage4/coverage.json new file mode 100644 index 0000000..e0a780b --- /dev/null +++ b/tests/coverage4/coverage.json @@ -0,0 +1,49 @@ +{ + "total": 50.0, + "fileReports": [ + { + "total": 66.67, + "coverage": { + "1": 1, + "4": 1 + }, + "filename": "src/codacy/__init__.py" + }, + { + "total": 49.15, + "coverage": { + "50": 1, + "60": 1, + "80": 1, + "52": 1, + "26": 1, + "20": 1, + "49": 1, + "44": 1, + "42": 1, + "43": 1, + "3": 1, + "5": 1, + "4": 1, + "7": 1, + "6": 1, + "9": 1, + "11": 1, + "15": 1, + "14": 1, + "17": 1, + "16": 1, + "55": 1, + "54": 1, + "31": 1, + "30": 1, + "51": 1, + "36": 1, + "34": 1, + "57": 1 + }, + "filename": "src/codacy/reporter.py" + } + ], + "language": "python" +} \ No newline at end of file diff --git a/tests/filepath/cobertura.xml b/tests/filepath/cobertura.xml new file mode 100644 index 0000000..0aced17 --- /dev/null +++ b/tests/filepath/cobertura.xml @@ -0,0 +1,87 @@ + + + + + + /Users/rafaelcortes/Documents/qamine/python-codacy-coverage/src/codacy + /Users/rafaelcortes/Documents/qamine/python-codacycov/src/codacy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/filepath/coverage.json b/tests/filepath/coverage.json new file mode 100644 index 0000000..e0a780b --- /dev/null +++ b/tests/filepath/coverage.json @@ -0,0 +1,49 @@ +{ + "total": 50.0, + "fileReports": [ + { + "total": 66.67, + "coverage": { + "1": 1, + "4": 1 + }, + "filename": "src/codacy/__init__.py" + }, + { + "total": 49.15, + "coverage": { + "50": 1, + "60": 1, + "80": 1, + "52": 1, + "26": 1, + "20": 1, + "49": 1, + "44": 1, + "42": 1, + "43": 1, + "3": 1, + "5": 1, + "4": 1, + "7": 1, + "6": 1, + "9": 1, + "11": 1, + "15": 1, + "14": 1, + "17": 1, + "16": 1, + "55": 1, + "54": 1, + "31": 1, + "30": 1, + "51": 1, + "36": 1, + "34": 1, + "57": 1 + }, + "filename": "src/codacy/reporter.py" + } + ], + "language": "python" +} \ No newline at end of file From ccb5910b0ae2c6ecbff641e78e23a613bb690090 Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Tue, 3 Nov 2015 14:11:56 +0000 Subject: [PATCH 19/33] Add badges to readme --- README.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 34a53b1..823da47 100644 --- a/README.rst +++ b/README.rst @@ -3,12 +3,10 @@ python-codacy-coverage Credits to Ryan for creating this! Python coverage reporter for Codacy https://www.codacy.com -.. image:: https://circleci.com/gh/codacy/python-codacy-coverage.png?style=shield&circle-token=:circle-token - :target: https://circleci.com/gh/codacy/python-codacy-coverage - :alt: Build Status -.. image:: https://www.codacy.com/project/badge/3a8cf06a9db94d0ab3d55e0357bc8f9d - :target: https://www.codacy.com/app/Codacy/python-codacy-coverage - :alt: Codacy Badge +[![Codacy Badge](https://api.codacy.com/project/badge/grade/3a8cf06a9db94d0ab3d55e0357bc8f9d)](https://www.codacy.com/app/Codacy/python-codacy-coverage) +[![Codacy Badge](https://api.codacy.com/project/badge/coverage/3a8cf06a9db94d0ab3d55e0357bc8f9d)](https://www.codacy.com/app/Codacy/python-codacy-coverage) +[![Circle CI](https://circleci.com/gh/codacy/python-codacy-coverage.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/codacy/python-codacy-coverage) +[![PyPI version](https://badge.fury.io/py/codacy-coverage.svg)](https://badge.fury.io/py/codacy-coverage) Setup ----- From 2b08859d10bed1c18a82441b52f2ca41c698f9a3 Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Tue, 3 Nov 2015 14:28:35 +0000 Subject: [PATCH 20/33] Fix badges --- README.rst | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 823da47..fd88aa1 100644 --- a/README.rst +++ b/README.rst @@ -3,11 +3,19 @@ python-codacy-coverage Credits to Ryan for creating this! Python coverage reporter for Codacy https://www.codacy.com -[![Codacy Badge](https://api.codacy.com/project/badge/grade/3a8cf06a9db94d0ab3d55e0357bc8f9d)](https://www.codacy.com/app/Codacy/python-codacy-coverage) -[![Codacy Badge](https://api.codacy.com/project/badge/coverage/3a8cf06a9db94d0ab3d55e0357bc8f9d)](https://www.codacy.com/app/Codacy/python-codacy-coverage) -[![Circle CI](https://circleci.com/gh/codacy/python-codacy-coverage.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/codacy/python-codacy-coverage) -[![PyPI version](https://badge.fury.io/py/codacy-coverage.svg)](https://badge.fury.io/py/codacy-coverage) - +.. image:: https://api.codacy.com/project/badge/grade/3a8cf06a9db94d0ab3d55e0357bc8f9d + :target: https://www.codacy.com/app/Codacy/python-codacy-coverage + :alt: Codacy Badge +.. image:: https://api.codacy.com/project/badge/coverage/3a8cf06a9db94d0ab3d55e0357bc8f9d + :target: https://www.codacy.com/app/Codacy/python-codacy-coverage + :alt: Codacy Badge +.. image:: https://circleci.com/gh/codacy/python-codacy-coverage.png?style=shield&circle-token=:circle-token + :target: https://circleci.com/gh/codacy/python-codacy-coverage + :alt: Build Status +.. image:: https://badge.fury.io/py/codacy-coverage.svg + :target: https://badge.fury.io/py/codacy-coverage + :alt: PyPI version + Setup ----- From 4c4ce23eb9087e1fe4a178e7152928ead27cee79 Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Tue, 3 Nov 2015 15:06:13 +0000 Subject: [PATCH 21/33] Add circle.yml to add coverage --- circle.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 circle.yml diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..acb4dd0 --- /dev/null +++ b/circle.yml @@ -0,0 +1,5 @@ +test: + override: + - make test + - make install + - make coverage \ No newline at end of file From cdc38445b65d94a069a2b59f7be1a413a5eba299 Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Tue, 3 Nov 2015 15:40:14 +0000 Subject: [PATCH 22/33] Fix circle.yml (pep8 version) --- Makefile | 2 +- circle.yml | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7ee3d18..6ad4cdf 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ test: pep8 pyflakes python setup.py test coverage: - rm coverage.xml + rm coverage.xml || true coverage run --source src/codacy/ setup.py test coverage xml python-codacy-coverage -r coverage.xml diff --git a/circle.yml b/circle.yml index acb4dd0..f47e9c4 100644 --- a/circle.yml +++ b/circle.yml @@ -1,3 +1,14 @@ +machine: + python: + version: + - 2.7.10 + - 3.4.3 + +dependencies: + post: + - sudo pip install pep8 --upgrade + - sudo pip install pyflakes + test: override: - make test From 1496f41ea49e570f97a2fb228a3398cd2a2994b9 Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Tue, 3 Nov 2015 15:42:41 +0000 Subject: [PATCH 23/33] Fix python version --- circle.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/circle.yml b/circle.yml index f47e9c4..1d8d8cf 100644 --- a/circle.yml +++ b/circle.yml @@ -1,8 +1,6 @@ machine: python: - version: - - 2.7.10 - - 3.4.3 + version: 3.4.3 dependencies: post: From 4234788e8d9ea2029f90bb6c173a336364b93399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Tue, 3 Nov 2015 16:13:18 +0000 Subject: [PATCH 24/33] Update file paths tests --- Makefile | 4 +++- tests/filepath/{cobertura.xml => cobertura.xml.tpl} | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) rename tests/filepath/{cobertura.xml => cobertura.xml.tpl} (95%) diff --git a/Makefile b/Makefile index 7ee3d18..8651703 100644 --- a/Makefile +++ b/Makefile @@ -7,10 +7,12 @@ install: build python setup.py develop test: pep8 pyflakes + sed 's?\$$1?'`pwd`'?' tests/filepath/cobertura.xml.tpl > tests/filepath/cobertura.xml python setup.py test + rm tests/filepath/cobertura.xml || true coverage: - rm coverage.xml + rm coverage.xml || true coverage run --source src/codacy/ setup.py test coverage xml python-codacy-coverage -r coverage.xml diff --git a/tests/filepath/cobertura.xml b/tests/filepath/cobertura.xml.tpl similarity index 95% rename from tests/filepath/cobertura.xml rename to tests/filepath/cobertura.xml.tpl index 0aced17..895abb8 100644 --- a/tests/filepath/cobertura.xml +++ b/tests/filepath/cobertura.xml.tpl @@ -3,8 +3,8 @@ - /Users/rafaelcortes/Documents/qamine/python-codacy-coverage/src/codacy - /Users/rafaelcortes/Documents/qamine/python-codacycov/src/codacy + $1/src/codacy + $1/src/codacy From 76ba257bc8b263bb963d8700c2f2043d3deb4393 Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Tue, 3 Nov 2015 16:36:40 +0000 Subject: [PATCH 25/33] Fix tests --- Makefile | 2 ++ circle.yml | 1 + 2 files changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 8651703..46ba071 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,9 @@ test: pep8 pyflakes coverage: rm coverage.xml || true + sed 's?\$$1?'`pwd`'?' tests/filepath/cobertura.xml.tpl > tests/filepath/cobertura.xml coverage run --source src/codacy/ setup.py test + rm tests/filepath/cobertura.xml || true coverage xml python-codacy-coverage -r coverage.xml diff --git a/circle.yml b/circle.yml index 1d8d8cf..ca7d482 100644 --- a/circle.yml +++ b/circle.yml @@ -6,6 +6,7 @@ dependencies: post: - sudo pip install pep8 --upgrade - sudo pip install pyflakes + - sudo pip install coverage test: override: From e7d828762b08ef6c0d1d91a8281f34bb24a3a01b Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Tue, 3 Nov 2015 17:50:27 +0000 Subject: [PATCH 26/33] Change to python 2.7.10 (CircleCI) --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index ca7d482..4019a7f 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: python: - version: 3.4.3 + version: 2.7.10 dependencies: post: From db580b9dde1545acd568cbf1c67df23321bf3004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 4 Nov 2015 18:05:30 +0000 Subject: [PATCH 27/33] Change API endpoint environment variable Change API endpoint environment variable to CODACY_API_BASE_URL --- src/codacy/reporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index d1956df..86bd1c3 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -12,7 +12,7 @@ format='%(asctime)s - %(levelname)s - %(message)s') CODACY_PROJECT_TOKEN = os.getenv('CODACY_PROJECT_TOKEN') -CODACY_BASE_API_URL = os.getenv('CODACY_BASE_API_URL', 'https://api.codacy.com') +CODACY_BASE_API_URL = os.getenv('CODACY_API_BASE_URL', 'https://api.codacy.com') URL = CODACY_BASE_API_URL + '/2.0/coverage/{commit}/python' DEFAULT_REPORT_FILE = 'coverage.xml' From 0b35b1e04bd8ae07ec0d2217c4394f0eb9248b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 4 Nov 2015 20:49:45 +0000 Subject: [PATCH 28/33] Rewrite as Python 3 compatible --- setup.py | 2 +- src/codacy/__init__.py | 3 ++- src/codacy/reporter.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 84a4178..dcdfc24 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', ], diff --git a/src/codacy/__init__.py b/src/codacy/__init__.py index acf3dc3..6068f5c 100644 --- a/src/codacy/__init__.py +++ b/src/codacy/__init__.py @@ -1,4 +1,5 @@ -import reporter +from __future__ import absolute_import +from . import reporter def main(): diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index 369ce59..5d1302c 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -72,7 +72,7 @@ def percent(s): 'fileReports': [], } - sources = map(lambda x: x.firstChild.nodeValue, report_xml.getElementsByTagName('source')) + sources = [x.firstChild.nodeValue for x in report_xml.getElementsByTagName('source')] classes = report_xml.getElementsByTagName('class') for cls in classes: file_report = { From 184475fb6033559ab559429eb8a5d6d0b75fe2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 4 Nov 2015 23:08:36 +0000 Subject: [PATCH 29/33] Run tests in 2.7 and 3.5 environment --- Makefile | 3 +++ circle.yml | 5 +++-- src/codacy/reporter.py | 4 ++-- tox.ini | 6 ++++++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 tox.ini diff --git a/Makefile b/Makefile index 46ba071..5ed5354 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,9 @@ test: pep8 pyflakes python setup.py test rm tests/filepath/cobertura.xml || true +test-all: + tox + coverage: rm coverage.xml || true sed 's?\$$1?'`pwd`'?' tests/filepath/cobertura.xml.tpl > tests/filepath/cobertura.xml diff --git a/circle.yml b/circle.yml index 4019a7f..9ded75f 100644 --- a/circle.yml +++ b/circle.yml @@ -7,9 +7,10 @@ dependencies: - sudo pip install pep8 --upgrade - sudo pip install pyflakes - sudo pip install coverage - + - sudo pip install virtualenv==12.0.2 + test: override: - - make test + - make test-all - make install - make coverage \ No newline at end of file diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index 5d1302c..3aaef5d 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -19,13 +19,13 @@ def get_git_revision_hash(): import subprocess - return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip() + return subprocess.check_output(['git', 'rev-parse', 'HEAD']).decode("utf-8").strip() def get_git_directory(): import subprocess - return subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).strip() + return subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).decode("utf-8").strip() def file_exists(rootdir, filename): diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..44f2288 --- /dev/null +++ b/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py27, py35 + +[testenv] +commands = make test +whitelist_externals=make From 27148fcc6a89667edb689d14d46e6443ece8ebca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Cort=C3=AAs?= Date: Wed, 4 Nov 2015 23:18:25 +0000 Subject: [PATCH 30/33] Run tests in 2.7 and 3.5 environment --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 44f2288..7149960 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27, py35 +envlist = py27, py350 [testenv] commands = make test From 50bc03a07d08552d64ef3377b415ccc39b6ad5d7 Mon Sep 17 00:00:00 2001 From: Philipp Wendler Date: Sun, 22 Nov 2015 17:01:46 +0100 Subject: [PATCH 31/33] Fix crash on final message with Python 3 With Python 3, the tool crashes after uploading the coverage results with the following message: {{{ 2015-11-22 16:25:40,601 - INFO - Parsing report file... 2015-11-22 16:25:40,909 - INFO - Uploading report... 2015-11-22 16:25:40,928 - INFO - Starting new HTTPS connection (1): api.codacy.com Traceback (most recent call last): File "/home/wendler/venv/benchexec-src/bin/python-codacy-coverage", line 9, in load_entry_point('codacy-coverage==1.1.0', 'console_scripts', 'python-codacy-coverage')() File "/home/wendler/venv/benchexec-src/src/codacy/src/codacy/__init__.py", line 6, in main return reporter.run() File "/home/wendler/venv/benchexec-src/src/codacy/src/codacy/reporter.py", line 140, in run upload_report(report, CODACY_PROJECT_TOKEN, args.commit) File "/home/wendler/venv/benchexec-src/src/codacy/src/codacy/reporter.py", line 110, in upload_report message = json.loads(r.content)['success'] File "/usr/lib/python3.4/json/__init__.py", line 312, in loads s.__class__.__name__)) TypeError: the JSON object must be str, not 'bytes' }}} --- src/codacy/reporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codacy/reporter.py b/src/codacy/reporter.py index 68ebc6c..8882e91 100755 --- a/src/codacy/reporter.py +++ b/src/codacy/reporter.py @@ -107,7 +107,7 @@ def upload_report(report, token, commit): logging.debug(r.content) r.raise_for_status() - message = json.loads(r.content)['success'] + message = json.loads(r.text)['success'] logging.info(message) From f7e687e684f2100bde6951d1135768938b246f34 Mon Sep 17 00:00:00 2001 From: Joao Machado Date: Thu, 26 Nov 2015 19:16:23 +0000 Subject: [PATCH 32/33] Change setup.py to get version from version.py --- setup.py | 11 ++++++++++- version.py | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 version.py diff --git a/setup.py b/setup.py index dcdfc24..536a339 100644 --- a/setup.py +++ b/setup.py @@ -10,10 +10,19 @@ with open(path.join(here, 'README.rst'), encoding='utf-8') as f: long_description = f.read() +# Default version +__version__ = '1.1.1' + +# Get the correct version from file +try: + exec(open('version.py').read()) +except: + pass + setup( name='codacy-coverage', - version='1.1.0', + version=__version__, description='Codacy coverage reporter for Python', long_description=long_description, diff --git a/version.py b/version.py new file mode 100644 index 0000000..b3ddbc4 --- /dev/null +++ b/version.py @@ -0,0 +1 @@ +__version__ = '1.1.1' From ec8be31519883833cb2e13e59cdb7990240a4f4d Mon Sep 17 00:00:00 2001 From: rshipp Date: Sat, 28 Nov 2015 15:11:12 +0100 Subject: [PATCH 33/33] Import version instead of reading it --- setup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 536a339..cacfa58 100644 --- a/setup.py +++ b/setup.py @@ -15,8 +15,9 @@ # Get the correct version from file try: - exec(open('version.py').read()) -except: + import version + __version__ = version.__version__ +except ImportError: pass setup(