Make WordPress Core

source: tags/4.5.25/Gruntfile.js

Last change on this file was 50208, checked in by desrosj, 5 years ago

Build/Test Tools: Support NodeJS 14.x in the 4.5 branch.

This updates the 4.5 branch to support the latest LTS version of NodeJS (currently 14.x), allowing the same version to be used across all WordPress branches that receive security updates as a courtesy.

Because older branches use (really) old versions of NodeJS, the local Docker environment cannot be backported since the needed dependencies will not run on these older versions (see #48301). This also blocks the ability to move automated testing over to GitHub Actions (see #50401).

This also replaces the npm-shrinkwrap.json with a package-lock.json file. Lock files were not supported in earlier versions of NPM, but can now be used.

In addition to backporting the package updates that happened after branching 4.5, dependencies that were removed in future releases have also been updated to their latest versions.

Props desrosj, dd32, netweb, jorbin.
Merges [37185,37212,37612,38111,38688,39110,39113-39119,39478,42460-42461,42463,42887,43320,43323,43977,44219,44233,44728,45321,45765,46404,46408-46409,47404,47867-47869,47872-47873,48705,49636,49933,49937,49939,50017,50126,50176,50185,50192] to the 4.5 branch.
See #52341.

File size: 19.0 KB
Line 
1/* jshint node:true */
2module.exports = function(grunt) {
3        var path = require('path'),
4                fs = require( 'fs' ),
5                SOURCE_DIR = 'src/',
6                BUILD_DIR = 'build/',
7                autoprefixer = require('autoprefixer'),
8                sass = require( 'sass' ),
9                mediaConfig = {},
10                mediaBuilds = ['audiovideo', 'grid', 'models', 'views'];
11
12        // Load tasks.
13        require('matchdep').filterDev(['grunt-*', '!grunt-legacy-util']).forEach( grunt.loadNpmTasks );
14        // Load legacy utils
15        grunt.util = require('grunt-legacy-util');
16
17        mediaBuilds.forEach( function ( build ) {
18                var path = SOURCE_DIR + 'wp-includes/js/media';
19                mediaConfig[ build ] = { files : {} };
20                mediaConfig[ build ].files[ path + '-' + build + '.js' ] = [ path + '/' + build + '.manifest.js' ];
21        } );
22
23        // Project configuration.
24        grunt.initConfig({
25                postcss: {
26                        options: {
27                                processors: [
28                                        autoprefixer({
29                                                cascade: false
30                                        })
31                                ]
32                        },
33                        core: {
34                                expand: true,
35                                cwd: SOURCE_DIR,
36                                dest: SOURCE_DIR,
37                                src: [
38                                        'wp-admin/css/*.css',
39                                        'wp-includes/css/*.css'
40                                ]
41                        },
42                        colors: {
43                                expand: true,
44                                cwd: BUILD_DIR,
45                                dest: BUILD_DIR,
46                                src: [
47                                        'wp-admin/css/colors/*/colors.css'
48                                ]
49                        }
50                },
51                clean: {
52                        all: [BUILD_DIR],
53                        dynamic: {
54                                dot: true,
55                                expand: true,
56                                cwd: BUILD_DIR,
57                                src: []
58                        },
59                        tinymce: ['<%= concat.tinymce.dest %>'],
60                        qunit: ['tests/qunit/compiled.html']
61                },
62                copy: {
63                        files: {
64                                files: [
65                                        {
66                                                dot: true,
67                                                expand: true,
68                                                cwd: SOURCE_DIR,
69                                                src: [
70                                                        '**',
71                                                        '!wp-includes/js/media/**',
72                                                        '!**/.{svn,git}/**', // Ignore version control directories.
73                                                        // Ignore unminified versions of external libs we don't ship:
74                                                        '!wp-includes/js/backbone.js',
75                                                        '!wp-includes/js/underscore.js',
76                                                        '!wp-includes/js/jquery/jquery.masonry.js',
77                                                        '!wp-includes/js/jquery/ui/*.js',
78                                                        '!wp-includes/js/tinymce/tinymce.js',
79                                                        '!wp-includes/version.php' // Exclude version.php
80                                                ],
81                                                dest: BUILD_DIR
82                                        },
83                                        {
84                                                src: 'wp-config-sample.php',
85                                                dest: BUILD_DIR
86                                        }
87                                ]
88                        },
89                        'wp-admin-css-compat-rtl': {
90                                options: {
91                                        processContent: function( src ) {
92                                                return src.replace( /\.css/g, '-rtl.css' );
93                                        }
94                                },
95                                src: SOURCE_DIR + 'wp-admin/css/wp-admin.css',
96                                dest: BUILD_DIR + 'wp-admin/css/wp-admin-rtl.css'
97                        },
98                        'wp-admin-css-compat-min': {
99                                options: {
100                                        processContent: function( src ) {
101                                                return src.replace( /\.css/g, '.min.css' );
102                                        }
103                                },
104                                files: [
105                                        {
106                                                src: SOURCE_DIR + 'wp-admin/css/wp-admin.css',
107                                                dest: BUILD_DIR + 'wp-admin/css/wp-admin.min.css'
108                                        },
109                                        {
110                                                src:  BUILD_DIR + 'wp-admin/css/wp-admin-rtl.css',
111                                                dest: BUILD_DIR + 'wp-admin/css/wp-admin-rtl.min.css'
112                                        }
113                                ]
114                        },
115                        version: {
116                                options: {
117                                        processContent: function( src ) {
118                                                return src.replace( /^\$wp_version = '(.+?)';/m, function( str, version ) {
119                                                        version = version.replace( /-src$/, '' );
120
121                                                        // If the version includes an SVN commit (-12345), it's not a released alpha/beta. Append a timestamp.
122                                                        version = version.replace( /-[\d]{5}$/, '-' + grunt.template.today( 'yyyymmdd.HHMMss' ) );
123
124                                                        /* jshint quotmark: true */
125                                                        return "$wp_version = '" + version + "';";
126                                                });
127                                        }
128                                },
129                                src: SOURCE_DIR + 'wp-includes/version.php',
130                                dest: BUILD_DIR + 'wp-includes/version.php'
131                        },
132                        dynamic: {
133                                dot: true,
134                                expand: true,
135                                cwd: SOURCE_DIR,
136                                dest: BUILD_DIR,
137                                src: []
138                        },
139                        qunit: {
140                                src: 'tests/qunit/index.html',
141                                dest: 'tests/qunit/compiled.html',
142                                options: {
143                                        processContent: function( src ) {
144                                                return src.replace( /(\".+?\/)src(\/.+?)(?:.min)?(.js\")/g , function( match, $1, $2, $3 ) {
145                                                        // Don't add `.min` to files that don't have it.
146                                                        return $1 + 'build' + $2 + ( /jquery$/.test( $2 ) ? '' : '.min' ) + $3;
147                                                } );
148                                        }
149                                }
150                        }
151                },
152                browserify: mediaConfig,
153                sass: {
154                        colors: {
155                                expand: true,
156                                cwd: SOURCE_DIR,
157                                dest: BUILD_DIR,
158                                ext: '.css',
159                                src: ['wp-admin/css/colors/*/colors.scss'],
160                                options: {
161                                        implementation: sass
162                                }
163                        }
164                },
165                cssmin: {
166                        options: {
167                                compatibility: 'ie7'
168                        },
169                        core: {
170                                expand: true,
171                                cwd: SOURCE_DIR,
172                                dest: BUILD_DIR,
173                                ext: '.min.css',
174                                src: [
175                                        'wp-admin/css/*.css',
176                                        '!wp-admin/css/wp-admin*.css',
177                                        'wp-includes/css/*.css',
178                                        'wp-includes/js/mediaelement/wp-mediaelement.css'
179                                ]
180                        },
181                        rtl: {
182                                expand: true,
183                                cwd: BUILD_DIR,
184                                dest: BUILD_DIR,
185                                ext: '.min.css',
186                                src: [
187                                        'wp-admin/css/*-rtl.css',
188                                        '!wp-admin/css/wp-admin*.css',
189                                        'wp-includes/css/*-rtl.css'
190                                ]
191                        },
192                        colors: {
193                                expand: true,
194                                cwd: BUILD_DIR,
195                                dest: BUILD_DIR,
196                                ext: '.min.css',
197                                src: [
198                                        'wp-admin/css/colors/*/*.css'
199                                ]
200                        }
201                },
202                rtlcss: {
203                        options: {
204                                // rtlcss options
205                                opts: {
206                                        clean: false,
207                                        processUrls: { atrule: true, decl: false },
208                                        stringMap: [
209                                                {
210                                                        name: 'import-rtl-stylesheet',
211                                                        priority: 10,
212                                                        exclusive: true,
213                                                        search: [ '.css' ],
214                                                        replace: [ '-rtl.css' ],
215                                                        options: {
216                                                                scope: 'url',
217                                                                ignoreCase: false
218                                                        }
219                                                }
220                                        ]
221                                },
222                                saveUnmodified: false,
223                                plugins: [
224                                        {
225                                                name: 'swap-dashicons-left-right-arrows',
226                                                priority: 10,
227                                                directives: {
228                                                        control: {},
229                                                        value: []
230                                                },
231                                                processors: [
232                                                        {
233                                                                expr: /content/im,
234                                                                action: function( prop, value ) {
235                                                                        if ( value === '"\\f141"' ) { // dashicons-arrow-left
236                                                                                value = '"\\f139"';
237                                                                        } else if ( value === '"\\f340"' ) { // dashicons-arrow-left-alt
238                                                                                value = '"\\f344"';
239                                                                        } else if ( value === '"\\f341"' ) { // dashicons-arrow-left-alt2
240                                                                                value = '"\\f345"';
241                                                                        } else if ( value === '"\\f139"' ) { // dashicons-arrow-right
242                                                                                value = '"\\f141"';
243                                                                        } else if ( value === '"\\f344"' ) { // dashicons-arrow-right-alt
244                                                                                value = '"\\f340"';
245                                                                        } else if ( value === '"\\f345"' ) { // dashicons-arrow-right-alt2
246                                                                                value = '"\\f341"';
247                                                                        }
248                                                                        return { prop: prop, value: value };
249                                                                }
250                                                        }
251                                                ]
252                                        }
253                                ]
254                        },
255                        core: {
256                                expand: true,
257                                cwd: SOURCE_DIR,
258                                dest: BUILD_DIR,
259                                ext: '-rtl.css',
260                                src: [
261                                        'wp-admin/css/*.css',
262                                        'wp-includes/css/*.css',
263
264                                        // Exceptions
265                                        '!wp-includes/css/dashicons.css',
266                                        '!wp-includes/css/wp-embed-template.css',
267                                        '!wp-includes/css/wp-embed-template-ie.css'
268                                ]
269                        },
270                        colors: {
271                                expand: true,
272                                cwd: BUILD_DIR,
273                                dest: BUILD_DIR,
274                                ext: '-rtl.css',
275                                src: [
276                                        'wp-admin/css/colors/*/colors.css'
277                                ]
278                        },
279                        dynamic: {
280                                expand: true,
281                                cwd: SOURCE_DIR,
282                                dest: BUILD_DIR,
283                                ext: '-rtl.css',
284                                src: []
285                        }
286                },
287                jshint: {
288                        options: grunt.file.readJSON('.jshintrc'),
289                        grunt: {
290                                src: ['Gruntfile.js']
291                        },
292                        tests: {
293                                src: [
294                                        'tests/qunit/**/*.js',
295                                        '!tests/qunit/vendor/*',
296                                        '!tests/qunit/editor/**'
297                                ],
298                                options: grunt.file.readJSON('tests/qunit/.jshintrc')
299                        },
300                        themes: {
301                                expand: true,
302                                cwd: SOURCE_DIR + 'wp-content/themes',
303                                src: [
304                                        'twenty*/**/*.js',
305                                        '!twenty{eleven,twelve,thirteen}/**',
306                                        // Third party scripts
307                                        '!twenty{fourteen,fifteen,sixteen}/js/html5.js'
308                                ]
309                        },
310                        media: {
311                                options: {
312                                        browserify: true
313                                },
314                                src: [
315                                        SOURCE_DIR + 'wp-includes/js/media/**/*.js'
316                                ]
317                        },
318                        core: {
319                                expand: true,
320                                cwd: SOURCE_DIR,
321                                src: [
322                                        'wp-admin/js/*.js',
323                                        'wp-includes/js/*.js',
324                                        // Built scripts.
325                                        '!wp-includes/js/media-*',
326                                        // WordPress scripts inside directories
327                                        'wp-includes/js/jquery/jquery.table-hotkeys.js',
328                                        'wp-includes/js/mediaelement/wp-mediaelement.js',
329                                        'wp-includes/js/mediaelement/wp-playlist.js',
330                                        'wp-includes/js/plupload/handlers.js',
331                                        'wp-includes/js/plupload/wp-plupload.js',
332                                        'wp-includes/js/tinymce/plugins/wordpress/plugin.js',
333                                        'wp-includes/js/tinymce/plugins/wp*/plugin.js',
334                                        // Third party scripts
335                                        '!wp-admin/js/farbtastic.js',
336                                        '!wp-includes/js/backbone*.js',
337                                        '!wp-includes/js/swfobject.js',
338                                        '!wp-includes/js/underscore*.js',
339                                        '!wp-includes/js/colorpicker.js',
340                                        '!wp-includes/js/hoverIntent.js',
341                                        '!wp-includes/js/json2.js',
342                                        '!wp-includes/js/tw-sack.js',
343                                        '!wp-includes/js/twemoji.js',
344                                        '!**/*.min.js'
345                                ],
346                                // Remove once other JSHint errors are resolved
347                                options: {
348                                        curly: false,
349                                        eqeqeq: false
350                                },
351                                // Limit JSHint's run to a single specified file:
352                                //
353                                //    grunt jshint:core --file=filename.js
354                                //
355                                // Optionally, include the file path:
356                                //
357                                //    grunt jshint:core --file=path/to/filename.js
358                                //
359                                filter: function( filepath ) {
360                                        var index, file = grunt.option( 'file' );
361
362                                        // Don't filter when no target file is specified
363                                        if ( ! file ) {
364                                                return true;
365                                        }
366
367                                        // Normalize filepath for Windows
368                                        filepath = filepath.replace( /\\/g, '/' );
369                                        index = filepath.lastIndexOf( '/' + file );
370
371                                        // Match only the filename passed from cli
372                                        if ( filepath === file || ( -1 !== index && index === filepath.length - ( file.length + 1 ) ) ) {
373                                                return true;
374                                        }
375
376                                        return false;
377                                }
378                        },
379                        plugins: {
380                                expand: true,
381                                cwd: SOURCE_DIR + 'wp-content/plugins',
382                                src: [
383                                        '**/*.js',
384                                        '!**/*.min.js'
385                                ],
386                                // Limit JSHint's run to a single specified plugin directory:
387                                //
388                                //    grunt jshint:plugins --dir=foldername
389                                //
390                                filter: function( dirpath ) {
391                                        var index, dir = grunt.option( 'dir' );
392
393                                        // Don't filter when no target folder is specified
394                                        if ( ! dir ) {
395                                                return true;
396                                        }
397
398                                        dirpath = dirpath.replace( /\\/g, '/' );
399                                        index = dirpath.lastIndexOf( '/' + dir );
400
401                                        // Match only the folder name passed from cli
402                                        if ( -1 !== index ) {
403                                                return true;
404                                        }
405
406                                        return false;
407                                }
408                        }
409                },
410                qunit: {
411                        files: [
412                                'tests/qunit/**/*.html',
413                                '!tests/qunit/editor/**'
414                        ]
415                },
416                phpunit: {
417                        'default': {
418                                cmd: 'phpunit',
419                                args: ['-c', 'phpunit.xml.dist']
420                        },
421                        ajax: {
422                                cmd: 'phpunit',
423                                args: ['-c', 'phpunit.xml.dist', '--group', 'ajax']
424                        },
425                        multisite: {
426                                cmd: 'phpunit',
427                                args: ['-c', 'tests/phpunit/multisite.xml']
428                        },
429                        'external-http': {
430                                cmd: 'phpunit',
431                                args: ['-c', 'phpunit.xml.dist', '--group', 'external-http']
432                        }
433                },
434                uglify: {
435                        options: {
436                                output: {
437                                        ascii_only: true,
438                                        ie8: true
439                                }
440                        },
441                        core: {
442                                expand: true,
443                                cwd: SOURCE_DIR,
444                                dest: BUILD_DIR,
445                                ext: '.min.js',
446                                src: [
447                                        'wp-admin/js/*.js',
448                                        'wp-includes/js/*.js',
449                                        'wp-includes/js/mediaelement/wp-mediaelement.js',
450                                        'wp-includes/js/mediaelement/wp-playlist.js',
451                                        'wp-includes/js/plupload/handlers.js',
452                                        'wp-includes/js/plupload/wp-plupload.js',
453                                        'wp-includes/js/tinymce/plugins/wordpress/plugin.js',
454                                        'wp-includes/js/tinymce/plugins/wp*/plugin.js',
455
456                                        // Exceptions
457                                        '!wp-admin/js/bookmarklet.*', // Minified and updated in /src with the precommit task. See uglify:bookmarklet.
458                                        '!wp-admin/js/custom-header.js', // Why? We should minify this.
459                                        '!wp-admin/js/farbtastic.js',
460                                        '!wp-admin/js/iris.min.js',
461                                        '!wp-includes/js/backbone.*',
462                                        '!wp-includes/js/masonry.min.js',
463                                        '!wp-includes/js/swfobject.js',
464                                        '!wp-includes/js/underscore.*',
465                                        '!wp-includes/js/zxcvbn.min.js',
466                                        '!wp-includes/js/wp-embed.js' // We have extra options for this, see uglify:embed
467                                ]
468                        },
469                        embed: {
470                                options: {
471                                        compress: {
472                                                conditionals: false
473                                        }
474                                },
475                                expand: true,
476                                cwd: SOURCE_DIR,
477                                dest: BUILD_DIR,
478                                ext: '.min.js',
479                                src: ['wp-includes/js/wp-embed.js']
480                        },
481                        media: {
482                                expand: true,
483                                cwd: SOURCE_DIR,
484                                dest: BUILD_DIR,
485                                ext: '.min.js',
486                                src: [
487                                        'wp-includes/js/media-audiovideo.js',
488                                        'wp-includes/js/media-grid.js',
489                                        'wp-includes/js/media-models.js',
490                                        'wp-includes/js/media-views.js'
491                                ]
492                        },
493                        jqueryui: {
494                                options: {
495                                        // Preserve comments that start with a bang.
496                                        output: {
497                                                comments: /^!/
498                                        }
499                                },
500                                expand: true,
501                                cwd: SOURCE_DIR,
502                                dest: BUILD_DIR,
503                                ext: '.min.js',
504                                src: ['wp-includes/js/jquery/ui/*.js']
505                        },
506                        bookmarklet: {
507                                options: {
508                                        compress: {
509                                                negate_iife: false
510                                        }
511                                },
512                                src: SOURCE_DIR + 'wp-admin/js/bookmarklet.js',
513                                dest: SOURCE_DIR + 'wp-admin/js/bookmarklet.min.js'
514                        }
515                },
516                concat: {
517                        tinymce: {
518                                options: {
519                                        separator: '\n',
520                                        process: function( src, filepath ) {
521                                                return '// Source: ' + filepath.replace( BUILD_DIR, '' ) + '\n' + src;
522                                        }
523                                },
524                                src: [
525                                        BUILD_DIR + 'wp-includes/js/tinymce/tinymce.min.js',
526                                        BUILD_DIR + 'wp-includes/js/tinymce/themes/modern/theme.min.js',
527                                        BUILD_DIR + 'wp-includes/js/tinymce/plugins/*/plugin.min.js'
528                                ],
529                                dest: BUILD_DIR + 'wp-includes/js/tinymce/wp-tinymce.js'
530                        },
531                        emoji: {
532                                options: {
533                                        separator: '\n',
534                                        process: function( src, filepath ) {
535                                                return '// Source: ' + filepath.replace( BUILD_DIR, '' ) + '\n' + src;
536                                        }
537                                },
538                                src: [
539                                        BUILD_DIR + 'wp-includes/js/twemoji.min.js',
540                                        BUILD_DIR + 'wp-includes/js/wp-emoji.min.js'
541                                ],
542                                dest: BUILD_DIR + 'wp-includes/js/wp-emoji-release.min.js'
543                        }
544                },
545                compress: {
546                        tinymce: {
547                                options: {
548                                        mode: 'gzip',
549                                        level: 9
550                                },
551                                src: '<%= concat.tinymce.dest %>',
552                                dest: BUILD_DIR + 'wp-includes/js/tinymce/wp-tinymce.js.gz'
553                        }
554                },
555                jsvalidate:{
556                        options: {
557                                globals: {},
558                                esprimaOptions:{},
559                                verbose: false
560                        },
561                        build: {
562                                files: {
563                                        src: [
564                                                BUILD_DIR + 'wp-{admin,includes}/**/*.js',
565                                                BUILD_DIR + 'wp-content/themes/twenty*/**/*.js'
566                                        ]
567                                }
568                        }
569                },
570                imagemin: {
571                        core: {
572                                expand: true,
573                                cwd: SOURCE_DIR,
574                                src: [
575                                        'wp-{admin,includes}/images/**/*.{png,jpg,gif,jpeg}',
576                                        'wp-includes/js/tinymce/skins/wordpress/images/*.{png,jpg,gif,jpeg}'
577                                ],
578                                dest: SOURCE_DIR
579                        }
580                },
581                includes: {
582                        emoji: {
583                                src: BUILD_DIR + 'wp-includes/formatting.php',
584                                dest: '.'
585                        },
586                        embed: {
587                                src: BUILD_DIR + 'wp-includes/embed.php',
588                                dest: '.'
589                        }
590                },
591                _watch: {
592                        all: {
593                                files: [
594                                        SOURCE_DIR + '**',
595                                        '!' + SOURCE_DIR + 'wp-includes/js/media/**',
596                                        // Ignore version control directories.
597                                        '!' + SOURCE_DIR + '**/.{svn,git}/**'
598                                ],
599                                tasks: ['clean:dynamic', 'copy:dynamic'],
600                                options: {
601                                        dot: true,
602                                        spawn: false,
603                                        interval: 2000
604                                }
605                        },
606                        config: {
607                                files: 'Gruntfile.js'
608                        },
609                        colors: {
610                                files: [SOURCE_DIR + 'wp-admin/css/colors/**'],
611                                tasks: ['sass:colors']
612                        },
613                        rtl: {
614                                files: [
615                                        SOURCE_DIR + 'wp-admin/css/*.css',
616                                        SOURCE_DIR + 'wp-includes/css/*.css'
617                                ],
618                                tasks: ['rtlcss:dynamic'],
619                                options: {
620                                        spawn: false,
621                                        interval: 2000
622                                }
623                        },
624                        test: {
625                                files: [
626                                        'tests/qunit/**',
627                                        '!tests/qunit/editor/**'
628                                ],
629                                tasks: ['qunit']
630                        }
631                }
632        });
633
634        // Register tasks.
635
636        // RTL task.
637        grunt.registerTask('rtl', ['rtlcss:core', 'rtlcss:colors']);
638
639        // Color schemes task.
640        grunt.registerTask('colors', ['sass:colors', 'postcss:colors']);
641
642        // JSHint task.
643        grunt.registerTask( 'jshint:corejs', [
644                'jshint:grunt',
645                'jshint:tests',
646                'jshint:themes',
647                'jshint:core',
648                'jshint:media'
649        ] );
650
651        grunt.renameTask( 'watch', '_watch' );
652
653        grunt.registerTask( 'watch', function() {
654                if ( ! this.args.length || this.args.indexOf( 'browserify' ) > -1 ) {
655                        grunt.config( 'browserify.options', {
656                                browserifyOptions: {
657                                        debug: true
658                                },
659                                watch: true
660                        } );
661
662                        grunt.task.run( 'browserify' );
663                }
664
665                grunt.task.run( '_' + this.nameArgs );
666        } );
667
668        grunt.registerTask( 'precommit:base', [
669                'imagemin:core'
670        ] );
671
672        grunt.registerTask( 'precommit:js', [
673                'browserify',
674                'jshint:corejs',
675                'uglify:bookmarklet',
676                'qunit:compiled'
677        ] );
678
679        grunt.registerTask( 'precommit:css', [
680                'postcss:core'
681        ] );
682
683        grunt.registerTask( 'precommit:php', [
684                'phpunit'
685        ] );
686
687        grunt.registerTask( 'precommit', 'Runs test and build tasks in preparation for a commit', function() {
688                var done = this.async();
689                var map = {
690                        svn: 'svn status --ignore-externals',
691                        git: 'git status --short'
692                };
693
694                find( [
695                        __dirname + '/.svn',
696                        __dirname + '/.git',
697                        path.dirname( __dirname ) + '/.svn'
698                ] );
699
700                function find( set ) {
701                        var dir;
702
703                        if ( set.length ) {
704                                fs.stat( dir = set.shift(), function( error ) {
705                                        error ? find( set ) : run( path.basename( dir ).substr( 1 ) );
706                                } );
707                        } else {
708                                grunt.fatal( 'This WordPress install is not under version control.' );
709                        }
710                }
711
712                function run( type ) {
713                        var command = map[ type ].split( ' ' );
714                        var taskList = [ 'precommit:base' ];
715
716                        grunt.util.spawn( {
717                                cmd: command.shift(),
718                                args: command
719                        }, function( error, result, code ) {
720                                if ( code !== 0 ) {
721                                        grunt.fatal( 'The `' +  map[ type ] + '` command returned a non-zero exit code.', code );
722                                }
723
724                                [ 'js', 'css', 'php' ].forEach( function( extension ) {
725                                        if ( ( result.stdout + '\n' ).indexOf( '.' + extension + '\n' ) !== -1 ) {
726                                                grunt.log.writeln( extension.toUpperCase() + ' files modified. ' + extension.toUpperCase() + ' tests will be run.');
727                                                taskList.push( 'precommit:' + extension );
728                                        }
729                                } );
730
731                                grunt.task.run( taskList );
732
733                                done();
734                        } );
735                }
736        } );
737
738        grunt.registerTask( 'copy:all', [
739                'copy:files',
740                'copy:wp-admin-css-compat-rtl',
741                'copy:wp-admin-css-compat-min',
742                'copy:version'
743        ] );
744
745        grunt.registerTask( 'build', [
746                'clean:all',
747                'copy:all',
748                'cssmin:core',
749                'colors',
750                'rtl',
751                'cssmin:rtl',
752                'cssmin:colors',
753                'uglify:core',
754                'uglify:embed',
755                'uglify:jqueryui',
756                'concat:tinymce',
757                'compress:tinymce',
758                'clean:tinymce',
759                'concat:emoji',
760                'includes:emoji',
761                'includes:embed',
762                'jsvalidate:build'
763        ] );
764
765        grunt.registerTask( 'prerelease', [
766                'precommit:php',
767                'precommit:js',
768                'precommit:css',
769                'precommit:base',
770                'build'
771        ] );
772
773        // Testing tasks.
774        grunt.registerMultiTask('phpunit', 'Runs PHPUnit tests, including the ajax, external-http, and multisite tests.', function() {
775                grunt.util.spawn({
776                        cmd: this.data.cmd,
777                        args: this.data.args,
778                        opts: {stdio: 'inherit'}
779                }, this.async());
780        });
781
782        grunt.registerTask('qunit:compiled', 'Runs QUnit tests on compiled as well as uncompiled scripts.',
783                ['build', 'copy:qunit', 'qunit']);
784
785        grunt.registerTask('test', 'Runs all QUnit and PHPUnit tasks.', ['qunit:compiled', 'phpunit']);
786
787        // Travis CI tasks.
788        grunt.registerTask('travis:js', 'Runs Javascript Travis CI tasks.', [ 'jshint:corejs', 'qunit:compiled' ]);
789        grunt.registerTask('travis:phpunit', 'Runs PHPUnit Travis CI tasks.', 'phpunit');
790
791        // Patch task.
792        grunt.renameTask('patch_wordpress', 'patch');
793
794        // Default task.
795        grunt.registerTask('default', ['build']);
796
797        /*
798         * Automatically updates the `:dynamic` configurations
799         * so that only the changed files are updated.
800         */
801        grunt.event.on('watch', function( action, filepath, target ) {
802                var src;
803
804                if ( [ 'all', 'rtl', 'browserify' ].indexOf( target ) === -1 ) {
805                        return;
806                }
807
808                src = [ path.relative( SOURCE_DIR, filepath ) ];
809
810                if ( action === 'deleted' ) {
811                        grunt.config( [ 'clean', 'dynamic', 'src' ], src );
812                } else {
813                        grunt.config( [ 'copy', 'dynamic', 'src' ], src );
814
815                        if ( target === 'rtl' ) {
816                                grunt.config( [ 'rtlcss', 'dynamic', 'src' ], src );
817                        }
818                }
819        });
820};
Note: See TracBrowser for help on using the repository browser.