grunt-banana-checker
Advanced tools
Comparing version 0.6.0 to 0.7.0
@@ -1,25 +0,14 @@ | ||
/*! | ||
* Grunt file | ||
*/ | ||
/*jshint node:true */ | ||
/* eslint-env node */ | ||
module.exports = function ( grunt ) { | ||
grunt.loadNpmTasks( 'grunt-contrib-jshint' ); | ||
grunt.loadNpmTasks( 'grunt-eslint' ); | ||
grunt.loadNpmTasks( 'grunt-contrib-watch' ); | ||
grunt.loadNpmTasks( 'grunt-jscs' ); | ||
grunt.loadTasks( './tasks/' ); | ||
grunt.initConfig( { | ||
jshint: { | ||
options: { | ||
jshintrc: true | ||
}, | ||
all: [ '*.js', '{tasks,test}/**/*.js' ] | ||
eslint: { | ||
all: '.' | ||
}, | ||
jscs: { | ||
src: '<%= jshint.all %>' | ||
}, | ||
banana: { | ||
simple: 'test/simple', | ||
lesssimple: { | ||
testSimple: 'test/simple', | ||
testLessSimple: { | ||
src: 'test/simple', | ||
@@ -31,3 +20,3 @@ options: { | ||
}, | ||
advanced: { | ||
testAdvanced: { | ||
src: 'test/advanced/{a,b}', | ||
@@ -39,3 +28,3 @@ options: { | ||
}, | ||
disallowEmptyDocumentation: { | ||
testAllowingEmptyDocumentation: { | ||
src: 'test/disallowEmptyDocumentation', | ||
@@ -46,3 +35,3 @@ options: { | ||
}, | ||
disallowUnusedDocumentation: { | ||
testAllowingUnusedDocumentation: { | ||
src: 'test/disallowUnusedDocumentation', | ||
@@ -53,3 +42,3 @@ options: { | ||
}, | ||
requireCompleteMessageDocumentation: { | ||
testNotRequiringCompleteMessageDocumentation: { | ||
src: 'test/requireCompleteMessageDocumentation', | ||
@@ -60,3 +49,3 @@ options: { | ||
}, | ||
requireMetadata: { | ||
testNotRequiringMetadata: { | ||
src: 'test/requireMetadata', | ||
@@ -67,3 +56,3 @@ options: { | ||
}, | ||
skipIncompleteMessageDocumentation: { | ||
testSkippingIncompleteMessageDocumentation: { | ||
src: 'test/skipIncompleteMessageDocumentation', | ||
@@ -76,6 +65,36 @@ options: { | ||
} | ||
}, | ||
testAllowMixedCaseButLowerInitial: { | ||
src: 'test/requireLowerCase/initial', | ||
options: { | ||
requireLowerCase: 'initial' | ||
} | ||
}, | ||
testAllowMixedCase: { | ||
src: 'test/requireLowerCase/full', | ||
options: { | ||
requireLowerCase: false | ||
} | ||
}, | ||
testRequiringSingleKeyPrefix: { | ||
src: 'test/requireKeyPrefix/single', | ||
options: { | ||
requireKeyPrefix: [ 'alice' ] | ||
} | ||
}, | ||
testRequiringSingleKeyPrefixShucked: { | ||
src: 'test/requireKeyPrefix/single', | ||
options: { | ||
requireKeyPrefix: 'alice' | ||
} | ||
}, | ||
testRequiringMultipleKeyPrefices: { | ||
src: 'test/requireKeyPrefix/multiple', | ||
options: { | ||
requireKeyPrefix: [ 'alice', 'bob', 'timmy' ] | ||
} | ||
} | ||
}, | ||
watch: { | ||
files: [ '<%= jshint.all %>', '.{jshintrc,jshintignore}' ], | ||
files: [ '<%= eslint.all %>', '.{eslintrc.json}' ], | ||
tasks: [ 'test' ] | ||
@@ -85,4 +104,4 @@ } | ||
grunt.registerTask( 'test', [ 'jshint', 'jscs', 'banana' ] ); | ||
grunt.registerTask( 'test', [ 'eslint', 'banana' ] ); | ||
grunt.registerTask( 'default', 'test' ); | ||
}; |
@@ -1,4 +0,16 @@ | ||
# grunt-banana-checker Release History | ||
v0.7.0 / 2019-01-08 | ||
================== | ||
## v0.5.0 / 2016-03-18 | ||
* Add check for message key case validity (James D. Forrester) | ||
* Add option to require a message key prefix (James D. Forrester) | ||
* build: Replace jshint and jscs with eslint (James D. Forrester) | ||
v0.6.0 / 2017-03-01 | ||
================== | ||
* Allow skipping keys that don't have message documentation (Kunal Mehta) | ||
v0.5.0 / 2016-03-18 | ||
================== | ||
* Don't crash when encountering file names that contain '.json' in the middle (Roan Kattouw) | ||
@@ -8,3 +20,5 @@ * Extract the regex for a JSON filename (James Forrester) | ||
## v0.4.0 / 2015-10-06 | ||
v0.4.0 / 2015-10-06 | ||
================== | ||
* Make disallowUnusedTranslations default to false (Ed Sanders) | ||
@@ -17,3 +31,5 @@ * Make disallowDuplicateTranslations default to false (Ed Sanders) | ||
## v0.3.0 / 2015-09-01 | ||
v0.3.0 / 2015-09-01 | ||
================== | ||
* Fail if the target directory doesn't exist (James D. Forrester) | ||
@@ -25,3 +41,5 @@ * Allow individual checks to be disabled in config (James D. Forrester) | ||
## v0.2.2 / 2015-06-05 | ||
v0.2.2 / 2015-06-05 | ||
================== | ||
* Fix off-by-one error in counting the number of messages (Kunal Mehta) | ||
@@ -32,3 +50,5 @@ * build: Bump devDep grunt-contrib-jshint to 0.11.2 (James D. Forrester) | ||
## v0.2.1 / 2015-03-27 | ||
v0.2.1 / 2015-03-27 | ||
================== | ||
* Fix catastrophic logic error (James D. Forrester) | ||
@@ -39,3 +59,5 @@ * build: Owner has moved from me to Wikimedia (James D. Forrester) | ||
## v0.2.0 / 2014-08-31 | ||
v0.2.0 / 2014-08-31 | ||
================== | ||
* task: Fail if a documentation message is blank or whitespace-only (James D. Forrester) | ||
@@ -46,3 +68,5 @@ * task: Fail if a documentation message has no matching source message (James D. Forrester) | ||
## v0.1.0 / 2014-04-04 | ||
v0.1.0 / 2014-04-04 | ||
================== | ||
* Initial release (James D. Forrester) |
{ | ||
"name": "grunt-banana-checker", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"description": "A grunt checker for the \"banana\" JSON i18n system provided by MediaWiki and jquery.i18n", | ||
@@ -12,2 +12,3 @@ "scripts": { | ||
}, | ||
"homepage": "https://github.com/wikimedia/grunt-banana-checker", | ||
"keywords": [ | ||
@@ -22,10 +23,8 @@ "gruntplugin", | ||
}, | ||
"homepage": "https://github.com/wikimedia/grunt-banana-checker", | ||
"devDependencies": { | ||
"grunt": "0.4.5", | ||
"grunt-cli": "0.1.13", | ||
"grunt-contrib-jshint": "1.0.0", | ||
"grunt-contrib-watch": "1.0.0", | ||
"grunt-jscs": "2.8.0" | ||
"eslint-config-wikimedia": "0.10.0", | ||
"grunt": "1.0.3", | ||
"grunt-contrib-watch": "1.1.0", | ||
"grunt-eslint": "21.0.0" | ||
} | ||
} |
@@ -68,2 +68,16 @@ [![NPM version](https://badge.fury.io/js/grunt-banana-checker.svg)](http://badge.fury.io/js/grunt-banana-checker) [![Build Status](https://travis-ci.org/wikimedia/grunt-banana-checker.svg?branch=master)](https://travis-ci.org/wikimedia/grunt-banana-checker) | ||
#### requireLowerCase | ||
Type: `boolean` or `"initial"` | ||
Default value: `true` | ||
Whether to fail if any message key is not lower case. If set to `"initial"`, fail only if the first | ||
character is not lower case. | ||
#### requireKeyPrefix | ||
Type: `string` or `string[]` | ||
Default value: `[]` | ||
Whether to fail if any message key is not prefixed by the given prefix, or if multiple, one of the | ||
given prefices. | ||
#### disallowUnusedDocumentation | ||
@@ -111,3 +125,3 @@ Type: `boolean` | ||
[OOjs UI](https://www.mediawiki.org/wiki/VisualEditor) uses this on [a single directory of messages](http://git.wikimedia.org/blob/oojs%2Fui.git/HEAD/Gruntfile.js): | ||
[OOjs UI](https://www.mediawiki.org/wiki/VisualEditor) uses this on [a single directory of messages](https://phabricator.wikimedia.org/diffusion/GOJU/browse/master/Gruntfile.js): | ||
@@ -120,3 +134,3 @@ <pre lang=js> | ||
[VisualEditor](https://www.mediawiki.org/wiki/VisualEditor)'s MediaWiki extension uses this on [two directories as a single test](https://git.wikimedia.org/blob/mediawiki%2Fextensions%2FVisualEditor.git/HEAD/Gruntfile.js): | ||
[VisualEditor](https://www.mediawiki.org/wiki/VisualEditor)'s MediaWiki extension uses this on [two directories as a single test](https://phabricator.wikimedia.org/diffusion/EVED/browse/master/Gruntfile.js): | ||
@@ -129,3 +143,3 @@ <pre lang=js> | ||
[MediaWiki](https://www.mediawiki.org/wiki/MediaWiki) uses this on [two directories as different tests](https://git.wikimedia.org/blob/mediawiki%2Fcore.git/HEAD/tests%2Ffrontend%2FGruntfile.js) – one for the main software and another for the installer: | ||
[MediaWiki](https://www.mediawiki.org/wiki/MediaWiki) uses this on [two directories as different tests](https://phabricator.wikimedia.org/source/mediawiki/browse/master/Gruntfile.js) – one for the main software and another for the installer: | ||
@@ -132,0 +146,0 @@ <pre lang=js> |
@@ -5,3 +5,3 @@ /*! | ||
/*jshint node:true */ | ||
/* eslint-env node */ | ||
module.exports = function ( grunt ) { | ||
@@ -25,2 +25,5 @@ grunt.registerMultiTask( 'banana', function () { | ||
requireLowerCase: true, | ||
requireKeyPrefix: [], | ||
requireCompleteTranslationLanguages: [], | ||
@@ -52,2 +55,4 @@ requireCompleteTranslationMessages: [], | ||
sourceMessageMissing = [], | ||
sourceMessageWrongCase = [], | ||
sourceMessageWrongPrefix = [], | ||
count = 0; | ||
@@ -68,2 +73,3 @@ | ||
} | ||
function keysNoMetadata( messageArray, type ) { | ||
@@ -92,2 +98,3 @@ var keys, offset; | ||
} | ||
sourceMessages = messages( options.sourceFile, 'source' ); | ||
@@ -149,2 +156,23 @@ sourceMessageKeys = keysNoMetadata( sourceMessages, 'source' ); | ||
if ( options.requireLowerCase === 'initial' ) { | ||
sourceMessageWrongCase = sourceMessageKeys.filter( function ( value ) { | ||
return ( value !== '' && value[ 0 ] !== value[ 0 ].toLowerCase() ); | ||
} ); | ||
} else if ( options.requireLowerCase ) { | ||
sourceMessageWrongCase = sourceMessageKeys.filter( function ( value ) { | ||
return value !== value.toLowerCase(); | ||
} ); | ||
} | ||
if ( options.requireKeyPrefix.length ) { | ||
if ( typeof options.requireKeyPrefix === 'string' ) { | ||
options.requireKeyPrefix = [ options.requireKeyPrefix ]; | ||
} | ||
sourceMessageWrongPrefix = sourceMessageKeys.filter( function ( key ) { | ||
return !options.requireKeyPrefix.some( function ( prefix ) { | ||
return key.startsWith( prefix ); | ||
} ); | ||
} ); | ||
} | ||
while ( sourceMessageKeys.length > 0 ) { | ||
@@ -202,2 +230,48 @@ message = sourceMessageKeys[ 0 ]; | ||
count = sourceMessageWrongCase.length; | ||
if ( count > 0 ) { | ||
ok = false; | ||
if ( options.requireLowerCase === 'initial' ) { | ||
grunt.log.error( | ||
count + ' message' + ( count > 1 ? 's do' : ' does' ) + ' not start with a lowercase character.' | ||
); | ||
sourceMessageWrongCase.forEach( function ( message ) { | ||
grunt.log.error( 'Message "' + message + '" should start with a lowercase character.' ); | ||
} ); | ||
} else { | ||
grunt.log.error( | ||
count + ' message' + ( count > 1 ? 's are' : ' is' ) + ' not wholly lowercase.' | ||
); | ||
sourceMessageWrongCase.forEach( function ( message ) { | ||
grunt.log.error( 'Message "' + message + '" should be in lowercase.' ); | ||
} ); | ||
} | ||
} | ||
count = sourceMessageWrongPrefix.length; | ||
if ( count > 0 ) { | ||
ok = false; | ||
if ( options.requireKeyPrefix.length === 1 ) { | ||
grunt.log.error( | ||
count + ' message' + ( count > 1 ? 's do' : ' does' ) + ' not start with the required prefix "' + options.requireKeyPrefix[ 0 ] + '".' | ||
); | ||
sourceMessageWrongPrefix.forEach( function ( message ) { | ||
grunt.log.error( 'Message "' + message + '" should start with the required prefix "' + options.requireKeyPrefix[ 0 ] + '".' ); | ||
} ); | ||
} else { | ||
grunt.log.error( | ||
count + ' message' + ( count > 1 ? 's do' : ' does' ) + ' not start with any of the required prefices.' | ||
); | ||
sourceMessageWrongPrefix.forEach( function ( message ) { | ||
grunt.log.error( 'Message "' + message + '" should start with one of the required prefices.' ); | ||
} ); | ||
} | ||
} | ||
if ( options.disallowUnusedDocumentation ) { | ||
@@ -219,2 +293,3 @@ count = documentationMessageKeys.length; | ||
for ( index in translatedData ) { | ||
// eslint-disable-next-line no-prototype-builtins | ||
if ( !translatedData.hasOwnProperty( index ) ) { | ||
@@ -228,9 +303,9 @@ continue; | ||
ok = false; | ||
grunt.log.error( 'The "' + index + '" translation has ' + count + ' blank translation' + ( count > 1 ? 's' : '' ) + ':' ); | ||
// jshint -W083 | ||
grunt.log.error( | ||
'The "' + index + '" translation has ' + count + ' blank translation' + | ||
( count > 1 ? 's' : '' ) + ':' | ||
); | ||
translatedData[ index ].blank.forEach( function ( message ) { | ||
grunt.log.error( 'The translation of "' + message + '" is blank.' ); | ||
} ); | ||
// jshint +W083 | ||
} | ||
@@ -243,9 +318,9 @@ } | ||
ok = false; | ||
grunt.log.error( 'The "' + index + '" translation has ' + count + ' duplicate translation' + ( count > 1 ? 's' : '' ) + ':' ); | ||
// jshint -W083 | ||
grunt.log.error( | ||
'The "' + index + '" translation has ' + count + ' duplicate translation' + | ||
( count > 1 ? 's' : '' ) + ':' | ||
); | ||
translatedData[ index ].duplicate.forEach( function ( message ) { | ||
grunt.log.error( 'The translation of "' + message + '" is a duplicate of the primary message.' ); | ||
grunt.log.error( 'The translation of "' + message + '" duplicates the primary message.' ); | ||
} ); | ||
// jshint +W083 | ||
} | ||
@@ -258,9 +333,10 @@ } | ||
ok = false; | ||
grunt.log.error( 'The "' + index + '" translation has ' + count + ' unused translation' + ( count > 1 ? 's' : '' ) + ':' ); | ||
grunt.log.error( | ||
'The "' + index + '" translation has ' + count + ' unused translation' + | ||
( count > 1 ? 's' : '' ) + ':' | ||
); | ||
// jshint -W083 | ||
translatedData[ index ].unused.forEach( function ( message ) { | ||
grunt.log.error( 'The translation of "' + message + '" is unused.' ); | ||
} ); | ||
// jshint +W083 | ||
} | ||
@@ -274,2 +350,3 @@ } | ||
if ( | ||
// eslint-disable-next-line no-prototype-builtins | ||
!translatedData.hasOwnProperty( index ) || | ||
@@ -286,7 +363,5 @@ ( options.requireCompleteTranslationLanguages.indexOf( index ) === -1 ) | ||
// jshint -W083 | ||
translatedData[ index ].missing.forEach( function ( message ) { | ||
grunt.log.error( 'The translation of "' + message + '" is missing.' ); | ||
} ); | ||
// jshint +W083 | ||
} | ||
@@ -298,2 +373,3 @@ } | ||
for ( index in translatedData ) { | ||
// eslint-disable-next-line no-prototype-builtins | ||
if ( !translatedData.hasOwnProperty( index ) ) { | ||
@@ -304,2 +380,3 @@ continue; | ||
for ( message in translatedData[ index ].missing ) { | ||
// eslint-disable-next-line no-prototype-builtins | ||
if ( !translatedData[ index ].missing.hasOwnProperty( sourceMessageKeys[ message ] ) ) { | ||
@@ -321,7 +398,5 @@ continue; | ||
// jshint -W083 | ||
translatedData[ index ].missing.forEach( function ( message ) { | ||
grunt.log.error( 'The required message "' + message + '" is missing.' ); | ||
} ); | ||
// jshint +W083 | ||
} | ||
@@ -328,0 +403,0 @@ } |
Sorry, the diff of this file is not supported yet
30627
4
35
667
158