mirror of
https://github.com/bower/bower.git
synced 2026-04-24 03:00:19 -04:00
Close GH-675: Upgrade to the new bower-json api.. Fixes #668
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
36
lib/util/readJson.js
Normal 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
23
lib/util/validLink.js
Normal 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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user