From 3a5bdc9ce839c524f96930496483c04dc396b201 Mon Sep 17 00:00:00 2001 From: Tobias Bocanegra Date: Sun, 20 Apr 2014 21:56:55 -0700 Subject: [PATCH 1/2] CB-6506 RTC: Add support for OSX --- src/platforms.js | 1 + src/platforms/osx.js | 215 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 src/platforms/osx.js diff --git a/src/platforms.js b/src/platforms.js index a2ad6348..ae5d7645 100644 --- a/src/platforms.js +++ b/src/platforms.js @@ -2,6 +2,7 @@ module.exports = { 'android': require('./platforms/android'), 'amazon-fireos': require('./platforms/amazon-fireos'), 'ios': require('./platforms/ios'), + 'osx': require('./platforms/osx'), 'blackberry10': require('./platforms/blackberry10'), 'wp7': require('./platforms/wp7'), 'wp8': require('./platforms/wp8'), diff --git a/src/platforms/osx.js b/src/platforms/osx.js new file mode 100644 index 00000000..c19e3cbf --- /dev/null +++ b/src/platforms/osx.js @@ -0,0 +1,215 @@ +/* + * + * Copyright 2013 Anis Kadri + * + * Licensed 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 path = require('path') + , fs = require('fs') + , glob = require('glob') + , xcode = require('xcode') + , plist = require('plist-with-patches') + , shell = require('shelljs') + , cachedProjectFiles = {}; + +module.exports = { + www_dir:function(project_dir) { + return path.join(project_dir, 'www'); + }, + package_name:function(project_dir) { + var plist_file = glob.sync(path.join(project_dir, '**', '*-Info.plist'))[0]; + return plist.parseFileSync(plist_file).CFBundleIdentifier; + }, + "source-file":{ + install:function(source_el, plugin_dir, project_dir, plugin_id, project) { + var src = source_el.attrib['src']; + var srcFile = path.resolve(plugin_dir, src); + var targetDir = path.resolve(project.plugins_dir, plugin_id, getRelativeDir(source_el)); + var destFile = path.resolve(targetDir, path.basename(src)); + var is_framework = source_el.attrib['framework'] && (source_el.attrib['framework'] == 'true' || source_el.attrib['framework'] == true); + var has_flags = source_el.attrib['compiler-flags'] && source_el.attrib['compiler-flags'].length ? true : false ; + + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (fs.existsSync(destFile)) throw new Error('target destination "' + destFile + '" already exists'); + var project_ref = path.join('Plugins', path.relative(project.plugins_dir, destFile)); + + if (is_framework) { + var weak = source_el.attrib['weak']; + var opt = { weak: (weak == undefined || weak == null || weak != 'true' ? false : true ) }; + var project_relative = path.join(path.basename(project.xcode_path), project_ref); + project.xcode.addFramework(project_relative, opt); + project.xcode.addToLibrarySearchPaths({path:project_ref}); + } else { + project.xcode.addSourceFile(project_ref, has_flags ? {compilerFlags:source_el.attrib['compiler-flags']} : {}); + } + shell.mkdir('-p', targetDir); + shell.cp(srcFile, destFile); + }, + uninstall:function(source_el, project_dir, plugin_id, project) { + var src = source_el.attrib['src']; + var targetDir = path.resolve(project.plugins_dir, plugin_id, getRelativeDir(source_el)); + var destFile = path.resolve(targetDir, path.basename(src)); + var is_framework = source_el.attrib['framework'] && (source_el.attrib['framework'] == 'true' || source_el.attrib['framework'] == true); + + var project_ref = path.join('Plugins', path.relative(project.plugins_dir, destFile)); + project.xcode.removeSourceFile(project_ref); + if (is_framework) { + var project_relative = path.join(path.basename(project.xcode_path), project_ref); + project.xcode.removeFramework(project_relative); + project.xcode.removeFromLibrarySearchPaths({path:project_ref}); + } + shell.rm('-rf', destFile); + + if(fs.existsSync(targetDir) && fs.readdirSync(targetDir).length>0){ + shell.rm('-rf', targetDir); + } + } + }, + "header-file":{ + install:function(header_el, plugin_dir, project_dir, plugin_id, project) { + var src = header_el.attrib['src']; + var srcFile = path.resolve(plugin_dir, src); + var targetDir = path.resolve(project.plugins_dir, plugin_id, getRelativeDir(header_el)); + var destFile = path.resolve(targetDir, path.basename(src)); + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (fs.existsSync(destFile)) throw new Error('target destination "' + destFile + '" already exists'); + project.xcode.addHeaderFile(path.join('Plugins', path.relative(project.plugins_dir, destFile))); + shell.mkdir('-p', targetDir); + shell.cp(srcFile, destFile); + }, + uninstall:function(header_el, project_dir, plugin_id, project) { + var src = header_el.attrib['src']; + var targetDir = path.resolve(project.plugins_dir, plugin_id, getRelativeDir(header_el)); + var destFile = path.resolve(targetDir, path.basename(src)); + project.xcode.removeHeaderFile(path.join('Plugins', path.relative(project.plugins_dir, destFile))); + shell.rm('-rf', destFile); + if(fs.existsSync(targetDir) && fs.readdirSync(targetDir).length>0){ + shell.rm('-rf', targetDir); + } + } + }, + "resource-file":{ + install:function(resource_el, plugin_dir, project_dir, plugin_id, project) { + var src = resource_el.attrib['src'], + srcFile = path.resolve(plugin_dir, src), + destFile = path.resolve(project.resources_dir, path.basename(src)); + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (fs.existsSync(destFile)) throw new Error('target destination "' + destFile + '" already exists'); + project.xcode.addResourceFile(path.join('Resources', path.basename(src))); + shell.cp('-R', srcFile, project.resources_dir); + }, + uninstall:function(resource_el, project_dir, plugin_id, project) { + var src = resource_el.attrib['src'], + destFile = path.resolve(project.resources_dir, path.basename(src)); + project.xcode.removeResourceFile(path.join('Resources', path.basename(src))); + shell.rm('-rf', destFile); + } + }, + "framework":{ // CB-5238 custom frameworks only + install:function(framework_el, plugin_dir, project_dir, plugin_id, project) { + var src = framework_el.attrib['src'], + custom = framework_el.attrib['custom'], + srcFile = path.resolve(plugin_dir, src), + targetDir = path.resolve(project.plugins_dir, plugin_id, path.basename(src)); + if (!custom) throw new Error('cannot add non custom frameworks.'); + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (fs.existsSync(targetDir)) throw new Error('target destination "' + targetDir + '" already exists'); + shell.mkdir('-p', path.dirname(targetDir)); + shell.cp('-R', srcFile, path.dirname(targetDir)); // frameworks are directories + var project_relative = path.relative(project_dir, targetDir); + project.xcode.addFramework(project_relative, {customFramework: true}); + }, + uninstall:function(framework_el, project_dir, plugin_id, project) { + var src = framework_el.attrib['src'], + targetDir = path.resolve(project.plugins_dir, plugin_id, path.basename(src)); + project.xcode.removeFramework(targetDir, {customFramework: true}); + shell.rm('-rf', targetDir); + } + }, + "lib-file": { + install:function(source_el, plugin_dir, project_dir, plugin_id) { + require('../../plugman').emit('verbose', 'lib-file.install is not supported for ios'); + }, + uninstall:function(source_el, project_dir, plugin_id) { + require('../../plugman').emit('verbose', 'lib-file.uninstall is not supported for ios'); + } + }, + parseProjectFile:function(project_dir) { + // TODO: With ConfigKeeper introduced in config-changes.js + // there is now double caching of iOS project files. + // Remove the cache here when install can handle + // a list of plugins at once. + if (cachedProjectFiles[project_dir]) { + return cachedProjectFiles[project_dir]; + } + // grab and parse pbxproj + // we don't want CordovaLib's xcode project + 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)"); + } + var pbxPath = project_files[0]; + var xcodeproj = xcode.project(pbxPath); + xcodeproj.parseSync(); + + // grab and parse plist file or config.xml + var config_files = (glob.sync(path.join(project_dir, '**', '{PhoneGap,Cordova}.plist')).length == 0 ? + glob.sync(path.join(project_dir, '**', 'config.xml')) : + glob.sync(path.join(project_dir, '**', '{PhoneGap,Cordova}.plist')) + ); + + config_files = config_files.filter(function (val) { + return !(/^build\//.test(val)) && !(/\/www\/config.xml$/.test(val)); + }); + + if (config_files.length === 0) { + throw new Error("could not find PhoneGap/Cordova plist file, or config.xml file."); + } + + var config_file = config_files[0]; + var config_filename = path.basename(config_file); + var xcode_dir = path.dirname(config_file); + var pluginsDir = path.resolve(xcode_dir, 'Plugins'); + var resourcesDir = path.resolve(xcode_dir, 'Resources'); + + cachedProjectFiles[project_dir] = { + plugins_dir:pluginsDir, + resources_dir:resourcesDir, + xcode:xcodeproj, + xcode_path:xcode_dir, + pbx: pbxPath, + write: function () { + fs.writeFileSync(pbxPath, xcodeproj.writeSync()); + } + }; + + return cachedProjectFiles[project_dir]; + }, + purgeProjectFileCache:function(project_dir) { + delete cachedProjectFiles[project_dir]; + } + +}; + +function getRelativeDir(file) { + var targetDir = file.attrib['target-dir']; + if (targetDir) { + return targetDir; + } else { + return ''; + } +} From 513f7019f801e1195505927780247646e0c1036a Mon Sep 17 00:00:00 2001 From: Tobias Bocanegra Date: Thu, 24 Apr 2014 21:43:04 -0700 Subject: [PATCH 2/2] CB-6506 RTC: Add support for OSX fixes: - change string refrences from "ios" to "osx" - drop wrong line in license header --- src/platforms/osx.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/platforms/osx.js b/src/platforms/osx.js index c19e3cbf..f4b7a028 100644 --- a/src/platforms/osx.js +++ b/src/platforms/osx.js @@ -1,7 +1,5 @@ /* - * - * Copyright 2013 Anis Kadri - * + * Licensed under the Apache License, Version 2.0 (the "License"); * Licensed 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 @@ -42,7 +40,7 @@ module.exports = { var is_framework = source_el.attrib['framework'] && (source_el.attrib['framework'] == 'true' || source_el.attrib['framework'] == true); var has_flags = source_el.attrib['compiler-flags'] && source_el.attrib['compiler-flags'].length ? true : false ; - if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" osx '); if (fs.existsSync(destFile)) throw new Error('target destination "' + destFile + '" already exists'); var project_ref = path.join('Plugins', path.relative(project.plugins_dir, destFile)); @@ -84,7 +82,7 @@ module.exports = { var srcFile = path.resolve(plugin_dir, src); var targetDir = path.resolve(project.plugins_dir, plugin_id, getRelativeDir(header_el)); var destFile = path.resolve(targetDir, path.basename(src)); - if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" osx '); if (fs.existsSync(destFile)) throw new Error('target destination "' + destFile + '" already exists'); project.xcode.addHeaderFile(path.join('Plugins', path.relative(project.plugins_dir, destFile))); shell.mkdir('-p', targetDir); @@ -106,7 +104,7 @@ module.exports = { var src = resource_el.attrib['src'], srcFile = path.resolve(plugin_dir, src), destFile = path.resolve(project.resources_dir, path.basename(src)); - if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" osx '); if (fs.existsSync(destFile)) throw new Error('target destination "' + destFile + '" already exists'); project.xcode.addResourceFile(path.join('Resources', path.basename(src))); shell.cp('-R', srcFile, project.resources_dir); @@ -125,7 +123,7 @@ module.exports = { srcFile = path.resolve(plugin_dir, src), targetDir = path.resolve(project.plugins_dir, plugin_id, path.basename(src)); if (!custom) throw new Error('cannot add non custom frameworks.'); - if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" ios '); + if (!fs.existsSync(srcFile)) throw new Error('cannot find "' + srcFile + '" osx '); if (fs.existsSync(targetDir)) throw new Error('target destination "' + targetDir + '" already exists'); shell.mkdir('-p', path.dirname(targetDir)); shell.cp('-R', srcFile, path.dirname(targetDir)); // frameworks are directories @@ -141,15 +139,15 @@ module.exports = { }, "lib-file": { install:function(source_el, plugin_dir, project_dir, plugin_id) { - require('../../plugman').emit('verbose', 'lib-file.install is not supported for ios'); + require('../../plugman').emit('verbose', 'lib-file.install is not supported for osx'); }, uninstall:function(source_el, project_dir, plugin_id) { - require('../../plugman').emit('verbose', 'lib-file.uninstall is not supported for ios'); + require('../../plugman').emit('verbose', 'lib-file.uninstall is not supported for osx'); } }, parseProjectFile:function(project_dir) { // TODO: With ConfigKeeper introduced in config-changes.js - // there is now double caching of iOS project files. + // there is now double caching of osx project files. // Remove the cache here when install can handle // a list of plugins at once. if (cachedProjectFiles[project_dir]) {