react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / node_modules / commoner / lib / context.js
81159 viewsvar assert = require("assert");1var path = require("path");2var Q = require("q");3var util = require("./util");4var spawn = require("child_process").spawn;5var ReadFileCache = require("./cache").ReadFileCache;6var grepP = require("./grep");7var glob = require("glob");8var env = process.env;910function BuildContext(options, readFileCache) {11var self = this;12assert.ok(self instanceof BuildContext);13assert.ok(readFileCache instanceof ReadFileCache);1415if (options) {16assert.strictEqual(typeof options, "object");17} else {18options = {};19}2021Object.freeze(options);2223Object.defineProperties(self, {24readFileCache: { value: readFileCache },25config: { value: options.config },26options: { value: options },27optionsHash: { value: util.deepHash(options) }28});29}3031var BCp = BuildContext.prototype;3233BCp.makePromise = function(callback, context) {34return util.makePromise(callback, context);35};3637BCp.spawnP = function(command, args, kwargs) {38args = args || [];39kwargs = kwargs || {};4041var deferred = Q.defer();4243var outs = [];44var errs = [];4546var options = {47stdio: "pipe",48env: env49};5051if (kwargs.cwd) {52options.cwd = kwargs.cwd;53}5455var child = spawn(command, args, options);5657child.stdout.on("data", function(data) {58outs.push(data);59});6061child.stderr.on("data", function(data) {62errs.push(data);63});6465child.on("close", function(code) {66if (errs.length > 0 || code !== 0) {67var err = {68code: code,69text: errs.join("")70};71}7273deferred.resolve([err, outs.join("")]);74});7576var stdin = kwargs && kwargs.stdin;77if (stdin) {78child.stdin.end(stdin);79}8081return deferred.promise;82};8384BCp.setIgnoreDependencies = function(value) {85Object.defineProperty(this, "ignoreDependencies", {86value: !!value87});88};8990// This default can be overridden by individual BuildContext instances.91BCp.setIgnoreDependencies(false);9293BCp.setRelativize = function(value) {94Object.defineProperty(this, "relativize", {95value: !!value96});97};9899// This default can be overridden by individual BuildContext instances.100BCp.setRelativize(false);101102BCp.setUseProvidesModule = function(value) {103Object.defineProperty(this, "useProvidesModule", {104value: !!value105});106};107108// This default can be overridden by individual BuildContext instances.109BCp.setUseProvidesModule(false);110111BCp.setCacheDirectory = function(dir) {112if (!dir) {113// Disable the cache directory.114} else {115assert.strictEqual(typeof dir, "string");116}117118Object.defineProperty(this, "cacheDir", {119value: dir || null120});121};122123// This default can be overridden by individual BuildContext instances.124BCp.setCacheDirectory(null);125126function PreferredFileExtension(ext) {127assert.strictEqual(typeof ext, "string");128assert.ok(this instanceof PreferredFileExtension);129Object.defineProperty(this, "extension", {130value: ext.toLowerCase()131});132}133134var PFEp = PreferredFileExtension.prototype;135136PFEp.check = function(file) {137return file.split(".").pop().toLowerCase() === this.extension;138};139140PFEp.trim = function(file) {141if (this.check(file)) {142var len = file.length;143var extLen = 1 + this.extension.length;144file = file.slice(0, len - extLen);145}146return file;147};148149PFEp.glob = function() {150return "**/*." + this.extension;151};152153exports.PreferredFileExtension = PreferredFileExtension;154155BCp.setPreferredFileExtension = function(pfe) {156assert.ok(pfe instanceof PreferredFileExtension);157Object.defineProperty(this, "preferredFileExtension", { value: pfe });158};159160BCp.setPreferredFileExtension(new PreferredFileExtension("js"));161162BCp.expandIdsOrGlobsP = function(idsOrGlobs) {163var context = this;164165return Q.all(166idsOrGlobs.map(this.expandSingleIdOrGlobP, this)167).then(function(listOfListsOfIDs) {168var result = [];169var seen = {};170171util.flatten(listOfListsOfIDs).forEach(function(id) {172if (!seen.hasOwnProperty(id)) {173seen[id] = true;174if (util.isValidModuleId(id))175result.push(id);176}177});178179return result;180});181};182183BCp.expandSingleIdOrGlobP = function(idOrGlob) {184var context = this;185186return util.makePromise(function(callback) {187// If idOrGlob already looks like an acceptable identifier, don't188// try to expand it.189if (util.isValidModuleId(idOrGlob)) {190callback(null, [idOrGlob]);191return;192}193194glob(idOrGlob, {195cwd: context.readFileCache.sourceDir196}, function(err, files) {197if (err) {198callback(err);199} else {200callback(null, files.filter(function(file) {201return !context.isHiddenFile(file);202}).map(function(file) {203return context.preferredFileExtension.trim(file);204}));205}206});207});208};209210BCp.readModuleP = function(id) {211return this.readFileCache.readFileP(212id + "." + this.preferredFileExtension.extension213);214};215216BCp.readFileP = function(file) {217return this.readFileCache.readFileP(file);218};219220// Text editors such as VIM and Emacs often create temporary swap files221// that should be ignored.222var hiddenExp = /^\.|~$/;223BCp.isHiddenFile = function(file) {224return hiddenExp.test(path.basename(file));225};226227BCp.getProvidedP = util.cachedMethod(function() {228var context = this;229var pattern = "@providesModule\\s+\\S+";230231return grepP(232pattern,233context.readFileCache.sourceDir234).then(function(pathToMatch) {235var idToPath = {};236237Object.keys(pathToMatch).sort().forEach(function(path) {238if (context.isHiddenFile(path))239return;240241var id = pathToMatch[path].split(/\s+/).pop();242243// If we're about to overwrite an existing module identifier,244// make sure the corresponding path ends with the preferred245// file extension. This allows @providesModule directives in246// .coffee files, for example, but prevents .js~ temporary247// files from taking precedence over actual .js files.248if (!idToPath.hasOwnProperty(id) ||249context.preferredFileExtension.check(path))250idToPath[id] = path;251});252253return idToPath;254});255});256257var providesExp = /@providesModule[ ]+(\S+)/;258259BCp.getProvidedId = function(source) {260var match = providesExp.exec(source);261return match && match[1];262};263264exports.BuildContext = BuildContext;265266267