Merge pull request #10 from xoxys/feat_better_logging

Respect PY_COLORS and refactor drone config
This commit is contained in:
Robert Kaussow 2019-03-25 11:12:38 +01:00 committed by GitHub
commit d7b165d4bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 299 additions and 100 deletions

View File

@ -1,9 +1,12 @@
local PythonVersions(pyversion="2.7", py="27") = { local PythonVersions(pyversion="2.7", py="27") = {
name: "python" + pyversion, name: "python" + pyversion + "-ansible",
image: "python:" + pyversion, image: "python:" + pyversion,
pull: "always", pull: "always",
environment: {
PY_COLORS: 1
},
commands: [ commands: [
"pip install tox -q", "pip install tox -qq",
"tox -e $(tox -l | grep py" + py + " | xargs | sed 's/ /,/g') -q", "tox -e $(tox -l | grep py" + py + " | xargs | sed 's/ /,/g') -q",
], ],
depends_on: [ depends_on: [
@ -23,7 +26,62 @@ local PipelineTesting = {
PythonVersions(pyversion="3.5", py="35"), PythonVersions(pyversion="3.5", py="35"),
PythonVersions(pyversion="3.6", py="36"), PythonVersions(pyversion="3.6", py="36"),
PythonVersions(pyversion="3.7", py="37"), PythonVersions(pyversion="3.7", py="37"),
{
name: "python-flake8",
image: "python:3.7",
pull: "always",
environment: {
PY_COLORS: 1
},
commands: [
"pip install -r test-requirements.txt -qq",
"pip install -qq .",
"flake8 ./ansiblelater",
],
depends_on: [
"clone",
],
},
{
name: "python-bandit",
image: "python:3.7",
pull: "always",
environment: {
PY_COLORS: 1
},
commands: [
"pip install -r test-requirements.txt -qq",
"pip install -qq .",
"bandit -r ./ansiblelater",
],
depends_on: [
"clone",
],
},
{
name: "codecov",
image: "python:3.7",
pull: "always",
environment: {
PY_COLORS: 1,
CODECOV_TOKEN: { "from_secret": "codecov_token" },
},
commands: [
"pip install codecov",
"coverage combine .tox/py*/.coverage",
"codecov --required"
],
depends_on: [
"python2.7-ansible",
"python3.5-ansible",
"python3.6-ansible",
"python3.7-ansible"
],
}
], ],
trigger: {
ref: ["refs/heads/master", "refs/tags/**", "refs/pull/**"],
},
}; };
local PipelineBuild = { local PipelineBuild = {
@ -61,6 +119,11 @@ local PipelineBuild = {
detach_sign: true, detach_sign: true,
files: [ "dist/*" ], files: [ "dist/*" ],
}, },
when: {
event: {
exclude: ['pull_request'],
},
},
}, },
{ {
name: "publish-github", name: "publish-github",
@ -68,7 +131,10 @@ local PipelineBuild = {
pull: "always", pull: "always",
settings: { settings: {
api_key: { "from_secret": "github_token"}, api_key: { "from_secret": "github_token"},
overwrite: true,
files: ["dist/*", "sha256sum.txt"], files: ["dist/*", "sha256sum.txt"],
title: "${DRONE_TAG}",
note: "CHANGELOG.md",
}, },
when: { when: {
event: [ "tag" ], event: [ "tag" ],
@ -92,6 +158,9 @@ local PipelineBuild = {
depends_on: [ depends_on: [
"testing", "testing",
], ],
trigger: {
ref: ["refs/heads/master", "refs/tags/**", "refs/pull/**"],
},
}; };
local PipelineNotifications = { local PipelineNotifications = {
@ -118,7 +187,7 @@ local PipelineNotifications = {
"build", "build",
], ],
trigger: { trigger: {
event: [ "push", "tag" ], ref: ["refs/heads/master", "refs/tags/**"],
status: [ "success", "failure" ], status: [ "success", "failure" ],
}, },
}; };

View File

@ -7,42 +7,97 @@ platform:
arch: amd64 arch: amd64
steps: steps:
- name: python2.7 - name: python2.7-ansible
pull: always pull: always
image: python:2.7 image: python:2.7
commands: commands:
- pip install tox -q - pip install tox -qq
- "tox -e $(tox -l | grep py27 | xargs | sed 's/ /,/g') -q" - "tox -e $(tox -l | grep py27 | xargs | sed 's/ /,/g') -q"
environment:
PY_COLORS: 1
depends_on: depends_on:
- clone - clone
- name: python3.5 - name: python3.5-ansible
pull: always pull: always
image: python:3.5 image: python:3.5
commands: commands:
- pip install tox -q - pip install tox -qq
- "tox -e $(tox -l | grep py35 | xargs | sed 's/ /,/g') -q" - "tox -e $(tox -l | grep py35 | xargs | sed 's/ /,/g') -q"
environment:
PY_COLORS: 1
depends_on: depends_on:
- clone - clone
- name: python3.6 - name: python3.6-ansible
pull: always pull: always
image: python:3.6 image: python:3.6
commands: commands:
- pip install tox -q - pip install tox -qq
- "tox -e $(tox -l | grep py36 | xargs | sed 's/ /,/g') -q" - "tox -e $(tox -l | grep py36 | xargs | sed 's/ /,/g') -q"
environment:
PY_COLORS: 1
depends_on: depends_on:
- clone - clone
- name: python3.7 - name: python3.7-ansible
pull: always pull: always
image: python:3.7 image: python:3.7
commands: commands:
- pip install tox -q - pip install tox -qq
- "tox -e $(tox -l | grep py37 | xargs | sed 's/ /,/g') -q" - "tox -e $(tox -l | grep py37 | xargs | sed 's/ /,/g') -q"
environment:
PY_COLORS: 1
depends_on: depends_on:
- clone - clone
- name: python-flake8
pull: always
image: python:3.7
commands:
- pip install -r test-requirements.txt -qq
- pip install -qq .
- flake8 ./ansiblelater
environment:
PY_COLORS: 1
depends_on:
- clone
- name: python-bandit
pull: always
image: python:3.7
commands:
- pip install -r test-requirements.txt -qq
- pip install -qq .
- bandit -r ./ansiblelater
environment:
PY_COLORS: 1
depends_on:
- clone
- name: codecov
pull: always
image: python:3.7
commands:
- pip install codecov
- "coverage combine .tox/py*/.coverage"
- codecov --required
environment:
CODECOV_TOKEN:
from_secret: codecov_token
PY_COLORS: 1
depends_on:
- python2.7-ansible
- python3.5-ansible
- python3.6-ansible
- python3.7-ansible
trigger:
ref:
- refs/heads/master
- "refs/tags/**"
- "refs/pull/**"
--- ---
kind: pipeline kind: pipeline
name: build name: build
@ -76,6 +131,10 @@ steps:
from_secret: gpgsign_key from_secret: gpgsign_key
passphrase: passphrase:
from_secret: gpgsign_passphrase from_secret: gpgsign_passphrase
when:
event:
exclude:
- pull_request
- name: publish-github - name: publish-github
pull: always pull: always
@ -86,6 +145,9 @@ steps:
files: files:
- "dist/*" - "dist/*"
- sha256sum.txt - sha256sum.txt
note: CHANGELOG.md
overwrite: true
title: "${DRONE_TAG}"
when: when:
event: event:
- tag - tag
@ -104,6 +166,12 @@ steps:
event: event:
- tag - tag
trigger:
ref:
- refs/heads/master
- "refs/tags/**"
- "refs/pull/**"
depends_on: depends_on:
- testing - testing
@ -128,9 +196,9 @@ steps:
from_secret: matrix_username from_secret: matrix_username
trigger: trigger:
event: ref:
- push - refs/heads/master
- tag - "refs/tags/**"
status: status:
- success - success
- failure - failure

View File

@ -1,3 +1,2 @@
- BUGFIX - ENHANCEMENT
- Controls like `when` used at block level will be added as metadata to each task inside this block [#9](https://github.com/xoxys/ansible-later/issues/9) - Respect `PY_COLORS` to get colorized output for nontty environments ([#10](https://github.com/xoxys/ansible-later/pull/10))
- Commands can be used in place of modules if the task use register [#8](https://github.com/xoxys/ansible-later/issues/8)

View File

@ -4,6 +4,7 @@
[![](https://img.shields.io/pypi/pyversions/ansible-later.svg)](https://pypi.org/project/ansible-later/) [![](https://img.shields.io/pypi/pyversions/ansible-later.svg)](https://pypi.org/project/ansible-later/)
[![](https://img.shields.io/pypi/status/ansible-later.svg)](https://pypi.org/project/ansible-later/) [![](https://img.shields.io/pypi/status/ansible-later.svg)](https://pypi.org/project/ansible-later/)
[![](https://img.shields.io/pypi/v/ansible-later.svg)](https://pypi.org/project/ansible-later/) [![](https://img.shields.io/pypi/v/ansible-later.svg)](https://pypi.org/project/ansible-later/)
[![codecov](https://codecov.io/gh/xoxys/ansible-later/branch/master/graph/badge.svg)](https://codecov.io/gh/xoxys/ansible-later)
This is a fork of Will Thames [ansible-review](https://github.com/willthames/ansible-review) so credits goes to him This is a fork of Will Thames [ansible-review](https://github.com/willthames/ansible-review) so credits goes to him
for his work on ansible-review and ansible-lint. for his work on ansible-review and ansible-lint.
@ -18,20 +19,22 @@ The project name is an acronym for **L**ovely **A**utomation **TE**sting f**R**m
## Table of Content ## Table of Content
- [Setup](#setup) - [ansible-later](#ansible-later)
- [Using pip](#using-pip) - [Table of Content](#table-of-content)
- [From source](#from-source) - [Setup](#setup)
- [Usage](#usage) - [Using pip](#using-pip)
- [Configuration](#configuration) - [From source](#from-source)
- [Review a git repositories](#review-a-git-repositories) - [Usage](#usage)
- [Review a list of files](#review-a-list-of-files) - [Configuration](#configuration)
- [Buildin rules](#buildin-rules) - [Review a git repositories](#review-a-git-repositories)
- [Build your own](#build-your-own) - [Review a list of files](#review-a-list-of-files)
- [The standards file](#the-standards-file) - [Buildin rules](#buildin-rules)
- [Candidates](#candidates) - [Build your own](#build-your-own)
- [Minimal standards checks](#minimal-standards-checks) - [The standards file](#the-standards-file)
- [License](#license) - [Candidates](#candidates)
- [Maintainers and Contributors](#maintainers-and-contributors) - [Minimal standards checks](#minimal-standards-checks)
- [License](#license)
- [Maintainers and Contributors](#maintainers-and-contributors)
--- ---

View File

@ -3,42 +3,51 @@ from __future__ import print_function
import importlib import importlib
import logging import logging
import os import os
import subprocess
import sys import sys
import re import re
import colorama
from distutils.version import LooseVersion from distutils.version import LooseVersion
from ansible.module_utils.parsing.convert_bool import boolean as to_bool
try: try:
import ConfigParser as configparser import ConfigParser as configparser
except ImportError: except ImportError:
import configparser import configparser
try:
from ansible.utils.color import stringc
except ImportError:
from ansible.color import stringc
# from yamlhelper import * def should_do_markup():
py_colors = os.environ.get('PY_COLORS', None)
if py_colors is not None:
return to_bool(py_colors, strict=False)
return sys.stdout.isatty() and os.environ.get('TERM') != 'dumb'
colorama.init(autoreset=True, strip=not should_do_markup())
def abort(message, file=sys.stderr): def abort(message, file=sys.stderr):
print(stringc("FATAL: %s" % message, 'red'), file=file) return color_text(colorama.Fore.RED, "FATAL: {}".format(message))
sys.exit(1) sys.exit(1)
def error(message, file=sys.stderr): def error(message, file=sys.stderr):
print(stringc("ERROR: %s" % message, 'red'), file=file) return color_text(colorama.Fore.RED, "ERROR: {}".format(message))
def warn(message, settings, file=sys.stdout): def warn(message, settings, file=sys.stdout):
if settings.log_level <= logging.WARNING: if settings.log_level <= logging.WARNING:
print(stringc("WARN: %s" % message, 'yellow'), file=file) return color_text(colorama.Fore.YELLOW, "WARN: {}".format(message))
def info(message, settings, file=sys.stdout): def info(message, settings, file=sys.stdout):
if settings.log_level <= logging.INFO: if settings.log_level <= logging.INFO:
print(stringc("INFO: %s" % message, 'green'), file=file) return color_text(colorama.Fore.BLUE, "INFO: {}".format(message))
def color_text(color, msg):
print('{}{}{}'.format(color, msg, colorama.Style.RESET_ALL))
def count_spaces(c_string): def count_spaces(c_string):
@ -104,18 +113,6 @@ def read_config(config_file):
return Settings(config, config_file) return Settings(config, config_file)
def execute(cmd):
result = ExecuteResult()
encoding = 'UTF-8'
env = dict(os.environ)
env['PYTHONIOENCODING'] = encoding
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, env=env)
result.output = proc.communicate()[0].decode(encoding)
result.rc = proc.returncode
return result
class Settings(object): class Settings(object):
def __init__(self, config, config_file): def __init__(self, config, config_file):
self.rulesdir = None self.rulesdir = None
@ -130,7 +127,3 @@ class Settings(object):
self.custom_modules = [x.strip() for x in modules.split(',')] self.custom_modules = [x.strip() for x in modules.split(',')]
self.configfile = config_file self.configfile = config_file
class ExecuteResult(object):
pass

View File

@ -1,3 +0,0 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

View File

@ -6,5 +6,10 @@ license_file = LICENSE
universal = 1 universal = 1
[flake8] [flake8]
ignore = E501, W503, F401, N813
max-line-length = 100 max-line-length = 100
exclude = .git,.hg,.svn,test,setup.py,__pycache__ exclude = .git,.tox,__pycache__,build,dist,tests,*.pyc,*.egg-info,.cache,.eggs
[tool:pytest]
filterwarnings =
ignore:.*collections.*:DeprecationWarning

View File

@ -65,7 +65,8 @@ setup(
"unidiff", "unidiff",
"flake8", "flake8",
"yamllint", "yamllint",
"nested-lookup" "nested-lookup",
"colorama"
], ],
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [

8
test-requirements.txt Normal file
View File

@ -0,0 +1,8 @@
flake8
flake8-colors
pep8-naming
wheel
pytest
pytest-mock
pytest-cov
bandit

0
tests/__init__.py Normal file
View File

View File

@ -0,0 +1,82 @@
from __future__ import print_function
import colorama
import logging
from ansiblelater.utils import info, warn, abort, error, should_do_markup
def test_abort(capsys, mocker):
abort('foo')
stdout, _ = capsys.readouterr()
print('{}{}{}'.format(colorama.Fore.RED, 'FATAL: foo'.rstrip(),
colorama.Style.RESET_ALL))
x, _ = capsys.readouterr()
assert x == stdout
def test_error(capsys, mocker):
error('foo')
stdout, _ = capsys.readouterr()
print('{}{}{}'.format(colorama.Fore.RED, 'ERROR: foo'.rstrip(),
colorama.Style.RESET_ALL))
x, _ = capsys.readouterr()
assert x == stdout
def test_warn(capsys, mocker):
settings = mocker.MagicMock()
settings.log_level = getattr(logging, 'WARNING')
warn('foo', settings)
stdout, _ = capsys.readouterr()
print('{}{}{}'.format(colorama.Fore.YELLOW, 'WARN: foo'.rstrip(),
colorama.Style.RESET_ALL))
x, _ = capsys.readouterr()
assert x == stdout
def test_info(capsys, mocker):
settings = mocker.MagicMock()
settings.log_level = getattr(logging, 'INFO')
info('foo', settings)
stdout, _ = capsys.readouterr()
print('{}{}{}'.format(colorama.Fore.BLUE, 'INFO: foo'.rstrip(),
colorama.Style.RESET_ALL))
x, _ = capsys.readouterr()
assert x == stdout
def test_markup_detection_pycolors0(monkeypatch):
monkeypatch.setenv('PY_COLORS', '0')
assert not should_do_markup()
def test_markup_detection_pycolors1(monkeypatch):
monkeypatch.setenv('PY_COLORS', '1')
assert should_do_markup()
def test_markup_detection_tty_yes(mocker):
mocker.patch('sys.stdout.isatty', return_value=True)
mocker.patch('os.environ', {'TERM': 'xterm'})
assert should_do_markup()
mocker.resetall()
mocker.stopall()
def test_markup_detection_tty_no(mocker):
mocker.patch('os.environ', {})
mocker.patch('sys.stdout.isatty', return_value=False)
assert not should_do_markup()
mocker.resetall()
mocker.stopall()

50
tox.ini
View File

@ -1,46 +1,20 @@
[tox] [tox]
minversion = 3.5 minversion = 3.7.0
envlist = py27-ansible{21},py{27,35,36,37}-ansible{22,23,24,25,26,27},py{27,35,36,37}-flake8 envlist =
py{27,35,36,37}-ansible{25,26,27,devel}
isolated_build = True isolated_build = True
[testenv] [testenv]
usedevelop = True
passenv = PY_COLORS
setenv = COVERAGE_FILE={envdir}/.coverage
deps = deps =
flake8 -rtest-requirements.txt
pep8-naming
wheel
flake8-colors
pytest
ansible21: ansible>=2.1,<2.2
ansible22: ansible>=2.2,<2.3
ansible23: ansible>=2.3,<2.4
ansible24: ansible>=2.4,<2.5
ansible25: ansible>=2.5,<2.6 ansible25: ansible>=2.5,<2.6
ansible26: ansible>=2.6,<2.7 ansible26: ansible>=2.6,<2.7
ansible27: ansible>=2.7,<2.8 ansible27: ansible>=2.7,<2.8
ansibledevel: git+https://github.com/ansible/ansible.git
commands = ansible-later -c tests/config/config.ini tests/data/yaml_success.yml commands =
passenv = HOME ansible-later --help
pytest tests/ --cov={toxinidir}/ansiblelater/ --no-cov-on-fail
[testenv:py27-flake8]
commands = flake8 ansiblelater
usedevelop = True
[testenv:py36-flake8]
commands = flake8 ansiblelater
usedevelop = True
[flake8]
ignore = E501, W503, F401, N813
exclude =
.tox,
.git,
__pycache__,
build,
dist,
tests/fixtures/*,
*.pyc,
*.egg-info,
.cache,
.eggs
format = %(path)s:%(row)d:%(col)d: ${red}%(code)s %(text)s${reset}