cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From agri...@apache.org
Subject [10/16] git commit: config-changes.js: Add pbxproj to ConfigKeeper.
Date Wed, 19 Feb 2014 20:32:56 GMT
config-changes.js: Add pbxproj to ConfigKeeper.

ios.parseProjectFile() is extremely slow.
Use xcode directly to load pbxproj file as one of ConfigFiles cached by
ConfigKeeper.


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/a67359b9
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/a67359b9
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/a67359b9

Branch: refs/heads/master
Commit: a67359b923a15bb4ff4c148f701af1deb0f2740b
Parents: 08b045b
Author: Mark Koudritsky <kamrik@chromium.org>
Authored: Tue Feb 11 16:14:31 2014 -0500
Committer: Andrew Grieve <agrieve@chromium.org>
Committed: Wed Feb 19 15:32:26 2014 -0500

----------------------------------------------------------------------
 spec/util/config-changes.spec.js | 13 +----
 src/util/config-changes.js       | 94 ++++++++++++++++++-----------------
 2 files changed, 50 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/a67359b9/spec/util/config-changes.spec.js
----------------------------------------------------------------------
diff --git a/spec/util/config-changes.spec.js b/spec/util/config-changes.spec.js
index 6798ce9..d995023 100644
--- a/spec/util/config-changes.spec.js
+++ b/spec/util/config-changes.spec.js
@@ -12,6 +12,7 @@ var configChanges = require('../../src/util/config-changes'),
     path    = require('path'),
     plist = require('plist-with-patches'),
     shell   = require('shelljs'),
+    xcode = require('xcode'),
     temp    = path.join(os.tmpdir(), 'plugman'),
     dummyplugin = path.join(__dirname, '..', 'plugins', 'DummyPlugin'),
     cbplugin = path.join(__dirname, '..', 'plugins', 'ChildBrowser'),
@@ -297,17 +298,7 @@ describe('config-changes module', function() {
                 beforeEach(function() {
                     shell.cp('-rf', ios_config_xml, temp);
                     shell.cp('-rf', cbplugin, plugins_dir);
-                    xcode_add = jasmine.createSpy();
-                    xcode_rm = jasmine.createSpy();
-                    spyOn(ios_parser, 'parseProjectFile').andReturn({
-                        xcode:{
-                            addFramework:xcode_add,
-                            removeFramework:xcode_rm,
-                            writeSync:function(){}
-                        },
-                        pbx:path.join(temp, 'pbxpath'),
-                        write: function() {}
-                    });
+                    xcode_add = spyOn(xcode.project.prototype, 'addFramework').andCallThrough();
                 });
                 it('should call into xcode.addFramework if plugin has <framework> file
defined and is ios',function() {
                     configChanges.add_installed_plugin_to_prepare_queue(plugins_dir, 'ChildBrowser',
'ios', {});

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/a67359b9/src/util/config-changes.js
----------------------------------------------------------------------
diff --git a/src/util/config-changes.js b/src/util/config-changes.js
index 5872cf6..b448105 100644
--- a/src/util/config-changes.js
+++ b/src/util/config-changes.js
@@ -37,6 +37,7 @@ var fs   = require('fs'),
     glob = require('glob'),
     plist = require('plist-with-patches'),
     bplist = require('bplist-parser'),
+    xcode = require('xcode'),
     et   = require('elementtree'),
     underscore = require('underscore'),
     xml_helpers = require('./../util/xml-helpers'),
@@ -230,13 +231,6 @@ function unmerge_plugin_changes(plugin_name, plugin_id, is_top_level,
should_dec
     // global munge looks at all plugins' changes to config files
     var global_munge = platform_config.config_munge;
 
-    var plistObj, pbxproj;
-    if (self.platform == 'ios') {
-        if (global_munge['framework'] && config_munge['framework']) {
-            pbxproj = ios_parser.parseProjectFile(self.project_dir);
-        }
-    }
-
     // Traverse config munge and decrement global munge
     Object.keys(config_munge).forEach(function(file) {
         if (file == 'plugins-plist' && self.platform == 'ios') {
@@ -262,9 +256,9 @@ function unmerge_plugin_changes(plugin_name, plugin_id, is_top_level,
should_dec
                                     // this is a .framework reference in ios files
                                     // We also need to keep some frameworks core to cordova-ios
                                     if (keep_these_frameworks.indexOf(selector) == -1) {
-                                        pbxproj.xcode.removeFramework(selector); // in this
case the 2nd-level key is the src attrib of <framework> els
-                                        // TODO: dont write on every loop eh
-                                        fs.writeFileSync(pbxproj.pbx, pbxproj.xcode.writeSync());
+                                        var pbxproj = self.config_keeper.get(self.project_dir,
self.platform, file);
+                                        pbxproj.data.removeFramework(selector); // in this
case the 2nd-level key is the src attrib of <framework> els
+                                        pbxproj.is_changed = true;
                                     }
                                 } else {
                                     // this xml child is no longer necessary, prune it
@@ -296,7 +290,7 @@ function unmerge_plugin_changes(plugin_name, plugin_id, is_top_level,
should_dec
 
 
 PlatformMunger.prototype.apply_plugin_changes = apply_plugin_changes;
-function apply_plugin_changes(plugin_id, plugin_vars, is_top_level, should_increment, cache)
{
+function apply_plugin_changes(plugin_id, plugin_vars, is_top_level, should_increment) {
     var self = this;
     var platform_config = module.exports.get_platform_json(self.plugins_dir, self.platform);
     var plugin_dir = path.join(self.plugins_dir, plugin_id);
@@ -308,20 +302,6 @@ function apply_plugin_changes(plugin_id, plugin_vars, is_top_level, should_incre
     // global munge looks at all plugins' changes to config files
     var global_munge = platform_config.config_munge;
 
-    var plistObj;
-    // Cache some slow stuff for reuse with multiple plugins.
-    cache = cache || {};
-    var pbxproj = cache.pbxproj;
-
-    if (self.platform == 'ios') {
-        if (config_munge['framework']) {
-            if (!pbxproj) {
-                // Note, parseProjectFile() is slow, ~250ms on MacBook Pro 2013.
-                cache.pbxproj = pbxproj = ios_parser.parseProjectFile(self.project_dir);
-            }
-        }
-    }
-
     // Traverse config munge and decrement global munge
     Object.keys(config_munge).forEach(function(file) {
         if (!global_munge[file]) {
@@ -356,8 +336,9 @@ function apply_plugin_changes(plugin_id, plugin_vars, is_top_level, should_incre
                         if (keep_these_frameworks.indexOf(src) == -1) {
                             // xml_child in this case is whether the framework should use
weak or not
                             var is_weak = {weak: (xml_child === 'true')};
-                            pbxproj.xcode.addFramework(src, is_weak);
-                            pbxproj.needs_write = true;
+                            var pbxproj = self.config_keeper.get(self.project_dir, self.platform,
file);
+                            pbxproj.data.addFramework(src, is_weak);
+                            pbxproj.is_changed = true;
                         }
                     } else {
                         // this xml child is new, graft it (only if config file exists)
@@ -381,9 +362,6 @@ function apply_plugin_changes(plugin_id, plugin_vars, is_top_level, should_incre
 
     // save
     module.exports.save_platform_json(platform_config, self.plugins_dir, self.platform);
-    if ( pbxproj && pbxproj.needs_write ){
-        pbxproj.write();
-    }
 }
 
 function ConfigKeeper() {
@@ -480,11 +458,14 @@ function ConfigFile_save() {
     var self = this;
     if (self.type === 'xml') {
         fs.writeFileSync(self.filepath, self.data.write({indent: 4}), 'utf-8');
+    } else if (self.type === 'pbxproj') {
+        fs.writeFileSync(self.filepath, self.data.writeSync());
     } else {
         // plist
         var regExp = new RegExp("<string>[ \t\r\n]+?</string>", "g");
         fs.writeFileSync(self.filepath, plist.build(self.data).replace(regExp, "<string></string>"));
     }
+    self.is_changed = false;
 }
 
 
@@ -507,6 +488,10 @@ function ConfigFile_load() {
     if (ext == '.xml' || ext == '.appxmanifest') {
         self.type = 'xml';
         self.data = xml_helpers.parseElementtreeSync(filepath);
+    } else if (ext == '.pbxproj') {
+        self.type = 'pbxproj';
+        self.data = xcode.project(filepath);
+        self.data.parseSync();
     } else {
         // plist file
         self.type = 'plist';
@@ -545,36 +530,53 @@ function isBinaryPlist(filename) {
 
 function getIOSProjectname(project_dir){
     var matches = glob.sync(path.join(project_dir, '*.xcodeproj'));
-    var iospath= project_dir;
+    var iospath= project_dir; // TODO: Do we ever want to return project dir here? I wont
work in resolveConfigFilePath().
     if (matches.length) {
         iospath = path.basename(matches[0],'.xcodeproj');
     }
     return iospath;
 }
 
-// Some config-file target attributes are not qualified with a full leading directory, or
contain wildcards. resolve to a real path in this function
+// Some config-file target attributes are not qualified with a full leading directory, or
contain wildcards.
+// Resolve to a real path in this function.
+// TODO: some globs are very slow, try to get rid of as many of them as possible.
 function resolveConfigFilePath(project_dir, platform, file) {
     var filepath = path.join(project_dir, file);
     var matches;
+
+    // .pbxproj file
+    if (file === 'framework') {
+        var project_files = glob.sync(path.join(project_dir, '*.xcodeproj', 'project.pbxproj'));
+        if (project_files.length === 0) {
+            throw new Error("does not appear to be an xcode project (no xcode project file)");
+        }
+        filepath = project_files[0];
+        return filepath;
+    }
+
     if (file.indexOf('*') > -1) {
         // handle wildcards in targets using glob.
         matches = glob.sync(path.join(project_dir, '**', file));
         if (matches.length) filepath = matches[0];
-    } else {
-        // special-case config.xml target that is just "config.xml". this should be resolved
to the real location of the file.
-        if (file == 'config.xml') {
-            if (platform == 'ubuntu') {
-                filepath = path.join(project_dir, 'config.xml');
-            } else if (platform == 'ios') {
-                var iospath = getIOSProjectname(project_dir);
-                filepath = path.join(project_dir,iospath, 'config.xml');
-            } else if (platform == 'android') {
-                filepath = path.join(project_dir, 'res', 'xml', 'config.xml');
-            } else {
-                matches = glob.sync(path.join(project_dir, '**', 'config.xml'));
-                if (matches.length) filepath = matches[0];
-            }
+        return filepath;
+    }
+
+    // special-case config.xml target that is just "config.xml". this should be resolved
to the real location of the file.
+    if (file == 'config.xml') {
+        if (platform == 'ubuntu') {
+            filepath = path.join(project_dir, 'config.xml');
+        } else if (platform == 'ios') {
+            var iospath = getIOSProjectname(project_dir);
+            filepath = path.join(project_dir,iospath, 'config.xml');
+        } else if (platform == 'android') {
+            filepath = path.join(project_dir, 'res', 'xml', 'config.xml');
+        } else {
+            matches = glob.sync(path.join(project_dir, '**', 'config.xml'));
+            if (matches.length) filepath = matches[0];
         }
+        return filepath;
     }
+
+    // None of the special cases matched, returning project_dir/file.
     return filepath;
 }


Mime
View raw message