Adopt use of pre-commit hooks

- rename pep8 target to more generic linters
- migrates flake8 execution to pre-commit
- adds yaml linting
- hardening flake8 rules
- setting max-line-lengh to 120 instead of ignoring it.
- bumped minimal sphinx version
- configured sphinx with warnings as errors

Change-Id: I4c598c07297ae6a2160ba6754cec860adbfeb6f2
Signed-off-by: Sorin Sbarnea <ssbarnea@redhat.com>
This commit is contained in:
Sorin Sbarnea 2018-06-20 15:20:58 +01:00
parent f7fa4ce059
commit e5e7a097b1
No known key found for this signature in database
GPG Key ID: B85725D917D27B8A
8 changed files with 95 additions and 63 deletions

14
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,14 @@
---
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v1.3.0
hooks:
- id: flake8
- id: check-yaml
files: .*\.(yaml|yml)$
# args: [--unsafe]
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.11.1
hooks:
- id: yamllint
files: \.(yaml|yml)$

View File

@ -1,3 +1,4 @@
---
- job: - job:
name: jjb-tox-cross-jenkins-job-builder name: jjb-tox-cross-jenkins-job-builder
description: Tests compatibility with master branch of jenkins-job-builder description: Tests compatibility with master branch of jenkins-job-builder
@ -9,6 +10,22 @@
failure-message: WARNING failure-message: WARNING
- project: - project:
templates:
- docs-on-readthedocs
- publish-to-pypi
check: check:
jobs: jobs:
- openstack-tox-linters
- openstack-tox-py27
- openstack-tox-py35
- openstack-tox-py36
- openstack-tox-pypy:
nodeset: ubuntu-bionic
- jjb-tox-cross-jenkins-job-builder - jjb-tox-cross-jenkins-job-builder
gate:
jobs:
- build-openstack-sphinx-docs
- openstack-tox-linters
- openstack-tox-py27
- openstack-tox-py35
- openstack-tox-py36

View File

@ -68,11 +68,8 @@ More details on how you can contribute is available on our wiki at:
Writing a patch Writing a patch
--------------- ---------------
We ask that all code submissions be flake8_ clean. The Be sure that you lint code before created an code review.
easiest way to do that is to run tox_ before submitting code for The easiest way to do this is to install git pre-commit_ hooks.
review in Gerrit. It will run ``flake8`` in the same
manner as the automated test suite that will run on proposed
patchsets.
Installing without setup.py Installing without setup.py
--------------------------- ---------------------------
@ -81,9 +78,9 @@ Then install the required python packages using pip_::
$ sudo pip install python-jenkins $ sudo pip install python-jenkins
.. _flake8: https://pypi.org/project/flake8
.. _tox: https://testrun.org/tox .. _tox: https://testrun.org/tox
.. _pip: https://pypi.org/project/pip .. _pip: https://pypi.org/project/pip
.. _pre-commit: https://pre-commit.com/#install
.. rubric:: Footnotes .. rubric:: Footnotes

View File

@ -14,18 +14,19 @@
import os import os
import sys import sys
from jenkins.version import version_info as python_jenkins_version
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here. # documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.')) # sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, os.path.abspath('../../jenkins')) sys.path.insert(0, os.path.abspath('../../jenkins'))
# -- General configuration ---------------------------------------------------- # -- General configuration ----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here. # If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0' # needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
@ -44,7 +45,7 @@ templates_path = ['_templates']
source_suffix = '.rst' source_suffix = '.rst'
# The encoding of source files. # The encoding of source files.
#source_encoding = 'utf-8-sig' # source_encoding = 'utf-8-sig'
# The master toctree document. # The master toctree document.
master_doc = 'index' master_doc = 'index'
@ -58,44 +59,43 @@ copyright = u'2010, Willow Garage'
# built documents. # built documents.
# #
# Version info # Version info
from jenkins.version import version_info as python_jenkins_version
release = python_jenkins_version.version_string_with_vcs() release = python_jenkins_version.version_string_with_vcs()
# The short X.Y version. # The short X.Y version.
version = python_jenkins_version.canonical_version_string() version = python_jenkins_version.canonical_version_string()
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.
#language = None # language = None
# There are two options for replacing |today|: either, you set today to some # There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used: # non-false value, then it is used:
#today = '' # today = ''
# Else, today_fmt is used as the format for a strftime call. # Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y' # today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
exclude_patterns = ['_build'] exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents # The reST default role (used for this markup: `text`) to use for all documents
#default_role = None # default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text. # If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True # add_function_parentheses = True
# If true, the current module name will be prepended to all description # If true, the current module name will be prepended to all description
# unit titles (such as .. function::). # unit titles (such as .. function::).
#add_module_names = True # add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the # If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default. # output. They are ignored by default.
#show_authors = False # show_authors = False
# The name of the Pygments (syntax highlighting) style to use. # The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx' pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting. # A list of ignored prefixes for module index sorting.
#modindex_common_prefix = [] # modindex_common_prefix = []
# -- Options for HTML output -------------------------------------------------- # -- Options for HTML output --------------------------------------------------
@ -107,72 +107,72 @@ html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
# documentation. # documentation.
#html_theme_options = {} # html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory. # Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = [] # html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to # The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation". # "<project> v<release> documentation".
#html_title = None # html_title = None
# A shorter title for the navigation bar. Default is the same as html_title. # A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None # html_short_title = None
# The name of an image file (relative to this directory) to place at the top # The name of an image file (relative to this directory) to place at the top
# of the sidebar. # of the sidebar.
#html_logo = None # html_logo = None
# The name of an image file (within the static path) to use as favicon of the # The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large. # pixels large.
#html_favicon = None # html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here, # Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static'] # html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format. # using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y' # html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to # If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities. # typographically correct entities.
#html_use_smartypants = True # html_use_smartypants = True
# Custom sidebar templates, maps document names to template names. # Custom sidebar templates, maps document names to template names.
#html_sidebars = {} # html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to # Additional templates that should be rendered to pages, maps page names to
# template names. # template names.
#html_additional_pages = {} # html_additional_pages = {}
# If false, no module index is generated. # If false, no module index is generated.
#html_domain_indices = True # html_domain_indices = True
# If false, no index is generated. # If false, no index is generated.
#html_use_index = True # html_use_index = True
# If true, the index is split into individual pages for each letter. # If true, the index is split into individual pages for each letter.
#html_split_index = False # html_split_index = False
# If true, links to the reST sources are added to the pages. # If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True # html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True # html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True # html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will # If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the # contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served. # base URL from which the finished HTML is served.
#html_use_opensearch = '' # html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml"). # This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None # html_file_suffix = None
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
htmlhelp_basename = 'PythonJenkinsdoc' htmlhelp_basename = 'PythonJenkinsdoc'
@ -181,10 +181,10 @@ htmlhelp_basename = 'PythonJenkinsdoc'
# -- Options for LaTeX output ------------------------------------------------- # -- Options for LaTeX output -------------------------------------------------
# The paper size ('letter' or 'a4'). # The paper size ('letter' or 'a4').
#latex_paper_size = 'letter' # latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt'). # The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt' # latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]) # (source start file, target name, title, author, documentclass [howto/manual])
@ -195,26 +195,26 @@ latex_documents = [
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of
# the title page. # the title page.
#latex_logo = None # latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts, # For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters. # not chapters.
#latex_use_parts = False # latex_use_parts = False
# If true, show page references after internal links. # If true, show page references after internal links.
#latex_show_pagerefs = False # latex_show_pagerefs = False
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
#latex_show_urls = False # latex_show_urls = False
# Additional stuff for the LaTeX preamble. # Additional stuff for the LaTeX preamble.
#latex_preamble = '' # latex_preamble = ''
# Documents to append as an appendix to all manuals. # Documents to append as an appendix to all manuals.
#latex_appendices = [] # latex_appendices = []
# If false, no module index is generated. # If false, no module index is generated.
#latex_domain_indices = True # latex_domain_indices = True
# -- Options for manual page output ------------------------------------------- # -- Options for manual page output -------------------------------------------

View File

@ -626,7 +626,7 @@ class Jenkins(object):
>>> build_info = server.get_build_info('build_name', next_build_number) >>> build_info = server.get_build_info('build_name', next_build_number)
>>> print(build_info) >>> print(build_info)
{u'building': False, u'changeSet': {u'items': [{u'date': u'2011-12-19T18:01:52.540557Z', u'msg': u'test', u'revision': 66, u'user': u'unknown', u'paths': [{u'editType': u'edit', u'file': u'/branches/demo/index.html'}]}], u'kind': u'svn', u'revisions': [{u'module': u'http://eaas-svn01.i3.level3.com/eaas', u'revision': 66}]}, u'builtOn': u'', u'description': None, u'artifacts': [{u'relativePath': u'dist/eaas-87-2011-12-19_18-01-57.war', u'displayPath': u'eaas-87-2011-12-19_18-01-57.war', u'fileName': u'eaas-87-2011-12-19_18-01-57.war'}, {u'relativePath': u'dist/eaas-87-2011-12-19_18-01-57.war.zip', u'displayPath': u'eaas-87-2011-12-19_18-01-57.war.zip', u'fileName': u'eaas-87-2011-12-19_18-01-57.war.zip'}], u'timestamp': 1324317717000, u'number': 87, u'actions': [{u'parameters': [{u'name': u'SERVICE_NAME', u'value': u'eaas'}, {u'name': u'PROJECT_NAME', u'value': u'demo'}]}, {u'causes': [{u'userName': u'anonymous', u'shortDescription': u'Started by user anonymous'}]}, {}, {}, {}], u'id': u'2011-12-19_18-01-57', u'keepLog': False, u'url': u'http://eaas-jenkins01.i3.level3.com:9080/job/build_war/87/', u'culprits': [{u'absoluteUrl': u'http://eaas-jenkins01.i3.level3.com:9080/user/unknown', u'fullName': u'unknown'}], u'result': u'SUCCESS', u'duration': 8826, u'fullDisplayName': u'build_war #87'} {u'building': False, u'changeSet': {u'items': [{u'date': u'2011-12-19T18:01:52.540557Z', u'msg': u'test', u'revision': 66, u'user': u'unknown', u'paths': [{u'editType': u'edit', u'file': u'/branches/demo/index.html'}]}], u'kind': u'svn', u'revisions': [{u'module': u'http://eaas-svn01.i3.level3.com/eaas', u'revision': 66}]}, u'builtOn': u'', u'description': None, u'artifacts': [{u'relativePath': u'dist/eaas-87-2011-12-19_18-01-57.war', u'displayPath': u'eaas-87-2011-12-19_18-01-57.war', u'fileName': u'eaas-87-2011-12-19_18-01-57.war'}, {u'relativePath': u'dist/eaas-87-2011-12-19_18-01-57.war.zip', u'displayPath': u'eaas-87-2011-12-19_18-01-57.war.zip', u'fileName': u'eaas-87-2011-12-19_18-01-57.war.zip'}], u'timestamp': 1324317717000, u'number': 87, u'actions': [{u'parameters': [{u'name': u'SERVICE_NAME', u'value': u'eaas'}, {u'name': u'PROJECT_NAME', u'value': u'demo'}]}, {u'causes': [{u'userName': u'anonymous', u'shortDescription': u'Started by user anonymous'}]}, {}, {}, {}], u'id': u'2011-12-19_18-01-57', u'keepLog': False, u'url': u'http://eaas-jenkins01.i3.level3.com:9080/job/build_war/87/', u'culprits': [{u'absoluteUrl': u'http://eaas-jenkins01.i3.level3.com:9080/user/unknown', u'fullName': u'unknown'}], u'result': u'SUCCESS', u'duration': 8826, u'fullDisplayName': u'build_war #87'}
''' ''' # noqa: E501
folder_url, short_name = self._get_job_folder(name) folder_url, short_name = self._get_job_folder(name)
try: try:
response = self.jenkins_open(requests.Request( response = self.jenkins_open(requests.Request(
@ -703,7 +703,7 @@ class Jenkins(object):
>>> queue_info = server.get_queue_info() >>> queue_info = server.get_queue_info()
>>> print(queue_info[0]) >>> print(queue_info[0])
{u'task': {u'url': u'http://your_url/job/my_job/', u'color': u'aborted_anime', u'name': u'my_job'}, u'stuck': False, u'actions': [{u'causes': [{u'shortDescription': u'Started by timer'}]}], u'buildable': False, u'params': u'', u'buildableStartMilliseconds': 1315087293316, u'why': u'Build #2,532 is already in progress (ETA:10 min)', u'blocked': True} {u'task': {u'url': u'http://your_url/job/my_job/', u'color': u'aborted_anime', u'name': u'my_job'}, u'stuck': False, u'actions': [{u'causes': [{u'shortDescription': u'Started by timer'}]}], u'buildable': False, u'params': u'', u'buildableStartMilliseconds': 1315087293316, u'why': u'Build #2,532 is already in progress (ETA:10 min)', u'blocked': True}
''' ''' # noqa: E501
return json.loads(self.jenkins_open( return json.loads(self.jenkins_open(
requests.Request('GET', self._build_url(Q_INFO)) requests.Request('GET', self._build_url(Q_INFO))
))['items'] ))['items']
@ -1540,7 +1540,8 @@ class Jenkins(object):
:param remoteFS: Remote filesystem location to use, ``str`` :param remoteFS: Remote filesystem location to use, ``str``
:param labels: Labels to associate with node, ``str`` :param labels: Labels to associate with node, ``str``
:param exclusive: Use this node for tied jobs only, ``bool`` :param exclusive: Use this node for tied jobs only, ``bool``
:param launcher: The launch method for the slave, ``jenkins.LAUNCHER_COMMAND``, ``jenkins.LAUNCHER_SSH``, ``jenkins.LAUNCHER_JNLP``, ``jenkins.LAUNCHER_WINDOWS_SERVICE`` :param launcher: The launch method for the slave, ``jenkins.LAUNCHER_COMMAND``, \
``jenkins.LAUNCHER_SSH``, ``jenkins.LAUNCHER_JNLP``, ``jenkins.LAUNCHER_WINDOWS_SERVICE``
:param launcher_params: Additional parameters for the launcher, ``dict`` :param launcher_params: Additional parameters for the launcher, ``dict``
''' '''
if self.node_exists(name): if self.node_exists(name):

View File

@ -34,3 +34,8 @@ warnerrors = True
all_files = 1 all_files = 1
build-dir = doc/build build-dir = doc/build
source-dir = doc/source source-dir = doc/source
[flake8]
show-source = True
exclude = .venv,.tox,dist,build,*.egg
max-line-length = 120

View File

@ -1,13 +1,13 @@
cmd2!=0.8.3,<0.9.0;python_version<'3.0' # MIT cmd2!=0.8.3,<0.9.0;python_version<'3.0' # MIT
cmd2!=0.8.3;python_version>='3.0' # MIT cmd2!=0.8.3;python_version>='3.0' # MIT
coverage>=3.6 coverage>=3.6
hacking>=0.5.6,<0.11
mock<1.1 mock<1.1
unittest2 unittest2
python-subunit python-subunit
requests-mock>=1.4.0 requests-mock>=1.4.0
requests-kerberos requests-kerberos
sphinx>=1.2,<1.3.0 sphinx>=1.6.0
stestr>=2.0.0 stestr>=2.0.0
testscenarios testscenarios
testtools testtools
pre-commit

22
tox.ini
View File

@ -1,7 +1,7 @@
[tox] [tox]
minversion = 1.6 minversion = 1.6
skipsdist = True skipsdist = True
envlist = py{34,27,35}, pep8, pypy envlist = py{34,27,35}, linters, pypy
[testenv] [testenv]
setenv = setenv =
@ -39,27 +39,25 @@ commands =
coverage html -d cover coverage html -d cover
coverage xml -o cover/coverage.xml coverage xml -o cover/coverage.xml
[testenv:linters]
basepython = python3
commands =
pre-commit run --all
# pep8 was replaced by linter, kept here till we remove it from project-config
[testenv:pep8] [testenv:pep8]
basepython = python3 basepython = python3
commands = flake8 commands =
pre-commit run --all
[testenv:docs] [testenv:docs]
basepython = python3 basepython = python3
commands = python setup.py build_sphinx commands = python setup.py build_sphinx -W
[testenv:venv] [testenv:venv]
basepython = python3 basepython = python3
commands = {posargs} commands = {posargs}
[flake8]
; E501 line too long (80 > 79 characters)
; H301 one import per line
; H405 multi line docstring summary not separated with an empty line
; H501 Do not use locals() for string formatting
ignore = E501,H301,H405,H501
show-source = True
exclude = .venv,.tox,dist,doc,build,*.egg
[testenv:bindep] [testenv:bindep]
basepython = python3 basepython = python3
# Do not install any requirements. We want this to be fast and work even if # Do not install any requirements. We want this to be fast and work even if