Home Manual Reference Source Test

src/lib/RuntimeConfig.js

import { readFileSync, writeFile, stat } from 'fs';
import { join as joinPath, sep } from 'path';
import through from 'through2';
import { log, colors } from 'gulp-util';
import File from './AtviseFile';
import stringify from 'json-stable-stringify';

function toUnixPath(p) {
  return p.split(sep).join('/');
}

/**
 * Provides utility methods for adding runtime configuration to a stream of {@link AtviseFile} and
 * extracting configuration from a {@link NodeStream}.
 */
export default class RuntimeConfig {

  /**
   * The path where the runtime configuration will be stored.
   * @type {String}
   */
  static get path() {
    return joinPath(process.cwd(), '.atviserc');
  }

  /**
   * Extracts the runtime configuration from a stream and writes it to a file at
   * {@link RuntimeConfig.path}.
   * @return {Stream} Stream to get further transformed.
   */
  static write() {
    const rc = {};
    return through.obj(function(file, enc, cb) {
      rc[file.path] = file.rc;

      cb(null, file);
    }, function(cb) {
      writeFile(RuntimeConfig.path, stringify(rc, { space: '  ' }), cb);
    });
  }

  /**
   * Loads the runtime configuration from the file at {@link RuntimeConfig.path} and attaches it to
   * streamed files.
   * @return {Stream} A stream of {@link AtviseFile}s.
   */
  static load() {
    const rc = JSON.parse(readFileSync(RuntimeConfig.path));

    return through.obj(function(file, enc, cb) {
      if (!file.isDirectory()) { // Fixes a bug with gulp 4.0
        const key = toUnixPath(file.relative);
        let r = rc[key];

        if (!r) {
          const dir = toUnixPath(joinPath(file.relative, '../'));

          r = rc[dir.substr(0, dir.length - 1)];

          if (!r) {
            log(colors.red('Missing runtime config for'), colors.cyan(file.relative));
          }
        }

        stat(file.path, (err, s) => {
          if (err) {
            throw err;
          }

          file.stat = { mtime: s.mtime };
          cb(null, File.from(file, r));
        });
      } else {
        cb();
      }
    });
  }

}