Merge "Add namespace to maintenance/includes classes"
[mediawiki.git] / Gruntfile.js
blob6d59f54e42144282ff85c3595c7a4fcff20917fa
1 'use strict';
2 module.exports = function ( grunt ) {
3         grunt.loadNpmTasks( 'grunt-banana-checker' );
4         grunt.loadNpmTasks( 'grunt-eslint' );
5         grunt.loadNpmTasks( 'grunt-karma' );
6         grunt.loadNpmTasks( 'grunt-stylelint' );
8         const fs = require( 'fs' );
9         const wgServer = process.env.MW_SERVER;
10         const wgScriptPath = process.env.MW_SCRIPT_PATH;
11         const karmaProxy = {};
13         let qunitURL = wgServer + wgScriptPath + '/index.php?title=Special:JavaScriptTest/qunit/export';
15         // "MediaWiki" for core, or extension/skin name (e.g. "GrowthExperiments")
16         const qunitComponent = grunt.option( 'qunit-component' );
17         const qunitWatch = grunt.option( 'qunit-watch' ) || false;
18         const qunitWatchFiles = [];
19         if ( qunitComponent ) {
20                 qunitURL = qunitURL + '&component=' + qunitComponent;
21         }
22         if ( qunitWatch ) {
23                 if ( !qunitComponent || qunitComponent === 'MediaWiki' ) {
24                         // MediaWiki core
25                         qunitWatchFiles.push( 'tests/qunit/**' );
26                         qunitWatchFiles.push( 'resources/**' );
27                 } else {
28                         // one extension or skin
29                         const extPath = __dirname + '/extensions/' + qunitComponent + '/extension.json';
30                         const skinPath = __dirname + '/skins/' + qunitComponent + '/skin.json';
31                         // eslint-disable-next-line security/detect-non-literal-fs-filename
32                         if ( fs.existsSync( extPath ) ) {
33                                 qunitWatchFiles.push( 'extensions/' + qunitComponent + '/extension.json' );
34                                 qunitWatchFiles.push( 'extensions/' + qunitComponent + '/{modules,resources,tests}/**' );
35                         }
36                         // eslint-disable-next-line security/detect-non-literal-fs-filename
37                         if ( fs.existsSync( skinPath ) ) {
38                                 qunitWatchFiles.push( 'skins/' + qunitComponent + '/skin.json' );
39                                 qunitWatchFiles.push( 'skins/' + qunitComponent + '/{modules,resources,tests}/**' );
40                         }
41                 }
42         }
44         karmaProxy[ wgScriptPath ] = {
45                 target: wgServer + wgScriptPath,
46                 changeOrigin: true
47         };
49         grunt.initConfig( {
50                 eslint: {
51                         options: {
52                                 extensions: [ '.js', '.json', '.vue' ],
53                                 cache: true,
54                                 fix: grunt.option( 'fix' )
55                         },
56                         all: '.'
57                 },
58                 banana: {
59                         options: {
60                                 requireLowerCase: false,
61                                 disallowBlankTranslations: false
62                         },
63                         core: 'languages/i18n/',
64                         codex: 'languages/i18n/codex/',
65                         exif: 'languages/i18n/exif/',
66                         preferences: 'languages/i18n/preferences/',
67                         api: 'includes/api/i18n/',
68                         rest: 'includes/Rest/i18n/',
69                         installer: 'includes/installer/i18n/',
70                         paramvalidator: 'includes/libs/ParamValidator/i18n/'
71                 },
72                 stylelint: {
73                         options: {
74                                 reportNeedlessDisables: true
75                         },
76                         resources: 'resources/src/**/*.{css,less,vue}',
77                         config: 'mw-config/**/*.css'
78                 },
79                 watch: {
80                         files: [
81                                 '.{stylelintrc,eslintrc}.json',
82                                 '**/*',
83                                 '!{extensions,node_modules,skins,vendor}/**'
84                         ],
85                         tasks: 'test'
86                 },
87                 karma: {
88                         options: {
89                                 plugins: [
90                                         '@wikimedia/karma-firefox-launcher',
91                                         'karma-*'
92                                 ],
93                                 customLaunchers: {
94                                         ChromeCustom: {
95                                                 base: 'ChromeHeadless',
96                                                 // Chrome requires --no-sandbox in Docker/CI.
97                                                 // WMF CI images expose CHROMIUM_FLAGS which sets that.
98                                                 flags: process.env.CHROMIUM_FLAGS ? ( process.env.CHROMIUM_FLAGS || '' ).split( ' ' ) : []
99                                         }
100                                 },
101                                 proxies: karmaProxy,
102                                 files: [ {
103                                         pattern: qunitURL,
104                                         type: 'js',
105                                         watched: false,
106                                         included: true,
107                                         served: false
108                                 }, ...qunitWatchFiles.map( ( file ) => ( {
109                                         pattern: file,
110                                         type: 'js',
111                                         watched: true,
112                                         included: false,
113                                         served: false
114                                 } ) ) ],
115                                 logLevel: ( process.env.ZUUL_PROJECT ? 'DEBUG' : 'INFO' ),
116                                 frameworks: [ 'qunit' ],
117                                 // Disable autostart because we load modules asynchronously.
118                                 client: {
119                                         qunit: {
120                                                 autostart: false
121                                         }
122                                 },
123                                 reporters: [ 'mocha' ],
124                                 singleRun: !qunitWatch,
125                                 autoWatch: qunitWatch,
126                                 // Some tests in extensions don't yield for more than the default 10s (T89075)
127                                 browserNoActivityTimeout: 60 * 1000,
128                                 // Karma requires Same-Origin (or CORS) by default since v1.1.1
129                                 // for better stacktraces. But we load the first request from wgServer
130                                 crossOriginAttribute: false
131                         },
132                         main: {
133                                 browsers: [ 'FirefoxHeadless' ]
134                         },
135                         firefox: {
136                                 browsers: [ 'FirefoxHeadless' ]
137                         },
138                         chrome: {
139                                 browsers: [ 'ChromeCustom' ]
140                         }
141                 }
142         } );
144         grunt.registerTask( 'assert-mw-env', () => {
145                 let ok = true;
146                 if ( !process.env.MW_SERVER ) {
147                         grunt.log.error( 'Environment variable MW_SERVER must be set.\n' +
148                                 'Set this like $wgServer, e.g. "http://localhost"'
149                         );
150                         ok = false;
151                 }
152                 // MW_SCRIPT_PATH= empty string is valid, e.g. for docroot installs
153                 // This includes "composer serve" (Quickstart)
154                 if ( process.env.MW_SCRIPT_PATH === undefined ) {
155                         grunt.log.error( 'Environment variable MW_SCRIPT_PATH must be set.\n' +
156                                 'Set this like $wgScriptPath, e.g. "/w"' );
157                         ok = false;
158                 }
159                 return ok;
160         } );
162         grunt.registerTask( 'lint', [ 'eslint', 'banana', 'stylelint' ] );
163         grunt.registerTask( 'qunit', [ 'assert-mw-env', 'karma:firefox' ] );