{ "info": { "author": "Timo Stollenwerk | kitconcept GmbH", "author_email": "stollenwerk@kitconcept.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Buildout", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License (GPL)", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Build Tools" ], "description": ".. image:: https://img.shields.io/pypi/status/plone.recipe.codeanalysis.svg\n :target: https://pypi.python.org/pypi/plone.recipe.codeanalysis/\n :alt: Egg Status\n\n.. image:: https://img.shields.io/travis/plone/plone.recipe.codeanalysis/master.svg\n :target: http://travis-ci.org/plone/plone.recipe.codeanalysis\n :alt: Travis Build Status\n\n.. image:: https://img.shields.io/coveralls/plone/plone.recipe.codeanalysis/master.svg\n :target: https://coveralls.io/r/plone/plone.recipe.codeanalysis\n :alt: Test Coverage\n\n.. image:: https://img.shields.io/pypi/dm/plone.recipe.codeanalysis.svg\n :target: https://pypi.python.org/pypi/plone.recipe.codeanalysis/\n :alt: Downloads\n\n.. image:: https://img.shields.io/pypi/pyversions/plone.recipe.codeanalysis.svg\n :target: https://pypi.python.org/pypi/plone.recipe.codeanalysis/\n :alt: Python Versions\n\n.. image:: https://img.shields.io/pypi/v/plone.recipe.codeanalysis.svg\n :target: https://pypi.python.org/pypi/plone.recipe.codeanalysis/\n :alt: Latest Version\n\n.. image:: https://img.shields.io/pypi/l/plone.recipe.codeanalysis.svg\n :target: https://pypi.python.org/pypi/plone.recipe.codeanalysis/\n :alt: License\n\n.. contents::\n\nIntroduction\n============\n\n``plone.recipe.codeanalysis`` provides static code analysis for Buildout-based\nPython projects, including `flake8`_, `JSHint`_, `CSS Lint`_, and\nother code checks.\n\nThis buildout recipe creates a script to run the code analysis::\n\n bin/code-analysis\n\nBy default ``plone.recipe.codeanalysis`` also creates a git pre-commit hook, in\norder to run the code analysis automatically before each commit.\n\n``plone.recipe.codeanalysis`` comes with a Jenkins integration, that allows to\nuse the same code analysis settings on your local machine as well as on\nJenkins.\n\nIt also allows to run code analysis to any arbitrary folder::\n\n bin/code-analysis src/Products.CMFPlone\n\n\nInstallation\n============\n\nJust add a code-analysis section to your buildout.cfg:\n\n.. code-block:: ini\n\n [buildout]\n parts += code-analysis\n\n [code-analysis]\n recipe = plone.recipe.codeanalysis\n directory = ${buildout:directory}/src\n\nThe directory option is not required. Though, if you don't specify a directory\nthe code analysis will check every file in your buildout directory.\n\nThis configuration is helpful for working on already existing packages.\nIf you create a new package you might want to enable all checks.\nThis configuration looks like this:\n\n.. code-block:: ini\n\n [code-analysis]\n recipe = plone.recipe.codeanalysis[recommended]\n multiprocessing = True\n jenkins = False\n directory =\n ${buildout:directory}/src\n return-status-codes = True\n pre-commit-hook = True\n # JS\n jshint = True\n jshint-bin = ${buildout:bin-directory}/jshint\n jshint-suppress-warnings = False\n jscs = True\n jscs-bin = ${buildout:bin-directory}/jscs\n jscs-exclude =\n ${buildout:directory}/dev/bower_components\n ${buildout:directory}/node_modules\n # CSS\n csslint = True\n csslint-bin = ${buildout:bin-directory}/csslint\n # ZPT\n zptlint = True\n zptlint-bin = ${buildout:bin-directory}/zptlint\n # Chameleon uses XML (there is no chameleon-lint-bin, it uses lxml)\n chameleon-lint = False\n # XML (there is no xmllint-bin, it uses lxml)\n xmllint = True\n # scss-lint\n scsslint = True\n scsslint-bin = ${buildout:bin-directory}/scss-lint\n # TS\n tslint = True\n tslint-bin = ${buildout:directory}/bin/tslint\n tslint-exclude = ${:jscs-exclude}\n # Conventions\n clean-lines = True\n clean-lines-exclude = ${:jscs-exclude}\n # dependency-checker\n dependencychecker = True\n dependencychecker-bin = ${buildout:directory}/bin/dependencychecker\n # i18n\n find-untranslated = True\n i18ndude-bin = ${buildout:bin-directory}/i18ndude\n flake8-exclude = bootstrap.py,bootstrap-buildout.py,docs,*.egg,*.cpy,*.vpy,overrides\n\n [node]\n recipe = gp.recipe.node\n npms = csslint jshint jscs tslint\n scripts = csslint jshint jscs tslint\n\n``[recommended]`` extra\n=======================\n\nThis extra enables a host of flake8 plugins.\nThey are mostly coding `Plone's styleguide`_ (specially the Python section).\n\nThese are the current extras installed:\n\n- flake8-blind-except: warns about catching any exception, i.e ``except:``\n- flake8-coding: warns about python files with missing coding header\n- flake8-debugger: warns about debug statements found in code (like pdb...)\n- flake8-deprecated: warns about deprecated method calls\n- flake8-isort: warns about imports not sorted properly (note that an `extra configuration`_ is needed)\n- flake8-pep3101: warns about old-style formatting, i.e ``'format a %s' % string``\n- flake8-plone-api: warns about code that could be replaced by plone.api calls (note that this is forbidden for Plone core packages)\n- flake8-plone-hasattr: warns about using ``hasattr`` as it shallows exceptions\n- flake8-print: warns about ``print`` being used\n- flake8-quotes: warns about using double quotes (plone style guide says single quotes)\n- flake8-string-format: warns about errors on string formatting\n- flake8-todo: warns if there are ``TODO``, ``XXX`` found on the code\n- flake8-commas: warns if the last element on a method call, list or dictionary does not end with a comma\n\n\nGit hooks\n=========\n\n- pre-commit-hook\n- pre-commit-return-status-codes\n- pre-push-hook\n- pre-push-return-status-codes\n\nYou can choose to activate git ``pre-commit-hook`` and/or ``pre-push-hook`` hooks.\nYou can make these hooks blocking (aborting) by setting ``return-status-codes``\nto 'True'. You can tune the return code behavior differently from the default\nfor each hook, using ``pre-commit-return-status-codes`` and\n``pre-push-return-status-codes``.\n\nWhat works best for you is a matter of taste, and code base.\n\nIf you want to ensure that your working area is always clean on each commit,\nand you'd like to abort the commit if anything untowards is found, you can\nconfigure::\n\n [code-analysis]\n return-status-codes = True\n pre-commit-hook = True\n\nIf you're working in a large code base, which takes a long time to\nparse, and your workflow is to use many small commits, you may be\nannoyed by the pre-commit delay. Or maybe you like to check in parts\nof your work, while having other files hanging around in your working\ntree which aren't cleaned up yet.\n\nIn that case you may want to disable pre-commit checks, and have a blocking\npre-push check instead::\n\n [code-analysis]\n return-status-codes = True\n pre-commit-hook = False\n pre-push-hook = True\n\nOr maybe you want ``code-analysis`` by default to run unblocking, to\nplease Jenkins, but still want to have blocking checks on both pre-commit\nand pre-push? Can do::\n\n [code-analysis]\n return-status-codes = False\n pre-commit-hook = True\n pre-commit-return-status-codes = True\n pre-push-hook = True\n pre-push-return-status-codes = True\n\nYeah I know, it's a contrived example, but it illustrates the relevant options.\n\nConfiguration ``overrides``\n===========================\n\nThe options documented above configure code-analysis at the project level.\nSometimes developers may want to deviate from the project-level settings locally,\nfor example to make the git pre-commit hook block on violations, even when\nthe project-wide setting is to not abort the commit on violations.\n\nIf for example the project ``buildout.cfg`` reads::\n\n [code-analysis]\n overrides = code-analysis-overrides-acmecorp\n return-status-codes = False\n pre-commit-hook = True\n\nBut as a developer I'd rather have a blocking pre-push instead of a nonblocking\npre-commit, I can configure overrides in my\n``.buildout/default.cfg`` configuration as follows::\n\n [code-analysis-overrides-acmecorp]\n return-status-codes = True\n pre-commit-hook = False\n pre-push-hook = True\n\nThis is especially handy to let users choose themselves whether they want\na pre-commit-hook or a pre-push-hook, and whether they want\nto block on violations (so they don't have to amend commits) or whether they\nwant non-blocking checks (so they can have invalid files in their\nworking tree outside the commited c.q. pushed set of files). YMMV.\n\nNote that if a project does not configure ``overrides`` at the project\nlevel, you can as a dev still configure that in ``.buildout/default.cfg``::\n\n [code-analysis]\n overrides = code-analysis-overrides\n\n [code-analysis-overrides]\n return-status-codes = True\n\nThe recommended policy is to define an overrides name per project, so devs\ncan tune their overrides per project. Repo-specific override names only\nmake sense if the repo is really different (say much bigger) than typical.\nPer-project override names would show up in a devs ``.buildout/default.cfg``\nfor example as follows::\n\n [code-analysis-overrides-plone]\n return-status-codes = True\n pre-commit-hook = True\n pre-push-hook = True\n\n [code-analysis-overrides-grok]\n <= code-analysis-overrides-plone\n\n [code-analysis-overrides-acmecorp]\n return-status-codes = True\n pre-commit-hook = False\n pre-push-hook = True\n\n\nFor projects that really really want to NOT offer this option to their\ndevelopers, there's the simple solution of blocking overrides in the\nproject ``buildout.cfg``::\n\n [code-analysis]\n overrides = False\n\nIt's recommended to actually talk to your fellow devs about which\noverrides are not acceptable, instead of taking this nuclear option.\nIf a developer disagrees with the set of flake8 extensions you're validating\nwith, that's really a social issue, not something that can be solved in code.\n\nA more suble way of controlling what local reconfigurations a dev is\nallowed to perform is to configure the ``overrides-allowed`` whitelist\nat the project level::\n\n [code-analysis]\n overrides-allowed = multiprocessing\n return-status-codes\n pre-commit-hook\n pre-commit-return-status-codes\n pre-push-hook\n pre-push-return-status-codes\n\nAs a result, only the override options listed here will be taken from\nthe developer's local configuration, all other options will be taken\nfrom the project buildout.cfg. Listing an empty ``overrides-allowed``\noption allows all options to be overridden.\n\nBut of course, all of this runs on the developer's machine...\n\nJenkins Installation\n====================\n\nplone.recipe.codeanalysis provides a Jenkins setting that allows to run it on a Jenkins CI server and to process and integrate the output via the\n`Jenkins Violations plugin`_.\n\nUsually you don't want the recipe to create Jenkins output files on your\nlocal machine. Therefore it makes sense to enable the Jenkins output only\non the CI machine. To do so, just create a jenkins.cfg that extends and\noverrides the default buildout file (that includes the other settings):\n\n.. code-block:: ini\n\n [buildout]\n parts += code-analysis\n\n [code-analysis]\n recipe = plone.recipe.codeanalysis\n jenkins = True\n\nThe Jenkins job itself should run ``bin/code-analysis``::\n\n python bootstrap.py -c jenkins.cfg\n bin/buildout -c jenkins.cfg\n bin/jenkins-test --all\n bin/code-analysis\n\nThe `Jenkins Violations plugin`_ needs to be configured to read the output\nfiles generated by this configuration.\n\npep8 (to read the flake8 output)::\n\n **/parts/code-analysis/flake8.log\n\ncsslint::\n\n **/parts/code-analysis/csslint.xml\n\ncsslint::\n\n **/parts/code-analysis/scsslint.xml\n\njslint (to read the jshint output)::\n\n **/parts/code-analysis/jshint.xml\n\ncheckstyle (to read the jscs output)::\n\n **/parts/code-analysis/jscs.xml\n\nFilesystem output\n=================\n\nIf jenkins is set to False, you can still store the output on the filesystem by setting ``flake8-filesystem = True``.\nThis is ignored if jenkins is set to True.\n\noutput::\n\n **/parts/code-analysis/flake8.txt\n\nLinks\n=====\n\nCode repository:\n\n https://github.com/plone/plone.recipe.codeanalysis\n\nContinuous Integration:\n\n https://travis-ci.org/plone/plone.recipe.codeanalysis\n\nIssue Tracker:\n\n https://github.com/plone/plone.recipe.codeanalysis/issues\n\n\nSupported options\n=================\n\nIf you need to bypass checks for some reasons on a specific line you may use\n``# noqa`` in Python or ``// noqa`` in Javascript files. This works for most\nof our checks.\n\nThe recipe supports the following options:\n\n**directory**\n Directory that is subject to the code analysis.\n\n**return-status-codes**\n If set to True, the ``bin/code-analysis`` script returns an error code\n that Continuous Integration servers (like Travis CI) can use to fail or\n pass a job, based on the code analysis output. Note that Jenkins usually\n does not need this option (this is better handled by the Jenkins\n Violations plugin). Note that this option does not have any effect on the\n other code analysis scripts. Default is ``False``.\n\n Note that this option can be overridden command-line by using the\n ``--return-status-codes`` or ``--no-return-status-codes`` command-line\n options.\n\n Note also that the pre-commit and post-commit hooks can be tuned to\n have a different status code behavior, if wanted, see below.\n\n**pre-commit-hook**\n If set to True, a git pre-commit hook is installed that runs the code\n analysis before each commit. Default is ``True``.\n\n**pre-commit-hook-return-status-codes**\n If set to True, if a pre-commit hook is run it will abort the commit\n if violations are found. Default value is the value configured for\n ``return-status-codes``.\n\n**pre-push-hook**\n If set to True, a git pre-push hook is installed that runs the code\n analysis before it gets pushed to a remote. Default is ``False``.\n\n**pre-push-hook-return-status-codes**\n If set to True, if a pre-push hook is run it will abort the push\n if violations are found. Default value is the value configured for\n ``return-status-codes``.\n\n Note that in general it will be advisable to set this option to ``True``\n so you will avoid pushing broken work. YMMV.\n\n**multiprocessing**\n If set to ``True``, ``code-analysis`` will fork multiple processes and run\n all linters in parallel. This will dramatically increase speed on a\n multi-core system, specially when using ``code-analysis`` as pre-commit\n hook. Default is ``False``.\n\n**jenkins**\n If set to True, the code analysis steps will\n write output files that can be processed by the\n `Jenkins Violations plugin`_. Default is ``False``.\n\n**flake8-filesystem**\n If set to True, the flake8 code analysis step will\n write an output file. Ignored if jenkins is True. Default is ``False``.\n\n**flake8**\n If set to True, run Flake8 code analysis. Default is ``True``.\n\n**flake8-extensions**\n Flake8 now takes advantage of ``flake8`` extension system. Default is none.\n If ``flake8`` is set to False, this option will be ignored. Example to\n supercharge with some extensions:\n\n.. code-block:: ini\n\n [code-analysis]\n recipe = plone.recipe.codeanalysis\n flake8 = True\n flake8-extensions =\n flake8-blind-except\n flake8-coding\n flake8-debugger\n flake8-quotes\n pep8-naming\n\n\n**flake8 Settings**\n\n Flake8 uses the following files to look for settings:\n\n - setup.cfg (recommended for Plone)\n - tox.ini\n - .flake8\n\n.. code-block:: ini\n\n [flake8]\n exclude = bootstrap.py,boostrap-buildout.py,docs,*.egg\n max-complexity = 10\n max-line-length = 79\n\nLook at `Flake8 documentation`_\n and it's plugins to see which options are available.\n\n**check-manifest**\n If set to True, ``check-manifest`` will be run to check you MANIFEST.in\n file. Default is ``False``.\n\n**check-manifest-directory**\n Default is ``.`` which means check the current package where you included\n code-analysis in buildout.\n\n EXPERIMENTAL: For project buildouts where you use several source\n packages you may want to enter multiple directories or use\n ``${buildout:develop}`` to include all your development packages.\n\n**dependencychecker**\n If set to True, import statement analysis is run and verified\n against declared dependencies in setup.py. Default is ``False``.\n\n**dependencychecker-bin**\n Set the path to a custom version of ``dependencychecker``.\n\n**importchecker**\n If set to True, import statement analysis is run and unused\n imports are reported. Default is ``False``.\n\n**importchecker-bin**\n Set the path to a custom version of ``importchecker``.\n\n**jshint**\n If set to True, jshint code analysis is run. Default is ``False``. Note\n that plone.recipe.codeanalysis requires jshint >= 1.0.\n\n**jshint-bin**\n JSHint executable. Default is ``jshint``. If you have JSHint installed on\n your system and in your path, there is nothing to do. To install JSHint in\n your buildout, use the following:\n\n.. code-block:: ini\n\n [jshint]\n recipe = gp.recipe.node\n npms = jshint\n scripts = jshint\n\nset jshint-bin to ``${buildout:bin-directory}/jshint``.\n\n**jshint-exclude**\n Allows you to specify directories which you don't want to be linted.\n Default is none. If you want JSHint to skip some files you can list them\n in a file named ``.jshintignore``. See `JSHint documentation`_ for more\n details.\n\n**jshint-suppress-warnings**\n By default warnings of jshint are suppressed and not shown. You may disable\n this by setting to False, default is ``True`` for backward compatibility\n reasons.\n\n**jscs**\n If set to True, jscs code analysis is run. Default is ``False``.\n\n JavaScript Code Style options should be configured using a ``.jscs.json``\n file. You should align your javascript code to the next generation of\n Plone's javascript framework Mockup_ and take it's ``.jscs.json`` file\n which is available here:\n https://github.com/plone/mockup/blob/master/mockup/.jscs.json\n\n All configuration options are documented on the `jscs website`_.\n\n**jscs-bin**\n Set the path to a custom version of JSCS, e.g. ``/usr/local/bin/jscs``.\n\n If you have Javascript Code Style Checker installed in your system and\n path, you have nothing to do. To install with Buildout, add the following\n section to your buildout and set jscs-bin to\n ``{buildout:bin-directory}/jscs``:\n\n.. code-block:: ini\n\n [jscs]\n recipe = gp.recipe.node\n npms = jscs\n scripts = jscs\n\n**jscs-exclude**\n Allows you to specify directories and/or files which you don't want to be\n checked. Default is none. Note that these directories have to be given in\n absolute paths, use ``${buildout:directory}/foo/bar/static/js-3rd-party``\n for example.\n\n**csslint**\n If set to True, CSS Lint code analysis is run. Default is ``False``.\n\n CSS Lint options should be configured using a ``.csslintrc`` file. A\n typical ``.csslintrc`` file will look like this::\n\n --format=compact\n --quiet\n --ignore=adjoining-classes,floats,font-faces,font-sizes,ids,qualified-headings,unique-headings\n --exclude-list=foo/bar/static/third-party.css\n\n This typical configuration includes a list of CSS rules that will be\n ignored as they are `considered useless`_.\n\n See `CSS Lint documentation`_ and `CSS Lint command-line interface`_ for a\n detailed list and description of the rules.\n\n**csslint-bin**\n Set the path to a custom version of CSS Lint, e.g. ``/usr/local/bin/csslint``.\n\n If you have CSS Lint installed in your system and path, you have nothing\n to do. To install CSS Lint with Buildout, add the following section to\n your buildout and set csslint-bin to\n ``{buildout:bin-directory}/csslint``:\n\n.. code-block:: ini\n\n [csslint]\n recipe = gp.recipe.node\n npms = csslint\n scripts = csslint\n\n**csslint-exclude**\n Allows you to specify directories and/or files which you don't want to be\n checked. Default is none.\n\n**chameleon-lint**\n If set to True, ChamleonLint code analysis is run. Default is ``False``.\n\n ChameleonLint uses ``lxml`` for xml parsing. There is no ``chameleon-lint-bin``.\n\n Note that you will want to activate either ``chameleon-lint`` or ``zpt-lint``,\n not both, since they will apply to the same set of file extensions (``.pt``,\n ``.cpt``, ``.zpt``). The ``zpt-lint`` parser uses the actual TAL expression engine\n to validate templates, and this will generally choke on the Chameleon extensions.\n The ``chameleon-lint`` parser on the other hand just checks that the template is\n valid XML basically.\n\n**xmllint**\n If set to True, XMLLint code analysis is run. Default is ``False``.\n\n XMLLint uses ``lxml`` for xml parsing. There is no ``xmllint-bin``.\n\n**clean-lines**\n If set to True, **any file** containing trailing spaces or tabs anywhere\n on the lines will cause a warning. Default is ``False``.\n\n**clean-lines-exclude**\n Allows you to specify directories and/or files which you don't want to be\n checked. Default is none.\n\ni18ndude, scsslint and zptlint support\n--------------------------------------\n\nTo reduce the number of Zope/Plone direct dependencies, plone.recipe.codeanalysis no longer depends on `i18ndude`_ nor `SCSS Lint`_ nor `zptlint`_;\nin order to use the following options you have to install them on your\nsystem, see ``buildout.cfg`` for an example install.\n\n**find-untranslated**\n If set to True, scan Zope templates to find untranslated strings.\n Default is ``False``.\n To use this you will need to set the ``i18ndude-bin`` option.\n\n**find-untranslated-exclude**\n Allows you to specify directories and/or files which you don't want to be\n checked. Default is none.\n\n**find-untranslated-no-summary**\n The report will contain only the errors for each file.\n Default is ``False``.\n However, summaries will also be suppressed when ``jenkins`` is set to ``True``.\n\n**i18ndude-bin**\n Set the path to a custom version of `i18ndude`_.\n Default is none.\n\n**scsslint**\n If set to True, `SCSS Lint`_ code analysis is run. Default is ``True``.\n\n**scsslint-bin**\n Set the path to a custom version of `SCSS Lint`_.\n Default is none.\n\n Note that you'll typically install the gem ``scss_lint`` (with underscore)\n to get a bin file ``scss-lint`` (with a dash).\n\n If you have SCSS Lint installed in your system and path, you have nothing\n to do. To install SCSS Lint with Buildout, add the following section to\n your buildout and set scsslint-bin to\n ``{buildout:bin-directory}/scss-lint``:\n\n.. code-block:: ini\n\n [rubygems]\n recipe = rubygemsrecipe\n gems = scss_lint\n\n Please note that due to some buildout weirdness this will break buildout\n on the first buildout run; a second buildout run will complete just fine.\n\n**scsslint-configuration**\n\n SCSS Lint options can be configured, see `SCSS Lint`_ README.\n\n**zptlint**\n If set to True, zptlint code analysis is run.\n Default is ``False``.\n To use this you will need to set the ``zptlint-bin`` option.\n\n Note that you will want to use either ``zptlint`` or ``chameleon-lint``, not both.\n\n**zptlint-bin**\n Set the path to a custom version of `zptlint`_.\n Default is none.\n\n**zptlint-exclude**\n Allows you to specify directories and/or files which you don't want to be\n checked. Default is none.\n\nSelf-tests for these extra linters are disabled by default.\nTo run a ``plone.recipe.codeanalysis`` self-test that covers these extra linters::\n\n TEST_ALL=true bin/test\n\nKnown Issues\n============\n\nJSHint \"ERROR: Unknown option --verbose\"::\n\n JSHint [ OK ]\n ERROR: Unknown option --verbose\n\nUpgrade JSHint to latest version (>= 1.0) to fix this issue, e.g.::\n\n $ sudo npm install -g jshint\n\n\nJSHint \"ERROR: Unknown option --exclude\"::\n\n JSHint [ OK ]\n ERROR: Unknown option --exclude\n\nUpgrade JSHint to latest version (>= 2.1.6) to fix this issue, e.g.::\n\n $ sudo npm install -g jshint\n\n\nRubygems woes::\n\n Installing rubygems.\n rubygems: Extracting package to /app/plone.recipe.codeanalysis/parts\n ERROR: While executing gem ... (Errno::EACCES)\n Permission denied @ rb_sysopen - /usr/lib/ruby/gems/2.3.0/specifications/default/bundler-1.16.1.gemspec\n rubygems: b''\n rubygems: Command failed with exit code 1: ['ruby', 'setup.rb', 'all', '--prefix=/app/plone.recipe.codeanalysis/parts/rubygems', '--no-rdoc', '--no-ri']\n While:\n Installing rubygems.\n Error: System error\n\nSolution: run buildout again. Really.\n\nTests fail::\n\n Traceback (most recent call last):\n File \"/app/plone.recipe.codeanalysis/plone/recipe/codeanalysis/__init__.py\", line 18, in \n import zc.buildout\n ModuleNotFoundError: No module named 'zc.buildout'\n\nThis is likely caused by https://github.com/pypa/pip/issues/4695.\nSolution: run::\n\n bin/easy_install -U zc.buildout==2.11.0\n\nbefore running ``bin/buildout``.\n\n\n.. _`considered useless`: http://2002-2012.mattwilcox.net/archive/entry/id/1054/\n.. _`CSS Lint documentation`: https://github.com/CSSLint/csslint/wiki/Rules\n.. _`CSS Lint command-line interface`: https://github.com/CSSLint/csslint/wiki/Command-line-interface\n.. _`CSS Lint`: http://csslint.net/\n.. _`SCSS Lint`: https://github.com/brigade/scss-lint\n.. _`Flake8 documentation`: http://flake8.readthedocs.org/en/latest/warnings.html#error-codes\n.. _`Jenkins Violations plugin`: https://wiki.jenkins-ci.org/display/JENKINS/Violations\n.. _`flake8`: https://pypi.python.org/pypi/flake8\n.. _`JSHint documentation`: http://jshint.com/docs/\n.. _`JSHint`: http://www.jshint.com/\n.. _`PEP 3101 (Advanced String Formatting)`: http://www.python.org/dev/peps/pep-3101/\n.. _`plone.api conventions`: http://ploneapi.readthedocs.org/en/latest/contribute/conventions.html#about-imports\n.. _`zptlint`: https://pypi.python.org/pypi/spirit.zptlint\n.. _`i18ndude`: https://pypi.python.org/pypi/i18ndude\n.. _`Unit testing framework documentation`: http://docs.python.org/2/library/unittest.html#deprecated-aliases\n.. _`Mockup`: https://github.com/plone/mockup\n.. _`jscs website`: https://www.npmjs.org/package/jscs\n.. _`Plone's styleguide`: http://docs.plone.org/develop/styleguide/\n.. _`extra configuration`: https://raw.githubusercontent.com/plone/plone.recipe.codeanalysis/master/.isort.cfg\n\n\nExample usage\n=============\n\nMinimal buildout::\n\n >>> write('buildout.cfg',\n ... \"\"\"\n ... [buildout]\n ... parts = code-analysis\n ...\n ... [code-analysis]\n ... recipe = plone.recipe.codeanalysis\n ... directory = %(directory)s\n ... \"\"\" % {\n ... 'directory' : '${buildout:directory}/plone/recipe/codeanalysis',\n ... })\n\nRunning the buildout gives us a 'code-analysis' script that runs the entire\ncode analysis::\n\n >>> buildout_output_lower = system(buildout).lower()\n >>> '/sample-buildout/bin/code-analysis' in buildout_output_lower\n True\n\nIt is also possible to run single code analysis scripts::\n\n >>> '/sample-buildout/bin/code-analysis-flake8' in buildout_output_lower\n True\n >>> '/sample-buildout/bin/code-analysis-jshint' in buildout_output_lower\n True\n\nFlake 8 is installed by the buildout script, there is no need to install it on\nthe system::\n\n >>> '/sample-buildout/bin/flake8' in buildout_output_lower\n True\n\n\nPre-commit hook\n===============\n\nIf we have a git repository::\n\n >>> import subprocess\n >>> subprocess.call(['mkdir', '-p', '.git/hooks'])\n 0\n\nAnd run buildout again::\n\n >>> buildout_output_lower = system(buildout).lower()\n\nThen the git pre-commit hook is installed::\n\n >>> 'installed git pre-commit hook.' in buildout_output_lower\n True\n\n\nContributors\n============\n\n- Timo Stollenwerk, Original Author\n- Gil Forcada\n- H\u00e9ctor Velarde\n- Ramiro Batista da Luz\n- Daniel Widerin\n- Michael Davis\n\n\nChange history\n==============\n\n3.0.1 (2018-06-27)\n------------------\n\n- Fix PyPi readme page.\n [timo]\n\n\n3.0.0 (2018-06-27)\n------------------\n\n- Re-release of 3.0.0a (brown bag release).\n [timo]\n\n\n3.0.0a (2018-06-15)\n-------------------\n\n- Removed flake8 default settings in favor of using setug.cfg [iham]\n\n- Add XMLLint for .xml .xsl .zcml files. [janjaapdriessen]\n\n- Add scss-lint for sass files. [janjaapdriessen]\n\n- Add a XML linter for Chameleon template files.\n [janjaapdriessen]\n\n- Work around Travis bootstrapping and coverage failures caused by\n https://github.com/buildout/buildout/issues/434 and\n https://github.com/pypa/pip/issues/4695, which obscure that the tests\n are actually green. Mark python3 builds without extras as critical again.\n Note that this requires a double-buildout sequence to get the ``scss-lint``\n gem properly installed...\n Fixes #214.\n [gyst]\n\n- Revive XMLLint, and SCSSLint work by janjaapdriessen.\n Add tests and documentation.\n [gyst]\n\n- Replace unmaintained ``zptlint`` upstream by ``spirit.zptlint``.\n [gyst]\n\n- Add tests for Chameleon Linter and fixup the linter.\n Fixes #180, sort of; the validation is much less strict than the ZPTLint one.\n [gyst]\n\n- Pull in ``i18ndude`` python3 fixes and mark EXTRAS tests as critical.\n [gyst]\n\n- Update ``z3c.dependencychecker`` dependency and provide an analyser for it.\n No tests for this since it would require a full egg fixture.\n Fixes #67.\n [gyst]\n\n- Add ``importchecker`` linter.\n Fixes #67.\n [gyst]\n\n- Post-merge cleanup of source dependencies for the python3 work.\n [gyst]\n\n- Introduce ``overrides`` to support individual developer preferences.\n [gyst]\n\n- Introduce ``pre-push-hook`` and allow command-line and githook\n deviation from default ``return-status-codes``.\n [gyst]\n\n- Remove trailing dot from Jenkins output, to ease copy-pasting filenames.\n [janwijbrand]\n\n- Bring our own dogfood linter config and version pins in sync with coredev qa.cfg.\n [gyst]\n\n\n2.3 (2018-01-18)\n----------------\n\n- Install isort script if flake8-isort is installed as well.\n [gforcada]\n\n- Add a new recommended flake8 plugin:\n `flake8-commas `_.\n [gforcada]\n\n- Fix Continuous Integration (Travis) by using pip to install setuptools and zc.buildout.\n [gforcada]\n\n- Run tests only once on CI.\n [gforcada]\n\n- Remove bootstrap-buildout.py as it is no longer used.\n [gforcada]\n\n- Fix code analysis errors.\n [gforcada]\n\n- Fix travis (newer setuptools and zc.buildout needed)\n [gforcada]\n\n- Check Python 3.5 and 3.6 in travis as well (although they fail currently).\n [gforcada]\n\n- Add 'find-untranslated-no-summary' option for i18ndude.\n [tmassman]\n\n2.2 (2016-02-20)\n----------------\n\n- Fix issue where commit hook did not work on NixOS\n (fixed to use ``/usr/bin/env bash`` instead ``/bin/bash``).\n [datakurre]\n\n- Allow to pass a folder where to run code analysis against.\n [gforcada]\n\n- Increase minimum requirement of flake8. Older versions could make\n checks with exceptions in plugins as passed.\n [do3cc]\n\n2.1 (2015-09-21)\n----------------\n\n- Remove debug statements checker,\n `flake8-debugger `_,\n `flake8-print `_\n and jshint can do the same job.\n [gforcada]\n\n- Removed pep3101 checker,\n `flake8-pep3101 `_\n works exactly the same.\n [gforcada]\n\n- Remove deprecated aliases checker,\n `flake8-deprecated `_\n does the same job.\n [gforcada]\n\n- Remove hasattr checker,\n `flake8-plone-hasattr `_\n does the same job.\n [gforcada]\n\n- Add a ``[recommended]`` extra to install a set of flake8 plugins,\n some of them where part of p.r.codeanalysis up until this release.\n [gforcada]\n\n- Remove leftovers from utf-8 checker removal.\n [gforcada]\n\n- Remove imports checker,\n `flake8-isort `_\n does the same job.\n [tisto] [gforcada]\n\n- Fix typo on test that prevented ipdb imports from being found.\n [hvelarde]\n\n2.0.2 (2015-09-03)\n------------------\n\n- Less false positives for pep3101.\n [do3cc]\n\n- Add ``--jobs=1`` to flake8 if ``multiprocessing`` is set to ``False``.\n [saily]\n\n- Fix #151 by not instantiating ``Lock`` and ``Value`` if ``multiprocessing``\n was set to ``False``.\n [saily]\n\n\n2.0.1 (2015-09-02)\n------------------\n\n- synchronize :-)\n [do3cc]\n Fix multiprocessing bug. Shared state is hard to\n\n- Change pep3101 logic. No more false positives on log\n strings.\n [do3cc]\n\n- Clean tests output.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/122\n [gforcada]\n\n\n2.0 (2015-08-07)\n----------------\n\n- Improve split_lines from analyser which makes exclude statements with more\n than one directory to be ignored with ``zc.buildout 1.7.1``.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/129\n [gil-cano]\n\n- Allow passing any option to flake8 or its plugins.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/131\n [gforcada]\n\n- Create .git/hooks folder if it doesn't exist.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/124\n [gforcada]\n\n- Compile all regexes on initialization to not have to compile them\n at every single use, it should make code analysis faster.\n [gforcada]\n\n2.0b1 (2015-05-03)\n------------------\n\n- Allow usage of wildcards in exclude statements.\n [saily]\n\n- Add ``check-manifest`` as new dependency and a basic check.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/69\n [saily]\n\n- Add a new option to disable ``jshint`` warning suppression.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/94\n [saily]\n\n- If an executable could not be found the code-analysis always failed. We've\n changed this behaviour to return True and succeed the code-analysis.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/71\n [saily]\n\n- Exclude paths directly in ``find`` unix command which speeds up again a lot.\n [saily]\n\n- Exclude empty strings in ``self.extensions`` which broke install with\n ``zc.buildout 1.7.1``.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/115\n [saily]\n\n- Add check for relative imports.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/44\n [saily]\n\n\n2.0a2 (2015-04-30)\n------------------\n\n- Replace manual comparisons of buildout options to ``False`` with a\n ``bool_option`` method.\n [saily]\n\n- Removed some plugins and replaced them with ``flake8`` plugins. Please\n not the API change in buildout. Following options have been removed:\n\n - **utf8-headers** has been removed, replace it with ``flake8-coding`` if\n needed.\n - **utf8-headers-exclude**\n - **prefer-single-quotes** has been removed, replace it with\n ``flake8-quotes``.\n - **prefer-single-quotes-exclude**\n - **debug-statements** has some reduced functionality, because python\n debugger checks should be included using ``flake8-debugger`` extension which\n also checks for ``ipdb``.\n\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/112\n [saily]\n\n- Add missing tests for deprecated_aliases parser.\n [saily]\n\n- Add new double quotes parser and add test for it. It now also supports\n # noqa statments and nested quotes.\n [saily]\n\n\n2.0a1 (2015-04-27)\n------------------\n\n- Added multiprocessing. This will dramatically increase speed on large\n packages when using pre-commit hooks.\n [saily]\n\n- Return correct exit codes for console-scripts.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/66\n [saily]\n\n- Refactor whole linters framework to use OO design patterns, inherit from\n ``Analyser`` abstract base class.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/62\n [saily]\n\n- Add bootstrap-buildout.py to flake8-exclude default. zc.buildout > 2 uses\n bootstrap-buildout.py instead of bootstrap.py.\n [timo]\n\n\n1.1 (2014-12-04)\n----------------\n\n- Add a check to look for hasattr() calls, which are considered bad practice.\n [gforcada, jensens]\n\n- Add option to store flake8 output if jenkins is False\n [Michael Davis]\n\n- Fix find_files from utils to find files, not directories\n [do3cc]\n\n\n1.0 (2014-12-04)\n----------------\n\n- Nothing changed since 1.0rc1.\n\n\n1.0rc1 (2014-06-18)\n-------------------\n\n- Return a string to avoid TypeError when no file was checked with ``jscs``.\n [saily]\n\n- Check import sorting in ``code_analysis_imports`` and add tests for\n clean and sorted imports.\n [saily]\n\n- Refactor ``code_analysis_clean_lines`` to use a new method to retrieve\n files and avoid too complex violation.\n [saily]\n\n\n1.0b8 (2014-06-05)\n------------------\n\n- Add ``clean-lines-exclude`` support and updated README.\n [saily]\n\n- Added tests for clean-lines checks.\n [saily]\n\n- Use indices for format() to support Python 2.6.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/77\n [timo]\n\n\n1.0b7 (2014-05-04)\n------------------\n\n- Add Javascript Code Style Checker ``jscs`` support.\n [saily]\n\n- Remove hard dependency on i18ndude and zptlint; this will reduce the number\n of Zope/Plone direct dependencies to make life happier to people using\n Pyramid and other web Python-based development frameworks.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/53\n [hvelarde]\n\n- Do not print out jshint and csslint output for Jenkins. Those files can\n become quite large.\n [timo]\n\n\n1.0b6 (2013-10-16)\n------------------\n\n- Remove progress bullets from flake8 check.\n [timo]\n\n- Improve the way to handle an exception if the command used in popen does\n not exist.\n [flohcim]\n\n\n1.0b5 (2013-10-08)\n------------------\n\n- Fix code analysis method by making it call each check only if the option\n is activated.\n [flohcim]\n\n- Keep backward compatibility with 'string-formatting' option.\n [hvelarde]\n\n- Rename 'deprecated-alias' to 'deprecated-aliases' and keep backward\n compatibility.\n [hvelarde]\n\n\n1.0b4 (2013-10-06)\n------------------\n\n- Implement Jenkins option on CSS Lint and JSHint.\n [hvelarde, ramiroluz]\n\n- Rename 'deprecated-methods' to 'deprecated-alias'.\n [gforcada]\n\n- Rename 'string-formatting' option to 'pep3101' to keep consistency.\n [hvelarde]\n\n- Remove unused CSSLINT_IGNORE remainings.\n [timo]\n\n- Simplify code analysis method and make it more readable.\n [timo]\n\n\n1.0b3 (2013-09-12)\n------------------\n\n- Add return-status-codes option that allows to fail a CI-build on Travis.\n [timo]\n\n- Make system wide installed csslint the default value for\n the csslint-bin option.\n [timo]\n\n\n1.0b2 (2013-09-11)\n------------------\n\n- Deprecate 'csslint-quiet', 'csslint-ignore' and 'csslint-exclude-list'\n options; CSS Lint must be configured now using a '.csslintrc' file.\n 'csslint-bin' option now defaults to ``bin/csslint``; documentation was\n updated (closes #20).\n [hvelarde]\n\n- Implement removal of pre-commit hook.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/21\n [hvelarde]\n\n\n1.0b1 (2013-08-12)\n------------------\n\n- Workaround over JSHint limitations to avoid displaying warning messages as\n errors.\n Fixes https://github.com/plone/plone.recipe.codeanalysis/issues/13\n [hvelarde]\n\n- Fix CSS Lint validation and implement new 'csslint-quiet' option.\n [hvelarde]\n\n- Fix package distribution.\n [hvelarde]\n\n\n1.0a1 (2013-08-04)\n------------------\n\n- Initial release.\n [timo]", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/plone/plone.recipe.codeanalysis/", "keywords": "", "license": "GPL version 2", "maintainer": "", "maintainer_email": "", "name": "plone.recipe.codeanalysis", "package_url": "https://pypi.org/project/plone.recipe.codeanalysis/", "platform": "", "project_url": "https://pypi.org/project/plone.recipe.codeanalysis/", "project_urls": { "Homepage": "http://github.com/plone/plone.recipe.codeanalysis/" }, "release_url": "https://pypi.org/project/plone.recipe.codeanalysis/3.0.1/", "requires_dist": null, "requires_python": "", "summary": "Static code analysis for buildout-based Python projects.", "version": "3.0.1" }, "last_serial": 4008667, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "8800412eb7e4386d4c655abfc3986079", "sha256": "06f2554cc25dae5d0eba7e27840bae14ba2ebaa27111066860fe5f8f4ff6e695" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0.zip", "has_sig": false, "md5_digest": "8800412eb7e4386d4c655abfc3986079", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 61762, "upload_time": "2014-12-04T14:23:15", "url": "https://files.pythonhosted.org/packages/12/da/22726cde7ca7e0c62a932edf774966967939e5807174a348fd6dd0bb20ee/plone.recipe.codeanalysis-1.0.zip" } ], "1.0a1": [ { "comment_text": "", "digests": { "md5": "99643a9b811caa33a6442abd8092a495", "sha256": "0b8a7748fe7ae13fe13011d334510e351cc1392f07d65e9a6e544bd09dc22029" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0a1.zip", "has_sig": false, "md5_digest": "99643a9b811caa33a6442abd8092a495", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17569, "upload_time": "2013-08-04T16:20:37", "url": "https://files.pythonhosted.org/packages/48/b8/ad7d9dafbf60ef5cf1a43e7c34fa4be5af9465ce9e35a83e03524aa7c930/plone.recipe.codeanalysis-1.0a1.zip" } ], "1.0b1": [ { "comment_text": "", "digests": { "md5": "8c97420e11ed47429cce8ed8bb4a301f", "sha256": "1a8416da99a7ca31e96347b488749c8ef2e6e03dec8be8c62e32f686464d9b68" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b1.zip", "has_sig": false, "md5_digest": "8c97420e11ed47429cce8ed8bb4a301f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29742, "upload_time": "2013-08-12T08:49:21", "url": "https://files.pythonhosted.org/packages/05/cd/a794c35b5dc381d96168c4bdcb5bcf902403151e023f61b58a05d2da9634/plone.recipe.codeanalysis-1.0b1.zip" } ], "1.0b2": [ { "comment_text": "", "digests": { "md5": "6d28f3e31c1e9253dc0cc540ec37bdca", "sha256": "8a9a3170ce6747f6def196247e2e2c58befcb1fb3afd31fa218ef0050897e5c5" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b2.zip", "has_sig": false, "md5_digest": "6d28f3e31c1e9253dc0cc540ec37bdca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39997, "upload_time": "2013-09-11T17:58:25", "url": "https://files.pythonhosted.org/packages/9d/7a/2b97d27aa49c564014a3edf60e864c31a258b3efe5613af9ab797599bce0/plone.recipe.codeanalysis-1.0b2.zip" } ], "1.0b3": [ { "comment_text": "", "digests": { "md5": "35c8d5cd4ebb8913a5e88801763ec77e", "sha256": "eef6b92f364993c91ec53b09b8c6c567aa2c5da18ed2369fbd0540d0619e0b48" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b3.zip", "has_sig": false, "md5_digest": "35c8d5cd4ebb8913a5e88801763ec77e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40993, "upload_time": "2013-09-12T18:33:29", "url": "https://files.pythonhosted.org/packages/09/a7/e0e4ae07c1383fc37bfecc0c3b412771e0cbefa0e48fbc4b40984c38cd54/plone.recipe.codeanalysis-1.0b3.zip" } ], "1.0b4": [ { "comment_text": "", "digests": { "md5": "9082cdfcc321a0c4af3a486f5cabb257", "sha256": "8bac2355fce54dd7444ca2b92c49244fb9d5aa801c0b88937bbb1314b1a2dea5" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b4.zip", "has_sig": false, "md5_digest": "9082cdfcc321a0c4af3a486f5cabb257", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40414, "upload_time": "2013-10-06T16:19:30", "url": "https://files.pythonhosted.org/packages/f0/f2/ffdf7acd7f94c31fecd28045cdd567092e3fd13ecff10b3db19601ad4d7a/plone.recipe.codeanalysis-1.0b4.zip" } ], "1.0b5": [ { "comment_text": "", "digests": { "md5": "af6fc772942ee1b7f262b4798349be78", "sha256": "c35d8ad510d35b2db1e760388015d2315fe40a5819a2dd488059ed3fd7b7fdee" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b5.zip", "has_sig": false, "md5_digest": "af6fc772942ee1b7f262b4798349be78", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43913, "upload_time": "2013-10-08T15:16:25", "url": "https://files.pythonhosted.org/packages/26/b6/6524fb92f3adf5e2b85cd47e3c7e099cac7d50e0f73457485e4c61133783/plone.recipe.codeanalysis-1.0b5.zip" } ], "1.0b6": [ { "comment_text": "", "digests": { "md5": "11d304282b36e8fce0b6d24a08bcfda7", "sha256": "419b9cc3e03c4d2680302c79097cbfccd3acce97e60c47bcd04aa170d721841a" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b6.zip", "has_sig": false, "md5_digest": "11d304282b36e8fce0b6d24a08bcfda7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 46530, "upload_time": "2013-10-16T16:17:23", "url": "https://files.pythonhosted.org/packages/77/01/4699bb4f51c639c98f64700206dfbae8f8100a33008fce95c5992626ffba/plone.recipe.codeanalysis-1.0b6.zip" } ], "1.0b7": [ { "comment_text": "", "digests": { "md5": "787863a172f0cd1a36e8105b32301559", "sha256": "affe78432ef34a74cac46752096584e61798bf15b7c77608c163683d6d8acd27" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b7.zip", "has_sig": false, "md5_digest": "787863a172f0cd1a36e8105b32301559", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 57792, "upload_time": "2014-05-04T07:11:42", "url": "https://files.pythonhosted.org/packages/37/3c/6787968f34e1d1d8ed17babf891889e45e81041d715d3417ee34cbd232da/plone.recipe.codeanalysis-1.0b7.zip" } ], "1.0b8": [ { "comment_text": "", "digests": { "md5": "7f3e8662af516d3864841564a55e4663", "sha256": "5280778867d4fe2a0bf710839ead7e42b4bb9c5fe21bf80bc59bb4e44881fbe0" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0b8.zip", "has_sig": false, "md5_digest": "7f3e8662af516d3864841564a55e4663", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 60075, "upload_time": "2014-06-05T07:41:19", "url": "https://files.pythonhosted.org/packages/f3/6b/c5f4a0ed4a281bda124cfc6f4843e5c124ac4cad2b11d4dff3cbf2915183/plone.recipe.codeanalysis-1.0b8.zip" } ], "1.0rc1": [ { "comment_text": "", "digests": { "md5": "ee1645cd3bb064d04bbb9e44e115421f", "sha256": "549f81262646750195be7f65507703c20a13a1c7948e81915b8d4b6cfb21ed5f" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.0rc1.zip", "has_sig": false, "md5_digest": "ee1645cd3bb064d04bbb9e44e115421f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 62008, "upload_time": "2014-06-18T11:21:37", "url": "https://files.pythonhosted.org/packages/ac/a3/6139a495e6c046379eca7839a7314bdad2668494a70960ffc6f2850e8c4f/plone.recipe.codeanalysis-1.0rc1.zip" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "444b2729da8ac9725cd7c67842ae9008", "sha256": "e83bfb17eb4b3e052477c98402cbed497fd04e6d83d444a59aa6979dbb130bd5" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.1.zip", "has_sig": false, "md5_digest": "444b2729da8ac9725cd7c67842ae9008", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 65769, "upload_time": "2014-12-04T14:33:34", "url": "https://files.pythonhosted.org/packages/d6/95/9f009f5a2133f75eb8fa372ccada19ec94be5faa9111e263eb27c0008f85/plone.recipe.codeanalysis-1.1.zip" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "eb221f725204cc6e777b9e8312d75920", "sha256": "563716598380ef9757d75cd8f73ba2ace8f058f307238e715524512bbd868874" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-1.1.1.zip", "has_sig": false, "md5_digest": "eb221f725204cc6e777b9e8312d75920", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 66136, "upload_time": "2015-02-13T06:36:12", "url": "https://files.pythonhosted.org/packages/f9/80/43d833012517e87c6fccfdff1a4c5a24cde8423e46f7c6bf627c03ddf67a/plone.recipe.codeanalysis-1.1.1.zip" } ], "2.0": [ { "comment_text": "", "digests": { "md5": "62ff9541dd716fb461a81db47baa72d7", "sha256": "1f60ef2672ef1e8f5a6be13cc1091a45a05a2100b48cde038c8ee7b5d18c33ae" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.0.tar.gz", "has_sig": false, "md5_digest": "62ff9541dd716fb461a81db47baa72d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47320, "upload_time": "2015-08-07T09:10:39", "url": "https://files.pythonhosted.org/packages/9e/06/7f0c8bc9cd6d13750ad351d61065f3f28a1902fb1aa8f50574a3cd54b1bb/plone.recipe.codeanalysis-2.0.tar.gz" } ], "2.0.1": [ { "comment_text": "", "digests": { "md5": "4904b632129ae9c0a455d4b2b977d2a7", "sha256": "e6bd9893ce14937678cd4f95f8ca8283e397801a7cc735d9def9d211f3b6385b" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.0.1.tar.gz", "has_sig": false, "md5_digest": "4904b632129ae9c0a455d4b2b977d2a7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 53321, "upload_time": "2015-09-02T20:13:27", "url": "https://files.pythonhosted.org/packages/ec/88/1e37fad6760ba898feb8979748adf041dc2bffe16225ac3b89e60e902efe/plone.recipe.codeanalysis-2.0.1.tar.gz" } ], "2.0.2": [ { "comment_text": "", "digests": { "md5": "cb1fa60ec9e98b0a99299ef3ac17a153", "sha256": "25494d88aeaa462fbdd1c52d972d1f699ad34948564d8d1bbbb461eb5b1353e5" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.0.2.tar.gz", "has_sig": false, "md5_digest": "cb1fa60ec9e98b0a99299ef3ac17a153", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 53842, "upload_time": "2015-09-03T21:14:53", "url": "https://files.pythonhosted.org/packages/ba/65/28ad409628d3b07dae4e5bec2fd1645be80c1fb9361a3f33472c730fb7fe/plone.recipe.codeanalysis-2.0.2.tar.gz" } ], "2.0a1": [ { "comment_text": "", "digests": { "md5": "60894960777c43a61185bf49ae4bb09f", "sha256": "3be12f8fa087b27ef4b0fa3eb21252849410dbfee0ea8dde91e0c863dc5505fd" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.0a1.tar.gz", "has_sig": false, "md5_digest": "60894960777c43a61185bf49ae4bb09f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42101, "upload_time": "2015-04-27T12:01:44", "url": "https://files.pythonhosted.org/packages/14/46/412efbba182c0262e6b7a220e7fb60f99eabe9265ec04a9b728836827aa3/plone.recipe.codeanalysis-2.0a1.tar.gz" } ], "2.0a2": [ { "comment_text": "", "digests": { "md5": "59bc9e2c5250ab46e50c9b3cf58110e6", "sha256": "57b548cde018b4e4cce70aacbbc53969e44fb16dafd78ab3e10fcbcbfbae5bc8" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.0a2.tar.gz", "has_sig": false, "md5_digest": "59bc9e2c5250ab46e50c9b3cf58110e6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43873, "upload_time": "2015-04-30T08:45:45", "url": "https://files.pythonhosted.org/packages/f2/17/09a0263211226e8f8e462515b88554e484124a79420f258953d1bf862371/plone.recipe.codeanalysis-2.0a2.tar.gz" } ], "2.0b1": [ { "comment_text": "", "digests": { "md5": "f990bdca459c49370f68966b300a003f", "sha256": "12309d5a5bdfcebba01ac420fdac7420065154aedb2b1a106ef288ddc74526ff" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.0b1.tar.gz", "has_sig": false, "md5_digest": "f990bdca459c49370f68966b300a003f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47913, "upload_time": "2015-05-03T21:19:36", "url": "https://files.pythonhosted.org/packages/0f/ae/9900f17a63647e93f892e46279d58457ae84a7ab9ec09b6c3ac6df070bda/plone.recipe.codeanalysis-2.0b1.tar.gz" } ], "2.1": [ { "comment_text": "", "digests": { "md5": "0afd9fbefc2803892ab0781e5f190ee8", "sha256": "8f0cd745bf0ad6b47b57d12707f06876a131d85a5f9412f52b9d69b6daff09fc" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.1.tar.gz", "has_sig": false, "md5_digest": "0afd9fbefc2803892ab0781e5f190ee8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47374, "upload_time": "2015-09-21T05:23:22", "url": "https://files.pythonhosted.org/packages/92/6e/92d37ce226c8ce7b1a6a0aa69a1938d031d9cad054ea365a7f061724d26d/plone.recipe.codeanalysis-2.1.tar.gz" } ], "2.2": [ { "comment_text": "", "digests": { "md5": "1faf38cc1c3022e1431519ae52967991", "sha256": "cf11a5965eeeec0f85a9ab03e14b1d914671ab5d7db4a98d6b3f83063a20f2ef" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.2.tar.gz", "has_sig": false, "md5_digest": "1faf38cc1c3022e1431519ae52967991", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50475, "upload_time": "2016-02-20T21:40:58", "url": "https://files.pythonhosted.org/packages/ef/0c/031a06ef77922453230a6359988e7d18e5f13be5df4d1c3551bdf8e151a2/plone.recipe.codeanalysis-2.2.tar.gz" } ], "2.3": [ { "comment_text": "", "digests": { "md5": "568d272ecee6933c2c316f1db916c575", "sha256": "50fc8da8bf5f11fad4e73799fb044348242a14ba7deba17ed5478ebd524e9eb2" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-2.3.tar.gz", "has_sig": false, "md5_digest": "568d272ecee6933c2c316f1db916c575", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 48278, "upload_time": "2018-01-18T08:47:42", "url": "https://files.pythonhosted.org/packages/1a/0d/1ca521aa7f9c2685c48edaf3ff0496fb6790e72f03f4e064c23f6e829088/plone.recipe.codeanalysis-2.3.tar.gz" } ], "3.0.0": [ { "comment_text": "", "digests": { "md5": "380d4e19066121251e20bfc7470e9497", "sha256": "5878be16b18db50fe0be87e7a2473a391266a008604d33552c2622fbd6e973ea" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-3.0.0.tar.gz", "has_sig": false, "md5_digest": "380d4e19066121251e20bfc7470e9497", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 66875, "upload_time": "2018-06-27T05:40:15", "url": "https://files.pythonhosted.org/packages/8c/ec/40c1241ce67cfe508c453094602007d5c66c47c87c9cee66115d63a343b7/plone.recipe.codeanalysis-3.0.0.tar.gz" } ], "3.0.0a0": [ { "comment_text": "", "digests": { "md5": "1b1411d6aa106cfc5befcca97348edff", "sha256": "5189a7846032a275b3dab8888e01d48be353ca507155c615c300abfc8c886d7c" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-3.0.0a0.tar.gz", "has_sig": false, "md5_digest": "1b1411d6aa106cfc5befcca97348edff", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 65301, "upload_time": "2018-06-15T16:38:18", "url": "https://files.pythonhosted.org/packages/6b/fe/2852e95bd148ce8ab6a4b365fc95578d076f7c734d3ae81f176be47741ba/plone.recipe.codeanalysis-3.0.0a0.tar.gz" } ], "3.0.1": [ { "comment_text": "", "digests": { "md5": "143ce3e9d0eb3f20e14b82cad5acf352", "sha256": "ce51bc83d3aadfeac853d196eddc0ca38d301048e1b8128ad9637f415b57b4de" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-3.0.1.tar.gz", "has_sig": false, "md5_digest": "143ce3e9d0eb3f20e14b82cad5acf352", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 66860, "upload_time": "2018-06-27T19:37:30", "url": "https://files.pythonhosted.org/packages/5e/20/79bda8c4c438377f62b3567495972efe38ba05cf4ae3b71d074d6fdbb4b9/plone.recipe.codeanalysis-3.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "143ce3e9d0eb3f20e14b82cad5acf352", "sha256": "ce51bc83d3aadfeac853d196eddc0ca38d301048e1b8128ad9637f415b57b4de" }, "downloads": -1, "filename": "plone.recipe.codeanalysis-3.0.1.tar.gz", "has_sig": false, "md5_digest": "143ce3e9d0eb3f20e14b82cad5acf352", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 66860, "upload_time": "2018-06-27T19:37:30", "url": "https://files.pythonhosted.org/packages/5e/20/79bda8c4c438377f62b3567495972efe38ba05cf4ae3b71d074d6fdbb4b9/plone.recipe.codeanalysis-3.0.1.tar.gz" } ] }