Initial commit, from shield-studies-addon-template
This commit is contained in:
Коммит
2a029c1931
|
@ -0,0 +1,3 @@
|
|||
ignorerules:
|
||||
LOW_LEVEL_MODULE: true
|
||||
KNOWN_LIBRARY: true
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"ignore": ["addons-linter", "depcheck-ci", "jpm"],
|
||||
"ignoreDirs": [
|
||||
],
|
||||
"strict": false,
|
||||
"unused": true
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
testing-env
|
||||
coverage
|
|
@ -0,0 +1,19 @@
|
|||
env:
|
||||
browser: true
|
||||
es6: true
|
||||
node: true
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
|
||||
rules:
|
||||
comma-dangle: off
|
||||
eol-last: error
|
||||
eqeqeq: error
|
||||
handle-callback-err: error
|
||||
indent: [error, 2]
|
||||
no-console: off
|
||||
no-unused-vars: [error, {vars: all, args: none}]
|
||||
one-var: [error, never]
|
||||
quotes: [error, single]
|
||||
semi: [error, always]
|
|
@ -0,0 +1,10 @@
|
|||
*.log
|
||||
*.update.rdf
|
||||
*.xpi
|
||||
.DS_Store
|
||||
coverage/
|
||||
deprecated/*
|
||||
npm-shrinkwrap.json
|
||||
node_modules/*
|
||||
test/test-z-ensure-coverage.js
|
||||
testing-env
|
|
@ -0,0 +1,18 @@
|
|||
# start by blocking everything
|
||||
|
||||
*
|
||||
.*
|
||||
|
||||
# allow basic things
|
||||
!/package.json
|
||||
!/icon.png
|
||||
|
||||
## these node modules should ship
|
||||
!/node_modules/shield-studies-addon-utils/**
|
||||
|
||||
## allow in lib and data
|
||||
!/{lib,data}/**
|
||||
|
||||
# but not .DS_Store files!
|
||||
{lib,data}/**/.DS_Store
|
||||
{lib,data}/**/.eslintrc
|
|
@ -0,0 +1,4 @@
|
|||
# special for testing
|
||||
!/node_modules/{deep-eql,type-detect,assertion-error}/**
|
||||
!/node_modules/chai/**
|
||||
!/node_modules/istanbul-jpm/**
|
|
@ -0,0 +1,28 @@
|
|||
sudo: false
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "6"
|
||||
|
||||
env:
|
||||
global:
|
||||
# for screen
|
||||
- DISPLAY=:99.0
|
||||
- TRAVIS=1
|
||||
- JPM_FIREFOX_BINARY=$TRAVIS_BUILD_DIR/../firefox/firefox
|
||||
|
||||
# before_install:
|
||||
# - cd to your src if needed
|
||||
|
||||
before_script:
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- sleep 2 # give xvfb some time to start
|
||||
|
||||
- npm i -g get-firefox
|
||||
- cd ..
|
||||
- get-firefox -ceb unbranded-release
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
|
||||
|
||||
notifications:
|
||||
email: false
|
|
@ -0,0 +1,89 @@
|
|||
module.exports = function (grunt) {
|
||||
var istanbulJpm = require('istanbul-jpm');
|
||||
|
||||
// gross, put this in the process
|
||||
process.env.coveragedir = require('os').tmpdir();
|
||||
console.log('coveragedir: %s', process.env.coveragedir);
|
||||
|
||||
var fxBinary = process.env.JPM_FIREFOX_BINARY || 'Aurora';
|
||||
|
||||
grunt.initConfig({
|
||||
eslint: {
|
||||
files: '**/*.js',
|
||||
options: {
|
||||
quiet: true
|
||||
}
|
||||
},
|
||||
shell: {
|
||||
addonLintTest: {
|
||||
command: 'scripts/addonLintTest',
|
||||
},
|
||||
cleanCoverage: {
|
||||
command: 'rm -rf coverage'
|
||||
},
|
||||
'ensure-files-are-covered': {
|
||||
command: 'scripts/ensure-files-are-covered'
|
||||
},
|
||||
makeTestEnv: {
|
||||
command: 'scripts/makeTestEnv'
|
||||
},
|
||||
jpmTest: {
|
||||
command: 'cd testing-env && node_modules/.bin/jpm test --tbpl -b ' + fxBinary
|
||||
}
|
||||
},
|
||||
instrument: {
|
||||
files: 'lib/**/*.js',
|
||||
options: {
|
||||
lazy: false,
|
||||
basePath: 'coverage/instrument',
|
||||
instrumenter: istanbulJpm.Instrumenter
|
||||
}
|
||||
},
|
||||
storeCoverage: {
|
||||
options: {
|
||||
dir: 'coverage/reports'
|
||||
}
|
||||
},
|
||||
makeReport: {
|
||||
src: 'coverage/reports/**/*.json',
|
||||
options: {
|
||||
type: 'lcov',
|
||||
dir: 'coverage/reports',
|
||||
print: 'detail'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-shell');
|
||||
grunt.loadNpmTasks('grunt-istanbul');
|
||||
|
||||
grunt.registerTask('readcoverageglobal', 'Reads the coverage global JPM wrote', function () {
|
||||
global.__coverage__ = require('istanbul-jpm/global-node').global.__coverage__;
|
||||
grunt.log.ok('Read __coverage__ global');
|
||||
});
|
||||
|
||||
grunt.registerTask('reportLocation', function () {
|
||||
grunt.log.writeln('report at:', 'coverage/reports/lcov-report/index.html'['blue']);
|
||||
});
|
||||
|
||||
grunt.registerTask('coverageReport', [
|
||||
'readcoverageglobal',
|
||||
'storeCoverage',
|
||||
'makeReport',
|
||||
'reportLocation'
|
||||
]);
|
||||
|
||||
grunt.registerTask('jpmtest', [
|
||||
'shell:ensure-files-are-covered',
|
||||
'shell:makeTestEnv',
|
||||
'shell:jpmTest',
|
||||
]);
|
||||
|
||||
grunt.registerTask('test', [
|
||||
'shell:addonLintTest',
|
||||
'shell:cleanCoverage',
|
||||
'instrument',
|
||||
'jpmtest',
|
||||
'coverageReport'
|
||||
]);
|
||||
};
|
|
@ -0,0 +1,55 @@
|
|||
# Base Template for Shield Studies Addons
|
||||
|
||||
## Features
|
||||
|
||||
- `eslint`
|
||||
|
||||
- es6 for lib, data, test
|
||||
- browser, not node for `data/`
|
||||
|
||||
- `addons-linter` with `.addonslinterrc`
|
||||
|
||||
- ci with Travis OR CircleCi (TODO)
|
||||
|
||||
- ability to do code coverage, using `grunt-istanbul` and [`istanbul-jpm`](https://github.com/freaktechnik/istanbul-jpm)
|
||||
|
||||
- uses Grunt to do some of the heavy lifting. Sorry if you hate Grunt. [I do as well](#1).
|
||||
|
||||
- TODO: Allow better build of React type things for front ends
|
||||
|
||||
## General Setup and Install
|
||||
|
||||
1. Clone / copy the directory
|
||||
2. `npm install`
|
||||
|
||||
## Adding a new npm library
|
||||
|
||||
```
|
||||
npm install --save-dev somelibrary
|
||||
#edit .jpmignore to allow it in
|
||||
```
|
||||
|
||||
## Contribute
|
||||
|
||||
Issues on this Github :)
|
||||
|
||||
## Assumptions and Opinions
|
||||
|
||||
1. All code lives in `lib` and is ES6.
|
||||
2. All website stuff (web-workers, ui) lives in `data`
|
||||
3. Index at `lib/index.js`
|
||||
4. Grunt, b/c it makes instrument / coverage easier
|
||||
|
||||
- `grunt-istanbul` + `istanbul-jpm`
|
||||
- if you want or need `make`, `gulp`, `webpack` you absolutely can
|
||||
|
||||
5. All the testing happens in a create `testing-env` folder, so that
|
||||
|
||||
- it can use a custom `.jpmignore` file
|
||||
- it can do coverage with less silliness
|
||||
|
||||
6. As built, the tests will fail, until you fix the facade tests.
|
||||
7. We use `chai` for testing. If you don't, remove it where it happens.
|
||||
8. You are somewhere with some resemblence to Unix cli (Linux or OSX).
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
env:
|
||||
browser: true
|
||||
es6: true
|
||||
node: false
|
||||
worker: true
|
||||
|
||||
extends:
|
||||
- eslint:recommended
|
||||
|
||||
rules:
|
||||
no-console: off # it would be better to find the right env for this
|
|
@ -0,0 +1,17 @@
|
|||
/** feature.js **/
|
||||
const prefSvc = require('sdk/preferences/service');
|
||||
|
||||
const ourpref = 'some.pref.somewhere';
|
||||
|
||||
exports.which = function (val) {
|
||||
prefSvc.set(ourpref, val);
|
||||
return val;
|
||||
};
|
||||
|
||||
exports.isEligible = function () {
|
||||
return !prefSvc.isSet(ourpref);
|
||||
};
|
||||
|
||||
exports.reset = function () {
|
||||
return prefSvc.reset(ourpref);
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
/** index.js **/
|
||||
const self = require('sdk/self');
|
||||
console.log(Object.keys(require('./study')));
|
||||
console.log(Object.keys(require('./study').study));
|
||||
|
||||
require('./study').study.startup(self.loadReason);
|
|
@ -0,0 +1,73 @@
|
|||
/** study.js **/
|
||||
const self = require('sdk/self');
|
||||
const shield = require('shield-studies-addon-utils');
|
||||
const tabs = require('sdk/tabs');
|
||||
const { when: unload } = require('sdk/system/unload');
|
||||
|
||||
const feature = require('./feature');
|
||||
|
||||
const studyConfig = {
|
||||
name: self.addonId,
|
||||
duration: 14,
|
||||
surveyUrls: {
|
||||
'end-of-study': 'some/url',
|
||||
'user-ended-study': 'some/url',
|
||||
'ineligible': null
|
||||
},
|
||||
variations: {
|
||||
'v1': () => feature.which('v1'),
|
||||
'v2': () => feature.which('v2'),
|
||||
'v3': () => feature.which('v3')
|
||||
}
|
||||
};
|
||||
|
||||
class OurStudy extends shield.Study {
|
||||
constructor (config) {
|
||||
super(config);
|
||||
}
|
||||
isEligible () {
|
||||
// bool Already Has the feature. Stops install if true
|
||||
return super.isEligible() && feature.isEligible();
|
||||
}
|
||||
whenIneligible () {
|
||||
super.whenIneligible();
|
||||
// additional actions for 'user isn't eligible'
|
||||
tabs.open('data:text/html,Uninstalling, you are not eligible for this study');
|
||||
}
|
||||
whenInstalled () {
|
||||
super.whenInstalled();
|
||||
// orientation, unless our branch is 'notheme'
|
||||
if (this.variation === 'notheme') {
|
||||
// noop
|
||||
}
|
||||
feature.orientation(this.variation);
|
||||
}
|
||||
cleanup (reason) {
|
||||
super.cleanup(); // cleanup simple-prefs, simple-storage
|
||||
feature.cleanup();
|
||||
// do things, maybe depending on reason, branch
|
||||
}
|
||||
whenComplete () {
|
||||
// when the study is naturally complete after this.days
|
||||
super.whenComplete(); // calls survey, uninstalls
|
||||
}
|
||||
whenUninstalled () {
|
||||
// user uninstall
|
||||
super.whenUninstalled();
|
||||
}
|
||||
decideVariation () {
|
||||
return super.decideVariation(); // chooses at random
|
||||
// unequal or non random allocation for example
|
||||
}
|
||||
}
|
||||
|
||||
const thisStudy = new OurStudy(studyConfig);
|
||||
|
||||
// for testing / linting
|
||||
exports.OurStudy = OurStudy;
|
||||
exports.studyConfig = studyConfig;
|
||||
|
||||
// for use by index.js
|
||||
exports.study = thisStudy;
|
||||
|
||||
unload((reason) => thisStudy.shutdown(reason));
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"name": "shield-study-privacy",
|
||||
"description": "<some feature> as a Shield Study",
|
||||
"version": "1.0.0",
|
||||
"author": "Unknown",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mozilla/shield-study-privacy/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"addons-linter": "^0.15.5",
|
||||
"chai": "^3.5.0",
|
||||
"depcheck-ci": "^1.0.1",
|
||||
"eslint": "^3.6.1",
|
||||
"fixpack": "^2.3.1",
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-cli": "^1.2.0",
|
||||
"grunt-istanbul": "^0.7.0",
|
||||
"grunt-shell": "^1.3.0",
|
||||
"istanbul-jpm": "^0.1.0",
|
||||
"jpm": "^1.0.7",
|
||||
"npm-run-all": "^3.1.0",
|
||||
"nsp": "^2.6.2",
|
||||
"shield-studies-addon-utils": "^2.0.0",
|
||||
"yamljs": "^0.2.8"
|
||||
},
|
||||
"engines": {
|
||||
"firefox": ">=38.0a1",
|
||||
"fennec": ">=38.0a1"
|
||||
},
|
||||
"homepage": "http://github.com/mozilla/shield-study-privacy",
|
||||
"keywords": [
|
||||
"jetpack",
|
||||
"shield-study"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"main": "lib/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/mozilla/shield-study-privacy.git"
|
||||
},
|
||||
"scripts": {
|
||||
"eslint": "grunt eslint",
|
||||
"lint": "npm-run-all lint:*",
|
||||
"lint:depcheck": "depcheck-ci # use coverage to catch missing",
|
||||
"lint:eslint": "eslint .",
|
||||
"lint:fixpack": "fixpack",
|
||||
"lint:nsp": "nsp check",
|
||||
"prepublish": "npm shrinkwrap",
|
||||
"pretest": "npm-run-all lint:*",
|
||||
"test": "grunt test && istanbul check-coverage --statements 100 --functions 100 --branches 100 --lines 100 coverage/reports/coverage.json"
|
||||
},
|
||||
"title": "Template for creating shield study add-ons"
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/*
|
||||
usage:
|
||||
|
||||
```
|
||||
jpm xpi # makes myaddon.xpi
|
||||
npm install addon-linter
|
||||
./node_modules/.bin/addon-linter myaddon.xpi | node addon-lint-consumer.js
|
||||
```
|
||||
|
||||
license: PUBLIC DOMAIN.
|
||||
|
||||
|
||||
//example .addonlinterrc
|
||||
ignorerules:
|
||||
LOW_LEVEL_MODULE: true
|
||||
KNOWN_LIBRARY: true
|
||||
|
||||
*/
|
||||
|
||||
var yamljs = require('yamljs');
|
||||
|
||||
function loadRules (fn) {
|
||||
var ignored = {};
|
||||
try {
|
||||
ignored = (yamljs.load(fn)).ignorerules;
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
return ignored;
|
||||
}
|
||||
|
||||
function filterLint(lint, ignored) {
|
||||
['errors', 'notices', 'warnings'].map(function (k) {
|
||||
var filtered = lint[k].filter(function (seen) {
|
||||
return !(seen.code in ignored);
|
||||
});
|
||||
lint[k] = filtered;
|
||||
});
|
||||
return lint;
|
||||
}
|
||||
|
||||
function output(filteredLint) {
|
||||
var show = 0;
|
||||
['errors', 'notices', 'warnings'].map(function (k) {
|
||||
if (filteredLint[k].length) {
|
||||
show = 1;
|
||||
}
|
||||
});
|
||||
if (show) {
|
||||
console.error(filteredLint);
|
||||
}
|
||||
process.exit(show);
|
||||
}
|
||||
|
||||
function doTheWork(content) {
|
||||
// your code here
|
||||
var ignored = loadRules('.addonlinterrc');
|
||||
output(filterLint(JSON.parse(content),ignored));
|
||||
}
|
||||
|
||||
// read in all the stdin
|
||||
var content = '';
|
||||
process.stdin.resume();
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('data', function (buf) {
|
||||
content += buf.toString();
|
||||
});
|
||||
process.stdin.on('end', function () {
|
||||
// your code here
|
||||
doTheWork(content);
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
set -o nounset
|
||||
set -o errexit
|
||||
|
||||
node_modules/.bin/jpm xpi
|
||||
node_modules/.bin/addons-linter --output json --pretty *xpi |\
|
||||
node scripts/addon-lint-consumer.js
|
||||
|
||||
echo "OK" $0
|
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
set -o nounset
|
||||
set -o errexit
|
||||
|
||||
cat << DONE > test/test-z-ensure-coverage.js
|
||||
// automatically created by makeCoverageTest
|
||||
DONE
|
||||
|
||||
git ls-tree -r HEAD --name-only lib | \
|
||||
grep "js$" | \
|
||||
xargs -I '{}' echo "require('../{}');" | \
|
||||
egrep -v "(jetpack|index.js|main.js)" >> test/test-z-ensure-coverage.js
|
||||
|
||||
echo "OK" $0
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
set -o nounset
|
||||
set -o errexit
|
||||
|
||||
rm -rf testing-env
|
||||
mkdir testing-env
|
||||
cd testing-env
|
||||
cat ../.jpmignore ../.jpmignore-testing-env > .jpmignore
|
||||
ln -s ../Gruntfile.js .
|
||||
ln -s ../node_modules .
|
||||
ln -s ../data .
|
||||
ln -s ../coverage/instrument/lib .
|
||||
ln -s ../package.json .
|
||||
ln -s ../test .
|
||||
echo "OK" $0
|
|
@ -0,0 +1,6 @@
|
|||
// all the usual gregg questions
|
||||
|
||||
// grep for surveyUrl
|
||||
// where is the variations?
|
||||
|
||||
// livecheck all the SG urls
|
|
@ -0,0 +1,12 @@
|
|||
//var main = require("../");
|
||||
|
||||
exports['test main'] = function(assert) {
|
||||
assert.pass('Unit test running!');
|
||||
};
|
||||
|
||||
exports['test main async'] = function(assert, done) {
|
||||
assert.pass('async Unit test running!');
|
||||
done();
|
||||
};
|
||||
|
||||
require('sdk/test').run(exports);
|
Загрузка…
Ссылка в новой задаче