Skip to content
This repository has been archived by the owner on Jan 31, 2019. It is now read-only.

Commit

Permalink
fix installing by name, building a valid version tree before updating…
Browse files Browse the repository at this point in the history
… with latest satisfying version
  • Loading branch information
Caolan McMahon committed Feb 10, 2012
1 parent 47b611a commit 03afb8c
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 61 deletions.
62 changes: 47 additions & 15 deletions lib/commands/install.js
Expand Up @@ -91,7 +91,7 @@ exports.install = function (pkg, opt, callback) {
// may not be a file
opt.target_dir = opt.target_dir || utils.abspath('packages');
logger.info('installing from repositories', pkg);
return exports.installRepo(pkg, opt, callback);
return exports.installName(pkg, opt, callback);
}
if (stats.isDirectory()) {
opt.target_dir = opt.target_dir || utils.abspath('packages', pkg);
Expand Down Expand Up @@ -186,23 +186,55 @@ exports.installTree = function (packages, opt, callback) {
}, callback);
};

exports.installRepo = function (name, /*optional*/range, opt, callback) {
if (!callback) {
// arity 3
callback = opt;
opt = range;
range = null;
exports.installName = function (name, opt, callback) {
var range = null;
if (!range && name.indexOf('@') !== -1) {
var parts = name.split('@');
name = parts[0];
range = parts.slice(1).join('@');
}
if (!range) {
if (name.indexOf('@') !== -1) {
var parts = name.split('@');
name = parts[0];
range = parts.slice(1).join('@');
kansorc.loadFile('.kansorc', function (err, _settings) {
if (err) {
return logger.error(err);
}
else {
range = 'latest';
if (_settings.repositories && !opt.fixed_repositories) {
// overwrite repository list with package directory's list
opt.repositories = _settings.repositories;
}
}
settings.load('.', function (err, cfg) {
if (err) {
return callback(err);
}
var sources1 = [
// TODO: should this use other package_paths too?
exports.dirSource(opt.target_dir),
exports.repoSource(opt.repositories)
];
var pkg1 = {
config: cfg,
source: 'root'
};
tree.build(pkg1, sources1, function (err, packages) {
if (err) {
return callback(err);
}
var sources2 = [
// TODO: should this use other package_paths too?
exports.dirSource(opt.target_dir),
exports.repoSource(opt.repositories)
];
tree.addDependency(
cfg.name, name, range, sources2, packages,
function (err, packages) {
exports.installTree(packages, opt, callback);
}
);
});
});
});
};

exports.installRepo = function (name, range, opt, callback) {
repository.fetch(name, range, opt.repositories,
function (err, tfile, cdir, v, cfg, from_cache) {
if (err) {
Expand Down
26 changes: 8 additions & 18 deletions lib/repository.js
Expand Up @@ -389,7 +389,7 @@ exports.resolve = function (name, ranges, repos, callback) {
return callback(e);
}
}
return callback(null, m.version, m.doc, m.repository);
return callback(null, m.version, m.config, m.repository);
});
};

Expand Down Expand Up @@ -481,8 +481,7 @@ exports.maxSatisfying = function (name, ranges, repositories, callback) {
// data argument is an optional cached package document from a previous call to
// repository.resolve to avoid multiple db.get calls if possible

exports.fetch = function (name, version, repositories,
/*optional*/data, /*optional*/ repository, callback) {
exports.fetch = function (name, version, repos, /*opt*/repository, callback) {

logger.debug('fetching', name + ' (' + version + ')');

Expand All @@ -506,7 +505,10 @@ exports.fetch = function (name, version, repositories,
return;
}

function getVersion(v, data, repository) {
exports.resolve(name, version, repos, function (err, v, cfg, repo) {
if (err) {
return callback(err);
}
cache.get(name, v, function (err, c_tfile, c_cdir) {
if (err) {
return callback(err);
Expand All @@ -521,33 +523,21 @@ exports.fetch = function (name, version, repositories,
return;
}
var filename = name + '-' + v + '.tar.gz';
var url = repository + '/' + name + '/' + filename;
var url = repo + '/' + name + '/' + filename;
logger.info('downloading', utils.noAuthURL(url));
exports.download(url, function (err, tarfile) {
if (err) {
return callback(err);
}
cache.moveTar(name, v, tarfile,
function (err, tfile, cdir) {
var cfg = data.versions[v];
callback(err, tfile, cdir, v, cfg);
}
);
});
});
}
});

if (data) {
getVersion(version, data, repository);
}
else {
exports.resolve(name, version, repositories, function (err, v, data, repository) {
if (err) {
return callback(err);
}
getVersion(v, data, repository);
});
}
});
};

Expand Down
69 changes: 41 additions & 28 deletions lib/tree.js
Expand Up @@ -65,42 +65,55 @@ exports.extend = function (pkg, sources, packages, callback) {
if (!dependencies.length) {
return callback(null, packages);
}
// TODO: split this into a separate exported function with a better name?
function iterator(k, cb) {
if (!packages[k]) {
packages[k] = exports.createPackage(sources);
}
var dep = packages[k];
var curr = dep.current_version;
dep.ranges[pkg.config.name] = pkg.config.dependencies[k];

if (!curr || !versions.satisfiesAll(curr, Object.keys(dep.ranges))) {
var available = Object.keys(dep.versions);
var ranges = _.values(dep.ranges);
var match = versions.maxSatisfying(available, ranges);

if (match) {
dep.current_version = match;
exports.extend(dep.versions[match], sources, packages, cb);
}
else {
return exports.updateDep(k, dep, function (err) {
if (err) {
return cb(err);
}
// re-run iterator with original args now there are
// new versions available
return iterator(k, cb);
});
}
}
exports.addDependency(
pkg.config.name, // parent name
k, // dependency name
pkg.config.dependencies[k], // dependency version range
sources, // package sources
packages, // version tree
cb // callback
);
}
async.forEach(dependencies, iterator, function (err) {
callback(err, packages);
});
};


exports.addDependency = function (parent, name, range, sources, packages, cb) {
if (!packages[name]) {
packages[name] = exports.createPackage(sources);
}
var dep = packages[name];
var curr = dep.current_version;
dep.ranges[parent] = range;

if (!curr || !versions.satisfiesAll(curr, Object.keys(dep.ranges))) {
var available = Object.keys(dep.versions);
var ranges = _.values(dep.ranges);
var match = versions.maxSatisfying(available, ranges);

if (match) {
dep.current_version = match;
exports.extend(dep.versions[match], sources, packages, cb);
}
else {
return exports.updateDep(name, dep, function (err) {
if (err) {
return cb(err);
}
// re-run iterator with original args now there are
// new versions available
return exports.addDependency(
parent, name, range, sources, packages, cb
);
});
}
}
};


exports.updateDep = function (name, dep, callback) {
if (dep.update_in_progress) {
return dep.ev.once('update', callback);
Expand Down

0 comments on commit 03afb8c

Please sign in to comment.