Close GH-675: Upgrade to the new bower-json api.. Fixes #668

This commit is contained in:
André Cruz
2013-07-29 21:57:35 +01:00
parent 1210ea821a
commit e1a443177e
7 changed files with 173 additions and 153 deletions

View File

@@ -6,13 +6,14 @@ var semver = require('semver');
var mout = require('mout');
var rimraf = require('rimraf');
var promptly = require('promptly');
var bowerJson = require('bower-json');
var endpointParser = require('bower-endpoint-parser');
var Logger = require('bower-logger');
var Manager = require('./Manager');
var defaultConfig = require('../config');
var md5 = require('../util/md5');
var createError = require('../util/createError');
var readJson = require('../util/readJson');
var validLink = require('../util/validLink');
function Project(config, logger) {
// This is the only architecture component that ensures defaults
@@ -309,43 +310,6 @@ Project.prototype.uninstall = function (names, options) {
});
};
Project.prototype.hasJson = function () {
return this._readJson()
.then(function (json) {
return json ? this._jsonFile : false;
}.bind(this));
};
Project.prototype.getJson = function () {
return this._readJson();
};
Project.prototype.saveJson = function (forceCreate) {
var file;
var jsonStr = JSON.stringify(this._json, null, ' ') + '\n';
var jsonHash = md5(jsonStr);
// Save only if there's something different
if (jsonHash === this._jsonHash) {
return Q.resolve();
}
// Error out if the json file does not exist, unless force create
// is true
if (!this._jsonFile && !forceCreate) {
this._logger.warn('no-json', 'No bower.json file to save to');
return Q.resolve();
}
file = this._jsonFile || path.join(this._config.cwd, 'bower.json');
return Q.nfcall(fs.writeFile, file, jsonStr)
.then(function () {
this._jsonHash = jsonHash;
this._jsonFile = file;
return this._json;
}.bind(this));
};
Project.prototype.getTree = function () {
return this._analyse()
.spread(function (json, tree, flattened) {
@@ -425,6 +389,43 @@ Project.prototype.walkTree = function (node, fn, onlyOnce) {
}
};
Project.prototype.saveJson = function (forceCreate) {
var file;
var jsonStr = JSON.stringify(this._json, null, ' ') + '\n';
var jsonHash = md5(jsonStr);
// Save only if there's something different
if (jsonHash === this._jsonHash) {
return Q.resolve();
}
// Error out if the json file does not exist, unless force create
// is true
if (!this._jsonFile && !forceCreate) {
this._logger.warn('no-json', 'No bower.json file to save to');
return Q.resolve();
}
file = this._jsonFile || path.join(this._config.cwd, 'bower.json');
return Q.nfcall(fs.writeFile, file, jsonStr)
.then(function () {
this._jsonHash = jsonHash;
this._jsonFile = file;
return this._json;
}.bind(this));
};
Project.prototype.hasJson = function () {
return this._readJson()
.then(function (json) {
return json ? this._jsonFile : false;
}.bind(this));
};
Project.prototype.getJson = function () {
return this._readJson();
};
Project.prototype.getManager = function () {
return this._manager;
};
@@ -515,37 +516,17 @@ Project.prototype._readJson = function () {
}
// Read local json
return this._json = Q.nfcall(bowerJson.find, this._config.cwd)
.then(function (filename) {
// If it is a component.json, warn about the deprecation
if (path.basename(filename) === 'component.json') {
process.nextTick(function () {
that._logger.warn('deprecated', 'You are using the deprecated component.json file', {
json: filename
});
});
return this._json = readJson(this._config.cwd, {
name: path.basename(this._config.cwd) || 'root'
})
.spread(function (json, deprecated) {
var jsonStr;
if (deprecated) {
that._logger.warn('deprecated', 'You are using the deprecated ' + deprecated + ' file');
}
that._jsonFile = filename;
// Read it
return Q.nfcall(bowerJson.read, filename)
.fail(function (err) {
throw createError('Something went wrong while reading ' + filename, err.code, {
details: err.message,
data: {
filename: filename
}
});
});
}, function () {
// No json file was found, assume one
return Q.nfcall(bowerJson.parse, {
name: path.basename(that._config.cwd) || 'root'
});
})
.then(function (json) {
var jsonStr = JSON.stringify(json, null, ' ') + '\n';
jsonStr = JSON.stringify(json, null, ' ') + '\n';
that._jsonHash = md5(jsonStr);
return that._json = json;
});
@@ -576,8 +557,8 @@ Project.prototype._readInstalled = function () {
var metaFile = path.join(componentsDir, filename);
// Read package metadata
return Q.nfcall(bowerJson.read, metaFile)
.then(function (pkgMeta) {
return readJson(metaFile)
.spread(function (pkgMeta) {
decEndpoints[name] = {
name: name,
source: pkgMeta._source,
@@ -585,8 +566,7 @@ Project.prototype._readInstalled = function () {
canonicalDir: path.dirname(metaFile),
pkgMeta: pkgMeta
};
// Ignore if failed to read file
}, function () {});
});
});
// Wait until all files have been read
@@ -600,6 +580,7 @@ Project.prototype._readInstalled = function () {
Project.prototype._readLinks = function () {
var componentsDir;
var that = this;
// Read directory, looking for links
componentsDir = path.join(this._config.cwd, this._config.directory);
@@ -608,44 +589,41 @@ Project.prototype._readLinks = function () {
var promises;
var decEndpoints = {};
// Filter only those that are links
promises = filenames.map(function (filename) {
var dir = path.join(componentsDir, filename);
return Q.nfcall(fs.lstat, dir)
.then(function (stat) {
if (stat.isSymbolicLink()) {
return Q.nfcall(bowerJson.find, dir)
.then(function (jsonFile) {
return Q.nfcall(bowerJson.read, jsonFile)
.then(function (pkgMeta) {
var name = path.basename(filename);
// Filter only those that are valid links
return validLink(dir)
.spread(function (valid, err) {
var name;
decEndpoints[name] = {
name: name,
source: dir,
target: '*',
canonicalDir: dir,
pkgMeta: pkgMeta,
linked: true
};
})
.fail(function (err) {
throw createError('Failed to read ' + filename, err.code, {
details: err.message,
data: {
filename: filename
}
});
if (!valid) {
if (err) {
that._logger.debug('read-link', 'Link ' + dir + ' is invalid', {
filename: dir,
error: err
});
}, function () {
// No json file was found, assume one
return Q.nfcall(bowerJson.parse, {
name: path.basename(dir)
});
});
}
return;
}
}, function () {});
name = path.basename(dir);
return readJson(dir, { name: name })
.spread(function (json, deprecated) {
if (deprecated) {
that._logger.warn('deprecated', 'Package ' + name + ' is using the deprecated ' + deprecated);
}
decEndpoints[name] = {
name: name,
source: dir,
target: '*',
canonicalDir: dir,
pkgMeta: json,
linked: true
};
});
});
});
// Wait until all links have been read

View File

@@ -3,11 +3,10 @@ var path = require('path');
var semver = require('semver');
var mout = require('mout');
var Q = require('q');
var bowerJson = require('bower-json');
var mkdirp = require('mkdirp');
var rimraf = require('rimraf');
var LRU = require('lru-cache');
var createError = require('../util/createError');
var readJson = require('../util/readJson');
var copy = require('../util/copy');
var md5 = require('../util/md5');
@@ -325,14 +324,9 @@ ResolveCache.prototype._getPkgRelease = function (pkgMeta) {
ResolveCache.prototype._readPkgMeta = function (dir) {
var filename = path.join(dir, '.bower.json');
return Q.nfcall(bowerJson.read, filename)
.fail(function (err) {
throw createError('Something went wrong while reading ' + filename, err.code || 'EMALFORMED', {
details: err.message,
data: {
json: filename
}
});
return readJson(filename)
.spread(function (json) {
return json;
});
};

View File

@@ -37,15 +37,14 @@ FsResolver.isTargetable = function () {
// is an archive file, by piping read stream to the zip extractor
// This will likely increase the complexity of code but might worth it
FsResolver.prototype._resolve = function () {
return this._readJson(this._source)
.then(this._copy.bind(this))
return this._copy()
.then(this._extract.bind(this))
.then(this._rename.bind(this));
};
// -----------------
FsResolver.prototype._copy = function (meta) {
FsResolver.prototype._copy = function () {
var that = this;
return Q.nfcall(fs.stat, this._source)
@@ -55,18 +54,19 @@ FsResolver.prototype._copy = function (meta) {
var promise;
that._sourceStat = stat;
// Pass in the ignore to the copy options to avoid copying ignored files
// Also, pass in the mode to avoid additional stat calls when copying
copyOpts = {
mode: stat.mode,
ignore: meta.ignore
};
copyOpts = { mode: stat.mode };
// If it's a folder
if (stat.isDirectory()) {
dst = that._tempDir;
promise = copy.copyDir(that._source, that._tempDir, copyOpts)
// Read the bower.json inside the folder, so that we
// copy only the necessary files if it has ignore specified
promise = that._readJson(that._source)
.then(function (json) {
copyOpts.ignore = json.ignore;
return copy.copyDir(that._source, dst, copyOpts);
})
.then(function () {
// Resolve to null because it's a dir
return;

View File

@@ -3,7 +3,7 @@ var path = require('path');
var Q = require('q');
var tmp = require('tmp');
var mkdirp = require('mkdirp');
var bowerJson = require('bower-json');
var readJson = require('../../util/readJson');
var createError = require('../../util/createError');
var removeIgnores = require('../../util/removeIgnores');
@@ -61,10 +61,15 @@ Resolver.prototype.hasNew = function (canonicalDir, pkgMeta) {
} else {
metaFile = path.join(canonicalDir, '.bower.json');
promise = Q.nfcall(bowerJson.read, metaFile)
.then(function (pkgMeta) {
promise = readJson(metaFile)
.spread(function (pkgMeta) {
return that._hasNew(canonicalDir, pkgMeta);
}, function () {
}, function (err) {
that._logger.debug('read-json', 'Failed to read ' + metaFile, {
filename: metaFile,
error: err
});
return true; // Simply resolve to true if there was an error reading the file
});
}
@@ -151,33 +156,17 @@ Resolver.prototype._createTempDir = function () {
};
Resolver.prototype._readJson = function (dir) {
dir = dir || this._tempDir;
var that = this;
return Q.nfcall(bowerJson.find, dir)
.then(function (filename) {
// If it is a component.json, warn about the deprecation
if (path.basename(filename) === 'component.json') {
this._logger.warn('deprecated', 'Package ' + this._name + ' is using the deprecated component.json file', {
json: filename
});
dir = dir || this._tempDir;
return readJson(dir, { name: this._name })
.spread(function (json, deprecated) {
if (deprecated) {
that._logger.warn('deprecated', 'Package ' + that._name + ' is using the deprecated ' + deprecated);
}
// Read it
return Q.nfcall(bowerJson.read, filename)
.fail(function (err) {
throw createError('Something went wrong while reading ' + filename, err.code, {
details: err.message,
data: {
json: filename
}
});
});
}.bind(this), function () {
// No json file was found, assume one
return Q.nfcall(bowerJson.parse, {
name: this._name
});
}.bind(this));
return json;
});
};
Resolver.prototype._applyPkgMeta = function (meta) {

36
lib/util/readJson.js Normal file
View File

@@ -0,0 +1,36 @@
var path = require('path');
var bowerJson = require('bower-json');
var Q = require('q');
function readJson(file, options) {
options = options || {};
// Read
return Q.nfcall(bowerJson.read, file, options)
.spread(function (json, jsonFile) {
var deprecated;
jsonFile = path.basename(jsonFile);
deprecated = jsonFile === 'component.json' ? jsonFile : false;
return [json, deprecated];
}, function (err) {
// No json file was found, assume one
if (err.code === 'ENOENT' && options.name) {
return [bowerJson.parse({ name: options.name }), false];
}
err.details = err.message;
if (err.file) {
err.message = 'Failed to read ' + err.file;
err.data = { filename: err.file };
} else {
err.message = 'Failed to read json from ' + file;
}
throw err;
});
}
module.exports = readJson;

23
lib/util/validLink.js Normal file
View File

@@ -0,0 +1,23 @@
var Q = require('q');
var fs = require('graceful-fs');
function validLink(file) {
// Filter only those that are valid links
return Q.nfcall(fs.lstat, file)
.then(function (stat) {
if (!stat.isSymbolicLink()) {
return [false, null];
}
return Q.nfcall(fs.stat, file)
.then(function () {
return [true, null];
});
})
.fail(function (err) {
return [false, err];
});
}
module.exports = validLink;

View File

@@ -23,7 +23,7 @@
"abbrev": "~1.0.4",
"bower-config": "~0.2.0",
"bower-endpoint-parser": "~0.1.0",
"bower-json": "~0.1.0",
"bower-json": "~0.2.0",
"bower-logger": "~0.1.0",
"bower-registry-client": "~0.1.1",
"chmodr": "~0.1.0",