From 60e6ce01e5772a5976c157c44f0bf9cae0d7ee6b Mon Sep 17 00:00:00 2001 From: dennismeister93 Date: Fri, 7 Jun 2024 15:26:37 +0200 Subject: [PATCH] fix: fix detection of failed package download (#276) * fix: detection of failed package download Signed-off-by: Dennis Meister --- NOTICE-3RD-PARTY-CONTENT.md | 21 +-- package-lock.json | 232 ++++++++++++++---------------- package.json | 21 +-- src/commands/init/index.ts | 2 +- src/modules/package-downloader.ts | 52 ++++--- src/modules/package.ts | 11 +- src/utils/fs-bridge.ts | 24 ++++ test/commands/init/init.test.ts | 24 +++- test/helpers/simpleGit.ts | 4 +- 9 files changed, 219 insertions(+), 172 deletions(-) diff --git a/NOTICE-3RD-PARTY-CONTENT.md b/NOTICE-3RD-PARTY-CONTENT.md index d567c6c..bcb2227 100644 --- a/NOTICE-3RD-PARTY-CONTENT.md +++ b/NOTICE-3RD-PARTY-CONTENT.md @@ -3,14 +3,15 @@ ## JavaScript | Dependency | Version | License | |:-----------|:-------:|--------:| -|@oclif/core|3.26.2|MIT| -|@oclif/test|3.2.8|MIT| -|@types/chai|4.3.14|MIT| +|@oclif/core|3.27.0|MIT| +|@oclif/test|3.2.15|MIT| +|@types/chai|4.3.16|MIT| |@types/fs-extra|11.0.4|MIT| |@types/mocha|10.0.6|MIT| -|@types/node|20.12.7|MIT| -|@typescript-eslint/eslint-plugin|7.6.0|MIT| -|@typescript-eslint/parser|7.6.0|unknown| +|@types/node|20.14.2|MIT| +|@types/semver|7.5.8|MIT| +|@typescript-eslint/eslint-plugin|7.12.0|MIT| +|@typescript-eslint/parser|7.12.0|unknown| |@yao-pkg/pkg|5.11.5|MIT| |chai|4.4.1|MIT| |eslint|8.57.0|ISC
MIT| @@ -19,17 +20,17 @@ |mocha|10.4.0|ISC
MIT| |node-pty|1.0.0|MIT| |nyc|15.1.0|ISC
MIT| -|prettier|3.2.5|Apache 2.0| +|prettier|3.3.1|Apache 2.0| |prettier-plugin-organize-imports|3.2.4|MIT| |recursive-copy|2.0.14|ISC
MIT| -|semver|7.6.0|ISC| +|semver|7.6.2|ISC| |shx|0.3.4|MIT| |simple-git|3.24.0|unknown| |sinon|17.0.1|MIT
New BSD| |ts-node|10.9.2|MIT| -|typescript|5.4.4|Apache 2.0| +|typescript|5.4.5|Apache 2.0| |velocitas-cli|0.0.0|Apache 2.0| -|yaml|2.4.1|ISC| +|yaml|2.4.3|ISC| ## Workflows | Dependency | Version | License | |:-----------|:-------:|--------:| diff --git a/package-lock.json b/package-lock.json index c02a726..a06e1aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,37 +9,38 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { - "@oclif/core": "3.26.2", + "@oclif/core": "3.27.0", "fs-extra": "11.2.0", "inquirer": "8.2.6", "node-pty": "1.0.0", "recursive-copy": "2.0.14", - "semver": "7.6.0", + "semver": "7.6.2", "simple-git": "3.24.0" }, "bin": { "velocitas": "bin/run" }, "devDependencies": { - "@oclif/test": "3.2.8", - "@types/chai": "4.3.14", + "@oclif/test": "3.2.15", + "@types/chai": "4.3.16", "@types/fs-extra": "11.0.4", "@types/mocha": "10.0.6", - "@types/node": "20.12.7", - "@typescript-eslint/eslint-plugin": "7.6.0", - "@typescript-eslint/parser": "7.6.0", + "@types/node": "20.14.2", + "@types/semver": "^7.5.8", + "@typescript-eslint/eslint-plugin": "7.12.0", + "@typescript-eslint/parser": "7.12.0", "@yao-pkg/pkg": "5.11.5", "chai": "4.4.1", "eslint": "8.57.0", "mocha": "10.4.0", "nyc": "15.1.0", - "prettier": "3.2.5", + "prettier": "3.3.1", "prettier-plugin-organize-imports": "3.2.4", "shx": "0.3.4", "sinon": "^17.0.1", "ts-node": "10.9.2", - "typescript": "5.4.4", - "yaml": "2.4.1" + "typescript": "5.4.5", + "yaml": "2.4.3" }, "engines": { "node": ">=20.0.0" @@ -949,9 +950,9 @@ } }, "node_modules/@oclif/core": { - "version": "3.26.2", - "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.26.2.tgz", - "integrity": "sha512-Gpn21jKjcOx0TecI1wLJrY/65jtgJx5f1GzTc81oKvEpKes1b3Li2SMZygRaWRpcQ3wjN0d7lTPi8WwLsmTBjA==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.27.0.tgz", + "integrity": "sha512-Fg93aNFvXzBq5L7ztVHFP2nYwWU1oTCq48G0TjF/qC1UN36KWa2H5Hsm72kERd5x/sjy2M2Tn4kDEorUlpXOlw==", "dependencies": { "@types/cli-progress": "^3.11.5", "ansi-escapes": "^4.3.2", @@ -961,8 +962,8 @@ "clean-stack": "^3.0.1", "cli-progress": "^3.12.0", "color": "^4.2.3", - "debug": "^4.3.4", - "ejs": "^3.1.9", + "debug": "^4.3.5", + "ejs": "^3.1.10", "get-package-type": "^0.1.0", "globby": "^11.1.0", "hyperlinker": "^1.0.0", @@ -986,15 +987,31 @@ "node": ">=18.0.0" } }, + "node_modules/@oclif/core/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/@oclif/test": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@oclif/test/-/test-3.2.8.tgz", - "integrity": "sha512-aC523gJxzRxzL1P1m2Mrdu/xl0FG+ho8GAcZtdUKNOMM6te2iwR481GRzs8B0xDtAPNi0jZWiPFetbyR7mh/kA==", + "version": "3.2.15", + "resolved": "https://registry.npmjs.org/@oclif/test/-/test-3.2.15.tgz", + "integrity": "sha512-XqG3RosozNqySkxSXInU12Xec2sPSOkqYHJDfdFZiWG3a8Cxu4dnPiAQvms+BJsOlLQmfEQlSHqiyVUKOMHhXA==", "dev": true, "dependencies": { - "@oclif/core": "^3.26.0", + "@oclif/core": "^3.26.6", "chai": "^4.4.1", - "fancy-test": "^3.0.14" + "fancy-test": "^3.0.15" }, "engines": { "node": ">=18.0.0" @@ -1069,9 +1086,9 @@ "dev": true }, "node_modules/@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", "dev": true }, "node_modules/@types/cli-progress": { @@ -1092,12 +1109,6 @@ "@types/node": "*" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, "node_modules/@types/jsonfile": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", @@ -1108,9 +1119,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==", "dev": true }, "node_modules/@types/mocha": { @@ -1120,9 +1131,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "dependencies": { "undici-types": "~5.26.4" } @@ -1149,21 +1160,19 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.6.0.tgz", - "integrity": "sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.12.0.tgz", + "integrity": "sha512-7F91fcbuDf/d3S8o21+r3ZncGIke/+eWk0EpO21LXhDfLahriZF9CGj4fbAetEjlaBdjdSm9a6VeXbpbT6Z40Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/type-utils": "7.6.0", - "@typescript-eslint/utils": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.12.0", + "@typescript-eslint/type-utils": "7.12.0", + "@typescript-eslint/utils": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -1184,15 +1193,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.12.0.tgz", + "integrity": "sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/typescript-estree": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", + "@typescript-eslint/scope-manager": "7.12.0", + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/typescript-estree": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0", "debug": "^4.3.4" }, "engines": { @@ -1212,13 +1221,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz", - "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.12.0.tgz", + "integrity": "sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0" + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1229,13 +1238,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.6.0.tgz", - "integrity": "sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.12.0.tgz", + "integrity": "sha512-lib96tyRtMhLxwauDWUp/uW3FMhLA6D0rJ8T7HmH7x23Gk1Gwwu8UZ94NMXBvOELn6flSPiBrCKlehkiXyaqwA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.6.0", - "@typescript-eslint/utils": "7.6.0", + "@typescript-eslint/typescript-estree": "7.12.0", + "@typescript-eslint/utils": "7.12.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1256,9 +1265,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz", - "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.12.0.tgz", + "integrity": "sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1269,13 +1278,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz", - "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.12.0.tgz", + "integrity": "sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/visitor-keys": "7.12.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1297,18 +1306,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.6.0.tgz", - "integrity": "sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.12.0.tgz", + "integrity": "sha512-Y6hhwxwDx41HNpjuYswYp6gDbkiZ8Hin9Bf5aJQn1bpTs3afYY4GX+MPYxma8jtoIV2GRwTM/UJm/2uGCVv+DQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/typescript-estree": "7.6.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.12.0", + "@typescript-eslint/types": "7.12.0", + "@typescript-eslint/typescript-estree": "7.12.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1322,12 +1328,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz", - "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.12.0.tgz", + "integrity": "sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", + "@typescript-eslint/types": "7.12.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2259,9 +2265,9 @@ } }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dependencies": { "jake": "^10.8.5" }, @@ -2546,9 +2552,10 @@ } }, "node_modules/fancy-test": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/fancy-test/-/fancy-test-3.0.14.tgz", - "integrity": "sha512-FkiDltQA8PBZzw5tUnMrP1QtwIdNQWxxbZK5C22M9wu6HfFNciwkG3D9siT4l4s1fBTDaEG+Fdkbpi9FDTxtrg==", + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/fancy-test/-/fancy-test-3.0.16.tgz", + "integrity": "sha512-y1xZFpyYbE2TMiT+agOW2Emv8gr73zvDrKKbcXc8L+gMyIVJFn71cc4ICfzu2zEXjHirpHpdDJN0JBX99wwDXQ==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "dependencies": { "@types/chai": "*", @@ -3561,9 +3568,9 @@ } }, "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -4742,9 +4749,9 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.1.tgz", + "integrity": "sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -5209,12 +5216,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "bin": { "semver": "bin/semver.js" }, @@ -5222,22 +5226,6 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -5906,9 +5894,9 @@ } }, "node_modules/typescript": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", - "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6105,9 +6093,9 @@ "dev": true }, "node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.3.tgz", + "integrity": "sha512-sntgmxj8o7DE7g/Qi60cqpLBA3HG3STcDA0kO+WfB05jEKhZMbY7umNm2rBpQvsmZ16/lPXCJGW2672dgOUkrg==", "dev": true, "bin": { "yaml": "bin.mjs" diff --git a/package.json b/package.json index ef0484e..5c9d4e8 100644 --- a/package.json +++ b/package.json @@ -17,34 +17,35 @@ ], "repository": "eclipse-velocitas/cli", "dependencies": { - "@oclif/core": "3.26.2", + "@oclif/core": "3.27.0", "fs-extra": "11.2.0", "inquirer": "8.2.6", "node-pty": "1.0.0", "recursive-copy": "2.0.14", - "semver": "7.6.0", + "semver": "7.6.2", "simple-git": "3.24.0" }, "devDependencies": { - "@oclif/test": "3.2.8", - "@types/chai": "4.3.14", + "@oclif/test": "3.2.15", + "@types/chai": "4.3.16", "@types/fs-extra": "11.0.4", "@types/mocha": "10.0.6", - "@types/node": "20.12.7", - "@typescript-eslint/eslint-plugin": "7.6.0", - "@typescript-eslint/parser": "7.6.0", + "@types/node": "20.14.2", + "@types/semver": "^7.5.8", + "@typescript-eslint/eslint-plugin": "7.12.0", + "@typescript-eslint/parser": "7.12.0", "@yao-pkg/pkg": "5.11.5", "chai": "4.4.1", "eslint": "8.57.0", "mocha": "10.4.0", "nyc": "15.1.0", - "prettier": "3.2.5", + "prettier": "3.3.1", "prettier-plugin-organize-imports": "3.2.4", "shx": "0.3.4", "sinon": "^17.0.1", "ts-node": "10.9.2", - "typescript": "5.4.4", - "yaml": "2.4.1" + "typescript": "5.4.5", + "yaml": "2.4.3" }, "oclif": { "bin": "velocitas", diff --git a/src/commands/init/index.ts b/src/commands/init/index.ts index c95f491..75bef98 100644 --- a/src/commands/init/index.ts +++ b/src/commands/init/index.ts @@ -179,7 +179,7 @@ export default class Init extends Command { for (const packageConfig of packageConfigs) { await this._resolveVersion(packageConfig, flags.verbose); - if (!flags.force && packageConfig.isPackageInstalled()) { + if (!flags.force && packageConfig.isPackageInstalled() && (await packageConfig.isPackageValidRepo(flags.verbose))) { this.log(`... '${packageConfig.getPackageName()}:${packageConfig.version}' already installed.`); continue; } diff --git a/src/modules/package-downloader.ts b/src/modules/package-downloader.ts index 0b1b42b..47bfb43 100644 --- a/src/modules/package-downloader.ts +++ b/src/modules/package-downloader.ts @@ -12,7 +12,7 @@ // // SPDX-License-Identifier: Apache-2.0 -import { posix as pathPosix } from 'node:path'; +import { join } from 'node:path'; import { CheckRepoActions, SimpleGit, simpleGit } from 'simple-git'; import { CliFileSystem } from '../utils/fs-bridge'; import { PackageConfig } from './package'; @@ -26,57 +26,65 @@ export class PackageDownloader { this.packageConfig = packageConfig; } - async cloneRepository(packageDir: string, cloneOpts: string[]): Promise { + private async _cloneRepository(packageDir: string, cloneOpts: string[]): Promise { await this.git.clone(this.packageConfig.getPackageRepo(), packageDir, cloneOpts); } - async updateRepository(checkRepoAction: CheckRepoActions, packageDir: string, cloneOpts: string[]): Promise { + private async _updateRepository(checkRepoAction: CheckRepoActions): Promise { const localRepoExists = await this.git.checkIsRepo(checkRepoAction); if (localRepoExists) { await this.git.fetch(['--force', '--tags', '--prune', '--prune-tags']); - } else { - await this.git.clone(this.packageConfig.getPackageRepo(), packageDir, cloneOpts); } } - async checkoutVersion(): Promise { - await this.git.checkout( - this.packageConfig.version.startsWith(BRANCH_PREFIX) - ? this.packageConfig.version.substring(BRANCH_PREFIX.length) - : this.packageConfig.version, - ); + private async _checkoutVersion(version: string): Promise { + const branchOrTag = version.startsWith(BRANCH_PREFIX) ? version.substring(BRANCH_PREFIX.length) : version; + await this.git.checkout(branchOrTag); + } + + private async _checkForValidRepo(packageDir: string, cloneOpts: string[], checkRepoAction: CheckRepoActions): Promise { + let directoryExists = CliFileSystem.existsSync(packageDir); + if (directoryExists && !(await this.isValidRepo(packageDir, checkRepoAction))) { + CliFileSystem.removeSync(packageDir); + directoryExists = false; + } + + if (!directoryExists) { + await this._cloneRepository(packageDir, cloneOpts); + } + } + + public async isValidRepo(packageDir: string, checkRepoAction?: CheckRepoActions): Promise { + return await simpleGit(packageDir).checkIsRepo(checkRepoAction); } - async downloadPackage(option: { checkVersionOnly: boolean }): Promise { + public async downloadPackage(option: { checkVersionOnly: boolean }): Promise { let packageDir: string = this.packageConfig.getPackageDirectory(); - let cloneOpts: string[] = []; let checkRepoAction: CheckRepoActions; + const cloneOpts: string[] = []; if (option.checkVersionOnly) { - packageDir = pathPosix.join(packageDir, '_cache'); + packageDir = join(packageDir, '_cache'); cloneOpts.push('--bare'); checkRepoAction = CheckRepoActions.BARE; } else { - packageDir = pathPosix.join(packageDir, this.packageConfig.version); + packageDir = join(packageDir, this.packageConfig.version); checkRepoAction = CheckRepoActions.IS_REPO_ROOT; } - if (!CliFileSystem.existsSync(packageDir)) { - await this.cloneRepository(packageDir, cloneOpts); - } - + await this._checkForValidRepo(packageDir, cloneOpts, checkRepoAction); this.git = simpleGit(packageDir); - await this.updateRepository(checkRepoAction, packageDir, cloneOpts); + await this._updateRepository(checkRepoAction); if (!option.checkVersionOnly) { - await this.checkoutVersion(); + await this._checkoutVersion(this.packageConfig.version); } return this.git; } } -export const packageDownloader = (packageConfig: PackageConfig) => { +export const packageDownloader = (packageConfig: PackageConfig): PackageDownloader => { return new PackageDownloader(packageConfig); }; diff --git a/src/modules/package.ts b/src/modules/package.ts index b20a15a..830d168 100644 --- a/src/modules/package.ts +++ b/src/modules/package.ts @@ -116,10 +116,15 @@ export class PackageConfig { } isPackageInstalled(): boolean { - if (!CliFileSystem.existsSync(this.getPackageDirectoryWithVersion())) { - return false; + return CliFileSystem.existsSync(this.getPackageDirectoryWithVersion()); + } + + async isPackageValidRepo(verbose?: boolean): Promise { + const isValid = await packageDownloader(this).isValidRepo(this.getPackageDirectoryWithVersion()); + if (!isValid && verbose) { + console.log(`... Corrupted .git directory found for: '${this.getPackageName()}:${this.version}'`); } - return true; + return isValid; } readPackageManifest(): PackageManifest { diff --git a/src/utils/fs-bridge.ts b/src/utils/fs-bridge.ts index cd0da33..cc5cd78 100644 --- a/src/utils/fs-bridge.ts +++ b/src/utils/fs-bridge.ts @@ -43,6 +43,13 @@ interface IFileSystem { */ mkdirSync(path: fs.PathLike): string | undefined; + /** + * Removes a file or directory. The directory can have contents. + * If the path does not exist, silently does nothing. + * @param path A path to the file or directory as string. + */ + removeSync(path: string): void; + /** * Synchronously writes data to a file, replacing the file if it already exists. * @param path A path to the file to write to. @@ -100,6 +107,10 @@ class RealFileSystem implements IFileSystem { return fs.mkdirSync(path, { recursive: true }); } + removeSync(path: string): void { + fse.removeSync(path); + } + writeFileSync(path: fs.PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView): void { fs.writeFileSync(path, data, { encoding: DEFAULT_BUFFER_ENCODING }); } @@ -143,6 +154,10 @@ export class MockFileSystem implements IFileSystem, IFileSystemTests { return (this._fileSystemObj[path.toString()] = ''); } + removeSync(path: string): void { + delete this._fileSystemObj[path]; + } + writeFileSync(path: fs.PathOrFileDescriptor, data: any): void { this._fileSystemObj[path.toString()] = data; } @@ -203,6 +218,15 @@ export class CliFileSystem { return this._impl.mkdirSync(path); } + /** + * Removes a file or directory. The directory can have contents. + * If the path does not exist, silently does nothing. + * @param path A path to the file or directory as string. + */ + static removeSync(path: string): void { + return this._impl.removeSync(path); + } + /** * Synchronously writes data to a file, replacing the file if it already exists. * @param path A path to the file to write to. diff --git a/test/commands/init/init.test.ts b/test/commands/init/init.test.ts index 7f49294..83878a4 100644 --- a/test/commands/init/init.test.ts +++ b/test/commands/init/init.test.ts @@ -91,6 +91,26 @@ describe('init', () => { expect(ProjectConfigIO.isLockAvailable()).to.be.true; }); + test.do(() => { + mockFolders({ velocitasConfig: true, packageIndex: true, installedComponents: true }); + }) + .stdout() + .stub(gitModule, 'simpleGit', (stub) => stub.returns(simpleGitInstanceMock(undefined, false))) + .stub(exec, 'runExecSpec', (stub) => stub.returns({})) + .command(['init', '-v']) + .it('downloads corrupted packages again', (ctx) => { + expect(ctx.stdout).to.contain('Initializing Velocitas packages ...'); + expect(ctx.stdout).to.contain( + `... Corrupted .git directory found for: '${corePackageInfoMock.repo}:${corePackageInfoMock.resolvedVersion}'`, + ); + expect(ctx.stdout).to.contain(`... Downloading package: '${corePackageInfoMock.repo}:${corePackageInfoMock.resolvedVersion}'`); + expect( + CliFileSystem.existsSync( + `${userHomeDir}/.velocitas/packages/${corePackageInfoMock.repo}/${corePackageInfoMock.resolvedVersion}`, + ), + ).to.be.true; + }); + test.do(() => { mockFolders({ velocitasConfig: true, velocitasConfigLock: true, installedComponents: true, appManifest: false }); }) @@ -144,9 +164,9 @@ describe('init', () => { .stdout() .stub(gitModule, 'simpleGit', (stub) => stub.returns(simpleGitInstanceMock())) .stub(exec, 'runExecSpec', (stub) => stub.returns({})) - .command(['init', '--package', 'devenv-runtime']) + .command(['init', '--package', 'devenv-runtimes']) .it('adds a new entry to .velocitas.json if the package does not exist', (ctx) => { - expect(ctx.stdout).to.contain(`... Package 'devenv-runtime:v1.1.1' added to .velocitas.json`); + expect(ctx.stdout).to.contain(`... Package 'devenv-runtimes:v1.1.1' added to .velocitas.json`); }); test.do(() => { diff --git a/test/helpers/simpleGit.ts b/test/helpers/simpleGit.ts index 5d9cd87..64aaf97 100644 --- a/test/helpers/simpleGit.ts +++ b/test/helpers/simpleGit.ts @@ -15,7 +15,7 @@ import { CliFileSystem } from '../../src/utils/fs-bridge'; import { corePackageManifestMock, runtimePackageManifestMock, setupPackageManifestMock } from '../utils/mockConfig'; -export const simpleGitInstanceMock = (mockedNewVersionTag?: string) => { +export const simpleGitInstanceMock = (mockedNewVersionTag?: string, checkRepo: boolean = true) => { return { clone: async (repoPath: string, localPath: string, options?: any) => { await CliFileSystem.promisesMkdir(localPath); @@ -30,7 +30,7 @@ export const simpleGitInstanceMock = (mockedNewVersionTag?: string) => { } }, checkIsRepo: () => { - return true; + return checkRepo; }, fetch: () => {}, checkout: () => {