github.com/kayoticsully/syncthing@v0.8.9-0.20140724133906-c45a2fdc03f8/assets/bootstrap-3.1.1/Gruntfile.js (about)

     1  /*!
     2   * Bootstrap's Gruntfile
     3   * http://getbootstrap.com
     4   * Copyright 2013-2014 Twitter, Inc.
     5   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     6   */
     7  
     8  module.exports = function (grunt) {
     9    'use strict';
    10  
    11    // Force use of Unix newlines
    12    grunt.util.linefeed = '\n';
    13  
    14    RegExp.quote = function (string) {
    15      return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
    16    };
    17  
    18    var fs = require('fs');
    19    var path = require('path');
    20    var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
    21    var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
    22    var generateRawFilesJs = require('./grunt/bs-raw-files-generator.js');
    23    var updateShrinkwrap = require('./grunt/shrinkwrap.js');
    24  
    25    // Project configuration.
    26    grunt.initConfig({
    27  
    28      // Metadata.
    29      pkg: grunt.file.readJSON('package.json'),
    30      banner: '/*!\n' +
    31              ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
    32              ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
    33              ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
    34              ' */\n',
    35      jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',
    36  
    37      // Task configuration.
    38      clean: {
    39        dist: ['dist', 'docs/dist']
    40      },
    41  
    42      jshint: {
    43        options: {
    44          jshintrc: 'js/.jshintrc'
    45        },
    46        grunt: {
    47          options: {
    48            jshintrc: 'grunt/.jshintrc'
    49          },
    50          src: ['Gruntfile.js', 'grunt/*.js']
    51        },
    52        src: {
    53          src: 'js/*.js'
    54        },
    55        test: {
    56          src: 'js/tests/unit/*.js'
    57        },
    58        assets: {
    59          src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js']
    60        }
    61      },
    62  
    63      jscs: {
    64        options: {
    65          config: 'js/.jscs.json',
    66        },
    67        grunt: {
    68          src: ['Gruntfile.js', 'grunt/*.js']
    69        },
    70        src: {
    71          src: 'js/*.js'
    72        },
    73        test: {
    74          src: 'js/tests/unit/*.js'
    75        },
    76        assets: {
    77          src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js']
    78        }
    79      },
    80  
    81      csslint: {
    82        options: {
    83          csslintrc: 'less/.csslintrc'
    84        },
    85        src: [
    86          'dist/css/bootstrap.css',
    87          'dist/css/bootstrap-theme.css',
    88          'docs/assets/css/docs.css',
    89          'docs/examples/**/*.css'
    90        ]
    91      },
    92  
    93      concat: {
    94        options: {
    95          banner: '<%= banner %>\n<%= jqueryCheck %>',
    96          stripBanners: false
    97        },
    98        bootstrap: {
    99          src: [
   100            'js/transition.js',
   101            'js/alert.js',
   102            'js/button.js',
   103            'js/carousel.js',
   104            'js/collapse.js',
   105            'js/dropdown.js',
   106            'js/modal.js',
   107            'js/tooltip.js',
   108            'js/popover.js',
   109            'js/scrollspy.js',
   110            'js/tab.js',
   111            'js/affix.js'
   112          ],
   113          dest: 'dist/js/<%= pkg.name %>.js'
   114        }
   115      },
   116  
   117      uglify: {
   118        options: {
   119          report: 'min'
   120        },
   121        bootstrap: {
   122          options: {
   123            banner: '<%= banner %>'
   124          },
   125          src: '<%= concat.bootstrap.dest %>',
   126          dest: 'dist/js/<%= pkg.name %>.min.js'
   127        },
   128        customize: {
   129          options: {
   130            preserveComments: 'some'
   131          },
   132          src: [
   133            'docs/assets/js/vendor/less.min.js',
   134            'docs/assets/js/vendor/jszip.min.js',
   135            'docs/assets/js/vendor/uglify.min.js',
   136            'docs/assets/js/vendor/blob.js',
   137            'docs/assets/js/vendor/filesaver.js',
   138            'docs/assets/js/raw-files.min.js',
   139            'docs/assets/js/customizer.js'
   140          ],
   141          dest: 'docs/assets/js/customize.min.js'
   142        },
   143        docsJs: {
   144          options: {
   145            preserveComments: 'some'
   146          },
   147          src: [
   148            'docs/assets/js/vendor/holder.js',
   149            'docs/assets/js/application.js'
   150          ],
   151          dest: 'docs/assets/js/docs.min.js'
   152        }
   153      },
   154  
   155      less: {
   156        compileCore: {
   157          options: {
   158            strictMath: true,
   159            sourceMap: true,
   160            outputSourceFiles: true,
   161            sourceMapURL: '<%= pkg.name %>.css.map',
   162            sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
   163          },
   164          files: {
   165            'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
   166          }
   167        },
   168        compileTheme: {
   169          options: {
   170            strictMath: true,
   171            sourceMap: true,
   172            outputSourceFiles: true,
   173            sourceMapURL: '<%= pkg.name %>-theme.css.map',
   174            sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
   175          },
   176          files: {
   177            'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less'
   178          }
   179        },
   180        minify: {
   181          options: {
   182            cleancss: true,
   183            report: 'min'
   184          },
   185          files: {
   186            'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css',
   187            'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css'
   188          }
   189        }
   190      },
   191  
   192      cssmin: {
   193        compress: {
   194          options: {
   195            keepSpecialComments: '*',
   196            noAdvanced: true, // turn advanced optimizations off until the issue is fixed in clean-css
   197            report: 'min',
   198            selectorsMergeMode: 'ie8'
   199          },
   200          src: [
   201            'docs/assets/css/docs.css',
   202            'docs/assets/css/pygments-manni.css'
   203          ],
   204          dest: 'docs/assets/css/docs.min.css'
   205        }
   206      },
   207  
   208      usebanner: {
   209        dist: {
   210          options: {
   211            position: 'top',
   212            banner: '<%= banner %>'
   213          },
   214          files: {
   215            src: [
   216              'dist/css/<%= pkg.name %>.css',
   217              'dist/css/<%= pkg.name %>.min.css',
   218              'dist/css/<%= pkg.name %>-theme.css',
   219              'dist/css/<%= pkg.name %>-theme.min.css'
   220            ]
   221          }
   222        }
   223      },
   224  
   225      csscomb: {
   226        options: {
   227          config: 'less/.csscomb.json'
   228        },
   229        dist: {
   230          files: {
   231            'dist/css/<%= pkg.name %>.css': 'dist/css/<%= pkg.name %>.css',
   232            'dist/css/<%= pkg.name %>-theme.css': 'dist/css/<%= pkg.name %>-theme.css'
   233          }
   234        },
   235        examples: {
   236          expand: true,
   237          cwd: 'docs/examples/',
   238          src: ['**/*.css'],
   239          dest: 'docs/examples/'
   240        }
   241      },
   242  
   243      copy: {
   244        fonts: {
   245          expand: true,
   246          src: 'fonts/*',
   247          dest: 'dist/'
   248        },
   249        docs: {
   250          expand: true,
   251          cwd: './dist',
   252          src: [
   253            '{css,js}/*.min.*',
   254            'css/*.map',
   255            'fonts/*'
   256          ],
   257          dest: 'docs/dist'
   258        }
   259      },
   260  
   261      qunit: {
   262        options: {
   263          inject: 'js/tests/unit/phantom.js'
   264        },
   265        files: 'js/tests/index.html'
   266      },
   267  
   268      connect: {
   269        server: {
   270          options: {
   271            port: 3000,
   272            base: '.'
   273          }
   274        }
   275      },
   276  
   277      jekyll: {
   278        docs: {}
   279      },
   280  
   281      jade: {
   282        compile: {
   283          options: {
   284            pretty: true,
   285            data: function () {
   286              var filePath = path.join(__dirname, 'less/variables.less');
   287              var fileContent = fs.readFileSync(filePath, {encoding: 'utf8'});
   288              var parser = new BsLessdocParser(fileContent);
   289              return {sections: parser.parseFile()};
   290            }
   291          },
   292          files: {
   293            'docs/_includes/customizer-variables.html': 'docs/jade/customizer-variables.jade',
   294            'docs/_includes/nav-customize.html': 'docs/jade/customizer-nav.jade'
   295          }
   296        }
   297      },
   298  
   299      validation: {
   300        options: {
   301          charset: 'utf-8',
   302          doctype: 'HTML5',
   303          failHard: true,
   304          reset: true,
   305          relaxerror: [
   306            'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
   307            'Element img is missing required attribute src.'
   308          ]
   309        },
   310        files: {
   311          src: '_gh_pages/**/*.html'
   312        }
   313      },
   314  
   315      watch: {
   316        src: {
   317          files: '<%= jshint.src.src %>',
   318          tasks: ['jshint:src', 'qunit']
   319        },
   320        test: {
   321          files: '<%= jshint.test.src %>',
   322          tasks: ['jshint:test', 'qunit']
   323        },
   324        less: {
   325          files: 'less/*.less',
   326          tasks: 'less'
   327        }
   328      },
   329  
   330      sed: {
   331        versionNumber: {
   332          pattern: (function () {
   333            var old = grunt.option('oldver');
   334            return old ? RegExp.quote(old) : old;
   335          })(),
   336          replacement: grunt.option('newver'),
   337          recursive: true
   338        }
   339      },
   340  
   341      'saucelabs-qunit': {
   342        all: {
   343          options: {
   344            build: process.env.TRAVIS_JOB_ID,
   345            concurrency: 10,
   346            urls: ['http://127.0.0.1:3000/js/tests/index.html'],
   347            browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml')
   348          }
   349        }
   350      },
   351  
   352      exec: {
   353        npmUpdate: {
   354          command: 'npm update'
   355        },
   356        npmShrinkWrap: {
   357          command: 'npm shrinkwrap --dev'
   358        }
   359      }
   360    });
   361  
   362  
   363    // These plugins provide necessary tasks.
   364    require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});
   365  
   366    // Docs HTML validation task
   367    grunt.registerTask('validate-html', ['jekyll', 'validation']);
   368  
   369    // Test task.
   370    var testSubtasks = [];
   371    // Skip core tests if running a different subset of the test suite
   372    if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') {
   373      testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
   374    }
   375    // Skip HTML validation if running a different subset of the test suite
   376    if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') {
   377      testSubtasks.push('validate-html');
   378    }
   379    // Only run Sauce Labs tests if there's a Sauce access key
   380    if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
   381        // Skip Sauce if running a different subset of the test suite
   382        (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) {
   383      testSubtasks.push('connect');
   384      testSubtasks.push('saucelabs-qunit');
   385    }
   386    grunt.registerTask('test', testSubtasks);
   387  
   388    // JS distribution task.
   389    grunt.registerTask('dist-js', ['concat', 'uglify']);
   390  
   391    // CSS distribution task.
   392    grunt.registerTask('dist-css', ['less', 'cssmin', 'csscomb', 'usebanner']);
   393  
   394    // Docs distribution task.
   395    grunt.registerTask('dist-docs', 'copy:docs');
   396  
   397    // Full distribution task.
   398    grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']);
   399  
   400    // Default task.
   401    grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer', 'update-shrinkwrap']);
   402  
   403    // Version numbering task.
   404    // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
   405    // This can be overzealous, so its changes should always be manually reviewed!
   406    grunt.registerTask('change-version-number', 'sed');
   407  
   408    grunt.registerTask('build-glyphicons-data', generateGlyphiconsData);
   409  
   410    // task for building customizer
   411    grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
   412    grunt.registerTask('build-customizer-html', 'jade');
   413    grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
   414      var banner = grunt.template.process('<%= banner %>');
   415      generateRawFilesJs(banner);
   416    });
   417  
   418    // Task for updating the npm packages used by the Travis build.
   419    grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']);
   420    grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); });
   421  };