PK!| xxmig3_client/__init__.pyfrom __future__ import absolute_import, unicode_literals import json import sys import click import git import requests from .vendors import poetry_version __version__ = poetry_version.extract(source_file=__file__) class Regression(Exception): """Raised when Mig3 service rejects the submission request.""" class log_attempt(object): def __init__(self, message): self._message = message def __enter__(self): click.echo("{}...".format(self._message), err=True, nl=False) return def __exit__(self, exc_type, exc_val, exc_tb): if exc_type or exc_val or exc_tb: click.secho("FAIL\n{exc_type}: {exc_val}".format(**locals()), err=True, fg="red") exit(1) else: click.secho("OK", err=True, fg="green") class ReportConverter(object): def __init__(self, report): self.report = report def _tests(self): for test_document in self.report["included"]: module, test = test_document["attributes"]["name"].split("::") yield {"module": module, "test": test, "outcome": test_document["attributes"]["outcome"]} def convert(self): return [test for test in self._tests()] class JobSubmissionBuilder(object): """Build the job submission for Mig3.""" def __init__(self, project, configuration, test_data): self.project = project self.configuration = configuration self.test_data = test_data def _get_version(self): repository = git.Repo(search_parent_directories=True) return repository.head.object.hexsha def build(self): return { "project_version": self._get_version(), "tests": self.test_data, "project": self.project, "configuration": self.configuration, "mig3_version": __version__, } @click.command() @click.option("-p", "--project", required=True, help="Project ID (from Mig3 service).") @click.option("-c", "--configuration", required=True, help="Configuration ID (from mig3 service).") @click.option("--endpoint", required=True, help="Mig3 job submission endpoint.") @click.option("--token", required=True, help="Mig3 builder authorization token.") @click.option("--report", default=".report.json", type=click.File(), help="Specify the pytest-json report filename.") @click.option("-n", "--dry-run", is_flag=True, help="Show report on stdout instead of submitting it to Mig3 service.") @click.version_option(__version__) def mig3(project, configuration, endpoint, token, report, dry_run): """Validate test results with mig3 service. Run this command after running py.test with json results enabled to validate the test outcome: py.test --json=.report.json The following environment variables can be used in lieu of passing options: MIG3_PROJECT, MIG3_CONFIGURATION, MIG3_ENDPOINT, MIG3_TOKEN, MIG3_DRY_RUN """ with log_attempt("Reading report"): report_json = json.loads(report.read()) with log_attempt("Converting test data"): test_data = ReportConverter(report_json).convert() with log_attempt("Building submission"): submission = JobSubmissionBuilder(project, configuration, test_data).build() with log_attempt("Sending submission"): if not dry_run: response = requests.post( endpoint, data=submission, headers={"Authorization": "Bearer {token}".format(**locals())} ) if response.status_code != 200: raise Regression(response.content) else: json.dump(submission, sys.stdout) if __name__ == "__main__": mig3(auto_envvar_prefix="MIG3") PK!mig3_client/vendors/__init__.pyPK!j@gg%mig3_client/vendors/poetry_version.pyfrom __future__ import unicode_literals import tomlkit from pathlib2 import Path def extract(source_file): d = Path(source_file) result = None while d.parent != d and result is None: d = d.parent pyproject_toml_path = d / "pyproject.toml" if pyproject_toml_path.exists(): pyproject_toml = tomlkit.parse(string=pyproject_toml_path.read_text()) if "tool" in pyproject_toml and "poetry" in pyproject_toml["tool"]: # noinspection PyUnresolvedReferences result = pyproject_toml["tool"]["poetry"]["version"] return result PK!Hʩϲ&),mig3_client-0.1.0.dist-info/entry_points.txtN+I/N.,()L79y%V 6PK!Y 66#mig3_client-0.1.0.dist-info/LICENSE MIT License Copyright (c) 2019, Matthew de Verteuil Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!H|n-WY!mig3_client-0.1.0.dist-info/WHEEL A н#Z;/" bFF]xzwK;<*mTֻ0*Ri.4Vm0[H, JPK!HO4z$mig3_client-0.1.0.dist-info/METADATAn0 Zpsh#,bNj6먱$OG0 IIfdW0WRjA|BCp$D$cHd@  nR Za)s{X~[~.9 :Vǒhϐ!aC,D-U5)V5ڭ׫":-Q! [jTycAy)gM2skv!f02nC5xg'0ʹ2ʓdߤQëdӲtv*qӞp'eޒ_kV,u\,`Tw6wRKW|ԣA_^ŨwƸwu׶Tisc#=KdsNcktl. |?snDt9y/wo\Qٖ)A O@gN'DbTS}58QY]lj㺤H\_PK!H߀"mig3_client-0.1.0.dist-info/RECORD}л@|хV@!PA@nq~'`_u",(8`dr5(uF@LQ-:q͕TIyF\~=d19 Àlxv\Q,8Р"KE'g#̄Ri>