Skip to content
Snippets Groups Projects
Select Git revision
  • 6067536ea5c4ad4268e6975dd40ef867134afdda
  • master default protected
  • greenkeeper/webpack-4.10.1
  • greenkeeper/webpack-4.10.0
  • greenkeeper/webpack-4.9.2
  • greenkeeper/promise-polyfill-8.0.0
  • greenkeeper/webpack-4.9.1
  • greenkeeper/webpack-4.9.0
  • greenkeeper/webpack-manifest-plugin-2.0.3
  • greenkeeper/update-to-node-10
  • gh-pages
  • greenkeeper/webpack-4.8.3
  • greenkeeper/webpack-4.8.2
  • greenkeeper/webpack-4.7.0
  • greenkeeper/webpack-manifest-plugin-2.0.2
  • greenkeeper/webpack-manifest-plugin-2.0.1
  • greenkeeper/style-loader-0.21.0
  • greenkeeper/webpack-4.6.0
  • greenkeeper/sass-loader-7.0.1
  • greenkeeper/sass-loader-7.0.0
  • greenkeeper/webpack-manifest-plugin-2.0.0
  • 2.7.3
  • 2.7.2
  • 2.7.1
  • 2.7.0
  • 2.6.6
  • 2.6.5
  • 2.6.4
  • 2.6.3
  • 2.6.2
  • 2.6.1
  • 2.6.0
  • 2.5.5
  • 2.5.4
  • 2.5.3
  • 2.5.2
  • 2.5.1
  • 2.5.0
  • 2.4.0
  • 2.3.0
  • 2.2.6
41 results

Gulpfile.babel.js

Blame
  • user avatar
    squidfunk authored and Martin Donath committed
    ad9388ab
    History
    Gulpfile.babel.js 11.24 KiB
    /*
     * Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to
     * deal in the Software without restriction, including without limitation the
     * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     * sell copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     * IN THE SOFTWARE.
     */
    
    import chalk from "chalk"
    import gulp from "gulp"
    import notifier from "node-notifier"
    import plumber from "gulp-plumber"
    import util from "gulp-util"
    import yargs from "yargs"
    
    /* ----------------------------------------------------------------------------
     * Configuration and arguments
     * ------------------------------------------------------------------------- */
    
    /* General configuration */
    const config = {
      assets: {
        src: "src/assets",                 /* Source directory for assets */
        build: "material/assets"           /* Target directory for assets */
      },
      lib: "lib",                          /* Libraries and tasks */
      views: {
        src: "src",                        /* Source directory for views */
        build: "material"                  /* Target directory for views */
      }
    }
    
    /* Commandline arguments */
    let args = yargs
      .locale("en")
      .usage(`\n${chalk.yellow("Usage:")} yarn run <command> -- [options]`)
      .wrap(84)
      .updateStrings({
        "Commands:": chalk.yellow("Commands:"),
        "Examples:": chalk.yellow("Examples:")
      })
    
      /* Commands */
      .command("build", chalk.grey("build assets and views"))
      .command("clean", chalk.grey("clean build artifacts"))
      .command("flow", chalk.grey("type check with flow"))
      .command("help", chalk.grey("display this message"))
      .command("lint", chalk.grey("lint sources"))
      .command("start", chalk.grey("start development server"))
    
      /* Options */
      .group([
        "help", "clean"
      ], chalk.yellow("Options:"))
      .help("help", chalk.grey("display this message"))
      .option("clean", {
        describe: chalk.grey("clean artifacts before command"),
        default: false,
        global: true
      })
    
      /* Build options */
      .group([
        "lint", "optimize", "revision", "sourcemaps", "mkdocs"
      ], chalk.yellow("Build Options:"))
      .option("lint", {
        describe: chalk.grey("lint sources before build"),
        default: true,
        global: true
      })
      .option("optimize", {
        describe: chalk.grey("optimize and minify assets"),
        default: false,
        global: true
      })
      .option("revision", {
        describe: chalk.grey("revision assets for cache busting"),
        default: false,
        global: true
      })
      .option("sourcemaps", {
        describe: chalk.grey("generate sourcemaps for assets"),
        default: false,
        global: true
      })
      .option("mkdocs", {
        describe: chalk.grey("build documentation or start watchdog"),
        default: true,
        global: true
      })
    
      /* Example commands */
      .example("yarn run build")
      .example("yarn run build -- --no-optimize")
      .example("yarn run clean")
      .example("yarn run flow")
      .example("yarn run lint")
      .example("yarn run start")
    
      /* Apply to process.argv */
      .argv
    
    /* Only use the last seen value if boolean, so overrides are possible */
    args = Object.keys(args).reduce((result, arg) => {
      result[arg] = Array.isArray(args[arg]) && typeof args[arg][0] === "boolean"
        ? [].concat(args[arg]).pop()
        : args[arg]
      return result
    }, {})
    
    /* ----------------------------------------------------------------------------
     * Overrides and helpers
     * ------------------------------------------------------------------------- */
    
    /*
     * Override gulp.src() for nicer error handling.
     */
    const src = gulp.src
    gulp.src = (...glob) => {
      return src.apply(gulp, glob)
        .pipe(
          plumber(function(error) {
            util.log(util.colors.red(
              `Error (${error.plugin}): ${error.message}`
            ))
    
            /* Extract file where error happened, if existent */
            const file = error.relativePath
              ? error.relativePath.split("/").pop()
              : ""
    
            /* Dispatch system-level notification */
            notifier.notify({
              title: `Error (${error.plugin}): ${file}`,
              message: error.messageOriginal
            })
    
            // eslint-disable-next-line no-invalid-this
            this.emit("end")
    
            /* Throw error and abort, if not in watch mode */
            if (args._[0] !== "watch")
              throw error
          }))
    }
    
    /*
     * Helper function to load a task
     *
     * This function returns a callback that will require the task with the given
     * name and execute the function that is returned by this task. It omits the
     * need to load all tasks upfront, speeding up the build a gazillion times.
     */
    const load = task => {
      return done => {
        return require(`./${config.lib}/tasks/${task}`)
          .call(gulp, gulp, config, args)(done)
      }
    }
    
    /* ----------------------------------------------------------------------------
     * Images
     * ------------------------------------------------------------------------- */
    
    /*
     * Copy favicon
     */
    gulp.task("assets:images:build:ico", [
      args.clean ? "assets:images:clean" : false
    ].filter(Boolean), load("assets/images/build/ico"))
    
    /*
     * Copy and minify vector graphics
     */
    gulp.task("assets:images:build:svg", [
      args.clean ? "assets:images:clean" : false
    ].filter(Boolean), load("assets/images/build/svg"))
    
    /*
     * Copy images
     */
    gulp.task("assets:images:build", [
      "assets:images:build:ico",
      "assets:images:build:svg"
    ])
    
    /*
     * Clean images generated by build
     */
    gulp.task("assets:images:clean",
      load("assets/images/clean"))
    
    /* ----------------------------------------------------------------------------
     * JavaScript
     * ------------------------------------------------------------------------- */
    
    /*
     * Build application logic
     *
     * When revisioning assets, the build must be serialized due to possible race
     * conditions when two tasks try to write manifest.json simultaneously
     */
    
    gulp.task("assets:javascripts:build:application", [
      args.clean ? "assets:javascripts:clean" : false,
      args.lint ? "assets:javascripts:lint" : false,
      args.revision ? "assets:stylesheets:build" : false
    ].filter(Boolean), load("assets/javascripts/build/application"))
    
    /*
     * Build custom modernizr
     *
     * When revisioning assets, the build must be serialized due to possible race
     * conditions when two tasks try to write manifest.json simultaneously
     */
    gulp.task("assets:javascripts:build:modernizr", [
      "assets:stylesheets:build",
      args.clean ? "assets:javascripts:clean" : false,
      args.lint ? "assets:javascripts:lint" : false,
      args.revision ? "assets:javascripts:build:application" : false
    ].filter(Boolean), load("assets/javascripts/build/modernizr"))
    
    /*
     * Build search language support files
     */
    gulp.task("assets:javascripts:build:languages", [
      args.clean ? "assets:javascripts:clean" : false
    ].filter(Boolean), load("assets/javascripts/build/languages"))
    
    /*
     * Build JavaScript
     */
    gulp.task("assets:javascripts:build", [
      "assets:javascripts:build:application",
      "assets:javascripts:build:modernizr",
      "assets:javascripts:build:languages"
    ])
    
    /*
     * Clean JavaScript generated by build
     */
    gulp.task("assets:javascripts:clean",
      load("assets/javascripts/clean"))
    
    /*
     * Annotate JavaScript
     */
    gulp.task("assets:javascripts:annotate",
      load("assets/javascripts/annotate"))
    
    /*
     * Lint JavaScript
     */
    gulp.task("assets:javascripts:lint",
      load("assets/javascripts/lint"))
    
    /* ----------------------------------------------------------------------------
     * Stylesheets
     * ------------------------------------------------------------------------- */
    
    /*
     * Build stylesheets from SASS source
     */
    gulp.task("assets:stylesheets:build", [
      args.clean ? "assets:stylesheets:clean" : false,
      args.lint ? "assets:stylesheets:lint" : false
    ].filter(Boolean), load("assets/stylesheets/build"))
    
    /*
     * Clean stylesheets generated by build
     */
    gulp.task("assets:stylesheets:clean",
      load("assets/stylesheets/clean"))
    
    /*
     * Lint SASS sources
     */
    gulp.task("assets:stylesheets:lint",
      load("assets/stylesheets/lint"))
    
    /* ----------------------------------------------------------------------------
     * Assets
     * ------------------------------------------------------------------------- */
    
    /*
     * Build assets
     */
    gulp.task("assets:build", [
      "assets:images:build",
      "assets:javascripts:build",
      "assets:stylesheets:build"
    ])
    
    /*
     * Clean files generated by build
     */
    gulp.task("assets:clean", [
      "assets:images:clean",
      "assets:javascripts:clean",
      "assets:stylesheets:clean"
    ])
    
    /* ----------------------------------------------------------------------------
     * Views
     * ------------------------------------------------------------------------- */
    
    /*
     * Minify views
     */
    
    gulp.task("views:build", [
      args.clean ? "views:clean" : false,
      args.revision ? "assets:images:build" : false,
      args.revision ? "assets:stylesheets:build" : false,
      args.revision ? "assets:javascripts:build" : false
    ].filter(Boolean), load("views/build"))
    
    /*
     * Clean views
     */
    gulp.task("views:clean",
      load("views/clean"))
    
    /* ----------------------------------------------------------------------------
     * MkDocs
     * ------------------------------------------------------------------------- */
    
    /*
     * Build documentation
     */
    gulp.task("mkdocs:build", [
      "assets:build",
      "views:build",
      "mkdocs:clean"
    ], load("mkdocs/build"))
    
    /*
     * Clean documentation build
     */
    gulp.task("mkdocs:clean",
      load("mkdocs/clean"))
    
    /*
     * Restart MkDocs server
     */
    gulp.task("mkdocs:serve",
      load("mkdocs/serve"))
    
    /* ----------------------------------------------------------------------------
     * Interface
     * ------------------------------------------------------------------------- */
    
    /*
     * Build assets and documentation
     */
    gulp.task("build", [
      "assets:build",
      "views:build",
      args.mkdocs ? "mkdocs:build" : false
    ].filter(f => f))
    
    /*
     * Clean assets and documentation
     */
    gulp.task("clean", [
      "assets:clean",
      "views:clean",
      "mkdocs:clean"
    ])
    
    /*
     * Watch for changes and rebuild assets on the fly
     */
    gulp.task("watch", [
      "assets:build",
      "views:build"
    ], () => {
      process.env.WATCH = true
    
      /* Start MkDocs server */
      if (args.mkdocs)
        gulp.start("mkdocs:serve")
    
      /* Rebuild stylesheets */
      gulp.watch([
        `${config.assets.src}/stylesheets/**/*.scss`
      ], ["assets:stylesheets:build"])
    
      /* Rebuild JavaScript */
      gulp.watch([
        `${config.assets.src}/javascripts/**/*.{js,jsx}`
      ], ["assets:javascripts:build:application"])
    
      /* Copy images */
      gulp.watch([
        `${config.assets.src}/images/**/*`
      ], ["assets:images:build"])
    
      /* Minify views */
      gulp.watch([
        `${config.views.src}/**/*.html`
      ], ["views:build"])
    })
    
    /*
     * Print help message
     */
    gulp.task("help")
    
    /*
     * Build assets by default
     */
    gulp.task("default", ["build"])