diff --git a/index.js b/index.js index a9f326fb..5b761336 100644 --- a/index.js +++ b/index.js @@ -23,6 +23,7 @@ var path = require('path'); var tmp = require('tmp'); const npa = require('npm-package-arg'); +const globby = require('globby'); var isObject = require('isobject'); var pathIsInside = require('path-is-inside'); var requireFresh = require('import-fresh'); @@ -127,6 +128,15 @@ function cordovaCreate (dest, opts = {}) { throw e; } + // It is impossible to deploy .gitignore files via npm packages. + // Instead, Cordova templates should include gitignore files that we + // rename to .gitignore here. For more details see + // https://github.com/apache/cordova-discuss/issues/69 + globby.sync(['**/gitignore'], { cwd: dir, absolute: true }) + .forEach(f => + fs.moveSync(f, path.join(path.dirname(f), '.gitignore')) + ); + // Write out id, name and version to config.xml const configPath = path.join(dir, 'config.xml'); const conf = new ConfigParser(configPath); diff --git a/package-lock.json b/package-lock.json index 1018595b..c1d25239 100644 --- a/package-lock.json +++ b/package-lock.json @@ -125,6 +125,54 @@ "eslint-plugin-standard": "^4.0.1" } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==" + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + }, + "@types/node": { + "version": "12.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.7.tgz", + "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==" + }, "acorn": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", @@ -218,6 +266,11 @@ "es-abstract": "^1.7.0" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", @@ -315,6 +368,14 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -507,9 +568,8 @@ } }, "cordova-app-hello-world": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cordova-app-hello-world/-/cordova-app-hello-world-4.0.0.tgz", - "integrity": "sha512-hTNYHUJT5YyMa1cQQE1naGyU6Eh5D5Jl33sMnCh3+q15ZwWTL/TOy3k8+mUvjTp8bwhO5eECGKULYoVO+fp9ZA==" + "version": "github:apache/cordova-app-hello-world#4046a690e49f122bec22d56c0b59f518a35f45fb", + "from": "github:apache/cordova-app-hello-world#4046a690e49f" }, "cordova-common": { "version": "3.2.1", @@ -641,6 +701,21 @@ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1045,6 +1120,18 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", + "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + } + }, "fast-json-parse": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", @@ -1062,6 +1149,14 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "requires": { + "reusify": "^1.0.0" + } + }, "figures": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", @@ -1080,6 +1175,14 @@ "flat-cache": "^2.0.1" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", @@ -1261,7 +1364,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -1272,6 +1374,28 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==" + } + } + }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", @@ -1431,8 +1555,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -1444,11 +1567,15 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -1742,6 +1869,20 @@ } } }, + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -2114,6 +2255,11 @@ } } }, + "picomatch": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", + "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==" + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -2291,6 +2437,11 @@ "through": "~2.3.4" } }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, "rewire": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/rewire/-/rewire-4.0.1.tgz", @@ -2676,6 +2827,11 @@ "is-promise": "^2.1.0" } }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" + }, "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", @@ -2747,6 +2903,11 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -3117,6 +3278,14 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", diff --git a/package.json b/package.json index 0f82f0d1..bbb17a4a 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,11 @@ "node": ">=10" }, "dependencies": { - "cordova-app-hello-world": "^4.0.0", + "cordova-app-hello-world": "github:apache/cordova-app-hello-world#4046a690e49f", "cordova-common": "^3.1.0", "cordova-fetch": "^2.0.0", "fs-extra": "^8.1.0", + "globby": "^10.0.1", "import-fresh": "^3.1.0", "isobject": "^4.0.0", "npm-package-arg": "^6.1.1", diff --git a/spec/create.spec.js b/spec/create.spec.js index 2bc77b3e..38929728 100644 --- a/spec/create.spec.js +++ b/spec/create.spec.js @@ -181,6 +181,33 @@ describe('create end-to-end', function () { return create(project, opts) .then(checkProjectCreatedWithDefaultTemplate); }); + + it('should rename all gitignore files in template to .gitignore', () => { + const baseTemplatePkg = path.join(__dirname, 'templates/withsubdirectory'); + const templatePkg = path.join(tmpDir, 'gitignore-template'); + fs.copySync(baseTemplatePkg, templatePkg); + + // Setup a few gitignore files that should be renamed (or not) + const templateDir = path.join(templatePkg, 'template'); + fs.ensureFileSync(path.join(templateDir, 'gitignore')); + fs.ensureFileSync(path.join(templateDir, 'www/gitignore')); + fs.ensureDirSync(path.join(templateDir, 'foo/gitignore')); + + opts.template = templatePkg; + return create(project, opts).then(() => { + // Renames gitignore at template root + expect(path.join(project, 'gitignore')).not.toExist(); + expect(path.join(project, '.gitignore')).toExist(); + + // Renames gitignores in sub-directories + expect(path.join(project, 'www/gitignore')).not.toExist(); + expect(path.join(project, 'www/.gitignore')).toExist(); + + // Does not rename directories with name gitignore + expect(path.join(project, 'foo/gitignore')).toExist(); + expect(path.join(project, 'foo/.gitignore')).not.toExist(); + }); + }); }); describe('when shit happens', function () {