mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
wip refactoring
... towards an idempotent `ensureCordovaProject` sub-routine
This commit is contained in:
@@ -1459,7 +1459,11 @@ main.registerCommand({
|
||||
// cordova
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var generateCordovaBoilerplate = function (clientDir, clientJson, boilerplateTemplateSource) {
|
||||
var generateCordovaBoilerplate = function (clientDir) {
|
||||
var clientJsonPath = path.join(clientDir, 'program.json');
|
||||
var clientJson = JSON.parse(fs.readFileSync(clientJsonPath, 'utf8'));
|
||||
var boilerplatePath = path.join(__dirname, 'client', 'cordova-boilerplate.html');
|
||||
var boilerplateTemplateSource = fs.readFileSync(boilerplatePath, 'utf8');
|
||||
var boilerplateData = {
|
||||
css: [],
|
||||
js: [],
|
||||
@@ -1509,6 +1513,82 @@ var generateCordovaBoilerplate = function (clientDir, clientJson, boilerplateTem
|
||||
HTML.toHTML(boilerplateHtmlJs, boilerplateInstance);
|
||||
};
|
||||
|
||||
// Creates a Cordova project if necessary and makes sure added Cordova
|
||||
// platforms and Cordova plugins are up to date with the project's
|
||||
// definition.
|
||||
var ensureCordovaProject = function (appName, projectPath, bundlePath) {
|
||||
// XXX temp hack as the easiest way to ensure right now is to destroy and
|
||||
// recreate
|
||||
files.rm_recursive(projectPath);
|
||||
|
||||
var bundler = require(path.join(__dirname, 'bundler.js'));
|
||||
var loader = project.getPackageLoader();
|
||||
|
||||
var clientArchName = 'client.cordova';
|
||||
|
||||
var bundleResult = bundler.bundle({
|
||||
outputPath: bundlePath,
|
||||
buildOptions: {
|
||||
minify: false, // XXX ! options.debug,
|
||||
arch: archinfo.host(),
|
||||
clientArchs: [clientArchName]
|
||||
}
|
||||
});
|
||||
|
||||
if (bundleResult.errors) {
|
||||
throw new Error("Errors prevented bundling:\n" +
|
||||
bundleResult.errors.formatMessages());
|
||||
}
|
||||
|
||||
var programPath = path.join(bundlePath, 'programs');
|
||||
|
||||
// XXX check if Cordova folder exists, don't run `cordova create`
|
||||
|
||||
execFileSync('cordova', ['create', path.basename(projectPath),
|
||||
'com.meteor.' + appName,
|
||||
appName.replace(/\s/g, '')],
|
||||
{ cwd: path.dirname(projectPath) });
|
||||
|
||||
var wwwPath = path.join(projectPath, "www");
|
||||
|
||||
var cordovaProgramPath = path.join(programPath, clientArchName);
|
||||
var cordovaProgramAppPath = path.join(cordovaProgramPath, 'app');
|
||||
|
||||
// XXX hack, copy files from app folder one level up
|
||||
files.cp_r(cordovaProgramAppPath, cordovaProgramPath);
|
||||
files.rm_recursive(cordovaProgramAppPath);
|
||||
|
||||
// rewrite the www folder
|
||||
files.rm_recursive(wwwPath);
|
||||
files.cp_r(cordovaProgramPath, wwwPath);
|
||||
|
||||
// clean up the temporary bundle directory
|
||||
files.rm_recursive(bundlePath);
|
||||
|
||||
// generate index.html
|
||||
var indexHtml = generateCordovaBoilerplate(wwwPath);
|
||||
fs.writeFileSync(path.join(wwwPath, 'index.html'), indexHtml, 'utf8');
|
||||
|
||||
// XXX get the output of `cordova plugins` and compare to the project
|
||||
// dependencies; add/remove plugins if different.
|
||||
// XXX compare the latest used sha's with the currently required sha's for
|
||||
// plugins fetched from a github/tarball url.
|
||||
|
||||
// XXX get platforms from project file
|
||||
// _.each(platforms, function (platform) {
|
||||
// execFileSync('cordova', ['platform', 'add', platform], { cwd: projectPath });
|
||||
// });
|
||||
|
||||
_.each(bundleResult.starManifest.cordovaDependencies,
|
||||
function (version, name) {
|
||||
// XXX do something different for plugins fetched from a url.
|
||||
execFileSync('cordova', ['plugin', 'add', name + '@' + version],
|
||||
{ cwd: projectPath });
|
||||
});
|
||||
|
||||
execFileSync('cordova', ['build'], { cwd: projectPath });
|
||||
};
|
||||
|
||||
main.registerCommand({
|
||||
name: 'cordova',
|
||||
minArgs: 1,
|
||||
@@ -1519,75 +1599,22 @@ main.registerCommand({
|
||||
},
|
||||
}, function (options) {
|
||||
var localDir = path.join(options.appDir, '.meteor', 'local');
|
||||
var cordovaPath = path.join(localDir, 'client.cordova');
|
||||
var cordovaPath = path.join(localDir, 'cordova-build');
|
||||
var bundleDir = path.join(localDir, 'bundle-tar');
|
||||
var appName = path.basename(options.appDir);
|
||||
|
||||
if (options.args[0] === 'create') {
|
||||
files.rm_recursive(cordovaPath);
|
||||
var buildDir = path.join(localDir, 'build_tar');
|
||||
var outputPath = path.join(buildDir, 'bundle');
|
||||
var cordovaCommand = options.args[0];
|
||||
var cordovaArgs = options.args.slice(1);
|
||||
|
||||
var bundler = require(path.join(__dirname, 'bundler.js'));
|
||||
var loader = project.getPackageLoader();
|
||||
stats.recordPackages(options.appDir);
|
||||
|
||||
var clientArchs = ['client.cordova'];
|
||||
|
||||
var bundleResult = bundler.bundle({
|
||||
outputPath: outputPath,
|
||||
buildOptions: {
|
||||
minify: false, // XXX ! options.debug,
|
||||
arch: archinfo.host(),
|
||||
clientArchs: clientArchs
|
||||
}
|
||||
});
|
||||
|
||||
if (bundleResult.errors) {
|
||||
process.stdout.write("Errors prevented bundling:\n");
|
||||
process.stdout.write(bundleResult.errors.formatMessages());
|
||||
return 1;
|
||||
}
|
||||
|
||||
var programPath = path.join(outputPath, 'programs');
|
||||
var appName = path.basename(options.appDir);
|
||||
execFileSync('cordova', ['create', 'client.cordova',
|
||||
'com.meteor.' + appName,
|
||||
appName.replace(/\s/g, '')], { cwd: localDir });
|
||||
|
||||
var wwwPath = path.join(cordovaPath, "www");
|
||||
|
||||
var fromPath = path.join(programPath, 'client.cordova');
|
||||
var appPath = path.join(fromPath, 'app');
|
||||
|
||||
files.cp_r(appPath, fromPath);
|
||||
files.rm_recursive(appPath);
|
||||
|
||||
files.rm_recursive(wwwPath);
|
||||
files.cp_r(fromPath, wwwPath);
|
||||
|
||||
var clientJsonPath = path.join(wwwPath, 'program.json');
|
||||
var clientJson = JSON.parse(fs.readFileSync(clientJsonPath, 'utf8'));
|
||||
var boilerplatePath = path.join(__dirname, 'client', 'cordova-boilerplate.html');
|
||||
var boilerplateTemplateSource = fs.readFileSync(boilerplatePath, 'utf8');
|
||||
var indexHtml = generateCordovaBoilerplate(wwwPath, clientJson, boilerplateTemplateSource);
|
||||
fs.writeFileSync(path.join(wwwPath, 'index.html'), indexHtml, 'utf8');
|
||||
|
||||
_.each(options.args.slice(1), function (arch) {
|
||||
execFileSync('cordova', ['platform', 'add', arch], { cwd: cordovaPath });
|
||||
});
|
||||
|
||||
_.each(bundleResult.starManifest.cordovaDependencies,
|
||||
function (version, name) {
|
||||
execFileSync('cordova', ['plugin', 'add', name + '@' + version],
|
||||
{ cwd: cordovaPath });
|
||||
});
|
||||
|
||||
execFileSync('cordova', ['build'], { cwd: cordovaPath });
|
||||
|
||||
files.rm_recursive(fromPath);
|
||||
files.rm_recursive(buildDir);
|
||||
} else {
|
||||
// XXX error if not a Cordova project
|
||||
execFileSync('cordova', options.args, { cwd: cordovaPath });
|
||||
try {
|
||||
ensureCordovaProject(appName, cordovaPath, bundleDir);
|
||||
} catch (e) {
|
||||
process.stderr.write('Errors preventing the Cordova project from build:\n');
|
||||
process.stderr.write(e.stack);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// XXX error if not a Cordova project
|
||||
execFileSync('cordova', options.args, { cwd: cordovaPath });
|
||||
});
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ var trimLine = function (line) {
|
||||
return line;
|
||||
};
|
||||
|
||||
// Given a set of lines, each of the form "foo@bar", return an array of form
|
||||
// [{packageName: foo, versionConstraint: bar}]. If there is bar,
|
||||
// versionConstraint is null.
|
||||
// Given a set of lines, each of the form "foo@bar", return an object of form
|
||||
// {foo: "bar", bar: null}. If there is "bar", value of the corresponding key is
|
||||
// null.
|
||||
var processPerConstraintLines = function(lines) {
|
||||
var ret = {};
|
||||
|
||||
@@ -66,6 +66,15 @@ var Project = function () {
|
||||
// and recorded in the .meteor/versions file.
|
||||
self.dependencies = null;
|
||||
|
||||
// Plugins & versions of all Cordova plugins dependencies.
|
||||
// A mapping from the Cordova plugin identifier to a semver string or a
|
||||
// tarball url with sha.
|
||||
// XXX Ignores the transitive dependencies.
|
||||
self.cordovaPlugins = null;
|
||||
|
||||
// Platfroms & versions used by the Cordova project.
|
||||
self.cordovaPlatforms = null
|
||||
|
||||
// The package loader for this project, with the project's dependencies as its
|
||||
// version file. (See package-loader.js for more information about package
|
||||
// loaders). Derived from self.dependencies.
|
||||
@@ -128,6 +137,12 @@ _.extend(Project.prototype, {
|
||||
// Also, make sure we have an app identifier for this app.
|
||||
self.ensureAppIdentifier();
|
||||
|
||||
self.cordovaPlugins = processPerConstraintLines(
|
||||
files.getLinesOrEmpty(self._getCordovaPluginsFile()));
|
||||
|
||||
self.cordovaPlatforms = processPerConstraintLines(
|
||||
files.getLinesOrEmpty(self._getCordovaPlatformsFile()));
|
||||
|
||||
// Lastly, invalidate everything that we have computed -- obviously the
|
||||
// dependencies that we counted with the previous rootPath are wrong and we
|
||||
// need to recompute them.
|
||||
@@ -442,6 +457,30 @@ _.extend(Project.prototype, {
|
||||
return path.join(self.rootDir, '.meteor', 'versions');
|
||||
},
|
||||
|
||||
getCordovaPlugins: function () {
|
||||
var self = this;
|
||||
return self.cordovaPlugins;
|
||||
},
|
||||
|
||||
getCordovaPlatforms: function () {
|
||||
var self = this;
|
||||
return self.cordovaPlatforms;
|
||||
},
|
||||
|
||||
// Returns the file path to the .meteor/cordova-plugins file, containing the
|
||||
// Cordova plugins dependencies for this specific project.
|
||||
_getCordovaPluginsFile: function () {
|
||||
var self = this;
|
||||
return path.join(self.rootDir, '.meteor', 'cordova-plugins');
|
||||
},
|
||||
|
||||
// Returns the file path to the .meteor/cordova-platforms file, containing the
|
||||
// targetted Cordova platforms for this specific project.
|
||||
_getCordovaPlatformsFile: function () {
|
||||
var self = this;
|
||||
return path.join(self.rootDir, '.meteor', 'cordova-platforms');
|
||||
},
|
||||
|
||||
// Give the package loader attached to this project to the caller.
|
||||
//
|
||||
// Returns a packageLoader that has been pre-loaded with this project's
|
||||
@@ -800,7 +839,49 @@ _.extend(Project.prototype, {
|
||||
appendText += upgrader + '\n';
|
||||
|
||||
fs.appendFileSync(self._finishedUpgradersFile(), appendText);
|
||||
},
|
||||
|
||||
// Adds the passed plugins to the cordovaPlugins list. If the plugin was
|
||||
// already in the list, just updates it in-place.
|
||||
// newPlugins is an object with a mapping from the Cordova plugin identifier
|
||||
// to an semver string or a tarball url with a sha.
|
||||
addCordovaPlugins: function (newPlugins) {
|
||||
var self = this;
|
||||
self.cordovaPlugins = _.extend(self.cordovaPlugins, newPlugins);
|
||||
|
||||
var plugins = self._getCordovaPluginsFile();
|
||||
var lines = files.getLinesOrEmpty(plugins);
|
||||
_.each(self.cordovaPlugins, function (versionString, plugin) {
|
||||
if (versionString)
|
||||
lines.push(plugin + '@' + versionString);
|
||||
else
|
||||
lines.push(plugin);
|
||||
});
|
||||
lines.push('\n');
|
||||
fs.writeFileSync(plugins, lines.join('\n'), 'utf8');
|
||||
},
|
||||
|
||||
// Removes the plugins from the cordova-plugins file if they existed.
|
||||
// pluginsToRemove - array of Cordova plugin identifiers
|
||||
removeCordovaPlugins: function (pluginsToRemove) {
|
||||
var self = this;
|
||||
|
||||
self.cordovaPlugins =
|
||||
_.omit.apply(null, [self.cordovaPlugins].concat(pluginsToRemove));
|
||||
|
||||
var plugins = self._getCordovaPluginsFile();
|
||||
var lines = files.getLinesOrEmpty(plugins);
|
||||
_.each(self.cordovaPlugins, function (versionString, plugin) {
|
||||
if (versionString)
|
||||
lines.push(plugin + '@' + versionString);
|
||||
else
|
||||
lines.push(plugin);
|
||||
});
|
||||
lines.push('\n');
|
||||
fs.writeFileSync(plugins, lines.join('\n'), 'utf8');
|
||||
}
|
||||
|
||||
// XXX addCordovaPlatforms, removeCordovaPlatforms
|
||||
});
|
||||
|
||||
// The project is currently a singleton, but there is no universal reason for
|
||||
|
||||
Reference in New Issue
Block a user