blob: b43cc81903485dd32a0e8fa14644f737c8b97d38 [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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 apputil = require('./apputil');
var optimist = require('optimist');
var flagutil = require('./flagutil');
var repoutil = require('./repoutil');
var repoupdate = require('./repo-update');
var retrieveSha = require('./retrieve-sha');
var npmpublish = require('./npm-publish');
var versionutil = require('./versionutil');
var gitutil = require('./gitutil');
var fs = require('fs');
var path = require('path');
var repoclone = require('./repo-clone');
module.exports = function * (argv) {
/** Specifies the default repos to build nightlies for */
var DEFAULT_NIGHTLY_REPOS = ['cli', 'lib', 'fetch', 'common', 'create', 'coho'];
var opt = flagutil.registerHelpFlag(optimist);
opt = flagutil.registerRepoFlag(opt);
argv = opt
.usage('Publish CLI & LIB to NPM under nightly tag. \n' +
'Cordova platform add uses latest commits to the platforms. \n' +
'Usage: $0 nightly'
)
.options('pretend', {
desc: 'Don\'t actually publish to npm, just print what would be run.',
type: 'boolean'
})
.default({ r: DEFAULT_NIGHTLY_REPOS })
.argv;
if (argv.h) {
optimist.showHelp();
process.exit(1);
}
// Clone and update Repos
yield prepareRepos(argv.r);
var reposToBuild = flagutil.computeReposFromFlag(argv.r, { includeModules: true });
// Get updated nightly versions for all repos
/** @type {Object} A map of repo.id and a short SHA for every repo to build */
var VERSIONS = yield retrieveVersions(reposToBuild);
// Update version in package.json and other respective files for every repo
// and update dependencies to use nightly versions of packages to be released
yield repoutil.forEachRepo(reposToBuild, function * (repo) {
apputil.print('Updating ' + repo.id + ' version to ' + VERSIONS[repo.id]);
yield versionutil.updateRepoVersion(repo, VERSIONS[repo.id], { commitChanges: false });
updateRepoDependencies(repo, VERSIONS);
});
// Pin nightly versions of platforms
if (reposToBuild.some(function (repo) { return repo.id === 'lib'; })) {
apputil.print('Updating platforms pinned versions...');
versionutil.updatePlatformsConfig(VERSIONS);
}
var options = {};
options.tag = 'nightly';
options.pretend = argv.pretend;
options.r = reposToBuild.map(function (repo) { return repo.id; });
// publish to npm under nightly tag
yield npmpublish.publishTag(options);
};
function * prepareRepos (repoNames) {
// Clone and update required repos
apputil.print('Cloning and updating required repositories...');
var reposToClone = flagutil.computeReposFromFlag(['tools'].concat(repoNames));
yield repoclone.cloneRepos(reposToClone, /* silent= */true);
yield repoupdate.updateRepos(reposToClone, /* silent= */true);
// Remove local changes and sync up with remote master
apputil.print('Resetting repositories to "master" branches...');
var reposToUpdate = flagutil.computeReposFromFlag(repoNames);
yield repoutil.forEachRepo(reposToUpdate, function * () {
yield gitutil.gitClean();
yield gitutil.resetFromOrigin();
});
}
/**
* Updates current repo dependencies with versions, supplied in dependencies object
* @param {Object} repo Current repo which dependencies need to be updated
* @param {Object<String, String>} dependencies Map of package's id's and nightly versions
*/
function updateRepoDependencies (repo, dependencies) {
var packageJSONPath = path.join(process.cwd(), 'package.json');
var packageJSON = JSON.parse(fs.readFileSync(packageJSONPath));
// Let's iterate through repos we're going to release
Object.keys(dependencies).map(function (dependencyId) {
var repo = repoutil.getRepoById(dependencyId);
var packageId = repo.packageName || repo.repoName;
if (packageJSON.dependencies[packageId]) {
// If current repo has dependency that points to one of packages, we're going
// to release, update that dependency's version to nightly
apputil.print('Updating ' + packageId + ' dependency version to ' + dependencies[dependencyId]);
packageJSON.dependencies[packageId] = dependencies[dependencyId];
}
});
fs.writeFileSync(packageJSONPath, JSON.stringify(packageJSON, null, 2) + '\n', 'utf8');
}
/**
* Generates suffix for appending to nightly package version
* based on current date and SHA string.
* @param SHA {String} String to use to generate nightly version
* @returns {String} A newly generated nightly suffix
*/
function getNightlySuffix (SHA) {
var currentDate = new Date();
var nightlySuffix = '-nightly.' + currentDate.getUTCFullYear() + '.' +
(currentDate.getUTCMonth() + 1) + '.' + currentDate.getUTCDate() +
'.' + SHA;
return nightlySuffix;
}
/**
* Generates map of repo.id -> nightly version based on current
* date and SHA of current revision of repository
* @param {Object[]} repos An array of cordova repos
* @returns {Object} Mapped object
*/
function * retrieveVersions (repos) {
var SHAJSON = yield retrieveSha(repos);
return Object.keys(SHAJSON).reduce(function (result, repoId) {
var repoPath = repoutil.getRepoDir(repoutil.getRepoById(repoId));
var oldVersion = require(path.join(repoPath, 'package.json')).version;
result[repoId] = versionutil.removeDev(oldVersion) + getNightlySuffix(SHAJSON[repoId]);
return result;
}, {});
}