var mout = require('mout'); var Q = require('q'); var chalk = require('chalk'); var PackageRepository = require('../core/PackageRepository'); var Config = require('bower-config'); var Tracker = require('../util/analytics').Tracker; var cli = require('../util/cli'); var createError = require('../util/createError'); var defaultConfig = require('../config'); var GitHubResolver = require('../core/resolvers/GitHubResolver'); function register(logger, name, url, config) { var repository; var registryClient; var tracker; var force; config = defaultConfig(config); force = config.force; tracker = new Tracker(config); // Bypass any cache config.offline = false; config.force = true; // Trim name name = name.trim(); return Q.try(function () { // Verify name // TODO: Verify with the new spec regexp? if (!name) { throw createError('Please type a name', 'EINVNAME'); } // The public registry only allows git:// endpoints // As such, we attempt to convert URLs as necessary if (config.registry.register === Config.DEFAULT_REGISTRY) { url = convertUrl(url, logger); if (!mout.string.startsWith(url, 'git://')) { throw createError('The registry only accepts URLs starting with git://', 'EINVFORMAT'); } } tracker.track('register'); // Attempt to resolve the package referenced by the URL to ensure // everything is ok before registering repository = new PackageRepository(config, logger); return repository.fetch({ name: name, source: url, target: '*' }); }) .spread(function (canonicalDir, pkgMeta) { if (pkgMeta.private) { throw createError('The package you are trying to register is marked as private', 'EPRIV'); } // If non interactive or user forced, bypass confirmation if (!config.interactive || force) { return true; } // Confirm if the user really wants to register return Q.nfcall(logger.prompt.bind(logger), { type: 'confirm', message: 'Registering a package will make it installable via the registry (' + chalk.cyan.underline(config.registry.register) + '), continue?', default: true }); }) .then(function (result) { // If user response was negative, abort if (!result) { return; } // Register registryClient = repository.getRegistryClient(); logger.action('register', url, { name: name, url: url }); return Q.nfcall(registryClient.register.bind(registryClient), name, url); }); } function convertUrl(url, logger) { var pair; var newUrl; if (!mout.string.startsWith(url, 'git://')) { // Convert GitHub ssh & https to git:// pair = GitHubResolver.getOrgRepoPair(url); if (pair) { newUrl = 'git://github.com/' + pair.org + '/' + pair.repo + '.git'; logger.warn('convert', 'Converted ' + url + ' to ' + newUrl); } } return newUrl || url; } // ------------------- register.line = function (logger, argv) { var options = cli.readOptions(argv); var name = options.argv.remain[1]; var url = options.argv.remain[2]; if (!name || !url) { return new Q(); } else { return register(logger, name, url); } }; register.completion = function () { // TODO: }; module.exports = register;