diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5927cfa --- /dev/null +++ b/.pre-commit-config.yaml @@ -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)$ diff --git a/.zuul.yaml b/.zuul.yaml index d1eaf17..9c77ab6 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -1,3 +1,4 @@ +--- - job: name: jjb-tox-cross-jenkins-job-builder description: Tests compatibility with master branch of jenkins-job-builder @@ -9,6 +10,22 @@ failure-message: WARNING - project: + templates: + - docs-on-readthedocs + - publish-to-pypi check: 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 + gate: + jobs: + - build-openstack-sphinx-docs + - openstack-tox-linters + - openstack-tox-py27 + - openstack-tox-py35 + - openstack-tox-py36 diff --git a/README.rst b/README.rst index e6b7192..e5ded31 100644 --- a/README.rst +++ b/README.rst @@ -68,11 +68,8 @@ More details on how you can contribute is available on our wiki at: Writing a patch --------------- -We ask that all code submissions be flake8_ clean. The -easiest way to do that is to run tox_ before submitting code for -review in Gerrit. It will run ``flake8`` in the same -manner as the automated test suite that will run on proposed -patchsets. +Be sure that you lint code before created an code review. +The easiest way to do this is to install git pre-commit_ hooks. Installing without setup.py --------------------------- @@ -81,9 +78,9 @@ Then install the required python packages using pip_:: $ sudo pip install python-jenkins -.. _flake8: https://pypi.org/project/flake8 .. _tox: https://testrun.org/tox .. _pip: https://pypi.org/project/pip +.. _pre-commit: https://pre-commit.com/#install .. rubric:: Footnotes diff --git a/doc/source/conf.py b/doc/source/conf.py index 7667ab9..1d58a9d 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -14,18 +14,19 @@ import os import sys +from jenkins.version import version_info as python_jenkins_version # 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 # 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('../../jenkins')) # -- General configuration ---------------------------------------------------- # 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 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. @@ -44,7 +45,7 @@ templates_path = ['_templates'] source_suffix = '.rst' # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' @@ -58,44 +59,43 @@ copyright = u'2010, Willow Garage' # built documents. # # Version info -from jenkins.version import version_info as python_jenkins_version release = python_jenkins_version.version_string_with_vcs() # The short X.Y version. version = python_jenkins_version.canonical_version_string() # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # 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 # directories to ignore when looking for source files. exclude_patterns = ['_build'] # 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. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # -- 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 # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # 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 # " v documentation". -#html_title = None +# html_title = None # 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 # 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 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # 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, # 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, # 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 # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # 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 # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # 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. -#html_split_index = False +# html_split_index = False # 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. -#html_show_sphinx = True +# html_show_sphinx = 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 # contain a tag referring to it. The value of this option must be the # 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"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'PythonJenkinsdoc' @@ -181,10 +181,10 @@ htmlhelp_basename = 'PythonJenkinsdoc' # -- Options for LaTeX output ------------------------------------------------- # The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' +# latex_paper_size = 'letter' # 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 # (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 title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Additional stuff for the LaTeX preamble. -#latex_preamble = '' +# latex_preamble = '' # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output ------------------------------------------- diff --git a/jenkins/__init__.py b/jenkins/__init__.py index 5cb99ea..a027729 100755 --- a/jenkins/__init__.py +++ b/jenkins/__init__.py @@ -626,7 +626,7 @@ class Jenkins(object): >>> build_info = server.get_build_info('build_name', next_build_number) >>> 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'} - ''' + ''' # noqa: E501 folder_url, short_name = self._get_job_folder(name) try: response = self.jenkins_open(requests.Request( @@ -703,7 +703,7 @@ class Jenkins(object): >>> queue_info = server.get_queue_info() >>> 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} - ''' + ''' # noqa: E501 return json.loads(self.jenkins_open( requests.Request('GET', self._build_url(Q_INFO)) ))['items'] @@ -1540,7 +1540,8 @@ class Jenkins(object): :param remoteFS: Remote filesystem location to use, ``str`` :param labels: Labels to associate with node, ``str`` :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`` ''' if self.node_exists(name): diff --git a/setup.cfg b/setup.cfg index 97bd267..6f2c262 100644 --- a/setup.cfg +++ b/setup.cfg @@ -34,3 +34,8 @@ warnerrors = True all_files = 1 build-dir = doc/build source-dir = doc/source + +[flake8] +show-source = True +exclude = .venv,.tox,dist,build,*.egg +max-line-length = 120 diff --git a/test-requirements.txt b/test-requirements.txt index 30bb5f9..b3ec1af 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,13 +1,13 @@ cmd2!=0.8.3,<0.9.0;python_version<'3.0' # MIT cmd2!=0.8.3;python_version>='3.0' # MIT coverage>=3.6 -hacking>=0.5.6,<0.11 mock<1.1 unittest2 python-subunit requests-mock>=1.4.0 requests-kerberos -sphinx>=1.2,<1.3.0 +sphinx>=1.6.0 stestr>=2.0.0 testscenarios testtools +pre-commit diff --git a/tox.ini b/tox.ini index 27a201b..4b255e8 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] minversion = 1.6 skipsdist = True -envlist = py{34,27,35}, pep8, pypy +envlist = py{34,27,35}, linters, pypy [testenv] setenv = @@ -39,27 +39,25 @@ commands = coverage html -d cover 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] basepython = python3 -commands = flake8 +commands = + pre-commit run --all [testenv:docs] basepython = python3 -commands = python setup.py build_sphinx +commands = python setup.py build_sphinx -W [testenv:venv] basepython = python3 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] basepython = python3 # Do not install any requirements. We want this to be fast and work even if