The Add-ons Linter, JS edition.
Here is the canonical list of rules we're working from.
You need node.js to use the add-ons linter.
To validate your add-on locally, install the linter from npm:
# Install globally so you can use the linter from any directory on # your machine. npm install -g addons-linter
After installation, run the linter and direct it to your add-on file:
Alternatively you can point it at a directory:
The 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
;const sourceDir = process;const linter = linter;linter;
linter.output is composed by the following properties (the same of the 'json' report type):
metadata: ...summary:error notice warningscanFilecounterror:type: "error"code message descriptioncolumn file line...warning: ...notice: ...
If 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.
If you have node.js installed, here's the quick start to getting your development dependencies installed and building the binary:
git clone https://github.com/mozilla/addons-linter.git cd addons-linter npm install npm start # Leave running to watch for changes or cancel to stop watching. bin/addons-linter my-addon.zip
addons-linter requires node.js v0.12.x or greater. Using nvm is probably the easiest way to manage multiple node versions side by side. See nvm on github for more details.
Install dependencies with npm:
Dependencies are automatically kept up-to-date using greenkeeper.
Run basic automation tasks via npm scripts (e.g.
These don't need
grunt-cli installed globally.
|npm test||Runs the tests|
|npm start||Builds the lib and watches for changes|
|npm run build||Builds the lib (used by Travis)|
If you install
grunt-cli globally then you can run other tasks.
npm install -g grunt-cli
From the grunt docs:
The job of the Grunt CLI is simple: run the version of Grunt which has been installed next to a Gruntfile. This allows multiple versions of Grunt to be installed on the same machine simultaneously.
|grunt test||Runs the tests|
|grunt test-no-coverage||Runs the tests (without coverage)|
|grunt build||Builds the lib|
|grunt start||Builds the lib and watches for changes|
|grunt eslint||Lints the files with eslint (Run in grunt test)|
You can run
npm start to build the library and then rebuild on file changes.
Once you build the library you can use the CLI in
grunt but don't require global
grunt. Just run
We'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.
Tests using promises should return the promise. This removes the need to call
done() in your tests:
To test for rejection you can use this pattern:
available in tests by default–you don't need to import anything
for those to work.
We're using chai for assertions see the Chai docs for the API available
We use bunyan for logging:
LOG_LEVEL=debug grunt test
LOG_LEVEL=debug grunt test | node_modules/bunyan/bin/bunyan
In 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.
Each file-type has a scanner. For example: CSS files use
files and passes each file through a parser which then hands off to
a set of rules that look for specific things.
Rules 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.
Each 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.
The Collector is an in-memory store for all validation message objects "collected" as the contents of the package are processed.
Each 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.
Lastly when the processing is complete the linter will output the collected data as text or JSON.
We deploy to npm automatically using TravisCI. 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:
After merging the PR, create a new release with the same tag name as your new version. Once the build passes it will deploy. Magic! ✨