{"id":13476466,"url":"https://github.com/mozilla/addons-linter","last_synced_at":"2025-05-14T04:09:40.972Z","repository":{"id":37556096,"uuid":"42436885","full_name":"mozilla/addons-linter","owner":"mozilla","description":"🔍 Firefox Add-ons linter, written in JavaScript. 👁","archived":false,"fork":false,"pushed_at":"2025-05-07T11:38:43.000Z","size":32491,"stargazers_count":333,"open_issues_count":67,"forks_count":146,"subscribers_count":33,"default_branch":"master","last_synced_at":"2025-05-08T09:34:12.447Z","etag":null,"topics":["cli","web-extensions"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mozilla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-09-14T08:34:44.000Z","updated_at":"2025-04-30T14:27:45.000Z","dependencies_parsed_at":"2023-02-19T06:46:05.561Z","dependency_job_id":"35781ff6-3bad-4c7d-882f-33efdd05b492","html_url":"https://github.com/mozilla/addons-linter","commit_stats":{"total_commits":4861,"total_committers":230,"mean_commits":21.13478260869565,"dds":0.7876980045258177,"last_synced_commit":"72c1c2c04a12ac6c0e69a7c0a9672a85e413f65d"},"previous_names":["mozilla/addons-validator"],"tags_count":319,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mozilla%2Faddons-linter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mozilla%2Faddons-linter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mozilla%2Faddons-linter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mozilla%2Faddons-linter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mozilla","download_url":"https://codeload.github.com/mozilla/addons-linter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253807544,"owners_count":21967379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","web-extensions"],"created_at":"2024-07-31T16:01:30.769Z","updated_at":"2025-05-14T04:09:40.931Z","avatar_url":"https://github.com/mozilla.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Testing","Projects using BCD"],"sub_categories":["VSCode extension for contributors"],"readme":"[![CircleCI](https://circleci.com/gh/mozilla/addons-linter.svg?style=svg)](https://circleci.com/gh/mozilla/addons-linter) [![codecov](https://codecov.io/gh/mozilla/addons-linter/branch/master/graph/badge.svg)](https://codecov.io/gh/mozilla/addons-linter) [![npm version](https://badge.fury.io/js/addons-linter.svg)](https://badge.fury.io/js/addons-linter)\n\n# addons-linter\n\nThe Add-ons Linter is being used by [web-ext](https://github.com/mozilla/web-ext/) and [addons.mozilla.org](https://github.com/mozilla/addons-server/) to lint [WebExtensions](https://developer.mozilla.org/en-US/Add-ons/WebExtensions).\n\nIt can also be used as a standalone binary and library.\n\nYou can find more information about the linter and it's implemented rules in our [documentation](https://mozilla.github.io/addons-linter/).\n\n## Usage\n\n### Command Line\n\nYou need Node.js to use the add-ons linter.\n\nTo validate your add-on locally, install the linter from [npm](http://nodejs.org/):\n\n```sh\n# Install globally so you can use the linter from any directory on\n# your machine.\nnpm install -g addons-linter\n```\n\nAfter installation, run the linter and direct it to your add-on file:\n\n```sh\naddons-linter my-addon.zip\n```\n\nAlternatively you can point it at a directory:\n\n```sh\naddons-linter my-addon/src/\n```\n\nThe addons-linter will check your add-on and show you errors, warnings, and friendly messages for your add-on. If you want more info on the options you can enable/disable for the command-line app, use the `--help` option:\n\n```sh\naddons-linter --help\n```\n\n#### Privileged extensions\n\nThe addons-linter can lint privileged extensions **only** when the `--privileged` option is passed to it. This option changes the behavior of the linter to:\n\n1. emit errors when the input file (or directory) is a regular extension (i.e. the extension does not use privileged features)\n2. hide messages related to privileged features (e.g., permissions and properties) when the input file (or directory) is a privileged extension\n\n### Linter API Usage\n\nYou can use the linter directly as a library to integrate it better into your development process.\n\n```js\nimport linter from 'addons-linter';\n\nconst sourceDir = process.cwd();\n\nconst linter = linter.createInstance({\n  config: {\n    // This mimics the first command line argument from yargs,\n    // which should be the directory to the extension.\n    _: [sourceDir],\n    logLevel: process.env.VERBOSE ? 'debug' : 'fatal',\n    stack: Boolean(process.env.VERBOSE),\n    pretty: false,\n    warningsAsErrors: false,\n    metadata: false,\n    output: 'none',\n    boring: false,\n    selfHosted: false,\n    // Exclude files:\n    shouldScanFile: (fileName) =\u003e true,\n  },\n  // This prevent the linter to exit the nodejs application\n  runAsBinary: false,\n});\n\nlinter.run()\n  .then((linterResults) =\u003e ...)\n  .catch((err) =\u003e console.error(\"addons-linter failure: \", err));\n```\n\n`linter.output` is composed by the following properties (the same of the 'json' report type):\n\n```js\n{\n  metadata: {...},\n  summary: {\n    error, notice, warning,\n  },\n  count,\n  error: [{\n    type: \"error\",\n    code, message, description,\n    column, file, line\n  }, ...],\n  warning: [...],\n  notice: [...]\n}\n```\n\n## Development\n\nIf you'd like to help us develop the addons-linter, that's great! It's pretty easy to get started, you just need Node.js installed on your machine.\n\n### Quick Start\n\nIf you have Node.js installed, here's the quick start to getting your development dependencies installed and running the tests\n\n```sh\ngit clone https://github.com/mozilla/addons-linter.git\ncd addons-linter\nnpm install\n# Build the project.\nnpm run build\n# Run the test-suite and watch for changes. Use `npm run test-once` to\n# just run it once.\nnpm run test\n```\n\nYou can also build the addons-linter binary to test your changes.\n\n```sh\nnpm run build\n# Now run it against your add-on. Please note that for every change\n# in the linter itself you'll have to re-build the linter.\nbin/addons-linter my-addon.zip\n```\n\n### Required Node version\n\naddons-linter requires Node.js v16 or greater. Have a look at our `.circleci/config.yml` file which Node.js versions we officially test.\n\nUsing nvm is probably the easiest way to manage multiple Node versions side by side. See [nvm on GitHub](https://github.com/creationix/nvm) for more details.\n\n### Install dependencies\n\nInstall dependencies with npm:\n\n```sh\nnpm install\n```\n\n#### npm scripts\n\n| Script                          | Description                                                                      |\n| ------------------------------- | -------------------------------------------------------------------------------- |\n| npm test                        | Runs the tests (watches for changes)                                             |\n| npm [run] build                 | Builds the lib (used by CI)                                                      |\n| npm run test-coverage           | Runs the tests with coverage (watches for changes)                               |\n| npm run test-once               | Runs the tests once                                                              |\n| npm run lint                    | Runs ESLint                                                                      |\n| npm run test-coverage-once      | Runs the tests once with coverage                                                |\n| npm run test-integration-linter | Runs our integration test-suite                                                  |\n| npm run prettier                | Automatically format the whole code-base with Prettier                           |\n| npm run prettier-ci             | Run [Prettier][] and fail if some code has been changed without being formatted  |\n| npm run prettier-dev            | Automatically compare and format modified source files against the master branch |\n\n### Building\n\nYou can run `npm run build` to build the library.\n\nOnce you build the library you can use the CLI in `bin/addons-linter`.\n\n### Testing\n\nRun `npm test`. This will watch for file-changes and re-runs the test suite.\n\n#### Coverage\n\nWe're looking to maintain coverage at 100%. Use the coverage data in the test output to work out what lines aren't covered and ensure they're covered.\n\n#### Assertions and testing APIs\n\nWe are using using Sinon for assertions, mocks, stubs and more [see the Sinon docs for the API available](http://sinonjs.org/).\n\n[Jest](https://facebook.github.io/jest/) is being used as a test-runner but also provides helpful tools. Please make sure you read their documentation for more details.\n\n### Logging\n\nWe use [pino](https://github.com/pinojs/pino) for logging:\n\n- By default logging is off (level is set to 'fatal') .\n- Logging in tests can be enabled using an env var e.g: `LOG_LEVEL=debug jest test`\n- Logging on the CLI can be enabled with `--log-level [level]`.\n\n### Prettier\n\nWe use [Prettier](https://prettier.io/) to automatically format our JavaScript code and stop all the on-going debates over styles. As a developer, you have to run it (with `npm run prettier-dev`) before submitting a Pull Request.\n\n## Architecture\n\nIn a nutshell the way the linter works is to take an add-on package, extract the metadata from the xpi (zip) format and then process the files it finds through various content scanners.\n\nWe are heavily relying on [ESLint](https://eslint.org/) for JavaScript linting, [cheerio](https://github.com/cheeriojs/cheerio) for HTML parsing as well as [fluent.js](https://github.com/projectfluent/fluent.js) for parsing language packs.\n\n### Scanners\n\nEach file-type has a scanner. For example: JavaScript files use `JavaScriptScanner`. Each scanner looks at relevant files and passes each file through a parser which then hands off to a set of rules that look for specific things.\n\n### Rules\n\nRules get exported via a single function in a single file. A rule can have private functions it uses internally, but rule code should not depend on another rule file and each rule file should export one rule.\n\nEach rule function is passed data from the scanner in order to carry out the specific checks for that rule it returns a list of objects which are then made into message objects and are passed to the Collector.\n\n### Collector\n\nThe Collector is an in-memory store for all validation message objects \"collected\" as the contents of the package are processed.\n\n### Messages\n\nEach message has a code which is also its key. It has a message which is a short outline of what the message represents, and a description which is more detail into why that message was logged. The type of the message is set as messages are added so that if necessary the same message could be an error _or_ a warning for example.\n\n### Output\n\nLastly when the processing is complete the linter will output the collected data as text or JSON.\n\n## Deploys\n\nWe deploy to npm automatically using Circle CI. To release a new version, increment the version in `package.json` and create a PR. Make sure your version number conforms to the [semver][] format eg: `0.2.1`.\n\nAfter merging the PR, [create a new release][new release] with the same tag name as your new version. Once the build passes it will deploy. Magic! ✨\n\n## Dispensary\n\nAs of November 2021, [dispensary](https://github.com/mozilla/dispensary) has been merged into this project and a CLI is available by running `./scripts/dispensary`.\n\n### Libraries updates\n\nThis is the (manual) process to update the \"dispensary\" libraries:\n\n1. Open `src/dispensary/libraries.json`\n2. Open the release pages of each library. Here is a list:\n\n\u003c!--RELEASE_PAGES_START--\u003e\n\n- https://github.com/angular/angular.js/releases\n- https://github.com/jashkenas/backbone/releases\n- https://github.com/twbs/bootstrap/releases\n- https://download.dojotoolkit.org/\n- https://github.com/cure53/DOMPurify/releases\n- https://github.com/jquery/jquery/releases\n- https://github.com/jquery/jquery-ui/releases\n- https://github.com/moment/moment/releases\n- https://github.com/mootools/mootools-core/releases\n- http://prototypejs.org/\n- https://github.com/facebook/react/releases\n- https://github.com/jashkenas/underscore/releases\n- https://github.com/mozilla/webextension-polyfill/releases\n\n\u003c!--RELEASE_PAGES_END--\u003e\n\n3. On each page, check whether there are newer release versions than what is in `src/dispensary/libraries.json`. Note that some libraries, like react, support several versions, so we need to check each \"branch\".\n4. For major upgrades, take a quick look at the code changes\n5. Add new versions to `src/dispensary/libraries.json`\n6. Run `npm run update-hashes`\n7. Commit the changes in `src/dispensary/libraries.json`and `src/dispensary/hashes.txt`\n8. Open a Pull Request\n\nNote: `hashes.txt` will be embedded into the addons-linter bundle.\n\nThe `scripts/update-dispensary-doc` command updates the list of release pages above based on the `src/dispensary/libraries.json` file.\n\n## License\n\nThis source code is available under the [Mozilla Public License 2.0](LICENSE).\n\nAdditionally, parts of the schema files originated from Chromium source code:\n\n\u003e Copyright (c) 2012 The Chromium Authors. All rights reserved.\n\u003e Use of this source code is governed by a BSD-style license that can be\n\u003e found in the [LICENSE-CHROMIUM](src/schema/imported/LICENSE-CHROMIUM) file.\n\nYou are not granted rights or licenses to the trademarks of the\nMozilla Foundation or any party, including without limitation the\nFirefox name or logo.\n\nFor more information, see: https://www.mozilla.org/foundation/licensing.html\n\n[new release]: https://github.com/mozilla/addons-linter/releases/new\n[semver]: http://semver.org/\n[prettier]: https://prettier.io/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmozilla%2Faddons-linter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmozilla%2Faddons-linter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmozilla%2Faddons-linter/lists"}