Permalink
Browse files

Initial naive pass at forking the validator

  • Loading branch information...
1 parent 289e398 commit ac8e0163f00ad1f989f4d08d59a6e8d51d5c6d2b @mattbasta committed Aug 1, 2012
Showing with 13 additions and 656 deletions.
  1. +0 −3 .gitmodules
  2. +0 −2 MANIFEST.in
  3. +9 −130 README.rst
  4. 0 addon-validator → app-validator
  5. 0 {validator/testcases/markup → appvalidator}/__init__.py
  6. 0 {validator → appvalidator}/app_versions.json
  7. 0 {validator → appvalidator}/chromemanifest.py
  8. 0 {validator → appvalidator}/compat.py
  9. 0 {validator → appvalidator}/constants.py
  10. 0 {validator → appvalidator}/contextgenerator.py
  11. 0 {validator → appvalidator}/decorator.py
  12. 0 {validator → appvalidator}/errorbundler.py
  13. 0 {validator → appvalidator}/loader.py
  14. 0 {validator → appvalidator}/main.py
  15. 0 {validator → appvalidator}/opensearch.py
  16. 0 {validator/testcases/l10n → appvalidator/outputhandlers}/__init__.py
  17. 0 {validator → appvalidator}/outputhandlers/shellcolors.py
  18. 0 {validator → appvalidator}/rdf.py
  19. 0 {validator → appvalidator}/specprocessor.py
  20. 0 {validator/testcases/javascript → appvalidator/specs}/__init__.py
  21. 0 {validator → appvalidator}/specs/webapps.py
  22. 0 {validator → appvalidator}/submain.py
  23. 0 {validator → appvalidator}/testcases/__init__.py
  24. 0 {validator → appvalidator}/testcases/chromemanifest.py
  25. 0 {validator → appvalidator}/testcases/conduit.py
  26. 0 {validator → appvalidator}/testcases/content.py
  27. 0 {validator → appvalidator}/testcases/hashes.txt
  28. 0 {validator → appvalidator}/testcases/installrdf.py
  29. 0 {validator/specs → appvalidator/testcases/javascript}/__init__.py
  30. 0 {validator → appvalidator}/testcases/javascript/actions.py
  31. 0 {validator → appvalidator}/testcases/javascript/call_definitions.py
  32. 0 {validator → appvalidator}/testcases/javascript/entity_values.py
  33. 0 {validator → appvalidator}/testcases/javascript/instanceactions.py
  34. 0 {validator → appvalidator}/testcases/javascript/instanceproperties.py
  35. 0 {validator → appvalidator}/testcases/javascript/jstypes.py
  36. 0 {validator → appvalidator}/testcases/javascript/nodedefinitions.py
  37. 0 {validator → appvalidator}/testcases/javascript/predefinedentities.py
  38. 0 {validator → appvalidator}/testcases/javascript/spidermonkey.py
  39. 0 {validator → appvalidator}/testcases/javascript/traverser.py
  40. 0 {validator → appvalidator}/testcases/jetpack.py
  41. 0 {validator → appvalidator}/testcases/jetpack_data.txt
  42. 0 {validator/outputhandlers → appvalidator/testcases/l10n}/__init__.py
  43. 0 {validator → appvalidator}/testcases/l10n/dtd.py
  44. 0 {validator → appvalidator}/testcases/l10n/properties.py
  45. 0 {validator → appvalidator}/testcases/l10ncompleteness.py
  46. 0 {validator → appvalidator}/testcases/langpack.py
  47. 0 {validator → appvalidator}/testcases/langpacks/fennec.xpi
  48. 0 {validator → appvalidator}/testcases/langpacks/firefox.xpi
  49. 0 {validator → appvalidator}/testcases/langpacks/mozilla.xpi
  50. 0 {validator → appvalidator}/testcases/langpacks/seamonkey.xpi
  51. 0 {validator → appvalidator}/testcases/langpacks/sunbird.xpi
  52. 0 {validator → appvalidator}/testcases/langpacks/thunderbird.xpi
  53. 0 {validator → appvalidator/testcases/markup}/__init__.py
  54. 0 {validator → appvalidator}/testcases/markup/csstester.py
  55. 0 {validator → appvalidator}/testcases/markup/markuptester.py
  56. 0 {validator → appvalidator}/testcases/packagelayout.py
  57. 0 {validator → appvalidator}/testcases/regex.py
  58. 0 {validator → appvalidator}/testcases/scripting.py
  59. 0 {validator → appvalidator}/testcases/targetapplication.py
  60. 0 {validator → appvalidator}/testcases/themes.py
  61. 0 {validator → appvalidator}/testcases/whitelist_hashes.txt
  62. 0 {validator → appvalidator}/textfilter.py
  63. 0 {validator → appvalidator}/typedetection.py
  64. 0 {validator → appvalidator}/unicodehelper.py
  65. 0 {validator → appvalidator}/validate.py
  66. 0 {validator → appvalidator}/version.py
  67. 0 {validator → appvalidator}/webapp.py
  68. 0 {validator → appvalidator}/xpi.py
  69. +0 −17 extras/build_whitelist.py
  70. +0 −42 extras/bundle.py
  71. +0 −305 extras/cover.py
  72. +0 −47 extras/unbundle.py
  73. +0 −72 extras/update_langpacks.py
  74. +0 −1 jetpack/addon-sdk
  75. +0 −25 jetpack/generate_jp_whitelist.sh
  76. +0 −6 jetpack/make_hash.py
  77. +0 −2 requirements.txt
  78. +4 −4 setup.py
View
3 .gitmodules
@@ -1,3 +0,0 @@
-[submodule "jetpack/addon-sdk"]
- path = jetpack/addon-sdk
- url = git://github.com/mozilla/addon-sdk.git
View
2 MANIFEST.in
@@ -1,4 +1,2 @@
include validator/testcases/hashes.txt
-include validator/app_versions.json
-include validator/testcases/jetpack_data.txt
include validator/testcases/whitelist_hashes.txt
View
139 README.rst
@@ -1,10 +1,9 @@
-==============================
- addons.mozilla.org Validator
-==============================
+===================================
+ marketplace.mozilla.org Validator
+===================================
-The AMO Validator is a tool designed to scan Mozilla add-on packages for
-problems such as security vulnerabilities, exploits, spamware and badware,
-and lots of other gunk. By using a combination of various techniques and
+The Apps Validator is a tool designed to scan open web apps for
+problems and invalid code. By using a combination of various techniques and
detection mechanisms, the validator is capable of being both efficient as well
as thorough.
@@ -19,7 +18,6 @@ Python Libraries:
- argparse
- cssutils
-- rdflib
- fastchardet
Python Libraries for Testing:
@@ -86,12 +84,10 @@ your environment.
Run the validator as follows ::
- python addon-validator <path to xpi> [-t <expected type>] [-o <output type>] [-v] [--boring] [--selfhosted] [--determined]
+ python app-validator <path to app> [-o <output type>] [-v] [--boring] [--selfhosted] [--determined]
The path to the XPI should point to an XPI file.
--t The type that you expect your add-on to be detected as. The
- list of types is listed below.
-o The type of output to generate. Types are listed below.
-v Enable verbose mode. Extra information will be displayed in
verbose mode, namely notices (informational messages),
@@ -105,44 +101,6 @@ The path to the XPI should point to an XPI file.
tier has failed. Certain high-tiered tests may
inadvertently fail when this option is enabled for badly
malformed add-ons.
---target-appversion Accepts a JSON string containing an object whose keys
- are GUIDs and values are lists of version strings. In the
- targetApplication and compatibility tests, the add-on's
- predefined ``<em:targetApplication>`` values will be
- overridden if its GUIDs match thoes from the JSON. E.g.:
- ``{"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": "5.*"}``
---for-appversions Accepts a JSON string containing an object whose keys are
- GUIDs and values are lists of version strings. If this
- list is specified, non-inlinecompatibility tests will only
- be run if they specifically target the applications and
- veresions in this parameter. E.g.:
- ``{"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": ["6.*"]}``
-
-
-Expected Type:
-==============
-
-The expected type should be one of the following values:
-
-any (default)
- Accepts any extension
-extension
- Accepts only extensions
-theme
- Accepts only themes
-dictionary
- Accepts only dictionaries
-languagepack
- Accepts only language packs
-search
- Accepts only OpenSearch XML files (unpackaged)
-multi
- Accepts only multi-item XPI packages
-
-Specifying an expected type will throw an error if the validator
-does not detect that particular type when scanning. All addon type
-detection mechanisms are used to make this determination.
-
Output Type:
============
@@ -180,16 +138,11 @@ sample document below.
::
{
- "detected_type": "extension",
+ "detected_type": "packaged_app",
"errors": 2,
"warnings": 1,
"notices": 1,
"success": false,
- "compatibility_summary": {
- "errors": 1,
- "warnings": 0,
- "notices": 0
- },
"ending_tier": 4,
"message_tree": {
"module": {
@@ -223,26 +176,17 @@ sample document below.
"message": "This is the error message text.",
"description": ["Description of the error message.",
"Additional description text"],
- "file": ["chrome/foo.jar", "bar/zap.js"],
+ "file": "chrome/foo.bar",
"line": 12,
"column": 50,
"context: [
" if(foo = bar())",
" an_error_is_somewhere_on_this_line.prototy.eval("whatever");",
null
],
- "compatibility_type": "error",
- "for_appversions": {
- "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": ["5.0a2", "6.0a1"]
- },
"tier": 2
}
- ],
- "metadata": {
- "name": "Best Add-on Evar",
- "version": "9000",
- "guid": "foo@bar.com"
- }
+ ]
}
@@ -371,40 +315,13 @@ or, after setting the proper python path: ::
nosetests
-However, to turn run unit tests with code coverage, the appropriate
-command would be: ::
-
- nosetests --with-coverage --cover-package=validator --cover-skip=validator.outputhandlers.,validator.main,validator.constants,validator.constants_local --cover-inclusive --cover-tests
-
-Note that in order to use the --cover-skip nose parameter, you must
-install the included patch for nose's coverage.py plugin: ::
-
- extras/cover.py
-
-This file should overwrite the standard nose coverage plugin at the
-appropriate location: ::
-
- ~/.virtualenvs/[virtual environment]/lib/pythonX.X/site-packages/nose/plugins/cover.py
- /usr/lib/pythonX.X/site-packages/nose/plugins/cover.py
-
-
----------
Updating
----------
Some regular maintenance needs to be performed on the validator in order to
make sure that the results are accurate.
-App Versions
-============
-
-A list of Mozilla ``<em:targetApplication>`` values is stored in the
-``validator/app_versions.json`` file. This must be updated to include the latest
-application versions. This information can be found on AMO:
-
-https://addons.mozilla.org/en-US/firefox/pages/appversions/
-
-
JS Libraries
============
@@ -422,41 +339,3 @@ regenerated with each new library version. To update: ::
To add new libraries to the mix, edit ``extras/jslibfetcher.py`` and add the
version number to the appropriate tuple.
-
-Jetpack
-=======
-
-In order to maintain Jetpack compatibility, the whitelist hashes need to be
-regenerated with each successive Jetpack version. To rebuild the hash library,
-simply run: ::
-
- cd jetpack
- ./generate_jp_whitelist.sh
-
-That's it!
-
-
-Language Packs
-==============
-
-With every version of every app that's released, the language pack references
-need to be updated.
-
-We now have an automated tool to ease this tedious process. It is currently
-designed to work on OS X with the OS X versions of Mozilla applications, though
-it could conceivably run on any \*NIX platform against the OS X application
-packages.
-
-To run the tool, first create a new directory: ``extras/language_controls/``
-
-Put the ``.app`` packages for each updated product into this directory. Once
-this is ready, simply run: ::
-
- cd extras
- python update_langpacks.py
-
-That should be it. Note that this tool will fail horribly if any of the teams
-change the locations that the various language files are stored in.
-
-Also note that this tool should only be run against the en-US versions of these
-applications.
View
0 addon-validator → app-validator
File renamed without changes.
View
0 validator/testcases/markup/__init__.py → appvalidator/__init__.py
File renamed without changes.
View
0 validator/app_versions.json → appvalidator/app_versions.json
File renamed without changes.
View
0 validator/chromemanifest.py → appvalidator/chromemanifest.py
File renamed without changes.
View
0 validator/compat.py → appvalidator/compat.py
File renamed without changes.
View
0 validator/constants.py → appvalidator/constants.py
File renamed without changes.
View
0 validator/contextgenerator.py → appvalidator/contextgenerator.py
File renamed without changes.
View
0 validator/decorator.py → appvalidator/decorator.py
File renamed without changes.
View
0 validator/errorbundler.py → appvalidator/errorbundler.py
File renamed without changes.
View
0 validator/loader.py → appvalidator/loader.py
File renamed without changes.
View
0 validator/main.py → appvalidator/main.py
File renamed without changes.
View
0 validator/opensearch.py → appvalidator/opensearch.py
File renamed without changes.
View
0 validator/testcases/l10n/__init__.py → appvalidator/outputhandlers/__init__.py
File renamed without changes.
View
0 validator/outputhandlers/shellcolors.py → appvalidator/outputhandlers/shellcolors.py
File renamed without changes.
View
0 validator/rdf.py → appvalidator/rdf.py
File renamed without changes.
View
0 validator/specprocessor.py → appvalidator/specprocessor.py
File renamed without changes.
View
0 validator/testcases/javascript/__init__.py → appvalidator/specs/__init__.py
File renamed without changes.
View
0 validator/specs/webapps.py → appvalidator/specs/webapps.py
File renamed without changes.
View
0 validator/submain.py → appvalidator/submain.py
File renamed without changes.
View
0 validator/testcases/__init__.py → appvalidator/testcases/__init__.py
File renamed without changes.
View
0 validator/testcases/chromemanifest.py → appvalidator/testcases/chromemanifest.py
File renamed without changes.
View
0 validator/testcases/conduit.py → appvalidator/testcases/conduit.py
File renamed without changes.
View
0 validator/testcases/content.py → appvalidator/testcases/content.py
File renamed without changes.
View
0 validator/testcases/hashes.txt → appvalidator/testcases/hashes.txt
File renamed without changes.
View
0 validator/testcases/installrdf.py → appvalidator/testcases/installrdf.py
File renamed without changes.
View
0 validator/specs/__init__.py → ...alidator/testcases/javascript/__init__.py
File renamed without changes.
View
0 validator/testcases/javascript/actions.py → appvalidator/testcases/javascript/actions.py
File renamed without changes.
View
0 .../testcases/javascript/call_definitions.py → .../testcases/javascript/call_definitions.py
File renamed without changes.
View
0 ...tor/testcases/javascript/entity_values.py → ...tor/testcases/javascript/entity_values.py
File renamed without changes.
View
0 ...r/testcases/javascript/instanceactions.py → ...r/testcases/javascript/instanceactions.py
File renamed without changes.
View
0 ...estcases/javascript/instanceproperties.py → ...estcases/javascript/instanceproperties.py
File renamed without changes.
View
0 validator/testcases/javascript/jstypes.py → appvalidator/testcases/javascript/jstypes.py
File renamed without changes.
View
0 ...r/testcases/javascript/nodedefinitions.py → ...r/testcases/javascript/nodedefinitions.py
File renamed without changes.
View
0 ...estcases/javascript/predefinedentities.py → ...estcases/javascript/predefinedentities.py
File renamed without changes.
View
0 ...ator/testcases/javascript/spidermonkey.py → ...ator/testcases/javascript/spidermonkey.py
File renamed without changes.
View
0 validator/testcases/javascript/traverser.py → ...lidator/testcases/javascript/traverser.py
File renamed without changes.
View
0 validator/testcases/jetpack.py → appvalidator/testcases/jetpack.py
File renamed without changes.
View
0 validator/testcases/jetpack_data.txt → appvalidator/testcases/jetpack_data.txt
File renamed without changes.
View
0 validator/outputhandlers/__init__.py → appvalidator/testcases/l10n/__init__.py
File renamed without changes.
View
0 validator/testcases/l10n/dtd.py → appvalidator/testcases/l10n/dtd.py
File renamed without changes.
View
0 validator/testcases/l10n/properties.py → appvalidator/testcases/l10n/properties.py
File renamed without changes.
View
0 validator/testcases/l10ncompleteness.py → appvalidator/testcases/l10ncompleteness.py
File renamed without changes.
View
0 validator/testcases/langpack.py → appvalidator/testcases/langpack.py
File renamed without changes.
View
0 validator/testcases/langpacks/fennec.xpi → appvalidator/testcases/langpacks/fennec.xpi
File renamed without changes.
View
0 validator/testcases/langpacks/firefox.xpi → appvalidator/testcases/langpacks/firefox.xpi
File renamed without changes.
View
0 validator/testcases/langpacks/mozilla.xpi → appvalidator/testcases/langpacks/mozilla.xpi
File renamed without changes.
View
0 validator/testcases/langpacks/seamonkey.xpi → ...lidator/testcases/langpacks/seamonkey.xpi
File renamed without changes.
View
0 validator/testcases/langpacks/sunbird.xpi → appvalidator/testcases/langpacks/sunbird.xpi
File renamed without changes.
View
0 ...dator/testcases/langpacks/thunderbird.xpi → ...dator/testcases/langpacks/thunderbird.xpi
File renamed without changes.
View
0 validator/__init__.py → appvalidator/testcases/markup/__init__.py
File renamed without changes.
View
0 validator/testcases/markup/csstester.py → appvalidator/testcases/markup/csstester.py
File renamed without changes.
View
0 validator/testcases/markup/markuptester.py → ...alidator/testcases/markup/markuptester.py
File renamed without changes.
View
0 validator/testcases/packagelayout.py → appvalidator/testcases/packagelayout.py
File renamed without changes.
View
0 validator/testcases/regex.py → appvalidator/testcases/regex.py
File renamed without changes.
View
0 validator/testcases/scripting.py → appvalidator/testcases/scripting.py
File renamed without changes.
View
0 validator/testcases/targetapplication.py → appvalidator/testcases/targetapplication.py
File renamed without changes.
View
0 validator/testcases/themes.py → appvalidator/testcases/themes.py
File renamed without changes.
View
0 validator/testcases/whitelist_hashes.txt → appvalidator/testcases/whitelist_hashes.txt
File renamed without changes.
View
0 validator/textfilter.py → appvalidator/textfilter.py
File renamed without changes.
View
0 validator/typedetection.py → appvalidator/typedetection.py
File renamed without changes.
View
0 validator/unicodehelper.py → appvalidator/unicodehelper.py
File renamed without changes.
View
0 validator/validate.py → appvalidator/validate.py
File renamed without changes.
View
0 validator/version.py → appvalidator/version.py
File renamed without changes.
View
0 validator/webapp.py → appvalidator/webapp.py
File renamed without changes.
View
0 validator/xpi.py → appvalidator/xpi.py
File renamed without changes.
View
17 extras/build_whitelist.py
@@ -1,17 +0,0 @@
-import sys
-import os
-import os.path as pth
-import hashlib
-
-output = open("whitelist_hashes.txt", mode="w")
-
-for root, dirs, files in os.walk(sys.argv[1]):
- for filename in files:
- path = pth.join(pth.dirname(pth.abspath(sys.argv[0])),
- root, filename)
- hash = hashlib.sha1(open(path).read()).hexdigest()
- print path, hash
- output.write(hash + "\n")
-
-output.close()
-
View
42 extras/bundle.py
@@ -1,42 +0,0 @@
-import sys
-import os
-
-import zipfile
-from zipfile import ZipFile
-from StringIO import StringIO
-
-source = sys.argv[1]
-target = sys.argv[2]
-zf = ZipFile(target, 'w')
-
-def _build_directory(source, zip, root):
- for item in os.listdir(source):
-
- if item in ("__MACOSX",
- ".DS_Store"):
- continue
-
- if item.startswith("__"):
- continue
-
- item = "%s/%s" % (source, item)
- print item
-
- if os.path.isdir(item):
- if item.startswith("_") and item.endswith(".jar"):
- zipbuffer = StringIO()
- subzip = ZipFile(zipbuffer, "w")
- _build_directory(item, subzip, item)
- subzip.close()
-
- zip.writestr(item[len(root) + 2:], zipbuffer.getvalue())
- else:
- _build_directory(item, zip, root)
- else:
- print item[len(root) + 1:]
- zip.write(item, item[len(root) + 1:])
-
-
-
-_build_directory(source, zf, source)
-zf.close()
View
305 extras/cover.py
@@ -1,305 +0,0 @@
-"""If you have Ned Batchelder's coverage_ module installed, you may activate a
-coverage report with the ``--with-coverage`` switch or NOSE_WITH_COVERAGE
-environment variable. The coverage report will cover any python source module
-imported after the start of the test run, excluding modules that match
-testMatch. If you want to include those modules too, use the ``--cover-tests``
-switch, or set the NOSE_COVER_TESTS environment variable to a true value. To
-restrict the coverage report to modules from a particular package or packages,
-use the ``--cover-packages`` switch or the NOSE_COVER_PACKAGES environment
-variable.
-
-.. _coverage: http://www.nedbatchelder.com/code/modules/coverage.html
-"""
-import logging
-import os
-import sys
-from nose.plugins.base import Plugin
-from nose.util import src, tolist
-
-log = logging.getLogger(__name__)
-
-COVERAGE_TEMPLATE = '''<html>
-<head>
-%(title)s
-</head>
-<body>
-%(header)s
-<style>
-.coverage pre {float: left; margin: 0px 1em; border: none;
- padding: 0px; }
-.num pre { margin: 0px }
-.nocov, .nocov pre {background-color: #faa}
-.cov, .cov pre {background-color: #cfc}
-div.coverage div { clear: both; height: 1.1em}
-</style>
-<div class="stats">
-%(stats)s
-</div>
-<div class="coverage">
-%(body)s
-</div>
-</body>
-</html>
-'''
-
-COVERAGE_STATS_TEMPLATE = '''Covered: %(covered)s lines<br/>
-Missed: %(missed)s lines<br/>
-Skipped %(skipped)s lines<br/>
-Percent: %(percent)s %%<br/>
-'''
-
-
-class Coverage(Plugin):
- """
- Activate a coverage report using Ned Batchelder's coverage module.
- """
- coverTests = False
- coverPackages = None
- score = 200
- status = {}
-
- def options(self, parser, env):
- """
- Add options to command line.
- """
- Plugin.options(self, parser, env)
- parser.add_option("--cover-package", action="append",
- default=env.get('NOSE_COVER_PACKAGE'),
- metavar="PACKAGE",
- dest="cover_packages",
- help="Restrict coverage output to selected packages "
- "[NOSE_COVER_PACKAGE]")
- parser.add_option("--cover-skip", action="store",
- dest="cover_skip",
- help="Skip packages "
- "[NOSE_COVER_SKIP]")
- parser.add_option("--cover-erase", action="store_true",
- default=env.get('NOSE_COVER_ERASE'),
- dest="cover_erase",
- help="Erase previously collected coverage "
- "statistics before run")
- parser.add_option("--cover-tests", action="store_true",
- dest="cover_tests",
- default=env.get('NOSE_COVER_TESTS'),
- help="Include test modules in coverage report "
- "[NOSE_COVER_TESTS]")
- parser.add_option("--cover-inclusive", action="store_true",
- dest="cover_inclusive",
- default=env.get('NOSE_COVER_INCLUSIVE'),
- help="Include all python files under working "
- "directory in coverage report. Useful for "
- "discovering holes in test coverage if not all "
- "files are imported by the test suite. "
- "[NOSE_COVER_INCLUSIVE]")
- parser.add_option("--cover-html", action="store_true",
- default=env.get('NOSE_COVER_HTML'),
- dest='cover_html',
- help="Produce HTML coverage information")
- parser.add_option('--cover-html-dir', action='store',
- default=env.get('NOSE_COVER_HTML_DIR', 'cover'),
- dest='cover_html_dir',
- metavar='DIR',
- help='Produce HTML coverage information in dir')
-
- def configure(self, options, config):
- """
- Configure plugin.
- """
- try:
- self.status.pop('active')
- except KeyError:
- pass
- Plugin.configure(self, options, config)
- if config.worker:
- return
- if self.enabled:
- try:
- import coverage
- except ImportError:
- log.error("Coverage not available: "
- "unable to import coverage module")
- self.enabled = False
- return
- self.conf = config
- cskip = options.cover_skip
- if cskip:
- self.coverSkip = cskip.split(",")
- else:
- self.coverSkip = []
- self.coverErase = options.cover_erase
- self.coverTests = options.cover_tests
- self.coverPackages = []
- if options.cover_packages:
- for pkgs in [tolist(x) for x in options.cover_packages]:
- self.coverPackages.extend(pkgs)
- self.coverInclusive = options.cover_inclusive
- if self.coverPackages:
- log.info("Coverage report will include only packages: %s",
- self.coverPackages)
- self.coverHtmlDir = None
- if options.cover_html:
- self.coverHtmlDir = options.cover_html_dir
- log.debug('Will put HTML coverage report in %s', self.coverHtmlDir)
- if self.enabled:
- self.status['active'] = True
-
- def begin(self):
- """
- Begin recording coverage information.
- """
- log.debug("Coverage begin")
- import coverage
- self.skipModules = sys.modules.keys()[:]
- if self.coverErase:
- log.debug("Clearing previously collected coverage statistics")
- coverage.erase()
- coverage.exclude('#pragma[: ]+[nN][oO] [cC][oO][vV][eE][rR]')
- coverage.start()
-
- def report(self, stream):
- """
- Output code coverage report.
- """
- log.debug("Coverage report")
- import coverage
- coverage.stop()
- modules = [ module
- for name, module in sys.modules.items()
- if self.wantModuleCoverage(name, module, stream) ]
- log.debug("Coverage report will cover modules: %s", modules)
- coverage.report(modules, file=stream)
- if self.coverHtmlDir:
- if not os.path.exists(self.coverHtmlDir):
- os.makedirs(self.coverHtmlDir)
- log.debug("Generating HTML coverage report")
- files = {}
- for m in modules:
- if hasattr(m, '__name__') and hasattr(m, '__file__'):
- files[m.__name__] = m.__file__
- coverage.annotate(files.values())
- global_stats = {'covered': 0, 'missed': 0, 'skipped': 0}
- file_list = []
- for m, f in files.iteritems():
- if f.endswith('pyc'):
- f = f[:-1]
- coverfile = f+',cover'
- outfile, stats = self.htmlAnnotate(m, f, coverfile,
- self.coverHtmlDir)
- for field in ('covered', 'missed', 'skipped'):
- global_stats[field] += stats[field]
- file_list.append((stats['percent'], m, outfile, stats))
- os.unlink(coverfile)
- file_list.sort()
- global_stats['percent'] = self.computePercent(
- global_stats['covered'], global_stats['missed'])
- # Now write out an index file for the coverage HTML
- index = open(os.path.join(self.coverHtmlDir, 'index.html'), 'w')
- index.write('<html><head><title>Coverage Index</title></head>'
- '<body><p>')
- index.write(COVERAGE_STATS_TEMPLATE % global_stats)
- index.write('<table><tr><td>File</td><td>Covered</td><td>Missed'
- '</td><td>Skipped</td><td>Percent</td></tr>')
- for junk, name, outfile, stats in file_list:
- stats['a'] = '<a href="%s">%s</a>' % (outfile, name)
- index.write('<tr><td>%(a)s</td><td>%(covered)s</td><td>'
- '%(missed)s</td><td>%(skipped)s</td><td>'
- '%(percent)s %%</td></tr>' % stats)
- index.write('</table></p></html')
- index.close()
-
- def htmlAnnotate(self, name, file, coverfile, outputDir):
- log.debug('Name: %s file: %s' % (name, file, ))
- rows = []
- data = open(coverfile, 'r').read().split('\n')
- padding = len(str(len(data)))
- stats = {'covered': 0, 'missed': 0, 'skipped': 0}
- for lineno, line in enumerate(data):
- lineno += 1
- if line:
- status = line[0]
- line = line[2:]
- else:
- status = ''
- line = ''
- lineno = (' ' * (padding - len(str(lineno)))) + str(lineno)
- for old, new in (('&', '&amp;'), ('<', '&lt;'), ('>', '&gt;'),
- ('"', '&quot;'), ):
- line = line.replace(old, new)
- if status == '!':
- rows.append('<div class="nocov"><span class="num"><pre>'
- '%s</pre></span><pre>%s</pre></div>' % (lineno,
- line))
- stats['missed'] += 1
- elif status == '>':
- rows.append('<div class="cov"><span class="num"><pre>%s</pre>'
- '</span><pre>%s</pre></div>' % (lineno, line))
- stats['covered'] += 1
- else:
- rows.append('<div class="skip"><span class="num"><pre>%s</pre>'
- '</span><pre>%s</pre></div>' % (lineno, line))
- stats['skipped'] += 1
- stats['percent'] = self.computePercent(stats['covered'],
- stats['missed'])
- html = COVERAGE_TEMPLATE % {'title': '<title>%s</title>' % name,
- 'header': name,
- 'body': '\n'.join(rows),
- 'stats': COVERAGE_STATS_TEMPLATE % stats,
- }
- outfilename = name + '.html'
- outfile = open(os.path.join(outputDir, outfilename), 'w')
- outfile.write(html)
- outfile.close()
- return outfilename, stats
-
- def computePercent(self, covered, missed):
- if covered + missed == 0:
- percent = 1
- else:
- percent = covered/(covered+missed+0.0)
- return int(percent * 100)
-
- def wantModuleCoverage(self, name, module, stream=None):
- if not hasattr(module, '__file__'):
- log.debug("no coverage of %s: no __file__", name)
- return False
- module_file = src(module.__file__)
- if not module_file or not module_file.endswith('.py'):
- log.debug("no coverage of %s: not a python file", name)
- return False
- if self.coverSkip:
- for package in self.coverSkip:
- if name.startswith(package):
- return False
- if self.coverPackages:
- for package in self.coverPackages:
- if (name.startswith(package)
- and (self.coverTests
- or not self.conf.testMatch.search(name))):
- log.debug("coverage for %s", name)
- return True
-
- if name in self.skipModules:
- log.debug("no coverage for %s: loaded before coverage start",
- name)
- return False
- if self.conf.testMatch.search(name) and not self.coverTests:
- log.debug("no coverage for %s: is a test", name)
- return False
- # accept any package that passed the previous tests, unless
- # coverPackages is on -- in that case, if we wanted this
- # module, we would have already returned True
- return not self.coverPackages
-
- def wantFile(self, file, package=None):
- """If inclusive coverage enabled, return true for all source files
- in wanted packages.
- """
- if self.coverInclusive:
- if file.endswith(".py"):
- if package and self.coverPackages:
- for want in self.coverPackages:
- if package.startswith(want):
- return True
- else:
- return True
- return None
View
47 extras/unbundle.py
@@ -1,47 +0,0 @@
-import sys
-import os
-
-import zipfile
-from zipfile import ZipFile
-from StringIO import StringIO
-
-source = sys.argv[1]
-target = sys.argv[2]
-
-if not target.endswith("/"):
- target = "%s/" % target
-
-def _unbundle(path, target):
- zf = ZipFile(path, 'r')
- contents = zf.namelist()
- for item in contents:
- sp = item.split("/")
- if not sp[-1]:
- continue
-
- if "__MACOSX" in item:
- continue
-
- print item, ">", target + item
-
- cpath = target + "/".join(sp[:-1])
- if not os.path.exists(cpath):
- os.makedirs(cpath)
- if item.endswith((".jar", ".xpi", ".zip")):
- now = target + item
- path_item = item.split("/")
- path_item[-1] = "_" + path_item[-1]
- path = target + "/".join(path_item)
-
- buff = StringIO(zf.read(item))
- _unbundle(buff, path + "/")
- else:
- f = open(target + item, 'w')
- f.write(zf.read(item))
- f.close()
- zf.close()
-
-if not os.path.exists(target):
- os.mkdir(target)
-
-_unbundle(source, target)
View
72 extras/update_langpacks.py
@@ -1,72 +0,0 @@
-import os
-from fnmatch import fnmatch
-from tempfile import NamedTemporaryFile
-from zipfile import ZipFile
-
-
-PACKAGE_MAPPINGS = {"Fennec.app": "fennec",
- "Firefox.app": "firefox",
- "SeaMonkey.app": "seamonkey",
- "Thunderbird.app": "thunderbird",}
-
-
-def copy_to_zip(read_zip, write_zip, pattern, prefix=""):
- for member in read_zip.namelist():
- if fnmatch(member, pattern):
- filename = member.split("/")[-1]
- write_zip.writestr("%s%s" % (prefix, filename),
- read_zip.read(member))
-
-
-def copy_to_new_zip(callback, read_zip, pattern, prefix=""):
- with NamedTemporaryFile("w") as temp:
- with ZipFile(temp.name, "w") as write_zip:
- copy_to_zip(read_zip, write_zip, pattern, prefix)
-
- callback(temp.name)
-
-
-def main():
- for package in os.listdir("language_controls/"):
- if package.startswith(".") or package not in PACKAGE_MAPPINGS:
- continue
-
- platform = PACKAGE_MAPPINGS[package]
- path = "language_controls/%s" % package
- jar = ZipFile("../validator/testcases/langpacks/%s.xpi" % platform, "w")
-
- if platform == "firefox":
- # Firefox puts this stuff in omni.ja.
- with ZipFile("%s/Contents/MacOS/omni.ja" % path, "r") as omni_ja:
- #print list(x for x in omni_ja.namelist() if x.startswith("chrome/"))
- jar.writestr("chrome.manifest",
- omni_ja.read("chrome/localized.manifest"))
-
- # Copy the chrome/en-US/ directory to /en-US.jar in the new zip.
- def callback(name):
- jar.write(name, "en-US.jar")
- copy_to_new_zip(callback, omni_ja, "chrome/en-US/*")
-
- elif platform in ("thunderbird", "seamonkey", ):
- # Thunderbird puts stuff in omni.ja, too,
- with ZipFile("%s/Contents/MacOS/omni.ja" % path, "r") as omni_ja:
- jar.writestr("chrome.manifest",
- omni_ja.read("chrome/localized.manifest"))
-
- # Copy the chrome/en-US/ directory to /en-US.jar in the new zip.
- def callback(name):
- jar.write(name, "en-US.jar")
- copy_to_new_zip(callback, omni_ja, "chrome/en-US/*")
-
- else:
- jar.write("%s/Contents/MacOS/chrome/localized.manifest" % path,
- "chrome.manifest")
- jar.write("%s/Contents/MacOS/chrome/en-US.jar" % path,
- "en-US.jar")
-
- jar.close()
-
-
-if __name__ == "__main__":
- main()
-
1 jetpack/addon-sdk
@@ -1 +0,0 @@
-Subproject commit e2b154aff5c452d3b4f25bd67513122bd6172319
View
25 jetpack/generate_jp_whitelist.sh
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-rm ../validator/testcases/jetpack_data.txt
-
-cd addon-sdk
-git pull origin --tags
-for tagname in `git tag`;
-do
- # Check out the tag.
- git checkout $tagname
-
- # Hash all of the JS files.
- for f in `find . -type f -name "*.js"`;
- do
- python ../make_hash.py $f $tagname >> ../../validator/testcases/jetpack_data.txt
- done
-
- # Run again for HTML, because it gets bundled, too.
- for f in `find . -type f -name "*.html"`;
- do
- python ../make_hash.py $f $tagname >> ../../validator/testcases/jetpack_data.txt
- done
-done
-
-sort ../../validator/testcases/jetpack_data.txt -d -o ../../validator/testcases/jetpack_data.txt
View
6 jetpack/make_hash.py
@@ -1,6 +0,0 @@
-import hashlib
-import os
-import sys
-
-hash = hashlib.sha256(open(sys.argv[1]).read()).hexdigest()
-print sys.argv[1], sys.argv[2], hash
View
2 requirements.txt
@@ -1,8 +1,6 @@
-coverage==3.3.1
cssutils==0.9.7
Fabric==0.9.0
nose==0.11.4
-rdflib==3.2.1
simplejson==2.3.0
argparse==1.1
-e git://github.com/mattbasta/fastchardet#egg=fastchardet
View
8 setup.py
@@ -2,13 +2,13 @@
setup(
- name='amo-validator',
+ name='app-validator',
version='1.0',
- description='Validates addons for Mozilla products.',
+ description='Validates open web apps.',
long_description=open('README.rst').read(),
author='Matt Basta',
author_email='me@mattbasta.com',
- url='http://github.com/mattbasta/amo-validator',
+ url='http://github.com/mattbasta/app-validator',
license='BSD',
packages=find_packages(exclude=['tests',
'tests/*',
@@ -19,7 +19,7 @@
install_requires=[p.strip() for p in open('./requirements.txt')
if not p.startswith(('#',
'-e'))],
- scripts=["addon-validator"],
+ scripts=["app-validator"],
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Web Environment',

0 comments on commit ac8e016

Please sign in to comment.