Fetch templates to a temporary directory

This reduces pollution of user's home directory and definitely makes
the previously performed makeshift cache-busting obsolete since we fetch
into a fresh temp directory every time.

Addresses §6 of https://github.com/apache/cordova-discuss/issues/89

Co-authored-by: Christopher J. Brody <chris.brody@gmail.com>
diff --git a/index.js b/index.js
index 7dff53c..9fb0339 100644
--- a/index.js
+++ b/index.js
@@ -19,10 +19,10 @@
 
 const fs = require('fs-extra');
 
-var os = require('os');
 var path = require('path');
 
 var Q = require('q');
+var tmp = require('tmp');
 var isUrl = require('is-url');
 var isObject = require('isobject');
 var pathIsInside = require('path-is-inside');
@@ -37,9 +37,6 @@
 
 const DEFAULT_VERSION = '1.0.0';
 
-// Global configuration paths
-var global_config_path = process.env.CORDOVA_HOME || path.join(os.homedir(), '.cordova');
-
 /**
  * Sets up to forward events to another instance, or log console.
  * This will make the create internal events visible outside
@@ -140,16 +137,9 @@
             var isNPM = opts.template && (opts.url.indexOf('@') > -1 || !fs.existsSync(path.resolve(opts.url))) && !isGit;
             // Always use cordova fetch to obtain the npm or git template
             if (isGit || isNPM) {
-                // Saved to .Cordova folder (ToDo: Delete installed template after using)
-                var tempDest = global_config_path;
                 var target = opts.url;
-                // add latest to npm module if no version is specified
-                // this prevents create using an older cached version of the template
-                if (isNPM && target.indexOf('@') === -1) {
-                    target = opts.url + '@latest';
-                }
                 events.emit('verbose', 'Using cordova-fetch for ' + target);
-                return fetch(target, tempDest, {})
+                return fetch(target, getSelfDestructingTempDir(), {})
                     .catch(function (err) {
                         events.emit('error', '\x1B[1m \x1B[31m Error from Cordova Fetch: ' + err.message);
                         events.emit('error', 'The template you are trying to use is invalid.' +
@@ -365,3 +355,11 @@
 function stockAssetPath (p) {
     return path.join(require('cordova-app-hello-world').dirname, p);
 }
+
+// Creates temp dir that is deleted on process exit
+function getSelfDestructingTempDir () {
+    return tmp.dirSync({
+        prefix: 'cordova-create-',
+        unsafeCleanup: true
+    }).name;
+}
diff --git a/package.json b/package.json
index 56b248e..c69988c 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
     "isobject": "^3.0.1",
     "path-is-inside": "^1.0.2",
     "q": "^1.5.1",
+    "tmp": "0.0.33",
     "valid-identifier": "0.0.1"
   },
   "devDependencies": {
diff --git a/spec/create.spec.js b/spec/create.spec.js
index c4fc241..4b2d109 100644
--- a/spec/create.spec.js
+++ b/spec/create.spec.js
@@ -153,7 +153,7 @@
             .then(checkProjectCreatedWithDefaultTemplate);
     });
 
-    it('should successfully run with NPM package', function () {
+    it('should successfully run with NPM package (specific version)', function () {
         // Create a real project with npm module as template
         var config = {
             lib: {
@@ -171,9 +171,8 @@
             .then(checkProjectCreatedWithDefaultTemplate);
     });
 
-    it('should successfully run with NPM package and explicitly fetch latest if no version is given', function () {
+    it('should successfully run with NPM package (no specific version)', function () {
         // Create a real project with npm module as template
-        // TODO fetch should be responsible for the cache busting part of this test
         var config = {
             lib: {
                 www: {
@@ -185,7 +184,7 @@
         return createWithMockFetch(project, appId, appName, config, events)
             .then(fetchSpy => {
                 expect(fetchSpy).toHaveBeenCalledTimes(1);
-                expect(fetchSpy.calls.argsFor(0)[0]).toBe(config.lib.www.url + '@latest');
+                expect(fetchSpy.calls.argsFor(0)[0]).toBe(config.lib.www.url);
             })
             .then(checkProjectCreatedWithDefaultTemplate);
     });