From fd954adc81d0355e03996b6128a33792cdc7c10f Mon Sep 17 00:00:00 2001 From: Andrew Grieve Date: Wed, 30 Oct 2013 12:18:20 -0400 Subject: [PATCH] CB-5232 Change create script to use Cordova as a library. --- bin/create | 17 ++++----- bin/lib/create.js | 81 ++++++++++++++++++++++++------------------- bin/lib/simpleargs.js | 32 +++++++++++++++++ bin/update | 15 +++----- 4 files changed, 89 insertions(+), 56 deletions(-) create mode 100644 bin/lib/simpleargs.js diff --git a/bin/create b/bin/create index 9ab6689b..7aaa7d61 100755 --- a/bin/create +++ b/bin/create @@ -20,20 +20,17 @@ */ var path = require('path'); var create = require('./lib/create'); -var args = process.argv; +var args = require('./lib/simpleargs').getArgs(process.argv); -// Support basic help commands -if(args.length < 3 || (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' || - args[2] == 'help' || args[2] == '-help' || args[2] == '/help')) { - console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' '); +if (args['--help'] || args._.length === 0) { + console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' [] [--shared]'); console.log(' : Path to your new Cordova Android project'); console.log(' : Package name, following reverse-domain style convention'); console.log(' : Project name'); + console.log(' : Path to a custom application template to use'); + console.log(' --shared will use the CordovaLib project directly instead of making a copy.'); process.exit(1); -} else { - create.createProject(args[2], args[3], args[4], args[5]).done(null, function(err) { - console.error(err); - process.exit(2); - }); } +create.createProject(args._[0], args._[1], args._[2], args._[3], args['--shared']).done(); + diff --git a/bin/lib/create.js b/bin/lib/create.js index c5696696..f11b4cee 100755 --- a/bin/lib/create.js +++ b/bin/lib/create.js @@ -29,14 +29,13 @@ var shell = require('shelljs'), // Returns a promise. function exec(command, opt_cwd) { var d = Q.defer(); - try { - child_process.exec(command, { cwd: opt_cwd }, function(err, stdout, stderr) { - if (err) d.reject(err); - else d.resolve(stdout); - }); - } catch(e) { - return Q.reject('Command error on execution: ' + command + '\n' + e); - } + console.log('Running: ' + command); + child_process.exec(command, { cwd: opt_cwd }, function(err, stdout, stderr) { + stdout && console.log(stdout); + stderr && console.error(stderr); + if (err) d.reject(err); + else d.resolve(stdout); + }); return d.promise; } @@ -47,32 +46,45 @@ function setShellFatal(value, func) { shell.config.fatal = oldVal; } -// Returns a promise. -function ensureJarIsBuilt(version, target_api) { - var isDevVersion = /-dev$/.test(version); - if (isDevVersion || !fs.existsSync(path.join(ROOT, 'framework', 'cordova-' + version + '.jar')) && fs.existsSync(path.join(ROOT, 'framework'))) { - var valid_target = check_reqs.get_target(); - console.log('Building cordova-' + version + '.jar'); - // update the cordova-android framework for the desired target - return exec('android --silent update lib-project --target "' + target_api + '" --path "' + path.join(ROOT, 'framework') + '"') - .then(function() { - // compile cordova.js and cordova.jar - return exec('ant jar', path.join(ROOT, 'framework')); - }); - } - return Q(); +function getFrameworkDir(projectPath, shared) { + return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib'); } -function copyJsAndJar(projectPath, version) { +function copyJsAndLibrary(projectPath, shared, projectName) { + var nestedCordovaLibPath = getFrameworkDir(projectPath, false); shell.cp('-f', path.join(ROOT, 'framework', 'assets', 'www', 'cordova.js'), path.join(projectPath, 'assets', 'www', 'cordova.js')); // Don't fail if there are no old jars. setShellFatal(false, function() { shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function(oldJar) { console.log("Deleting " + oldJar); - shell.rm('-f', path.join(oldJar)); + shell.rm('-f', oldJar); }); + // Delete old library project if it existed. + if (shared) { + shell.rm('-rf', nestedCordovaLibPath); + } else { + // Delete only the src, since eclipse can't handle its .project file being deleted. + shell.rm('-rf', path.join(nestedCordovaLibPath, 'src')); + } }); - shell.cp('-f', path.join(ROOT, 'framework', 'cordova-' + version + '.jar'), path.join(projectPath, 'libs', 'cordova-' + version + '.jar')); + if (!shared) { + shell.mkdir('-p', nestedCordovaLibPath); + shell.cp('-f', path.join(ROOT, 'framework', 'AndroidManifest.xml'), nestedCordovaLibPath); + shell.cp('-f', path.join(ROOT, 'framework', 'project.properties'), nestedCordovaLibPath); + shell.cp('-r', path.join(ROOT, 'framework', 'src'), nestedCordovaLibPath); + // Create an eclipse project file and set the name of it to something unique. + // Without this, you can't import multiple CordovaLib projects into the same workspace. + var eclipseProjectFilePath = path.join(nestedCordovaLibPath, '.project'); + if (!fs.existsSync(eclipseProjectFilePath)) { + var data = '' + projectName + '-' + 'CordovaLib'; + fs.writeFileSync(eclipseProjectFilePath, data, 'utf8'); + } + } +} + +function runAndroidUpdate(projectPath, target_api, shared) { + var targetFrameworkDir = getFrameworkDir(projectPath, shared); + return exec('android update project --subprojects --path "' + projectPath + '" --target ' + target_api + ' --library "' + path.relative(projectPath, targetFrameworkDir) + '"'); } function copyScripts(projectPath) { @@ -104,7 +116,7 @@ function copyScripts(projectPath) { * Returns a promise. */ -exports.createProject = function(project_path, package_name, project_name, project_template_dir) { +exports.createProject = function(project_path, package_name, project_name, project_template_dir, use_shared_project) { var VERSION = fs.readFileSync(path.join(ROOT, 'VERSION'), 'utf-8').trim(); // Set default values for path, package and name @@ -142,9 +154,6 @@ exports.createProject = function(project_path, package_name, project_name, proje console.log('\tName: ' + project_name); console.log('\tAndroid target: ' + target_api); - // build from source. distro should have these files - return ensureJarIsBuilt(VERSION, target_api); - }).then(function() { console.log('Copying template files...'); setShellFatal(true, function() { @@ -156,7 +165,7 @@ exports.createProject = function(project_path, package_name, project_name, proje // copy cordova.js, cordova.jar and res/xml shell.cp('-r', path.join(ROOT, 'framework', 'res', 'xml'), path.join(project_path, 'res')); - copyJsAndJar(project_path, VERSION); + copyJsAndLibrary(project_path, use_shared_project, safe_activity_name); // interpolate the activity name and package shell.mkdir('-p', activity_dir); @@ -172,8 +181,7 @@ exports.createProject = function(project_path, package_name, project_name, proje copyScripts(project_path); }); // Link it to local android install. - console.log('Running "android update project"'); - return exec('android --silent update project --target "'+target_api+'" --path "'+ project_path+'"'); + return runAndroidUpdate(project_path, target_api, use_shared_project); }).then(function() { console.log('Project successfully created.'); }); @@ -186,11 +194,12 @@ exports.updateProject = function(projectPath) { return check_reqs.run() .then(function() { var target_api = check_reqs.get_target(); - return ensureJarIsBuilt(version, target_api); - }).then(function() { - copyJsAndJar(projectPath, version); + copyJsAndLibrary(projectPath, false, null); copyScripts(projectPath); - console.log('Android project is now at version ' + version); + return runAndroidUpdate(projectPath, target_api, false) + .then(function() { + console.log('Android project is now at version ' + version); + }); }); }; diff --git a/bin/lib/simpleargs.js b/bin/lib/simpleargs.js new file mode 100644 index 00000000..d286f06e --- /dev/null +++ b/bin/lib/simpleargs.js @@ -0,0 +1,32 @@ +/* + 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. +*/ + +exports.getArgs = function(argv) { + var ret = {}; + var posArgs = []; + for (var i = 2, arg; arg = argv[i] || i < argv.length; ++i) { + if (/^--/.exec(arg)) { + ret[arg] = true; + } else { + posArgs.push(arg); + } + } + ret._ = posArgs; + return ret; +}; diff --git a/bin/update b/bin/update index 59f2bb6d..40c14741 100755 --- a/bin/update +++ b/bin/update @@ -19,18 +19,13 @@ under the License. */ var path = require('path'); -var args = process.argv; var create = require('./lib/create'); +var args = require('./lib/simpleargs').getArgs(process.argv); -// Support basic help commands -if(args.length < 3 || (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' || - args[2] == 'help' || args[2] == '-help' || args[2] == '/help')) { - console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'update')) + ' '); +if (args['--help'] || args._.length === 0) { + console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'update')) + ' [--shared]'); + console.log(' --shared will use the CordovaLib project directly instead of making a copy.'); process.exit(1); -} else { - create.updateProject(args[2]).done(null, function(err) { - console.error(err); - process.exit(2); - }); } +create.updateProject(args._[0], args['--shared']).done();