You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2016/05/09 21:18:37 UTC
[2/2] cordova-lib git commit: CB-9858 merging initial fetch work for
plugin and platform fetching
CB-9858 merging initial fetch work for plugin and platform fetching
Project: http://git-wip-us.apache.org/repos/asf/cordova-lib/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-lib/commit/6025a5f2
Tree: http://git-wip-us.apache.org/repos/asf/cordova-lib/tree/6025a5f2
Diff: http://git-wip-us.apache.org/repos/asf/cordova-lib/diff/6025a5f2
Branch: refs/heads/master
Commit: 6025a5f23c00284fb3416d8042ff5d738bf03db3
Parents: b21bcc3
Author: Steve Gill <st...@gmail.com>
Authored: Mon May 9 14:18:21 2016 -0700
Committer: Steve Gill <st...@gmail.com>
Committed: Mon May 9 14:18:21 2016 -0700
----------------------------------------------------------------------
.gitignore | 1 +
.travis.yml | 2 +
appveyor.yml | 2 +
cordova-fetch/.jshintrc | 12 +
cordova-fetch/README.md | 36 +
cordova-fetch/RELEASENOTES.md | 22 +
cordova-fetch/index.js | 236 ++++
cordova-fetch/package.json | 43 +
cordova-fetch/spec/fetch.spec.js | 300 +++++
cordova-fetch/spec/helpers.js | 16 +
cordova-fetch/spec/support/jasmine.json | 11 +
cordova-fetch/spec/testpkg.json | 11 +
cordova-lib/spec-cordova/helpers.js | 3 +
cordova-lib/spec-cordova/platform.spec.js | 108 ++
cordova-lib/src/cordova/platform.js | 31 +-
cordova-lib/src/cordova/plugin.js | 1608 ++++++++++++------------
cordova-lib/src/plugman/fetch.js | 35 +-
cordova-lib/src/plugman/plugman.js | 13 +-
cordova-lib/src/plugman/uninstall.js | 29 +-
19 files changed, 1700 insertions(+), 819 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index ea05522..dae2aca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ src/plugman/defaults.json
cordova-lib/src/plugman/defaults.json
cordova-lib/spec-plugman/plugins/recursivePlug/demo/fetch.json
cordova-lib/spec-plugman/plugins/recursivePlug/demo/test-recursive
+cordova-fetch/test/temp
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index bb404a1..e9f15ee 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,8 +12,10 @@ install:
- npm link ../cordova-js
- npm link ../cordova-common
- npm link ../cordova-serve
+ - npm link ../cordova-fetch
- npm install
script:
- "(cd ../cordova-common && npm test)"
+ - "(cd ../cordova-common && npm test)"
- "npm run ci"
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/appveyor.yml
----------------------------------------------------------------------
diff --git a/appveyor.yml b/appveyor.yml
index 36e2b26..dc26ed4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -7,6 +7,7 @@ install:
- npm link ../cordova-js
- npm link ../cordova-common
- npm link ../cordova-serve
+ - npm link ../cordova-fetch
- npm install
build: off
@@ -15,4 +16,5 @@ test_script:
- node --version
- npm --version
- "cd ../cordova-common && npm test"
+ - "cd ../cordova-fetch && npm test"
- "cd ../cordova-lib && npm test"
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/.jshintrc
----------------------------------------------------------------------
diff --git a/cordova-fetch/.jshintrc b/cordova-fetch/.jshintrc
new file mode 100644
index 0000000..62edb5c
--- /dev/null
+++ b/cordova-fetch/.jshintrc
@@ -0,0 +1,12 @@
+{
+ "node": true,
+ "bitwise": true,
+ "undef": true,
+ "trailing": true,
+ "quotmark": true,
+ "indent": 4,
+ "unused": "vars",
+ "latedef": "nofunc",
+ "-W030": false,
+ "jasmine": true
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/README.md
----------------------------------------------------------------------
diff --git a/cordova-fetch/README.md b/cordova-fetch/README.md
new file mode 100644
index 0000000..5cc75e9
--- /dev/null
+++ b/cordova-fetch/README.md
@@ -0,0 +1,36 @@
+<!--
+#
+# 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.
+#
+-->
+
+# cordova-fetch
+
+This module is used for fetching modules from npm and gitURLs. It fetches the modules via `npm install`.
+
+Usage:
+```
+var fetch = require('cordova-fetch');
+
+fetch(spec, dest, opts);
+```
+
+`spec` can be a string containg a npm `packageID` or a `git URL`.
+`dest` is string of the directory location you wish to `npm install` these modules.
+`opts` is an Object of options cordova fetch handles. Currently, fetch only support the `save` option.
+ eg. `{'save':true}`
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/RELEASENOTES.md
----------------------------------------------------------------------
diff --git a/cordova-fetch/RELEASENOTES.md b/cordova-fetch/RELEASENOTES.md
new file mode 100644
index 0000000..305cdc6
--- /dev/null
+++ b/cordova-fetch/RELEASENOTES.md
@@ -0,0 +1,22 @@
+<!--
+#
+# 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.
+#
+-->
+# Cordova-fetch Release Notes
+
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/index.js
----------------------------------------------------------------------
diff --git a/cordova-fetch/index.js b/cordova-fetch/index.js
new file mode 100644
index 0000000..0e3c3fe
--- /dev/null
+++ b/cordova-fetch/index.js
@@ -0,0 +1,236 @@
+/**
+ 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 Q = require('q');
+var shell = require('shelljs');
+var superspawn = require('cordova-common').superspawn;
+var events = require('cordova-common').events;
+var depls = require('dependency-ls');
+var path = require('path');
+var fs = require('fs');
+var CordovaError = require('cordova-common').CordovaError;
+var isUrl = require('is-url');
+
+/*
+ * A function that npm installs a module from npm or a git url
+ *
+ * @param {String} target the packageID or git url
+ * @param {String} dest destination of where to install the module
+ * @param {Object} opts [opts={save:true}] options to pass to fetch module
+ *
+ * @return {String|Promise} Returns string of the absolute path to the installed module.
+ *
+ */
+module.exports = function(target, dest, opts) {
+ var fetchArgs = ['install'];
+ opts = opts || {};
+ var tree1;
+
+ //check if npm is installed
+ return isNpmInstalled()
+ .then(function() {
+ if(dest && target) {
+ //add target to fetchArgs Array
+ fetchArgs.push(target);
+
+ //append node_modules to dest if it doesn't come included
+ if (path.basename(dest) !== 'node_modules') {
+ dest = path.resolve(path.join(dest, 'node_modules'));
+ }
+
+ //create dest if it doesn't exist
+ if(!fs.existsSync(dest)) {
+ shell.mkdir('-p', dest);
+ }
+
+ } else return Q.reject(new CordovaError('Need to supply a target and destination'));
+
+ //set the directory where npm install will be run
+ opts.cwd = dest;
+
+ //if user added --save flag, pass it to npm install command
+ if(opts.save) {
+ events.emit('verbose', 'saving');
+ fetchArgs.push('--save');
+ }
+
+
+ //Grab json object of installed modules before npm install
+ return depls(dest);
+ })
+ .then(function(depTree) {
+ tree1 = depTree;
+
+ //install new module
+ return superspawn.spawn('npm', fetchArgs, opts);
+ })
+ .then(function(output) {
+ //Grab object of installed modules after npm install
+ return depls(dest);
+ })
+ .then(function(depTree2) {
+ var tree2 = depTree2;
+
+ //getJsonDiff will fail if the module already exists in node_modules.
+ //Need to use trimID in that case.
+ //This could happen on a platform update.
+ var id = getJsonDiff(tree1, tree2) || trimID(target);
+
+ return getPath(id, dest);
+ })
+ .fail(function(err){
+ return Q.reject(new CordovaError(err));
+ });
+};
+
+
+/*
+ * Takes two JSON objects and returns the key of the new property as a string.
+ * If a module already exists in node_modules, the diff will be blank.
+ * cordova-fetch will use trimID in that case.
+ *
+ * @param {Object} obj1 json object representing installed modules before latest npm install
+ * @param {Object} obj2 json object representing installed modules after latest npm install
+ *
+ * @return {String} String containing the key value of the difference between the two objects
+ *
+ */
+function getJsonDiff(obj1, obj2) {
+ var result = '';
+
+ //regex to filter out peer dependency warnings from result
+ var re = /UNMET PEER DEPENDENCY/;
+
+ for (var key in obj2) {
+ //if it isn't a unmet peer dependency, continue
+ if (key.search(re) === -1) {
+ if(obj2[key] != obj1[key]) result = key;
+ }
+ }
+ return result;
+}
+
+/*
+ * Takes the specified target and returns the moduleID
+ * If the git repoName is different than moduleID, then the
+ * output from this function will be incorrect. This is the
+ * backup way to get ID. getJsonDiff is the preferred way to
+ * get the moduleID of the installed module.
+ *
+ * @param {String} target target that was passed into cordova-fetch.
+ * can be moduleID, moduleID@version or gitURL
+ *
+ * @return {String} ID moduleID without version.
+ */
+function trimID(target) {
+ var parts;
+
+ //If GITURL, set target to repo name
+ if (isUrl(target)) {
+ var re = /.*\/(.*).git/;
+ parts = target.match(re);
+ target = parts[1];
+ }
+
+ //strip away everything after '@'
+ if(target.indexOf('@') != -1) {
+ parts = target.split('@');
+ target = parts[0];
+ }
+
+ return target;
+}
+
+/*
+ * Takes the moduleID and destination and returns an absolute path to the module
+ *
+ * @param {String} id the packageID
+ * @param {String} dest destination of where to fetch the modules
+ *
+ * @return {String|Error} Returns the absolute url for the module or throws a error
+ *
+ */
+
+function getPath(id, dest) {
+ var finalDest = path.resolve(path.join(dest, id));
+
+ //Sanity check it exists
+ if(fs.existsSync(finalDest)){
+ return finalDest;
+ } else return Q.reject(new CordovaError('Failed to get absolute path to installed module'));
+}
+
+
+/*
+ * Checks to see if npm is installed on the users system
+ * @return {Promise|Error} Returns true or a cordova error.
+ */
+
+function isNpmInstalled() {
+ if(!shell.which('npm')) {
+ return Q.reject(new CordovaError('"npm" command line tool is not installed: make sure it is accessible on your PATH.'));
+ }
+ return Q();
+}
+
+/*
+ * A function that deletes the target from node_modules and runs npm uninstall
+ *
+ * @param {String} target the packageID
+ * @param {String} dest destination of where to uninstall the module from
+ * @param {Object} opts [opts={save:true}] options to pass to npm uninstall
+ *
+ * @return {Promise|Error} Returns a promise with the npm uninstall output or an error.
+ *
+ */
+module.exports.uninstall = function(target, dest, opts) {
+ var fetchArgs = ['uninstall'];
+ opts = opts || {};
+
+ //check if npm is installed on the system
+ return isNpmInstalled()
+ .then(function() {
+ if(dest && target) {
+ //add target to fetchArgs Array
+ fetchArgs.push(target);
+ } else return Q.reject(new CordovaError('Need to supply a target and destination'));
+
+ //set the directory where npm uninstall will be run
+ opts.cwd = dest;
+
+ //if user added --save flag, pass it to npm uninstall command
+ if(opts.save) {
+ fetchArgs.push('--save');
+ }
+
+ //run npm uninstall, this will remove dependency
+ //from package.json if --save was used.
+ return superspawn.spawn('npm', fetchArgs, opts);
+ })
+ .then(function(res) {
+ var pluginDest = path.join(dest, 'node_modules', target);
+ if(fs.existsSync(pluginDest)) {
+ shell.rm('-rf', pluginDest);
+ }
+ return res;
+ })
+ .fail(function(err) {
+ return Q.reject(new CordovaError(err));
+ });
+};
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/package.json
----------------------------------------------------------------------
diff --git a/cordova-fetch/package.json b/cordova-fetch/package.json
new file mode 100644
index 0000000..2e7e330
--- /dev/null
+++ b/cordova-fetch/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "cordova-fetch",
+ "version": "1.0.0-dev",
+ "description": "Apache Cordova fetch module. Fetches from git and npm.",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git://git-wip-us.apache.org/repos/asf/cordova-lib.git"
+ },
+ "keywords": [
+ "cordova",
+ "fetch",
+ "apache",
+ "ecosystem:cordova",
+ "cordova:tool"
+ ],
+ "author": "Apache Software Foundation",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://issues.apache.org/jira/browse/CB",
+ "email": "dev@cordova.apache.org"
+ },
+ "dependencies": {
+ "cordova-common": "^1.0.0",
+ "dependency-ls": "^1.0.0",
+ "is-url": "^1.2.1",
+ "q": "^1.4.1",
+ "shelljs": "^0.7.0"
+ },
+ "devDependencies": {
+ "jasmine": "^2.4.1",
+ "jshint": "^2.8.0"
+ },
+ "scripts": {
+ "test": "npm run jshint && npm run jasmine",
+ "jshint": "jshint index.js spec/fetch.spec.js",
+ "jasmine": "jasmine spec/fetch.spec.js"
+ },
+ "engines": {
+ "node": ">= 0.12.0",
+ "npm": ">= 2.5.1"
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/spec/fetch.spec.js
----------------------------------------------------------------------
diff --git a/cordova-fetch/spec/fetch.spec.js b/cordova-fetch/spec/fetch.spec.js
new file mode 100644
index 0000000..2f6513a
--- /dev/null
+++ b/cordova-fetch/spec/fetch.spec.js
@@ -0,0 +1,300 @@
+/**
+ 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 fetch = require('../index.js');
+var uninstall = require('../index.js').uninstall;
+var shell = require('shelljs');
+var path = require('path');
+var fs = require('fs');
+var helpers = require('./helpers.js');
+
+describe('platform fetch/uninstall tests via npm & git', function () {
+
+ var tmpDir = helpers.tmpDir('plat_fetch');
+ var opts = {};
+
+ beforeEach(function() {
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should fetch and uninstall a cordova platform via npm & git', function(done) {
+
+ fetch('cordova-android', tmpDir, opts)
+ .then(function(result) {
+ var pkgJSON = require(path.join(result,'package.json'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-android');
+
+ return uninstall('cordova-android', tmpDir, opts);
+ })
+ .then(function() {
+ expect(fs.existsSync(path.join(tmpDir,'node_modules', 'cordova-android'))).toBe(false);
+
+ return fetch('https://github.com/apache/cordova-ios.git', tmpDir, opts);
+ })
+ .then(function(result) {
+ var pkgJSON = require(path.join(result,'package.json'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-ios');
+
+ return uninstall('cordova-ios', tmpDir, opts);
+ })
+ .then(function() {
+ expect(fs.existsSync(path.join(tmpDir,'node_modules', 'cordova-ios'))).toBe(false);
+ })
+ .fail(function(err) {
+ console.error(err);
+ expect(err).toBeUndefined();
+ })
+ .fin(done);
+ }, 60000);
+});
+
+describe('platform fetch/uninstall test via npm & git tags with --save', function () {
+
+ var tmpDir = helpers.tmpDir('plat_fetch_save');
+ var opts = {'save':true};
+
+ beforeEach(function() {
+ //copy package.json from spec directory to tmpDir
+ shell.cp('spec/testpkg.json', path.join(tmpDir,'package.json'));
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should fetch and uninstall a cordova platform via npm & git tags/branches', function(done) {
+ fetch('cordova-android@5.1.1', tmpDir, opts)
+ .then(function(result) {
+ var pkgJSON = require(path.join(result,'package.json'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-android');
+ expect(pkgJSON.version).toBe('5.1.1');
+
+ var rootPJ = require(path.join(tmpDir,'package.json'));
+ expect(rootPJ.dependencies['cordova-android']).toBe('^5.1.1');
+
+ return uninstall('cordova-android', tmpDir, opts);
+ })
+ .then(function() {
+ var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir,'package.json'), 'utf8'));
+ expect(Object.keys(rootPJ.dependencies).length).toBe(0);
+ expect(fs.existsSync(path.join(tmpDir,'node_modules', 'cordova-android'))).toBe(false);
+
+ return fetch('https://github.com/apache/cordova-ios.git#rel/4.1.1', tmpDir, opts);
+ })
+ .then(function(result) {
+ var pkgJSON = require(path.join(result,'package.json'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-ios');
+ expect(pkgJSON.version).toBe('4.1.1');
+
+ var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir,'package.json'), 'utf8'));
+ expect(rootPJ.dependencies['cordova-ios']).toBe('git+https://github.com/apache/cordova-ios.git#rel/4.1.1');
+
+ return uninstall('cordova-ios', tmpDir, opts);
+ })
+ .then(function() {
+ var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir,'package.json'), 'utf8'));
+ expect(Object.keys(rootPJ.dependencies).length).toBe(0);
+ expect(fs.existsSync(path.join(tmpDir,'node_modules', 'cordova-ios'))).toBe(false);
+
+ return fetch('https://github.com/apache/cordova-android.git#4.1.x', tmpDir, opts);
+ })
+ .then(function(result) {
+ var pkgJSON = JSON.parse(fs.readFileSync(path.join(result,'package.json'), 'utf8'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-android');
+ expect(pkgJSON.version).toBe('4.1.1');
+
+ var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir,'package.json'), 'utf8'));
+ expect(rootPJ.dependencies['cordova-android']).toBe('git+https://github.com/apache/cordova-android.git#4.1.x');
+
+ return uninstall('cordova-android', tmpDir, opts);
+ })
+ .fail(function(err) {
+ console.error(err);
+ expect(err).toBeUndefined();
+ })
+ .fin(done);
+ }, 60000);
+});
+
+describe('plugin fetch/uninstall test with --save', function () {
+
+ var tmpDir = helpers.tmpDir('plug_fetch_save');
+ var opts = {'save':true};
+
+ beforeEach(function() {
+ //copy package.json from spec directory to tmpDir
+ shell.cp('spec/testpkg.json', path.join(tmpDir,'package.json'));
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should fetch and uninstall a cordova plugin via git commit sha', function(done) {
+ fetch('https://github.com/apache/cordova-plugin-contacts.git#7db612115755c2be73a98dda76ff4c5fd9d8a575', tmpDir, opts)
+ .then(function(result) {
+ var pkgJSON = require(path.join(result,'package.json'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-plugin-contacts');
+ expect(pkgJSON.version).toBe('2.0.2-dev');
+
+ var rootPJ = require(path.join(tmpDir,'package.json'));
+ expect(rootPJ.dependencies['cordova-plugin-contacts']).toBe('git+https://github.com/apache/cordova-plugin-contacts.git#7db612115755c2be73a98dda76ff4c5fd9d8a575');
+
+ return uninstall('cordova-plugin-contacts', tmpDir, opts);
+ })
+ .then(function() {
+ var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir,'package.json'), 'utf8'));
+ expect(Object.keys(rootPJ.dependencies).length).toBe(0);
+ expect(fs.existsSync(path.join(tmpDir,'node_modules', 'cordova-plugin-contacts'))).toBe(false);
+ })
+ .fail(function(err) {
+ console.error(err);
+ expect(err).toBeUndefined();
+ })
+ .fin(done);
+ }, 30000);
+});
+
+describe('test trimID method for npm and git', function () {
+
+ var tmpDir = helpers.tmpDir('plug_trimID');
+ var opts = {};
+
+ beforeEach(function() {
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should fetch the same cordova plugin twice in a row', function(done) {
+ fetch('cordova-plugin-device', tmpDir, opts)
+ .then(function(result) {
+ var pkgJSON = require(path.join(result,'package.json'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-plugin-device');
+
+ return fetch('https://github.com/apache/cordova-plugin-media.git', tmpDir, opts);
+ })
+ .then(function(result) {
+ var pkgJSON = require(path.join(result,'package.json'));
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ expect(pkgJSON.name).toBe('cordova-plugin-media');
+
+ //refetch to trigger trimID
+ return fetch('cordova-plugin-device', tmpDir, opts);
+
+ })
+ .then(function(result) {
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+
+ //refetch to trigger trimID
+ return fetch('https://github.com/apache/cordova-plugin-media.git', tmpDir, opts);
+ })
+ .then(function(result) {
+ expect(result).toBeDefined();
+ expect(fs.existsSync(result)).toBe(true);
+ })
+ .fail(function(err) {
+ console.error(err);
+ expect(err).toBeUndefined();
+ })
+ .fin(done);
+ }, 30000);
+});
+
+describe('fetch failure with unknown module', function () {
+
+ var tmpDir = helpers.tmpDir('fetch_fails_npm');
+ var opts = {};
+
+ beforeEach(function() {
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should fail fetching a module that does not exist on npm', function(done) {
+ fetch('NOTAMODULE', tmpDir, opts)
+ .then(function(result) {
+ console.log('This should fail and it should not be seen');
+ })
+ .fail(function(err) {
+ expect(err.message.code).toBe(1);
+ expect(err).toBeDefined();
+ })
+ .fin(done);
+ }, 30000);
+});
+
+describe('fetch failure with git subdirectory', function () {
+
+ var tmpDir = helpers.tmpDir('fetch_fails_subdirectory');
+ var opts = {};
+
+ beforeEach(function() {
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should fail fetching a giturl which contains a subdirectory', function(done) {
+ fetch('https://github.com/apache/cordova-plugins.git#:keyboard', tmpDir, opts)
+ .then(function(result) {
+ console.log('This should fail and it should not be seen');
+ })
+ .fail(function(err) {
+ expect(err.message.code).toBe(1);
+ expect(err).toBeDefined();
+ })
+ .fin(done);
+ }, 30000);
+});
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/spec/helpers.js
----------------------------------------------------------------------
diff --git a/cordova-fetch/spec/helpers.js b/cordova-fetch/spec/helpers.js
new file mode 100644
index 0000000..ee3f57b
--- /dev/null
+++ b/cordova-fetch/spec/helpers.js
@@ -0,0 +1,16 @@
+var path = require('path'),
+ fs = require('fs'),
+ shell = require('shelljs'),
+ os = require('os');
+
+module.exports.tmpDir = function (subdir) {
+ var dir = path.join(os.tmpdir(), 'e2e-test');
+ if (subdir) {
+ dir = path.join(dir, subdir);
+ }
+ if(fs.existsSync(dir)) {
+ shell.rm('-rf', dir);
+ }
+ shell.mkdir('-p', dir);
+ return dir;
+};
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/spec/support/jasmine.json
----------------------------------------------------------------------
diff --git a/cordova-fetch/spec/support/jasmine.json b/cordova-fetch/spec/support/jasmine.json
new file mode 100644
index 0000000..3ea3166
--- /dev/null
+++ b/cordova-fetch/spec/support/jasmine.json
@@ -0,0 +1,11 @@
+{
+ "spec_dir": "spec",
+ "spec_files": [
+ "**/*[sS]pec.js"
+ ],
+ "helpers": [
+ "helpers/**/*.js"
+ ],
+ "stopSpecOnExpectationFailure": false,
+ "random": false
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-fetch/spec/testpkg.json
----------------------------------------------------------------------
diff --git a/cordova-fetch/spec/testpkg.json b/cordova-fetch/spec/testpkg.json
new file mode 100644
index 0000000..94e7f64
--- /dev/null
+++ b/cordova-fetch/spec/testpkg.json
@@ -0,0 +1,11 @@
+{
+ "name": "test",
+ "version": "1.0.0",
+ "description": "",
+ "main": "fetch.spec.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC"
+}
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-lib/spec-cordova/helpers.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/helpers.js b/cordova-lib/spec-cordova/helpers.js
index a5d23fd..4cc1e2c 100644
--- a/cordova-lib/spec-cordova/helpers.js
+++ b/cordova-lib/spec-cordova/helpers.js
@@ -40,6 +40,9 @@ module.exports.tmpDir = function (subdir) {
if (subdir) {
dir = path.join(dir, subdir);
}
+ if(fs.existsSync(dir)) {
+ shell.rm('-rf', dir);
+ }
shell.mkdir('-p', dir);
return dir;
};
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-lib/spec-cordova/platform.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/platform.spec.js b/cordova-lib/spec-cordova/platform.spec.js
index a35216f..a0bd104 100644
--- a/cordova-lib/spec-cordova/platform.spec.js
+++ b/cordova-lib/spec-cordova/platform.spec.js
@@ -248,3 +248,111 @@ describe('platform add plugin rm end-to-end', function () {
.fin(done);
}, 20000);
});
+
+describe('platform add and remove --fetch', function () {
+
+ var tmpDir = helpers.tmpDir('plat_add_remove_fetch_test');
+ var project = path.join(tmpDir, 'helloFetch');
+ var platformsDir = path.join(project, 'platforms');
+ var nodeModulesDir = path.join(project, 'node_modules');
+
+ beforeEach(function() {
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should add and remove platform from node_modules directory', function(done) {
+
+ cordova.raw.create('helloFetch')
+ .then(function() {
+ process.chdir(project);
+ return cordova.raw.platform('add', 'ios', {'fetch':true});
+ })
+ .then(function() {
+ expect(path.join(nodeModulesDir, 'cordova-ios')).toExist();
+ expect(path.join(platformsDir, 'ios')).toExist();
+ return cordova.raw.platform('add', 'android', {'fetch':true});
+ })
+ .then(function() {
+ expect(path.join(nodeModulesDir, 'cordova-android')).toExist();
+ expect(path.join(platformsDir, 'android')).toExist();
+ //Tests finish before this command finishes resolving
+ //return cordova.raw.platform('rm', 'ios', {'fetch':true});
+ })
+ .then(function() {
+ //expect(path.join(nodeModulesDir, 'cordova-ios')).not.toExist();
+ //expect(path.join(platformsDir, 'ios')).not.toExist();
+ //Tests finish before this command finishes resolving
+ //return cordova.raw.platform('rm', 'android', {'fetch':true});
+ })
+ .then(function() {
+ //expect(path.join(nodeModulesDir, 'cordova-android')).not.toExist();
+ //expect(path.join(platformsDir, 'android')).not.toExist();
+ })
+ .fail(function(err) {
+ console.error(err);
+ expect(err).toBeUndefined();
+ })
+ .fin(done);
+ }, 40000);
+});
+
+describe('plugin add and rm end-to-end --fetch', function () {
+
+ var tmpDir = helpers.tmpDir('plugin_rm_fetch_test');
+ var project = path.join(tmpDir, 'hello3');
+ var pluginsDir = path.join(project, 'plugins');
+
+ beforeEach(function() {
+ process.chdir(tmpDir);
+ });
+
+ afterEach(function() {
+ process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
+ shell.rm('-rf', tmpDir);
+ });
+
+ it('should remove dependency when removing parent plugin', function(done) {
+
+ cordova.raw.create('hello3')
+ .then(function() {
+ process.chdir(project);
+ return cordova.raw.platform('add', 'ios', {'fetch': true});
+ })
+ .then(function() {
+ return cordova.raw.plugin('add', 'cordova-plugin-media', {'fetch': true});
+ })
+ .then(function() {
+ expect(path.join(pluginsDir, 'cordova-plugin-media')).toExist();
+ expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
+ expect(path.join(pluginsDir, 'cordova-plugin-compat')).toExist();
+ expect(path.join(project, 'node_modules', 'cordova-plugin-media')).toExist();
+ expect(path.join(project, 'node_modules', 'cordova-plugin-file')).toExist();
+ expect(path.join(project, 'node_modules', 'cordova-plugin-compat')).toExist();
+ return cordova.raw.platform('add', 'android', {'fetch':true});
+ })
+ .then(function() {
+ expect(path.join(pluginsDir, 'cordova-plugin-media')).toExist();
+ expect(path.join(pluginsDir, 'cordova-plugin-file')).toExist();
+ return cordova.raw.plugin('rm', 'cordova-plugin-media', {'fetch':true});
+ })
+ .then(function() {
+ expect(path.join(pluginsDir, 'cordova-plugin-media')).not.toExist();
+ expect(path.join(pluginsDir, 'cordova-plugin-file')).not.toExist();
+ expect(path.join(pluginsDir, 'cordova-plugin-compat')).not.toExist();
+ //These don't work yet due to the tests finishing before the promise resolves.
+ //expect(path.join(project, 'node_modules', 'cordova-plugin-media')).not.toExist();
+ //expect(path.join(project, 'node_modules', 'cordova-plugin-file')).not.toExist();
+ //expect(path.join(project, 'node_modules', 'cordova-plugin-compat')).not.toExist();
+ })
+ .fail(function(err) {
+ console.error(err);
+ expect(err).toBeUndefined();
+ })
+ .fin(done);
+ }, 60000);
+});
http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/6025a5f2/cordova-lib/src/cordova/platform.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/platform.js b/cordova-lib/src/cordova/platform.js
index db6f53c..cdfeb85 100644
--- a/cordova-lib/src/cordova/platform.js
+++ b/cordova-lib/src/cordova/platform.js
@@ -37,6 +37,8 @@ var config = require('./config'),
shell = require('shelljs'),
_ = require('underscore'),
PlatformJson = require('cordova-common').PlatformJson,
+ fetch = require('cordova-fetch'),
+ npmUninstall = require('cordova-fetch').uninstall,
platformMetadata = require('./platform_metadata');
// Expose the platform parsers on top of this command
@@ -257,6 +259,21 @@ function getSpecString(spec) {
function downloadPlatform(projectRoot, platform, version, opts) {
var target = version ? (platform + '@' + version) : platform;
return Q().then(function() {
+ if (opts.fetch) {
+ //append cordova to platform
+ if(platform in platforms) {
+ target = 'cordova-'+target;
+ }
+
+ //gitURLs don't supply a platform, it equals null
+ if(!platform) {
+ target = version;
+ }
+
+ events.emit('log', 'Using cordova-fetch for '+ target);
+ return fetch(target, projectRoot, opts);
+ }
+
if (cordova_util.isUrl(version)) {
events.emit('log', 'git cloning: ' + version);
var parts = version.split('#');
@@ -356,8 +373,8 @@ function remove(hooksRunner, projectRoot, targets, opts) {
events.emit('log', 'Removing ' + target + ' from config.xml file ...');
cfg.removeEngine(platformName);
cfg.write();
- });
- }
+ });
+ }
}).then(function() {
// Remove targets from platforms.json
targets.forEach(function(target) {
@@ -365,6 +382,16 @@ function remove(hooksRunner, projectRoot, targets, opts) {
platformMetadata.remove(projectRoot, target);
});
}).then(function() {
+ //Remove from node_modules if it exists and --fetch was used
+ if(opts.fetch) {
+ targets.forEach(function(target) {
+ if(target in platforms) {
+ target = 'cordova-'+target;
+ }
+ return npmUninstall(target, projectRoot, opts);
+ });
+ }
+ }).then(function() {
return hooksRunner.fire('after_platform_rm', opts);
});
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org