Browse Source

Deploy with Kubernetes

Joshua Gleitze 8 months ago
parent
commit
06805ff8b2
7 changed files with 428 additions and 601 deletions
  1. 3 0
      .dockerignore
  2. 6 0
      Dockerfile
  3. 110 0
      deployment.yaml
  4. 38 19
      gulpfile.js
  5. 37 0
      httpd.conf
  6. 231 580
      package-lock.json
  7. 3 2
      package.json

+ 3 - 0
.dockerignore

@@ -0,0 +1,3 @@
+*
+!/release/
+!/httpd.conf

+ 6 - 0
Dockerfile

@@ -0,0 +1,6 @@
+FROM httpd:2.4.39-alpine
+COPY release/ /var/www/
+COPY httpd.conf /etc/httpd-extra.conf
+RUN cat /etc/httpd-extra.conf >> /usr/local/apache2/conf/httpd.conf \
+ && sed -i '/CustomLog .*/d' /usr/local/apache2/conf/httpd.conf \
+ && rm /etc/httpd-extra.conf

+ 110 - 0
deployment.yaml

@@ -0,0 +1,110 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: studierlangsam-de
+  namespace: studierlangsam
+  labels:
+    app: studierlangsam.de
+spec:
+  selector:
+    matchLabels:
+      app: studierlangsam.de
+  template:
+    metadata:
+      name: studierlangsam-de
+      labels:
+        app: studierlangsam.de
+    spec:
+      containers:
+        - name: studierlangsam-de
+          image: dockerimages.studierlangsam.de/studierlangsam.de:${DEPLOYMENT_VERSION}
+          ports:
+            - containerPort: 80
+              name: web
+          readinessProbe:
+            httpGet:
+              path: /
+              port: web
+            timeoutSeconds: 30
+            periodSeconds: 15
+          livenessProbe:
+            httpGet:
+              path: /
+              port: web
+            timeoutSeconds: 30
+            periodSeconds: 15
+          resources:
+            limits:
+              cpu: 100m
+              memory: 64Mi
+      imagePullSecrets:
+        - name: local-registry
+  strategy:
+    type: RollingUpdate
+    rollingUpdate:
+      maxUnavailable: 0
+  minReadySeconds: 20
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: studierlangsam-de
+  namespace: studierlangsam
+  labels:
+    app: studierlangsam.de
+spec:
+  ports:
+    - port: 80
+      targetPort: web
+      name: web
+  selector:
+    app: studierlangsam.de
+
+---
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  name: studierlangsam-de
+  namespace: studierlangsam
+  labels:
+    app: studierlangsam.de
+  annotations:
+    traefik.ingress.kubernetes.io/redirect-entry-point: https
+    traefik.ingress.kubernetes.io/redirect-permanent: "true"
+spec:
+  rules:
+    - host: studierlangsam.de
+      http:
+        paths:
+          - path: /
+            backend:
+              serviceName: studierlangsam-de
+              servicePort: web
+  tls:
+    - secretName: studierlangsam-de-tls
+
+---
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: Certificate
+metadata:
+  name: studierlangsam-de
+  namespace: studierlangsam
+  labels:
+    app: studierlangsam.de
+spec:
+  secretName: studierlangsam-de-tls
+  renewBefore: 360h # 15d
+  commonName: studierlangsam.de
+  dnsNames:
+    - studierlangsam.de
+    - www.studierlangsam.de
+  issuerRef:
+    name: letsencrypt
+    kind: ClusterIssuer
+  acme:
+    config:
+      - http01: {}
+        domains:
+          - studierlangsam.de
+          - www.studierlangsam.de

+ 38 - 19
gulpfile.js

@@ -7,7 +7,6 @@ const rename = require('gulp-rename');
 const htmlmin = require('gulp-htmlmin');
 const rmrf = require('rimraf');
 const sourcemaps = require('gulp-sourcemaps');
-const rsync = require('gulp-rsync');
 const w3cjs = require('gulp-w3cjs');
 const scsslint = require('gulp-scss-lint');
 const cleanCss = require('gulp-clean-css');
@@ -20,6 +19,8 @@ const plumber = require('gulp-plumber');
 const os = require('os');
 const plainresize = require('gulp-image-resize');
 const resize = options => parallel(plainresize(options), os.cpus().length);
+const run = require('gulp-run-command').default;
+const yargs = require('yargs');
 
 
 // whether we are building a release version, as opposed to a development build.
@@ -217,29 +218,47 @@ function setreleasemode(done) {
 	done();
 }
 
-/**
- * Uploads the built files to the webserver.
- */
-function upload() {
-	return gulp.src(builddir)
-		.pipe(rsync({
-			root: builddir,
-			hostname: 'studierlangsam@studierlangsam.de',
-			destination: 'studierlangsam.de',
-			port: 2222,
-			archive: false,
-			recursive: true,
-			incremental: true,
-			progress: true,
-			links: true,
-			clean: true
-		}));
+function getVersion() {
+	return yargs
+		.alias('dv', 'dversion')
+		.argv["dversion"];
+}
+
+function imageName() {
+	return `dockerimages.studierlangsam.de/studierlangsam.de:${getVersion()}`
 }
 
+function checkVersion() {
+	const version = getVersion();
+	if (!version) {
+		throw new Error("Please specify this deployment’s version by providing it via --dversion!");
+	}
+	console.log(`Deploying version ${version}`);
+	return Promise.resolve();
+}
+
+gulp.task('buildDocker',
+	run(`sudo docker build . -t ${imageName()}`)
+)
+gulp.task('pushDocker',
+	run(`sudo docker push ${imageName()}`)
+)
+gulp.task('deployKubernetes',
+	run(`bash -c "` + (
+		`cat deployment.yaml`
+		+ ` | envsubst '$DEPLOYMENT_VERSION'`
+		+ ` | kubectl apply -f - --prune --selector app=studierlangsam.de`
+	) + `"`, {
+			env: {
+				DEPLOYMENT_VERSION: getVersion()
+			}
+		})
+)
+
 gulp.task('clean', cleanbuilddir);
 gulp.task('build', gulp.parallel(style, content, graphics, images, miscstatic));
 gulp.task('buildrelease', gulp.series(setreleasemode, 'clean', 'build', revision));
 gulp.task('watch', gulp.series('clean', 'build', gulp.parallel(watch, serve)));
 gulp.task('serverelease', gulp.series('buildrelease', serve));
 gulp.task('check', gulp.series('clean', 'build', gulp.parallel(checkHTML, checkStyle)));
-gulp.task('deploy', gulp.series('buildrelease', upload));
+gulp.task('deploy', gulp.series(checkVersion, 'buildrelease', 'buildDocker', 'pushDocker', 'deployKubernetes'));

+ 37 - 0
httpd.conf

@@ -0,0 +1,37 @@
+LoadModule logio_module modules/mod_logio.so
+LoadModule rewrite_module modules/mod_rewrite.so
+LoadModule expires_module modules/mod_expires.so
+
+LogFormat "[%{%Y-%m-%dT%T}t.%{msec_frac}t%{%z}t] %h:%p %u %L %H \"%m %U%q\" %>s %OB (%{ms}Tms) \"%{Referer}i\" \"%{User-Agent}i\""
+TransferLog /proc/self/fd/1
+ErrorLogFormat "%v %A %-L [%{cu}t] [%m] %l: %M (%E) @%F [client\ %a] [pid %P tid %T] \"%-{Referer}i\" \"%-{User-Agent}i\""
+
+DocumentRoot /var/www/
+
+<Directory /var/www/>
+    Require all granted
+
+    Options FollowSymLinks
+    AllowOverride None
+
+    # Don’t require slashes at the end of URLs
+    DirectorySlash Off
+    RewriteEngine On
+    RewriteCond %{REQUEST_FILENAME} -d
+    RewriteRule ^(.++)$(?<!\/) /$1/ [L]
+</Directory>
+
+# Default cache headers
+ExpiresActive On
+ExpiresDefault "access plus 1 hour"
+Header append Cache-Control "public"
+
+# Set long time cache header on hashed files
+<FilesMatch "\.[a-f0-9]{6}\.(css|jpg|png|svg|html|ico|js|ttf|otf|eot)$">
+    ExpiresDefault "access plus 1 year"
+    Header unset ETag
+    FileETag None
+</FilesMatch>
+
+# Compress svg
+AddOutputFilter DEFLATE svg

+ 231 - 580
package-lock.json

@@ -345,12 +345,6 @@
       "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
       "dev": true
     },
-    "array-differ": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
-      "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
-      "dev": true
-    },
     "array-each": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
@@ -435,12 +429,6 @@
         }
       }
     },
-    "array-uniq": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
-      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
-      "dev": true
-    },
     "array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -579,6 +567,15 @@
         "is-buffer": "^1.1.5"
       }
     },
+    "babel-plugin-transform-runtime": {
+      "version": "6.15.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.15.0.tgz",
+      "integrity": "sha1-PXW02Umtga8VdXAnOEb7Wa6w1Xw=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.9.0"
+      }
+    },
     "babel-runtime": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -718,12 +715,6 @@
         "tweetnacl": "^0.14.3"
       }
     },
-    "beeper": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz",
-      "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=",
-      "dev": true
-    },
     "better-assert": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
@@ -835,6 +826,30 @@
         "socket.io": "2.1.1",
         "ua-parser-js": "0.7.17",
         "yargs": "6.4.0"
+      },
+      "dependencies": {
+        "yargs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz",
+          "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=",
+          "dev": true,
+          "requires": {
+            "camelcase": "^3.0.0",
+            "cliui": "^3.2.0",
+            "decamelize": "^1.1.1",
+            "get-caller-file": "^1.0.1",
+            "os-locale": "^1.4.0",
+            "read-pkg-up": "^1.0.1",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^1.0.1",
+            "set-blocking": "^2.0.0",
+            "string-width": "^1.0.2",
+            "which-module": "^1.0.0",
+            "window-size": "^0.2.0",
+            "y18n": "^3.2.1",
+            "yargs-parser": "^4.1.0"
+          }
+        }
       }
     },
     "browser-sync-client": {
@@ -1400,12 +1415,6 @@
         "@types/node": "^8.0.7"
       }
     },
-    "dateformat": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
-      "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=",
-      "dev": true
-    },
     "debug": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -1582,41 +1591,6 @@
       "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
       "dev": true
     },
-    "duplexer2": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
-      "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=",
-      "dev": true,
-      "requires": {
-        "readable-stream": "~1.1.9"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "1.1.14",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.1",
-            "isarray": "0.0.1",
-            "string_decoder": "~0.10.x"
-          }
-        },
-        "string_decoder": {
-          "version": "0.10.31",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
-          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
-          "dev": true
-        }
-      }
-    },
     "duplexify": {
       "version": "3.7.1",
       "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -1673,6 +1647,12 @@
       "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
       "dev": true
     },
+    "emoji-regex": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+      "dev": true
+    },
     "emojione": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/emojione/-/emojione-4.5.0.tgz",
@@ -3692,51 +3672,26 @@
         }
       }
     },
-    "gulp-rsync": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/gulp-rsync/-/gulp-rsync-0.0.8.tgz",
-      "integrity": "sha1-s+ZINc1gWaTrEhrVj/cXRrTYmMw=",
+    "gulp-run-command": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npmjs.org/gulp-run-command/-/gulp-run-command-0.0.9.tgz",
+      "integrity": "sha512-8/Gzh+zfe6CFLqaL+LxwqLPj5fk/N1eCHEr36K5p9Al40iuxpbVnq1aZRGXMj+4DlWBzjjAAxas3EkMNI/6Vcw==",
       "dev": true,
       "requires": {
-        "better-assert": "^1.0.1",
-        "gulp-util": "^3.0.0",
-        "lodash.every": "^2.4.1",
-        "lodash.isstring": "^2.4.1",
-        "through2": "^0.6.1"
+        "babel-plugin-transform-runtime": "6.15.0",
+        "cross-spawn": "4.0.0",
+        "spawn-args": "0.2.0",
+        "timeout-as-promise": "^1.0.0"
       },
       "dependencies": {
-        "isarray": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "1.0.34",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.1",
-            "isarray": "0.0.1",
-            "string_decoder": "~0.10.x"
-          }
-        },
-        "string_decoder": {
-          "version": "0.10.31",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
-          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
-          "dev": true
-        },
-        "through2": {
-          "version": "0.6.5",
-          "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
-          "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
+        "cross-spawn": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.0.tgz",
+          "integrity": "sha1-glR3SrR4a4xbPPTfumbOVjkywlI=",
           "dev": true,
           "requires": {
-            "readable-stream": ">=1.0.33-1 <1.1.0-0",
-            "xtend": ">=4.0.0 <4.1.0-0"
+            "lru-cache": "^4.0.1",
+            "which": "^1.2.9"
           }
         }
       }
@@ -3911,69 +3866,6 @@
         }
       }
     },
-    "gulp-util": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
-      "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=",
-      "dev": true,
-      "requires": {
-        "array-differ": "^1.0.0",
-        "array-uniq": "^1.0.2",
-        "beeper": "^1.0.0",
-        "chalk": "^1.0.0",
-        "dateformat": "^2.0.0",
-        "fancy-log": "^1.1.0",
-        "gulplog": "^1.0.0",
-        "has-gulplog": "^0.1.0",
-        "lodash._reescape": "^3.0.0",
-        "lodash._reevaluate": "^3.0.0",
-        "lodash._reinterpolate": "^3.0.0",
-        "lodash.template": "^3.0.0",
-        "minimist": "^1.1.0",
-        "multipipe": "^0.1.2",
-        "object-assign": "^3.0.0",
-        "replace-ext": "0.0.1",
-        "through2": "^2.0.0",
-        "vinyl": "^0.5.0"
-      },
-      "dependencies": {
-        "clone": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
-          "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
-          "dev": true
-        },
-        "clone-stats": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
-          "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=",
-          "dev": true
-        },
-        "object-assign": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
-          "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=",
-          "dev": true
-        },
-        "replace-ext": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
-          "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=",
-          "dev": true
-        },
-        "vinyl": {
-          "version": "0.5.3",
-          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz",
-          "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=",
-          "dev": true,
-          "requires": {
-            "clone": "^1.0.0",
-            "clone-stats": "^0.0.1",
-            "replace-ext": "0.0.1"
-          }
-        }
-      }
-    },
     "gulp-w3cjs": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/gulp-w3cjs/-/gulp-w3cjs-1.3.1.tgz",
@@ -4082,15 +3974,6 @@
       "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
       "dev": true
     },
-    "has-gulplog": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz",
-      "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=",
-      "dev": true,
-      "requires": {
-        "sparkles": "^1.0.0"
-      }
-    },
     "has-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
@@ -4847,204 +4730,28 @@
         }
       }
     },
-    "lodash": {
-      "version": "4.17.11",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
-      "dev": true
-    },
-    "lodash._arraypool": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._arraypool/-/lodash._arraypool-2.4.1.tgz",
-      "integrity": "sha1-6I7suS4ruEyQZWEv2VigcZzUf5Q=",
-      "dev": true
-    },
-    "lodash._basebind": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.4.1.tgz",
-      "integrity": "sha1-6UC5690nwyfgqNqxtVkWxTQelXU=",
-      "dev": true,
-      "requires": {
-        "lodash._basecreate": "~2.4.1",
-        "lodash._setbinddata": "~2.4.1",
-        "lodash._slice": "~2.4.1",
-        "lodash.isobject": "~2.4.1"
-      }
-    },
-    "lodash._basecopy": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
-      "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
-      "dev": true
-    },
-    "lodash._basecreate": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz",
-      "integrity": "sha1-+Ob1tXip405UEXm1a47uv0oofgg=",
-      "dev": true,
-      "requires": {
-        "lodash._isnative": "~2.4.1",
-        "lodash.isobject": "~2.4.1",
-        "lodash.noop": "~2.4.1"
-      }
-    },
-    "lodash._basecreatecallback": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.4.1.tgz",
-      "integrity": "sha1-fQsmdknLKeehOdAQO3wR+uhOSFE=",
-      "dev": true,
-      "requires": {
-        "lodash._setbinddata": "~2.4.1",
-        "lodash.bind": "~2.4.1",
-        "lodash.identity": "~2.4.1",
-        "lodash.support": "~2.4.1"
-      }
-    },
-    "lodash._basecreatewrapper": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.4.1.tgz",
-      "integrity": "sha1-TTHy595+E0+/KAN2K4FQsyUZZm8=",
-      "dev": true,
-      "requires": {
-        "lodash._basecreate": "~2.4.1",
-        "lodash._setbinddata": "~2.4.1",
-        "lodash._slice": "~2.4.1",
-        "lodash.isobject": "~2.4.1"
-      }
-    },
-    "lodash._baseisequal": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-2.4.1.tgz",
-      "integrity": "sha1-ax5i5YfFUjER9vIoVT2rGeRF/AM=",
-      "dev": true,
-      "requires": {
-        "lodash._getarray": "~2.4.1",
-        "lodash._objecttypes": "~2.4.1",
-        "lodash._releasearray": "~2.4.1",
-        "lodash.forin": "~2.4.1",
-        "lodash.isfunction": "~2.4.1"
-      }
-    },
-    "lodash._basetostring": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz",
-      "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=",
-      "dev": true
-    },
-    "lodash._basevalues": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz",
-      "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=",
-      "dev": true
-    },
-    "lodash._createwrapper": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.4.1.tgz",
-      "integrity": "sha1-UdaVeXPaTtVW43KQ2MGhjFPeFgc=",
-      "dev": true,
-      "requires": {
-        "lodash._basebind": "~2.4.1",
-        "lodash._basecreatewrapper": "~2.4.1",
-        "lodash._slice": "~2.4.1",
-        "lodash.isfunction": "~2.4.1"
-      }
-    },
-    "lodash._getarray": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._getarray/-/lodash._getarray-2.4.1.tgz",
-      "integrity": "sha1-+vH3+BD6mFolHCGHQESBCUg55e4=",
-      "dev": true,
-      "requires": {
-        "lodash._arraypool": "~2.4.1"
-      }
-    },
-    "lodash._getnative": {
-      "version": "3.9.1",
-      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
-      "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
-      "dev": true
-    },
-    "lodash._isiterateecall": {
-      "version": "3.0.9",
-      "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
-      "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
-      "dev": true
-    },
-    "lodash._isnative": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz",
-      "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=",
-      "dev": true
-    },
-    "lodash._maxpoolsize": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._maxpoolsize/-/lodash._maxpoolsize-2.4.1.tgz",
-      "integrity": "sha1-nUgvRjuOZq++WcLBTtsRcGAXIzQ=",
-      "dev": true
-    },
-    "lodash._objecttypes": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
-      "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
-      "dev": true
-    },
-    "lodash._reescape": {
+    "locate-path": {
       "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz",
-      "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=",
-      "dev": true
-    },
-    "lodash._reevaluate": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz",
-      "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=",
-      "dev": true
-    },
-    "lodash._reinterpolate": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
-      "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
-      "dev": true
-    },
-    "lodash._releasearray": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._releasearray/-/lodash._releasearray-2.4.1.tgz",
-      "integrity": "sha1-phOWMNdtFTawfdyAliiJsIL2pkE=",
-      "dev": true,
-      "requires": {
-        "lodash._arraypool": "~2.4.1",
-        "lodash._maxpoolsize": "~2.4.1"
-      }
-    },
-    "lodash._root": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
-      "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=",
-      "dev": true
-    },
-    "lodash._setbinddata": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.4.1.tgz",
-      "integrity": "sha1-98IAzRuS7yNrOZ7s9zxkjReqlNI=",
-      "dev": true,
-      "requires": {
-        "lodash._isnative": "~2.4.1",
-        "lodash.noop": "~2.4.1"
-      }
-    },
-    "lodash._shimkeys": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz",
-      "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
       "dev": true,
       "requires": {
-        "lodash._objecttypes": "~2.4.1"
+        "p-locate": "^3.0.0",
+        "path-exists": "^3.0.0"
+      },
+      "dependencies": {
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        }
       }
     },
-    "lodash._slice": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.4.1.tgz",
-      "integrity": "sha1-dFz0GlNZexj2iImFREBe+isG2Q8=",
+    "lodash": {
+      "version": "4.17.11",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
       "dev": true
     },
     "lodash.assign": {
@@ -5053,217 +4760,24 @@
       "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
       "dev": true
     },
-    "lodash.bind": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.4.1.tgz",
-      "integrity": "sha1-XRn6AFyMTSNvr0dCx7eh/Kvikmc=",
-      "dev": true,
-      "requires": {
-        "lodash._createwrapper": "~2.4.1",
-        "lodash._slice": "~2.4.1"
-      }
-    },
     "lodash.clonedeep": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
       "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
       "dev": true
     },
-    "lodash.createcallback": {
-      "version": "2.4.4",
-      "resolved": "https://registry.npmjs.org/lodash.createcallback/-/lodash.createcallback-2.4.4.tgz",
-      "integrity": "sha1-SkUwhJsBZVAD/L31Y1JO/zzrAsQ=",
-      "dev": true,
-      "requires": {
-        "lodash._basecreatecallback": "~2.4.1",
-        "lodash._baseisequal": "~2.4.1",
-        "lodash.isobject": "~2.4.1",
-        "lodash.keys": "~2.4.1",
-        "lodash.property": "~2.4.1"
-      },
-      "dependencies": {
-        "lodash.keys": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
-          "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
-          "dev": true,
-          "requires": {
-            "lodash._isnative": "~2.4.1",
-            "lodash._shimkeys": "~2.4.1",
-            "lodash.isobject": "~2.4.1"
-          }
-        }
-      }
-    },
-    "lodash.escape": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz",
-      "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=",
-      "dev": true,
-      "requires": {
-        "lodash._root": "^3.0.0"
-      }
-    },
-    "lodash.every": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-2.4.1.tgz",
-      "integrity": "sha1-Iozlheb0kMAymAW4/A+s1BW4OwU=",
-      "dev": true,
-      "requires": {
-        "lodash.createcallback": "~2.4.1",
-        "lodash.forown": "~2.4.1"
-      }
-    },
-    "lodash.forin": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.forin/-/lodash.forin-2.4.1.tgz",
-      "integrity": "sha1-gInq7X0lsIZyt8Zv0HrFXQYjIOs=",
-      "dev": true,
-      "requires": {
-        "lodash._basecreatecallback": "~2.4.1",
-        "lodash._objecttypes": "~2.4.1"
-      }
-    },
-    "lodash.forown": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-2.4.1.tgz",
-      "integrity": "sha1-eLQer+FAX6lmRZ6kGT/VAtCEUks=",
-      "dev": true,
-      "requires": {
-        "lodash._basecreatecallback": "~2.4.1",
-        "lodash._objecttypes": "~2.4.1",
-        "lodash.keys": "~2.4.1"
-      },
-      "dependencies": {
-        "lodash.keys": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
-          "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
-          "dev": true,
-          "requires": {
-            "lodash._isnative": "~2.4.1",
-            "lodash._shimkeys": "~2.4.1",
-            "lodash.isobject": "~2.4.1"
-          }
-        }
-      }
-    },
-    "lodash.identity": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.4.1.tgz",
-      "integrity": "sha1-ZpTP+mX++TH3wxzobHRZfPVg9PE=",
-      "dev": true
-    },
-    "lodash.isarguments": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
-      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
-      "dev": true
-    },
-    "lodash.isarray": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
-      "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
-      "dev": true
-    },
     "lodash.isfinite": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
       "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=",
       "dev": true
     },
-    "lodash.isfunction": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz",
-      "integrity": "sha1-LP1XXHPkmKtX4xm3f6Aq3vE6lNE=",
-      "dev": true
-    },
-    "lodash.isobject": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
-      "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
-      "dev": true,
-      "requires": {
-        "lodash._objecttypes": "~2.4.1"
-      }
-    },
-    "lodash.isstring": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-2.4.1.tgz",
-      "integrity": "sha1-OkpC7jRLW8Ca6qh+8dwwl3idB5I=",
-      "dev": true
-    },
-    "lodash.keys": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
-      "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
-      "dev": true,
-      "requires": {
-        "lodash._getnative": "^3.0.0",
-        "lodash.isarguments": "^3.0.0",
-        "lodash.isarray": "^3.0.0"
-      }
-    },
     "lodash.mergewith": {
       "version": "4.6.1",
       "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
       "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==",
       "dev": true
     },
-    "lodash.noop": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz",
-      "integrity": "sha1-T7VPgWZS5a4Q6PcvcXo4jHMmU4o=",
-      "dev": true
-    },
-    "lodash.property": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.property/-/lodash.property-2.4.1.tgz",
-      "integrity": "sha1-QEnAVJ2vWnECvF6T7q67N53rEy8=",
-      "dev": true
-    },
-    "lodash.restparam": {
-      "version": "3.6.1",
-      "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
-      "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=",
-      "dev": true
-    },
-    "lodash.support": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/lodash.support/-/lodash.support-2.4.1.tgz",
-      "integrity": "sha1-Mg4LZwMWc8KNeiu12eAzGkUkBRU=",
-      "dev": true,
-      "requires": {
-        "lodash._isnative": "~2.4.1"
-      }
-    },
-    "lodash.template": {
-      "version": "3.6.2",
-      "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz",
-      "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=",
-      "dev": true,
-      "requires": {
-        "lodash._basecopy": "^3.0.0",
-        "lodash._basetostring": "^3.0.0",
-        "lodash._basevalues": "^3.0.0",
-        "lodash._isiterateecall": "^3.0.0",
-        "lodash._reinterpolate": "^3.0.0",
-        "lodash.escape": "^3.0.0",
-        "lodash.keys": "^3.0.0",
-        "lodash.restparam": "^3.0.0",
-        "lodash.templatesettings": "^3.0.0"
-      }
-    },
-    "lodash.templatesettings": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz",
-      "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=",
-      "dev": true,
-      "requires": {
-        "lodash._reinterpolate": "^3.0.0",
-        "lodash.escape": "^3.0.0"
-      }
-    },
     "longest": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
@@ -5623,15 +5137,6 @@
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
       "dev": true
     },
-    "multipipe": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
-      "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=",
-      "dev": true,
-      "requires": {
-        "duplexer2": "0.0.2"
-      }
-    },
     "mute-stdout": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
@@ -6072,6 +5577,30 @@
         "os-tmpdir": "^1.0.0"
       }
     },
+    "p-limit": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+      "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+      "dev": true,
+      "requires": {
+        "p-try": "^2.0.0"
+      }
+    },
+    "p-locate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+      "dev": true,
+      "requires": {
+        "p-limit": "^2.0.0"
+      }
+    },
+    "p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true
+    },
     "pac-proxy-agent": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz",
@@ -7558,6 +7087,12 @@
       "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
       "dev": true
     },
+    "spawn-args": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/spawn-args/-/spawn-args-0.2.0.tgz",
+      "integrity": "sha1-+30L0dcP1DFr2ePew4nmX51jYbs=",
+      "dev": true
+    },
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@@ -7899,6 +7434,12 @@
       "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
       "dev": true
     },
+    "timeout-as-promise": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/timeout-as-promise/-/timeout-as-promise-1.0.0.tgz",
+      "integrity": "sha1-c2foEfyZKs/Nzaq/LlDfr4shV28=",
+      "dev": true
+    },
     "timers-ext": {
       "version": "0.1.7",
       "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
@@ -8516,25 +8057,135 @@
       "dev": true
     },
     "yargs": {
-      "version": "6.4.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz",
-      "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=",
+      "version": "13.3.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
+      "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
       "dev": true,
       "requires": {
-        "camelcase": "^3.0.0",
-        "cliui": "^3.2.0",
-        "decamelize": "^1.1.1",
-        "get-caller-file": "^1.0.1",
-        "os-locale": "^1.4.0",
-        "read-pkg-up": "^1.0.1",
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
         "require-directory": "^2.1.1",
-        "require-main-filename": "^1.0.1",
+        "require-main-filename": "^2.0.0",
         "set-blocking": "^2.0.0",
-        "string-width": "^1.0.2",
-        "which-module": "^1.0.0",
-        "window-size": "^0.2.0",
-        "y18n": "^3.2.1",
-        "yargs-parser": "^4.1.0"
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        },
+        "cliui": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+          "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+          "dev": true,
+          "requires": {
+            "string-width": "^3.1.0",
+            "strip-ansi": "^5.2.0",
+            "wrap-ansi": "^5.1.0"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "get-caller-file": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+          "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "require-main-filename": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+          "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "which-module": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+          "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+          "dev": true
+        },
+        "wrap-ansi": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+          "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.0",
+            "string-width": "^3.0.0",
+            "strip-ansi": "^5.0.0"
+          }
+        },
+        "y18n": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+          "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+          "dev": true
+        },
+        "yargs-parser": {
+          "version": "13.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
+          "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
       }
     },
     "yargs-parser": {

+ 3 - 2
package.json

@@ -19,13 +19,14 @@
     "gulp-read": "1.0.1",
     "gulp-rename": "^1.4.0",
     "gulp-rev-all": "^1.0.0",
-    "gulp-rsync": "0.0.8",
+    "gulp-run-command": "0.0.9",
     "gulp-sass": "^4.0.2",
     "gulp-scss-lint": "^1.0.0",
     "gulp-sourcemaps": "^2.6.4",
     "gulp-w3cjs": "^1.3.0",
     "rimraf": "^2.6.1",
-    "sass": "^1.17.3"
+    "sass": "^1.17.3",
+    "yargs": "^13.3.0"
   },
   "scripts": {
     "test": "gulp check"