2017-03-22 16:34:05 +01:00
'use strict'
2015-12-20 05:22:45 +01:00
// load plugins
2017-03-22 16:34:05 +01:00
const $ = require ( 'gulp-load-plugins' ) ( )
2015-12-20 05:22:45 +01:00
2017-03-28 17:55:40 +02:00
// manually import modules that won't get picked up by gulp-load-plugins
import { src , dest , watch , parallel , series } from 'gulp'
2017-04-11 12:43:45 +02:00
import del from 'del'
import parallelize from 'concurrent-transform'
import browser from 'browser-sync'
import critical from 'critical'
import fs from 'fs'
import yaml from 'js-yaml'
2017-04-11 12:58:51 +02:00
import request from 'request'
2017-04-11 12:43:45 +02:00
2017-05-30 21:47:32 +02:00
// required to get our mix of old and ES6+ js to work with ugify-js 3
import uglifyjs from 'uglify-es'
import composer from 'gulp-uglify/composer'
const minify = composer ( uglifyjs , console )
2017-04-11 12:43:45 +02:00
// get all the configs: `pkg` and `site`
2017-03-28 17:55:40 +02:00
import pkg from './package.json'
2017-04-11 12:43:45 +02:00
const site = yaml . safeLoad ( fs . readFileSync ( './_config.yml' ) )
2015-12-20 05:22:45 +01:00
// handle errors
2017-03-22 16:34:05 +01:00
const onError = ( error ) => {
console . log ( $ . util . colors . red ( '\nYou fucked up:' , error . message , 'on line' , error . lineNumber , '\n' ) )
this . emit ( 'end' )
2015-12-20 05:22:45 +01:00
}
// 'development' is just default, production overrides are triggered
// by adding the production flag to the gulp command e.g. `gulp build --production`
2017-03-22 16:34:05 +01:00
const isProduction = ( $ . util . env . production === true ? true : false ) ,
isStaging = ( $ . util . env . staging === true ? true : false )
2015-12-20 05:22:45 +01:00
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Terminal Banner
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
console . log ( "" ) ;
2017-03-22 16:34:05 +01:00
console . log ( $ . util . colors . gray ( " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>" ) )
console . log ( $ . util . colors . cyan ( " __ __ __ " ) )
console . log ( $ . util . colors . cyan ( " |__). _ _|_ _ . _ | \ |__) " ) )
console . log ( $ . util . colors . cyan ( " |__)|(_)(_| )(_||| )|__/|__) " ) )
console . log ( $ . util . colors . cyan ( " _/ " ) )
console . log ( $ . util . colors . gray ( " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>" ) )
console . log ( "" )
2015-12-20 05:22:45 +01:00
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Config
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Port to use for the development server
2017-03-22 16:34:05 +01:00
const PORT = 1337
2015-12-20 05:22:45 +01:00
// paths
2017-04-11 12:43:45 +02:00
const SRC = site . source + '/' ,
DIST = site . destination + '/'
2015-12-20 05:22:45 +01:00
2016-01-08 12:00:57 +01:00
// deployment
2017-03-22 16:34:05 +01:00
const S3BUCKET = 'www.bigchaindb.com' ,
S3REGION = 'eu-central-1' ,
S3BUCKET _BETA = 'beta.bigchaindb.com' ,
S3REGION _BETA = 'eu-central-1' ,
S3BUCKET _GAMMA = 'gamma.bigchaindb.com' ,
S3REGION _GAMMA = 'eu-central-1'
2016-01-08 12:00:57 +01:00
2015-12-20 05:22:45 +01:00
// SVG sprite
2017-03-22 16:34:05 +01:00
const SPRITECONFIG = {
2015-12-20 05:22:45 +01:00
dest : DIST + 'assets/img/' ,
mode : {
symbol : {
dest : './' ,
sprite : 'sprite.svg'
}
}
}
// code banner
2017-03-22 16:34:05 +01:00
const BANNER = [
2015-12-20 05:22:45 +01:00
'/**' ,
2017-03-28 17:55:40 +02:00
' ** <%= pkg.name %>' ,
2015-12-20 05:22:45 +01:00
' ** <%= pkg.description %>' ,
' ** <%= pkg.homepage %>' ,
' **' ,
' ** <%= pkg.author.name %> <<%= pkg.author.email %>>' ,
' **/' ,
''
2017-03-22 16:34:05 +01:00
] . join ( '\n' )
2015-12-20 05:22:45 +01:00
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2017-03-28 17:55:40 +02:00
// Tasks
2015-12-20 05:22:45 +01:00
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// Delete build artifacts
//
2017-03-28 17:55:40 +02:00
export const clean = ( ) =>
del ( [
2015-12-20 05:22:45 +01:00
DIST + '**/*' ,
DIST + '.*' // delete all hidden files
2017-03-22 16:34:05 +01:00
] )
2015-12-20 05:22:45 +01:00
//
// Jekyll
//
2017-03-28 17:55:40 +02:00
export const jekyll = ( done ) => {
2015-12-20 05:22:45 +01:00
2017-03-22 16:34:05 +01:00
browser . notify ( 'Compiling Jekyll' )
2015-12-20 05:22:45 +01:00
if ( isProduction ) {
2017-03-22 16:34:05 +01:00
process . env . JEKYLL _ENV = 'production'
var jekyll _options = 'jekyll build'
2017-03-20 16:16:03 +01:00
} else if ( isStaging ) {
2017-03-22 16:34:05 +01:00
process . env . JEKYLL _ENV = 'staging'
var jekyll _options = 'jekyll build'
2015-12-20 05:22:45 +01:00
} else {
2017-03-22 16:34:05 +01:00
process . env . JEKYLL _ENV = 'development'
var jekyll _options = 'jekyll build --incremental --drafts --future'
2015-12-20 05:22:45 +01:00
}
2017-03-28 17:55:40 +02:00
let spawn = require ( 'child_process' ) . spawn ,
jekyll = spawn ( 'bundle' , [ 'exec' , jekyll _options ] , { stdio : 'inherit' } )
2017-03-04 23:08:40 +01:00
2017-03-28 17:55:40 +02:00
jekyll . on ( 'error' , ( error ) => onError ( ) ) . on ( 'close' , done )
}
2015-12-20 05:22:45 +01:00
//
// HTML
//
2017-03-28 17:55:40 +02:00
export const html = ( ) => src ( DIST + '**/*.html' )
. pipe ( $ . if ( isProduction || isStaging , $ . htmlmin ( {
collapseWhitespace : true ,
conservativeCollapse : true ,
removeComments : true ,
useShortDoctype : true ,
collapseBooleanAttributes : true ,
removeRedundantAttributes : true ,
removeEmptyAttributes : true ,
minifyJS : true ,
minifyCSS : true
} ) ) )
. pipe ( dest ( DIST ) )
2015-12-20 05:22:45 +01:00
//
// Styles
//
2017-03-28 17:55:40 +02:00
export const css = ( ) => src ( SRC + '_assets/styles/bigchain.scss' )
. pipe ( $ . if ( ! ( isProduction || isStaging ) , $ . sourcemaps . init ( ) ) )
2017-05-06 18:03:40 +02:00
. pipe ( $ . sass ( {
includePaths : [ 'node_modules' ]
} ) . on ( 'error' , $ . sass . logError ) )
2017-05-15 11:51:08 +02:00
. pipe ( $ . autoprefixer ( ) )
2017-03-28 17:55:40 +02:00
. pipe ( $ . if ( isProduction || isStaging , $ . cleanCss ( ) ) )
. pipe ( $ . if ( ! ( isProduction || isStaging ) , $ . sourcemaps . write ( ) ) )
. pipe ( $ . if ( isProduction || isStaging , $ . header ( BANNER , { pkg : pkg } ) ) )
. pipe ( $ . rename ( { suffix : '.min' } ) )
. pipe ( dest ( DIST + 'assets/css/' ) )
. pipe ( browser . stream ( ) )
// inline critical-path CSS
export const criticalCss = ( done ) => {
if ( isProduction || isStaging ) {
critical . generate ( {
base : DIST ,
src : 'index.html' ,
dest : 'index.html' ,
inline : true ,
minify : true ,
dimensions : [ {
height : 320 ,
width : 640
} , {
height : 600 ,
width : 800
} , {
height : 900 ,
width : 1360
} ]
} )
}
done ( )
}
2015-12-20 05:22:45 +01:00
//
// JavaScript
//
2017-05-06 18:03:40 +02:00
export const js = ( ) =>
2017-03-28 17:55:40 +02:00
src ( [
2015-12-20 05:22:45 +01:00
SRC + '_assets/javascripts/bigchain.js' ,
SRC + '_assets/javascripts/page-*.js'
] )
2017-03-28 17:55:40 +02:00
. pipe ( $ . if ( ! ( isProduction || isStaging ) , $ . sourcemaps . init ( ) ) )
2017-05-06 18:03:40 +02:00
. pipe ( $ . include ( {
includePaths : [ 'node_modules' , SRC + '_assets/javascripts' ]
} ) ) . on ( 'error' , onError )
2017-05-30 21:47:32 +02:00
. pipe ( $ . if ( isProduction || isStaging , minify ( ) ) ) . on ( 'error' , onError )
2017-03-28 17:55:40 +02:00
. pipe ( $ . if ( ! ( isProduction || isStaging ) , $ . sourcemaps . write ( ) ) )
2017-03-20 16:16:03 +01:00
. pipe ( $ . if ( isProduction || isStaging , $ . header ( BANNER , { pkg : pkg } ) ) )
2015-12-20 05:22:45 +01:00
. pipe ( $ . rename ( { suffix : '.min' } ) )
2017-03-28 17:55:40 +02:00
. pipe ( dest ( DIST + 'assets/js/' ) )
2015-12-20 05:22:45 +01:00
//
// SVG sprite
//
2017-06-29 21:33:51 +02:00
export const svg = ( ) => src ( SRC + '_assets/images/*.svg' )
2017-03-28 17:55:40 +02:00
. pipe ( $ . if ( isProduction || isStaging , $ . imagemin ( {
svgoPlugins : [ { removeRasterImages : true } ]
} ) ) )
. pipe ( $ . svgSprite ( SPRITECONFIG ) )
. pipe ( dest ( DIST + 'assets/img/' ) )
2015-12-20 05:22:45 +01:00
//
// Copy Images
//
2017-03-28 17:55:40 +02:00
export const images = ( ) => src ( SRC + '_assets/images/**/*' )
. pipe ( $ . if ( isProduction || isStaging , $ . imagemin ( [
$ . imagemin . gifsicle ( { interlaced : true } ) ,
$ . imagemin . jpegtran ( { progressive : true } ) ,
$ . imagemin . optipng ( { optimizationLevel : 5 } ) ,
$ . imagemin . svgo ( { plugins : [ { removeViewBox : true } ] } )
] ) ) )
. pipe ( dest ( DIST + 'assets/img/' ) )
2015-12-20 05:22:45 +01:00
2017-08-12 18:09:47 +02:00
//
// Copy Fonts
//
export const fonts = ( ) => src ( SRC + '_assets/fonts/**/*' )
. pipe ( dest ( DIST + 'assets/fonts/' ) )
2017-08-22 13:54:40 +02:00
//
// Zip up media kit
//
2017-12-22 11:57:22 +01:00
export const mediakit = ( ) => src ( SRC + 'mediakit/**/*' , { base : SRC } )
2017-08-22 23:07:28 +02:00
. pipe ( $ . zip ( 'mediakit.zip' ) )
2017-08-22 14:28:39 +02:00
. pipe ( dest ( DIST ) )
2017-08-22 12:58:59 +02:00
2015-12-20 05:22:45 +01:00
//
// Revision static assets
//
2017-03-28 17:55:40 +02:00
export const rev = ( done ) => {
2015-12-20 05:22:45 +01:00
// globbing is slow so do everything conditionally for faster dev build
2017-03-20 16:16:03 +01:00
if ( isProduction || isStaging ) {
2017-03-28 17:55:40 +02:00
return src ( DIST + 'assets/**/*.{css,js,png,jpg,jpeg,svg,eot,ttf,woff,woff2}' )
2015-12-20 05:22:45 +01:00
. pipe ( $ . rev ( ) )
2017-03-28 17:55:40 +02:00
. pipe ( dest ( DIST + 'assets/' ) )
2015-12-20 05:22:45 +01:00
// output rev manifest for next replace task
. pipe ( $ . rev . manifest ( ) )
2017-03-28 17:55:40 +02:00
. pipe ( dest ( DIST + 'assets/' ) )
}
2017-03-22 16:34:05 +01:00
done ( )
2017-03-28 17:55:40 +02:00
}
2015-12-20 05:22:45 +01:00
//
// Replace all links to assets in files
// from a manifest file
//
2017-03-28 17:55:40 +02:00
export const revReplace = ( done ) => {
2015-12-20 05:22:45 +01:00
// globbing is slow so do everything conditionally for faster dev build
2017-03-20 16:16:03 +01:00
if ( isProduction || isStaging ) {
2017-03-28 17:55:40 +02:00
let manifest = src ( DIST + 'assets/rev-manifest.json' )
2015-12-20 05:22:45 +01:00
2017-03-28 17:55:40 +02:00
return src ( DIST + '**/*.{html,css,js}' )
2015-12-20 05:22:45 +01:00
. pipe ( $ . revReplace ( { manifest : manifest } ) )
2017-03-28 17:55:40 +02:00
. pipe ( dest ( DIST ) )
2015-12-20 05:22:45 +01:00
}
2017-03-22 16:34:05 +01:00
done ( )
2017-03-28 17:55:40 +02:00
}
2015-12-20 05:22:45 +01:00
//
// Dev Server
//
2017-03-28 17:55:40 +02:00
export const server = ( done ) => {
2015-12-20 05:22:45 +01:00
browser . init ( {
server : DIST ,
port : PORT ,
reloadDebounce : 2000
2017-03-22 16:34:05 +01:00
} )
done ( )
2017-03-28 17:55:40 +02:00
}
2015-12-20 05:22:45 +01:00
//
2017-03-22 16:34:05 +01:00
// Watch for file changes
2015-12-20 05:22:45 +01:00
//
2017-03-28 17:55:40 +02:00
export const watchSrc = ( ) => {
watch ( SRC + '_assets/styles/**/*.scss' ) . on ( 'all' , series ( css ) )
watch ( SRC + '_assets/javascripts/**/*.js' ) . on ( 'all' , series ( js , browser . reload ) )
watch ( SRC + '_assets/images/**/*.{png,jpg,jpeg,gif,webp}' ) . on ( 'all' , series ( images , browser . reload ) )
watch ( SRC + '_assets/images/**/*.{svg}' ) . on ( 'all' , series ( svg , browser . reload ) )
watch ( [ SRC + '**/*.{html,xml,json,txt,md,yml}' , './*.yml' , SRC + '_includes/svg/*' ] ) . on ( 'all' , series ( 'build' , browser . reload ) )
2017-03-22 16:34:05 +01:00
}
2015-12-20 05:22:45 +01:00
2016-06-23 16:23:53 +02:00
//
2017-03-28 17:55:40 +02:00
// Build banner
2016-06-23 16:23:53 +02:00
//
2017-03-28 17:55:40 +02:00
const buildBanner = ( done ) => {
console . log ( $ . util . colors . gray ( " ------------------------------------------" ) )
console . log ( $ . util . colors . green ( ' Building ' + ( $ . util . env . production ? 'production' : $ . util . env . staging ? 'staging' : 'dev' ) + ' version...' ) )
console . log ( $ . util . colors . gray ( " ------------------------------------------" ) )
done ( )
}
2017-03-22 16:34:05 +01:00
2017-03-28 17:55:40 +02:00
//
// Deploy banner
//
const deployBanner = ( done ) => {
2017-03-22 16:34:05 +01:00
if ( ( $ . util . env . live || $ . util . env . beta || $ . util . env . gamma ) === true ) {
console . log ( $ . util . colors . gray ( " ------------------------------------------" ) )
console . log ( $ . util . colors . green ( ' Deploying to ' + ( $ . util . env . live ? 'Live' : $ . util . env . beta ? 'Beta' : 'Gamma' ) + '... ' ) )
console . log ( $ . util . colors . gray ( " ------------------------------------------" ) )
} else {
console . log ( $ . util . colors . red ( '\nHold your horses! You need to specify a deployment target like so: gulp deploy --beta. Possible targets are: --live, --beta, --gamma\n' ) )
2017-03-28 17:55:40 +02:00
}
done ( )
}
2017-03-22 16:34:05 +01:00
2017-03-28 17:55:40 +02:00
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Collection tasks
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// Full build
//
// `gulp build` is the development build
// `gulp build --production` is the production build
//
2017-12-22 16:08:54 +01:00
//export const build = series(buildBanner, clean, jekyll, parallel(html, css, js, images, fonts, svg, mediakit), rev, revReplace, criticalCss)
export const build = series ( buildBanner , clean , jekyll , parallel ( html , css , js , images , fonts , svg ) , criticalCss )
2017-03-28 17:55:40 +02:00
//
// Build site, run server, and watch for file changes
//
// `gulp dev`
//
export const dev = series ( build , server , watchSrc )
// Set `gulp dev` as default: `gulp`
export default dev
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Deployment
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// gulp deploy --live
// gulp deploy --beta
// gulp deploy --gamma
//
export const s3 = ( ) => {
2016-01-08 15:42:05 +01:00
// create publisher, define config
2016-06-23 16:23:53 +02:00
if ( $ . util . env . live === true ) {
var publisher = $ . awspublish . create ( {
2017-03-28 17:55:40 +02:00
params : { 'Bucket' : S3BUCKET } ,
'accessKeyId' : process . env . AWS _ACCESS _KEY ,
'secretAccessKey' : process . env . AWS _SECRET _KEY ,
'region' : S3REGION
2017-03-22 16:34:05 +01:00
} )
} else if ( $ . util . env . beta === true ) {
2016-06-23 16:23:53 +02:00
var publisher = $ . awspublish . create ( {
2017-03-28 17:55:40 +02:00
params : { 'Bucket' : S3BUCKET _BETA } ,
'accessKeyId' : process . env . AWS _BETA _ACCESS _KEY ,
'secretAccessKey' : process . env . AWS _BETA _SECRET _KEY ,
'region' : S3REGION _BETA
2017-03-22 16:34:05 +01:00
} )
} else if ( $ . util . env . gamma === true ) {
2017-03-07 16:24:23 +01:00
var publisher = $ . awspublish . create ( {
2017-03-28 17:55:40 +02:00
params : { 'Bucket' : S3BUCKET _GAMMA } ,
'accessKeyId' : process . env . AWS _GAMMA _ACCESS _KEY ,
'secretAccessKey' : process . env . AWS _GAMMA _SECRET _KEY ,
'region' : S3REGION _GAMMA
2017-03-22 16:34:05 +01:00
} )
2017-03-28 17:55:40 +02:00
} else {
return
2016-06-23 16:23:53 +02:00
}
2016-01-08 15:42:05 +01:00
2017-03-28 17:55:40 +02:00
return src ( DIST + '**/*' )
2016-01-08 12:00:57 +01:00
. pipe ( $ . awspublishRouter ( {
cache : {
// cache for 5 minutes by default
cacheTime : 300
} ,
routes : {
// all static assets, cached & gzipped
2017-03-04 23:08:40 +01:00
'^assets/(?:.+)\\.(?:js|css|png|jpg|jpeg|gif|ico|svg|ttf|eot|woff|woff2)$' : {
2016-01-08 12:00:57 +01:00
cacheTime : 2592000 , // cache for 1 month
gzip : true
} ,
// every other asset, cached
'^assets/.+$' : {
cacheTime : 2592000 // cache for 1 month
} ,
// all html files, not cached & gzipped
'^.+\\.html' : {
cacheTime : 0 ,
gzip : true
} ,
2017-01-25 12:23:41 +01:00
2016-12-15 11:41:24 +01:00
// all pdf files, not cached
'^.+\\.pdf' : {
cacheTime : 0
} ,
2016-01-08 12:00:57 +01:00
2017-08-23 00:39:07 +02:00
// all zip files, not cached
'^.+\\.zip' : {
cacheTime : 0
} ,
2016-01-14 12:10:46 +01:00
// font mime types
'\.ttf$' : {
key : '$&' ,
headers : { 'Content-Type' : 'application/x-font-ttf' }
} ,
'\.woff$' : {
key : '$&' ,
headers : { 'Content-Type' : 'application/x-font-woff' }
} ,
'\.woff2$' : {
key : '$&' ,
headers : { 'Content-Type' : 'application/x-font-woff2' }
} ,
2016-01-08 12:00:57 +01:00
// pass-through for anything that wasn't matched by routes above, to be uploaded with default options
"^.+$" : "$&"
}
} ) )
2016-06-23 16:23:53 +02:00
. pipe ( parallelize ( publisher . publish ( ) , 100 ) )
2016-01-08 12:00:57 +01:00
. pipe ( publisher . sync ( ) ) // delete files in bucket that are not in local folder
. pipe ( $ . awspublish . reporter ( {
states : [ 'create' , 'update' , 'delete' ]
2017-03-22 16:34:05 +01:00
} ) )
2017-03-28 17:55:40 +02:00
}
2017-04-11 12:43:45 +02:00
//
// Ping search engines on live deployment
//
export const seo = ( done ) => {
const googleUrl = 'http://www.google.com/webmasters/tools/ping?sitemap=' ,
bingUrl = 'http://www.bing.com/webmaster/ping.aspx?siteMap='
const response = ( error , response ) => {
if ( error ) {
$ . util . log ( $ . util . colors . red ( error ) )
} else {
$ . util . log ( $ . util . colors . gray ( 'Status:' , response && response . statusCode ) )
if ( response . statusCode === 200 ) {
$ . util . log ( $ . util . colors . green ( 'Successfully notified' ) )
}
}
}
if ( $ . util . env . live === true ) {
request ( googleUrl + site . url + '/sitemap.xml' , response )
request ( bingUrl + site . url + '/sitemap.xml' , response )
}
done ( )
}
//
2017-03-28 17:55:40 +02:00
// `gulp deploy`
2017-04-11 12:43:45 +02:00
//
export const deploy = series ( deployBanner , s3 , seo )