jspm
Version:
Registry and format agnostic JavaScript package manager
182 lines (166 loc) • 5.11 kB
JavaScript
/*
* Copyright 2014-2015 Guy Bedford (http://guybedford.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var ui = require('./ui');
var fs = require('graceful-fs');
var path = require('path');
var HOME = require('./config').HOME;
var lockFile = require('proper-lockfile');
var dprepend = require('./common').dprepend;
var readJSONSync = require('./common').readJSONSync;
var stringify = require('./common').stringify;
// global config - automatically created and loaded on startup
exports.registries = [];
var globalConfigFile = HOME + path.sep + '.jspm' + path.sep + 'config';
// old windows HOME migration
// can deprecate with jspm 0.15.3
if (process.env.USERPROFILE && HOME !== process.env.USERPROFILE && !fs.existsSync(path.join(HOME, '.jspm')) && fs.existsSync(path.join(process.env.USERPROFILE, '.jspm'))) {
var OLD_HOME = process.env.USERPROFILE;
var from = path.join(OLD_HOME, '.jspm');
var to = path.join(HOME, '.jspm');
ui.log('info', 'Migrating global jspm folder from `' + from + '` to `' + to + '`...');
try {
ui.log('info', 'Copying configuration...');
var oldConfig = fs.readFileSync(path.resolve(from, 'config'));
fs.mkdirSync(to);
fs.writeFileSync(path.resolve(to, 'config'), oldConfig);
ui.log('ok', 'Migration successful. Note that linked packages will need to be relinked.');
}
catch (e) {
ui.log('err', 'Error migrating to new jspm folder\n' + (e && e.stack || e));
}
}
// Begin file lock
lock();
// after loading, we'll dprepend all defaults to `exports.config` in this `try` block
exports.config = readJSONSync(globalConfigFile);
// NB can deprecate with jspm 0.14
if (!exports.config.defaultRegistry && exports.config.registry)
exports.config.defaultRegistry = exports.config.registry;
if (!exports.config.registries && exports.config.endpoints)
exports.config.registries = exports.config.endpoints;
// NB add this to deprecate 0.14
// delete exports.config.registry;
// delete exports.config.endpoints;
// config upgrade paths
// NB can deprecate with jspm < 10
if (exports.config.github) {
dprepend(exports.config.registries.github, exports.config.github);
delete exports.config.github;
}
// populate default registry configuration
dprepend(exports.config, {
defaultTranspiler: 'babel',
defaultRegistry: 'jspm',
strictSSL: true,
registries: {
github: {
handler: 'jspm-github',
remote: 'https://github.jspm.io'
},
npm: {
handler: 'jspm-npm',
remote: 'https://npm.jspm.io'
},
jspm: {
handler: 'jspm-registry',
remote: 'https://registry.jspm.io'
}
}
});
try{
if (HOME)
save();
} catch(ex) {
console.error('Unable to initialize JSPM home configuration folder!');
}
// end file lock
unlock();
function save() {
try {
fs.mkdirSync(HOME + path.sep + '.jspm');
}
catch (e) {
if (e.code !== 'EEXIST')
throw 'Unable to create jspm system folder\n' + e.stack;
}
try {
lock();
var existing = readJSONSync(globalConfigFile);
// only write to a new file if the local changes are different
if (JSON.stringify(existing) != JSON.stringify(exports.config)) {
fs.writeFileSync(globalConfigFile, stringify(exports.config));
}
}
catch (e) {
throw 'Unable to write global configuration file\n' + e.stack;
}
finally {
unlock();
}
}
exports.save = save;
exports.set = function(name, val) {
var nameParts = name.split('.');
var config = exports.config;
var part;
while (nameParts.length > 1) {
part = nameParts.shift();
config[part] = typeof config[part] === 'object' ? config[part] : {};
config = config[part];
}
if (val !== undefined) {
config[nameParts[0]] = val;
}
else {
// If no value is specified, then remove property from config
delete config[nameParts[0]];
}
save();
};
var _unlock;
function lock() {
if (!_unlock) {
try {
_unlock = lockFile.lockSync(globalConfigFile, {
retries: {
retries: 10,
minTimeout: 20,
maxTimeout: 300,
randomize: true
},
realpath: false
});
} catch (e) {
if (e.code === 'ELOCKED')
throw 'Unable to lock global config file %' + globalConfigFile + '%, not overwriting';
}
}
}
function unlock() {
if (_unlock) {
_unlock();
_unlock = undefined;
}
}
// Map SIGINT & SIGTERM to process exit
// so that lockfile removes the lockfile automatically
process
.once('SIGINT', function () {
process.exit(1);
})
.once('SIGTERM', function () {
process.exit(1);
});