@automattic/vip 4.1.6 → 4.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/dev-env.lando.template.yml.ejs +1 -1
- package/dist/bin/vip-app-deploy-token-generate.js +110 -78
- package/dist/bin/vip-app-deploy-token.js +24 -16
- package/dist/bin/vip-app-deploy-validate.js +45 -41
- package/dist/bin/vip-app-deploy.js +222 -215
- package/dist/bin/vip-app-list.js +59 -43
- package/dist/bin/vip-app.js +97 -66
- package/dist/bin/vip-backup-db.js +36 -29
- package/dist/bin/vip-backup.js +16 -9
- package/dist/bin/vip-cache-purge-url.js +93 -55
- package/dist/bin/vip-cache.js +23 -14
- package/dist/bin/vip-config-envvar-delete.js +74 -73
- package/dist/bin/vip-config-envvar-get-all.js +68 -68
- package/dist/bin/vip-config-envvar-get.js +46 -46
- package/dist/bin/vip-config-envvar-list.js +54 -57
- package/dist/bin/vip-config-envvar-set.js +102 -96
- package/dist/bin/vip-config-envvar.js +38 -24
- package/dist/bin/vip-config-software-get.js +88 -75
- package/dist/bin/vip-config-software-update.js +116 -120
- package/dist/bin/vip-config-software.js +31 -21
- package/dist/bin/vip-config.js +25 -17
- package/dist/bin/vip-db-phpmyadmin.js +40 -39
- package/dist/bin/vip-db.js +13 -12
- package/dist/bin/vip-defensive-mode-configure.js +197 -197
- package/dist/bin/vip-defensive-mode-disable.js +43 -35
- package/dist/bin/vip-defensive-mode-enable.js +47 -38
- package/dist/bin/vip-defensive-mode.js +28 -17
- package/dist/bin/vip-dev-env-create.js +147 -104
- package/dist/bin/vip-dev-env-destroy.js +48 -39
- package/dist/bin/vip-dev-env-envvar-delete.js +60 -49
- package/dist/bin/vip-dev-env-envvar-get-all.js +52 -45
- package/dist/bin/vip-dev-env-envvar-get.js +48 -37
- package/dist/bin/vip-dev-env-envvar-list.js +48 -41
- package/dist/bin/vip-dev-env-envvar-set.js +83 -70
- package/dist/bin/vip-dev-env-envvar.js +38 -23
- package/dist/bin/vip-dev-env-exec.js +81 -74
- package/dist/bin/vip-dev-env-import-media.js +34 -26
- package/dist/bin/vip-dev-env-import-sql.js +65 -51
- package/dist/bin/vip-dev-env-import.js +23 -14
- package/dist/bin/vip-dev-env-info.js +59 -50
- package/dist/bin/vip-dev-env-list.js +34 -31
- package/dist/bin/vip-dev-env-logs.js +59 -49
- package/dist/bin/vip-dev-env-purge.js +71 -63
- package/dist/bin/vip-dev-env-shell.js +82 -71
- package/dist/bin/vip-dev-env-start.js +77 -65
- package/dist/bin/vip-dev-env-stop.js +80 -74
- package/dist/bin/vip-dev-env-sync-sql.js +80 -72
- package/dist/bin/vip-dev-env-sync.js +18 -11
- package/dist/bin/vip-dev-env-update.js +93 -84
- package/dist/bin/vip-dev-env.js +25 -8
- package/dist/bin/vip-edge-workers-build.js +82 -54
- package/dist/bin/vip-edge-workers-delete.js +84 -52
- package/dist/bin/vip-edge-workers-deploy.js +186 -126
- package/dist/bin/vip-edge-workers-disable.js +75 -44
- package/dist/bin/vip-edge-workers-enable.js +86 -54
- package/dist/bin/vip-edge-workers-get.js +108 -88
- package/dist/bin/vip-edge-workers-init.js +83 -53
- package/dist/bin/vip-edge-workers-list.js +89 -54
- package/dist/bin/vip-edge-workers-new.js +98 -69
- package/dist/bin/vip-edge-workers-validate.js +123 -82
- package/dist/bin/vip-edge-workers.js +19 -6
- package/dist/bin/vip-export-sql.js +75 -69
- package/dist/bin/vip-export.js +12 -7
- package/dist/bin/vip-import-media-abort.js +99 -73
- package/dist/bin/vip-import-media-status.js +83 -51
- package/dist/bin/vip-import-media.js +165 -166
- package/dist/bin/vip-import-sql-status.js +75 -45
- package/dist/bin/vip-import-sql.js +536 -596
- package/dist/bin/vip-import-validate-files.js +122 -141
- package/dist/bin/vip-import-validate-sql.js +52 -16
- package/dist/bin/vip-import.js +16 -7
- package/dist/bin/vip-logout.js +17 -13
- package/dist/bin/vip-logs.js +209 -183
- package/dist/bin/vip-search-replace.js +85 -53
- package/dist/bin/vip-slowlogs.js +168 -147
- package/dist/bin/vip-sync.js +163 -133
- package/dist/bin/vip-whoami.js +71 -35
- package/dist/bin/vip-wp.js +506 -549
- package/dist/bin/vip.js +161 -116
- package/dist/commands/backup-db.js +183 -149
- package/dist/commands/dev-env-import-sql.js +162 -117
- package/dist/commands/dev-env-sync-sql.js +372 -330
- package/dist/commands/export-sql.js +441 -425
- package/dist/commands/phpmyadmin.js +232 -212
- package/dist/commands/wp-ssh.js +218 -187
- package/dist/lib/analytics/clients/tracks.js +84 -91
- package/dist/lib/analytics/index.js +27 -27
- package/dist/lib/api/app.js +37 -36
- package/dist/lib/api/cache-purge.js +17 -20
- package/dist/lib/api/constants.js +5 -6
- package/dist/lib/api/edge-workers.js +84 -135
- package/dist/lib/api/error-debug.js +10 -13
- package/dist/lib/api/feature-flags.js +16 -17
- package/dist/lib/api/http.js +47 -48
- package/dist/lib/api/user.js +17 -18
- package/dist/lib/api.js +107 -116
- package/dist/lib/app-logs/app-logs.js +24 -25
- package/dist/lib/app-slowlogs/app-slowlogs.js +23 -24
- package/dist/lib/app-slowlogs/types.js +2 -1
- package/dist/lib/app.js +6 -8
- package/dist/lib/backup-storage-availability/backup-storage-availability.js +119 -119
- package/dist/lib/backup-storage-availability/docker-machine-not-found-error.js +5 -6
- package/dist/lib/cli/apiConfig.js +71 -41
- package/dist/lib/cli/command.js +1120 -873
- package/dist/lib/cli/config.js +29 -29
- package/dist/lib/cli/envAlias.js +35 -50
- package/dist/lib/cli/exit.js +19 -19
- package/dist/lib/cli/format.js +172 -172
- package/dist/lib/cli/progress.js +193 -236
- package/dist/lib/cli/prompt.js +14 -15
- package/dist/lib/cli/runtime-mode.js +5 -6
- package/dist/lib/client-file-uploader.js +489 -641
- package/dist/lib/config/software.js +206 -212
- package/dist/lib/constants/dev-environment.js +40 -37
- package/dist/lib/constants/file-size.js +6 -7
- package/dist/lib/constants/vipgo.js +24 -12
- package/dist/lib/custom-deploy/custom-deploy.js +138 -120
- package/dist/lib/database.js +88 -85
- package/dist/lib/defensive-mode/api.js +41 -46
- package/dist/lib/defensive-mode/cli-helpers.js +40 -40
- package/dist/lib/dev-environment/dev-environment-cli.js +776 -735
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +224 -191
- package/dist/lib/dev-environment/dev-environment-core.js +697 -732
- package/dist/lib/dev-environment/dev-environment-database.js +57 -41
- package/dist/lib/dev-environment/dev-environment-lando.js +734 -666
- package/dist/lib/dev-environment/docker-utils.js +96 -90
- package/dist/lib/dev-environment/env-vars.js +61 -59
- package/dist/lib/dev-environment/lando-loader.js +6 -7
- package/dist/lib/dev-environment/types.js +2 -1
- package/dist/lib/edge-workers/confirmation.js +42 -36
- package/dist/lib/edge-workers/deployment.js +150 -159
- package/dist/lib/edge-workers/index.js +68 -85
- package/dist/lib/edge-workers/location.js +26 -26
- package/dist/lib/edge-workers/output.js +14 -15
- package/dist/lib/edge-workers/project.js +123 -132
- package/dist/lib/edge-workers/toolchains/assemblyscript/constants.js +6 -8
- package/dist/lib/edge-workers/toolchains/assemblyscript/index.js +100 -101
- package/dist/lib/edge-workers/toolchains/assemblyscript/templates.js +31 -33
- package/dist/lib/edge-workers/toolchains/index.js +15 -15
- package/dist/lib/edge-workers/types.js +10 -38
- package/dist/lib/edge-workers/validation.js +161 -150
- package/dist/lib/env.js +16 -17
- package/dist/lib/envvar/api-delete.js +16 -18
- package/dist/lib/envvar/api-get-all.js +15 -19
- package/dist/lib/envvar/api-get.js +8 -9
- package/dist/lib/envvar/api-list.js +16 -21
- package/dist/lib/envvar/api-set.js +20 -19
- package/dist/lib/envvar/api.js +34 -29
- package/dist/lib/envvar/input.js +29 -34
- package/dist/lib/envvar/logging.js +9 -11
- package/dist/lib/envvar/read-file.js +6 -7
- package/dist/lib/http/download-file.js +76 -44
- package/dist/lib/http/proxy-agent.js +37 -40
- package/dist/lib/http/proxy-dispatcher.js +69 -71
- package/dist/lib/keychain/insecure.js +40 -36
- package/dist/lib/keychain/keychain.js +2 -1
- package/dist/lib/keychain/secure.js +16 -15
- package/dist/lib/keychain.js +22 -22
- package/dist/lib/live-backup-copy.js +117 -115
- package/dist/lib/logout.js +17 -19
- package/dist/lib/media-import/config.js +15 -14
- package/dist/lib/media-import/media-file-import.js +9 -13
- package/dist/lib/media-import/progress.js +53 -65
- package/dist/lib/media-import/status.js +241 -256
- package/dist/lib/media-import/utils.js +15 -15
- package/dist/lib/node-version-check.js +16 -16
- package/dist/lib/promise.js +16 -17
- package/dist/lib/read-file.js +48 -16
- package/dist/lib/rechallenge/client.js +37 -43
- package/dist/lib/rechallenge/errors.js +38 -37
- package/dist/lib/rechallenge/flow.js +148 -123
- package/dist/lib/rechallenge/index.js +23 -24
- package/dist/lib/rechallenge/link.js +153 -151
- package/dist/lib/rechallenge/open-browser.js +14 -17
- package/dist/lib/rechallenge/token-cache.js +83 -86
- package/dist/lib/rechallenge/types.js +5 -14
- package/dist/lib/retry.js +93 -129
- package/dist/lib/search-and-replace.js +164 -148
- package/dist/lib/site-import/db-file-import.js +12 -16
- package/dist/lib/site-import/status.js +291 -291
- package/dist/lib/token.js +86 -87
- package/dist/lib/tracker.js +51 -62
- package/dist/lib/types/graphql/rate-limit-exceeded-error.js +2 -1
- package/dist/lib/types.js +2 -1
- package/dist/lib/user-error.js +6 -8
- package/dist/lib/utils.js +81 -87
- package/dist/lib/validations/custom-deploy.js +218 -186
- package/dist/lib/validations/is-multi-site-sql-dump.js +6 -6
- package/dist/lib/validations/is-multi-site.js +83 -50
- package/dist/lib/validations/is-multisite-domain-mapped.js +92 -62
- package/dist/lib/validations/line-by-line.js +78 -46
- package/dist/lib/validations/site-type.js +59 -63
- package/dist/lib/validations/sql-insert-parser.js +415 -0
- package/dist/lib/validations/sql.js +551 -431
- package/dist/lib/validations/utils.js +27 -29
- package/dist/lib/vip-import-validate-files.js +481 -490
- package/dist/lib/wp/helpers.js +41 -45
- package/dist/lib/wp/readline.js +21 -57
- package/dist/lib/xdg-data.js +11 -12
- package/helpers/mark-cli-executable.js +9 -0
- package/node_modules/@apollo/client/CHANGELOG.md +10 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/helpers.cjs +5 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/helpers.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/inMemoryCache.cjs +2 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/key-extractor.cjs +14 -2
- package/node_modules/@apollo/client/__cjs/cache/inmemory/key-extractor.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.cjs +16 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/cache/inmemory/policies.d.cts +2 -0
- package/node_modules/@apollo/client/__cjs/cache/inmemory/writeToStore.cjs +3 -2
- package/node_modules/@apollo/client/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/core/QueryInfo.cjs +9 -1
- package/node_modules/@apollo/client/__cjs/core/QueryInfo.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/core/QueryInfo.d.cts +1 -1
- package/node_modules/@apollo/client/__cjs/core/QueryManager.cjs +10 -3
- package/node_modules/@apollo/client/__cjs/core/QueryManager.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/react/hooks/useFragment.cjs.map +1 -1
- package/node_modules/@apollo/client/__cjs/react/hooks/useFragment.d.cts +42 -43
- package/node_modules/@apollo/client/__cjs/version.cjs +1 -1
- package/node_modules/@apollo/client/cache/inmemory/helpers.js +5 -0
- package/node_modules/@apollo/client/cache/inmemory/helpers.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js +2 -1
- package/node_modules/@apollo/client/cache/inmemory/inMemoryCache.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/key-extractor.js +14 -2
- package/node_modules/@apollo/client/cache/inmemory/key-extractor.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/policies.d.ts +2 -0
- package/node_modules/@apollo/client/cache/inmemory/policies.js +17 -1
- package/node_modules/@apollo/client/cache/inmemory/policies.js.map +1 -1
- package/node_modules/@apollo/client/cache/inmemory/writeToStore.js +3 -2
- package/node_modules/@apollo/client/cache/inmemory/writeToStore.js.map +1 -1
- package/node_modules/@apollo/client/core/QueryInfo.d.ts +1 -1
- package/node_modules/@apollo/client/core/QueryInfo.js +10 -2
- package/node_modules/@apollo/client/core/QueryInfo.js.map +1 -1
- package/node_modules/@apollo/client/core/QueryManager.js +10 -3
- package/node_modules/@apollo/client/core/QueryManager.js.map +1 -1
- package/node_modules/@apollo/client/package.json +1 -1
- package/node_modules/@apollo/client/react/hooks/useFragment.d.ts +42 -43
- package/node_modules/@apollo/client/react/hooks/useFragment.js.map +1 -1
- package/node_modules/@apollo/client/react/hooks-compiled/useFragment.d.ts +42 -43
- package/node_modules/@apollo/client/react/hooks-compiled/useFragment.js.map +1 -1
- package/node_modules/@apollo/client/version.js +1 -1
- package/node_modules/@automattic/vip-search-replace/README.md +6 -1
- package/node_modules/@automattic/vip-search-replace/lib/index.js +46 -14
- package/node_modules/@automattic/vip-search-replace/package.json +1 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/zlib.d.ts +752 -0
- package/node_modules/check-disk-space/README.md +92 -32
- package/node_modules/check-disk-space/dist/check-disk-space.d.mts +58 -0
- package/node_modules/check-disk-space/dist/check-disk-space.mjs +170 -190
- package/node_modules/check-disk-space/package.json +43 -71
- package/node_modules/cpu-features/build/Makefile +2 -2
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/filesystem.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_macos_or_iphone.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_aarch64_windows.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_arm_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_mips_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_ppc_linux.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_freebsd.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_linux_or_android.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_macos.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/impl_x86_windows.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/stack_line_reader.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpu_features/deps/cpu_features/src/string_view.o.d +1 -1
- package/node_modules/cpu-features/build/Release/.deps/Release/obj.target/cpufeatures/src/binding.o.d +157 -145
- package/node_modules/cpu-features/build/Release/cpufeatures.node +0 -0
- package/node_modules/cpu-features/build/Release/obj.target/cpufeatures/src/binding.o +0 -0
- package/node_modules/cpu-features/build/Release/obj.target/cpufeatures.node +0 -0
- package/node_modules/cpu-features/build/config.gypi +100 -31
- package/node_modules/cpu-features/build/cpufeatures.target.mk +14 -14
- package/node_modules/cpu-features/build/deps/cpu_features/cpu_features.target.mk +14 -14
- package/node_modules/ssh2/lib/protocol/crypto/build/Makefile +2 -2
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto/src/binding.o.d.raw +136 -0
- package/node_modules/ssh2/lib/protocol/crypto/build/sshcrypto.target.mk +14 -14
- package/node_modules/undici/docs/docs/api/Interceptors.md +15 -2
- package/node_modules/undici/lib/dispatcher/client-h2.js +78 -3
- package/node_modules/undici/lib/dispatcher/pool-base.js +20 -3
- package/node_modules/undici/package.json +3 -3
- package/node_modules/undici/types/api.d.ts +1 -1
- package/node_modules/undici/types/utility.d.ts +4 -4
- package/package.json +44 -13
- package/dist/lib/analytics/clients/client.js +0 -1
- package/dist/lib/analytics/clients/pendo.js +0 -78
- package/helpers/check-version.js +0 -16
- package/node_modules/check-disk-space/dist/check-disk-space.cjs +0 -210
- package/node_modules/check-disk-space/dist/check-disk-space.d.ts +0 -53
- package/node_modules/fetch-retry/.eslintignore +0 -1
- package/node_modules/fetch-retry/.eslintrc.yml +0 -20
- package/node_modules/fetch-retry/.github/workflows/node.js.yml +0 -32
- package/node_modules/fetch-retry/.husky/pre-commit +0 -6
- package/node_modules/fetch-retry/.nycrc.json +0 -24
- package/node_modules/fetch-retry/.travis.yml +0 -3
- package/node_modules/fetch-retry/LICENSE +0 -21
- package/node_modules/fetch-retry/README.md +0 -128
- package/node_modules/fetch-retry/dist/fetch-retry.umd.js +0 -151
- package/node_modules/fetch-retry/index.d.ts +0 -29
- package/node_modules/fetch-retry/index.js +0 -143
- package/node_modules/fetch-retry/package.json +0 -41
- package/node_modules/fetch-retry/rollup.config.js +0 -12
- package/node_modules/fetch-retry/test/.eslintrc.yml +0 -7
- package/node_modules/fetch-retry/test/integration/index.js +0 -212
- package/node_modules/fetch-retry/test/integration/mock-api/index.js +0 -42
- package/node_modules/fetch-retry/test/unit/index.js +0 -1169
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto/src/binding.o.d +0 -265
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/obj.target/sshcrypto.node.d +0 -1
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/.deps/Release/sshcrypto.node.d +0 -1
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/obj.target/sshcrypto/src/binding.o +0 -0
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/obj.target/sshcrypto.node +0 -0
- package/node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node +0 -0
|
@@ -1,198 +1,189 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
exports
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.getDevEnvLogFile = getDevEnvLogFile;
|
|
10
|
-
exports.getEnvTrackingInfo = getEnvTrackingInfo;
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateDependencies = exports.CONFIGURATION_FOLDER = exports.DEFAULT_SLUG = void 0;
|
|
7
|
+
exports.setIsTTY = setIsTTY;
|
|
8
|
+
exports.handleCLIException = handleCLIException;
|
|
11
9
|
exports.getEnvironmentName = getEnvironmentName;
|
|
12
10
|
exports.getEnvironmentStartCommand = getEnvironmentStartCommand;
|
|
13
|
-
exports.getOptionsFromAppInfo = getOptionsFromAppInfo;
|
|
14
|
-
exports.getTagChoices = getTagChoices;
|
|
15
|
-
exports.handleCLIException = handleCLIException;
|
|
16
|
-
exports.postStart = postStart;
|
|
17
11
|
exports.printTable = printTable;
|
|
18
|
-
exports.processBooleanOption = processBooleanOption;
|
|
19
12
|
exports.processComponentOptionInput = processComponentOptionInput;
|
|
20
|
-
exports.
|
|
21
|
-
exports.processSlug = processSlug;
|
|
22
|
-
exports.processStringOrBooleanOption = processStringOrBooleanOption;
|
|
23
|
-
exports.processVersionOption = processVersionOption;
|
|
13
|
+
exports.getOptionsFromAppInfo = getOptionsFromAppInfo;
|
|
24
14
|
exports.promptForArguments = promptForArguments;
|
|
25
|
-
exports.
|
|
26
|
-
exports.
|
|
27
|
-
exports.promptForMultisite = promptForMultisite;
|
|
28
|
-
exports.promptForPhpVersion = promptForPhpVersion;
|
|
15
|
+
exports.ensureValidPathsInOptions = ensureValidPathsInOptions;
|
|
16
|
+
exports.resolvePath = resolvePath;
|
|
29
17
|
exports.promptForText = promptForText;
|
|
30
18
|
exports.promptForURL = promptForURL;
|
|
31
|
-
exports.
|
|
19
|
+
exports.promptForMultisite = promptForMultisite;
|
|
20
|
+
exports.promptForBoolean = promptForBoolean;
|
|
32
21
|
exports.resolveMultisite = resolveMultisite;
|
|
33
|
-
exports.resolvePath = resolvePath;
|
|
34
22
|
exports.resolvePhpVersion = resolvePhpVersion;
|
|
35
|
-
exports.
|
|
36
|
-
exports.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
23
|
+
exports.promptForPhpVersion = promptForPhpVersion;
|
|
24
|
+
exports.promptForWordPress = promptForWordPress;
|
|
25
|
+
exports.promptForComponent = promptForComponent;
|
|
26
|
+
exports.processBooleanOption = processBooleanOption;
|
|
27
|
+
exports.processMediaRedirectDomainOption = processMediaRedirectDomainOption;
|
|
28
|
+
exports.processStringOrBooleanOption = processStringOrBooleanOption;
|
|
29
|
+
exports.processSlug = processSlug;
|
|
30
|
+
exports.formatDevEnvLogTimestamp = formatDevEnvLogTimestamp;
|
|
31
|
+
exports.formatDevEnvLogSlug = formatDevEnvLogSlug;
|
|
32
|
+
exports.getDevEnvLogFile = getDevEnvLogFile;
|
|
33
|
+
exports.processVersionOption = processVersionOption;
|
|
34
|
+
exports.addDevEnvConfigurationOptions = addDevEnvConfigurationOptions;
|
|
35
|
+
exports.getTagChoices = getTagChoices;
|
|
36
|
+
exports.getEnvTrackingInfo = getEnvTrackingInfo;
|
|
37
|
+
exports.postStart = postStart;
|
|
38
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
39
|
+
const child_process_1 = require("child_process");
|
|
40
|
+
const debug_1 = __importDefault(require("debug"));
|
|
41
|
+
const enquirer_1 = require("enquirer");
|
|
42
|
+
const node_fs_1 = require("node:fs");
|
|
43
|
+
const node_os_1 = require("node:os");
|
|
44
|
+
const path_1 = __importDefault(require("path"));
|
|
45
|
+
const shelljs_1 = require("shelljs");
|
|
46
|
+
const dev_environment_configuration_file_1 = require("./dev-environment-configuration-file");
|
|
47
|
+
const dev_environment_core_1 = require("./dev-environment-core");
|
|
48
|
+
const dev_environment_lando_1 = require("./dev-environment-lando");
|
|
49
|
+
const lando_loader_1 = require("./lando-loader");
|
|
50
|
+
const user_1 = require("../api/user");
|
|
51
|
+
const dev_environment_1 = require("../constants/dev-environment");
|
|
52
|
+
const tracker_1 = require("../tracker");
|
|
53
|
+
const user_error_1 = __importDefault(require("../user-error"));
|
|
54
|
+
const debug = (0, debug_1.default)('@automattic/vip:bin:dev-environment');
|
|
55
|
+
exports.DEFAULT_SLUG = 'vip-local';
|
|
56
|
+
exports.CONFIGURATION_FOLDER = '.wpvip';
|
|
57
57
|
let isStdinTTY = Boolean(process.stdin.isTTY);
|
|
58
58
|
let landoFormatters = null;
|
|
59
59
|
const getLandoFormatters = () => {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
if (!landoFormatters) {
|
|
61
|
+
landoFormatters = (0, lando_loader_1.loadLandoModule)('lando/lib/formatters');
|
|
62
|
+
}
|
|
63
|
+
return landoFormatters;
|
|
64
64
|
};
|
|
65
|
-
|
|
66
65
|
/**
|
|
67
66
|
* Used internally for tests
|
|
68
67
|
*
|
|
69
68
|
* @param {boolean} val Value to set
|
|
70
69
|
*/
|
|
71
70
|
function setIsTTY(val) {
|
|
72
|
-
|
|
71
|
+
isStdinTTY = val;
|
|
73
72
|
}
|
|
74
73
|
const componentDisplayNames = {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
wordpress: 'WordPress',
|
|
75
|
+
muPlugins: 'VIP MU Plugins',
|
|
76
|
+
appCode: 'application code',
|
|
78
77
|
};
|
|
79
78
|
const componentDemoNames = {
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
muPlugins: 'vip-go-mu-plugins',
|
|
80
|
+
appCode: 'vip-go-skeleton',
|
|
82
81
|
};
|
|
83
82
|
async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const duration = new Date().getTime() - now.getTime();
|
|
118
|
-
debug('Validation checks completed in %d ms', duration);
|
|
83
|
+
const errorPrefix = chalk_1.default.red('Error:');
|
|
84
|
+
if (dev_environment_1.DEV_ENVIRONMENT_NOT_FOUND === exception.message) {
|
|
85
|
+
const createCommand = chalk_1.default.bold(dev_environment_1.DEV_ENVIRONMENT_FULL_COMMAND + ' create');
|
|
86
|
+
const message = `Environment doesn't exist.\n\n\nTo create a new environment run:\n\n${createCommand}\n`;
|
|
87
|
+
console.error(errorPrefix, message);
|
|
88
|
+
}
|
|
89
|
+
else if (exception instanceof user_error_1.default) {
|
|
90
|
+
// User errors are handled in global error handler
|
|
91
|
+
throw exception;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
let message = exception.message;
|
|
95
|
+
// if the message has already ERROR prefix we should drop it as we are adding our own cool red Error-prefix
|
|
96
|
+
message = message.replace('ERROR: ', '');
|
|
97
|
+
console.error(errorPrefix, message);
|
|
98
|
+
if (trackKey) {
|
|
99
|
+
const errorTrackingInfo = { ...trackBaseInfo, failure: message, stack: exception.stack };
|
|
100
|
+
// trackEvent does not throw
|
|
101
|
+
await (0, tracker_1.trackEvent)(trackKey, errorTrackingInfo);
|
|
102
|
+
}
|
|
103
|
+
if (!process.env.DEBUG) {
|
|
104
|
+
console.error(`\nPlease re-run the command with "--debug ${chalk_1.default.bold('@automattic/vip:bin:dev-environment')}" appended to it and provide the stack trace on the support ticket.`);
|
|
105
|
+
console.error(chalk_1.default.bold('\nExample:\n'));
|
|
106
|
+
console.error('vip dev-env <command> <arguments> --debug @automattic/vip:bin:dev-environment \n');
|
|
107
|
+
}
|
|
108
|
+
debug(exception);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const validateDependencies = (lando) => {
|
|
112
|
+
const now = new Date();
|
|
113
|
+
(0, dev_environment_lando_1.validateDockerInstalled)(lando);
|
|
114
|
+
const duration = new Date().getTime() - now.getTime();
|
|
115
|
+
debug('Validation checks completed in %d ms', duration);
|
|
119
116
|
};
|
|
120
117
|
exports.validateDependencies = validateDependencies;
|
|
121
118
|
async function getEnvironmentName(options, quiet = false) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
119
|
+
if (options.slug) {
|
|
120
|
+
return options.slug;
|
|
121
|
+
}
|
|
122
|
+
if (options.app) {
|
|
123
|
+
const envSuffix = options.env ? `-${options.env}` : '';
|
|
124
|
+
const appName = options.app + envSuffix;
|
|
125
|
+
if (options.allowAppEnv) {
|
|
126
|
+
return appName;
|
|
127
|
+
}
|
|
128
|
+
const message = `This command does not support @app.env notation. Use '--slug=${appName}' to target the local environment.`;
|
|
129
|
+
throw new user_error_1.default(message);
|
|
130
|
+
}
|
|
131
|
+
const configurationFileOptions = await (0, dev_environment_configuration_file_1.getConfigurationFileOptions)();
|
|
132
|
+
if (configurationFileOptions.slug && configurationFileOptions.meta) {
|
|
133
|
+
const slug = configurationFileOptions.slug;
|
|
134
|
+
if (!quiet) {
|
|
135
|
+
console.log(`Using environment ${chalk_1.default.blue.bold(slug)} from ${chalk_1.default.gray(configurationFileOptions.meta['configuration-path'])}\n`);
|
|
136
|
+
}
|
|
137
|
+
return slug;
|
|
138
|
+
}
|
|
139
|
+
const envs = (0, dev_environment_core_1.getAllEnvironmentNames)();
|
|
140
|
+
if (envs.length === 1) {
|
|
141
|
+
return envs[0];
|
|
142
|
+
}
|
|
143
|
+
if (envs.length > 1 && typeof options.slug !== 'string') {
|
|
144
|
+
const msg = `More than one environment found: ${chalk_1.default.blue.bold(envs.join(', '))}. Please re-run command with the --slug parameter for the targeted environment.`;
|
|
145
|
+
throw new user_error_1.default(msg);
|
|
146
|
+
}
|
|
147
|
+
return exports.DEFAULT_SLUG; // Fall back to the default slug if we don't have any, e.g. during the env creation purpose
|
|
151
148
|
}
|
|
152
149
|
function getEnvironmentStartCommand(slug, configurationFileOptions) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
150
|
+
const isUsingConfigurationFileSlug = Object.keys(configurationFileOptions).length > 0 && configurationFileOptions.slug === slug;
|
|
151
|
+
if (!slug || isUsingConfigurationFileSlug) {
|
|
152
|
+
return `${dev_environment_1.DEV_ENVIRONMENT_FULL_COMMAND} start`;
|
|
153
|
+
}
|
|
154
|
+
return `${dev_environment_1.DEV_ENVIRONMENT_FULL_COMMAND} start --slug ${slug}`;
|
|
158
155
|
}
|
|
159
156
|
function printTable(data) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}, {
|
|
163
|
-
border: false
|
|
164
|
-
});
|
|
165
|
-
console.log(formattedData);
|
|
157
|
+
const formattedData = getLandoFormatters().formatData(data, { format: 'table' }, { border: false });
|
|
158
|
+
console.log(formattedData);
|
|
166
159
|
}
|
|
167
160
|
function processComponentOptionInput(passedParam, allowLocal) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
161
|
+
// cast to string
|
|
162
|
+
const param = String(passedParam);
|
|
163
|
+
// This is a bit of a naive check
|
|
164
|
+
if (allowLocal && /[\\/]/.test(param)) {
|
|
165
|
+
return {
|
|
166
|
+
mode: 'local',
|
|
167
|
+
dir: param,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
172
170
|
return {
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
mode: 'image',
|
|
172
|
+
tag: param === 'demo' || param === 'image' ? undefined : param,
|
|
175
173
|
};
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
mode: 'image',
|
|
179
|
-
tag: param === 'demo' || param === 'image' ? undefined : param
|
|
180
|
-
};
|
|
181
174
|
}
|
|
182
175
|
function getOptionsFromAppInfo(appInfo) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
176
|
+
const integrationsConfig = appInfo.environment?.integrations ?? {};
|
|
177
|
+
const hasES = integrationsConfig['enterprise-search']?.env?.status === 'enabled';
|
|
178
|
+
return {
|
|
179
|
+
title: appInfo.environment?.name || appInfo.name || '', // NOSONAR
|
|
180
|
+
multisite: Boolean(appInfo.environment?.isMultisite),
|
|
181
|
+
mediaRedirectDomain: appInfo.environment?.primaryDomain,
|
|
182
|
+
php: appInfo.environment?.php ?? '',
|
|
183
|
+
wordpress: appInfo.environment?.wordpress ?? '',
|
|
184
|
+
elasticsearch: hasES,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
196
187
|
/**
|
|
197
188
|
* Prompt for arguments
|
|
198
189
|
*
|
|
@@ -203,671 +194,721 @@ function getOptionsFromAppInfo(appInfo) {
|
|
|
203
194
|
*/
|
|
204
195
|
// eslint-disable-next-line complexity
|
|
205
196
|
async function promptForArguments(preselectedOptions, defaultOptions, suppressPrompts, create) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
197
|
+
debug('Provided preselected', preselectedOptions, 'and default', defaultOptions);
|
|
198
|
+
let isVIPUser;
|
|
199
|
+
try {
|
|
200
|
+
const currentUser = await (0, user_1.getCurrentUserInfo)(true);
|
|
201
|
+
isVIPUser = currentUser?.isVIP ?? false;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
isVIPUser = false;
|
|
205
|
+
}
|
|
206
|
+
if (suppressPrompts) {
|
|
207
|
+
preselectedOptions = { ...defaultOptions, ...preselectedOptions };
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log(dev_environment_1.DEV_ENVIRONMENT_PROMPT_INTRO);
|
|
211
|
+
}
|
|
212
|
+
let multisiteText = 'Multisite';
|
|
213
|
+
if (defaultOptions.title) {
|
|
214
|
+
multisiteText += ` (${defaultOptions.title} ${defaultOptions.multisite ? 'IS' : 'is NOT'} multisite)`;
|
|
215
|
+
}
|
|
216
|
+
const instanceData = {
|
|
217
|
+
wpTitle: preselectedOptions.title ??
|
|
218
|
+
(await promptForText('WordPress site title', defaultOptions.title ?? dev_environment_1.DEV_ENVIRONMENT_DEFAULTS.title)),
|
|
219
|
+
multisite: resolveMultisite(preselectedOptions.multisite ??
|
|
220
|
+
(await promptForMultisite(multisiteText, defaultOptions.multisite ?? dev_environment_1.DEV_ENVIRONMENT_DEFAULTS.multisite))),
|
|
221
|
+
elasticsearch: false,
|
|
222
|
+
php: preselectedOptions.php
|
|
223
|
+
? resolvePhpVersion(preselectedOptions.php)
|
|
224
|
+
: await promptForPhpVersion(resolvePhpVersion(defaultOptions.php ?? dev_environment_1.DEV_ENVIRONMENT_DEFAULTS.phpVersion)),
|
|
225
|
+
mariadb: preselectedOptions.mariadb ?? defaultOptions.mariadb,
|
|
226
|
+
mediaRedirectDomain: preselectedOptions.mediaRedirectDomain ?? defaultOptions.mediaRedirectDomain ?? '',
|
|
227
|
+
wordpress: {
|
|
228
|
+
mode: 'image',
|
|
229
|
+
tag: '',
|
|
230
|
+
},
|
|
231
|
+
muPlugins: {
|
|
232
|
+
mode: 'image',
|
|
233
|
+
},
|
|
234
|
+
appCode: {
|
|
235
|
+
mode: 'image',
|
|
236
|
+
},
|
|
237
|
+
phpmyadmin: false,
|
|
238
|
+
xdebug: false,
|
|
239
|
+
xdebugConfig: preselectedOptions.xdebugConfig,
|
|
240
|
+
siteSlug: '',
|
|
241
|
+
mailpit: false,
|
|
242
|
+
photon: false,
|
|
243
|
+
cron: false,
|
|
244
|
+
overrides: preselectedOptions.overrides,
|
|
245
|
+
adminPassword: preselectedOptions.adminPassword,
|
|
218
246
|
};
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
photon
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
instanceData.appCode = await processComponent('appCode', preselectedOptions.appCode ?? '', defaultOptions.appCode ?? '', suppressPrompts, validateAppCodeLocalPath);
|
|
273
|
-
let preselectedMU = preselectedOptions.muPlugins;
|
|
274
|
-
const defaultMU = defaultOptions.muPlugins;
|
|
275
|
-
if (!preselectedMU && !isVIPUser && (!defaultMU || ['demo', 'image'].includes(defaultMU))) {
|
|
276
|
-
preselectedMU = 'image';
|
|
277
|
-
}
|
|
278
|
-
instanceData.muPlugins = await processComponent('muPlugins', preselectedMU ?? '', defaultMU ?? '', suppressPrompts, validateMuPluginsLocalPath);
|
|
279
|
-
debug(`Processing elasticsearch with preselected "%s"`, preselectedOptions.elasticsearch);
|
|
280
|
-
if ('elasticsearch' in preselectedOptions) {
|
|
281
|
-
instanceData.elasticsearch = Boolean(preselectedOptions.elasticsearch);
|
|
282
|
-
} else {
|
|
283
|
-
instanceData.elasticsearch = await promptForBoolean('Enable Elasticsearch (needed by Enterprise Search)?', Boolean(defaultOptions.elasticsearch));
|
|
284
|
-
}
|
|
285
|
-
const services = ['phpmyadmin', 'xdebug', 'mailpit', 'photon', 'cron'];
|
|
286
|
-
for (const service of services) {
|
|
287
|
-
if (service in instanceData) {
|
|
288
|
-
const preselected = preselectedOptions[service];
|
|
289
|
-
if (preselected !== undefined) {
|
|
290
|
-
instanceData[service] = preselected;
|
|
291
|
-
} else {
|
|
292
|
-
// eslint-disable-next-line no-await-in-loop
|
|
293
|
-
instanceData[service] = await promptForBoolean(`Enable ${promptLabels[service] || service}`, Boolean(defaultOptions[service]));
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
debug('Instance data after prompts', instanceData);
|
|
298
|
-
return instanceData;
|
|
247
|
+
const promptLabels = {
|
|
248
|
+
xdebug: 'XDebug',
|
|
249
|
+
phpmyadmin: 'phpMyAdmin',
|
|
250
|
+
mailpit: 'Mailpit',
|
|
251
|
+
photon: 'Photon',
|
|
252
|
+
cron: 'Cron',
|
|
253
|
+
};
|
|
254
|
+
if (create && !instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
|
|
255
|
+
const mediaRedirectPromptText = `Would you like to redirect to ${defaultOptions.mediaRedirectDomain} for missing media files?`;
|
|
256
|
+
const setMediaRedirectDomain = await promptForBoolean(mediaRedirectPromptText, true);
|
|
257
|
+
if (setMediaRedirectDomain) {
|
|
258
|
+
instanceData.mediaRedirectDomain = defaultOptions.mediaRedirectDomain;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else if (!create &&
|
|
262
|
+
defaultOptions.mediaRedirectDomain &&
|
|
263
|
+
!preselectedOptions.mediaRedirectDomain) {
|
|
264
|
+
const mediaRedirectPromptText = 'URL to redirect for missing media files ("n" to disable)?';
|
|
265
|
+
const mediaRedirectDomain = await promptForURL(mediaRedirectPromptText, defaultOptions.mediaRedirectDomain);
|
|
266
|
+
instanceData.mediaRedirectDomain = mediaRedirectDomain;
|
|
267
|
+
}
|
|
268
|
+
instanceData.wordpress = await processWordPress(preselectedOptions.wordpress ?? '', defaultOptions.wordpress ?? '');
|
|
269
|
+
instanceData.appCode = await processComponent('appCode', preselectedOptions.appCode ?? '', defaultOptions.appCode ?? '', suppressPrompts, validateAppCodeLocalPath);
|
|
270
|
+
let preselectedMU = preselectedOptions.muPlugins;
|
|
271
|
+
const defaultMU = defaultOptions.muPlugins;
|
|
272
|
+
if (!preselectedMU &&
|
|
273
|
+
!isVIPUser &&
|
|
274
|
+
(!defaultMU || ['demo', 'image'].includes(defaultMU))) {
|
|
275
|
+
preselectedMU = 'image';
|
|
276
|
+
}
|
|
277
|
+
instanceData.muPlugins = await processComponent('muPlugins', preselectedMU ?? '', defaultMU ?? '', suppressPrompts, validateMuPluginsLocalPath);
|
|
278
|
+
debug(`Processing elasticsearch with preselected "%s"`, preselectedOptions.elasticsearch);
|
|
279
|
+
if ('elasticsearch' in preselectedOptions) {
|
|
280
|
+
instanceData.elasticsearch = Boolean(preselectedOptions.elasticsearch);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
instanceData.elasticsearch = await promptForBoolean('Enable Elasticsearch (needed by Enterprise Search)?', Boolean(defaultOptions.elasticsearch));
|
|
284
|
+
}
|
|
285
|
+
const services = ['phpmyadmin', 'xdebug', 'mailpit', 'photon', 'cron'];
|
|
286
|
+
for (const service of services) {
|
|
287
|
+
if (service in instanceData) {
|
|
288
|
+
const preselected = preselectedOptions[service];
|
|
289
|
+
if (preselected !== undefined) {
|
|
290
|
+
instanceData[service] = preselected;
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
// eslint-disable-next-line no-await-in-loop
|
|
294
|
+
instanceData[service] = await promptForBoolean(`Enable ${promptLabels[service] || service}`, Boolean(defaultOptions[service]));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
debug('Instance data after prompts', instanceData);
|
|
299
|
+
return instanceData;
|
|
299
300
|
}
|
|
300
301
|
async function processWordPress(preselectedValue, defaultValue) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
302
|
+
debug(`processing 'WordPress', with preselected/default - ${preselectedValue}/${defaultValue}`);
|
|
303
|
+
let result;
|
|
304
|
+
const allowLocal = false;
|
|
305
|
+
const defaultObject = defaultValue
|
|
306
|
+
? processComponentOptionInput(defaultValue, allowLocal)
|
|
307
|
+
: null;
|
|
308
|
+
if (preselectedValue) {
|
|
309
|
+
result = processComponentOptionInput(preselectedValue, allowLocal);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
result = await promptForWordPress(defaultObject);
|
|
313
|
+
}
|
|
314
|
+
const versions = await (0, dev_environment_core_1.getVersionList)();
|
|
315
|
+
if (versions.length) {
|
|
316
|
+
versions.sort((before, after) => (before.tag < after.tag ? 1 : -1));
|
|
317
|
+
const match = versions.find(({ prerelease, tag }) => result.tag === 'latest' ? !prerelease : tag === result.tag);
|
|
318
|
+
if (match === undefined) {
|
|
319
|
+
throw new user_error_1.default(`Unknown or unsupported WordPress version: ${result.tag}.`);
|
|
320
|
+
}
|
|
321
|
+
result.tag = match.tag;
|
|
322
|
+
}
|
|
323
|
+
debug(result);
|
|
324
|
+
return result;
|
|
324
325
|
}
|
|
325
326
|
async function processComponent(componentType, preselectedValue, defaultValue, suppressPrompts, localPathValidator) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
327
|
+
debug(`Processing the '${componentType}' component, with preselected = %s, default = %s`, preselectedValue, defaultValue);
|
|
328
|
+
const defaultObject = defaultValue ? processComponentOptionInput(defaultValue, true) : null;
|
|
329
|
+
if (preselectedValue && !suppressPrompts) {
|
|
330
|
+
console.log('%s Path to your local %s: %s', chalk_1.default.green('✓'), componentDisplayNames[componentType], preselectedValue);
|
|
331
|
+
}
|
|
332
|
+
let result = preselectedValue
|
|
333
|
+
? processComponentOptionInput(preselectedValue, true)
|
|
334
|
+
: await promptForComponent(componentType, true, defaultObject);
|
|
335
|
+
debug(result);
|
|
336
|
+
if (result.mode === 'local') {
|
|
337
|
+
result = await validateLocalPath(result, localPathValidator, componentType, defaultObject);
|
|
338
|
+
}
|
|
339
|
+
debug(result);
|
|
340
|
+
return result;
|
|
338
341
|
}
|
|
339
342
|
function ensureValidPathsInOptions(opt) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
343
|
+
if (opt.appCode) {
|
|
344
|
+
const result = validateAppCodeLocalPath(`${opt.appCode}`);
|
|
345
|
+
if (!result.result) {
|
|
346
|
+
console.warn(chalk_1.default.yellow('Warning:'), result.message);
|
|
347
|
+
delete opt.appCode;
|
|
348
|
+
delete opt.a;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (opt.muPlugins) {
|
|
352
|
+
const result = validateMuPluginsLocalPath(`${opt.muPlugins}`);
|
|
353
|
+
if (!result.result) {
|
|
354
|
+
console.warn(chalk_1.default.yellow('Warning:'), result.message);
|
|
355
|
+
delete opt.muPlugins;
|
|
356
|
+
delete opt.m;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
356
359
|
}
|
|
357
360
|
async function validateLocalPath(config, validator, componentName, defaultObject) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return config;
|
|
361
|
+
while (config.mode === 'local') {
|
|
362
|
+
const resolvedPath = resolvePath(config.dir ?? '');
|
|
363
|
+
config.dir = resolvedPath;
|
|
364
|
+
const { result: isPathValid, message } = validator(resolvedPath);
|
|
365
|
+
if (isPathValid) {
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
else if (isStdinTTY) {
|
|
369
|
+
console.log(chalk_1.default.yellow('Warning:'), message);
|
|
370
|
+
// eslint-disable-next-line no-await-in-loop
|
|
371
|
+
config = await promptForComponent(componentName, true, defaultObject);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
throw new Error(message);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return config;
|
|
376
378
|
}
|
|
377
379
|
function validateMuPluginsLocalPath(providedPath) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
+
if (!isNonEmptyDirectory(providedPath)) {
|
|
381
|
+
const message = `Provided path "${providedPath}" does not point to a valid or existing directory.`;
|
|
382
|
+
return {
|
|
383
|
+
result: false,
|
|
384
|
+
message,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
380
387
|
return {
|
|
381
|
-
|
|
382
|
-
|
|
388
|
+
result: true,
|
|
389
|
+
message: '',
|
|
383
390
|
};
|
|
384
|
-
}
|
|
385
|
-
return {
|
|
386
|
-
result: true,
|
|
387
|
-
message: ''
|
|
388
|
-
};
|
|
389
391
|
}
|
|
390
392
|
function validateAppCodeLocalPath(providedPath) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const
|
|
393
|
+
if (!isNonEmptyDirectory(providedPath)) {
|
|
394
|
+
const message = `Provided path "${providedPath}" does not point to a valid or existing directory.`;
|
|
395
|
+
return {
|
|
396
|
+
result: false,
|
|
397
|
+
message,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
const files = [
|
|
401
|
+
'languages',
|
|
402
|
+
'plugins',
|
|
403
|
+
'themes',
|
|
404
|
+
'private',
|
|
405
|
+
'images',
|
|
406
|
+
'client-mu-plugins',
|
|
407
|
+
'vip-config',
|
|
408
|
+
];
|
|
409
|
+
const missingFiles = [];
|
|
410
|
+
for (const file of files) {
|
|
411
|
+
const filePath = path_1.default.resolve(providedPath, file);
|
|
412
|
+
if (!(0, node_fs_1.existsSync)(filePath)) {
|
|
413
|
+
missingFiles.push(file);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (missingFiles.length > 0) {
|
|
417
|
+
const message = `Provided path "${providedPath}" is missing following files/folders: ${missingFiles.join(', ')}. Learn more: https://docs.wpvip.com/wordpress-skeleton/`;
|
|
418
|
+
return {
|
|
419
|
+
result: false,
|
|
420
|
+
message,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
408
423
|
return {
|
|
409
|
-
|
|
410
|
-
|
|
424
|
+
result: true,
|
|
425
|
+
message: '',
|
|
411
426
|
};
|
|
412
|
-
}
|
|
413
|
-
return {
|
|
414
|
-
result: true,
|
|
415
|
-
message: ''
|
|
416
|
-
};
|
|
417
427
|
}
|
|
418
428
|
function isNonEmptyDirectory(directoryPath) {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
429
|
+
const isDirectory = directoryPath && (0, node_fs_1.existsSync)(directoryPath) && (0, node_fs_1.lstatSync)(directoryPath).isDirectory();
|
|
430
|
+
const isEmpty = isDirectory ? (0, node_fs_1.readdirSync)(directoryPath).length === 0 : true;
|
|
431
|
+
return !isEmpty && isDirectory;
|
|
422
432
|
}
|
|
423
433
|
function resolvePath(input) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
434
|
+
// Resolve does not do ~ reliably
|
|
435
|
+
const resolvedPath = input.replace(/^~/, (0, node_os_1.homedir)());
|
|
436
|
+
// And resolve to handle relative paths
|
|
437
|
+
return path_1.default.resolve(resolvedPath);
|
|
428
438
|
}
|
|
429
439
|
async function promptForText(message, initial) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
return (result.input || '').trim();
|
|
440
|
+
let result = { input: initial };
|
|
441
|
+
if (isStdinTTY) {
|
|
442
|
+
const nonEmptyValidator = (value) => {
|
|
443
|
+
if ((value || '').trim()) {
|
|
444
|
+
return true;
|
|
445
|
+
}
|
|
446
|
+
return 'value needs to be provided';
|
|
447
|
+
};
|
|
448
|
+
result = await (0, enquirer_1.prompt)({
|
|
449
|
+
type: 'input',
|
|
450
|
+
name: 'input',
|
|
451
|
+
message,
|
|
452
|
+
initial,
|
|
453
|
+
validate: nonEmptyValidator,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
return (result.input || '').trim();
|
|
449
457
|
}
|
|
450
458
|
async function promptForURL(message, initial) {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
return retval === 'n' ? '' : retval;
|
|
459
|
+
let result = { input: initial };
|
|
460
|
+
if (isStdinTTY) {
|
|
461
|
+
const URLValidator = (value) => {
|
|
462
|
+
if (!value.trim() || value === 'n') {
|
|
463
|
+
return true;
|
|
464
|
+
}
|
|
465
|
+
try {
|
|
466
|
+
const url = new URL(value);
|
|
467
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
468
|
+
return 'value must be a http:// or https:// URL';
|
|
469
|
+
}
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
return 'value needs to be a valid URL or an empty string';
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
result = await (0, enquirer_1.prompt)({
|
|
477
|
+
type: 'input',
|
|
478
|
+
name: 'input',
|
|
479
|
+
message,
|
|
480
|
+
initial,
|
|
481
|
+
validate: URLValidator,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
const retval = result.input.trim();
|
|
485
|
+
return retval === 'n' ? '' : retval;
|
|
479
486
|
}
|
|
480
487
|
const multisiteOptions = ['subdomain', 'subdirectory'];
|
|
481
488
|
async function promptForMultisite(message, initial) {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
489
|
+
// `undefined` is used here only because our tests need overhauling
|
|
490
|
+
let result = { input: initial };
|
|
491
|
+
if (isStdinTTY) {
|
|
492
|
+
result = await (0, enquirer_1.prompt)({
|
|
493
|
+
type: 'input',
|
|
494
|
+
name: 'input',
|
|
495
|
+
message,
|
|
496
|
+
initial,
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
let input = (result?.input ?? initial).toString().trim();
|
|
500
|
+
const allowedOptions = [
|
|
501
|
+
...FALSE_OPTIONS,
|
|
502
|
+
...TRUE_OPTIONS,
|
|
503
|
+
...multisiteOptions,
|
|
504
|
+
'none',
|
|
505
|
+
];
|
|
506
|
+
if (!allowedOptions.includes(input) && isStdinTTY) {
|
|
507
|
+
const select = new enquirer_1.Select({
|
|
508
|
+
message: `Please choose a valid option for multisite:`,
|
|
509
|
+
choices: [...multisiteOptions, 'false'],
|
|
510
|
+
});
|
|
511
|
+
input = await select.run();
|
|
512
|
+
}
|
|
513
|
+
return processStringOrBooleanOption(input);
|
|
504
514
|
}
|
|
505
515
|
function promptForBoolean(message, initial) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
516
|
+
if (isStdinTTY) {
|
|
517
|
+
const confirm = new enquirer_1.Confirm({
|
|
518
|
+
message,
|
|
519
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment
|
|
520
|
+
initial: initial, // TS definition is wrong, so we need to bypass it to show the correct hint.
|
|
521
|
+
});
|
|
522
|
+
return confirm.run();
|
|
523
|
+
}
|
|
524
|
+
return Promise.resolve(initial);
|
|
515
525
|
}
|
|
516
526
|
function resolveMultisite(value) {
|
|
517
|
-
|
|
518
|
-
|
|
527
|
+
const isMultisiteOption = (val) => (typeof val === 'string' && multisiteOptions.includes(val)) ||
|
|
528
|
+
typeof val === 'boolean';
|
|
529
|
+
return isMultisiteOption(value) ? value : dev_environment_1.DEV_ENVIRONMENT_DEFAULTS.multisite;
|
|
519
530
|
}
|
|
520
531
|
function resolvePhpVersion(version) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
532
|
+
// It is painful to rewrite tests :-(
|
|
533
|
+
if (version === '') {
|
|
534
|
+
return '';
|
|
535
|
+
}
|
|
536
|
+
debug(`Resolving PHP version %j`, version);
|
|
537
|
+
let result;
|
|
538
|
+
if (!Object.hasOwn(dev_environment_1.DEV_ENVIRONMENT_PHP_VERSIONS, version)) {
|
|
539
|
+
const images = Object.values(dev_environment_1.DEV_ENVIRONMENT_PHP_VERSIONS);
|
|
540
|
+
const image = images.find(value => value.image === version);
|
|
541
|
+
if (image) {
|
|
542
|
+
result = image.image;
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
throw new user_error_1.default(`Unknown or unsupported PHP version: ${version}.`);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
result =
|
|
550
|
+
dev_environment_1.DEV_ENVIRONMENT_PHP_VERSIONS[version].image;
|
|
551
|
+
}
|
|
552
|
+
debug('Resolved PHP image: %j', result);
|
|
553
|
+
return result;
|
|
540
554
|
}
|
|
541
555
|
async function promptForPhpVersion(initialValue) {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
});
|
|
568
|
-
answer = await select.run();
|
|
569
|
-
}
|
|
570
|
-
return resolvePhpVersion(answer);
|
|
556
|
+
debug(`Prompting for PHP version, preselected option is ${initialValue}`);
|
|
557
|
+
let answer = initialValue;
|
|
558
|
+
if (isStdinTTY) {
|
|
559
|
+
const choices = [];
|
|
560
|
+
Object.keys(dev_environment_1.DEV_ENVIRONMENT_PHP_VERSIONS).forEach(version => {
|
|
561
|
+
const phpImage = dev_environment_1.DEV_ENVIRONMENT_PHP_VERSIONS[version];
|
|
562
|
+
const label = version === dev_environment_1.DEV_ENVIRONMENT_DEFAULT_PHP_VERSION
|
|
563
|
+
? `${phpImage.label} (recommended)`
|
|
564
|
+
: phpImage.label;
|
|
565
|
+
choices.push({ message: label, value: version });
|
|
566
|
+
});
|
|
567
|
+
const images = Object.values(dev_environment_1.DEV_ENVIRONMENT_PHP_VERSIONS);
|
|
568
|
+
let initial = images.findIndex(version => version.image === initialValue);
|
|
569
|
+
if (initial === -1) {
|
|
570
|
+
choices.push({ message: initialValue, value: initialValue });
|
|
571
|
+
initial = choices.length - 1;
|
|
572
|
+
}
|
|
573
|
+
const select = new enquirer_1.Select({
|
|
574
|
+
message: 'PHP version to use',
|
|
575
|
+
choices,
|
|
576
|
+
initial,
|
|
577
|
+
});
|
|
578
|
+
answer = await select.run();
|
|
579
|
+
}
|
|
580
|
+
return resolvePhpVersion(answer);
|
|
571
581
|
}
|
|
572
582
|
async function promptForWordPress(defaultObject) {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
583
|
+
debug(`Prompting for wordpress with default:`, defaultObject);
|
|
584
|
+
const componentDisplayName = componentDisplayNames.wordpress;
|
|
585
|
+
const messagePrefix = `${componentDisplayName} - `;
|
|
586
|
+
// image with selection
|
|
587
|
+
const tagChoices = await getTagChoices();
|
|
588
|
+
if (typeof defaultObject === 'string' &&
|
|
589
|
+
!tagChoices.find(choice => choice.value === defaultObject)) {
|
|
590
|
+
throw new Error(`Unknown or unsupported WordPress version: ${defaultObject}.`);
|
|
591
|
+
}
|
|
592
|
+
let option = typeof defaultObject === 'string' ? defaultObject : defaultObject?.tag ?? tagChoices[0].value;
|
|
593
|
+
if (isStdinTTY) {
|
|
594
|
+
const message = `${messagePrefix}Which version would you like`;
|
|
595
|
+
const selectTag = new enquirer_1.Select({
|
|
596
|
+
message,
|
|
597
|
+
choices: tagChoices,
|
|
598
|
+
initial: option,
|
|
599
|
+
});
|
|
600
|
+
option = await selectTag.run();
|
|
601
|
+
}
|
|
602
|
+
return {
|
|
603
|
+
mode: 'image',
|
|
604
|
+
tag: option,
|
|
605
|
+
};
|
|
596
606
|
}
|
|
597
607
|
async function promptForComponent(component, allowLocal, defaultObject) {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
608
|
+
debug(`Prompting for ${component} with default:`, defaultObject);
|
|
609
|
+
const componentDisplayName = componentDisplayNames[component] || component;
|
|
610
|
+
const componentDemoName = componentDemoNames[component];
|
|
611
|
+
const modChoices = [];
|
|
612
|
+
if (allowLocal) {
|
|
613
|
+
modChoices.push({
|
|
614
|
+
message: `Custom - Path to a locally cloned ${componentDisplayName} directory`,
|
|
615
|
+
value: 'local',
|
|
616
|
+
});
|
|
617
|
+
}
|
|
603
618
|
modChoices.push({
|
|
604
|
-
|
|
605
|
-
|
|
619
|
+
message: `Demo - Automatically fetched ${componentDemoName}`,
|
|
620
|
+
value: 'image',
|
|
606
621
|
});
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
622
|
+
let initialMode = 'image';
|
|
623
|
+
if ('appCode' === component && isStdinTTY) {
|
|
624
|
+
initialMode = 'local';
|
|
625
|
+
}
|
|
626
|
+
if (defaultObject?.mode) {
|
|
627
|
+
initialMode = defaultObject.mode;
|
|
628
|
+
}
|
|
629
|
+
let modeResult = initialMode;
|
|
630
|
+
const selectMode = modChoices.length > 1;
|
|
631
|
+
if (selectMode && isStdinTTY) {
|
|
632
|
+
const initialModeIndex = modChoices.findIndex(choice => choice.value === initialMode);
|
|
633
|
+
const select = new enquirer_1.Select({
|
|
634
|
+
message: `How would you like to source ${componentDisplayName}`,
|
|
635
|
+
choices: modChoices,
|
|
636
|
+
initial: initialModeIndex,
|
|
637
|
+
});
|
|
638
|
+
modeResult = (await select.run());
|
|
639
|
+
}
|
|
640
|
+
debug(modeResult);
|
|
641
|
+
const messagePrefix = selectMode ? '\t' : `${componentDisplayName} - `;
|
|
642
|
+
if ('local' === modeResult) {
|
|
643
|
+
const directoryPath = await promptForText(`${messagePrefix}What is a path to your local ${componentDisplayName}?`, defaultObject?.dir ?? '');
|
|
644
|
+
return {
|
|
645
|
+
mode: modeResult,
|
|
646
|
+
dir: directoryPath,
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
// image
|
|
634
650
|
return {
|
|
635
|
-
|
|
636
|
-
dir: directoryPath
|
|
651
|
+
mode: modeResult,
|
|
637
652
|
};
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
// image
|
|
641
|
-
return {
|
|
642
|
-
mode: modeResult
|
|
643
|
-
};
|
|
644
653
|
}
|
|
645
654
|
const FALSE_OPTIONS = ['false', 'no', 'n', '0'];
|
|
646
655
|
const TRUE_OPTIONS = ['true', 'yes', 'y', '1'];
|
|
647
656
|
function processBooleanOption(value) {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
return !FALSE_OPTIONS.includes(value.toString().toLowerCase()); // NOSONAR
|
|
657
|
+
if (!value) {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
661
|
+
return !FALSE_OPTIONS.includes(value.toString().toLowerCase()); // NOSONAR
|
|
654
662
|
}
|
|
655
663
|
function processMediaRedirectDomainOption(value) {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
664
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
665
|
+
const val = (value ?? '').toString();
|
|
666
|
+
if (FALSE_OPTIONS.includes(val.toLowerCase())) {
|
|
667
|
+
return '';
|
|
668
|
+
}
|
|
669
|
+
if (TRUE_OPTIONS.includes(val.toLowerCase())) {
|
|
670
|
+
throw new user_error_1.default('Media redirect domain must be a domain name or an URL');
|
|
671
|
+
}
|
|
672
|
+
return val;
|
|
665
673
|
}
|
|
666
674
|
function processStringOrBooleanOption(value) {
|
|
667
|
-
|
|
675
|
+
if (typeof value === 'boolean') {
|
|
676
|
+
return value;
|
|
677
|
+
}
|
|
678
|
+
if (!value || FALSE_OPTIONS.includes(value.toLowerCase())) {
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
if (TRUE_OPTIONS.includes(value.toLowerCase())) {
|
|
682
|
+
return true;
|
|
683
|
+
}
|
|
668
684
|
return value;
|
|
669
|
-
}
|
|
670
|
-
if (!value || FALSE_OPTIONS.includes(value.toLowerCase())) {
|
|
671
|
-
return false;
|
|
672
|
-
}
|
|
673
|
-
if (TRUE_OPTIONS.includes(value.toLowerCase())) {
|
|
674
|
-
return true;
|
|
675
|
-
}
|
|
676
|
-
return value;
|
|
677
685
|
}
|
|
678
686
|
function processSlug(value) {
|
|
679
|
-
|
|
680
|
-
|
|
687
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
688
|
+
return (value ?? '').toString().toLowerCase();
|
|
681
689
|
}
|
|
682
690
|
function formatDevEnvLogTimestamp(date) {
|
|
683
|
-
|
|
691
|
+
return date.toISOString().replace(/\..*$/, '').replace(/[-:]/g, '').replace('T', '-');
|
|
684
692
|
}
|
|
685
693
|
function formatDevEnvLogSlug(slug) {
|
|
686
|
-
|
|
694
|
+
return slug.replace(/[^a-z0-9_-]+/gi, '-').toLowerCase();
|
|
687
695
|
}
|
|
688
696
|
function getDevEnvLogFile(slug) {
|
|
689
|
-
|
|
690
|
-
|
|
697
|
+
const slugPart = slug ? formatDevEnvLogSlug(slug) : 'all';
|
|
698
|
+
return `vip-dev-env-${slugPart}-${formatDevEnvLogTimestamp(new Date())}.log`;
|
|
691
699
|
}
|
|
692
700
|
function processVersionOption(value) {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
701
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
702
|
+
if (!isNaN(value) && Number(value) % 1 === 0) {
|
|
703
|
+
return parseFloat(value).toFixed(1);
|
|
704
|
+
}
|
|
696
705
|
}
|
|
697
|
-
|
|
698
|
-
return value?.toString() ?? '';
|
|
706
|
+
return value?.toString() ?? '';
|
|
699
707
|
}
|
|
700
|
-
const phpVersionsSupported = Object.keys(
|
|
708
|
+
const phpVersionsSupported = Object.keys(dev_environment_1.DEV_ENVIRONMENT_PHP_VERSIONS).join(', ');
|
|
701
709
|
function addDevEnvConfigurationOptions(command) {
|
|
702
|
-
|
|
703
|
-
|
|
710
|
+
// We leave the third parameter to undefined on some because the defaults are handled in preProcessInstanceData()
|
|
711
|
+
return command
|
|
712
|
+
.option('wordpress', 'Manage the version of WordPress. Accepts a string value for major versions (6.x) or "latest". Defaults to the recommended version of WordPress for development.', undefined, processVersionOption)
|
|
713
|
+
.option(['u', 'mu-plugins'], 'Manage the source for VIP MU plugins. Accepts "demo" (default) for a read-only image of the staging branch, or a path to a built copy of VIP MU plugins on the local machine.')
|
|
714
|
+
.option('app-code', 'Manage the source for application code. Accepts "demo" (default) for a read-only image of WordPress VIP skeleton application code, or a path to a VIP formatted application repo on the local machine.')
|
|
715
|
+
.option('phpmyadmin', 'Enable or disable phpMyAdmin, disabled by default. Accepts "y" (default value) to enable or "n" to disable. When enabled, refer to the value of "PHPMYADMIN URLS" in the information output for a local environment for the URL to access phpMyAdmin.', undefined, processBooleanOption)
|
|
716
|
+
.option('xdebug', 'Enable or disable XDebug, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption)
|
|
717
|
+
.option('xdebug_config', 'Override some default configuration settings for Xdebug. Accepts a string value that is assigned to the XDEBUG_CONFIG environment variable.')
|
|
718
|
+
.option('elasticsearch', 'Enable or disable Elasticsearch (required by Enterprise Search), disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption)
|
|
719
|
+
.option(['r', 'media-redirect-domain'], 'Configure media files to be proxied from a VIP Platform environment. Accepts a string value for the primary domain of the VIP Platform environment or "n" to disable the media proxy.', undefined, processMediaRedirectDomainOption)
|
|
720
|
+
.option('php', `Manage the version of PHP. Accepts a string value for minor versions: ${phpVersionsSupported}`, undefined, processVersionOption)
|
|
721
|
+
.option('cron', 'Enable or disable cron, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption)
|
|
722
|
+
.option(['A', 'mailpit'], 'Enable or disable Mailpit, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption)
|
|
723
|
+
.option(['H', 'photon'], 'Enable or disable Photon, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption);
|
|
704
724
|
}
|
|
705
|
-
|
|
706
725
|
/**
|
|
707
726
|
* Provides the list of tag choices for selection
|
|
708
727
|
*/
|
|
709
728
|
async function getTagChoices() {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
const prerelease = version.prerelease ? '(Pre-Release)' : '';
|
|
736
|
-
if (version.tag !== version.ref) {
|
|
737
|
-
mapping = `→ ${prerelease} ${version.ref}`;
|
|
738
|
-
} else {
|
|
739
|
-
mapping = '';
|
|
729
|
+
let versions = await (0, dev_environment_core_1.getVersionList)();
|
|
730
|
+
if (versions.length < 1) {
|
|
731
|
+
versions = [
|
|
732
|
+
{
|
|
733
|
+
ref: '6.1.1',
|
|
734
|
+
tag: '6.1',
|
|
735
|
+
cacheable: true,
|
|
736
|
+
locked: true,
|
|
737
|
+
prerelease: false,
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
ref: '6.0.3',
|
|
741
|
+
tag: '6.0',
|
|
742
|
+
cacheable: true,
|
|
743
|
+
locked: true,
|
|
744
|
+
prerelease: false,
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
ref: '5.9.5',
|
|
748
|
+
tag: '5.9',
|
|
749
|
+
cacheable: true,
|
|
750
|
+
locked: true,
|
|
751
|
+
prerelease: false,
|
|
752
|
+
},
|
|
753
|
+
];
|
|
740
754
|
}
|
|
741
|
-
return {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
755
|
+
return versions.map(version => {
|
|
756
|
+
let mapping;
|
|
757
|
+
const tagFormatted = version.tag.padEnd(8 - version.tag.length);
|
|
758
|
+
const prerelease = version.prerelease ? '(Pre-Release)' : '';
|
|
759
|
+
if (version.tag !== version.ref) {
|
|
760
|
+
mapping = `→ ${prerelease} ${version.ref}`;
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
mapping = '';
|
|
764
|
+
}
|
|
765
|
+
return {
|
|
766
|
+
name: version.tag,
|
|
767
|
+
message: `${tagFormatted} ${mapping}`,
|
|
768
|
+
value: version.tag,
|
|
769
|
+
};
|
|
770
|
+
});
|
|
747
771
|
}
|
|
748
|
-
|
|
749
772
|
// Keep this list in sync with vip-next's devEnvTrackingInfo. Instance data may
|
|
750
773
|
// contain credentials and user-defined fields that must stay local (PLTFRM-2820).
|
|
751
|
-
const TRACKING_ALLOWED_KEYS = [
|
|
774
|
+
const TRACKING_ALLOWED_KEYS = [
|
|
775
|
+
'siteSlug',
|
|
776
|
+
'wpTitle',
|
|
777
|
+
'multisite',
|
|
778
|
+
'wordpress',
|
|
779
|
+
'muPlugins',
|
|
780
|
+
'appCode',
|
|
781
|
+
'mediaRedirectDomain',
|
|
782
|
+
'phpmyadmin',
|
|
783
|
+
'xdebug',
|
|
784
|
+
'xdebugConfig',
|
|
785
|
+
'mariadb',
|
|
786
|
+
'php',
|
|
787
|
+
'elasticsearch',
|
|
788
|
+
'mailpit',
|
|
789
|
+
'photon',
|
|
790
|
+
'cron',
|
|
791
|
+
'pullAfter',
|
|
792
|
+
'version',
|
|
793
|
+
];
|
|
752
794
|
function getEnvTrackingInfo(slug) {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
795
|
+
try {
|
|
796
|
+
const envData = (0, dev_environment_core_1.readEnvironmentData)(slug);
|
|
797
|
+
const result = { slug };
|
|
798
|
+
for (const key of TRACKING_ALLOWED_KEYS) {
|
|
799
|
+
if (!Object.hasOwn(envData, key)) {
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
// track doesn't like camelCase
|
|
803
|
+
const snakeCasedKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
|
|
804
|
+
const value = dev_environment_1.DEV_ENVIRONMENT_COMPONENTS_WITH_WP.includes(key)
|
|
805
|
+
? JSON.stringify(envData[key])
|
|
806
|
+
: envData[key];
|
|
807
|
+
result[snakeCasedKey] = value;
|
|
808
|
+
}
|
|
809
|
+
if (typeof result.php === 'string') {
|
|
810
|
+
result.php = result.php.replace(/^[^:]+:/, '');
|
|
811
|
+
}
|
|
812
|
+
return result;
|
|
813
|
+
}
|
|
814
|
+
catch {
|
|
815
|
+
return {
|
|
816
|
+
slug,
|
|
817
|
+
};
|
|
770
818
|
}
|
|
771
|
-
return result;
|
|
772
|
-
} catch {
|
|
773
|
-
return {
|
|
774
|
-
slug
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
819
|
}
|
|
778
820
|
// Map of supported editors and their configurations
|
|
779
821
|
const SUPPORTED_EDITORS = {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
822
|
+
vscode: {
|
|
823
|
+
displayName: 'VS Code',
|
|
824
|
+
candidates: ['code', 'code-insiders', 'codium'],
|
|
825
|
+
workspace: {
|
|
826
|
+
extension: 'code-workspace',
|
|
827
|
+
generator: dev_environment_core_1.generateVSCodeWorkspace,
|
|
828
|
+
},
|
|
829
|
+
},
|
|
830
|
+
cursor: {
|
|
831
|
+
displayName: 'Cursor',
|
|
832
|
+
candidates: ['cursor'],
|
|
833
|
+
workspace: {
|
|
834
|
+
extension: 'code-workspace',
|
|
835
|
+
generator: dev_environment_core_1.generateVSCodeWorkspace,
|
|
836
|
+
},
|
|
837
|
+
},
|
|
838
|
+
phpstorm: {
|
|
839
|
+
displayName: 'PHPStorm',
|
|
840
|
+
candidates: ['phpstorm', 'phpstorm64.exe'],
|
|
841
|
+
errors: {
|
|
842
|
+
notFound: `PHPStorm launcher was not detected in the expected path.\nPlease follow the setup instructions: https://www.jetbrains.com/help/phpstorm/working-with-the-ide-features-from-command-line.html#standalone`,
|
|
843
|
+
},
|
|
844
|
+
workspace: {
|
|
845
|
+
extension: 'iml',
|
|
846
|
+
generator: dev_environment_core_1.generatePHPStormWorkspace,
|
|
847
|
+
},
|
|
848
|
+
},
|
|
849
|
+
windsurf: {
|
|
850
|
+
displayName: 'Windsurf',
|
|
851
|
+
candidates: ['windsurf'],
|
|
852
|
+
workspace: {
|
|
853
|
+
extension: 'code-workspace',
|
|
854
|
+
generator: dev_environment_core_1.generateVSCodeWorkspace,
|
|
855
|
+
},
|
|
801
856
|
},
|
|
802
|
-
workspace: {
|
|
803
|
-
extension: 'iml',
|
|
804
|
-
generator: _devEnvironmentCore.generatePHPStormWorkspace
|
|
805
|
-
}
|
|
806
|
-
},
|
|
807
|
-
windsurf: {
|
|
808
|
-
displayName: 'Windsurf',
|
|
809
|
-
candidates: ['windsurf'],
|
|
810
|
-
workspace: {
|
|
811
|
-
extension: 'code-workspace',
|
|
812
|
-
generator: _devEnvironmentCore.generateVSCodeWorkspace
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
857
|
};
|
|
816
|
-
|
|
817
858
|
// Helper to get workspace path for any editor
|
|
818
859
|
function getWorkspacePath(slug, editor) {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
return
|
|
824
|
-
}
|
|
825
|
-
return _path.default.join((0, _devEnvironmentCore.getEnvironmentPath)(slug), `${slug}.${workspace.extension}`);
|
|
860
|
+
const { workspace } = SUPPORTED_EDITORS[editor];
|
|
861
|
+
if (editor === 'phpstorm') {
|
|
862
|
+
return path_1.default.join((0, dev_environment_core_1.getEnvironmentPath)(slug), '.idea', `${slug}.${workspace.extension}`);
|
|
863
|
+
}
|
|
864
|
+
return path_1.default.join((0, dev_environment_core_1.getEnvironmentPath)(slug), `${slug}.${workspace.extension}`);
|
|
826
865
|
}
|
|
827
866
|
function postStart(slug, options) {
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
867
|
+
let editorType;
|
|
868
|
+
if (options.editor) {
|
|
869
|
+
const editor = options.editor.toLowerCase();
|
|
870
|
+
if (!Object.keys(SUPPORTED_EDITORS).includes(editor)) {
|
|
871
|
+
throw new Error(`Invalid editor specified. Supported editors are: ${Object.keys(SUPPORTED_EDITORS).join(', ')}`);
|
|
872
|
+
}
|
|
873
|
+
editorType = editor;
|
|
874
|
+
}
|
|
875
|
+
else if (options.vscode) {
|
|
876
|
+
editorType = 'vscode';
|
|
877
|
+
}
|
|
878
|
+
if (editorType) {
|
|
879
|
+
launchEditor(slug, editorType);
|
|
880
|
+
}
|
|
841
881
|
}
|
|
842
882
|
const launchEditor = (slug, type) => {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
883
|
+
const editorConfig = SUPPORTED_EDITORS[type];
|
|
884
|
+
const workspacePath = getWorkspacePath(slug, type);
|
|
885
|
+
if ((0, node_fs_1.existsSync)(workspacePath)) {
|
|
886
|
+
console.log('Project already exists, skipping creation.');
|
|
887
|
+
}
|
|
888
|
+
else {
|
|
889
|
+
editorConfig.workspace.generator(slug);
|
|
890
|
+
console.log(`${editorConfig.displayName} project generated`);
|
|
891
|
+
}
|
|
892
|
+
console.log(`Project file location:\n${workspacePath}\n`);
|
|
893
|
+
const executable = findExecutable(editorConfig.candidates);
|
|
894
|
+
if (executable) {
|
|
895
|
+
// For PHPStorm, pass the environment home folder instead of the workspace path
|
|
896
|
+
const launchPath = type === 'phpstorm' ? (0, dev_environment_core_1.getEnvironmentPath)(slug) : workspacePath;
|
|
897
|
+
(0, child_process_1.spawn)(executable, [launchPath], { shell: process.platform === 'win32' });
|
|
898
|
+
}
|
|
899
|
+
else {
|
|
900
|
+
console.log(editorConfig.errors?.notFound ||
|
|
901
|
+
`${editorConfig.displayName} was not detected in the expected path.`);
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
const findExecutable = (candidates) => {
|
|
905
|
+
for (const candidate of candidates) {
|
|
906
|
+
const result = (0, shelljs_1.which)(candidate);
|
|
907
|
+
if (result) {
|
|
908
|
+
debug(`Found ${candidate} in path`);
|
|
909
|
+
return candidate;
|
|
910
|
+
}
|
|
911
|
+
debug(`Could not find ${candidate} in path`);
|
|
912
|
+
}
|
|
913
|
+
return null;
|
|
862
914
|
};
|
|
863
|
-
const findExecutable = candidates => {
|
|
864
|
-
for (const candidate of candidates) {
|
|
865
|
-
const result = (0, _shelljs.which)(candidate);
|
|
866
|
-
if (result) {
|
|
867
|
-
debug(`Found ${candidate} in path`);
|
|
868
|
-
return candidate;
|
|
869
|
-
}
|
|
870
|
-
debug(`Could not find ${candidate} in path`);
|
|
871
|
-
}
|
|
872
|
-
return null;
|
|
873
|
-
};
|