2015-07-11 20:56:26 +01:00

197 lines
4.2 KiB
JavaScript

import { validateOption, normaliseOptions } from "./index";
import stripJsonComments from "strip-json-comments";
import isAbsolute from "path-is-absolute";
import pathExists from "path-exists";
import clone from "lodash/lang/clone";
import merge from "../../../helpers/merge";
import config from "./config";
import path from "path";
import fs from "fs";
var existsCache = {};
var jsonCache = {};
const BABELIGNORE_FILENAME = ".babelignore";
const BABELRC_FILENAME = ".babelrc";
const PACKAGE_FILENAME = "package.json";
function exists(filename) {
var cached = existsCache[filename];
if (cached != null) {
return cached;
} else {
return existsCache[filename] = pathExists.sync(filename);
}
}
export default class OptionManager {
constructor(log, pipeline) {
this.resolvedConfigs = [];
this.options = OptionManager.createBareOptions();
this.pipeline = pipeline;
this.log = log;
}
/**
* Description
*/
static createBareOptions() {
var opts = {};
for (var key in config) {
var opt = config[key];
opts[key] = clone(opt.default);
}
return opts;
}
/**
* Description
*/
addConfig(loc, key?) {
if (this.resolvedConfigs.indexOf(loc) >= 0) return;
var content = fs.readFileSync(loc, "utf8");
var opts;
try {
opts = jsonCache[content] = jsonCache[content] || JSON.parse(stripJsonComments(content));
if (key) opts = opts[key];
} catch (err) {
err.message = `${loc}: ${err.message}`;
throw err;
}
this.mergeOptions(opts, loc);
this.resolvedConfigs.push(loc);
}
/**
* Description
*/
mergeOptions(opts, alias = "foreign") {
if (!opts) return;
for (let key in opts) {
if (key[0] === "_") continue;
let option = config[key];
// check for an unknown option
if (!option) this.log.error(`Unknown option: ${alias}.${key}`, ReferenceError);
}
// normalise options
normaliseOptions(opts);
// merge them into this current files options
merge(this.options, opts);
}
/**
* Description
*/
addIgnoreConfig(loc) {
var file = fs.readFileSync(loc, "utf8");
var lines = file.split("\n");
lines = lines.map(function (line) {
return line.replace(/#(.*?)$/, "").trim();
}).filter((line) => !!line);
console.log(lines);
this.mergeOptions({ ignore: lines }, loc);
}
/**
* Description
*/
findConfigs(loc) {
if (!loc) return;
if (!isAbsolute(loc)) {
loc = path.join(process.cwd(), loc);
}
while (loc !== (loc = path.dirname(loc))) {
if (this.options.breakConfig) return;
var configLoc = path.join(loc, BABELRC_FILENAME);
if (exists(configLoc)) this.addConfig(configLoc);
var pkgLoc = path.join(loc, PACKAGE_FILENAME);
if (exists(pkgLoc)) this.addConfig(pkgLoc, "babel");
var ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
if (exists(ignoreLoc)) this.addIgnoreConfig(ignoreLoc);
}
}
/**
* Description
*/
normaliseOptions() {
var opts = this.options;
for (let key in config) {
var option = config[key];
var val = opts[key];
// optional
if (!val && option.optional) continue;
// deprecated
if (this.log && val && option.deprecated) {
this.log.deprecate(`Deprecated option ${key}: ${option.deprecated}`);
}
// validate
if (this.pipeline && val) {
val = validateOption(key, val, this.pipeline);
}
// aaliases
if (option.alias) {
opts[option.alias] = opts[option.alias] || val;
} else {
opts[key] = val;
}
}
}
/**
* Description
*/
init(opts) {
this.mergeOptions(opts, "direct");
// babelrc option
if (opts.babelrc) {
for (var loc of (opts.babelrc: Array)) this.addConfig(loc);
}
// resolve all .babelrc files
this.findConfigs(opts.filename);
// merge in env
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
if (this.options.env) {
this.mergeOptions(this.options.env[envKey], `direct.env.${envKey}`);
}
// normalise
this.normaliseOptions(opts);
return this.options;
}
}