@codiac.io/codiac-cli 1.2.209 → 1.2.211
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/README.md +4651 -4636
- package/bin/dev +16 -16
- package/bin/dev.cmd +2 -2
- package/bin/run +3 -3
- package/bin/run.cmd +3 -3
- package/codiac.json +9 -9
- package/dist/apis/codiac-api/common/api-client-base.d.ts +165 -165
- package/dist/apis/codiac-api/common/api-client-base.js +547 -547
- package/dist/apis/codiac-api/common/api-user-creds.d.ts +7 -7
- package/dist/apis/codiac-api/common/api-user-creds.js +18 -18
- package/dist/apis/codiac-api/common/config-loader.d.ts +6 -6
- package/dist/apis/codiac-api/common/config-loader.js +18 -18
- package/dist/apis/codiac-api/common/endpoint-spec.d.ts +17 -17
- package/dist/apis/codiac-api/common/endpoint-spec.js +27 -27
- package/dist/apis/codiac-api/common/security/api-auth-methods-legacy.d.ts +87 -87
- package/dist/apis/codiac-api/common/security/api-auth-methods-legacy.js +367 -367
- package/dist/apis/codiac-api/common/security/auth-constants.d.ts +15 -15
- package/dist/apis/codiac-api/common/security/auth-constants.js +21 -21
- package/dist/apis/codiac-api/common/security/i-auth-client.d.ts +44 -44
- package/dist/apis/codiac-api/common/security/i-auth-client.js +2 -2
- package/dist/apis/codiac-api/common/security/token-holder.d.ts +13 -13
- package/dist/apis/codiac-api/common/security/token-holder.js +17 -17
- package/dist/apis/codiac-api/common/utils.d.ts +23 -23
- package/dist/apis/codiac-api/common/utils.js +82 -82
- package/dist/apis/codiac-api/contracts/index.d.ts +1 -1
- package/dist/apis/codiac-api/contracts/index.js +4 -4
- package/dist/apis/codiac-api/gen/client-config.d.ts +10 -10
- package/dist/apis/codiac-api/gen/client-config.js +28 -28
- package/dist/apis/codiac-api/gen/client.d.ts +1663 -1663
- package/dist/apis/codiac-api/gen/client.js +15629 -15629
- package/dist/apis/codiac-api/gen/contracts.d.ts +2722 -2722
- package/dist/apis/codiac-api/gen/contracts.js +402 -402
- package/dist/apis/codiac-api/index.d.ts +3 -3
- package/dist/apis/codiac-api/index.js +8 -8
- package/dist/apis/codiac-relay/common/api-client-base.d.ts +165 -165
- package/dist/apis/codiac-relay/common/api-client-base.js +547 -547
- package/dist/apis/codiac-relay/common/api-user-creds.d.ts +7 -7
- package/dist/apis/codiac-relay/common/api-user-creds.js +18 -18
- package/dist/apis/codiac-relay/common/config-loader.d.ts +6 -6
- package/dist/apis/codiac-relay/common/config-loader.js +18 -18
- package/dist/apis/codiac-relay/common/endpoint-spec.d.ts +17 -17
- package/dist/apis/codiac-relay/common/endpoint-spec.js +27 -27
- package/dist/apis/codiac-relay/common/security/api-auth-methods-legacy.d.ts +87 -87
- package/dist/apis/codiac-relay/common/security/api-auth-methods-legacy.js +367 -367
- package/dist/apis/codiac-relay/common/security/auth-constants.d.ts +15 -15
- package/dist/apis/codiac-relay/common/security/auth-constants.js +21 -21
- package/dist/apis/codiac-relay/common/security/i-auth-client.d.ts +44 -44
- package/dist/apis/codiac-relay/common/security/i-auth-client.js +2 -2
- package/dist/apis/codiac-relay/common/security/token-holder.d.ts +13 -13
- package/dist/apis/codiac-relay/common/security/token-holder.js +17 -17
- package/dist/apis/codiac-relay/common/utils.d.ts +23 -23
- package/dist/apis/codiac-relay/common/utils.js +82 -82
- package/dist/apis/codiac-relay/contracts/index.d.ts +1 -1
- package/dist/apis/codiac-relay/contracts/index.js +4 -4
- package/dist/apis/codiac-relay/gen/client-config.d.ts +10 -10
- package/dist/apis/codiac-relay/gen/client-config.js +28 -28
- package/dist/apis/codiac-relay/gen/client.d.ts +244 -244
- package/dist/apis/codiac-relay/gen/client.js +1862 -1862
- package/dist/apis/codiac-relay/gen/contracts.d.ts +3113 -3113
- package/dist/apis/codiac-relay/gen/contracts.js +434 -434
- package/dist/apis/codiac-relay/index.d.ts +3 -3
- package/dist/apis/codiac-relay/index.js +8 -8
- package/dist/cli-common/ImagesList.js +66 -66
- package/dist/cli-common/argument-manager.d.ts +28 -28
- package/dist/cli-common/argument-manager.js +194 -194
- package/dist/cli-common/built-in-cli-user-input.d.ts +18 -18
- package/dist/cli-common/built-in-cli-user-input.js +309 -309
- package/dist/cli-common/cli-interfaces.js +6 -6
- package/dist/cli-common/command-base.d.ts +72 -72
- package/dist/cli-common/command-base.js +182 -182
- package/dist/cli-common/entities/index.d.ts +1 -1
- package/dist/cli-common/entities/index.js +4 -4
- package/dist/cli-common/entities/prompt-choice.d.ts +7 -7
- package/dist/cli-common/entities/prompt-choice.js +2 -2
- package/dist/cli-common/file-selector.d.ts +48 -48
- package/dist/cli-common/file-selector.js +186 -186
- package/dist/cli-common/i-user-input-provider.js +18 -18
- package/dist/cli-common/index.d.ts +4 -4
- package/dist/cli-common/index.js +10 -10
- package/dist/cli-common/mock-ui.d.ts +27 -27
- package/dist/cli-common/mock-ui.js +82 -82
- package/dist/cli-common/prompt-select-fuzzy.d.ts +19 -19
- package/dist/cli-common/prompt-select-fuzzy.js +118 -118
- package/dist/cli-common/tenant-contextualizer.js +435 -435
- package/dist/cli-common/test/tenant-contextualizer.spec.js +142 -142
- package/dist/cli-entities/output-format-enum.d.ts +7 -7
- package/dist/cli-entities/output-format-enum.js +11 -11
- package/dist/cli-entities/prompt-choice.js +5 -5
- package/dist/codiac-constants.d.ts +35 -35
- package/dist/codiac-constants.js +40 -40
- package/dist/codiac-entities/asset-binding.d.ts +12 -12
- package/dist/codiac-entities/asset-binding.js +17 -17
- package/dist/codiac-entities/azure-container-registry.d.ts +4 -4
- package/dist/codiac-entities/azure-container-registry.js +2 -2
- package/dist/codiac-entities/azure-service-principal.d.ts +23 -23
- package/dist/codiac-entities/azure-service-principal.js +23 -23
- package/dist/codiac-entities/cloud-account-ref.d.ts +28 -28
- package/dist/codiac-entities/cloud-account-ref.js +36 -36
- package/dist/codiac-entities/deployment-temp.js +132 -132
- package/dist/codiac-entities/i-cloud-account-ref.d.ts +5 -5
- package/dist/codiac-entities/i-cloud-account-ref.js +2 -2
- package/dist/command-base-enterprise.d.ts +121 -121
- package/dist/command-base-enterprise.js +523 -523
- package/dist/command-base-tenantless.d.ts +44 -44
- package/dist/command-base-tenantless.js +179 -179
- package/dist/commands/asset/create.d.ts +42 -42
- package/dist/commands/asset/create.js +475 -475
- package/dist/commands/asset/destroy.d.ts +20 -20
- package/dist/commands/asset/destroy.js +128 -128
- package/dist/commands/asset/helm.d.ts +23 -23
- package/dist/commands/asset/helm.js +152 -152
- package/dist/commands/asset/list.d.ts +28 -28
- package/dist/commands/asset/list.js +171 -171
- package/dist/commands/asset/probe/create.d.ts +38 -38
- package/dist/commands/asset/probe/create.js +186 -186
- package/dist/commands/asset/recycle.d.ts +23 -23
- package/dist/commands/asset/recycle.js +174 -174
- package/dist/commands/asset/view.d.ts +188 -188
- package/dist/commands/asset/view.js +1364 -1364
- package/dist/commands/asset/volume/create.d.ts +23 -23
- package/dist/commands/asset/volume/create.js +175 -175
- package/dist/commands/asset/volume/delete.d.ts +19 -19
- package/dist/commands/asset/volume/delete.js +111 -111
- package/dist/commands/asset/volume/list.d.ts +19 -19
- package/dist/commands/asset/volume/list.js +69 -69
- package/dist/commands/branch/current.d.ts +10 -10
- package/dist/commands/branch/current.js +33 -33
- package/dist/commands/branch/list.d.ts +15 -15
- package/dist/commands/branch/list.js +55 -55
- package/dist/commands/branch.d.ts +12 -12
- package/dist/commands/branch.js +41 -41
- package/dist/commands/build.d.ts +38 -38
- package/dist/commands/build.js +119 -119
- package/dist/commands/cabinet/create.d.ts +21 -21
- package/dist/commands/cabinet/create.js +107 -107
- package/dist/commands/cabinet/list.d.ts +23 -23
- package/dist/commands/cabinet/list.js +133 -133
- package/dist/commands/cabinet/obliterate.d.ts +20 -20
- package/dist/commands/cabinet/obliterate.js +82 -82
- package/dist/commands/cli.d.ts +10 -10
- package/dist/commands/cli.js +99 -99
- package/dist/commands/commit.d.ts +11 -11
- package/dist/commands/commit.js +39 -39
- package/dist/commands/config/add.d.ts +78 -78
- package/dist/commands/config/add.js +559 -559
- package/dist/commands/config/delete.d.ts +18 -18
- package/dist/commands/config/delete.js +118 -118
- package/dist/commands/config/deploy.d.ts +22 -22
- package/dist/commands/config/deploy.js +124 -124
- package/dist/commands/config/import.d.ts +27 -27
- package/dist/commands/config/import.js +195 -195
- package/dist/commands/config/view.d.ts +25 -25
- package/dist/commands/config/view.js +120 -120
- package/dist/commands/csp/login.d.ts +18 -18
- package/dist/commands/csp/login.js +122 -122
- package/dist/commands/csp/logout.d.ts +15 -15
- package/dist/commands/csp/logout.js +73 -73
- package/dist/commands/dep/create.d.ts +13 -13
- package/dist/commands/dep/create.js +40 -40
- package/dist/commands/dep/install.d.ts +9 -9
- package/dist/commands/dep/install.js +29 -29
- package/dist/commands/dep/list.d.ts +55 -55
- package/dist/commands/dep/list.js +97 -97
- package/dist/commands/dep/remove.d.ts +12 -12
- package/dist/commands/dep/remove.js +61 -61
- package/dist/commands/dep/source.d.ts +13 -13
- package/dist/commands/dep/source.js +82 -82
- package/dist/commands/dep/syncup.d.ts +11 -11
- package/dist/commands/dep/syncup.js +53 -53
- package/dist/commands/dep/unsource.d.ts +14 -14
- package/dist/commands/dep/unsource.js +67 -67
- package/dist/commands/dep/upgrade.d.ts +44 -44
- package/dist/commands/dep/upgrade.js +243 -243
- package/dist/commands/dep.d.ts +12 -12
- package/dist/commands/dep.js +50 -50
- package/dist/commands/deploy.d.ts +38 -38
- package/dist/commands/deploy.js +385 -385
- package/dist/commands/enterprise/create.d.ts +20 -20
- package/dist/commands/enterprise/create.js +97 -97
- package/dist/commands/enterprise/list.d.ts +14 -14
- package/dist/commands/enterprise/list.js +83 -83
- package/dist/commands/env/add.d.ts +22 -22
- package/dist/commands/env/add.js +199 -199
- package/dist/commands/environment/create.d.ts +19 -19
- package/dist/commands/environment/create.js +88 -88
- package/dist/commands/environment/list.d.ts +25 -25
- package/dist/commands/environment/list.js +157 -157
- package/dist/commands/filestore/capture.d.ts +31 -31
- package/dist/commands/filestore/capture.js +341 -341
- package/dist/commands/host/map.d.ts +33 -33
- package/dist/commands/host/map.js +346 -346
- package/dist/commands/identity/delete.d.ts +15 -15
- package/dist/commands/identity/delete.js +82 -82
- package/dist/commands/identity/list.d.ts +11 -11
- package/dist/commands/identity/list.js +42 -42
- package/dist/commands/identity.d.ts +22 -22
- package/dist/commands/identity.js +76 -76
- package/dist/commands/imageRegistry/capture.d.ts +27 -27
- package/dist/commands/imageRegistry/capture.js +159 -159
- package/dist/commands/imageRegistry/forget.d.ts +23 -23
- package/dist/commands/imageRegistry/forget.js +160 -160
- package/dist/commands/imageRegistry/pullSecret/set.d.ts +27 -27
- package/dist/commands/imageRegistry/pullSecret/set.js +299 -299
- package/dist/commands/imageRegistry/pullSecret/unset.d.ts +24 -24
- package/dist/commands/imageRegistry/pullSecret/unset.js +242 -242
- package/dist/commands/images/add.d.ts +25 -25
- package/dist/commands/images/add.js +75 -75
- package/dist/commands/images/list.d.ts +14 -14
- package/dist/commands/images/list.js +71 -71
- package/dist/commands/images/patch.d.ts +14 -14
- package/dist/commands/images/patch.js +92 -92
- package/dist/commands/images/remove.d.ts +12 -12
- package/dist/commands/images/remove.js +37 -37
- package/dist/commands/images/version/bump.d.ts +18 -18
- package/dist/commands/images/version/bump.js +60 -60
- package/dist/commands/images/version.d.ts +16 -16
- package/dist/commands/images/version.js +64 -64
- package/dist/commands/init.d.ts +17 -17
- package/dist/commands/init.js +130 -130
- package/dist/commands/kit/create.d.ts +25 -25
- package/dist/commands/kit/create.js +141 -141
- package/dist/commands/login.d.ts +22 -22
- package/dist/commands/login.js +92 -92
- package/dist/commands/logout.d.ts +8 -8
- package/dist/commands/logout.js +36 -36
- package/dist/commands/merge.d.ts +12 -12
- package/dist/commands/merge.js +42 -42
- package/dist/commands/noc/cluster/create.d.ts +28 -28
- package/dist/commands/noc/cluster/create.js +132 -132
- package/dist/commands/noc/cluster/deinit.d.ts +17 -17
- package/dist/commands/noc/cluster/deinit.js +116 -116
- package/dist/commands/noc/cluster/destroy.d.ts +20 -20
- package/dist/commands/noc/cluster/destroy.js +137 -137
- package/dist/commands/noc/cluster/forget.d.ts +16 -16
- package/dist/commands/noc/cluster/forget.js +136 -136
- package/dist/commands/noc/cluster/grant.d.ts +24 -24
- package/dist/commands/noc/cluster/grant.js +159 -159
- package/dist/commands/noc/cluster/init.d.ts +17 -17
- package/dist/commands/noc/cluster/init.js +116 -116
- package/dist/commands/noc/cluster/list.d.ts +21 -21
- package/dist/commands/noc/cluster/list.js +83 -83
- package/dist/commands/noc/cluster/recreate.d.ts +28 -28
- package/dist/commands/noc/cluster/recreate.js +185 -185
- package/dist/commands/pkg/add.d.ts +15 -15
- package/dist/commands/pkg/add.js +42 -42
- package/dist/commands/pkg/list.d.ts +9 -9
- package/dist/commands/pkg/list.js +32 -32
- package/dist/commands/pkg/patch.d.ts +13 -13
- package/dist/commands/pkg/patch.js +78 -78
- package/dist/commands/pkg/remove.d.ts +12 -12
- package/dist/commands/pkg/remove.js +69 -69
- package/dist/commands/portal.d.ts +11 -11
- package/dist/commands/portal.js +81 -81
- package/dist/commands/publish.d.ts +21 -21
- package/dist/commands/publish.js +51 -51
- package/dist/commands/pull.d.ts +13 -13
- package/dist/commands/pull.js +29 -29
- package/dist/commands/push.d.ts +13 -13
- package/dist/commands/push.js +29 -29
- package/dist/commands/run.d.ts +35 -35
- package/dist/commands/run.js +193 -193
- package/dist/commands/secretStore/capture.d.ts +27 -27
- package/dist/commands/secretStore/capture.js +174 -174
- package/dist/commands/secretStore/forget.d.ts +20 -20
- package/dist/commands/secretStore/forget.js +146 -146
- package/dist/commands/stage.d.ts +13 -13
- package/dist/commands/stage.js +64 -64
- package/dist/commands/stash.d.ts +13 -13
- package/dist/commands/stash.js +30 -30
- package/dist/commands/status.d.ts +12 -12
- package/dist/commands/status.js +48 -48
- package/dist/commands/stop.d.ts +10 -10
- package/dist/commands/stop.js +51 -51
- package/dist/commands/switch.d.ts +11 -11
- package/dist/commands/switch.js +41 -41
- package/dist/commands/sync.d.ts +14 -14
- package/dist/commands/sync.js +20 -20
- package/dist/commands/tenant/create.d.ts +27 -27
- package/dist/commands/tenant/create.js +119 -119
- package/dist/commands/tenant/switch.d.ts +24 -24
- package/dist/commands/tenant/switch.js +108 -108
- package/dist/commands/unstage.d.ts +12 -12
- package/dist/commands/unstage.js +57 -57
- package/dist/commands/whereami.d.ts +15 -15
- package/dist/commands/whereami.js +122 -122
- package/dist/commands/whoami.d.ts +8 -8
- package/dist/commands/whoami.js +39 -39
- package/dist/errors/NoMembershipError.d.ts +8 -8
- package/dist/errors/NoMembershipError.js +14 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -16
- package/dist/log-update-wrapper.d.ts +24 -24
- package/dist/log-update-wrapper.js +28 -28
- package/dist/log4js-logger.d.ts +26 -26
- package/dist/log4js-logger.js +137 -137
- package/dist/ops/INTERFACES_CLI.d.ts +3 -3
- package/dist/ops/INTERFACES_CLI.js +7 -7
- package/dist/ops/LocalOps.d.ts +417 -417
- package/dist/ops/LocalOps.js +3121 -3121
- package/dist/ops/azure-container-registry-client/azure-container-registry-client.js +147 -147
- package/dist/ops/cli-path-walker.js +54 -54
- package/dist/ops/codiac-entities/dependency.d.ts +5 -5
- package/dist/ops/codiac-entities/dependency.js +10 -10
- package/dist/ops/codiac-entities/index.d.ts +1 -1
- package/dist/ops/codiac-entities/index.js +4 -4
- package/dist/ops/composite-image-registry-client.js +73 -73
- package/dist/ops/data/cli-context-repo.d.ts +61 -61
- package/dist/ops/data/cli-context-repo.js +269 -269
- package/dist/ops/data/index.d.ts +2 -2
- package/dist/ops/data/index.js +5 -5
- package/dist/ops/data/npm-config-repo.d.ts +13 -13
- package/dist/ops/data/npm-config-repo.js +64 -64
- package/dist/ops/docker-config.js +130 -130
- package/dist/ops/docker-constants.js +21 -21
- package/dist/ops/docker-credentials-store.js +237 -237
- package/dist/ops/docker-registry-api-client/docker-registry-api-client.js +288 -288
- package/dist/ops/docker-registry-api-client/entities/blob-sum.d.ts +7 -7
- package/dist/ops/docker-registry-api-client/entities/blob-sum.js +12 -12
- package/dist/ops/docker-registry-api-client/entities/docker-access-actions-enum.d.ts +5 -5
- package/dist/ops/docker-registry-api-client/entities/docker-access-actions-enum.js +9 -9
- package/dist/ops/docker-registry-api-client/entities/docker-auth-token-criteria.d.ts +30 -30
- package/dist/ops/docker-registry-api-client/entities/docker-auth-token-criteria.js +35 -35
- package/dist/ops/docker-registry-api-client/entities/i-docker-error-response.d.ts +55 -55
- package/dist/ops/docker-registry-api-client/entities/i-docker-error-response.js +51 -51
- package/dist/ops/docker-registry-api-client/entities/i-docker-list-response.d.ts +7 -7
- package/dist/ops/docker-registry-api-client/entities/i-docker-list-response.js +2 -2
- package/dist/ops/docker-registry-api-client/entities/image-repository.d.ts +31 -31
- package/dist/ops/docker-registry-api-client/entities/image-repository.js +29 -29
- package/dist/ops/docker-registry-api-client/entities/image-tag-criteria.d.ts +8 -8
- package/dist/ops/docker-registry-api-client/entities/image-tag-criteria.js +13 -13
- package/dist/ops/docker-registry-api-client/entities/image-tag-list.d.ts +7 -7
- package/dist/ops/docker-registry-api-client/entities/image-tag-list.js +12 -12
- package/dist/ops/docker-registry-api-client/entities/manifest-criteria.d.ts +9 -9
- package/dist/ops/docker-registry-api-client/entities/manifest-criteria.js +14 -14
- package/dist/ops/docker-registry-api-client/entities/manifest.d.ts +15 -15
- package/dist/ops/docker-registry-api-client/entities/manifest.js +20 -20
- package/dist/ops/docker-registry-api-client/entities/repository-criteria.d.ts +16 -16
- package/dist/ops/docker-registry-api-client/entities/repository-criteria.js +23 -23
- package/dist/ops/docker-registry-api-client/entities/token-response.d.ts +15 -15
- package/dist/ops/docker-registry-api-client/entities/token-response.js +14 -14
- package/dist/ops/docker-registry-api-client/entities/token.d.ts +17 -17
- package/dist/ops/docker-registry-api-client/entities/token.js +21 -21
- package/dist/ops/docker-registry-api-client/entities/version-check-criteria.d.ts +4 -4
- package/dist/ops/docker-registry-api-client/entities/version-check-criteria.js +9 -9
- package/dist/ops/dx-constants.d.ts +26 -26
- package/dist/ops/dx-constants.js +42 -42
- package/dist/ops/entities/ImageBuildContext.d.ts +12 -12
- package/dist/ops/entities/ImageBuildContext.js +18 -18
- package/dist/ops/entities/PipelineContext.d.ts +21 -21
- package/dist/ops/entities/PipelineContext.js +22 -22
- package/dist/ops/entities/TenantContext.d.ts +10 -10
- package/dist/ops/entities/TenantContext.js +15 -15
- package/dist/ops/entities/ThaulConfig.js +29 -29
- package/dist/ops/entities/azure-service-principal.d.ts +23 -23
- package/dist/ops/entities/azure-service-principal.js +23 -23
- package/dist/ops/entities/better-logger.js +1 -1
- package/dist/ops/entities/branch.d.ts +13 -13
- package/dist/ops/entities/branch.js +15 -15
- package/dist/ops/entities/cli-config.d.ts +48 -48
- package/dist/ops/entities/cli-config.js +60 -60
- package/dist/ops/entities/docker-image.d.ts +60 -60
- package/dist/ops/entities/docker-image.js +2 -2
- package/dist/ops/entities/helm-spec.d.ts +15 -15
- package/dist/ops/entities/helm-spec.js +22 -22
- package/dist/ops/entities/index.d.ts +4 -4
- package/dist/ops/entities/index.js +11 -11
- package/dist/ops/entities/operation-meta.d.ts +8 -8
- package/dist/ops/entities/operation-meta.js +18 -18
- package/dist/ops/entities/scaffolding.d.ts +19 -19
- package/dist/ops/entities/scaffolding.js +20 -20
- package/dist/ops/extensions/azart-identity-adapter.d.ts +19 -19
- package/dist/ops/extensions/azart-identity-adapter.js +96 -96
- package/dist/ops/extensions/npm-identity-adapter-base.d.ts +13 -13
- package/dist/ops/extensions/npm-identity-adapter-base.js +2 -2
- package/dist/ops/extensions/npmjs-identity-adapter.d.ts +13 -13
- package/dist/ops/extensions/npmjs-identity-adapter.js +63 -63
- package/dist/ops/git-ops.d.ts +8 -8
- package/dist/ops/git-ops.js +13 -13
- package/dist/ops/i-client-for-image-registry.js +16 -16
- package/dist/ops/i-identity-handler.d.ts +33 -33
- package/dist/ops/i-identity-handler.js +164 -164
- package/dist/ops/i-output-styler.js +16 -16
- package/dist/ops/index.d.ts +12 -12
- package/dist/ops/index.js +14 -14
- package/dist/ops/json-utils.js +58 -58
- package/dist/ops/no-style-output-styler.js +29 -29
- package/dist/ops/oauth2-client.ts/oauth2-client.d.ts +23 -23
- package/dist/ops/oauth2-client.ts/oauth2-client.js +63 -63
- package/dist/ops/project-initializer.d.ts +36 -36
- package/dist/ops/project-initializer.js +218 -218
- package/dist/ops/scaffolding/base-scaffolding.d.ts +7 -7
- package/dist/ops/scaffolding/base-scaffolding.js +20 -20
- package/dist/ops/scaffolding/codiac-api-scaffolding.d.ts +7 -7
- package/dist/ops/scaffolding/codiac-api-scaffolding.js +63 -63
- package/dist/ops/scaffolding/typescript-scaffolding.d.ts +15 -15
- package/dist/ops/scaffolding/typescript-scaffolding.js +162 -162
- package/dist/ops/test/mock-ui.d.ts +26 -26
- package/dist/ops/test/mock-ui.js +87 -87
- package/dist/ops/test/test-extensions.d.ts +13 -13
- package/dist/ops/test/test-extensions.js +70 -70
- package/dist/ops/test/when-a-recursive-file-search-is-run.spec.d.ts +2 -2
- package/dist/ops/test/when-a-recursive-file-search-is-run.spec.js +54 -54
- package/dist/ops/test/when-git-branchline-is-attempted.spec.d.ts +2 -2
- package/dist/ops/test/when-git-branchline-is-attempted.spec.js +37 -37
- package/dist/ops/test/when-versions-are-parsed.spec.d.ts +2 -2
- package/dist/ops/test/when-versions-are-parsed.spec.js +61 -61
- package/dist/ops/throwing-user-input-provider.js +36 -36
- package/dist/ops/workspace-versioner.d.ts +122 -122
- package/dist/ops/workspace-versioner.js +291 -291
- package/dist/prettify.d.ts +7 -7
- package/dist/prettify.js +23 -23
- package/dist/read-stdin.d.ts +2 -2
- package/dist/read-stdin.js +28 -28
- package/dist/relay/contracts/contracts.d.ts +207 -207
- package/dist/relay/contracts/contracts.js +229 -229
- package/dist/relay/extended-relay-client.d.ts +27 -27
- package/dist/relay/extended-relay-client.js +27 -27
- package/dist/relay/relay-container.d.ts +41 -41
- package/dist/relay/relay-container.js +297 -297
- package/dist/relay/wsclient/relay-socket-listener.d.ts +68 -68
- package/dist/relay/wsclient/relay-socket-listener.js +164 -164
- package/dist/relay/wsclient/relay-websocket-client.d.ts +33 -33
- package/dist/relay/wsclient/relay-websocket-client.js +178 -178
- package/dist/relay/wsclient/rx-websocket-subject.d.ts +25 -25
- package/dist/relay/wsclient/rx-websocket-subject.js +133 -133
- package/dist/relay/wsclient/socket-contracts.d.ts +22 -22
- package/dist/relay/wsclient/socket-contracts.js +2 -2
- package/dist/standard-probes.d.ts +5 -5
- package/dist/standard-probes.js +21 -21
- package/dist/uilogic/build-configurator.d.ts +21 -21
- package/dist/uilogic/build-configurator.js +110 -110
- package/dist/uilogic/cloud-provider-contextualizer.d.ts +46 -46
- package/dist/uilogic/cloud-provider-contextualizer.js +193 -193
- package/dist/uilogic/cloud-resource-configurator-factory.d.ts +41 -41
- package/dist/uilogic/cloud-resource-configurator-factory.js +157 -157
- package/dist/uilogic/cloud-resource-configurators/aws-resource-configurator.d.ts +38 -38
- package/dist/uilogic/cloud-resource-configurators/aws-resource-configurator.js +347 -347
- package/dist/uilogic/cloud-resource-configurators/az-acr-cli-authenticator.js +77 -77
- package/dist/uilogic/cloud-resource-configurators/az-interactive-login-configurator.d.ts +42 -42
- package/dist/uilogic/cloud-resource-configurators/az-interactive-login-configurator.js +247 -247
- package/dist/uilogic/cloud-resource-configurators/azure-resource-configurator.d.ts +110 -110
- package/dist/uilogic/cloud-resource-configurators/azure-resource-configurator.js +781 -781
- package/dist/uilogic/cloud-resource-configurators/azure-types.js +9 -9
- package/dist/uilogic/cloud-resource-configurators/docker-hub-resource-configurator.d.ts +24 -24
- package/dist/uilogic/cloud-resource-configurators/docker-hub-resource-configurator.js +105 -105
- package/dist/uilogic/cloud-resource-configurators/helm-resource-configurator.d.ts +16 -16
- package/dist/uilogic/cloud-resource-configurators/helm-resource-configurator.js +44 -44
- package/dist/uilogic/cloud-resource-configurators/unsupported-resource-configurator.d.ts +18 -18
- package/dist/uilogic/cloud-resource-configurators/unsupported-resource-configurator.js +61 -61
- package/dist/uilogic/enterprise-contextualizer.d.ts +76 -76
- package/dist/uilogic/enterprise-contextualizer.js +670 -670
- package/dist/uilogic/environment-contextualizer.d.ts +15 -15
- package/dist/uilogic/environment-contextualizer.js +42 -42
- package/dist/uilogic/i-cluster-configurator.d.ts +9 -9
- package/dist/uilogic/i-cluster-configurator.js +2 -2
- package/dist/uilogic/i-login-configurator.d.ts +6 -6
- package/dist/uilogic/i-login-configurator.js +2 -2
- package/dist/uilogic/i-registry-configurator.d.ts +6 -6
- package/dist/uilogic/i-registry-configurator.js +2 -2
- package/dist/uilogic/i-secret-store-configurator.d.ts +7 -7
- package/dist/uilogic/i-secret-store-configurator.js +2 -2
- package/dist/uilogic/image-configurator.d.ts +133 -133
- package/dist/uilogic/image-configurator.js +577 -577
- package/dist/uilogic/image-contextualizer.d.ts +24 -24
- package/dist/uilogic/image-contextualizer.js +89 -89
- package/dist/uilogic/image-registry-contextualizer.d.ts +28 -28
- package/dist/uilogic/image-registry-contextualizer.js +126 -126
- package/dist/uilogic/index.d.ts +9 -9
- package/dist/uilogic/index.js +13 -13
- package/dist/uilogic/prompt-select-fuzzy.js +138 -138
- package/dist/uilogic/render-methods.d.ts +12 -12
- package/dist/uilogic/render-methods.js +64 -64
- package/dist/uilogic/tenant-contextualizer.d.ts +79 -79
- package/dist/uilogic/tenant-contextualizer.js +577 -577
- package/dist/user-context-loader.d.ts +60 -60
- package/dist/user-context-loader.js +183 -183
- package/lib/api-command-base.d.ts +0 -0
- package/lib/api-command-base.js +52 -0
- package/lib/api-command-base.js.map +1 -0
- package/lib/apis/codiac-api/common/api-client-base.d.ts +165 -0
- package/lib/apis/codiac-api/common/api-client-base.js +548 -0
- package/lib/apis/codiac-api/common/api-client-base.js.map +1 -0
- package/lib/apis/codiac-api/common/api-user-creds.d.ts +7 -0
- package/lib/apis/codiac-api/common/api-user-creds.js +19 -0
- package/lib/apis/codiac-api/common/api-user-creds.js.map +1 -0
- package/lib/apis/codiac-api/common/config-loader.d.ts +6 -0
- package/lib/apis/codiac-api/common/config-loader.js +19 -0
- package/lib/apis/codiac-api/common/config-loader.js.map +1 -0
- package/lib/apis/codiac-api/common/endpoint-spec.d.ts +17 -0
- package/lib/apis/codiac-api/common/endpoint-spec.js +28 -0
- package/lib/apis/codiac-api/common/endpoint-spec.js.map +1 -0
- package/lib/apis/codiac-api/common/security/api-auth-methods-legacy.d.ts +87 -0
- package/lib/apis/codiac-api/common/security/api-auth-methods-legacy.js +368 -0
- package/lib/apis/codiac-api/common/security/api-auth-methods-legacy.js.map +1 -0
- package/lib/apis/codiac-api/common/security/auth-constants.d.ts +15 -0
- package/lib/apis/codiac-api/common/security/auth-constants.js +22 -0
- package/lib/apis/codiac-api/common/security/auth-constants.js.map +1 -0
- package/lib/apis/codiac-api/common/security/i-auth-client.d.ts +44 -0
- package/lib/apis/codiac-api/common/security/i-auth-client.js +3 -0
- package/lib/apis/codiac-api/common/security/i-auth-client.js.map +1 -0
- package/lib/apis/codiac-api/common/security/token-holder.d.ts +13 -0
- package/lib/apis/codiac-api/common/security/token-holder.js +18 -0
- package/lib/apis/codiac-api/common/security/token-holder.js.map +1 -0
- package/lib/apis/codiac-api/common/utils.d.ts +23 -0
- package/lib/apis/codiac-api/common/utils.js +83 -0
- package/lib/apis/codiac-api/common/utils.js.map +1 -0
- package/lib/apis/codiac-api/contracts/index.d.ts +1 -0
- package/lib/apis/codiac-api/contracts/index.js +5 -0
- package/lib/apis/codiac-api/contracts/index.js.map +1 -0
- package/lib/apis/codiac-api/gen/client-config.d.ts +10 -0
- package/lib/apis/codiac-api/gen/client-config.js +29 -0
- package/lib/apis/codiac-api/gen/client-config.js.map +1 -0
- package/lib/apis/codiac-api/gen/client.d.ts +1663 -0
- package/lib/apis/codiac-api/gen/client.js +15630 -0
- package/lib/apis/codiac-api/gen/client.js.map +1 -0
- package/lib/apis/codiac-api/gen/contracts.d.ts +2722 -0
- package/lib/apis/codiac-api/gen/contracts.js +403 -0
- package/lib/apis/codiac-api/gen/contracts.js.map +1 -0
- package/lib/apis/codiac-api/index.d.ts +3 -0
- package/lib/apis/codiac-api/index.js +9 -0
- package/lib/apis/codiac-api/index.js.map +1 -0
- package/lib/apis/codiac-relay/common/api-client-base.d.ts +165 -0
- package/lib/apis/codiac-relay/common/api-client-base.js +548 -0
- package/lib/apis/codiac-relay/common/api-client-base.js.map +1 -0
- package/lib/apis/codiac-relay/common/api-user-creds.d.ts +7 -0
- package/lib/apis/codiac-relay/common/api-user-creds.js +19 -0
- package/lib/apis/codiac-relay/common/api-user-creds.js.map +1 -0
- package/lib/apis/codiac-relay/common/config-loader.d.ts +6 -0
- package/lib/apis/codiac-relay/common/config-loader.js +19 -0
- package/lib/apis/codiac-relay/common/config-loader.js.map +1 -0
- package/lib/apis/codiac-relay/common/endpoint-spec.d.ts +17 -0
- package/lib/apis/codiac-relay/common/endpoint-spec.js +28 -0
- package/lib/apis/codiac-relay/common/endpoint-spec.js.map +1 -0
- package/lib/apis/codiac-relay/common/security/api-auth-methods-legacy.d.ts +87 -0
- package/lib/apis/codiac-relay/common/security/api-auth-methods-legacy.js +368 -0
- package/lib/apis/codiac-relay/common/security/api-auth-methods-legacy.js.map +1 -0
- package/lib/apis/codiac-relay/common/security/auth-constants.d.ts +15 -0
- package/lib/apis/codiac-relay/common/security/auth-constants.js +22 -0
- package/lib/apis/codiac-relay/common/security/auth-constants.js.map +1 -0
- package/lib/apis/codiac-relay/common/security/i-auth-client.d.ts +44 -0
- package/lib/apis/codiac-relay/common/security/i-auth-client.js +3 -0
- package/lib/apis/codiac-relay/common/security/i-auth-client.js.map +1 -0
- package/lib/apis/codiac-relay/common/security/token-holder.d.ts +13 -0
- package/lib/apis/codiac-relay/common/security/token-holder.js +18 -0
- package/lib/apis/codiac-relay/common/security/token-holder.js.map +1 -0
- package/lib/apis/codiac-relay/common/utils.d.ts +23 -0
- package/lib/apis/codiac-relay/common/utils.js +83 -0
- package/lib/apis/codiac-relay/common/utils.js.map +1 -0
- package/lib/apis/codiac-relay/contracts/index.d.ts +1 -0
- package/lib/apis/codiac-relay/contracts/index.js +5 -0
- package/lib/apis/codiac-relay/contracts/index.js.map +1 -0
- package/lib/apis/codiac-relay/gen/client-config.d.ts +10 -0
- package/lib/apis/codiac-relay/gen/client-config.js +29 -0
- package/lib/apis/codiac-relay/gen/client-config.js.map +1 -0
- package/lib/apis/codiac-relay/gen/client.d.ts +244 -0
- package/lib/apis/codiac-relay/gen/client.js +1863 -0
- package/lib/apis/codiac-relay/gen/client.js.map +1 -0
- package/lib/apis/codiac-relay/gen/contracts.d.ts +3111 -0
- package/lib/apis/codiac-relay/gen/contracts.js +435 -0
- package/lib/apis/codiac-relay/gen/contracts.js.map +1 -0
- package/lib/apis/codiac-relay/index.d.ts +3 -0
- package/lib/apis/codiac-relay/index.js +9 -0
- package/lib/apis/codiac-relay/index.js.map +1 -0
- package/lib/azure-rest-client.d.ts +6 -0
- package/lib/azure-rest-client.js +36 -0
- package/lib/azure-rest-client.js.map +1 -0
- package/lib/cli-common/ImagesList.d.ts +0 -0
- package/lib/cli-common/ImagesList.js +67 -0
- package/lib/cli-common/ImagesList.js.map +1 -0
- package/lib/cli-common/argument-manager.d.ts +28 -0
- package/lib/cli-common/argument-manager.js +195 -0
- package/lib/cli-common/argument-manager.js.map +1 -0
- package/lib/cli-common/built-in-cli-user-input.d.ts +18 -0
- package/lib/cli-common/built-in-cli-user-input.js +310 -0
- package/lib/cli-common/built-in-cli-user-input.js.map +1 -0
- package/lib/cli-common/cli-interfaces.d.ts +0 -0
- package/lib/cli-common/cli-interfaces.js +7 -0
- package/lib/cli-common/cli-interfaces.js.map +1 -0
- package/lib/cli-common/command-base.d.ts +72 -0
- package/lib/cli-common/command-base.js +182 -0
- package/lib/cli-common/command-base.js.map +1 -0
- package/lib/cli-common/entities/index.d.ts +1 -0
- package/lib/cli-common/entities/index.js +5 -0
- package/lib/cli-common/entities/index.js.map +1 -0
- package/lib/cli-common/entities/prompt-choice.d.ts +7 -0
- package/lib/cli-common/entities/prompt-choice.js +3 -0
- package/lib/cli-common/entities/prompt-choice.js.map +1 -0
- package/lib/cli-common/file-selector.d.ts +48 -0
- package/lib/cli-common/file-selector.js +187 -0
- package/lib/cli-common/file-selector.js.map +1 -0
- package/lib/cli-common/i-user-input-provider.d.ts +0 -0
- package/lib/cli-common/i-user-input-provider.js +19 -0
- package/lib/cli-common/i-user-input-provider.js.map +1 -0
- package/lib/cli-common/index.d.ts +4 -0
- package/lib/cli-common/index.js +11 -0
- package/lib/cli-common/index.js.map +1 -0
- package/lib/cli-common/mock-ui.d.ts +27 -0
- package/lib/cli-common/mock-ui.js +83 -0
- package/lib/cli-common/mock-ui.js.map +1 -0
- package/lib/cli-common/prompt-select-fuzzy.d.ts +19 -0
- package/lib/cli-common/prompt-select-fuzzy.js +119 -0
- package/lib/cli-common/prompt-select-fuzzy.js.map +1 -0
- package/lib/cli-common/tenant-contextualizer.d.ts +0 -0
- package/lib/cli-common/tenant-contextualizer.js +436 -0
- package/lib/cli-common/tenant-contextualizer.js.map +1 -0
- package/lib/cli-common/test/tenant-contextualizer.spec.d.ts +0 -0
- package/lib/cli-common/test/tenant-contextualizer.spec.js +143 -0
- package/lib/cli-common/test/tenant-contextualizer.spec.js.map +1 -0
- package/lib/cli-entities/output-format-enum.d.ts +7 -0
- package/lib/cli-entities/output-format-enum.js +12 -0
- package/lib/cli-entities/output-format-enum.js.map +1 -0
- package/lib/cli-entities/prompt-choice.d.ts +0 -0
- package/lib/cli-entities/prompt-choice.js +6 -0
- package/lib/cli-entities/prompt-choice.js.map +1 -0
- package/lib/codiac-constants.d.ts +35 -0
- package/lib/codiac-constants.js +41 -0
- package/lib/codiac-constants.js.map +1 -0
- package/lib/codiac-entities/asset-binding.d.ts +12 -0
- package/lib/codiac-entities/asset-binding.js +18 -0
- package/lib/codiac-entities/asset-binding.js.map +1 -0
- package/lib/codiac-entities/azure-container-registry.d.ts +4 -0
- package/lib/codiac-entities/azure-container-registry.js +3 -0
- package/lib/codiac-entities/azure-container-registry.js.map +1 -0
- package/lib/codiac-entities/azure-service-principal.d.ts +23 -0
- package/lib/codiac-entities/azure-service-principal.js +24 -0
- package/lib/codiac-entities/azure-service-principal.js.map +1 -0
- package/lib/codiac-entities/cloud-account-ref.d.ts +28 -0
- package/lib/codiac-entities/cloud-account-ref.js +37 -0
- package/lib/codiac-entities/cloud-account-ref.js.map +1 -0
- package/lib/codiac-entities/deployment-temp.d.ts +0 -0
- package/lib/codiac-entities/deployment-temp.js +133 -0
- package/lib/codiac-entities/deployment-temp.js.map +1 -0
- package/lib/codiac-entities/i-cloud-account-ref.d.ts +5 -0
- package/lib/codiac-entities/i-cloud-account-ref.js +3 -0
- package/lib/codiac-entities/i-cloud-account-ref.js.map +1 -0
- package/lib/command-base-enterprise.d.ts +121 -0
- package/lib/command-base-enterprise.js +524 -0
- package/lib/command-base-enterprise.js.map +1 -0
- package/lib/command-base-tenantless.d.ts +44 -0
- package/lib/command-base-tenantless.js +180 -0
- package/lib/command-base-tenantless.js.map +1 -0
- package/lib/commands/asset/create.d.ts +42 -0
- package/lib/commands/asset/create.js +467 -0
- package/lib/commands/asset/create.js.map +1 -0
- package/lib/commands/asset/destroy.d.ts +20 -0
- package/lib/commands/asset/destroy.js +129 -0
- package/lib/commands/asset/destroy.js.map +1 -0
- package/lib/commands/asset/helm.d.ts +23 -0
- package/lib/commands/asset/helm.js +153 -0
- package/lib/commands/asset/helm.js.map +1 -0
- package/lib/commands/asset/list.d.ts +28 -0
- package/lib/commands/asset/list.js +172 -0
- package/lib/commands/asset/list.js.map +1 -0
- package/lib/commands/asset/probe/create.d.ts +38 -0
- package/lib/commands/asset/probe/create.js +187 -0
- package/lib/commands/asset/probe/create.js.map +1 -0
- package/lib/commands/asset/recycle.d.ts +23 -0
- package/lib/commands/asset/recycle.js +175 -0
- package/lib/commands/asset/recycle.js.map +1 -0
- package/lib/commands/asset/view.d.ts +188 -0
- package/lib/commands/asset/view.js +1365 -0
- package/lib/commands/asset/view.js.map +1 -0
- package/lib/commands/asset/volume/create.d.ts +23 -0
- package/lib/commands/asset/volume/create.js +176 -0
- package/lib/commands/asset/volume/create.js.map +1 -0
- package/lib/commands/asset/volume/delete.d.ts +19 -0
- package/lib/commands/asset/volume/delete.js +112 -0
- package/lib/commands/asset/volume/delete.js.map +1 -0
- package/lib/commands/asset/volume/list.d.ts +19 -0
- package/lib/commands/asset/volume/list.js +70 -0
- package/lib/commands/asset/volume/list.js.map +1 -0
- package/lib/commands/branch/current.d.ts +10 -0
- package/lib/commands/branch/current.js +34 -0
- package/lib/commands/branch/current.js.map +1 -0
- package/lib/commands/branch/list.d.ts +15 -0
- package/lib/commands/branch/list.js +56 -0
- package/lib/commands/branch/list.js.map +1 -0
- package/lib/commands/branch.d.ts +12 -0
- package/lib/commands/branch.js +42 -0
- package/lib/commands/branch.js.map +1 -0
- package/lib/commands/build.d.ts +38 -0
- package/lib/commands/build.js +120 -0
- package/lib/commands/build.js.map +1 -0
- package/lib/commands/cabinet/create.d.ts +21 -0
- package/lib/commands/cabinet/create.js +108 -0
- package/lib/commands/cabinet/create.js.map +1 -0
- package/lib/commands/cabinet/list.d.ts +23 -0
- package/lib/commands/cabinet/list.js +134 -0
- package/lib/commands/cabinet/list.js.map +1 -0
- package/lib/commands/cabinet/obliterate.d.ts +20 -0
- package/lib/commands/cabinet/obliterate.js +83 -0
- package/lib/commands/cabinet/obliterate.js.map +1 -0
- package/lib/commands/cli.d.ts +10 -0
- package/lib/commands/cli.js +100 -0
- package/lib/commands/cli.js.map +1 -0
- package/lib/commands/commit.d.ts +11 -0
- package/lib/commands/commit.js +40 -0
- package/lib/commands/commit.js.map +1 -0
- package/lib/commands/config/add.d.ts +78 -0
- package/lib/commands/config/add.js +560 -0
- package/lib/commands/config/add.js.map +1 -0
- package/lib/commands/config/delete.d.ts +18 -0
- package/lib/commands/config/delete.js +119 -0
- package/lib/commands/config/delete.js.map +1 -0
- package/lib/commands/config/deploy.d.ts +22 -0
- package/lib/commands/config/deploy.js +125 -0
- package/lib/commands/config/deploy.js.map +1 -0
- package/lib/commands/config/import.d.ts +27 -0
- package/lib/commands/config/import.js +196 -0
- package/lib/commands/config/import.js.map +1 -0
- package/lib/commands/config/view.d.ts +25 -0
- package/lib/commands/config/view.js +121 -0
- package/lib/commands/config/view.js.map +1 -0
- package/lib/commands/csp/login.d.ts +18 -0
- package/lib/commands/csp/login.js +123 -0
- package/lib/commands/csp/login.js.map +1 -0
- package/lib/commands/csp/logout.d.ts +15 -0
- package/lib/commands/csp/logout.js +74 -0
- package/lib/commands/csp/logout.js.map +1 -0
- package/lib/commands/dep/create.d.ts +13 -0
- package/lib/commands/dep/create.js +41 -0
- package/lib/commands/dep/create.js.map +1 -0
- package/lib/commands/dep/install.d.ts +9 -0
- package/lib/commands/dep/install.js +30 -0
- package/lib/commands/dep/install.js.map +1 -0
- package/lib/commands/dep/list.d.ts +55 -0
- package/lib/commands/dep/list.js +98 -0
- package/lib/commands/dep/list.js.map +1 -0
- package/lib/commands/dep/remove.d.ts +12 -0
- package/lib/commands/dep/remove.js +62 -0
- package/lib/commands/dep/remove.js.map +1 -0
- package/lib/commands/dep/source.d.ts +13 -0
- package/lib/commands/dep/source.js +83 -0
- package/lib/commands/dep/source.js.map +1 -0
- package/lib/commands/dep/syncup.d.ts +11 -0
- package/lib/commands/dep/syncup.js +54 -0
- package/lib/commands/dep/syncup.js.map +1 -0
- package/lib/commands/dep/unsource.d.ts +14 -0
- package/lib/commands/dep/unsource.js +68 -0
- package/lib/commands/dep/unsource.js.map +1 -0
- package/lib/commands/dep/upgrade.d.ts +44 -0
- package/lib/commands/dep/upgrade.js +244 -0
- package/lib/commands/dep/upgrade.js.map +1 -0
- package/lib/commands/dep.d.ts +12 -0
- package/lib/commands/dep.js +51 -0
- package/lib/commands/dep.js.map +1 -0
- package/lib/commands/deploy.d.ts +38 -0
- package/lib/commands/deploy.js +386 -0
- package/lib/commands/deploy.js.map +1 -0
- package/lib/commands/enterprise/create.d.ts +20 -0
- package/lib/commands/enterprise/create.js +98 -0
- package/lib/commands/enterprise/create.js.map +1 -0
- package/lib/commands/enterprise/list.d.ts +14 -0
- package/lib/commands/enterprise/list.js +84 -0
- package/lib/commands/enterprise/list.js.map +1 -0
- package/lib/commands/env/add.d.ts +22 -0
- package/lib/commands/env/add.js +200 -0
- package/lib/commands/env/add.js.map +1 -0
- package/lib/commands/environment/create.d.ts +19 -0
- package/lib/commands/environment/create.js +89 -0
- package/lib/commands/environment/create.js.map +1 -0
- package/lib/commands/environment/list.d.ts +25 -0
- package/lib/commands/environment/list.js +158 -0
- package/lib/commands/environment/list.js.map +1 -0
- package/lib/commands/filestore/capture.d.ts +31 -0
- package/lib/commands/filestore/capture.js +342 -0
- package/lib/commands/filestore/capture.js.map +1 -0
- package/lib/commands/host/map.d.ts +33 -0
- package/lib/commands/host/map.js +347 -0
- package/lib/commands/host/map.js.map +1 -0
- package/lib/commands/identity/delete.d.ts +15 -0
- package/lib/commands/identity/delete.js +83 -0
- package/lib/commands/identity/delete.js.map +1 -0
- package/lib/commands/identity/list.d.ts +11 -0
- package/lib/commands/identity/list.js +43 -0
- package/lib/commands/identity/list.js.map +1 -0
- package/lib/commands/identity.d.ts +22 -0
- package/lib/commands/identity.js +77 -0
- package/lib/commands/identity.js.map +1 -0
- package/lib/commands/imageRegistry/capture.d.ts +27 -0
- package/lib/commands/imageRegistry/capture.js +160 -0
- package/lib/commands/imageRegistry/capture.js.map +1 -0
- package/lib/commands/imageRegistry/forget.d.ts +23 -0
- package/lib/commands/imageRegistry/forget.js +161 -0
- package/lib/commands/imageRegistry/forget.js.map +1 -0
- package/lib/commands/imageRegistry/pullSecret/set.d.ts +27 -0
- package/lib/commands/imageRegistry/pullSecret/set.js +300 -0
- package/lib/commands/imageRegistry/pullSecret/set.js.map +1 -0
- package/lib/commands/imageRegistry/pullSecret/unset.d.ts +24 -0
- package/lib/commands/imageRegistry/pullSecret/unset.js +243 -0
- package/lib/commands/imageRegistry/pullSecret/unset.js.map +1 -0
- package/lib/commands/images/add.d.ts +25 -0
- package/lib/commands/images/add.js +76 -0
- package/lib/commands/images/add.js.map +1 -0
- package/lib/commands/images/list.d.ts +14 -0
- package/lib/commands/images/list.js +72 -0
- package/lib/commands/images/list.js.map +1 -0
- package/lib/commands/images/patch.d.ts +14 -0
- package/lib/commands/images/patch.js +93 -0
- package/lib/commands/images/patch.js.map +1 -0
- package/lib/commands/images/remove.d.ts +12 -0
- package/lib/commands/images/remove.js +38 -0
- package/lib/commands/images/remove.js.map +1 -0
- package/lib/commands/images/version/bump.d.ts +18 -0
- package/lib/commands/images/version/bump.js +61 -0
- package/lib/commands/images/version/bump.js.map +1 -0
- package/lib/commands/images/version.d.ts +16 -0
- package/lib/commands/images/version.js +65 -0
- package/lib/commands/images/version.js.map +1 -0
- package/lib/commands/init.d.ts +17 -0
- package/lib/commands/init.js +131 -0
- package/lib/commands/init.js.map +1 -0
- package/lib/commands/kit/create.d.ts +25 -0
- package/lib/commands/kit/create.js +142 -0
- package/lib/commands/kit/create.js.map +1 -0
- package/lib/commands/login.d.ts +22 -0
- package/lib/commands/login.js +93 -0
- package/lib/commands/login.js.map +1 -0
- package/lib/commands/logout.d.ts +8 -0
- package/lib/commands/logout.js +37 -0
- package/lib/commands/logout.js.map +1 -0
- package/lib/commands/merge.d.ts +12 -0
- package/lib/commands/merge.js +43 -0
- package/lib/commands/merge.js.map +1 -0
- package/lib/commands/noc/cluster/create.d.ts +28 -0
- package/lib/commands/noc/cluster/create.js +133 -0
- package/lib/commands/noc/cluster/create.js.map +1 -0
- package/lib/commands/noc/cluster/deinit.d.ts +17 -0
- package/lib/commands/noc/cluster/deinit.js +117 -0
- package/lib/commands/noc/cluster/deinit.js.map +1 -0
- package/lib/commands/noc/cluster/destroy.d.ts +20 -0
- package/lib/commands/noc/cluster/destroy.js +138 -0
- package/lib/commands/noc/cluster/destroy.js.map +1 -0
- package/lib/commands/noc/cluster/forget.d.ts +16 -0
- package/lib/commands/noc/cluster/forget.js +137 -0
- package/lib/commands/noc/cluster/forget.js.map +1 -0
- package/lib/commands/noc/cluster/grant.d.ts +24 -0
- package/lib/commands/noc/cluster/grant.js +160 -0
- package/lib/commands/noc/cluster/grant.js.map +1 -0
- package/lib/commands/noc/cluster/init.d.ts +17 -0
- package/lib/commands/noc/cluster/init.js +117 -0
- package/lib/commands/noc/cluster/init.js.map +1 -0
- package/lib/commands/noc/cluster/list.d.ts +21 -0
- package/lib/commands/noc/cluster/list.js +84 -0
- package/lib/commands/noc/cluster/list.js.map +1 -0
- package/lib/commands/noc/cluster/recreate.d.ts +28 -0
- package/lib/commands/noc/cluster/recreate.js +186 -0
- package/lib/commands/noc/cluster/recreate.js.map +1 -0
- package/lib/commands/pkg/add.d.ts +15 -0
- package/lib/commands/pkg/add.js +43 -0
- package/lib/commands/pkg/add.js.map +1 -0
- package/lib/commands/pkg/list.d.ts +9 -0
- package/lib/commands/pkg/list.js +33 -0
- package/lib/commands/pkg/list.js.map +1 -0
- package/lib/commands/pkg/patch.d.ts +13 -0
- package/lib/commands/pkg/patch.js +79 -0
- package/lib/commands/pkg/patch.js.map +1 -0
- package/lib/commands/pkg/remove.d.ts +12 -0
- package/lib/commands/pkg/remove.js +70 -0
- package/lib/commands/pkg/remove.js.map +1 -0
- package/lib/commands/portal.d.ts +11 -0
- package/lib/commands/portal.js +82 -0
- package/lib/commands/portal.js.map +1 -0
- package/lib/commands/publish.d.ts +21 -0
- package/lib/commands/publish.js +52 -0
- package/lib/commands/publish.js.map +1 -0
- package/lib/commands/pull.d.ts +13 -0
- package/lib/commands/pull.js +30 -0
- package/lib/commands/pull.js.map +1 -0
- package/lib/commands/push.d.ts +13 -0
- package/lib/commands/push.js +30 -0
- package/lib/commands/push.js.map +1 -0
- package/lib/commands/run.d.ts +35 -0
- package/lib/commands/run.js +194 -0
- package/lib/commands/run.js.map +1 -0
- package/lib/commands/secretStore/capture.d.ts +27 -0
- package/lib/commands/secretStore/capture.js +175 -0
- package/lib/commands/secretStore/capture.js.map +1 -0
- package/lib/commands/secretStore/forget.d.ts +20 -0
- package/lib/commands/secretStore/forget.js +147 -0
- package/lib/commands/secretStore/forget.js.map +1 -0
- package/lib/commands/stage.d.ts +13 -0
- package/lib/commands/stage.js +65 -0
- package/lib/commands/stage.js.map +1 -0
- package/lib/commands/stash.d.ts +13 -0
- package/lib/commands/stash.js +31 -0
- package/lib/commands/stash.js.map +1 -0
- package/lib/commands/status.d.ts +12 -0
- package/lib/commands/status.js +49 -0
- package/lib/commands/status.js.map +1 -0
- package/lib/commands/stop.d.ts +10 -0
- package/lib/commands/stop.js +52 -0
- package/lib/commands/stop.js.map +1 -0
- package/lib/commands/switch.d.ts +11 -0
- package/lib/commands/switch.js +42 -0
- package/lib/commands/switch.js.map +1 -0
- package/lib/commands/sync.d.ts +14 -0
- package/lib/commands/sync.js +21 -0
- package/lib/commands/sync.js.map +1 -0
- package/lib/commands/tenant/create.d.ts +27 -0
- package/lib/commands/tenant/create.js +120 -0
- package/lib/commands/tenant/create.js.map +1 -0
- package/lib/commands/tenant/switch.d.ts +24 -0
- package/lib/commands/tenant/switch.js +109 -0
- package/lib/commands/tenant/switch.js.map +1 -0
- package/lib/commands/unstage.d.ts +12 -0
- package/lib/commands/unstage.js +58 -0
- package/lib/commands/unstage.js.map +1 -0
- package/lib/commands/view/dashboard.d.ts +17 -0
- package/lib/commands/view/dashboard.js +88 -0
- package/lib/commands/view/dashboard.js.map +1 -0
- package/lib/commands/view/pods.d.ts +14 -0
- package/lib/commands/view/pods.js +88 -0
- package/lib/commands/view/pods.js.map +1 -0
- package/lib/commands/whereami.d.ts +15 -0
- package/lib/commands/whereami.js +123 -0
- package/lib/commands/whereami.js.map +1 -0
- package/lib/commands/whoami.d.ts +8 -0
- package/lib/commands/whoami.js +40 -0
- package/lib/commands/whoami.js.map +1 -0
- package/lib/deployment.d.ts +2 -0
- package/lib/deployment.js +7 -0
- package/lib/deployment.js.map +1 -0
- package/lib/errors/NoMembershipError.d.ts +8 -0
- package/lib/errors/NoMembershipError.js +15 -0
- package/lib/errors/NoMembershipError.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +17 -0
- package/lib/index.js.map +1 -0
- package/lib/k8s-command-base.d.ts +60 -0
- package/lib/k8s-command-base.js +204 -0
- package/lib/k8s-command-base.js.map +1 -0
- package/lib/log-update-wrapper.d.ts +24 -0
- package/lib/log-update-wrapper.js +29 -0
- package/lib/log-update-wrapper.js.map +1 -0
- package/lib/log4js-logger.d.ts +26 -0
- package/lib/log4js-logger.js +138 -0
- package/lib/log4js-logger.js.map +1 -0
- package/lib/ops/INTERFACES_CLI.d.ts +3 -0
- package/lib/ops/INTERFACES_CLI.js +8 -0
- package/lib/ops/INTERFACES_CLI.js.map +1 -0
- package/lib/ops/LocalOps.d.ts +417 -0
- package/lib/ops/LocalOps.js +3122 -0
- package/lib/ops/LocalOps.js.map +1 -0
- package/lib/ops/azure-container-registry-client/azure-container-registry-client.d.ts +0 -0
- package/lib/ops/azure-container-registry-client/azure-container-registry-client.js +148 -0
- package/lib/ops/azure-container-registry-client/azure-container-registry-client.js.map +1 -0
- package/lib/ops/cli-path-walker.d.ts +0 -0
- package/lib/ops/cli-path-walker.js +55 -0
- package/lib/ops/cli-path-walker.js.map +1 -0
- package/lib/ops/codiac-entities/dependency.d.ts +5 -0
- package/lib/ops/codiac-entities/dependency.js +11 -0
- package/lib/ops/codiac-entities/dependency.js.map +1 -0
- package/lib/ops/codiac-entities/index.d.ts +1 -0
- package/lib/ops/codiac-entities/index.js +5 -0
- package/lib/ops/codiac-entities/index.js.map +1 -0
- package/lib/ops/composite-image-registry-client.d.ts +0 -0
- package/lib/ops/composite-image-registry-client.js +74 -0
- package/lib/ops/composite-image-registry-client.js.map +1 -0
- package/lib/ops/data/cli-context-repo.d.ts +61 -0
- package/lib/ops/data/cli-context-repo.js +270 -0
- package/lib/ops/data/cli-context-repo.js.map +1 -0
- package/lib/ops/data/index.d.ts +2 -0
- package/lib/ops/data/index.js +6 -0
- package/lib/ops/data/index.js.map +1 -0
- package/lib/ops/data/npm-config-repo.d.ts +13 -0
- package/lib/ops/data/npm-config-repo.js +65 -0
- package/lib/ops/data/npm-config-repo.js.map +1 -0
- package/lib/ops/docker-config.d.ts +0 -0
- package/lib/ops/docker-config.js +131 -0
- package/lib/ops/docker-config.js.map +1 -0
- package/lib/ops/docker-constants.d.ts +0 -0
- package/lib/ops/docker-constants.js +22 -0
- package/lib/ops/docker-constants.js.map +1 -0
- package/lib/ops/docker-credentials-store.d.ts +0 -0
- package/lib/ops/docker-credentials-store.js +238 -0
- package/lib/ops/docker-credentials-store.js.map +1 -0
- package/lib/ops/docker-registry-api-client/docker-registry-api-client.d.ts +0 -0
- package/lib/ops/docker-registry-api-client/docker-registry-api-client.js +289 -0
- package/lib/ops/docker-registry-api-client/docker-registry-api-client.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/blob-sum.d.ts +7 -0
- package/lib/ops/docker-registry-api-client/entities/blob-sum.js +13 -0
- package/lib/ops/docker-registry-api-client/entities/blob-sum.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/docker-access-actions-enum.d.ts +5 -0
- package/lib/ops/docker-registry-api-client/entities/docker-access-actions-enum.js +10 -0
- package/lib/ops/docker-registry-api-client/entities/docker-access-actions-enum.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/docker-auth-token-criteria.d.ts +30 -0
- package/lib/ops/docker-registry-api-client/entities/docker-auth-token-criteria.js +36 -0
- package/lib/ops/docker-registry-api-client/entities/docker-auth-token-criteria.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/i-docker-error-response.d.ts +55 -0
- package/lib/ops/docker-registry-api-client/entities/i-docker-error-response.js +52 -0
- package/lib/ops/docker-registry-api-client/entities/i-docker-error-response.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/i-docker-list-response.d.ts +7 -0
- package/lib/ops/docker-registry-api-client/entities/i-docker-list-response.js +3 -0
- package/lib/ops/docker-registry-api-client/entities/i-docker-list-response.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/image-repository.d.ts +31 -0
- package/lib/ops/docker-registry-api-client/entities/image-repository.js +30 -0
- package/lib/ops/docker-registry-api-client/entities/image-repository.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/image-tag-criteria.d.ts +8 -0
- package/lib/ops/docker-registry-api-client/entities/image-tag-criteria.js +14 -0
- package/lib/ops/docker-registry-api-client/entities/image-tag-criteria.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/image-tag-list.d.ts +7 -0
- package/lib/ops/docker-registry-api-client/entities/image-tag-list.js +13 -0
- package/lib/ops/docker-registry-api-client/entities/image-tag-list.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/manifest-criteria.d.ts +9 -0
- package/lib/ops/docker-registry-api-client/entities/manifest-criteria.js +15 -0
- package/lib/ops/docker-registry-api-client/entities/manifest-criteria.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/manifest.d.ts +15 -0
- package/lib/ops/docker-registry-api-client/entities/manifest.js +21 -0
- package/lib/ops/docker-registry-api-client/entities/manifest.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/repository-criteria.d.ts +16 -0
- package/lib/ops/docker-registry-api-client/entities/repository-criteria.js +24 -0
- package/lib/ops/docker-registry-api-client/entities/repository-criteria.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/token-response.d.ts +15 -0
- package/lib/ops/docker-registry-api-client/entities/token-response.js +15 -0
- package/lib/ops/docker-registry-api-client/entities/token-response.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/token.d.ts +17 -0
- package/lib/ops/docker-registry-api-client/entities/token.js +22 -0
- package/lib/ops/docker-registry-api-client/entities/token.js.map +1 -0
- package/lib/ops/docker-registry-api-client/entities/version-check-criteria.d.ts +4 -0
- package/lib/ops/docker-registry-api-client/entities/version-check-criteria.js +10 -0
- package/lib/ops/docker-registry-api-client/entities/version-check-criteria.js.map +1 -0
- package/lib/ops/dx-constants.d.ts +26 -0
- package/lib/ops/dx-constants.js +43 -0
- package/lib/ops/dx-constants.js.map +1 -0
- package/lib/ops/entities/ImageBuildContext.d.ts +12 -0
- package/lib/ops/entities/ImageBuildContext.js +19 -0
- package/lib/ops/entities/ImageBuildContext.js.map +1 -0
- package/lib/ops/entities/PipelineContext.d.ts +21 -0
- package/lib/ops/entities/PipelineContext.js +23 -0
- package/lib/ops/entities/PipelineContext.js.map +1 -0
- package/lib/ops/entities/TenantContext.d.ts +10 -0
- package/lib/ops/entities/TenantContext.js +16 -0
- package/lib/ops/entities/TenantContext.js.map +1 -0
- package/lib/ops/entities/ThaulConfig.d.ts +0 -0
- package/lib/ops/entities/ThaulConfig.js +30 -0
- package/lib/ops/entities/ThaulConfig.js.map +1 -0
- package/lib/ops/entities/azure-service-principal.d.ts +23 -0
- package/lib/ops/entities/azure-service-principal.js +24 -0
- package/lib/ops/entities/azure-service-principal.js.map +1 -0
- package/lib/ops/entities/better-logger.d.ts +0 -0
- package/lib/ops/entities/better-logger.js +2 -0
- package/lib/ops/entities/better-logger.js.map +1 -0
- package/lib/ops/entities/branch.d.ts +13 -0
- package/lib/ops/entities/branch.js +16 -0
- package/lib/ops/entities/branch.js.map +1 -0
- package/lib/ops/entities/cli-config.d.ts +48 -0
- package/lib/ops/entities/cli-config.js +61 -0
- package/lib/ops/entities/cli-config.js.map +1 -0
- package/lib/ops/entities/docker-image.d.ts +60 -0
- package/lib/ops/entities/docker-image.js +3 -0
- package/lib/ops/entities/docker-image.js.map +1 -0
- package/lib/ops/entities/helm-spec.d.ts +15 -0
- package/lib/ops/entities/helm-spec.js +23 -0
- package/lib/ops/entities/helm-spec.js.map +1 -0
- package/lib/ops/entities/index.d.ts +4 -0
- package/lib/ops/entities/index.js +12 -0
- package/lib/ops/entities/index.js.map +1 -0
- package/lib/ops/entities/operation-meta.d.ts +8 -0
- package/lib/ops/entities/operation-meta.js +19 -0
- package/lib/ops/entities/operation-meta.js.map +1 -0
- package/lib/ops/entities/scaffolding.d.ts +19 -0
- package/lib/ops/entities/scaffolding.js +21 -0
- package/lib/ops/entities/scaffolding.js.map +1 -0
- package/lib/ops/extensions/azart-identity-adapter.d.ts +19 -0
- package/lib/ops/extensions/azart-identity-adapter.js +97 -0
- package/lib/ops/extensions/azart-identity-adapter.js.map +1 -0
- package/lib/ops/extensions/npm-identity-adapter-base.d.ts +13 -0
- package/lib/ops/extensions/npm-identity-adapter-base.js +3 -0
- package/lib/ops/extensions/npm-identity-adapter-base.js.map +1 -0
- package/lib/ops/extensions/npmjs-identity-adapter.d.ts +13 -0
- package/lib/ops/extensions/npmjs-identity-adapter.js +64 -0
- package/lib/ops/extensions/npmjs-identity-adapter.js.map +1 -0
- package/lib/ops/git-ops.d.ts +8 -0
- package/lib/ops/git-ops.js +14 -0
- package/lib/ops/git-ops.js.map +1 -0
- package/lib/ops/i-client-for-image-registry.d.ts +0 -0
- package/lib/ops/i-client-for-image-registry.js +17 -0
- package/lib/ops/i-client-for-image-registry.js.map +1 -0
- package/lib/ops/i-identity-handler.d.ts +33 -0
- package/lib/ops/i-identity-handler.js +165 -0
- package/lib/ops/i-identity-handler.js.map +1 -0
- package/lib/ops/i-output-styler.d.ts +0 -0
- package/lib/ops/i-output-styler.js +17 -0
- package/lib/ops/i-output-styler.js.map +1 -0
- package/lib/ops/index.d.ts +12 -0
- package/lib/ops/index.js +15 -0
- package/lib/ops/index.js.map +1 -0
- package/lib/ops/json-utils.d.ts +0 -0
- package/lib/ops/json-utils.js +59 -0
- package/lib/ops/json-utils.js.map +1 -0
- package/lib/ops/no-style-output-styler.d.ts +0 -0
- package/lib/ops/no-style-output-styler.js +30 -0
- package/lib/ops/no-style-output-styler.js.map +1 -0
- package/lib/ops/oauth2-client.ts/oauth2-client.d.ts +23 -0
- package/lib/ops/oauth2-client.ts/oauth2-client.js +64 -0
- package/lib/ops/oauth2-client.ts/oauth2-client.js.map +1 -0
- package/lib/ops/project-initializer.d.ts +36 -0
- package/lib/ops/project-initializer.js +219 -0
- package/lib/ops/project-initializer.js.map +1 -0
- package/lib/ops/scaffolding/base-scaffolding.d.ts +7 -0
- package/lib/ops/scaffolding/base-scaffolding.js +21 -0
- package/lib/ops/scaffolding/base-scaffolding.js.map +1 -0
- package/lib/ops/scaffolding/codiac-api-scaffolding.d.ts +7 -0
- package/lib/ops/scaffolding/codiac-api-scaffolding.js +64 -0
- package/lib/ops/scaffolding/codiac-api-scaffolding.js.map +1 -0
- package/lib/ops/scaffolding/typescript-scaffolding.d.ts +15 -0
- package/lib/ops/scaffolding/typescript-scaffolding.js +163 -0
- package/lib/ops/scaffolding/typescript-scaffolding.js.map +1 -0
- package/lib/ops/test/mock-ui.d.ts +26 -0
- package/lib/ops/test/mock-ui.js +88 -0
- package/lib/ops/test/mock-ui.js.map +1 -0
- package/lib/ops/test/test-extensions.d.ts +13 -0
- package/lib/ops/test/test-extensions.js +71 -0
- package/lib/ops/test/test-extensions.js.map +1 -0
- package/lib/ops/test/when-a-recursive-file-search-is-run.spec.d.ts +2 -0
- package/lib/ops/test/when-a-recursive-file-search-is-run.spec.js +55 -0
- package/lib/ops/test/when-a-recursive-file-search-is-run.spec.js.map +1 -0
- package/lib/ops/test/when-git-branchline-is-attempted.spec.d.ts +2 -0
- package/lib/ops/test/when-git-branchline-is-attempted.spec.js +38 -0
- package/lib/ops/test/when-git-branchline-is-attempted.spec.js.map +1 -0
- package/lib/ops/test/when-versions-are-parsed.spec.d.ts +2 -0
- package/lib/ops/test/when-versions-are-parsed.spec.js +62 -0
- package/lib/ops/test/when-versions-are-parsed.spec.js.map +1 -0
- package/lib/ops/throwing-user-input-provider.d.ts +0 -0
- package/lib/ops/throwing-user-input-provider.js +37 -0
- package/lib/ops/throwing-user-input-provider.js.map +1 -0
- package/lib/ops/workspace-versioner.d.ts +122 -0
- package/lib/ops/workspace-versioner.js +292 -0
- package/lib/ops/workspace-versioner.js.map +1 -0
- package/lib/prettify.d.ts +7 -0
- package/lib/prettify.js +24 -0
- package/lib/prettify.js.map +1 -0
- package/lib/read-stdin.d.ts +2 -0
- package/lib/read-stdin.js +29 -0
- package/lib/read-stdin.js.map +1 -0
- package/lib/relay/contracts/contracts.d.ts +207 -0
- package/lib/relay/contracts/contracts.js +230 -0
- package/lib/relay/contracts/contracts.js.map +1 -0
- package/lib/relay/data/aws-k8s-versions.d.ts +6 -0
- package/lib/relay/data/aws-k8s-versions.js +16 -0
- package/lib/relay/data/aws-k8s-versions.js.map +1 -0
- package/lib/relay/data/aws-node-types.d.ts +37 -0
- package/lib/relay/data/aws-node-types.js +4246 -0
- package/lib/relay/data/aws-node-types.js.map +1 -0
- package/lib/relay/data/aws-regions.d.ts +6 -0
- package/lib/relay/data/aws-regions.js +34 -0
- package/lib/relay/data/aws-regions.js.map +1 -0
- package/lib/relay/extended-relay-client.d.ts +27 -0
- package/lib/relay/extended-relay-client.js +28 -0
- package/lib/relay/extended-relay-client.js.map +1 -0
- package/lib/relay/relay-container.d.ts +41 -0
- package/lib/relay/relay-container.js +298 -0
- package/lib/relay/relay-container.js.map +1 -0
- package/lib/relay/wsclient/relay-socket-listener.d.ts +68 -0
- package/lib/relay/wsclient/relay-socket-listener.js +165 -0
- package/lib/relay/wsclient/relay-socket-listener.js.map +1 -0
- package/lib/relay/wsclient/relay-websocket-client.d.ts +33 -0
- package/lib/relay/wsclient/relay-websocket-client.js +179 -0
- package/lib/relay/wsclient/relay-websocket-client.js.map +1 -0
- package/lib/relay/wsclient/rx-websocket-subject.d.ts +25 -0
- package/lib/relay/wsclient/rx-websocket-subject.js +134 -0
- package/lib/relay/wsclient/rx-websocket-subject.js.map +1 -0
- package/lib/relay/wsclient/socket-contracts.d.ts +22 -0
- package/lib/relay/wsclient/socket-contracts.js +3 -0
- package/lib/relay/wsclient/socket-contracts.js.map +1 -0
- package/lib/standard-probes.d.ts +5 -0
- package/lib/standard-probes.js +22 -0
- package/lib/standard-probes.js.map +1 -0
- package/lib/uilogic/build-configurator.d.ts +21 -0
- package/lib/uilogic/build-configurator.js +111 -0
- package/lib/uilogic/build-configurator.js.map +1 -0
- package/lib/uilogic/cloud-provider-contextualizer.d.ts +46 -0
- package/lib/uilogic/cloud-provider-contextualizer.js +194 -0
- package/lib/uilogic/cloud-provider-contextualizer.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurator-factory.d.ts +41 -0
- package/lib/uilogic/cloud-resource-configurator-factory.js +158 -0
- package/lib/uilogic/cloud-resource-configurator-factory.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.d.ts +11 -0
- package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.js +16 -0
- package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/aws-node-types.d.ts +5 -0
- package/lib/uilogic/cloud-resource-configurators/aws-node-types.js +536 -0
- package/lib/uilogic/cloud-resource-configurators/aws-node-types.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/aws-regions.d.ts +10 -0
- package/lib/uilogic/cloud-resource-configurators/aws-regions.js +34 -0
- package/lib/uilogic/cloud-resource-configurators/aws-regions.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/aws-resource-configurator.d.ts +38 -0
- package/lib/uilogic/cloud-resource-configurators/aws-resource-configurator.js +348 -0
- package/lib/uilogic/cloud-resource-configurators/aws-resource-configurator.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/az-acr-cli-authenticator.d.ts +0 -0
- package/lib/uilogic/cloud-resource-configurators/az-acr-cli-authenticator.js +78 -0
- package/lib/uilogic/cloud-resource-configurators/az-acr-cli-authenticator.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/az-interactive-login-configurator.d.ts +42 -0
- package/lib/uilogic/cloud-resource-configurators/az-interactive-login-configurator.js +248 -0
- package/lib/uilogic/cloud-resource-configurators/az-interactive-login-configurator.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/azure-resource-configurator.d.ts +110 -0
- package/lib/uilogic/cloud-resource-configurators/azure-resource-configurator.js +782 -0
- package/lib/uilogic/cloud-resource-configurators/azure-resource-configurator.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/azure-types.d.ts +0 -0
- package/lib/uilogic/cloud-resource-configurators/azure-types.js +10 -0
- package/lib/uilogic/cloud-resource-configurators/azure-types.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/docker-hub-resource-configurator.d.ts +24 -0
- package/lib/uilogic/cloud-resource-configurators/docker-hub-resource-configurator.js +106 -0
- package/lib/uilogic/cloud-resource-configurators/docker-hub-resource-configurator.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/helm-resource-configurator.d.ts +16 -0
- package/lib/uilogic/cloud-resource-configurators/helm-resource-configurator.js +45 -0
- package/lib/uilogic/cloud-resource-configurators/helm-resource-configurator.js.map +1 -0
- package/lib/uilogic/cloud-resource-configurators/unsupported-resource-configurator.d.ts +18 -0
- package/lib/uilogic/cloud-resource-configurators/unsupported-resource-configurator.js +62 -0
- package/lib/uilogic/cloud-resource-configurators/unsupported-resource-configurator.js.map +1 -0
- package/lib/uilogic/enterprise-contextualizer.d.ts +76 -0
- package/lib/uilogic/enterprise-contextualizer.js +671 -0
- package/lib/uilogic/enterprise-contextualizer.js.map +1 -0
- package/lib/uilogic/environment-contextualizer.d.ts +15 -0
- package/lib/uilogic/environment-contextualizer.js +43 -0
- package/lib/uilogic/environment-contextualizer.js.map +1 -0
- package/lib/uilogic/i-cluster-configurator.d.ts +9 -0
- package/lib/uilogic/i-cluster-configurator.js +3 -0
- package/lib/uilogic/i-cluster-configurator.js.map +1 -0
- package/lib/uilogic/i-login-configurator.d.ts +6 -0
- package/lib/uilogic/i-login-configurator.js +3 -0
- package/lib/uilogic/i-login-configurator.js.map +1 -0
- package/lib/uilogic/i-registry-configurator.d.ts +6 -0
- package/lib/uilogic/i-registry-configurator.js +3 -0
- package/lib/uilogic/i-registry-configurator.js.map +1 -0
- package/lib/uilogic/i-secret-store-configurator.d.ts +7 -0
- package/lib/uilogic/i-secret-store-configurator.js +3 -0
- package/lib/uilogic/i-secret-store-configurator.js.map +1 -0
- package/lib/uilogic/image-configurator.d.ts +133 -0
- package/lib/uilogic/image-configurator.js +578 -0
- package/lib/uilogic/image-configurator.js.map +1 -0
- package/lib/uilogic/image-contextualizer.d.ts +24 -0
- package/lib/uilogic/image-contextualizer.js +90 -0
- package/lib/uilogic/image-contextualizer.js.map +1 -0
- package/lib/uilogic/image-registry-contextualizer.d.ts +28 -0
- package/lib/uilogic/image-registry-contextualizer.js +127 -0
- package/lib/uilogic/image-registry-contextualizer.js.map +1 -0
- package/lib/uilogic/index.d.ts +9 -0
- package/lib/uilogic/index.js +14 -0
- package/lib/uilogic/index.js.map +1 -0
- package/lib/uilogic/prompt-select-fuzzy.d.ts +0 -0
- package/lib/uilogic/prompt-select-fuzzy.js +139 -0
- package/lib/uilogic/prompt-select-fuzzy.js.map +1 -0
- package/lib/uilogic/render-methods.d.ts +12 -0
- package/lib/uilogic/render-methods.js +65 -0
- package/lib/uilogic/render-methods.js.map +1 -0
- package/lib/uilogic/tenant-contextualizer.d.ts +79 -0
- package/lib/uilogic/tenant-contextualizer.js +578 -0
- package/lib/uilogic/tenant-contextualizer.js.map +1 -0
- package/lib/user-context-loader.d.ts +60 -0
- package/lib/user-context-loader.js +184 -0
- package/lib/user-context-loader.js.map +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +151 -151
- package/scaffolding/api/.gitignore-scaffolding +68 -68
- package/scaffolding/api/.vscode/launch.json +16 -16
- package/scaffolding/api/.vscode/settings.json +7 -7
- package/scaffolding/api/.vscode/tasks.json +15 -15
- package/scaffolding/api/src/app-config.json +2 -2
- package/scaffolding/api/src/index.ts-scaffolding +13 -13
- package/scaffolding/api/src/myApiDef.ts-scaffolding +25 -25
- package/scaffolding/default/.gitignore-scaffolding +2 -2
- package/scaffolding/typescript/.gitignore-scaffolding +69 -69
- package/scaffolding/typescript/.vscode/launch.json +16 -16
- package/scaffolding/typescript/.vscode/settings.json +7 -7
- package/scaffolding/typescript/.vscode/tasks.json +15 -15
|
@@ -0,0 +1,3122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalOps = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
// Node libs
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
// Third-party libs
|
|
9
|
+
const inversify_1 = require("inversify");
|
|
10
|
+
const figlet = require("figlet");
|
|
11
|
+
const rimraf = require("rimraf");
|
|
12
|
+
const _ = require("lodash");
|
|
13
|
+
const escapeStringRegexp = require("escape-string-regexp");
|
|
14
|
+
const fse = require("fs-extra");
|
|
15
|
+
// Ours
|
|
16
|
+
const codiac_common_1 = require("@codiac.io/codiac-common");
|
|
17
|
+
const IBetterLogger_1 = require("@codiac.io/codiac-common/IBetterLogger");
|
|
18
|
+
const contracts_1 = require("@codiac.io/codiac-common/contracts");
|
|
19
|
+
const codiac_ops_common_1 = require("@codiac.io/codiac-ops-common");
|
|
20
|
+
const codiac_ops_common_2 = require("@codiac.io/codiac-ops-common");
|
|
21
|
+
const codiac_ops_common_3 = require("@codiac.io/codiac-ops-common");
|
|
22
|
+
const codiac_relay_contracts_1 = require("@codiac.io/codiac-relay-contracts");
|
|
23
|
+
const codiac_relay_contracts_2 = require("@codiac.io/codiac-relay-contracts");
|
|
24
|
+
// Used only by DX
|
|
25
|
+
const branch_1 = require("./entities/branch");
|
|
26
|
+
const cli_context_repo_1 = require("./data/cli-context-repo");
|
|
27
|
+
const npm_config_repo_1 = require("./data/npm-config-repo");
|
|
28
|
+
const dx_constants_1 = require("./dx-constants");
|
|
29
|
+
const _1 = require(".");
|
|
30
|
+
const workspace_versioner_1 = require("./workspace-versioner");
|
|
31
|
+
let LocalOps = class LocalOps {
|
|
32
|
+
// constructor(private ioc: Container, public codiacVersion: string, private _projectRoot: string, private _cfgRepo: CliContextRepo, private ux: IUserInputProvider, private styler: IOutputStyler, private logger: IBetterLogger) {
|
|
33
|
+
// this._cliExec = new CliExec(logger);
|
|
34
|
+
// }
|
|
35
|
+
constructor(ioc
|
|
36
|
+
// , @inject(CliEnviro) public cliEnviro: CliEnviro
|
|
37
|
+
// , @inject(ProjectEnviro) private projEnviro: ProjectEnviro
|
|
38
|
+
// , @inject(CliContextRepo) private _cfgRepo: CliContextRepo
|
|
39
|
+
// , @inject(INTERFACES_OPS.IUserInputProvider) private ux: IUserInputProvider
|
|
40
|
+
// , @inject(INTERFACES_OPS.IOutputStyler) private styler: IOutputStyler
|
|
41
|
+
// , @inject(CliExec) private _cliExec: CliExec
|
|
42
|
+
// , @inject(INTERFACES.IBetterLogger) private logger: IBetterLogger
|
|
43
|
+
) {
|
|
44
|
+
this.ioc = ioc;
|
|
45
|
+
this.APP_CONFIG_FILENAME = "app-config.json";
|
|
46
|
+
/** Array of built-in app config keys that are supported by the api framework. */
|
|
47
|
+
this.AVAIL_CONFIG_KEYS_FILENAME = "app-config-keys.json";
|
|
48
|
+
}
|
|
49
|
+
// ====================================================================
|
|
50
|
+
// LAZY-LOADED PROPERTIES
|
|
51
|
+
//
|
|
52
|
+
// public _cliEnviro: CliEnviro | undefined;
|
|
53
|
+
// private _projEnviro: ProjectEnviro | undefined;
|
|
54
|
+
// private __cfgRepo: CliContextRepo | undefined;
|
|
55
|
+
// private _ux: IUserInputProvider | undefined;
|
|
56
|
+
// private _styler: IOutputStyler | undefined;
|
|
57
|
+
// private __cliExec: CliExec | undefined;
|
|
58
|
+
// private _logger: IBetterLogger | undefined;
|
|
59
|
+
//
|
|
60
|
+
// --------------------------------------------------------------------
|
|
61
|
+
get _projectRoot() {
|
|
62
|
+
return this.projEnviro.projectRoot;
|
|
63
|
+
}
|
|
64
|
+
get cliEnviro() {
|
|
65
|
+
if (this._cliEnviro === undefined) {
|
|
66
|
+
this._cliEnviro = this.ioc.get(_1.CliEnviro);
|
|
67
|
+
}
|
|
68
|
+
return this._cliEnviro;
|
|
69
|
+
}
|
|
70
|
+
get projEnviro() {
|
|
71
|
+
if (this._projEnviro === undefined) {
|
|
72
|
+
this._projEnviro = this.ioc.get(_1.ProjectEnviro);
|
|
73
|
+
}
|
|
74
|
+
return this._projEnviro;
|
|
75
|
+
}
|
|
76
|
+
get _projCfgRepo() {
|
|
77
|
+
if (this.__projCfgRepo === undefined) {
|
|
78
|
+
this.__projCfgRepo = this.ioc.get(cli_context_repo_1.ProjectContextRepo);
|
|
79
|
+
}
|
|
80
|
+
return this.__projCfgRepo;
|
|
81
|
+
}
|
|
82
|
+
get _projCfg() {
|
|
83
|
+
if (this.__projCfg === undefined) {
|
|
84
|
+
this.__projCfg = this.ioc.get(codiac_relay_contracts_2.ProjectConfig);
|
|
85
|
+
}
|
|
86
|
+
return this.__projCfg;
|
|
87
|
+
}
|
|
88
|
+
get _projUserCfg() {
|
|
89
|
+
if (this.__projUserCfg === undefined) {
|
|
90
|
+
this.__projUserCfg = this.ioc.get(codiac_relay_contracts_1.ProjectUserConfig);
|
|
91
|
+
}
|
|
92
|
+
return this.__projUserCfg;
|
|
93
|
+
}
|
|
94
|
+
get cliConfig() {
|
|
95
|
+
if (this.__cliConfig === undefined) {
|
|
96
|
+
this.__cliConfig = this.ioc.get(_1.CliConfig);
|
|
97
|
+
}
|
|
98
|
+
return this.__cliConfig;
|
|
99
|
+
}
|
|
100
|
+
get ux() {
|
|
101
|
+
if (this._ux === undefined) {
|
|
102
|
+
this._ux = this.ioc.get(codiac_ops_common_1.INTERFACES_OPS.IUserInputProvider);
|
|
103
|
+
}
|
|
104
|
+
return this._ux;
|
|
105
|
+
}
|
|
106
|
+
get styler() {
|
|
107
|
+
if (this._styler === undefined) {
|
|
108
|
+
this._styler = this.ioc.get(codiac_ops_common_1.INTERFACES_OPS.IOutputStyler);
|
|
109
|
+
}
|
|
110
|
+
return this._styler;
|
|
111
|
+
}
|
|
112
|
+
get _cliExec() {
|
|
113
|
+
if (this.__cliExec === undefined) {
|
|
114
|
+
this.__cliExec = this.ioc.get(codiac_ops_common_2.CliExec);
|
|
115
|
+
}
|
|
116
|
+
return this.__cliExec;
|
|
117
|
+
}
|
|
118
|
+
get logger() {
|
|
119
|
+
if (this._logger === undefined) {
|
|
120
|
+
this._logger = this.ioc.get(codiac_common_1.INTERFACES.IBetterLogger);
|
|
121
|
+
}
|
|
122
|
+
return this._logger;
|
|
123
|
+
}
|
|
124
|
+
get _workspaceVersioner() {
|
|
125
|
+
if (this.__workspaceVersioner === undefined) {
|
|
126
|
+
this.__workspaceVersioner = this.ioc.get(workspace_versioner_1.WorkspaceVersioner);
|
|
127
|
+
}
|
|
128
|
+
return this.__workspaceVersioner;
|
|
129
|
+
}
|
|
130
|
+
// --------------------------------------------------------------------
|
|
131
|
+
// END LAZY-LOADED PROPERTIES
|
|
132
|
+
// ====================================================================
|
|
133
|
+
/** Shows the ascii art product name and the version in the console */
|
|
134
|
+
renderTitleBlock() {
|
|
135
|
+
let title = figlet.textSync('Codiac', 'Slant'); // 'Graffiti')
|
|
136
|
+
let line = '-'.repeat(38);
|
|
137
|
+
this.logger.notice(this.styler.colorGood(line));
|
|
138
|
+
this.logger.notice(this.styler.hilite(title));
|
|
139
|
+
this.logger.notice(`Version ${this.cliEnviro.version} by Codiac LLC`);
|
|
140
|
+
this.logger.notice(this.styler.colorGood(line));
|
|
141
|
+
}
|
|
142
|
+
// /**
|
|
143
|
+
// * Ensures that the current user is logged in against a specific tenant subscription.
|
|
144
|
+
// */
|
|
145
|
+
// public getContext(): void {
|
|
146
|
+
// this.logger.debug('Acquiring context...')
|
|
147
|
+
// // check to see that user is logged in
|
|
148
|
+
// // if (cli.confirm('') tenant
|
|
149
|
+
// }
|
|
150
|
+
/**
|
|
151
|
+
* ***OBSOLETE!!! Use CliPathWalker.getProjectRoot() instead!!***
|
|
152
|
+
*
|
|
153
|
+
* Gets the Toyhauler project root folder
|
|
154
|
+
* that is in scope for the current working directory
|
|
155
|
+
* or the given folder.
|
|
156
|
+
* IMPORTANT: Throws by default when no Toyhauler config file exists up the parent folder chain.
|
|
157
|
+
* @param folder (optional, defaults to current working directory) The folder containing the thaul config file, or any folder underneath that one.
|
|
158
|
+
* @param errorWhenNotFound Setting to false will return an empty string if folder is not contained in a project root.
|
|
159
|
+
*
|
|
160
|
+
* @deprecated Use `CliPathWalker.getProjectRoot()` instead!
|
|
161
|
+
*/
|
|
162
|
+
getConfigRoot(folder, errorWhenNotFound = true) {
|
|
163
|
+
return codiac_ops_common_3.CliPathWalker.getProjectRoot(folder, errorWhenNotFound);
|
|
164
|
+
}
|
|
165
|
+
// /** Deserializes the global Thaul CLI configuration file. */
|
|
166
|
+
// public readCliConfig(): CliConfig|undefined {
|
|
167
|
+
// this.logger.debug(`Reading cli config from: ${path.join(this.cliConfigDir, CliConfig.FILENAME)}`);
|
|
168
|
+
// let config = this.deserializeJsonFile<CliConfig>(path.join(this.cliConfigDir, CliConfig.FILENAME));
|
|
169
|
+
// return config;
|
|
170
|
+
// }
|
|
171
|
+
// /** Serializes the global Thaul CLI configuration object. */
|
|
172
|
+
// public writeCliConfig(config: CliConfig): void {
|
|
173
|
+
// this.serializeJsonFile(config, path.join(this.cliConfigDir, CliConfig.FILENAME));
|
|
174
|
+
// }
|
|
175
|
+
/** Deserializes the Toyhauler config file in scope for the current working directory.
|
|
176
|
+
* Throws if none is defined up the folder tree. */
|
|
177
|
+
readCodiacProjectConfig(folder) {
|
|
178
|
+
let root = folder ? codiac_ops_common_3.CliPathWalker.getProjectRoot(folder) : this._projectRoot; // TODO: consider just "path.join(this._projectRoot, folder)"
|
|
179
|
+
let targetFile = path.join(root, codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME);
|
|
180
|
+
let contents = fs.readFileSync(targetFile, { encoding: "utf-8" });
|
|
181
|
+
let raw = JSON.parse(contents); // this doesnt run the ctor.
|
|
182
|
+
let config = Object.assign(new codiac_relay_contracts_2.ProjectConfig(raw.name, raw.tenantCode, dx_constants_1.DxConstants.DEFAULT_INIT_CODE_VERSION), raw);
|
|
183
|
+
return config;
|
|
184
|
+
}
|
|
185
|
+
// /** Serializes the given config to its file. Throws if the project root hasnt been initialized. */
|
|
186
|
+
// public updateToyHaulerProjectConfigFile(config: ProjectConfig): void {
|
|
187
|
+
// let pathName = path.join(this._projectRoot, OpsConstants.PROJECT_CONFIG_FILENAME);
|
|
188
|
+
// JsonUtils.serializeJsonFile(config, pathName);
|
|
189
|
+
// }
|
|
190
|
+
// /** News up a Toyhauler config object and serializes
|
|
191
|
+
// * to a file in the current working directory,
|
|
192
|
+
// * thus establishing it as a project root. */
|
|
193
|
+
// public writeNewToyhaulerProjectConfig(seed?: ProjectConfig): ProjectConfig {
|
|
194
|
+
// let folder = process.cwd();
|
|
195
|
+
// let projectName = Case.kebab(path.basename(folder));
|
|
196
|
+
// let config = seed || new ProjectConfig(projectName, DxConstants.UNREGISTERED_TENANT_CODE);
|
|
197
|
+
// let targetFile = path.join(folder, OpsConstants.PROJECT_CONFIG_FILENAME)
|
|
198
|
+
// // try {
|
|
199
|
+
// fs.writeFileSync(targetFile, JSON.stringify(config, undefined, ' '))
|
|
200
|
+
// // } catch (err) {
|
|
201
|
+
// // this.log(`Error creating ${CONFIG_NAME}: ${err}`)
|
|
202
|
+
// // }
|
|
203
|
+
// return config;
|
|
204
|
+
// }
|
|
205
|
+
// /** Reads the user-specific project config file, if it exists.
|
|
206
|
+
// * Otherwise returns a new empty instance.
|
|
207
|
+
// */
|
|
208
|
+
// public readProjectUserConfig(): ProjectUserConfig {
|
|
209
|
+
// let projectRoot = this.getConfigRoot();
|
|
210
|
+
// let userConfigFolder = path.join(projectRoot, OpsConstants.PROJECT_USER_CONFIG_FOLDER_NAME);
|
|
211
|
+
// let sourceFile = path.join(userConfigFolder, OpsConstants.PROJECT_USER_CONFIG_FILENAME);
|
|
212
|
+
// let config = new ProjectUserConfig();
|
|
213
|
+
// if (fs.existsSync(sourceFile)) {
|
|
214
|
+
// let contents = fs.readFileSync(sourceFile, { encoding: "utf-8"});
|
|
215
|
+
// let raw = JSON.parse(contents); // this doesnt run the ctor.
|
|
216
|
+
// config = Object.assign(new ProjectUserConfig(), raw);
|
|
217
|
+
// }
|
|
218
|
+
// return config;
|
|
219
|
+
// }
|
|
220
|
+
// /** Serializes the given config to a file in the project user folder. */
|
|
221
|
+
// public writeProjectUserConfig(config?: ProjectUserConfig): void {
|
|
222
|
+
// let projectRoot = this.getConfigRoot();
|
|
223
|
+
// let userConfigFolder = path.join(projectRoot, OpsConstants.PROJECT_USER_CONFIG_FOLDER_NAME);
|
|
224
|
+
// let targetFile = path.join(userConfigFolder, OpsConstants.PROJECT_USER_CONFIG_FILENAME);
|
|
225
|
+
// // try {
|
|
226
|
+
// if (!fs.existsSync(userConfigFolder)) {
|
|
227
|
+
// fs.mkdirSync(userConfigFolder, { recursive: true })
|
|
228
|
+
// }
|
|
229
|
+
// fs.writeFileSync(targetFile, JSON.stringify(config, undefined, ' '))
|
|
230
|
+
// // } catch (err) {
|
|
231
|
+
// // this.log(`Error creating ${CONFIG_NAME}: ${err}`)
|
|
232
|
+
// // }
|
|
233
|
+
// }
|
|
234
|
+
npmSyncIdentitiesWithNpmrc(...identities) {
|
|
235
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
236
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
237
|
+
try {
|
|
238
|
+
let npmRepo = new npm_config_repo_1.NpmConfigRepo(this._projectRoot);
|
|
239
|
+
// ------------------------------------------------------------------------------
|
|
240
|
+
// 1) Write the identities to the user npmrc file as before
|
|
241
|
+
// Gather up what was in the existing user config
|
|
242
|
+
// stripped of any auth tokens or scope variables
|
|
243
|
+
let userNpmrcRelPath = path.join(codiac_ops_common_3.OpsConstants.PROJECT_USER_CONFIG_FOLDER_NAME, dx_constants_1.DxConstants.NPM_PROJECT_USER_CONFIG_FILENAME);
|
|
244
|
+
let userNpmrcAbsPath = path.join(this._projectRoot, userNpmrcRelPath);
|
|
245
|
+
let existing = yield npmRepo.loadNpmrc(userNpmrcAbsPath);
|
|
246
|
+
let userNpmrc = npmRepo.scrubRegistriesFrom(existing);
|
|
247
|
+
for (let index in identities) {
|
|
248
|
+
let identity = identities[index];
|
|
249
|
+
let tokenSetting = `${identity.registryUrl}:_authToken`;
|
|
250
|
+
let value = identity.token; // The proj user folder doesnt get checked in, so we're gonna keep the token in the file. Otherwise, we'd use: `\${${identity.tokenName}}`
|
|
251
|
+
let exists = (existing[tokenSetting]) ? true : false;
|
|
252
|
+
// scope definition
|
|
253
|
+
if (identity.scope) {
|
|
254
|
+
userNpmrc[`${identity.scope}:always-auth`] = true;
|
|
255
|
+
userNpmrc[`${identity.scope}:registry`] = identity.registryUrl;
|
|
256
|
+
this.logger.detail(`Wrote ${identity.provider} scope definition [${identity.scope}] as [${identity.registryUrl}] to the .npmrc file for use during the image build.`);
|
|
257
|
+
}
|
|
258
|
+
// token reference
|
|
259
|
+
userNpmrc[tokenSetting] = value;
|
|
260
|
+
this.logger.detail(`${(exists) ? "Overwrote" : "Added"} ${identity.provider} token reference [${identity.tokenName}] to the .npmrc file for use during the image build.`);
|
|
261
|
+
}
|
|
262
|
+
npmRepo.saveNpmrc(userNpmrc, userNpmrcAbsPath);
|
|
263
|
+
// ------------------------------------------------------------------------------
|
|
264
|
+
// 2) Ensure that the project npmrc redirects the user config to our project user folder
|
|
265
|
+
// If the proj npmrc isnt redirecting the user level npmrc to live in our project-user folder,
|
|
266
|
+
// then put it there and reconfigure for it. Involves: "./.npmrc", "$HOME/.npmrc", "./.codiac-user/.npmrc-user"
|
|
267
|
+
// via `npm config get userconfig`
|
|
268
|
+
let projectNpmrcFullPathName = path.join(this._projectRoot, ".npmrc");
|
|
269
|
+
let projNpmrc = yield npmRepo.loadNpmrc(projectNpmrcFullPathName);
|
|
270
|
+
if (projNpmrc.userconfig != userNpmrcRelPath) {
|
|
271
|
+
projNpmrc.userconfig = userNpmrcRelPath;
|
|
272
|
+
projNpmrc = npmRepo.scrubRegistriesFrom(projNpmrc);
|
|
273
|
+
npmRepo.saveNpmrc(projNpmrc, projectNpmrcFullPathName);
|
|
274
|
+
}
|
|
275
|
+
resolve();
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
reject(err);
|
|
279
|
+
}
|
|
280
|
+
}));
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
/** Deserializes the npm package.json file in the given directory.
|
|
284
|
+
* Returns undefined if not found.
|
|
285
|
+
* Throws if no toyhauler project is defined up the folder tree.
|
|
286
|
+
* @param pkgRoot (Optional: defaults to the thaul project root) Fully qualified path to the folder containing the package.json file. */
|
|
287
|
+
readNpmPackageJson(pkgRoot, fileName = dx_constants_1.DxConstants.PACKAGE_JSON_FILENAME) {
|
|
288
|
+
let root = pkgRoot || this.getConfigRoot();
|
|
289
|
+
let targetFile = path.join(root, fileName);
|
|
290
|
+
if (fs.existsSync(targetFile)) {
|
|
291
|
+
this.logger.debug(`Found package json at: ${targetFile}`);
|
|
292
|
+
let contents = fs.readFileSync(targetFile, { encoding: "utf-8" });
|
|
293
|
+
let config = JSON.parse(contents);
|
|
294
|
+
return config;
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
this.logger.debug(`No ${dx_constants_1.DxConstants.PACKAGE_JSON_FILENAME} found at: ${targetFile}.`);
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/** Serializes the given object as the package.json for the project.
|
|
302
|
+
* @param config the npm package.json as an object in memory.
|
|
303
|
+
* @param projectRoot fully qualified target folder to write the package.json file (optional: defaults to the thaul project root)
|
|
304
|
+
*/
|
|
305
|
+
writeNpmPackageJson(config, projectRoot) {
|
|
306
|
+
let root = projectRoot || this.getConfigRoot();
|
|
307
|
+
let targetFile = path.join(root, dx_constants_1.DxConstants.PACKAGE_JSON_FILENAME);
|
|
308
|
+
// try {
|
|
309
|
+
fs.writeFileSync(targetFile, JSON.stringify(config, undefined, ' '));
|
|
310
|
+
// } catch (err) {
|
|
311
|
+
// this.log(`Error creating ${CONFIG_NAME}: ${err}`)
|
|
312
|
+
// }
|
|
313
|
+
return config;
|
|
314
|
+
}
|
|
315
|
+
/** Deletes the package.json file in the project root. */
|
|
316
|
+
deleteNpmPackageJson() {
|
|
317
|
+
this.deleteProjectFile(dx_constants_1.DxConstants.PACKAGE_JSON_FILENAME);
|
|
318
|
+
}
|
|
319
|
+
/** Deletes the package.json file in the project root. */
|
|
320
|
+
clearNpmNodeModulesFolder() {
|
|
321
|
+
this.clearProjectFolder(`${dx_constants_1.DxConstants.NODE_MODULES_DIR_NAME}/**/*`);
|
|
322
|
+
}
|
|
323
|
+
/** Retrieves a list of all production dependencies for the npm project with the given root folder.
|
|
324
|
+
* @param projectRoot The fully qualified pathg to the folder containing the package.json file.
|
|
325
|
+
*/
|
|
326
|
+
getNpmDependencies(projectRoot) {
|
|
327
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
328
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
329
|
+
try {
|
|
330
|
+
let pj = yield this.readNpmPackageJson(projectRoot);
|
|
331
|
+
let names = [];
|
|
332
|
+
if (pj && pj.dependencies) {
|
|
333
|
+
for (let key in pj.dependencies) {
|
|
334
|
+
names.push(key);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (pj && pj.devDependencies) {
|
|
338
|
+
for (let key in pj.devDependencies) {
|
|
339
|
+
names.push(key);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
this.logger.debug(JSON.stringify(names));
|
|
343
|
+
// COMMENTED OUT BECAUSE this fails when one of the dependencies is sourced
|
|
344
|
+
// // Select from the list of dependencies
|
|
345
|
+
// let cmd0 = "npm ls --depth 0 --json --prod"
|
|
346
|
+
// let result0 = await this._cliExec.execAsync(cmd0, { cwd: projectRoot })
|
|
347
|
+
// let doc = JSON.parse(result0.stdout);
|
|
348
|
+
// let names: string[] = [];
|
|
349
|
+
// for (let dep in doc.dependencies) {
|
|
350
|
+
// // this.logger.debug(dep);
|
|
351
|
+
// names.push(dep);
|
|
352
|
+
// }
|
|
353
|
+
resolve(names);
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
reject(err);
|
|
357
|
+
}
|
|
358
|
+
}));
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
/** Instantiates the tsconfig.json object from its file in the project root.
|
|
362
|
+
* NOTE: Returns undefined if no tsconfig.json is found.
|
|
363
|
+
* @param typescriptRoot (optional: defaults to main project root) Fully qualified path to the folder containing the typescript config file to load.
|
|
364
|
+
*/
|
|
365
|
+
readTsConfig(typescriptRoot) {
|
|
366
|
+
let root = typescriptRoot || this._projectRoot;
|
|
367
|
+
let fullPathName = path.join(root, dx_constants_1.DxConstants.TSCONFIG_JSON_FILENAME);
|
|
368
|
+
this.logger.debug(`tsconfig.json: ${fullPathName}`);
|
|
369
|
+
if (fs.existsSync(fullPathName)) {
|
|
370
|
+
return codiac_ops_common_3.JsonUtils.deserializeJsonFile(fullPathName, true);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/** Retrieves the fully qualified local path to the root folder
|
|
377
|
+
* of the source control repository clone
|
|
378
|
+
* (aka: the folder into which the repo was originally cloned).
|
|
379
|
+
* Though it is best that this folder coincide with the toyhauler project root,
|
|
380
|
+
* there are cases where it may not, such as with submodules,
|
|
381
|
+
* or subfolders that contain their own typescript and npm configs.
|
|
382
|
+
* @param projectRoot Fully qualified local path to the root of the thaul project (aka: nearest upstream folder containing a .codiac.json) */
|
|
383
|
+
getRepoRoot(projectRoot) {
|
|
384
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
385
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
386
|
+
try {
|
|
387
|
+
let cmd = `git rev-parse --show-toplevel`;
|
|
388
|
+
let result = yield this._cliExec.execAsync(cmd); //, { cwd: projectRoot }) // commented out bc we actually want it rel to the actual cwd.
|
|
389
|
+
if (result.stderr) {
|
|
390
|
+
throw new Error(result.stderr);
|
|
391
|
+
}
|
|
392
|
+
else if (!result.stdout) {
|
|
393
|
+
throw new Error(`Git returned nothing when asked for the repo root. idkwtf... ¯\\_(ツ)_/¯`);
|
|
394
|
+
}
|
|
395
|
+
let root = result.stdout.trim(); // that trim is IMPORTANT: the output has a trailing linebreak in it. Removing it allows us to use path.relative() the way it was intended.
|
|
396
|
+
resolve(root);
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
reject(err);
|
|
400
|
+
}
|
|
401
|
+
}));
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
/** Deserializes the app config file if it exists
|
|
405
|
+
* @param relFolder The folder relative to the root to read from:
|
|
406
|
+
* eg: Either the project source folder "./src" or the build output folder "/bin".
|
|
407
|
+
*/
|
|
408
|
+
loadConfig(relFolder = "./src") {
|
|
409
|
+
let root = this.getConfigRoot();
|
|
410
|
+
return codiac_ops_common_3.JsonUtils.deserializeJsonFile(path.join(root, relFolder, this.APP_CONFIG_FILENAME));
|
|
411
|
+
}
|
|
412
|
+
/** Serializes the app config object to a file. */
|
|
413
|
+
writeConfig(appConfig) {
|
|
414
|
+
codiac_ops_common_3.JsonUtils.serializeJsonFile(appConfig, `./src/${this.APP_CONFIG_FILENAME}`);
|
|
415
|
+
}
|
|
416
|
+
deleteConfigFile() {
|
|
417
|
+
this.deleteProjectFile(`/src/${this.APP_CONFIG_FILENAME}`);
|
|
418
|
+
}
|
|
419
|
+
/** Loads the list of names of the built in app-config settings
|
|
420
|
+
* supported by the framework
|
|
421
|
+
* (Reads from a json file in the cli executable folder). */
|
|
422
|
+
loadConfigKeys(
|
|
423
|
+
/** Path to the folder containing the CLI executable
|
|
424
|
+
* (from an oclif Command class, use "this.config.root"). */
|
|
425
|
+
execRoot) {
|
|
426
|
+
let sourceFile = path.join(execRoot, "assets", this.AVAIL_CONFIG_KEYS_FILENAME);
|
|
427
|
+
let array = codiac_ops_common_3.JsonUtils.deserializeJsonFile(sourceFile);
|
|
428
|
+
return array || [];
|
|
429
|
+
}
|
|
430
|
+
// /** Returns the instantiated object or array.
|
|
431
|
+
// * Returns undefined for both an empty or missing source file.
|
|
432
|
+
// * Uses JSON.parse and does not perform any explicit casting. Resolves tilde (~) path prefixes.
|
|
433
|
+
// * @param pathName Fully qualified or relative path and filename of the json file.
|
|
434
|
+
// * If relative (ie: not starting with / or ~), it is interpreted as relative to the project root
|
|
435
|
+
// * (eg: "src/app-config.json").
|
|
436
|
+
// * */
|
|
437
|
+
// deserializeJsonFile<T>(pathName: string, allowComments: boolean = false): T|undefined {
|
|
438
|
+
// try {
|
|
439
|
+
// let targetPathName = resolveHomeDir(pathName);
|
|
440
|
+
// if (!path.isAbsolute(targetPathName)) { // Relative path (defaults relative to project root)
|
|
441
|
+
// let root = this.getConfigRoot();
|
|
442
|
+
// targetPathName = path.join(root, pathName);
|
|
443
|
+
// }
|
|
444
|
+
// if (fs.existsSync(targetPathName)) {
|
|
445
|
+
// let json = fs.readFileSync(targetPathName, { encoding: 'utf-8'});
|
|
446
|
+
// if (allowComments) {
|
|
447
|
+
// let obj = commentJson.parse(json);
|
|
448
|
+
// return obj;
|
|
449
|
+
// } else {
|
|
450
|
+
// let obj = JSON.parse(json);
|
|
451
|
+
// return obj;
|
|
452
|
+
// }
|
|
453
|
+
// } else {
|
|
454
|
+
// return undefined;
|
|
455
|
+
// }
|
|
456
|
+
// } catch (err) {
|
|
457
|
+
// // throw err;
|
|
458
|
+
// this.logger.debug(err);
|
|
459
|
+
// return undefined;
|
|
460
|
+
// }
|
|
461
|
+
// }
|
|
462
|
+
// /** Uses JSON.stringify() to write the given object to a file. Resolves tilde (~) path prefixes.
|
|
463
|
+
// * @param subject The object to serialize.
|
|
464
|
+
// * @param pathName Path and filename. If relative (ie: not starting with / or ~),
|
|
465
|
+
// * it is interpreted as relative to the project root (eg: "src/app-config.json").
|
|
466
|
+
// */
|
|
467
|
+
// serializeJsonFile(subject: any, pathName: string): void {
|
|
468
|
+
// let targetPathName = resolveHomeDir(pathName);
|
|
469
|
+
// if (!path.isAbsolute(targetPathName)) { // Relative path (defaults relative to project root)
|
|
470
|
+
// let root = this.getConfigRoot();
|
|
471
|
+
// targetPathName = path.join(root, pathName);
|
|
472
|
+
// }
|
|
473
|
+
// if (!fs.existsSync(path.dirname(targetPathName))) {
|
|
474
|
+
// fs.mkdirSync(path.dirname(targetPathName), { recursive: true });
|
|
475
|
+
// }
|
|
476
|
+
// fs.writeFileSync(targetPathName, JSON.stringify(subject, undefined, ' '))
|
|
477
|
+
// }
|
|
478
|
+
/** Synchronously deletes the given file. Throws any exceptions.
|
|
479
|
+
* @param relPathName Path and filename of file relative to the project root
|
|
480
|
+
* (eg: "src/app-config.json").
|
|
481
|
+
*/
|
|
482
|
+
deleteProjectFile(relPathName) {
|
|
483
|
+
let root = this.getConfigRoot();
|
|
484
|
+
let targetFile = path.join(root, relPathName);
|
|
485
|
+
if (fs.existsSync(targetFile)) {
|
|
486
|
+
fs.unlinkSync(targetFile);
|
|
487
|
+
this.logger.debug(`Deleted file: [${targetFile}]`);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
/** Synchronously deletes all contents of the given folder without deleting the folder itself.
|
|
491
|
+
* Throws any exceptions.
|
|
492
|
+
* @param relPathName Path of target folder relative to the project root
|
|
493
|
+
* (eg: "src/my-outdated-stuff").
|
|
494
|
+
*/
|
|
495
|
+
clearProjectFolder(relPathName) {
|
|
496
|
+
let root = this.getConfigRoot();
|
|
497
|
+
let targetFolder = path.join(root, relPathName);
|
|
498
|
+
if (fs.existsSync(targetFolder)) {
|
|
499
|
+
let targetSpec = (targetFolder.endsWith("*")) ? targetFolder : path.join(targetFolder, "**/*");
|
|
500
|
+
rimraf.sync(targetSpec, {});
|
|
501
|
+
this.logger.debug(`Deleted contents of folder: [${targetFolder}]`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
/** Reads the current version of the main project.
|
|
505
|
+
* Uses npm's package.json as the system of record for the version. */
|
|
506
|
+
npmGetCurrentVersion(pkgRoot) {
|
|
507
|
+
let pkgJson = this.readNpmPackageJson(pkgRoot);
|
|
508
|
+
// this.logger.debug("Current pkg version: " + pkgJson.version);
|
|
509
|
+
let thisVersion = pkgJson.version || dx_constants_1.DxConstants.DEFAULT_INIT_PACKAGE_VERSION;
|
|
510
|
+
// this.logger.debug("This version: " + thisVersion)
|
|
511
|
+
return thisVersion;
|
|
512
|
+
}
|
|
513
|
+
getCodeVersion(pkgRoot) {
|
|
514
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
515
|
+
const cfg = yield this.readCodiacProjectConfig();
|
|
516
|
+
return cfg.codeVersion;
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
/** Loads the source code for the given repo as a git submodule of the project.
|
|
520
|
+
* DOES NOT interface with npm or any other tool - just git.
|
|
521
|
+
* @param packageName The official name of the project dependency whose repo is being submoduled (including any scope prefix, eg: "@codiac/").
|
|
522
|
+
* @param cloneUrl The url of the git repo that will be used to pull the source code.
|
|
523
|
+
* @param lastPkgVersion The version of its package that the project is currently depending on.
|
|
524
|
+
* @param nameOverride (optional: defaults to the repo name) The unique identifier for this submodule within the current project.
|
|
525
|
+
*/
|
|
526
|
+
addSubmodule(cloneUrl, packageName, lastPkgVersion, nameOverride, branch) {
|
|
527
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
528
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
529
|
+
try {
|
|
530
|
+
let cfg = this.readCodiacProjectConfig();
|
|
531
|
+
/*
|
|
532
|
+
* NOTE: Git doesnt like to let go of the remote for the submodule.
|
|
533
|
+
* So, if you have changed the repository url for that submodule name,
|
|
534
|
+
* Git will still clone from the previous repository. (!!! wtf !!!)
|
|
535
|
+
* Check it by comparing
|
|
536
|
+
* this output (run from the root folder of the submodule): $ git remote -v
|
|
537
|
+
* to the value in the file: ".gitmodules" in the root of the parent repo.
|
|
538
|
+
* You will need to explicitly tell your local git to do two things:
|
|
539
|
+
* 1) sync up with whatever repo url is written into the .gitmodules file,
|
|
540
|
+
* 2) refresh from that remote.
|
|
541
|
+
* Here's your commands to run on your submodule (eg: toyhauler-auth-contracts)
|
|
542
|
+
* 1) git submodule sync ./submodules/toyhauler-auth-contracts
|
|
543
|
+
* 2) git submodule update --remote ./submodules/toyhauler-auth-contracts
|
|
544
|
+
* ----THEN, you may need to do the following...
|
|
545
|
+
* 3) cd ./submodules/toyhauler-auth-contracts
|
|
546
|
+
* 4) git pull
|
|
547
|
+
* 5) [-- you may need to resolve merge conflicts --]
|
|
548
|
+
* 6) git add -A
|
|
549
|
+
* 7) git commit -m 'Detached stale remote and merged in latest from current remote.'
|
|
550
|
+
* 8) git push
|
|
551
|
+
* That should get you the source code from the proper repo.
|
|
552
|
+
* For more info see: https://git-scm.com/docs/git-submodule
|
|
553
|
+
* ALSO: submodule update doesnt really work with SSH keys -
|
|
554
|
+
* youll need to give it a url with a username that you have a password for...
|
|
555
|
+
* https://stackoverflow.com/questions/6031494/git-submodules-and-ssh-access
|
|
556
|
+
* Alos, git may have something with a "prune" subcommand that helps remove this repo-to-origin cache.
|
|
557
|
+
*/
|
|
558
|
+
// if a submodule already exists from that git repo, tell user to remove it first instead of overwriting it.
|
|
559
|
+
if (_.find(cfg.submodules, { cloneUrl: cloneUrl })) {
|
|
560
|
+
throw new Error("That repo is already submoduled in this project.");
|
|
561
|
+
}
|
|
562
|
+
// add the submodule
|
|
563
|
+
let folderName = packageName; // nameOverride || fileBaseName(cloneUrl);
|
|
564
|
+
let submodule = new codiac_relay_contracts_2.Submodule(cloneUrl, folderName);
|
|
565
|
+
if (packageName)
|
|
566
|
+
submodule.packageName = packageName;
|
|
567
|
+
if (lastPkgVersion)
|
|
568
|
+
submodule.lastUsedVersion = lastPkgVersion;
|
|
569
|
+
if (branch) {
|
|
570
|
+
submodule.branch = branch;
|
|
571
|
+
}
|
|
572
|
+
// NOTE: We are being VERY PRECISE in case projectRoot != repoRoot
|
|
573
|
+
// because Git sees paths rel to repoRoot,
|
|
574
|
+
// whereas the thaul cli sees paths relative to projectRoot.
|
|
575
|
+
let projectRoot = this.getConfigRoot();
|
|
576
|
+
let repoRoot = yield this.getRepoRoot(projectRoot);
|
|
577
|
+
// let projectPathInRepo = path.relative(repoRoot + "/", projectRoot + "/"); // why does this back out of the "from" directory? wtf?
|
|
578
|
+
let projectPathInRepo = projectRoot.slice(repoRoot.length);
|
|
579
|
+
this.logger.debug("resolved: " + path.resolve(repoRoot, projectPathInRepo));
|
|
580
|
+
this.logger.debug(`projectRoot: ${projectRoot}`);
|
|
581
|
+
this.logger.debug(`repoRoot: ${repoRoot}`);
|
|
582
|
+
this.logger.debug(`projectPathInRepo: ${projectPathInRepo}`);
|
|
583
|
+
// We're gonna run this relative to the thaul project root (not the repo root)
|
|
584
|
+
let targetFolder = path.posix.join(dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, folderName);
|
|
585
|
+
// git might do this for us
|
|
586
|
+
// let fqTargetFolder = path.posix.join(projectRoot, targetFolder);
|
|
587
|
+
// if (!fs.existsSync(fqTargetFolder)) {
|
|
588
|
+
// fs.mkdirSync(fqTargetFolder, { recursive: true });
|
|
589
|
+
// }
|
|
590
|
+
let argBranch = (submodule.branch) ? ` -b ${submodule.branch}` : "";
|
|
591
|
+
let cmd = `git submodule add ${argBranch} --force --name ${submodule.folderName} ${submodule.cloneUrl} ${targetFolder}`;
|
|
592
|
+
this.logger.debug(`ABOUT TO: ${cmd}`);
|
|
593
|
+
this.logger.debug(`FROM: cwd: ${process.cwd()} projectroot: ${projectRoot}`);
|
|
594
|
+
// Ensure the submodules folder exists within the project
|
|
595
|
+
// fs.mkdirSync(path.join(projectRoot, DxConstants.SUBMODULES_DIR_NAME));
|
|
596
|
+
yield this._cliExec.execAsyncStdOut(cmd, { cwd: projectRoot });
|
|
597
|
+
// Write the new submodule to the project context
|
|
598
|
+
if (!cfg.submodules)
|
|
599
|
+
cfg.submodules = [];
|
|
600
|
+
cfg.submodules.push(submodule);
|
|
601
|
+
yield this._projCfgRepo.updateProjectConfigFile(cfg);
|
|
602
|
+
// commit the change
|
|
603
|
+
// NOTE: these cmds run from the repo root cuz we're identifying items in the changeset.
|
|
604
|
+
let cmd3a = `git update-index --again`; // we were moving too fast for git to see our changes.
|
|
605
|
+
this.logger.debug(cmd3a);
|
|
606
|
+
yield this._cliExec.execAsync(cmd3a, { cwd: projectRoot });
|
|
607
|
+
let cmd3 = `git add ${codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME}`; // ${path.posix.join(projectPathInRepo, targetFolder)}` apparently the submodule folder is already staged
|
|
608
|
+
this.logger.debug(cmd3);
|
|
609
|
+
yield this._cliExec.execAsync(cmd3, { cwd: projectRoot });
|
|
610
|
+
let cmd4 = `git commit -m 'Added submodule: ${submodule.folderName}'`;
|
|
611
|
+
this.logger.debug(cmd4);
|
|
612
|
+
yield this._cliExec.execAsync(cmd4, { cwd: projectRoot });
|
|
613
|
+
resolve(submodule);
|
|
614
|
+
}
|
|
615
|
+
catch (err) {
|
|
616
|
+
reject(err);
|
|
617
|
+
}
|
|
618
|
+
}));
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
/** Replaces the installed package of the dependency with the local submodule folder as the source of the code references.
|
|
622
|
+
* ie: allows the developer to debug the submoduled source code instead of the code that was installed from the package.
|
|
623
|
+
* NOTE: There is no guarantee that the submodule code being linked
|
|
624
|
+
* matches that of the installed dependency.
|
|
625
|
+
* @param submodule A valid dependency sourced into the project.
|
|
626
|
+
*/
|
|
627
|
+
symLinkSubmodule(submodule) {
|
|
628
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
629
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
630
|
+
try {
|
|
631
|
+
let projectRoot = this.getConfigRoot();
|
|
632
|
+
let segments = [projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName];
|
|
633
|
+
if (submodule.distributionRoot)
|
|
634
|
+
segments.push(submodule.distributionRoot);
|
|
635
|
+
let linkTargetFolder = path.posix.join(...segments);
|
|
636
|
+
// WE'LL PROB NEED TO DO THIS (or perhaps even build)
|
|
637
|
+
if (!fs.existsSync(linkTargetFolder)) {
|
|
638
|
+
fs.mkdirSync(linkTargetFolder, { recursive: true });
|
|
639
|
+
}
|
|
640
|
+
// Copy the contents of the existing package folder in node_modules.
|
|
641
|
+
// NOTE: In order for the source code to lilne up with the package,
|
|
642
|
+
// the package needs to have a commit id in it somewhere.
|
|
643
|
+
// and we would need to ask for that commit Id on the addSubmodule() call.
|
|
644
|
+
// For now, we're just going to hope they line up and if not,
|
|
645
|
+
// the user can pull the right commit on their own, or rebuild on their own
|
|
646
|
+
// Do we always do this? Maybe only when there's no package.json in the dist folder, or when the dist folder is not the project root?
|
|
647
|
+
// (they shouldnt have, but they MAY have included their dist folder contents in their repo - what then? A: we just use what the repo has)
|
|
648
|
+
if (submodule.distributionRoot && !fs.existsSync(path.posix.join(linkTargetFolder, "package.json"))) {
|
|
649
|
+
let pkgInstallPath = path.posix.join(this._projectRoot, "node_modules", submodule.packageName);
|
|
650
|
+
this.logger.debug(`Copying installed pkg contents into submodule distributionRoot: ${linkTargetFolder}`);
|
|
651
|
+
// fse.copyFileSync(path.posix.join(pkgInstallPath, "**", "*.*"), linkTargetFolder);
|
|
652
|
+
fse.copySync(pkgInstallPath, linkTargetFolder);
|
|
653
|
+
}
|
|
654
|
+
let distNodeModulesFolder = path.posix.join(linkTargetFolder, "node_modules");
|
|
655
|
+
let removeNodeModules = !fs.existsSync(distNodeModulesFolder);
|
|
656
|
+
// cd ./submodules/bidstreak-domain
|
|
657
|
+
// && npm link
|
|
658
|
+
yield this._cliExec.execAsyncStdOut(`npm link --no-save`, { cwd: linkTargetFolder });
|
|
659
|
+
// && cd ../../
|
|
660
|
+
// && npm link @extradus/bidstreak-domain --no-save",
|
|
661
|
+
yield this._cliExec.execAsyncStdOut(`npm link ${submodule.packageName} --no-save`, { cwd: projectRoot });
|
|
662
|
+
if (removeNodeModules && fs.existsSync(distNodeModulesFolder)) {
|
|
663
|
+
fse.removeSync(distNodeModulesFolder);
|
|
664
|
+
}
|
|
665
|
+
resolve();
|
|
666
|
+
}
|
|
667
|
+
catch (err) {
|
|
668
|
+
reject(err);
|
|
669
|
+
}
|
|
670
|
+
}));
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
/** Reverts a linked submodule reference back to the installed package dependency.
|
|
674
|
+
* @param name Unique identifier in this project for the submodule (typically the package name).
|
|
675
|
+
*/
|
|
676
|
+
unSymLinkSubmodule(name) {
|
|
677
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
678
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
679
|
+
try {
|
|
680
|
+
let cfg = this.readCodiacProjectConfig();
|
|
681
|
+
let subm = yield this.chooseSubmodule('remove', name, cfg);
|
|
682
|
+
if (subm) {
|
|
683
|
+
let projectRoot = this.getConfigRoot();
|
|
684
|
+
let segments = [projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, subm.folderName];
|
|
685
|
+
if (subm.distributionRoot)
|
|
686
|
+
segments.push(subm.distributionRoot);
|
|
687
|
+
let submoduleFolder = path.posix.join(...segments);
|
|
688
|
+
// npm uninstall @extradus/bidstreak-domain --no-save
|
|
689
|
+
// && cd ./submodules/bidstreak-domain
|
|
690
|
+
// && npm uninstall
|
|
691
|
+
if (subm.packageName) {
|
|
692
|
+
yield this._cliExec.execAsyncStdOut(`npm uninstall ${subm.packageName} --no-save`, { cwd: projectRoot });
|
|
693
|
+
yield this._cliExec.execAsyncStdOut(`npm uninstall`, { cwd: submoduleFolder });
|
|
694
|
+
// && cd ../../
|
|
695
|
+
// && npm install @extradus/bidstreak-domain@latest",
|
|
696
|
+
if (subm.lastUsedVersion) {
|
|
697
|
+
yield this._cliExec.execAsyncStdOut(`npm install ${subm.packageName}@${subm.lastUsedVersion}`, { cwd: projectRoot });
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
resolve();
|
|
702
|
+
}
|
|
703
|
+
catch (err) {
|
|
704
|
+
reject(err);
|
|
705
|
+
}
|
|
706
|
+
}));
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
/** Fully exorcises a git submodule from the project.
|
|
710
|
+
* Returns the submodule object that was removed.
|
|
711
|
+
* NOTE: Does NOT remove the project package dependency that corresponds to the submodule.
|
|
712
|
+
*
|
|
713
|
+
* @param name Unique identifier in this project for the submodule (typically the package name without any scope prefix).
|
|
714
|
+
* @param discardChanges Discards all uncommitted changes (staged and unstaged) before unsourcing, and goes back to the previously installed version of the dependency. Again, uncomitted changes are LOST when this flag is set!
|
|
715
|
+
*/
|
|
716
|
+
removeSubmodule(name, discardChanges = false) {
|
|
717
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
718
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
719
|
+
try {
|
|
720
|
+
let cfg = this.readCodiacProjectConfig();
|
|
721
|
+
let subm = yield this.chooseSubmodule('remove', name, cfg);
|
|
722
|
+
if (subm) {
|
|
723
|
+
this.logger.debug(`Removing submodule: ${subm.folderName}...`);
|
|
724
|
+
let projectRoot = this.getConfigRoot();
|
|
725
|
+
let repoRoot = yield this.getRepoRoot(projectRoot);
|
|
726
|
+
// let projectPathInRepo = path.relative(repoRoot + "/", projectRoot + "/"); // why does this back out of the "from" directory? wtf?
|
|
727
|
+
this.logger.debug("projectRoot: " + projectRoot);
|
|
728
|
+
this.logger.debug("repoRoot: " + repoRoot);
|
|
729
|
+
let projectPathInRepo = projectRoot.slice(repoRoot.length);
|
|
730
|
+
let segments = [dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, subm.folderName];
|
|
731
|
+
if (subm.distributionRoot)
|
|
732
|
+
segments.push(subm.distributionRoot);
|
|
733
|
+
let submodulePath = path.posix.join(...segments);
|
|
734
|
+
// How do we check to see if it's sym linked? (it should always be, but we should allow for it to have been unlinked)
|
|
735
|
+
yield this.unSymLinkSubmodule(subm.folderName);
|
|
736
|
+
if (discardChanges) {
|
|
737
|
+
// rollback any uncommitted changes
|
|
738
|
+
yield this._cliExec.execAsync(`git reset --hard origin`, { cwd: submodulePath });
|
|
739
|
+
} // else {
|
|
740
|
+
// These need to be run within the context of the submodule folder
|
|
741
|
+
// git see-if-they-have-changes
|
|
742
|
+
// git add -A
|
|
743
|
+
// git commit -m flags.commit || "" // shall we prompt for this commit message?
|
|
744
|
+
//
|
|
745
|
+
// publish:
|
|
746
|
+
// increment
|
|
747
|
+
// build
|
|
748
|
+
// tsc, npm, docker as reqd
|
|
749
|
+
// publish
|
|
750
|
+
// git push, npm, docker as reqd
|
|
751
|
+
// }
|
|
752
|
+
// Apparently you can use either of these methods,
|
|
753
|
+
// depending on how much you want git to remember.
|
|
754
|
+
// We want it to forget it ever knew anything about our submodule.
|
|
755
|
+
// NOTE: It seems, however, that git still remembers the remote address
|
|
756
|
+
// for the given submodule name, even after you remove it.
|
|
757
|
+
// See the big note in this file under addSubmodule().
|
|
758
|
+
let typeOfRemove = "rm";
|
|
759
|
+
if (typeOfRemove == "rm") {
|
|
760
|
+
// this kills the submodule from the .gitmodules folder altogether
|
|
761
|
+
let cmd2 = `git rm -f ${submodulePath}`; // what about this: git rm --cached ${submodulePath} (will this remove gits memory of it too?)
|
|
762
|
+
this.logger.debug(cmd2);
|
|
763
|
+
// HEY!!! This fails if you do it after a deinit and gives us:
|
|
764
|
+
// git rm -f submodules/toyhauler-auth-contracts
|
|
765
|
+
// Error: ENOENT: no such file or directory, uv_cwd
|
|
766
|
+
yield this._cliExec.execAsync(cmd2, { cwd: projectRoot });
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
// deinit the submodule
|
|
770
|
+
let cmd = `git submodule deinit -f ${submodulePath}`;
|
|
771
|
+
this.logger.debug(cmd);
|
|
772
|
+
yield this._cliExec.execAsync(cmd, { cwd: projectRoot });
|
|
773
|
+
}
|
|
774
|
+
// update the project context file
|
|
775
|
+
_.remove(cfg.submodules, { folderName: subm.folderName });
|
|
776
|
+
yield this._projCfgRepo.updateProjectConfigFile(cfg);
|
|
777
|
+
// COMMIT
|
|
778
|
+
// NOTE: these cmds run from the repo root cuz we're identifying items in the changeset.
|
|
779
|
+
let cmd3a = `git update-index --again`; // we were moving too fast for git to see our changes.
|
|
780
|
+
this.logger.debug(cmd3a);
|
|
781
|
+
yield this._cliExec.execAsync(cmd3a, { cwd: projectRoot });
|
|
782
|
+
// let cmd3 = `git add .gitmodules ${path.join(projectPathInRepo, OpsConstants.PROJECT_CONFIG_FILENAME)}`
|
|
783
|
+
let cmd3 = `git add ${codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME}`;
|
|
784
|
+
this.logger.debug(cmd3);
|
|
785
|
+
yield this._cliExec.execAsync(cmd3, { cwd: projectRoot });
|
|
786
|
+
let cmd4 = `git commit -m 'Removed submodule: ${subm.folderName}'`;
|
|
787
|
+
this.logger.debug(cmd4);
|
|
788
|
+
yield this._cliExec.execAsync(cmd4, { cwd: projectRoot });
|
|
789
|
+
resolve(subm);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
catch (err) {
|
|
793
|
+
reject(err);
|
|
794
|
+
}
|
|
795
|
+
}));
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
/** Returns a valid submodule object from the given name or prompts for one.
|
|
799
|
+
* Guarantees a valid submodule reference, an undefined, or throws an exception.
|
|
800
|
+
* NOTE: The user can also cancel the operation entirely (CTRL-C), which will exit the whole process itself.
|
|
801
|
+
* @param actionIntended The verb for the process for which the submodule is being selected. (eg: 'remove' which will get used in user prompt as '...please select the dependency source to remove...')
|
|
802
|
+
* @param name Unique identifier in this project for the submodule (typically the package name).
|
|
803
|
+
* @param projectConfig The toyhauler settings for the current project.
|
|
804
|
+
*/
|
|
805
|
+
chooseSubmodule(actionIntended, name, projectConfig) {
|
|
806
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
807
|
+
try {
|
|
808
|
+
let cfg = projectConfig || this.readCodiacProjectConfig();
|
|
809
|
+
let subm = _.find(cfg.submodules, { folderName: name });
|
|
810
|
+
if (!subm) {
|
|
811
|
+
this.ux.userMessage(`There is no dependency sourced as: ${name}. Please select the dependency source to ${actionIntended}:`);
|
|
812
|
+
let names = cfg.submodules.map(sm => sm.folderName);
|
|
813
|
+
if (names && names.length > 0) {
|
|
814
|
+
let selected = yield this.ux.promptSelect('name', `dependency source to ${actionIntended}: (ctrl-c to cancel)`, names);
|
|
815
|
+
// let result = await inquirer.prompt({ type: 'list', name: 'name', message: `dependency source to ${actionIntended}: (ctrl-c to cancel)`, choices: names });
|
|
816
|
+
if (!selected) {
|
|
817
|
+
this.logger.debug("Operation cancelled by user.");
|
|
818
|
+
// cli.exit(0); // TODO: Stop and emit a workflow status instead. (This lib isnt necessarily being used by a TTY/console app)
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
subm = _.find(cfg.submodules, { folderName: selected });
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
this.ux.userMessage(`Cancelled: no dependencies are currently sourced.`);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
resolve(subm);
|
|
829
|
+
}
|
|
830
|
+
catch (err) {
|
|
831
|
+
reject(err);
|
|
832
|
+
}
|
|
833
|
+
}));
|
|
834
|
+
}
|
|
835
|
+
/** npm sends its warnings down the stderr pipe rather than stdout,
|
|
836
|
+
* so we have to parse it to find out if it is indeed an error.
|
|
837
|
+
* Fortunately they prefix them with "npm WARN" or "npm ERR!".
|
|
838
|
+
*/
|
|
839
|
+
npmStdErrIsJustAWarning(stderr) {
|
|
840
|
+
let errs = stderr.split("\n");
|
|
841
|
+
if (errs.find(e => e.startsWith("npm ERR!"))) {
|
|
842
|
+
return false;
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
845
|
+
return true;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
buildVersionTag(mainVersionNumber, workingFolder) {
|
|
849
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
850
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
851
|
+
try {
|
|
852
|
+
let branch = yield this.gitCurrentBranchFor(workingFolder);
|
|
853
|
+
let buildNumber = codiac_common_1.BuildNumberGenerator.getOne();
|
|
854
|
+
let seatCode = "fakeseatcode"; // TODO: Get the seatcode or user info
|
|
855
|
+
let tag = `${mainVersionNumber}-${branch}.${buildNumber}.${seatCode}`;
|
|
856
|
+
resolve(tag);
|
|
857
|
+
}
|
|
858
|
+
catch (err) {
|
|
859
|
+
reject(err);
|
|
860
|
+
}
|
|
861
|
+
}));
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
/** Creates and publishes to the npm registry any configured npm packages
|
|
865
|
+
* for the main project and its sourced dependencies.
|
|
866
|
+
* NOTE: Determines whether to publish based on the occurrence of commits since the last package date.
|
|
867
|
+
* @param force Publishes regardless of whether package contents have changed or not.
|
|
868
|
+
* */
|
|
869
|
+
npmPublish(force = false) {
|
|
870
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
871
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
872
|
+
try {
|
|
873
|
+
let projectRoot = this.getConfigRoot();
|
|
874
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
875
|
+
let pj = yield this.readNpmPackageJson();
|
|
876
|
+
let tag = yield this.buildVersionTag(pj.version, projectRoot);
|
|
877
|
+
let skipReason;
|
|
878
|
+
let tagArg = `--tag ${tag}`;
|
|
879
|
+
let distFolderArg = "dist"; // TODO: Consider making distFolder configurable.
|
|
880
|
+
let cmd = `npm publish ${distFolderArg} ${tagArg}`;
|
|
881
|
+
// SOURCED DEPENDENCIES
|
|
882
|
+
// Publish any all sourced dependencies (only if needed)
|
|
883
|
+
for (let index in cfg.submodules) {
|
|
884
|
+
let submodule = cfg.submodules[index];
|
|
885
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
886
|
+
if (yield this.npmIsPublishable(submoduleFolder, submodule.packageName, tag)) {
|
|
887
|
+
// let changes = await this.gitChangesSince(subModuleFolder, submodule.packagedDateUtc);
|
|
888
|
+
let changes = { commits: [{ hash: "123" }], stages: [{ filename: "hello.ts" }] };
|
|
889
|
+
let isChanged = (changes && (changes.commits.length > 0 || changes.stages.length > 0));
|
|
890
|
+
if (force || isChanged) {
|
|
891
|
+
this.logger.debug(`pretending to execute the command: "${cmd}" from folder: ${submoduleFolder}`);
|
|
892
|
+
// let outputDep = await this._cliExec.execAsyncStdOut(cmd, { cwd: submoduleFolder });
|
|
893
|
+
// DO we want to install this into the main? Im assuming we do...
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
else {
|
|
897
|
+
// gated; skip it
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
// MAIN PROJECT
|
|
901
|
+
if (yield this.npmIsPublishable(projectRoot, pj.name, tag)) {
|
|
902
|
+
this.logger.debug(`pretending to execute the command: "${cmd}" from folder: ${projectRoot}`);
|
|
903
|
+
// let output = await this._cliExec.execAsyncStdOut(cmd, { cwd: projectRoot });
|
|
904
|
+
}
|
|
905
|
+
resolve();
|
|
906
|
+
}
|
|
907
|
+
catch (err) {
|
|
908
|
+
reject(err);
|
|
909
|
+
}
|
|
910
|
+
}));
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
/** Determines whether the given npm module has changes
|
|
914
|
+
* that require the package to be rebuilt.
|
|
915
|
+
* Used to gate the publish of a package to avoid unnecessary processing. */
|
|
916
|
+
npmIsPublishable(workingFolder, fullPackageName, version) {
|
|
917
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
918
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
919
|
+
try {
|
|
920
|
+
let isPublishable;
|
|
921
|
+
let reason;
|
|
922
|
+
// 0) Validate that the registry itself exists and we can authenticate
|
|
923
|
+
// For more info see: https://docs.npmjs.com/cli/ping.html
|
|
924
|
+
// TODO: Add support for alternate package registries
|
|
925
|
+
// let pingCmd = `npm ping --registry ${registryUrl}`
|
|
926
|
+
// try {
|
|
927
|
+
// let pingResult = await this._cliExec.execAsyncStdOut(pingCmd, { cwd: workingFolder });
|
|
928
|
+
// isPublishable = true;
|
|
929
|
+
// } catch (err) {
|
|
930
|
+
// reason = `The package registry eiher does not exist or you are not authenticated.`
|
|
931
|
+
// isPublishable = false;
|
|
932
|
+
// }
|
|
933
|
+
// 1) if this version has already been published
|
|
934
|
+
// (lets do this some other time - it's practically impossible now that the tag has a build number in it)
|
|
935
|
+
isPublishable = yield this.hasYetToBePublished(fullPackageName, version, workingFolder);
|
|
936
|
+
if (!isPublishable) {
|
|
937
|
+
reason = `The package ${fullPackageName} version ${version} has already been published.`;
|
|
938
|
+
}
|
|
939
|
+
else {
|
|
940
|
+
// 2) if there are uncommitted changes
|
|
941
|
+
let uncommittedChanges = yield this.gitHasChanges(workingFolder);
|
|
942
|
+
if (uncommittedChanges) {
|
|
943
|
+
isPublishable = false;
|
|
944
|
+
reason = `Cannot publish with uncommitted changes. Undo or commit them to source control and try again.`;
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
// 3) if no commits have been made since the last creation of the package on this branch
|
|
948
|
+
// (npm pack and publish are the same UNLESS we decide to go local)
|
|
949
|
+
let branch = yield this.gitCurrentBranchFor(workingFolder);
|
|
950
|
+
let findCommand = `npm view ${fullPackageName}@'like ${version}-${branch}.*' --json time`;
|
|
951
|
+
let lastPublish = new Date("12/19/2019 18:00 -0600");
|
|
952
|
+
let logcmd = `git log --since "${lastPublish}" --format=oneline`;
|
|
953
|
+
let commits = yield this._cliExec.execAsyncStdOut(logcmd, { cwd: workingFolder });
|
|
954
|
+
if (!commits) {
|
|
955
|
+
isPublishable = false;
|
|
956
|
+
reason = `No source code has been committed since the last publish.`;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
if (!isPublishable)
|
|
961
|
+
this.logger.debug(`Module should not be published: ${reason}`);
|
|
962
|
+
resolve(isPublishable);
|
|
963
|
+
}
|
|
964
|
+
catch (err) {
|
|
965
|
+
reject(err);
|
|
966
|
+
}
|
|
967
|
+
}));
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
/** Installs any missing dependency packages. */
|
|
971
|
+
dependencyInstallAll() {
|
|
972
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
973
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
974
|
+
try {
|
|
975
|
+
let projectRoot = this.getConfigRoot();
|
|
976
|
+
let cmd = `npm install`;
|
|
977
|
+
let result = yield this._cliExec.execAsync(cmd, { cwd: projectRoot });
|
|
978
|
+
if (result.stderr) {
|
|
979
|
+
if (this.npmStdErrIsJustAWarning(result.stderr)) {
|
|
980
|
+
this.logger.debug(`Warnings found: \n${result.stderr}`);
|
|
981
|
+
}
|
|
982
|
+
else {
|
|
983
|
+
throw new Error(`Error attempting to install missing dependency packages: ${result.stderr}`);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
resolve();
|
|
987
|
+
}
|
|
988
|
+
catch (err) {
|
|
989
|
+
reject(err);
|
|
990
|
+
}
|
|
991
|
+
}));
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
dependencyInstall(name, version) {
|
|
995
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
996
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
997
|
+
try {
|
|
998
|
+
let projectRoot = this.getConfigRoot();
|
|
999
|
+
let cmd = `npm install --save-prod ${name}`;
|
|
1000
|
+
if (version) {
|
|
1001
|
+
cmd = cmd.concat(`@${version}`);
|
|
1002
|
+
}
|
|
1003
|
+
let result = yield this._cliExec.execAsync(cmd, { cwd: projectRoot });
|
|
1004
|
+
if (result.stderr) {
|
|
1005
|
+
if (this.npmStdErrIsJustAWarning(result.stderr)) {
|
|
1006
|
+
this.logger.debug(`Warnings found: \n${result.stderr}`);
|
|
1007
|
+
}
|
|
1008
|
+
else {
|
|
1009
|
+
throw new Error(`Error attempting to install npm package [${name}]: ${result.stderr}`);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
resolve();
|
|
1013
|
+
}
|
|
1014
|
+
catch (err) {
|
|
1015
|
+
reject(err);
|
|
1016
|
+
}
|
|
1017
|
+
}));
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Sources a new dependency into the project
|
|
1022
|
+
* from an existing repo url,
|
|
1023
|
+
* initializes it with npm if it is not already,
|
|
1024
|
+
* publishes the npm package if it does not already exist,
|
|
1025
|
+
* and sources the dependency.
|
|
1026
|
+
* Uses the version currently specified in its package.json
|
|
1027
|
+
* for the dependency reference in this project.
|
|
1028
|
+
*
|
|
1029
|
+
* @param cloneUrl The official clone url for the repository.
|
|
1030
|
+
* @param branch The source code branch to switch the dependency to.
|
|
1031
|
+
* @param packageName (Optional: defaults to the repo name) The globally unique name to use for the npm package if initializing npm, including any scope prefix, eg: "@codiac/").
|
|
1032
|
+
* @param initVersion (Optional: defaults to the built in initial version number 0.0.0-1) The version number to use if initializing npm for the dependency.
|
|
1033
|
+
*/
|
|
1034
|
+
dependencyAuthorNew(cloneUrl, packageName, branch, initVersion) {
|
|
1035
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1036
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1037
|
+
let submoduled = false;
|
|
1038
|
+
let folderName = packageName;
|
|
1039
|
+
try {
|
|
1040
|
+
// if (!folderName) folderName = fileBaseName(cloneUrl);
|
|
1041
|
+
// 1) Submodule it with source control
|
|
1042
|
+
let subm = yield this.addSubmodule(cloneUrl, packageName, undefined, undefined, branch); // TODO: consider switching to branch inside this fxn
|
|
1043
|
+
submoduled = true;
|
|
1044
|
+
let projectRoot = this.getConfigRoot();
|
|
1045
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, subm.folderName);
|
|
1046
|
+
let execOptions = { cwd: `${submoduleFolder}` };
|
|
1047
|
+
// 3) Ensure the packager is initialized in the submodule project.
|
|
1048
|
+
let pj = yield this.readNpmPackageJson(submoduleFolder);
|
|
1049
|
+
if (pj == undefined) {
|
|
1050
|
+
// Prompt the user for a scope and package name
|
|
1051
|
+
// try to validate that the name doesnt exist,
|
|
1052
|
+
// but beware that instead of incurring a 403 or 401 or some kind of authorization failure,
|
|
1053
|
+
// private pkgs will appear as "does not exist"
|
|
1054
|
+
// but will throw errors if you attempt to author packages with that name.
|
|
1055
|
+
// (Thanks, NPM)
|
|
1056
|
+
this.logger.debug(`This dependency needs to be initialized for packaging.`);
|
|
1057
|
+
let entered = yield this.ux.prompt("scope", "Package scope prefix (enter for none): ", false, "");
|
|
1058
|
+
let scope = entered || "";
|
|
1059
|
+
if (!scope.startsWith("@"))
|
|
1060
|
+
scope = `@${scope}`;
|
|
1061
|
+
let pkgName = yield this.ux.prompt("pkgName", "Package name: ", true, subm.folderName);
|
|
1062
|
+
subm.packageName = `${scope}/${pkgName}`;
|
|
1063
|
+
subm.lastUsedVersion = initVersion || dx_constants_1.DxConstants.DEFAULT_INIT_PACKAGE_VERSION;
|
|
1064
|
+
// Havent figured out how to wire up stdin on an execAsync call yet.
|
|
1065
|
+
// await this.execAndCommit([ `npm init` ], `npm initialization of ${name}`, submoduleFolder);
|
|
1066
|
+
// await this.execAndCommit([ `npm init -y` ], `npm initialization of ${name}`, submoduleFolder);
|
|
1067
|
+
yield this._cliExec.execAsyncStdOut(`npm init -y`, { cwd: submoduleFolder });
|
|
1068
|
+
// This (below) is one way to do it,
|
|
1069
|
+
// though npm tags the git branch with the version number,
|
|
1070
|
+
// which can cause problems if npm and git get out of sync
|
|
1071
|
+
// from this thaul command failing or being run a few times.
|
|
1072
|
+
// await this.execAndCommit([ `npm version ${version} --allow-same-version` ], `set initial npm version to ${version}`, submoduleFolder);
|
|
1073
|
+
pj = yield this.readNpmPackageJson(submoduleFolder);
|
|
1074
|
+
pj.name = subm.packageName;
|
|
1075
|
+
pj.version = subm.lastUsedVersion;
|
|
1076
|
+
pj.repository = { type: "git", url: subm.cloneUrl }; // we'll need this in order to source it.
|
|
1077
|
+
yield this.writeNpmPackageJson(pj, submoduleFolder);
|
|
1078
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1079
|
+
let index = _.findIndex(cfg.submodules, sm => sm.folderName == subm.folderName);
|
|
1080
|
+
cfg.submodules[index] = subm;
|
|
1081
|
+
yield this._projCfgRepo.updateProjectConfigFile(cfg);
|
|
1082
|
+
}
|
|
1083
|
+
this.logger.debug("package.json: " + JSON.stringify(pj));
|
|
1084
|
+
// 3a) Should the main (parent) project commit a ref the latest commmit of the dependency (if there are any)?
|
|
1085
|
+
// 4) Perform the initial publish if reqd
|
|
1086
|
+
if (yield this.hasYetToBePublished(pj.name, pj.version, submoduleFolder)) {
|
|
1087
|
+
yield this._cliExec.execAsyncStdOut(`npm publish`, execOptions);
|
|
1088
|
+
// this might create a package-lock.json that needs to be committed
|
|
1089
|
+
yield this._cliExec.execAsyncStdOut(`npm view ${pj.name}@${pj.version}`, execOptions);
|
|
1090
|
+
}
|
|
1091
|
+
else {
|
|
1092
|
+
this.logger.debug(`The package ${pj.name}@${pj.version} has already been previously published; it will be used as the dependency.`);
|
|
1093
|
+
}
|
|
1094
|
+
// 5) Add the submodule as a dependency of the main project
|
|
1095
|
+
yield this.dependencyInstall(pj.name, pj.version);
|
|
1096
|
+
// 6) Reference its source code directly instead of its installed package.
|
|
1097
|
+
// Q: Does it matter if we npm link before or after we add it as a dependency?
|
|
1098
|
+
yield this.symLinkSubmodule(subm);
|
|
1099
|
+
// 7) If all is successful, push the changes to the remote source control repo.
|
|
1100
|
+
// cmd = `git push`;
|
|
1101
|
+
// this.logger.debug(`Executing: ${cmd}`);
|
|
1102
|
+
// await this._cliExec.execAsync(cmd, execOptions);
|
|
1103
|
+
resolve();
|
|
1104
|
+
}
|
|
1105
|
+
catch (err) {
|
|
1106
|
+
this.logger.debug(err);
|
|
1107
|
+
if (submoduled && folderName) {
|
|
1108
|
+
yield this.removeSubmodule(folderName, true);
|
|
1109
|
+
}
|
|
1110
|
+
reject(err);
|
|
1111
|
+
}
|
|
1112
|
+
}));
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
dependencyUpgrade(dep, version) {
|
|
1116
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1117
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1118
|
+
try {
|
|
1119
|
+
let projectRoot = this.getConfigRoot();
|
|
1120
|
+
// Verify that the dep exists
|
|
1121
|
+
let pj = yield this.readNpmPackageJson();
|
|
1122
|
+
if ((!pj.dependencies || !pj.dependencies[dep]) && (!pj.devDependencies || !pj.devDependencies[dep])) {
|
|
1123
|
+
throw new Error(`Cannot upgrade [${dep}]: it is not currently a dependency in this project.`);
|
|
1124
|
+
}
|
|
1125
|
+
let targetFolder = path.resolve(projectRoot, `./node_modules/`, dep);
|
|
1126
|
+
if (fs.existsSync(targetFolder)) {
|
|
1127
|
+
this.logger.debug(`Clearing target folder: ${targetFolder}`);
|
|
1128
|
+
rimraf.sync(path.join(targetFolder, "**/*"), {});
|
|
1129
|
+
}
|
|
1130
|
+
else {
|
|
1131
|
+
this.logger.debug(`No pre-install-removal to do: npm target folder doesnt exist: ${targetFolder}`);
|
|
1132
|
+
}
|
|
1133
|
+
// let cmd = `npm upgrade ${dep}`;
|
|
1134
|
+
let cmd = `npm install ${dep}@latest`;
|
|
1135
|
+
if (version) {
|
|
1136
|
+
cmd = `npm install ${dep}@${version}`;
|
|
1137
|
+
}
|
|
1138
|
+
yield this._cliExec.spawnAndLog(cmd, projectRoot);
|
|
1139
|
+
// let output = await this._cliExec.execAsyncStdOut(cmd, { cwd: projectRoot });
|
|
1140
|
+
// if (output) this.logger.debug(output);
|
|
1141
|
+
resolve();
|
|
1142
|
+
}
|
|
1143
|
+
catch (err) {
|
|
1144
|
+
reject(err);
|
|
1145
|
+
}
|
|
1146
|
+
}));
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
/** Forces local source control to refresh its status
|
|
1150
|
+
* and returns true when uncommitted changes exist
|
|
1151
|
+
* on the local machine (staged AND unstaged)
|
|
1152
|
+
* for the git repo corresponding to the given working directory.
|
|
1153
|
+
* @param workingDirectory The fully qualified path in which to run the git status command.
|
|
1154
|
+
*/
|
|
1155
|
+
gitHasChanges(workingDirectory) {
|
|
1156
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1157
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1158
|
+
try {
|
|
1159
|
+
// we were moving too fast for git to see our changes.
|
|
1160
|
+
let cmdRefresh = `git update-index --again`;
|
|
1161
|
+
yield this._cliExec.execAsyncStdOut(cmdRefresh, { cwd: workingDirectory });
|
|
1162
|
+
// let cmd = `git diff --stat` // returns empty string when no changes exist
|
|
1163
|
+
let cmd = `git status --short`; // returns empty string when no changes exist
|
|
1164
|
+
let changes = yield this._cliExec.execAsyncStdOut(cmd, { cwd: workingDirectory });
|
|
1165
|
+
let isDirty = (changes != undefined && changes != "");
|
|
1166
|
+
resolve(isDirty);
|
|
1167
|
+
}
|
|
1168
|
+
catch (err) {
|
|
1169
|
+
reject(err);
|
|
1170
|
+
}
|
|
1171
|
+
}));
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
/** Returns a distinct list of branch names (without any prefixes such as "remotes/origin/").
|
|
1175
|
+
* @param remotes (optional: defaults to false) Flag to include remote branches.
|
|
1176
|
+
* @param locals (optional: defaults to true) Flag to include local branches.
|
|
1177
|
+
* @param repoRoot (optional: defaults to toyhauler project root) root folder of the repo being queried (used as the working folder for the git commands).
|
|
1178
|
+
*/
|
|
1179
|
+
gitListBranches(remotes = false, locals = true, repoRoot) {
|
|
1180
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1181
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1182
|
+
try {
|
|
1183
|
+
let workingFolder = repoRoot || this.getConfigRoot();
|
|
1184
|
+
let branches = [];
|
|
1185
|
+
let remotesArg = "";
|
|
1186
|
+
if (remotes) {
|
|
1187
|
+
remotesArg = (locals) ? "--all" : "--remotes";
|
|
1188
|
+
}
|
|
1189
|
+
// Ensures an up-to-date listing of the remotes
|
|
1190
|
+
// (otherwise we only see what was there on our last pull)
|
|
1191
|
+
let cmdRefresh = `git remote update origin --prune`;
|
|
1192
|
+
yield this._cliExec.execAsyncStdOut(cmdRefresh, { cwd: workingFolder });
|
|
1193
|
+
let cmd = `git branch --list ${remotesArg}`;
|
|
1194
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder });
|
|
1195
|
+
branches = output.trim().split("\n")
|
|
1196
|
+
.map(x => x.trim())
|
|
1197
|
+
.map(x => x.startsWith("* ") ? x.substr(2) : x) // git prefixes the current branch with "* "
|
|
1198
|
+
.map(x => x.substring(x.lastIndexOf("/") + 1))
|
|
1199
|
+
.sort();
|
|
1200
|
+
branches = _.sortedUniq(branches);
|
|
1201
|
+
this.logger.trace("branches:");
|
|
1202
|
+
this.logger.trace(branches.join("\n"));
|
|
1203
|
+
resolve(branches);
|
|
1204
|
+
}
|
|
1205
|
+
catch (err) {
|
|
1206
|
+
reject(err);
|
|
1207
|
+
}
|
|
1208
|
+
}));
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
/** Returns a distinct list of branch names (without any prefixes such as "remotes/origin/").
|
|
1212
|
+
* @param branchName duh.
|
|
1213
|
+
* @param remotes (optional: defaults to false) Flag to include remote branches.
|
|
1214
|
+
* @param locals (optional: defaults to true) Flag to include local branches.
|
|
1215
|
+
* @param repoRoot (optional: defaults to toyhauler project root) root folder of the repo being queried (used as the working directory for the git commands).
|
|
1216
|
+
*/
|
|
1217
|
+
gitBranchExists(branchName, remotes = false, locals = true, repoRoot) {
|
|
1218
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1219
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1220
|
+
try {
|
|
1221
|
+
let branches = yield this.gitListBranches(remotes, locals, repoRoot);
|
|
1222
|
+
let exists = branches.includes(branchName);
|
|
1223
|
+
resolve(exists);
|
|
1224
|
+
}
|
|
1225
|
+
catch (err) {
|
|
1226
|
+
reject(err);
|
|
1227
|
+
}
|
|
1228
|
+
}));
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
/** Switches the main project and any sourced dependencies to the given source code branch.
|
|
1232
|
+
* @param branchName duh.
|
|
1233
|
+
* @param autoCreate (optional: defaults to true) Turn this off to prevent creation of the branch in the sourced dependencies (if missing). CAUTION: This will lead to sourced dependencies on different branches than the main project.
|
|
1234
|
+
* @param track (Optional: defaults to false) If autoCreate is set and branches are created, creates a matching upstream branch at origin.
|
|
1235
|
+
*/
|
|
1236
|
+
gitSwitchToBranch(branchName, autoCreate = true, track = false) {
|
|
1237
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1238
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1239
|
+
try {
|
|
1240
|
+
let projectRoot = this.getConfigRoot();
|
|
1241
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1242
|
+
if (yield !this.gitBranchExists(branchName, true, true)) {
|
|
1243
|
+
if (autoCreate) {
|
|
1244
|
+
yield this.gitCreateBranch(branchName, track);
|
|
1245
|
+
}
|
|
1246
|
+
else {
|
|
1247
|
+
throw new Error(`Cannot switch to branch [${branchName}]: it does not exist.`);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
this.logger.debug(`Switching to branch [${branchName}] in main project [${cfg.name}]...`);
|
|
1251
|
+
let cmd = `git checkout ${branchName}`;
|
|
1252
|
+
let output = yield this._cliExec.execAsync(cmd, { cwd: projectRoot });
|
|
1253
|
+
// create and switch to branch in each sourced dependency...
|
|
1254
|
+
// We just switched branches, so we need to reload the config,
|
|
1255
|
+
// since this branch mau have diff sourced dependencies.
|
|
1256
|
+
cfg = yield this.readCodiacProjectConfig();
|
|
1257
|
+
for (let index in cfg.submodules) {
|
|
1258
|
+
let submodule = cfg.submodules[index];
|
|
1259
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1260
|
+
let exists = yield this.gitBranchExists(branchName, true, true, submoduleFolder);
|
|
1261
|
+
let doit = exists;
|
|
1262
|
+
if (!exists && autoCreate) {
|
|
1263
|
+
yield this.gitCreateBranch(branchName, track, submoduleFolder);
|
|
1264
|
+
}
|
|
1265
|
+
if (doit) {
|
|
1266
|
+
this.logger.debug(`Switching to branch [${branchName}] in sourced dependency: ${submodule.folderName}`);
|
|
1267
|
+
let outputsub = yield this._cliExec.execAsyncStdOut(cmd, { cwd: submoduleFolder });
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
resolve();
|
|
1271
|
+
}
|
|
1272
|
+
catch (err) {
|
|
1273
|
+
reject(err);
|
|
1274
|
+
}
|
|
1275
|
+
}));
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
/** Creates a new branch in repo rooted in the the given folder. DOES NOT SWITCH TO IT.
|
|
1279
|
+
* @param branchName duh.
|
|
1280
|
+
* @param track (Optional: defaults to false) Creates a matching upstream branch at origin.
|
|
1281
|
+
* @param repoRoot (optional: defaults to toyhauler project root) root folder of the repo being queried (used as the working directory for the git commands).
|
|
1282
|
+
*/
|
|
1283
|
+
gitCreateBranch(branchName, track = false, repoRoot) {
|
|
1284
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1285
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1286
|
+
try {
|
|
1287
|
+
let workingFolder = repoRoot || this.getConfigRoot();
|
|
1288
|
+
let trackFlag = (track) ? " --track" : "";
|
|
1289
|
+
let cmd = `git branch ${trackFlag} ${branchName}`;
|
|
1290
|
+
this.logger.debug(`Creating branch [${branchName}] in ${workingFolder}`);
|
|
1291
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder });
|
|
1292
|
+
if (output)
|
|
1293
|
+
this.logger.debug(output);
|
|
1294
|
+
resolve();
|
|
1295
|
+
}
|
|
1296
|
+
catch (err) {
|
|
1297
|
+
reject(err);
|
|
1298
|
+
}
|
|
1299
|
+
}));
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
/** Returns the current branch for the main proiject and any currently sourced dependencies. */
|
|
1303
|
+
gitEachCurrentBranch() {
|
|
1304
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1305
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1306
|
+
try {
|
|
1307
|
+
let projectRoot = this.getConfigRoot();
|
|
1308
|
+
let currentBranch = yield this.gitCurrentBranchFor(projectRoot);
|
|
1309
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1310
|
+
let output = {};
|
|
1311
|
+
output[cfg.name] = currentBranch;
|
|
1312
|
+
for (let index in cfg.submodules) {
|
|
1313
|
+
let submodule = cfg.submodules[index];
|
|
1314
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1315
|
+
let submoduleBranch = yield this.gitCurrentBranchFor(submoduleFolder);
|
|
1316
|
+
output[submodule.packageName] = submoduleBranch;
|
|
1317
|
+
}
|
|
1318
|
+
resolve(output);
|
|
1319
|
+
}
|
|
1320
|
+
catch (err) {
|
|
1321
|
+
reject(err);
|
|
1322
|
+
}
|
|
1323
|
+
}));
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
/** Retrieves just the abbreviated name of the current branch. */
|
|
1327
|
+
gitCurrentBranchNameFor(workingFolder) {
|
|
1328
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1329
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1330
|
+
try {
|
|
1331
|
+
// This one will return the branch name without the "refs/heads/" prefix...
|
|
1332
|
+
let cmd = "git rev-parse --abbrev-ref HEAD";
|
|
1333
|
+
let branch = yield this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder });
|
|
1334
|
+
resolve(branch);
|
|
1335
|
+
}
|
|
1336
|
+
catch (err) {
|
|
1337
|
+
reject(err);
|
|
1338
|
+
}
|
|
1339
|
+
}));
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
/** Retrieves the current branch for the given folder.
|
|
1343
|
+
* (Cuz git somehow makes that nontrivial).
|
|
1344
|
+
* @param workingFolder The folder from which to run the git command. */
|
|
1345
|
+
gitCurrentBranchFor(workingFolder) {
|
|
1346
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1347
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1348
|
+
try {
|
|
1349
|
+
// COMMENTED OUT: we wanted a branch instance with more info on it.
|
|
1350
|
+
// cuz 'git branch' returns a list of all local branches with an asterisk preceding the current one.
|
|
1351
|
+
// let magicalGitIncantation = `git branch | grep \\* | cut -d ' ' -f2-`;
|
|
1352
|
+
// return this._cliExec.execAsyncStdOut(magicalGitIncantation, { cwd: workingFolder});
|
|
1353
|
+
// from: https://stackoverflow.com/questions/6245570/how-to-get-the-current-branch-name-in-git
|
|
1354
|
+
// // NOTE:
|
|
1355
|
+
// // Using the --show-current argument ensures results despite there being no commits in the current tree.
|
|
1356
|
+
// // BUT WE CANT USE IT BC: --show-current requires git > 2.22
|
|
1357
|
+
// let formatArg = `--format "%(refname)|%(upstream)|%(if)%(HEAD)%(then)true%(else)false%(end)"`
|
|
1358
|
+
// let cmd = `git branch --show-current ${formatArg}`
|
|
1359
|
+
// let joined = await this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder });
|
|
1360
|
+
// let lines = joined.split("\n").filter(s => s.endsWith('|true'));
|
|
1361
|
+
// let split = lines[0].split('|');
|
|
1362
|
+
// this.logger.trace('split: ', split);
|
|
1363
|
+
// let branch = new Branch(split[0], split[2] == "true");
|
|
1364
|
+
// if (split[1] != "") branch.upstream = split[1];
|
|
1365
|
+
// So we can use "git symbolic-ref HEAD", which works in both cases (with and without any commits / detached ahead state)
|
|
1366
|
+
// this will; return a fully qaulified branch name, eg: "refs/heads/master", which we will nbeed to parse.
|
|
1367
|
+
let cmd = `git symbolic-ref HEAD`;
|
|
1368
|
+
let fullyQualified = yield this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder })
|
|
1369
|
+
.catch((error) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1370
|
+
// BYG: Added this for CI support inside an agent. git symbolic-ref HEAD throw even with it checked out. Somehow the way the branch is detached doesnt allow that call to resolve.
|
|
1371
|
+
this.logger.warn(`Cannot use 'git symbolic-ref HEAD' /n ${JSON.stringify(error, undefined, 2)}`);
|
|
1372
|
+
let formatArg = `--format "%(refname)|%(upstream)|%(if)%(HEAD)%(then)true%(else)false%(end)"`;
|
|
1373
|
+
let cmd = `git branch --show-current`; //${formatArg}
|
|
1374
|
+
let branchName = yield this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder })
|
|
1375
|
+
.catch(error => {
|
|
1376
|
+
throw new contracts_1.CodiacError(`Cannot find the current branch name /n ${JSON.stringify(error, undefined, 2)}`);
|
|
1377
|
+
});
|
|
1378
|
+
return branchName;
|
|
1379
|
+
}));
|
|
1380
|
+
let name = fullyQualified.split("/").reverse()[0];
|
|
1381
|
+
let branch = new branch_1.Branch(name, true);
|
|
1382
|
+
resolve(branch);
|
|
1383
|
+
}
|
|
1384
|
+
catch (err) {
|
|
1385
|
+
reject(err);
|
|
1386
|
+
}
|
|
1387
|
+
}));
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
/** Merges the given branch with the current one
|
|
1391
|
+
* for the main project and all sourced dependencies.
|
|
1392
|
+
* @param branchName The branch to merge into the current one.
|
|
1393
|
+
* @param commit Commits if merge succeeds. */
|
|
1394
|
+
gitMerge(branchName, commit = false) {
|
|
1395
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1396
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1397
|
+
try {
|
|
1398
|
+
let projectRoot = this.getConfigRoot();
|
|
1399
|
+
let currentBranch = yield this.gitCurrentBranchFor(projectRoot);
|
|
1400
|
+
let commitArg = (commit) ? "--commit" : "--no-commit";
|
|
1401
|
+
let cmd = `git merge ${commitArg} ${branchName}`;
|
|
1402
|
+
if (branchName != currentBranch.name) {
|
|
1403
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: projectRoot });
|
|
1404
|
+
if (output)
|
|
1405
|
+
this.logger.debug(output);
|
|
1406
|
+
}
|
|
1407
|
+
else {
|
|
1408
|
+
this.logger.debug(`Operation cancelled: you attempted to merge branch ${branchName} into itself on the main project. No work was done on the main project.`);
|
|
1409
|
+
}
|
|
1410
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1411
|
+
for (let index in cfg.submodules) {
|
|
1412
|
+
let submodule = cfg.submodules[index];
|
|
1413
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1414
|
+
let submoduleBranch = yield this.gitCurrentBranchFor(submoduleFolder);
|
|
1415
|
+
if (branchName != submoduleBranch.name) {
|
|
1416
|
+
// 1) check if the branch to merge from even exists for this submodule
|
|
1417
|
+
// 2) run the merge (take default comments)
|
|
1418
|
+
this.logger.debug(`Merging dependency branch ${branchName} into the ${submoduleBranch} branch of ${submodule.folderName}...`);
|
|
1419
|
+
this.logger.debug(`STUBBED: Not trying this on deps yet: ${cmd}`);
|
|
1420
|
+
// let output = await this._cliExec.execAsyncStdOut(cmdsub, { cwd: submoduleFolder });
|
|
1421
|
+
// if (output) this.logger.debug(output);
|
|
1422
|
+
}
|
|
1423
|
+
else {
|
|
1424
|
+
this.logger.debug(`Operation cancelled: you attempted to merge branch ${branchName} into itself for ${submodule.folderName}. No work was done on this sourced dependency.`);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
resolve();
|
|
1428
|
+
}
|
|
1429
|
+
catch (err) {
|
|
1430
|
+
reject(err);
|
|
1431
|
+
}
|
|
1432
|
+
}));
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
/** Syncs the current branch with the given branch by merging the given branch into it. */
|
|
1436
|
+
gitSyncWith(branchToPullFrom, includeDependencies = false, targetDependency) {
|
|
1437
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1438
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1439
|
+
try {
|
|
1440
|
+
let projRoot = this.getConfigRoot();
|
|
1441
|
+
let repoRoot = yield this.getRepoRoot(projRoot);
|
|
1442
|
+
let origBranch = yield this.gitCurrentBranchNameFor(projRoot);
|
|
1443
|
+
let exists = yield this.gitBranchExists(branchToPullFrom, true, true, repoRoot);
|
|
1444
|
+
if (exists) {
|
|
1445
|
+
yield this.gitSwitchToBranch(branchToPullFrom, false);
|
|
1446
|
+
yield this.gitPull();
|
|
1447
|
+
yield this.gitSwitchToBranch(origBranch, false);
|
|
1448
|
+
yield this.gitMerge(branchToPullFrom, true);
|
|
1449
|
+
this.logger.debug(`Synced with latest from ${branchToPullFrom}`);
|
|
1450
|
+
}
|
|
1451
|
+
else {
|
|
1452
|
+
// TODO: this lib may be used outside of a console, so emit a workflow status OR throw new Error(`Branch: ${branchToPullFrom} does not exist.`)
|
|
1453
|
+
this.logger.error(`Branch: ${branchToPullFrom} does not exist.`);
|
|
1454
|
+
}
|
|
1455
|
+
resolve();
|
|
1456
|
+
}
|
|
1457
|
+
catch (err) {
|
|
1458
|
+
reject(err);
|
|
1459
|
+
}
|
|
1460
|
+
}));
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
/** Lists uncommitted changed files (staged, unstaged, or both).
|
|
1464
|
+
* All paths are relative to the main project root.
|
|
1465
|
+
* (if both staged and unstaged are ignored, then both are returned)
|
|
1466
|
+
* @param unstaged Include unstaged files.
|
|
1467
|
+
* @param staged Include staged files.
|
|
1468
|
+
* @param repoRoot (optional: defaults to main project root) fully qualified path to the root folder of the cloned repo.
|
|
1469
|
+
*/
|
|
1470
|
+
gitListChanges(status, repoRoot) {
|
|
1471
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1472
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1473
|
+
try {
|
|
1474
|
+
let projectRoot = this.getConfigRoot();
|
|
1475
|
+
let workingFolder = repoRoot || projectRoot;
|
|
1476
|
+
// ---------------------------------------------------------
|
|
1477
|
+
// It'd be nice if this approach covered it,
|
|
1478
|
+
// but git diff can't include newly added files (untracked)
|
|
1479
|
+
// cuz they have no history.
|
|
1480
|
+
//
|
|
1481
|
+
// let filterArg: string;
|
|
1482
|
+
// if ((staged && unstaged) || (staged == unstaged == undefined)) {
|
|
1483
|
+
// filterArg = "HEAD" // includes both staged and unstaged
|
|
1484
|
+
// } else if (staged) {
|
|
1485
|
+
// filterArg = "--staged" // staged only
|
|
1486
|
+
// } else {
|
|
1487
|
+
// filterArg = "" // unstaged only
|
|
1488
|
+
// }
|
|
1489
|
+
// let cmd = `git diff --name-only ${filterArg}`
|
|
1490
|
+
// let result = await this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder });
|
|
1491
|
+
// let output = (result) ? result.split("\n") : [];
|
|
1492
|
+
//
|
|
1493
|
+
// ...and it seems git status needs us to do our own filtering of its output,
|
|
1494
|
+
// so we're left with the following:
|
|
1495
|
+
// ---------------------------------------------------------
|
|
1496
|
+
let cmd = `git status --porcelain=1`; // porcelain is a parseable format that git has committed to keeping backward compatible.
|
|
1497
|
+
let result = yield this._cliExec.execAsyncStdOut(cmd, { cwd: workingFolder });
|
|
1498
|
+
let output = (result) ? result.split("\n") : [];
|
|
1499
|
+
// Now parse the git status porcelain output
|
|
1500
|
+
// (character 0 is the staged status, character 1 is unstaged status, character 2 is a space)
|
|
1501
|
+
switch (status) {
|
|
1502
|
+
case "staged":
|
|
1503
|
+
output = output.filter(line => (line.charAt(0) != " ") && (line.charAt(0) != "?"));
|
|
1504
|
+
break;
|
|
1505
|
+
case "unstaged":
|
|
1506
|
+
output = output.filter(line => line.charAt(1) != ' ');
|
|
1507
|
+
break;
|
|
1508
|
+
}
|
|
1509
|
+
output = output.map(x => x.slice(3));
|
|
1510
|
+
// Recurse sourced dependencies
|
|
1511
|
+
// (only if the caller asked for the main project)
|
|
1512
|
+
if (workingFolder == projectRoot) {
|
|
1513
|
+
let cfg = this.readCodiacProjectConfig();
|
|
1514
|
+
let repoRoot = yield this.getRepoRoot(projectRoot);
|
|
1515
|
+
for (let index in cfg.submodules) {
|
|
1516
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, cfg.submodules[index].folderName);
|
|
1517
|
+
let changes = yield this.gitListChanges(status, submoduleFolder);
|
|
1518
|
+
let pathPrefix = path.relative(repoRoot, submoduleFolder);
|
|
1519
|
+
output = output.concat(changes.map(f => path.join(pathPrefix, f)));
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
output = output.sort();
|
|
1523
|
+
resolve(output);
|
|
1524
|
+
}
|
|
1525
|
+
catch (err) {
|
|
1526
|
+
reject(err);
|
|
1527
|
+
}
|
|
1528
|
+
}));
|
|
1529
|
+
});
|
|
1530
|
+
}
|
|
1531
|
+
/** Stages the given files for a commit.
|
|
1532
|
+
* @param files (optional: defaults to "all") the space-delimited list of files to stage
|
|
1533
|
+
*/
|
|
1534
|
+
gitStage(files) {
|
|
1535
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1536
|
+
return this.gitPerformStaging("stage", files);
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
/** Removes the given files from the git commit index.
|
|
1540
|
+
* @param files (optional: defaults to "all") the space-delimited list of files to stage
|
|
1541
|
+
*/
|
|
1542
|
+
gitUnstage(files) {
|
|
1543
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1544
|
+
return this.gitPerformStaging("unstage", files);
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
/** Stages or unstages the given files for/from a commit.
|
|
1548
|
+
* @param files (optional: defaults to "all") the space-delimited list of files to stage
|
|
1549
|
+
*/
|
|
1550
|
+
gitPerformStaging(operation, files) {
|
|
1551
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1552
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1553
|
+
try {
|
|
1554
|
+
let projectRoot = this.getConfigRoot();
|
|
1555
|
+
let repoRoot = yield this.getRepoRoot(projectRoot);
|
|
1556
|
+
let doAll = !(files);
|
|
1557
|
+
let mainFiles = files;
|
|
1558
|
+
let doAllArg = (operation == "stage") ? "-A" : "";
|
|
1559
|
+
// the -f prevents an error/warning when gitignore ignores a file
|
|
1560
|
+
// that was staged (this happens for the ref latest commit of a submodule,
|
|
1561
|
+
// which is named after the submodule folder path, which is ignored)
|
|
1562
|
+
// HOWEVER...
|
|
1563
|
+
// If you do a -f on a stage all, you'll get every file under the entire project folder,
|
|
1564
|
+
// so don't let those two flags happen together.
|
|
1565
|
+
let forceArg = (operation == "stage" && files && files.length > 0) ? "-f" : "";
|
|
1566
|
+
let command = (operation == "stage") ? "git add" : "git reset -q";
|
|
1567
|
+
// 1) extract the changes for each sourced dependency
|
|
1568
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1569
|
+
let prefix = path.relative(repoRoot, projectRoot);
|
|
1570
|
+
for (let index in cfg.submodules) {
|
|
1571
|
+
let submodule = cfg.submodules[index];
|
|
1572
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1573
|
+
// This prefix is the path prefix from the main repo to the root of the submodule.
|
|
1574
|
+
// the inbound files will have it, and it needs to be stripped off for the submodule git calls.
|
|
1575
|
+
let subPrefix = path.relative(repoRoot, submoduleFolder) + "/"; // this trailing slash will disinclude the main project change named after the submodule folder itself.
|
|
1576
|
+
this.logger.debug(submodule.folderName + "...");
|
|
1577
|
+
this.logger.debug(`subPrefix ${subPrefix}`);
|
|
1578
|
+
// 1a) Extract the files belonging to the submodule
|
|
1579
|
+
let args = undefined;
|
|
1580
|
+
if (doAll) {
|
|
1581
|
+
args = doAllArg;
|
|
1582
|
+
}
|
|
1583
|
+
else if (mainFiles && mainFiles.length > 0) {
|
|
1584
|
+
let subFiles;
|
|
1585
|
+
subFiles = _.filter(mainFiles, f => f.startsWith(subPrefix));
|
|
1586
|
+
this.logger.debug(JSON.stringify(subFiles));
|
|
1587
|
+
this.logger.debug("mainFiles: " + JSON.stringify(mainFiles));
|
|
1588
|
+
if (subFiles.length > 0) {
|
|
1589
|
+
mainFiles = _.without(mainFiles, ...subFiles);
|
|
1590
|
+
args = subFiles.map(f => f.slice(subPrefix.length)).join(" ");
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
// 1b) Stage em if you got em
|
|
1594
|
+
this.logger.debug(`args: ${args}`);
|
|
1595
|
+
if (args) {
|
|
1596
|
+
this.logger.debug(`Perfoming ${operation} on files from sourced dependency: ${submodule.folderName}...`);
|
|
1597
|
+
let cmdsub = `${command} ${args}`;
|
|
1598
|
+
let output = yield this._cliExec.execAsyncStdOut(cmdsub, { cwd: submoduleFolder });
|
|
1599
|
+
if (output)
|
|
1600
|
+
this.logger.debug(output);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
// 2) stage the main project changes.
|
|
1604
|
+
let fileArgs = undefined;
|
|
1605
|
+
if (doAll) {
|
|
1606
|
+
fileArgs = doAllArg;
|
|
1607
|
+
}
|
|
1608
|
+
else if (mainFiles && mainFiles.length > 0) {
|
|
1609
|
+
fileArgs = mainFiles.join(" ");
|
|
1610
|
+
}
|
|
1611
|
+
if (fileArgs) {
|
|
1612
|
+
this.logger.debug(`Perfoming ${operation} on files from main project: ${cfg.name}...`);
|
|
1613
|
+
let cmd = `${command} ${fileArgs}`;
|
|
1614
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: repoRoot });
|
|
1615
|
+
if (output)
|
|
1616
|
+
this.logger.debug(output);
|
|
1617
|
+
}
|
|
1618
|
+
resolve();
|
|
1619
|
+
}
|
|
1620
|
+
catch (err) {
|
|
1621
|
+
reject(err);
|
|
1622
|
+
}
|
|
1623
|
+
}));
|
|
1624
|
+
});
|
|
1625
|
+
}
|
|
1626
|
+
/** Standard git clone call
|
|
1627
|
+
* @param url valid git url to clone from.
|
|
1628
|
+
* @param targetFolder relative path to the folder into which the repo is to be cloned.
|
|
1629
|
+
*/
|
|
1630
|
+
gitClone(url, targetFolder) {
|
|
1631
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1632
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1633
|
+
try {
|
|
1634
|
+
let cmd = `git clone "${url}" ${targetFolder || ""}`;
|
|
1635
|
+
let responseCode = yield this._cliExec.spawnAndLog(cmd, process.cwd(), undefined, IBetterLogger_1.LogLevel.detail);
|
|
1636
|
+
resolve();
|
|
1637
|
+
}
|
|
1638
|
+
catch (err) {
|
|
1639
|
+
reject(err);
|
|
1640
|
+
}
|
|
1641
|
+
}));
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
/** Debug-Logs any failure but doesn't throw errors.
|
|
1645
|
+
* @param directory Absolute folder path to open.
|
|
1646
|
+
*/
|
|
1647
|
+
tryOpenVsCode(directory) {
|
|
1648
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1649
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1650
|
+
try {
|
|
1651
|
+
let cmd = `code ${directory}`;
|
|
1652
|
+
let outputsub = yield this._cliExec.execAsyncStdOut(cmd, {});
|
|
1653
|
+
if (outputsub)
|
|
1654
|
+
this.logger.debug(outputsub);
|
|
1655
|
+
resolve();
|
|
1656
|
+
}
|
|
1657
|
+
catch (err) {
|
|
1658
|
+
// Let this fail silently without killing the command...
|
|
1659
|
+
this.logger.debug(`Error opening VSCode: ${err.message || err.stderr || ""}`, err);
|
|
1660
|
+
resolve();
|
|
1661
|
+
}
|
|
1662
|
+
}));
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
/** Commits the currently staged changes on the current branch
|
|
1666
|
+
* of the main project and on any sourced dependencies.
|
|
1667
|
+
* @param message The description for this particular commit.
|
|
1668
|
+
*/
|
|
1669
|
+
gitCommit(message) {
|
|
1670
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1671
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1672
|
+
try {
|
|
1673
|
+
let projectRoot = this.getConfigRoot();
|
|
1674
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1675
|
+
let cmd = `git commit -m "${message.replace("\"", "\\\"")}"`;
|
|
1676
|
+
// Commit any staged changes for all sourced dependencies
|
|
1677
|
+
for (let index in cfg.submodules) {
|
|
1678
|
+
let submodule = cfg.submodules[index];
|
|
1679
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1680
|
+
let stagedSub = yield this.gitListChanges("staged", submoduleFolder);
|
|
1681
|
+
if (stagedSub.length > 0) {
|
|
1682
|
+
this.logger.debug(`Committing staged changes in sourced dependency: ${submodule.folderName}`);
|
|
1683
|
+
let outputsub = yield this._cliExec.execAsyncStdOut(cmd, { cwd: submoduleFolder });
|
|
1684
|
+
if (outputsub)
|
|
1685
|
+
this.logger.debug(outputsub);
|
|
1686
|
+
// TODO: stage the associated change in the main project (it'll be named the same as the submodule name)
|
|
1687
|
+
this.logger.debug(`Staging associated change in parent project.`);
|
|
1688
|
+
let cmd3a = `git update-index --again`; // we were moving too fast for git to see our changes.
|
|
1689
|
+
this.logger.debug(cmd3a);
|
|
1690
|
+
yield this._cliExec.execAsync(cmd3a, { cwd: projectRoot });
|
|
1691
|
+
let submoduleRelPath = path.posix.join(dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1692
|
+
let cmdStageInMain = `git add ${submoduleRelPath}`;
|
|
1693
|
+
yield this._cliExec.execAsyncStdOut(cmdStageInMain, { cwd: projectRoot });
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
// Commit any staged files in main project
|
|
1697
|
+
let staged = yield this.gitListChanges("staged");
|
|
1698
|
+
if (staged.length > 0) {
|
|
1699
|
+
this.logger.debug(`Committing staged changes in main project [${cfg.name}]...`);
|
|
1700
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: projectRoot });
|
|
1701
|
+
if (output)
|
|
1702
|
+
this.logger.debug(output);
|
|
1703
|
+
}
|
|
1704
|
+
this.logger.debug(`COMPLETE! "${message.replace("\"", "\\\"")}"`);
|
|
1705
|
+
resolve();
|
|
1706
|
+
}
|
|
1707
|
+
catch (err) {
|
|
1708
|
+
reject(err);
|
|
1709
|
+
}
|
|
1710
|
+
}));
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
/** Returns the hash in the git log that identifies the most recent commit. */
|
|
1714
|
+
gitReadLatestCommitId() {
|
|
1715
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1716
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1717
|
+
try {
|
|
1718
|
+
// For a list of format tokens, see "Table 1" on https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History
|
|
1719
|
+
let cmd = `git log -n 1 --all --pretty=format:"%H"`; // using custom format of "{hash}|{date}|{message}"
|
|
1720
|
+
// NOTE: using the --all flag prevents error when no commits exist: "fatal: your current branch 'master' does not have any commits yet"
|
|
1721
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: this._projectRoot });
|
|
1722
|
+
let hash = output.trim(); // the output likely has a linebreak in it.
|
|
1723
|
+
this.logger.debug(`Latest commit: ${hash}`);
|
|
1724
|
+
// ALTERNATE WAY (more data)
|
|
1725
|
+
// If someday we have a requirement for more data out of this...
|
|
1726
|
+
// let cmd = `git log -n 1 --pretty=format:"%H|%aD|%s"`; // using custom format of "{hash}|{date}|{message}"
|
|
1727
|
+
// let output = await this._cliExec.execAsyncStdOut(cmd, { cwd: this._projectRoot });
|
|
1728
|
+
// this.logger.debug(`Latest commit: ${output}`)
|
|
1729
|
+
// // let hash = output.split("|")[0];
|
|
1730
|
+
// let parts = output.split("|");
|
|
1731
|
+
// let commit: any = { };
|
|
1732
|
+
// let commit.hash = parts.shift();
|
|
1733
|
+
// let commit.commitDate = parts.shift();
|
|
1734
|
+
// let commit.message = parts.join("|");
|
|
1735
|
+
// OTHER ALTERNATE WAY (uses built-in format)
|
|
1736
|
+
// let cmd = `git log -n 1 --pretty=oneline --no-decorate`; // using built-in format
|
|
1737
|
+
// let output = await this._cliExec.execAsyncStdOut(cmd, { cwd: this._projectRoot });
|
|
1738
|
+
// this.logger.debug(`Latest commit: ${output}`)
|
|
1739
|
+
// Git's output is in the format "${hash} ${commit message}", with no quotes around the message.
|
|
1740
|
+
// We'll parse out just the hash
|
|
1741
|
+
// let hash = output.split(" ")[0];
|
|
1742
|
+
resolve(hash);
|
|
1743
|
+
}
|
|
1744
|
+
catch (err) {
|
|
1745
|
+
reject(err);
|
|
1746
|
+
}
|
|
1747
|
+
}));
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
/** Pushes upstream any local commits on the current branch
|
|
1751
|
+
* of the main project and on any sourced dependencies.
|
|
1752
|
+
* @param only (optional, defaults to "all") The name of a specific sourced dependency to pull instead of everything in the project. Pulls latest only for the sourced dependency specified by this parameter.
|
|
1753
|
+
*/
|
|
1754
|
+
gitPushProject(only = "all") {
|
|
1755
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1756
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1757
|
+
try {
|
|
1758
|
+
let projectRoot = this.getConfigRoot();
|
|
1759
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1760
|
+
let branches = yield this.gitEachCurrentBranch();
|
|
1761
|
+
if (only && only != "all") {
|
|
1762
|
+
let sourcedDep = cfg.submodules.find(sm => sm.folderName == only); // TODO: verify that this shouldnt be "sm.packageName" instead.
|
|
1763
|
+
if (sourcedDep) {
|
|
1764
|
+
let relPath = path.posix.join(dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, sourcedDep.folderName);
|
|
1765
|
+
yield this.gitPush(relPath, branches[sourcedDep.packageName]);
|
|
1766
|
+
}
|
|
1767
|
+
else {
|
|
1768
|
+
this.logger.debug(`There is no sourced dependency named: ${only}.`);
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
else {
|
|
1772
|
+
yield this.gitPush("./", branches[cfg.name]);
|
|
1773
|
+
// do so for all sourced dependencies
|
|
1774
|
+
for (let index in cfg.submodules) {
|
|
1775
|
+
let sourcedDep = cfg.submodules[index];
|
|
1776
|
+
let relPath = path.posix.join(dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, sourcedDep.folderName);
|
|
1777
|
+
yield this.gitPush(relPath, branches[sourcedDep.packageName]);
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
resolve();
|
|
1781
|
+
}
|
|
1782
|
+
catch (err) {
|
|
1783
|
+
reject(err);
|
|
1784
|
+
}
|
|
1785
|
+
}));
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1788
|
+
gitPush(relFolderPath, branch) {
|
|
1789
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1790
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1791
|
+
try {
|
|
1792
|
+
this.logger.debug(`Pushing local commits (branch: ${branch.name}) for: ${relFolderPath}`);
|
|
1793
|
+
let projectRoot = this.getConfigRoot();
|
|
1794
|
+
let sourceFolder = path.join(projectRoot, relFolderPath);
|
|
1795
|
+
let upstreamArg = (!branch.upstream) ? `--set-upstream origin ${branch.name}` : ``;
|
|
1796
|
+
let cmd = `git push --porcelain ${upstreamArg}`; // --porcelain keeps output parseable and doesnt write stdout to stderr (instead of --quiet, which simply doesnt report)
|
|
1797
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: sourceFolder });
|
|
1798
|
+
if (output)
|
|
1799
|
+
this.logger.debug(output);
|
|
1800
|
+
resolve();
|
|
1801
|
+
}
|
|
1802
|
+
catch (err) {
|
|
1803
|
+
reject(err);
|
|
1804
|
+
}
|
|
1805
|
+
}));
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1808
|
+
/** Retrieves remote changesets on the current branch
|
|
1809
|
+
* of the main project and on any sourced dependencies.
|
|
1810
|
+
* @param only (optional, defaults to "all") The name of a specific sourced dependency to pull instead of everything in the project. Pulls latest only for the sourced dependency specified by this parameter.
|
|
1811
|
+
*/
|
|
1812
|
+
gitPull(only = "all") {
|
|
1813
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1814
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1815
|
+
try {
|
|
1816
|
+
let projectRoot = this.getConfigRoot();
|
|
1817
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1818
|
+
let cmd = `git pull`;
|
|
1819
|
+
if (only && only != "all") {
|
|
1820
|
+
let submodule = cfg.submodules.find(d => d.folderName == only);
|
|
1821
|
+
if (!submodule) {
|
|
1822
|
+
let deps = yield this.getNpmDependencies(projectRoot);
|
|
1823
|
+
if (deps.indexOf(only) >= 0) {
|
|
1824
|
+
this.logger.warn(`The dependency [${only}] is not currently sourced. Use "codiac dep:source" to source it.`);
|
|
1825
|
+
}
|
|
1826
|
+
else {
|
|
1827
|
+
this.logger.error(`There is no sourced dependency named: [${only}].`);
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
else {
|
|
1831
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1832
|
+
this.logger.notice(`Pulling remote commits into sourced dependency: [${this.styler.hilite(submodule.folderName)}]...`);
|
|
1833
|
+
let outputsub = yield this._cliExec.spawnAndLog(cmd, submoduleFolder);
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
else {
|
|
1837
|
+
this.logger.notice(`Pulling any remote commits into main project: [${this.styler.hilite(cfg.name)}]...`);
|
|
1838
|
+
let output = yield this._cliExec.spawnAndLog(cmd, projectRoot);
|
|
1839
|
+
// do so for all sourced dependencies
|
|
1840
|
+
cfg = yield this.readCodiacProjectConfig();
|
|
1841
|
+
for (let index in cfg.submodules) {
|
|
1842
|
+
let submodule = cfg.submodules[index];
|
|
1843
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1844
|
+
this.logger.notice(`Pulling remote commits into sourced dependency: [${this.styler.hilite(submodule.folderName)}]...`);
|
|
1845
|
+
let outputsub = yield this._cliExec.spawnAndLog(cmd, submoduleFolder);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
resolve();
|
|
1849
|
+
}
|
|
1850
|
+
catch (err) {
|
|
1851
|
+
reject(err);
|
|
1852
|
+
}
|
|
1853
|
+
}));
|
|
1854
|
+
});
|
|
1855
|
+
}
|
|
1856
|
+
// gitStash
|
|
1857
|
+
/** Fails if the branch has pending changes or a pending merge status.
|
|
1858
|
+
* Set the discardChanges argument to ignore any pending status and force the delete.
|
|
1859
|
+
* @param branchName Must be a valid existing branch
|
|
1860
|
+
* @param discardChanges (optional: default = false) Ignores any pending changes or merge status and forces the delete of the branch.
|
|
1861
|
+
*/
|
|
1862
|
+
gitDeleteBranch(branchName, discardChanges = false) {
|
|
1863
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1864
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1865
|
+
try {
|
|
1866
|
+
let projectRoot = this.getConfigRoot();
|
|
1867
|
+
let forceArg = (discardChanges) ? "--force" : "";
|
|
1868
|
+
let cmd = `git branch --delete ${forceArg} ${branchName}`;
|
|
1869
|
+
let output = yield this._cliExec.execAsync(cmd, { cwd: projectRoot });
|
|
1870
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
1871
|
+
for (let index in cfg.submodules) {
|
|
1872
|
+
let submodule = cfg.submodules[index];
|
|
1873
|
+
let submoduleFolder = path.posix.join(projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, submodule.folderName);
|
|
1874
|
+
// TODO: If the branch doesnt exist, dont fail on these.
|
|
1875
|
+
this.logger.debug(`Deleting branch [${branchName}] in sourced dependency: ${submodule.folderName}`);
|
|
1876
|
+
//let outputsub = await this._cliExec.execAsync(cmd, { cwd: submoduleFolder });
|
|
1877
|
+
}
|
|
1878
|
+
resolve();
|
|
1879
|
+
}
|
|
1880
|
+
catch (err) {
|
|
1881
|
+
reject(err);
|
|
1882
|
+
}
|
|
1883
|
+
}));
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
hasYetToBePublished(pkgName, version, cwd) {
|
|
1887
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1888
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1889
|
+
try {
|
|
1890
|
+
let notYetPublished = false;
|
|
1891
|
+
let execOptions = { cwd: cwd };
|
|
1892
|
+
// Honestly, NPM:
|
|
1893
|
+
// npm search is unreliable,
|
|
1894
|
+
// npm view is unreliable,
|
|
1895
|
+
// niether differentiates unauthorized from non-existent,
|
|
1896
|
+
// and no systematic standard syntax for formatting output
|
|
1897
|
+
// WTF. Why dont we have a simple, reliable existence check?!?!
|
|
1898
|
+
// Fuck you, you hacks.
|
|
1899
|
+
// Check if the npm package name in the registry at all...
|
|
1900
|
+
// let cmd = `npm search /^${pkgName}$/ --json` // Why the fuck doesnt search return the listing sometimes (npm view does, but npm search doesnt? WTF!!!?
|
|
1901
|
+
// let matches = await this.execAsyncJson<string[]>(cmd, execOptions);
|
|
1902
|
+
// if (matches.length == 0 || matches.indexOf(pkgName) == 0) {
|
|
1903
|
+
// NOTE: Isnt this NESTED try block greeaaat?
|
|
1904
|
+
// npm's "view-or-fail" is all we have to work with here
|
|
1905
|
+
// cuz npm search is unreliable.
|
|
1906
|
+
let cmd = `npm view ${pkgName} name`; // this projects the name (why does it fail sometimes?)
|
|
1907
|
+
try {
|
|
1908
|
+
let match = yield this._cliExec.execAsyncStdOut(cmd, execOptions);
|
|
1909
|
+
// Now check whether this particular version is published...
|
|
1910
|
+
// NOTE: Oh, and turns out npm view with a VERSION
|
|
1911
|
+
// gives you "view-or-blank" behavior, so we dont have to
|
|
1912
|
+
// nest yet another try block here. Yay consistency! wait.. no.
|
|
1913
|
+
cmd = `npm view ${pkgName}@${version} name`; // name // we were projecting only the name, but got "ReferenceError: name is not defined" ...WTF?
|
|
1914
|
+
let nameFound = yield this._cliExec.execAsyncStdOut(cmd, execOptions);
|
|
1915
|
+
if (nameFound == undefined || nameFound == "") {
|
|
1916
|
+
notYetPublished = true;
|
|
1917
|
+
this.logger.debug(`The package version [${pkgName}@${version}] has not been published.`);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
catch (err) {
|
|
1921
|
+
// npm throws "E404" when missing (or if private and we're unauthorized)
|
|
1922
|
+
// eg: first line of stdout is "npm ERR! code E404"
|
|
1923
|
+
// Can we reliably just parse that exact string?
|
|
1924
|
+
// Or is there a more reliable, actually engineered, way to interpret an error response?
|
|
1925
|
+
notYetPublished = true;
|
|
1926
|
+
this.logger.debug(`The package name [${pkgName}] does not exist in the registry.`);
|
|
1927
|
+
}
|
|
1928
|
+
resolve(notYetPublished);
|
|
1929
|
+
}
|
|
1930
|
+
catch (err) {
|
|
1931
|
+
reject(err);
|
|
1932
|
+
}
|
|
1933
|
+
}));
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
/** OBSOLETE!! Use build() instead. */
|
|
1937
|
+
typescriptBuild(newVersion, buildDef = [], clear) {
|
|
1938
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1939
|
+
return this.build(newVersion, buildDef, clear);
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
/** Increments the version and builds each sourced dependency
|
|
1943
|
+
* and then the main project.
|
|
1944
|
+
* Returns the build number. */
|
|
1945
|
+
build(increment, buildDef = [], clear) {
|
|
1946
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1947
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1948
|
+
var _a, _b;
|
|
1949
|
+
try {
|
|
1950
|
+
let cfg = this.readCodiacProjectConfig();
|
|
1951
|
+
let buildNumber = codiac_common_1.BuildNumberGenerator.getOne(); // TODO: Suffix the build number with the seatId or branch or current user
|
|
1952
|
+
this.logger.notice(`BuildNumber: ${buildNumber}`);
|
|
1953
|
+
// build each sourced dependency
|
|
1954
|
+
for (let subm of cfg.submodules) {
|
|
1955
|
+
yield this.buildSubmodule(subm, clear);
|
|
1956
|
+
}
|
|
1957
|
+
// Get the build command and output folder
|
|
1958
|
+
let cmd = (buildDef && buildDef.length > 0) ? buildDef.join(" && ") : (_a = cfg.buildDef) === null || _a === void 0 ? void 0 : _a.join(" && ");
|
|
1959
|
+
let outputFolder = /* cfg.outputFolder || */ dx_constants_1.DxConstants.DEFAULT_BUILD_OUTPUT_DIR; // how do we make this accurate? Hopefully we dont have to make them declare this in the codiac.json...
|
|
1960
|
+
if (!cmd || cmd.trim() == "") {
|
|
1961
|
+
throw new contracts_1.CodiacError(`No build command has been declared for this project in ${codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME} (set the "buildDef" property to an array of command strings).`);
|
|
1962
|
+
}
|
|
1963
|
+
if (cmd) {
|
|
1964
|
+
this.logger.notice(`Building ${this.styler.hilite(cfg.name)}...`);
|
|
1965
|
+
if (clear && outputFolder)
|
|
1966
|
+
this.clearFolder(outputFolder);
|
|
1967
|
+
yield this._cliExec.spawnAndLog(cmd, this._projectRoot, undefined, IBetterLogger_1.LogLevel.detail);
|
|
1968
|
+
// Copy in any build includes
|
|
1969
|
+
if (outputFolder && cfg.buildIncludes && cfg.buildIncludes.length > 0) {
|
|
1970
|
+
for (const file of cfg.buildIncludes) {
|
|
1971
|
+
let sourceFile = path.join(this._projectRoot, file);
|
|
1972
|
+
let targetFile = path.join(this._projectRoot, outputFolder, file);
|
|
1973
|
+
if (fs.existsSync(sourceFile)) {
|
|
1974
|
+
let dirName = path.dirname(targetFile);
|
|
1975
|
+
yield fse.ensureDir(dirName);
|
|
1976
|
+
yield fse.copy(sourceFile, targetFile);
|
|
1977
|
+
// await this._cliExec.cpAsync(sourceFile, targetFile);
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
// // !!!!! HACK !!!!: copy in the app config
|
|
1982
|
+
// // TODO: This should be some less specific copy command
|
|
1983
|
+
// let sourceFile = path.join(this._projectRoot, "src/app-config.json");
|
|
1984
|
+
// if (fs.existsSync(sourceFile) && outputFolder) {
|
|
1985
|
+
// await this._cliExec.cpAsync(sourceFile, path.join(this._projectRoot, outputFolder, "app-config.json"));
|
|
1986
|
+
// }
|
|
1987
|
+
// This is only for bwd compatibility: codeVersion must always exist.
|
|
1988
|
+
if (!cfg.codeVersion) {
|
|
1989
|
+
cfg.codeVersion = (_b = (yield this.npmGetCurrentVersion())) !== null && _b !== void 0 ? _b : dx_constants_1.DxConstants.DEFAULT_INIT_CODE_VERSION;
|
|
1990
|
+
}
|
|
1991
|
+
if (increment) {
|
|
1992
|
+
// let cliConfig = await this._cfgRepo.read(); // TODO: Make this a lazy-load. This is a bad place for a file sys read.
|
|
1993
|
+
if (this.cliConfig.addBranchNameToPrereleases === true) {
|
|
1994
|
+
let currentBranch = yield this.gitCurrentBranchNameFor(this._projectRoot);
|
|
1995
|
+
if (this.isMainBranch(currentBranch) === false) {
|
|
1996
|
+
increment.preId = currentBranch;
|
|
1997
|
+
// cfg.codeVersion = this.addPrereleaseId(cfg.codeVersion, currentBranch);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
let codeVersion = yield this._workspaceVersioner.incrementCodeVersion(cfg, increment);
|
|
2001
|
+
yield this.npmIncrementVersion(increment);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
resolve(buildNumber);
|
|
2005
|
+
}
|
|
2006
|
+
catch (err) {
|
|
2007
|
+
reject(err);
|
|
2008
|
+
}
|
|
2009
|
+
}));
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
/** Bumps the version as specified.
|
|
2013
|
+
* NOTE!!! Currently uses npm for this!
|
|
2014
|
+
*
|
|
2015
|
+
* ***TODO: Move version persistence to image exports in codiac.json and get off of npm.***
|
|
2016
|
+
*/
|
|
2017
|
+
npmIncrementVersion(newVersion) {
|
|
2018
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2019
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2020
|
+
try {
|
|
2021
|
+
// Increment the package version only after the build has succeeded.
|
|
2022
|
+
// DEV NOTE: Even if there wasnt a tsc build performed, any images built after this will need the new version stamp.
|
|
2023
|
+
// TODO: Extract the version bump into a seaparate call
|
|
2024
|
+
if (newVersion) {
|
|
2025
|
+
let dontCommitIt = " --git-tag-version false"; // Prevents npm from tagging the git branch (which requires all changes to be committed or it fails)
|
|
2026
|
+
if (newVersion.fullName) {
|
|
2027
|
+
this.logger.notice(`Applying new version number ${this.styler.hilite(newVersion.fullName)}...`);
|
|
2028
|
+
yield this._cliExec.execAsyncStdOut(`npm version ${newVersion.fullName} ${dontCommitIt}`, { cwd: this._projectRoot });
|
|
2029
|
+
}
|
|
2030
|
+
else if (newVersion.major) {
|
|
2031
|
+
this.logger.notice(`Incrementing ${"major"} version number...`);
|
|
2032
|
+
yield this._cliExec.execAsyncStdOut(`npm version major ${dontCommitIt}`, { cwd: this._projectRoot });
|
|
2033
|
+
}
|
|
2034
|
+
else if (newVersion.minor) {
|
|
2035
|
+
this.logger.notice(`Incrementing ${"minor"} version number...`);
|
|
2036
|
+
yield this._cliExec.execAsyncStdOut(`npm version minor ${dontCommitIt}`, { cwd: this._projectRoot });
|
|
2037
|
+
}
|
|
2038
|
+
else if (newVersion.patch) {
|
|
2039
|
+
this.logger.notice(`Incrementing ${"patch"} version number...`);
|
|
2040
|
+
yield this._cliExec.execAsyncStdOut(`npm version patch ${dontCommitIt}`, { cwd: this._projectRoot });
|
|
2041
|
+
}
|
|
2042
|
+
else if (newVersion.preId) {
|
|
2043
|
+
this.logger.notice(`Incrementing ${"prerelease"} id and version number...`);
|
|
2044
|
+
yield this._cliExec.execAsyncStdOut(`npm version prerelease --preid ${newVersion.preId} ${dontCommitIt}`, { cwd: this._projectRoot });
|
|
2045
|
+
}
|
|
2046
|
+
else if (newVersion.prerelease) {
|
|
2047
|
+
this.logger.notice(`Incrementing ${"prerelease"} version number...`);
|
|
2048
|
+
yield this._cliExec.execAsyncStdOut(`npm version prerelease ${dontCommitIt}`, { cwd: this._projectRoot });
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
resolve();
|
|
2052
|
+
}
|
|
2053
|
+
catch (err) {
|
|
2054
|
+
reject(err);
|
|
2055
|
+
}
|
|
2056
|
+
}));
|
|
2057
|
+
});
|
|
2058
|
+
}
|
|
2059
|
+
// /** Increments the project code version number by the given increment.
|
|
2060
|
+
// * Retains existing version number if no increment is specified.
|
|
2061
|
+
// * Writes changes to the project config (aka: codiac.json).
|
|
2062
|
+
// * Throws if existing version is invalid.
|
|
2063
|
+
// *
|
|
2064
|
+
// * @param cfg Project config doc (aka: codiac.json deserialized)
|
|
2065
|
+
// */
|
|
2066
|
+
// private async incrementCodeVersion(cfg: ProjectConfig, increment: VersionBump): Promise<ProjectConfig> {
|
|
2067
|
+
// return new Promise<ProjectConfig>(async (resolve, reject) => {
|
|
2068
|
+
// try {
|
|
2069
|
+
// let newVersion = this._imageVersioner.incrementVersion(cfg.codeVersion, increment);
|
|
2070
|
+
// if (newVersion != cfg.codeVersion) {
|
|
2071
|
+
// cfg.codeVersion = newVersion;
|
|
2072
|
+
// await this._projCfgRepo.updateProjectConfigFile(cfg);
|
|
2073
|
+
// }
|
|
2074
|
+
// resolve(cfg);
|
|
2075
|
+
// } catch (err) {
|
|
2076
|
+
// reject(err);
|
|
2077
|
+
// }
|
|
2078
|
+
// });
|
|
2079
|
+
// }
|
|
2080
|
+
// /** Increments the version number of the given image export by the given increment.
|
|
2081
|
+
// * Retains existing version number if no increment is specified.
|
|
2082
|
+
// * Sets to the default init version number if the imageExport doesnt yet have a version declared.
|
|
2083
|
+
// * Writes changes to the project config (aka: codiac.json).
|
|
2084
|
+
// * Throws if existing version is invalid.
|
|
2085
|
+
// *
|
|
2086
|
+
// * @param cfg Project config doc (aka: codiac.json deserialized)
|
|
2087
|
+
// */
|
|
2088
|
+
// private async incrementImageVersion(imageExport: ImageExport, cfg: ProjectConfig, increment: VersionBump): Promise<ImageExport> {
|
|
2089
|
+
// return new Promise<ImageExport>(async (resolve, reject) => {
|
|
2090
|
+
// try {
|
|
2091
|
+
// if (!imageExport.version) imageExport.version = DxConstants.DEFAULT_INIT_IMAGE_VERSION;
|
|
2092
|
+
// let newVersion = this.incrementVersion(imageExport.version, increment);
|
|
2093
|
+
// if (newVersion != imageExport.version) {
|
|
2094
|
+
// imageExport.version = newVersion;
|
|
2095
|
+
// if (!cfg.images) cfg.images = {};
|
|
2096
|
+
// cfg.images[imageExport.name] = imageExport;
|
|
2097
|
+
// await this._projCfgRepo.updateProjectConfigFile(cfg);
|
|
2098
|
+
// }
|
|
2099
|
+
// resolve(imageExport);
|
|
2100
|
+
// } catch (err) {
|
|
2101
|
+
// reject(err);
|
|
2102
|
+
// }
|
|
2103
|
+
// });
|
|
2104
|
+
// }
|
|
2105
|
+
// /** Increments the given semantic version nnumber by the given increment.
|
|
2106
|
+
// * Returns existing version number if no increment is specified.
|
|
2107
|
+
// * Throws if existing version is invalid.
|
|
2108
|
+
// */
|
|
2109
|
+
// public incrementVersion(existing: string, increment: VersionBump): string {
|
|
2110
|
+
// try {
|
|
2111
|
+
// let newVersion: string | null = existing;
|
|
2112
|
+
// if (increment) {
|
|
2113
|
+
// if (increment.fullName) {
|
|
2114
|
+
// this.logger.notice(`Applying new version number ${this.styler.hilite(increment.fullName)}...`);
|
|
2115
|
+
// newVersion = increment.fullName;
|
|
2116
|
+
// } else if (increment.major) {
|
|
2117
|
+
// this.logger.notice(`Incrementing ${"major"} version number...`);
|
|
2118
|
+
// newVersion = semver.inc(existing, "major");
|
|
2119
|
+
// } else if (increment.minor) {
|
|
2120
|
+
// this.logger.notice(`Incrementing ${"minor"} version number...`);
|
|
2121
|
+
// newVersion = semver.inc(existing, "minor");
|
|
2122
|
+
// } else if (increment.patch) {
|
|
2123
|
+
// this.logger.notice(`Incrementing ${"patch"} version number...`);
|
|
2124
|
+
// newVersion = semver.inc(existing, "patch");
|
|
2125
|
+
// } else if (increment.prerelease) {
|
|
2126
|
+
// this.logger.notice(`Incrementing ${"prerelease"} version number...`);
|
|
2127
|
+
// newVersion = semver.inc(existing, "prerelease");
|
|
2128
|
+
// }
|
|
2129
|
+
// if (newVersion == null) throw new CodiacError(`Cannot increment; current version number [${existing}] is not a valid semantic version.`);
|
|
2130
|
+
// }
|
|
2131
|
+
// return newVersion;
|
|
2132
|
+
// } catch (err) {
|
|
2133
|
+
// throw err;
|
|
2134
|
+
// }
|
|
2135
|
+
// }
|
|
2136
|
+
/**
|
|
2137
|
+
* @param subm The sourced dependency project to build.
|
|
2138
|
+
* @param clear (Optional: defaults to false) Clears the output folder before build.
|
|
2139
|
+
*/
|
|
2140
|
+
buildSubmodule(subm, clear) {
|
|
2141
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2142
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2143
|
+
try {
|
|
2144
|
+
let submoduleFolder = path.posix.join(this._projectRoot, dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, subm.folderName);
|
|
2145
|
+
// TODO: Check for changes and skip the build if there's no need.
|
|
2146
|
+
// HACK: git doesnt know whats changes since your last build,
|
|
2147
|
+
// but you could check the time signature on each changed file
|
|
2148
|
+
// and compare it to the time signature recorded from the latest build...?
|
|
2149
|
+
// TODO: Detect if it's a codiac project, in which case, we just hv to run the build script declared in it.
|
|
2150
|
+
// If the current build is a named build,
|
|
2151
|
+
// and there's a matching build for the submodule,
|
|
2152
|
+
// then run the matching build namesake, otherwise, run the default build.
|
|
2153
|
+
let cmd;
|
|
2154
|
+
let outputFolder; // fully qualified path to the build output folder.
|
|
2155
|
+
if (subm.buildScript) {
|
|
2156
|
+
// We coud try this: the cod below loads the npm script: "build"
|
|
2157
|
+
// let pj = await this.readNpmPackageJson(submoduleFolder);
|
|
2158
|
+
// if (pj && pj.scripts && pj.scripts.build) cmd = pj.scripts["build"];
|
|
2159
|
+
cmd = subm.buildScript;
|
|
2160
|
+
}
|
|
2161
|
+
else {
|
|
2162
|
+
// TODO: If it's a dependency, it is likel to have the same default platform build command as the main project (eg: tsc)
|
|
2163
|
+
// Though if the main project is an angular proj that uses webpack, its main build command will be "webpack.." something,
|
|
2164
|
+
// so perhaps a project needs a default build command/script for its dependencies? Or we just have to ask the user when they source it.
|
|
2165
|
+
let tsconfig = this.readTsConfig(submoduleFolder);
|
|
2166
|
+
if (tsconfig) {
|
|
2167
|
+
// Typescript project
|
|
2168
|
+
cmd = "tsc -p .";
|
|
2169
|
+
outputFolder = this.getTsOutputFolder(submoduleFolder, tsconfig);
|
|
2170
|
+
this.logger.detail(`Detected typescript for sourced dependency ${subm.packageName} located in ${submoduleFolder}: using default typescript build because no build script is declared for it in ${codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME}.`);
|
|
2171
|
+
// TODO: DO WE WANT TO KEEP THIS BUILT IN TYPESCRIPT DEFAULT BEHAVIOR?
|
|
2172
|
+
// Or should we simply throw if there's no build explicitly defined for the submodule?
|
|
2173
|
+
}
|
|
2174
|
+
else {
|
|
2175
|
+
this.logger.warn(`Skipping build for sourced dependency ${subm.packageName} located in ${submoduleFolder}: No ${dx_constants_1.DxConstants.TSCONFIG_JSON_FILENAME} was found and no build script is declared in ${codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME}.`);
|
|
2176
|
+
// TODO: Add remediation instructions to that error message
|
|
2177
|
+
// on how to set the buildScript override for that submodule.
|
|
2178
|
+
// NOTE: We cannot just blindly fire any old npm build script that commes down in a dependency.
|
|
2179
|
+
// cuz what a great way to release trojans..
|
|
2180
|
+
// WE MUST get their explicit consent to fire a build script that is written into that source code.
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
if (cmd) {
|
|
2184
|
+
// QUESTION: Can we append the build # without changing the npm version in the package.json?
|
|
2185
|
+
this.logger.notice(`Building sourced dependency: ${this.styler.hilite(subm.folderName)}...`);
|
|
2186
|
+
if (clear && outputFolder)
|
|
2187
|
+
this.clearFolder(outputFolder);
|
|
2188
|
+
yield this._cliExec.spawnAndLog(cmd, submoduleFolder, undefined, IBetterLogger_1.LogLevel.detail);
|
|
2189
|
+
// let output = await this._cliExec.execAsyncStdOut(cmd, { cwd: submoduleFolder }, LogLevel.detail);
|
|
2190
|
+
// if (output) this.logger.debug(output);
|
|
2191
|
+
}
|
|
2192
|
+
resolve();
|
|
2193
|
+
}
|
|
2194
|
+
catch (err) {
|
|
2195
|
+
reject(err);
|
|
2196
|
+
}
|
|
2197
|
+
}));
|
|
2198
|
+
});
|
|
2199
|
+
}
|
|
2200
|
+
/** Determines the build output folder as specified in the given tsconfig doc.
|
|
2201
|
+
* @param tsConfigFolder The root folder for the typescript project (contains the tsconfig.json file).
|
|
2202
|
+
* @param tsconfig The typescript configuration documetn for the project.
|
|
2203
|
+
*/
|
|
2204
|
+
getTsOutputFolder(tsConfigFolder, tsconfig) {
|
|
2205
|
+
let outDir = tsconfig.compilerOptions.outDir || dx_constants_1.DxConstants.DEFAULT_BUILD_OUTPUT_DIR;
|
|
2206
|
+
let fullPath = path.join(tsConfigFolder, outDir);
|
|
2207
|
+
return fullPath;
|
|
2208
|
+
}
|
|
2209
|
+
clearTsOutputFolder(tsConfigFolder, tsconfig) {
|
|
2210
|
+
let fullPath = this.getTsOutputFolder(tsConfigFolder, tsconfig);
|
|
2211
|
+
this.clearFolder(fullPath);
|
|
2212
|
+
}
|
|
2213
|
+
clearFolder(fullPath) {
|
|
2214
|
+
if (fs.existsSync(fullPath)) {
|
|
2215
|
+
this.logger.detail("Clearing output folder", fullPath);
|
|
2216
|
+
let spec = (fullPath.endsWith("*")) ? fullPath : path.join(fullPath, "**/*");
|
|
2217
|
+
rimraf.sync(fullPath, {});
|
|
2218
|
+
return true;
|
|
2219
|
+
}
|
|
2220
|
+
return false;
|
|
2221
|
+
}
|
|
2222
|
+
/** Builds the container image based on the given container definition file.
|
|
2223
|
+
* @param requestedFrameworkVersion (Optional: defaults to latest) Explicitly sets the version of the codiac base image to use.
|
|
2224
|
+
* @param noCache (Optional: defaults to false) Ignores the local Docker image cache, thereby forcing a fresh download of each image from its container registry layer in the build.
|
|
2225
|
+
* @param identitySet (Optional) The collection of the current user's auth tokens to inject into the build env (eg: for enabling private packages in npm).
|
|
2226
|
+
* @param targetStage (Optional) For images defined with multi-stage builds, the name of the only build stage to be built on this pass.
|
|
2227
|
+
* @param imagesToBuild (Optional) Limits the list of images to build. Each value must match the name property of an image export defined in the codiac project file (codiac.json). Ignored if empty.
|
|
2228
|
+
*/
|
|
2229
|
+
buildProjectImages(buildNumber, versionBump, requestedFrameworkVersion, noCache = false, identitySet, targetStage, imagesToBuild) {
|
|
2230
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2231
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2232
|
+
var _a;
|
|
2233
|
+
try {
|
|
2234
|
+
this.logger.debug("Container build...");
|
|
2235
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
2236
|
+
cfg.submodules.forEach(submodule => {
|
|
2237
|
+
this.logger.debug(`Shall we build container(s) for submodule: ${submodule.folderName} ?`);
|
|
2238
|
+
});
|
|
2239
|
+
if (cfg.images) {
|
|
2240
|
+
// let projectVersion = this.npmGetCurrentVersion();
|
|
2241
|
+
let projectVersion = cfg.codeVersion; // this.npmGetCurrentVersion();
|
|
2242
|
+
let dockerRoot = this._projectRoot; // this shd be image-specific
|
|
2243
|
+
let tsconfig = this.readTsConfig();
|
|
2244
|
+
let distPath = (tsconfig) ? tsconfig.compilerOptions.outDir : undefined || dx_constants_1.DxConstants.DEFAULT_BUILD_OUTPUT_DIR;
|
|
2245
|
+
// We could just use latest, but we should ensure a full version match from package.json to the image.
|
|
2246
|
+
let frameworkVersion = requestedFrameworkVersion ? requestedFrameworkVersion : yield this.getInstalledFrameworkVersion();
|
|
2247
|
+
let buildContext = {
|
|
2248
|
+
dockerRoot: dockerRoot,
|
|
2249
|
+
distPath: distPath,
|
|
2250
|
+
codeVersion: cfg.codeVersion,
|
|
2251
|
+
buildNumber: buildNumber,
|
|
2252
|
+
apiFrameworkVersion: frameworkVersion,
|
|
2253
|
+
identitySet: identitySet
|
|
2254
|
+
};
|
|
2255
|
+
let selectedImages;
|
|
2256
|
+
if (imagesToBuild && imagesToBuild.length > 0) {
|
|
2257
|
+
selectedImages = [...imagesToBuild];
|
|
2258
|
+
}
|
|
2259
|
+
else {
|
|
2260
|
+
selectedImages = _.keys(cfg.images);
|
|
2261
|
+
}
|
|
2262
|
+
// let cliConfig = await this._cfgRepo.read(); // TODO: Make this a lazy-load. This is a bad place for a file sys read.
|
|
2263
|
+
for (let imageName of selectedImages) {
|
|
2264
|
+
let imageExport = cfg.images[imageName]; // TODO: get a non-nullable generic dictionary into @codiac.io/codiac-common
|
|
2265
|
+
if (imageExport == undefined) {
|
|
2266
|
+
throw new Error(`There is no image named: [${imageName}] declared in the project.`);
|
|
2267
|
+
}
|
|
2268
|
+
else {
|
|
2269
|
+
if (imageExport.readonly) {
|
|
2270
|
+
this.logger.debug(`Skipping build of readonly image: ${imageName}`);
|
|
2271
|
+
}
|
|
2272
|
+
else {
|
|
2273
|
+
if (imageExport.version == undefined)
|
|
2274
|
+
imageExport.version = (_a = cfg.codeVersion) !== null && _a !== void 0 ? _a : dx_constants_1.DxConstants.DEFAULT_INIT_IMAGE_VERSION; //
|
|
2275
|
+
if (versionBump && imageExport.version) {
|
|
2276
|
+
if (this.cliConfig.addBranchNameToPrereleases === true) {
|
|
2277
|
+
let currentBranch = yield this.gitCurrentBranchNameFor(this._projectRoot);
|
|
2278
|
+
if (this.isMainBranch(currentBranch) === false) {
|
|
2279
|
+
versionBump.preId = currentBranch;
|
|
2280
|
+
// imageExport.version = this.addPrereleaseId(imageExport.version, currentBranch);
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
imageExport = yield this._workspaceVersioner.incrementImageVersion(imageExport, cfg, versionBump);
|
|
2284
|
+
}
|
|
2285
|
+
let versionStamp = imageExport.version || projectVersion; // <---- ImageExports can have their own versions, otherwise fall back to project code version.
|
|
2286
|
+
yield this.buildSingleImage(imageExport, versionStamp, noCache, buildContext, targetStage);
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
else {
|
|
2292
|
+
this.logger.notice("This project is not set to export any container images. Use 'codiac images:add' to do so.");
|
|
2293
|
+
}
|
|
2294
|
+
resolve();
|
|
2295
|
+
}
|
|
2296
|
+
catch (err) {
|
|
2297
|
+
reject(err);
|
|
2298
|
+
}
|
|
2299
|
+
}));
|
|
2300
|
+
});
|
|
2301
|
+
}
|
|
2302
|
+
/** Currently conventional - check if the branch is main or master.
|
|
2303
|
+
*
|
|
2304
|
+
* TODO: This is too specific. Make this configurable in the codiac.json, backed by the cli config, backed by this convention..
|
|
2305
|
+
*/
|
|
2306
|
+
isMainBranch(branch) {
|
|
2307
|
+
return (branch === "master" || branch === "main");
|
|
2308
|
+
}
|
|
2309
|
+
/**
|
|
2310
|
+
*
|
|
2311
|
+
* @param imageExport
|
|
2312
|
+
* @param thisVersion
|
|
2313
|
+
* @param noCache
|
|
2314
|
+
* @param cntx
|
|
2315
|
+
* @param targetStage (Optional) For an image defined with a multi-stage build, the name of the only build stage to be built on this pass.
|
|
2316
|
+
*/
|
|
2317
|
+
buildSingleImage(imageExport, thisVersion, noCache, cntx, targetStage) {
|
|
2318
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2319
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2320
|
+
try {
|
|
2321
|
+
this.logger.notice(`Building Container Image: ${this.styler.hilite(`${imageExport.name}:${thisVersion}`)}`);
|
|
2322
|
+
let droot = (imageExport.definitionFile) ? path.dirname(imageExport.definitionFile) : ".";
|
|
2323
|
+
this.logger.trace(`droot: [${droot}]`);
|
|
2324
|
+
let flatten = false;
|
|
2325
|
+
let cmdArgs = [];
|
|
2326
|
+
if (noCache)
|
|
2327
|
+
cmdArgs.push("--no-cache");
|
|
2328
|
+
cmdArgs.push(`-t ${imageExport.name}:${thisVersion}`);
|
|
2329
|
+
cmdArgs.push(`-t ${imageExport.name}:latest`);
|
|
2330
|
+
// cmdArgs.push(`--squash`);
|
|
2331
|
+
if (targetStage)
|
|
2332
|
+
cmdArgs.push(`--target ${targetStage}`);
|
|
2333
|
+
// Apply labels
|
|
2334
|
+
let labels = {};
|
|
2335
|
+
labels["branch"] = (yield this.gitCurrentBranchFor(this._projectRoot)).name;
|
|
2336
|
+
let lastCommit = (yield this.gitReadLatestCommitId());
|
|
2337
|
+
if (lastCommit)
|
|
2338
|
+
labels["commit"] = lastCommit;
|
|
2339
|
+
labels["codeVersion"] = cntx.codeVersion;
|
|
2340
|
+
labels["buildNumber"] = cntx.buildNumber;
|
|
2341
|
+
for (let key in labels) {
|
|
2342
|
+
cmdArgs.push(`--label "${key}=${labels[key]}"`);
|
|
2343
|
+
}
|
|
2344
|
+
let buildEnv = Object.assign({}, process.env);
|
|
2345
|
+
let cmd;
|
|
2346
|
+
// NPM TOKEN SUPPORT (using docker secret build parameter)
|
|
2347
|
+
// from https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information
|
|
2348
|
+
// Create a temp npmrc file in the proj user folder, with all token variables resolved.
|
|
2349
|
+
// then pass it into the build as a secret
|
|
2350
|
+
// mount that secret for the npm install
|
|
2351
|
+
// then afterwards, delete the temp file we created in the poject user folder.
|
|
2352
|
+
buildEnv.DOCKER_BUILDKIT = "1"; // from https://docs.docker.com/engine/reference/builder/#buildkit
|
|
2353
|
+
// TODO: Consider merging contents of the project npmrc with the project-user npmrc
|
|
2354
|
+
// or copying them both into the image.
|
|
2355
|
+
let npmrcFilePath = path.join(this._projectRoot, codiac_ops_common_3.OpsConstants.PROJECT_USER_CONFIG_FOLDER_NAME, dx_constants_1.DxConstants.NPM_PROJECT_USER_CONFIG_FILENAME);
|
|
2356
|
+
// TODO: This shd be conditional on existince of identities
|
|
2357
|
+
// and throw if then the file doesnt exist.
|
|
2358
|
+
if (fs.existsSync(npmrcFilePath)) {
|
|
2359
|
+
cmdArgs.push(`--secret id=npmrc,src=${npmrcFilePath}`);
|
|
2360
|
+
}
|
|
2361
|
+
// TODO: Expose this as a build option.
|
|
2362
|
+
// Renders all the shell output from the build
|
|
2363
|
+
// (VERY VERBOSE AND MUCH SLOWER)
|
|
2364
|
+
// cmdArgs.push("--progress=plain");
|
|
2365
|
+
if (imageExport.buildParams) {
|
|
2366
|
+
for (let arg in imageExport.buildParams) {
|
|
2367
|
+
cmdArgs.push(`${arg}${(imageExport.buildParams[arg] !== undefined) ? " " + imageExport.buildParams[arg] : ""}`);
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
if (!imageExport.definitionFile) {
|
|
2371
|
+
// Autogen the def file contents and run the in-memory invocation
|
|
2372
|
+
let jitDockerFile = this.generateDockerImageDef(cntx.apiFrameworkVersion, cntx.distPath, "", cntx.identitySet, true);
|
|
2373
|
+
buildEnv.jitDockerFile = jitDockerFile.join("\\n");
|
|
2374
|
+
this.logger.debug(`JIT (Just-In-Time) docker image definition auto-generated`, jitDockerFile);
|
|
2375
|
+
cmd = `echo \$jitDockerFile | docker build ${cmdArgs.join(" ")} -f - .`;
|
|
2376
|
+
}
|
|
2377
|
+
else {
|
|
2378
|
+
let regen = false;
|
|
2379
|
+
let fullDefPath = path.join(this._projectRoot, imageExport.definitionFile);
|
|
2380
|
+
if (imageExport.overwrite == "always") {
|
|
2381
|
+
regen = true;
|
|
2382
|
+
}
|
|
2383
|
+
else {
|
|
2384
|
+
let fileExists = fs.existsSync(fullDefPath);
|
|
2385
|
+
if (!fileExists) {
|
|
2386
|
+
if (imageExport.overwrite == "never") {
|
|
2387
|
+
// never-overwrite AND the file is missing
|
|
2388
|
+
throw new Error(`Missing definition file [${fullDefPath}] for image [${imageExport.name}]; either create the definition file manually, unset its 'definitionFile' property altogether, or change its 'overwrite' setting to enable it to be autogenerated.`);
|
|
2389
|
+
}
|
|
2390
|
+
else {
|
|
2391
|
+
regen = true; // asneeded scenario
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
if (regen) {
|
|
2396
|
+
this.logger.detail(`Generating image definition file ${fullDefPath}.`);
|
|
2397
|
+
let autoContent = this.generateDockerImageDef(cntx.apiFrameworkVersion, cntx.distPath, "", cntx.identitySet);
|
|
2398
|
+
let targetFolder = path.dirname(fullDefPath);
|
|
2399
|
+
if (!fs.existsSync(targetFolder)) {
|
|
2400
|
+
fs.mkdirSync(targetFolder, { recursive: true });
|
|
2401
|
+
}
|
|
2402
|
+
fs.writeFileSync(fullDefPath, autoContent);
|
|
2403
|
+
}
|
|
2404
|
+
cmd = `docker build ${cmdArgs.join(" ")} -f ${imageExport.definitionFile} .`;
|
|
2405
|
+
}
|
|
2406
|
+
yield this._cliExec.spawnAndLog(cmd, cntx.dockerRoot, buildEnv);
|
|
2407
|
+
// if (flatten) {
|
|
2408
|
+
// this.logger.detail(`Flattening image...`);
|
|
2409
|
+
// let runCmd = `docker run -d ${imageExport.name}:${thisVersion} /bin/true`;
|
|
2410
|
+
// let ctrId = await this._cliExec.execAsyncStdOut(runCmd, { cwd: cntx.dockerRoot });
|
|
2411
|
+
// let importCmd = `docker export ${ctrId} | docker import - ${imageExport.name}:${thisVersion}`;
|
|
2412
|
+
// await this._cliExec.spawnAndLog(importCmd, cntx.dockerRoot);
|
|
2413
|
+
// await this._cliExec.spawnAndLog(`docker tag ${imageExport.name}:${thisVersion} ${imageExport.name}:latest`, cntx.dockerRoot);
|
|
2414
|
+
// }
|
|
2415
|
+
// TODO: Consider labeling the git log with the 'imageName:version' being created.
|
|
2416
|
+
// Q: Why not?
|
|
2417
|
+
// A: Because, according to the "Sharing Tags" section on https://git-scm.com/book/en/v2/Git-Basics-Tagging
|
|
2418
|
+
// "By default, the git push command doesn’t transfer tags to remote servers.
|
|
2419
|
+
// You will have to explicitly push tags to a shared server after you have created them."
|
|
2420
|
+
// eg: $ git push origin v1.5
|
|
2421
|
+
// eg: $ git push origin --tags
|
|
2422
|
+
//
|
|
2423
|
+
// let cmdTag = `git tag image-${imageExport.name}:${thisVersion}`
|
|
2424
|
+
// let commit = await this._cliExec.execAsyncStdOut(cmdTag, { cwd: this._projectRoot });
|
|
2425
|
+
let details = yield this._cliExec.execAsyncStdOut(`docker inspect ${imageExport.name}:${thisVersion} && docker image ls ${imageExport.name}:${thisVersion}`, { cwd: cntx.dockerRoot }, IBetterLogger_1.LogLevel.trace, false);
|
|
2426
|
+
this.logger.trace(`Newly minted image ${imageExport.name}:${thisVersion}`, details);
|
|
2427
|
+
yield this.updateConfigWithImageMetaFromInspection(imageExport.name, thisVersion, cntx);
|
|
2428
|
+
resolve();
|
|
2429
|
+
}
|
|
2430
|
+
catch (err) {
|
|
2431
|
+
reject(new contracts_1.CodiacError(`Error building image: ${err.message || ""}`, err));
|
|
2432
|
+
}
|
|
2433
|
+
finally {
|
|
2434
|
+
let tempNpmrcPathName = path.join(this._projectRoot, codiac_ops_common_3.OpsConstants.PROJECT_USER_CONFIG_FOLDER_NAME, ".npmrc");
|
|
2435
|
+
if (fs.existsSync(tempNpmrcPathName)) {
|
|
2436
|
+
try {
|
|
2437
|
+
fs.unlinkSync(tempNpmrcPathName);
|
|
2438
|
+
}
|
|
2439
|
+
catch (_a) { }
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
}));
|
|
2443
|
+
});
|
|
2444
|
+
}
|
|
2445
|
+
/**
|
|
2446
|
+
* Cherry Picking single property output from Docker inspection, and stored in the project > imgs > export cfg for:
|
|
2447
|
+
* Os - needed to support multi-platform nodepooling
|
|
2448
|
+
* Architecture - currently dont need it, but I have feeling it wont be long
|
|
2449
|
+
*/
|
|
2450
|
+
updateConfigWithImageMetaFromInspection(name, tag, cntx) {
|
|
2451
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2452
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2453
|
+
try {
|
|
2454
|
+
const inspectForOs = yield this._cliExec.execAsyncStdOut(`docker inspect ${name}:${tag} --format="{{json .Os}}"`, { cwd: cntx.dockerRoot }, undefined, false);
|
|
2455
|
+
const inspectForArch = yield this._cliExec.execAsyncStdOut(`docker inspect ${name}:${tag} --format="{{json .Architecture}}"`, { cwd: cntx.dockerRoot }, undefined, false);
|
|
2456
|
+
let cfg = yield this.readCodiacProjectConfig();
|
|
2457
|
+
if (cfg && cfg.images) {
|
|
2458
|
+
const osRaw = inspectForOs;
|
|
2459
|
+
this.logger.debug("found os as: ", osRaw);
|
|
2460
|
+
const os = osRaw.replace(/^"(.+)"$/, '$1');
|
|
2461
|
+
this.logger.debug("mutated os to: ", os);
|
|
2462
|
+
if (os)
|
|
2463
|
+
cfg.images[name].os = inspectForOs.replace(/^"(.+)"$/, '$1').toLowerCase(); // removing the quotes that the cmd sends it back with
|
|
2464
|
+
if (inspectForArch)
|
|
2465
|
+
cfg.images[name].architecture = inspectForArch.replace(/^"(.+)"$/, '$1').toLowerCase();
|
|
2466
|
+
yield this._projCfgRepo.updateProjectConfigFile(cfg);
|
|
2467
|
+
}
|
|
2468
|
+
resolve();
|
|
2469
|
+
}
|
|
2470
|
+
catch (error) {
|
|
2471
|
+
reject(new contracts_1.CodiacError(`Image inspection failed with error: ${error.message || ""}`, error));
|
|
2472
|
+
}
|
|
2473
|
+
}));
|
|
2474
|
+
});
|
|
2475
|
+
}
|
|
2476
|
+
/** Housekeeping method that deletes any untagged images
|
|
2477
|
+
* that get leftover after multiple builds of the same image. */
|
|
2478
|
+
dockerPruneDanglingImages() {
|
|
2479
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2480
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2481
|
+
try {
|
|
2482
|
+
this.logger.detail(`Pruning dangling images...`);
|
|
2483
|
+
let cmd = `docker images -q --filter 'dangling=true' | xarg docker rmi`;
|
|
2484
|
+
yield this._cliExec.spawnAndLog(cmd, this._projectRoot);
|
|
2485
|
+
this.logger.notice(`Complete! Deleted leftover untagged images.`);
|
|
2486
|
+
resolve();
|
|
2487
|
+
}
|
|
2488
|
+
catch (err) {
|
|
2489
|
+
reject(err);
|
|
2490
|
+
}
|
|
2491
|
+
}));
|
|
2492
|
+
});
|
|
2493
|
+
}
|
|
2494
|
+
/** Legacy logic to hydrate the build env and the npmrc file with token values. */
|
|
2495
|
+
npmHydrateTokensInNpmrc(npmrcFilePath, buildEnv, identitySet) {
|
|
2496
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2497
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2498
|
+
try {
|
|
2499
|
+
let npmrc = fs.readFileSync(npmrcFilePath, { encoding: "utf-8" });
|
|
2500
|
+
// We're going to inject the entire identity set (for now).
|
|
2501
|
+
// Later, we should get the project to tell us which identities it needs,
|
|
2502
|
+
// to build this image (based on its private dependencies),
|
|
2503
|
+
// eg: imageExport.onBuild.requiredTokenNames
|
|
2504
|
+
for (let tokenName in identitySet) {
|
|
2505
|
+
let identity = identitySet[tokenName];
|
|
2506
|
+
if (identity.provider == codiac_relay_contracts_1.IdentityProvider.npm) {
|
|
2507
|
+
// cmdArgs.push(`--build-arg ${tokenName}=\${${tokenName}}`)
|
|
2508
|
+
buildEnv[tokenName] = identity.token;
|
|
2509
|
+
// this.logger.debug(`Injecting ${identity.provider} identity token ${tokenName} as image build arg.`, identity);
|
|
2510
|
+
// flatten = true; // If we're ading tokens, we need to make sure we flatten to kill the history
|
|
2511
|
+
npmrc = npmrc.replace(`\${${tokenName}}`, identity.token);
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
fs.writeFileSync(npmrcFilePath, npmrc, { encoding: "utf-8" });
|
|
2515
|
+
resolve();
|
|
2516
|
+
}
|
|
2517
|
+
catch (err) {
|
|
2518
|
+
reject(err);
|
|
2519
|
+
}
|
|
2520
|
+
}));
|
|
2521
|
+
});
|
|
2522
|
+
}
|
|
2523
|
+
/** Retrieves the version of the api framework that is currently installed in the project
|
|
2524
|
+
* from the npm package.json dependencies list.
|
|
2525
|
+
* NOTE: Removes any version-support prefixes (eg: ^).
|
|
2526
|
+
* NOTE: Returns "latest" when not installed. */
|
|
2527
|
+
getInstalledFrameworkVersion() {
|
|
2528
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2529
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2530
|
+
try {
|
|
2531
|
+
let version = "latest";
|
|
2532
|
+
let pkg = yield this.readNpmPackageJson();
|
|
2533
|
+
if (pkg && pkg.dependencies) {
|
|
2534
|
+
let installed = pkg.dependencies[dx_constants_1.DxConstants.API_FRAMEWORK_PACKAGE];
|
|
2535
|
+
if (installed) {
|
|
2536
|
+
version = installed.match(/([\w\d].*)/)[0];
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
resolve(version);
|
|
2540
|
+
}
|
|
2541
|
+
catch (err) {
|
|
2542
|
+
reject(err);
|
|
2543
|
+
}
|
|
2544
|
+
}));
|
|
2545
|
+
});
|
|
2546
|
+
}
|
|
2547
|
+
/** Constructs from scratch the contents of a dockerfile from which to build an image.
|
|
2548
|
+
* @param frameworkVersion The version of the api framework to use within the image. That is, the api framework base image will need this version number applied to it.
|
|
2549
|
+
* @param distPath The path to the typescript output folder, relative to the project root (eg: "./dist").
|
|
2550
|
+
* @param prefixToProjRoot path prefix that, when applied to the image def file, resolves to the project root (ie: if using ".temp/jit.docker", this parameter would need to be "../") If this dockerfile exists within the project root itself, then any of "./" or "" or undefined are valid.
|
|
2551
|
+
* @param identities (Optional) The collection of tokenized identities registeed for the current user that are to be put into scope during the image build..
|
|
2552
|
+
*/
|
|
2553
|
+
generateDockerImageDef(frameworkVersion, distPath, prefixToProjRoot = "", identities, asArray = false) {
|
|
2554
|
+
let contents = [];
|
|
2555
|
+
// SECTION 1) Init...
|
|
2556
|
+
contents.push("# syntax = docker/dockerfile:1.0-experimental"); // Needed for buildKit and the --mount param we're gonna use on the RUN npm i (type=secret).
|
|
2557
|
+
// contents.push(`FROM letmeaskmydog/toyhauler-base:${frameworkVersion}`);
|
|
2558
|
+
contents.push(`FROM node:latest`);
|
|
2559
|
+
contents.push(`WORKDIR /app`);
|
|
2560
|
+
contents.push(`COPY ${prefixToProjRoot}${distPath} /app`);
|
|
2561
|
+
// Needed for generation of the openApi spec.
|
|
2562
|
+
// Without this openApi doc generation in the api framework will throw the error: "Cant resolve property 'length' on undefined."
|
|
2563
|
+
contents.push(`COPY ./tsconfig.json /app`);
|
|
2564
|
+
// SECTION 2) Package installation (including relevant authentication / identity tokens)...
|
|
2565
|
+
contents.push(`COPY ${prefixToProjRoot}package.json /app`); // shdnt the package.json already be there? (via build? or publish?)
|
|
2566
|
+
contents.push(`COPY ${prefixToProjRoot}package-lock.json /app`);
|
|
2567
|
+
// contents.push(`RUN if [ -f ${prefixToProjRoot}package.json ]; then echo "ITSTHERE"; fi;`);
|
|
2568
|
+
// contents.push("RUN echo \$ITSTHERE");
|
|
2569
|
+
let injectingNpmTokens = false;
|
|
2570
|
+
if (identities && !_.isEmpty(identities)) {
|
|
2571
|
+
for (let tokenName in identities) {
|
|
2572
|
+
let identity = identities[tokenName];
|
|
2573
|
+
// contents.push(`ARG ${tokenName}`);
|
|
2574
|
+
injectingNpmTokens = injectingNpmTokens || (identity.provider == codiac_relay_contracts_1.IdentityProvider.npm);
|
|
2575
|
+
}
|
|
2576
|
+
if (injectingNpmTokens) {
|
|
2577
|
+
// contents.push(`COPY ${prefixToProjRoot}.npmrc /app`); // only if it's not copied in already
|
|
2578
|
+
// contents.push(`RUN npm whoami`);
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
let npmrcRelPath = path.join(codiac_ops_common_3.OpsConstants.PROJECT_USER_CONFIG_FOLDER_NAME, dx_constants_1.DxConstants.NPM_PROJECT_USER_CONFIG_FILENAME);
|
|
2582
|
+
if (fs.existsSync(path.join(this._projectRoot, npmrcRelPath))) {
|
|
2583
|
+
contents.push("RUN --mount=type=secret,id=npmrc,dst=/app/.npmrc npm i");
|
|
2584
|
+
}
|
|
2585
|
+
else {
|
|
2586
|
+
// throw new Error(`${npmrcRelPath} is missing`);
|
|
2587
|
+
contents.push("RUN npm i");
|
|
2588
|
+
}
|
|
2589
|
+
// if (injectingNpmTokens) {
|
|
2590
|
+
// contents.push(`RUN if [ -f .npmrc ]; then rm -f .npmrc; echo "Removed .npmrc"; fi;`);
|
|
2591
|
+
// // contents.push(`RUN rm -f .npmrc`); // TODO: Remove only if we were the ones who added it (OR if they specified that it should be deleted..?)
|
|
2592
|
+
// }
|
|
2593
|
+
// SECTION 3) Entry point...
|
|
2594
|
+
contents.push(`CMD ["node", "./index.js"]`);
|
|
2595
|
+
return asArray ? contents : contents.join("\n");
|
|
2596
|
+
}
|
|
2597
|
+
declarePackageExport(config, target, sourceFile) {
|
|
2598
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2599
|
+
try {
|
|
2600
|
+
if (!sourceFile) {
|
|
2601
|
+
// TODO: This dialogue needs to happen in the host project. Here it needs to stop and return a workflow status.
|
|
2602
|
+
sourceFile = yield this.ux.prompt("file", "Enter the package definition file (Hit Enter for 'package.json'): ", true, "package.json");
|
|
2603
|
+
}
|
|
2604
|
+
let output = { operation: "add" };
|
|
2605
|
+
if (sourceFile) {
|
|
2606
|
+
let projRoot = this.getConfigRoot();
|
|
2607
|
+
let sourcePath = path.join(projRoot, sourceFile);
|
|
2608
|
+
if (fs.existsSync(sourcePath)) {
|
|
2609
|
+
let pkgDef = yield this.readNpmPackageJson(projRoot, sourceFile);
|
|
2610
|
+
let packageName = pkgDef.name;
|
|
2611
|
+
let pkgExport = new codiac_relay_contracts_2.PackageExport(target, sourceFile);
|
|
2612
|
+
let operation = "add";
|
|
2613
|
+
if (!config.packages) {
|
|
2614
|
+
config.packages = {};
|
|
2615
|
+
}
|
|
2616
|
+
else if (config.packages[packageName]) {
|
|
2617
|
+
let existing = config.packages[packageName];
|
|
2618
|
+
this.logger.debug(`Package export [${this.styler.hilite(packageName)}] is already registered in this project as [${this.styler.hilite(existing.definitionFile)}]!`);
|
|
2619
|
+
let confirm = yield this.ux.promptConfirm('reregister-pkg-export', `Re-register it? (y/n) `);
|
|
2620
|
+
if (confirm) {
|
|
2621
|
+
output.operation = "overwrite";
|
|
2622
|
+
}
|
|
2623
|
+
else {
|
|
2624
|
+
this.logger.debug("Operation cancelled by user.");
|
|
2625
|
+
pkgExport = undefined;
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
if (pkgExport) {
|
|
2629
|
+
config.packages[packageName] = pkgExport;
|
|
2630
|
+
yield this._projCfgRepo.updateProjectConfigFile(config);
|
|
2631
|
+
output.name = packageName;
|
|
2632
|
+
output.package = pkgExport;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
else {
|
|
2636
|
+
// TODO: Emit a workflow status so the host can ask the user if they want to init up a new one.
|
|
2637
|
+
this.logger.error(`Your package definition file: [${sourceFile}] does not exist.`);
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
else {
|
|
2641
|
+
this.logger.debug("Operation cancelled. No work was done.");
|
|
2642
|
+
}
|
|
2643
|
+
resolve(output);
|
|
2644
|
+
}
|
|
2645
|
+
catch (err) {
|
|
2646
|
+
reject(err);
|
|
2647
|
+
}
|
|
2648
|
+
}));
|
|
2649
|
+
}
|
|
2650
|
+
/** Adds container image specifications to the project,
|
|
2651
|
+
* which will add the image spec into the build, publish, and deploy sequences.
|
|
2652
|
+
*/
|
|
2653
|
+
declareImageExport(config, imageName, target, sourceFile, port, buildParams) {
|
|
2654
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2655
|
+
try {
|
|
2656
|
+
// TODO: Validate that sourceFile is not a dirName
|
|
2657
|
+
let imageExport = new codiac_relay_contracts_2.ImageExport(imageName, target, sourceFile, port);
|
|
2658
|
+
if (buildParams)
|
|
2659
|
+
imageExport.buildParams = buildParams;
|
|
2660
|
+
let operation = "add";
|
|
2661
|
+
if (!config.images) {
|
|
2662
|
+
config.images = {};
|
|
2663
|
+
}
|
|
2664
|
+
else if (config.images[imageName]) {
|
|
2665
|
+
// TODO: stop and emit a workflow status instead.
|
|
2666
|
+
let confirm = yield this.ux.promptConfirm("image-overwrite", `Image export "${imageName}" already exists! Overwrite? `);
|
|
2667
|
+
if (confirm) {
|
|
2668
|
+
operation = "overwrite";
|
|
2669
|
+
this.logger.debug(`Image export "${imageName}" already exists! Overwriting it...`);
|
|
2670
|
+
}
|
|
2671
|
+
else {
|
|
2672
|
+
imageExport = undefined;
|
|
2673
|
+
this.logger.debug("Operation cancelled. No work was done.");
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
if (imageExport) {
|
|
2677
|
+
config.images[imageName] = imageExport;
|
|
2678
|
+
yield this._projCfgRepo.updateProjectConfigFile(config);
|
|
2679
|
+
}
|
|
2680
|
+
resolve({ image: imageExport, operation: operation });
|
|
2681
|
+
}
|
|
2682
|
+
catch (err) {
|
|
2683
|
+
reject(err);
|
|
2684
|
+
}
|
|
2685
|
+
}));
|
|
2686
|
+
}
|
|
2687
|
+
/** Returns the pedigree of the current branch
|
|
2688
|
+
* starting with itself, through each parent, up to the root. */
|
|
2689
|
+
gitBranchLine(startingBranch) {
|
|
2690
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2691
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2692
|
+
try {
|
|
2693
|
+
let lineage = [startingBranch];
|
|
2694
|
+
let repoRoot = yield this.getRepoRoot(this._projectRoot);
|
|
2695
|
+
// This big stupid border is here because the output from these git branch commands is crazy long.
|
|
2696
|
+
// this.logger.trace("========================================================================");
|
|
2697
|
+
// this.logger.trace("| ============== gitBranchLine() ================= |");
|
|
2698
|
+
// this.logger.trace("========================================================================");
|
|
2699
|
+
let nxBranch = startingBranch;
|
|
2700
|
+
// IMPORTANT!!
|
|
2701
|
+
// This will only ever generate the first two branches in the lineage.
|
|
2702
|
+
// The git branch history needs to be walked forward (not from the start each time),
|
|
2703
|
+
// so it needs to be kept in this function's state and passed into gitParent().
|
|
2704
|
+
// GitBranchLine relies on stringparsing a garbled git output, so it may not be reliable anyway.
|
|
2705
|
+
// CONSIDER NEVER CALLING gitBranchLine().
|
|
2706
|
+
while (nxBranch != undefined && nxBranch != "") {
|
|
2707
|
+
let parent = yield this.gitParent(nxBranch);
|
|
2708
|
+
if (parent) {
|
|
2709
|
+
if (lineage.indexOf(parent) < 0 && parent != nxBranch) {
|
|
2710
|
+
if (lineage.indexOf(parent) < 0) {
|
|
2711
|
+
lineage.push(parent);
|
|
2712
|
+
nxBranch = parent;
|
|
2713
|
+
}
|
|
2714
|
+
else {
|
|
2715
|
+
nxBranch = undefined;
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
else {
|
|
2719
|
+
nxBranch = undefined;
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
else {
|
|
2723
|
+
nxBranch = undefined;
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
this.logger.debug(`Branch lineage: ${lineage.reverse().join(' > ')}`);
|
|
2727
|
+
resolve(lineage);
|
|
2728
|
+
}
|
|
2729
|
+
catch (err) {
|
|
2730
|
+
reject(err);
|
|
2731
|
+
}
|
|
2732
|
+
}));
|
|
2733
|
+
});
|
|
2734
|
+
}
|
|
2735
|
+
/** Returns the parent source code branch of the given one,
|
|
2736
|
+
* based on the commit history (because apparently git doesnt track branching history).
|
|
2737
|
+
* Returns undefined if the given branch has no parent (eg: master). */
|
|
2738
|
+
gitParent(branch) {
|
|
2739
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2740
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2741
|
+
try {
|
|
2742
|
+
let repoRoot = yield this.getRepoRoot(this._projectRoot);
|
|
2743
|
+
let cmd = `git show-branch -a --no-color ${branch}`;
|
|
2744
|
+
let raw = (yield this._cliExec.execAsyncStdOut(cmd, { cwd: repoRoot }, IBetterLogger_1.LogLevel.trace, false)); /* Traced cuz its LOOOONG. Raw git commit history for the branch... */
|
|
2745
|
+
let parent = undefined;
|
|
2746
|
+
if (raw || raw == "") {
|
|
2747
|
+
let pattern = escapeStringRegexp(`${branch}`);
|
|
2748
|
+
pattern = `\\[(${pattern})[\\^~\\d]*\\]`;
|
|
2749
|
+
let rows = raw
|
|
2750
|
+
.split("\n") /* each line becomes an element in a string array... */
|
|
2751
|
+
.filter(x => x.match(/\*[+-\s]*\[/)) /* we want only lines that start with an asterisk... */
|
|
2752
|
+
.filter(x => !x.match(new RegExp(pattern))); /* but also don't contain the current branch... */
|
|
2753
|
+
// .filter(x => !x.match(new RegExp(pattern))); /* but also don't contain the current branch... */
|
|
2754
|
+
if (rows.length > 0) {
|
|
2755
|
+
parent = rows[0] /* and only the first such line... */
|
|
2756
|
+
// .replace(/.*\[(.*)\].*/, "$1") /* and just the part of the line between []... */
|
|
2757
|
+
.match(/\[(.*?)\]/)[1] /* and the first matching string enclosed in square brackets (but without the brackets, so index 1)... */
|
|
2758
|
+
.replace(/[\^~].*/, "") /* and with any relative refs (^, ~n) removed... */
|
|
2759
|
+
.trim(); /* and without any leading or trailing spaces */
|
|
2760
|
+
if (parent == branch) {
|
|
2761
|
+
parent = undefined;
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
this.logger.debug(`Parent: ${parent}`);
|
|
2766
|
+
resolve(parent);
|
|
2767
|
+
}
|
|
2768
|
+
catch (err) {
|
|
2769
|
+
reject(err);
|
|
2770
|
+
}
|
|
2771
|
+
}));
|
|
2772
|
+
});
|
|
2773
|
+
}
|
|
2774
|
+
/** Returns the parent source code branch of the given one,
|
|
2775
|
+
* based on the commit history (because apparently git doesnt track branching history).
|
|
2776
|
+
* Returns undefined if the given branch has no parent (eg: master). */
|
|
2777
|
+
gitParent_LinuxOnly(branch) {
|
|
2778
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2779
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2780
|
+
try {
|
|
2781
|
+
// Getting the parent branch is non-trivial.
|
|
2782
|
+
// This command was lifted from: https://stackoverflow.com/questions/3161204/how-to-find-the-nearest-parent-of-a-git-branch
|
|
2783
|
+
let cmd = `git show-branch -a --no-color ${branch}`;
|
|
2784
|
+
cmd += " | grep '\\*' "; // we want only lines that contain an asterisk
|
|
2785
|
+
cmd += " | grep -v `git rev-parse --abbrev-ref HEAD` "; // but also don't contain the current branch
|
|
2786
|
+
cmd += " | head -n1 "; // and only the first such line
|
|
2787
|
+
cmd += " | sed 's/.*\\[\\(.*\\)\\].*/\\1/' "; // really, just the part of the line between []
|
|
2788
|
+
cmd += " | sed 's/[\\^~].*//' "; // and with any relative refs (^, ~n) removed
|
|
2789
|
+
let projectRoot = this.getConfigRoot();
|
|
2790
|
+
let repoRoot = yield this.getRepoRoot(projectRoot);
|
|
2791
|
+
let output = yield this._cliExec.execAsyncStdOut(cmd, { cwd: repoRoot }, IBetterLogger_1.LogLevel.trace); // traced cuz its output is looooooong.
|
|
2792
|
+
let parent = (output && output != "") ? output.trim() : undefined;
|
|
2793
|
+
resolve(parent);
|
|
2794
|
+
}
|
|
2795
|
+
catch (err) {
|
|
2796
|
+
reject(err);
|
|
2797
|
+
}
|
|
2798
|
+
}));
|
|
2799
|
+
});
|
|
2800
|
+
}
|
|
2801
|
+
/** It is possible that a registry target has not been defined for the given params. */
|
|
2802
|
+
getTargetImageRegistry(imageConfig, remoteOrLocal, branch) {
|
|
2803
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2804
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2805
|
+
try {
|
|
2806
|
+
let output = undefined;
|
|
2807
|
+
if (remoteOrLocal == codiac_relay_contracts_2.PublishingMode.local) {
|
|
2808
|
+
}
|
|
2809
|
+
else {
|
|
2810
|
+
// STEP 1 filter out the local targets
|
|
2811
|
+
let targets = imageConfig.targets.filter(t => t.environment != codiac_relay_contracts_2.ImageExport.LOCAL_ENVIRONMENT_NAME);
|
|
2812
|
+
// STEP 2 If there's a wildcard, hold onto it.
|
|
2813
|
+
let wildcards = _.remove(targets, t => t.environment == codiac_relay_contracts_2.ImageExport.DEFAULT_ENVIRONMENT_NAME);
|
|
2814
|
+
if (wildcards.length > 0) {
|
|
2815
|
+
// NOTE: the _.remove() mutated the targets array, so the wildcard isnt in there anymore.
|
|
2816
|
+
output = wildcards[0];
|
|
2817
|
+
}
|
|
2818
|
+
// TODO: CONSIDER REMOVING THIS. gitBranchLine() may not be entirely accurate or complete.
|
|
2819
|
+
// STEP 3 If there's more than one, walk the branch line
|
|
2820
|
+
// and see if there's anything more specific than the wildcard
|
|
2821
|
+
let match = imageConfig.targets.find(t => t.environment == branch || t.environment == `=${branch}`); // That "=branch" syntax prevents matching any child branches
|
|
2822
|
+
let nxBranch = branch;
|
|
2823
|
+
let branchLine = yield this.gitBranchLine(branch);
|
|
2824
|
+
let b = 0;
|
|
2825
|
+
while (!match && nxBranch) {
|
|
2826
|
+
match = imageConfig.targets.find(t => t.environment == nxBranch);
|
|
2827
|
+
b++;
|
|
2828
|
+
nxBranch = (b < branchLine.length) ? branchLine[b] : undefined;
|
|
2829
|
+
}
|
|
2830
|
+
if (match)
|
|
2831
|
+
output = match;
|
|
2832
|
+
}
|
|
2833
|
+
resolve(output);
|
|
2834
|
+
}
|
|
2835
|
+
catch (err) {
|
|
2836
|
+
reject(err);
|
|
2837
|
+
}
|
|
2838
|
+
}));
|
|
2839
|
+
});
|
|
2840
|
+
}
|
|
2841
|
+
/** Builds the container image based on the given container definition file.
|
|
2842
|
+
* @param targetRemote If set, publishes to the appropriate remote container registry
|
|
2843
|
+
* mapped for the current branch, or to the local built-in container registry. When not set, defaults to the previously set value, or to the system default of "local".
|
|
2844
|
+
* @param only (optional, defaults to "all") The name of a specific sourced dependency to pull instead of everything in the project. Pulls latest only for the sourced dependency specified by this parameter.
|
|
2845
|
+
*/
|
|
2846
|
+
projectPublishImages(targetRemote, only, imagesToPublish, username, password) {
|
|
2847
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2848
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2849
|
+
try {
|
|
2850
|
+
// let cfg = this._projCfg;
|
|
2851
|
+
// let userCfg = this._projUserCfg;
|
|
2852
|
+
let publishingTarget = this._projUserCfg.publishingMode || dx_constants_1.DxConstants.DEFAULT_PUBLISHING_TARGET;
|
|
2853
|
+
if (targetRemote != undefined)
|
|
2854
|
+
publishingTarget = (targetRemote) ? codiac_relay_contracts_2.PublishingMode.remote : codiac_relay_contracts_2.PublishingMode.local;
|
|
2855
|
+
let branches = yield this.gitEachCurrentBranch();
|
|
2856
|
+
if (only && only != "all") {
|
|
2857
|
+
let sourcedDep = this._projCfg.submodules.find(sm => sm.folderName == only); // TODO: verify that this shouldnt be "sm.packageName" instead.
|
|
2858
|
+
if (sourcedDep) {
|
|
2859
|
+
let relPath = path.posix.join(dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, sourcedDep.folderName);
|
|
2860
|
+
yield this.publishImages(relPath, branches[sourcedDep.packageName], publishingTarget, imagesToPublish, username, password);
|
|
2861
|
+
}
|
|
2862
|
+
else {
|
|
2863
|
+
this.logger.error(`There is no sourced dependency named: ${only}.`);
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
else {
|
|
2867
|
+
for (let key in this._projCfg.submodules) {
|
|
2868
|
+
let sourcedDep = this._projCfg.submodules[key];
|
|
2869
|
+
let relPath = path.posix.join(dx_constants_1.DxConstants.SUBMODULES_DIR_NAME, sourcedDep.folderName);
|
|
2870
|
+
yield this.publishImages(relPath, branches[sourcedDep.packageName], publishingTarget, imagesToPublish, username, password);
|
|
2871
|
+
}
|
|
2872
|
+
yield this.publishImages("./", branches[this._projCfg.name], publishingTarget, imagesToPublish, username, password);
|
|
2873
|
+
}
|
|
2874
|
+
resolve();
|
|
2875
|
+
}
|
|
2876
|
+
catch (err) {
|
|
2877
|
+
this.logger.debug(`If you get a "...interactive login from a non TTY device" failure from the docker login step...`, `\nIt means docker needs to ask you for your creds. EITHER set them using 'codiac images:add' OR do an 'az acr login --name myregistry'. For more info, see https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication#individual-login-with-azure-ad`);
|
|
2878
|
+
reject(err);
|
|
2879
|
+
}
|
|
2880
|
+
}));
|
|
2881
|
+
});
|
|
2882
|
+
}
|
|
2883
|
+
publishImages(relFolderPath, branch, publishingTarget, imagesToPublish, username, password) {
|
|
2884
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2885
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2886
|
+
var _a;
|
|
2887
|
+
try {
|
|
2888
|
+
this.logger.trace(`Running publishImages on [${this.styler.hilite(relFolderPath)}]...`);
|
|
2889
|
+
let projectRoot = this.getConfigRoot();
|
|
2890
|
+
let workingDir = path.join(projectRoot, relFolderPath);
|
|
2891
|
+
// let thisVersion = this.npmGetCurrentVersion(workingDir);
|
|
2892
|
+
// TODO: GOtta look for a thaulconfig in the workingDir and if it exists, check for imageExports declared in it.
|
|
2893
|
+
if (fs.existsSync(path.posix.join(workingDir, codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME))) {
|
|
2894
|
+
let thisProjConfig = yield this.readCodiacProjectConfig(workingDir);
|
|
2895
|
+
let imageExports = thisProjConfig.images;
|
|
2896
|
+
if (imageExports) {
|
|
2897
|
+
let selectedImages;
|
|
2898
|
+
if (imagesToPublish && imagesToPublish.length > 0) {
|
|
2899
|
+
selectedImages = [...imagesToPublish];
|
|
2900
|
+
}
|
|
2901
|
+
else {
|
|
2902
|
+
selectedImages = _.keys(thisProjConfig.images);
|
|
2903
|
+
}
|
|
2904
|
+
for (let imageName of selectedImages) {
|
|
2905
|
+
let image = imageExports[imageName];
|
|
2906
|
+
if (image == undefined) {
|
|
2907
|
+
this.logger.detail(`Could not find an imageExport named [${imageName}] in the project config.`);
|
|
2908
|
+
}
|
|
2909
|
+
else { // this is stupid - TODO: Get a non-nullable genericDict<T> into @codiac.io/codiac-common
|
|
2910
|
+
if (!image.readonly) {
|
|
2911
|
+
// let registry = image.targets.find(r => r.environment == targetEnvironment);
|
|
2912
|
+
// if (!registry) registry = image.targets.find(r => r.environment == ImageExport.DEFAULT_ENVIRONMENT_NAME);
|
|
2913
|
+
let registry = yield this.getTargetImageRegistry(image, publishingTarget, branch.name);
|
|
2914
|
+
if (!registry) {
|
|
2915
|
+
this.logger.warn(`No ${publishingTarget} registry was declared for the image: [${imageName}] that would apply to your current branch: [${branch.name}], and no default was set. Operation cancelled.`);
|
|
2916
|
+
}
|
|
2917
|
+
else {
|
|
2918
|
+
let tag = image.version || thisProjConfig.codeVersion; // Images can have their own independent version numbers, but default to the project code version.
|
|
2919
|
+
// We're going to let docker hub's registry url stay silent
|
|
2920
|
+
let fullImageId = registry.registryUrl ? `${registry.registryUrl}/${imageName}:${tag}` : `${imageName}:${tag}`;
|
|
2921
|
+
// Apply the given tag
|
|
2922
|
+
let cmd1 = `docker tag ${imageName}:${tag} ${fullImageId}`;
|
|
2923
|
+
yield this._cliExec.execAsyncStdOut(cmd1, { cwd: workingDir });
|
|
2924
|
+
// NOTE: If you attempt to log into the local built in registry,
|
|
2925
|
+
// Docker will throw: "Cannot perform a login from a non TTY device"
|
|
2926
|
+
if (registry.registryUrl != codiac_relay_contracts_2.ImageExport.LOCAL_REGISTRY_URL) {
|
|
2927
|
+
if (registry.registryUrl.endsWith(`.azurecr.io`)) {
|
|
2928
|
+
let result = yield this.pushToAzure(fullImageId, registry.registryUrl);
|
|
2929
|
+
if (result.error)
|
|
2930
|
+
throw result.error;
|
|
2931
|
+
if (result.success !== true) {
|
|
2932
|
+
this.logger.notice(`Failed without error pushing to Azure: ${(_a = result.message) !== null && _a !== void 0 ? _a : "(no details available)"}`);
|
|
2933
|
+
}
|
|
2934
|
+
}
|
|
2935
|
+
else {
|
|
2936
|
+
if (username == undefined || password == undefined) {
|
|
2937
|
+
this.ux.userMessage(`Credentials for registry [${this.styler.hilite(registry.registryUrl)}]...`);
|
|
2938
|
+
}
|
|
2939
|
+
let regUser = username !== null && username !== void 0 ? username : (yield this.ux.prompt(`regUser`, `Username: `, true, registry.username));
|
|
2940
|
+
let regSecret = password !== null && password !== void 0 ? password : (yield this.ux.promptPassword(`regUser`, `Password/Token: `, registry.password));
|
|
2941
|
+
;
|
|
2942
|
+
// login to the registry (unless it's the builtin)
|
|
2943
|
+
this.ux.userMessage(`Logging docker into registry [${this.styler.hilite(registry.registryUrl)}]...`);
|
|
2944
|
+
// let cmd2 = `docker login ${registry.registryUrl} -u ${regUser} -p ${regSecret}`;
|
|
2945
|
+
// await this._cliExec.spawnAndLog(cmd2, workingDir, { REG_PWD: regSecret }, LogLevel.detail);
|
|
2946
|
+
// NOTE: This execution requires a bash shell
|
|
2947
|
+
let cmd2 = `echo $REG_PWD | docker login ${registry.registryUrl} -u ${regUser} --password-stdin`;
|
|
2948
|
+
yield this._cliExec.execAsync(cmd2, { cwd: workingDir, shell: "bash", env: { REG_PWD: regSecret } });
|
|
2949
|
+
// Push the image
|
|
2950
|
+
this.ux.userMessage(`Pushing [${this.styler.hilite(imageName)}] to ${registry.environment} registry as [${this.styler.hilite(fullImageId)}]...`);
|
|
2951
|
+
let cmd3 = `docker push ${fullImageId}`;
|
|
2952
|
+
yield this._cliExec.spawnAndLog(cmd3, workingDir, undefined, IBetterLogger_1.LogLevel.detail);
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
else {
|
|
2956
|
+
// Push the image
|
|
2957
|
+
this.ux.userMessage(`Pushing [${this.styler.hilite(imageName)}] to ${registry.environment} registry as [${this.styler.hilite(fullImageId)}]...`);
|
|
2958
|
+
let cmd4 = `docker push ${fullImageId}`;
|
|
2959
|
+
yield this._cliExec.spawnAndLog(cmd4, workingDir, undefined, IBetterLogger_1.LogLevel.detail);
|
|
2960
|
+
// let pushResult = await this._cliExec.execAsyncStdOut(cmd3, { cwd: workingDir }, LogLevel.detail);
|
|
2961
|
+
}
|
|
2962
|
+
// this.logger.trace(`${fullImageId}`);
|
|
2963
|
+
this.ux.userMessage(this.styler.colorGood("COMPLETE!"));
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
else {
|
|
2967
|
+
this.logger.debug(`Skipping publish for readonly image: ${imageName}.`);
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
else {
|
|
2973
|
+
this.logger.detail(`No image exports are declared for [${relFolderPath}].`, `Use 'codiac images:add' to do so.`);
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
else {
|
|
2977
|
+
this.logger.detail(`No images to publish in [${relFolderPath}].`, `Did not find a ${codiac_ops_common_3.OpsConstants.PROJECT_CONFIG_FILENAME} in folder: ${workingDir}, in which images must be declared, so no images can be published. You must initialize the folder as a Codiac project and then use "codiac images:add" to declare image exports for it. `);
|
|
2978
|
+
}
|
|
2979
|
+
resolve();
|
|
2980
|
+
}
|
|
2981
|
+
catch (err) {
|
|
2982
|
+
reject(err);
|
|
2983
|
+
}
|
|
2984
|
+
}));
|
|
2985
|
+
});
|
|
2986
|
+
}
|
|
2987
|
+
pushLegacy() {
|
|
2988
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2989
|
+
try {
|
|
2990
|
+
// // ---Relay-only operations classes---------------------------------------------------------------------------------------------
|
|
2991
|
+
// let clientsFactory = this.ioc.get<ImageRegistryClientsFactory>(ImageRegistryClientsFactory);
|
|
2992
|
+
// var regClient = clientsFactory.createForDomain(registry.registryUrl);
|
|
2993
|
+
// let pushResult = await regClient.push(imageName, tag);
|
|
2994
|
+
// if (pushResult.error) {
|
|
2995
|
+
// this.logger.error(`Error pushing ${imageName}: ${pushResult.error.name ?? ""} ${pushResult.error.message ?? pushResult.error.stack}`, pushResult.error);
|
|
2996
|
+
// }
|
|
2997
|
+
// // ---Legacy Registry client---------------------------------------------------------------------------------------------
|
|
2998
|
+
// let regClient = new CompositeImageRegistryClient(this.ioc);
|
|
2999
|
+
// await regClient.push(registry.registryUrl, imageName, tag);
|
|
3000
|
+
// // ---Hardcoded for Azure---------------------------------------------------------------------------------------------
|
|
3001
|
+
// let userArg = (registry.username) ? ` -u ${registry.username}` : ``;
|
|
3002
|
+
// let passArg = (registry.password) ? ` -p ${registry.password}` : ``;
|
|
3003
|
+
// let cmdLogin: string;
|
|
3004
|
+
// let loginEnv: { [key: string]: any } = { ...process.env };
|
|
3005
|
+
// if (!userArg && !passArg && registry.registryUrl.endsWith(".azurecr.io")) {
|
|
3006
|
+
// cmdLogin = `az acr login --name ${registry.registryUrl.split(".")[0]}`
|
|
3007
|
+
// } else {
|
|
3008
|
+
// // let regToken = "8c307c0b-e0ae-4945-9567-1da692b99322";
|
|
3009
|
+
// // userArg = `-u "<token>"`; // nope that only works when using a credentials store.
|
|
3010
|
+
// loginEnv.registry_pwd = registry.password;
|
|
3011
|
+
// cmdLogin = `echo $registry_pwd | docker login ${registry.registryUrl} ${userArg} --password-stdin`;
|
|
3012
|
+
// }
|
|
3013
|
+
// this.logger.notice(`Logging in and pushing [${this.styler.hilite(imageName)}] to ${registry.environment} registry as [${this.styler.hilite(fullImageId)}]...`);
|
|
3014
|
+
// let cmdLoginAndPush = cmdLogin.concat(` && docker push ${fullImageId}`);
|
|
3015
|
+
// await this._cliExec.spawnAndLog(cmdLoginAndPush, workingDir, loginEnv, LogLevel.detail);
|
|
3016
|
+
// // let pushResult = await this._cliExec.execAsyncStdOut(cmdLoginAndPush, { cwd: workingDir, env: loginEnv });
|
|
3017
|
+
// // TODO: allow authentication to fail and prompt the user for creds and then save em down in cfg.
|
|
3018
|
+
// // ------------------------------------------------------------------------------------------------
|
|
3019
|
+
return;
|
|
3020
|
+
}
|
|
3021
|
+
catch (err) {
|
|
3022
|
+
throw err;
|
|
3023
|
+
}
|
|
3024
|
+
});
|
|
3025
|
+
}
|
|
3026
|
+
/** This was lifted Copy-Paste from AzureContainerRegistryClient in the relay. */
|
|
3027
|
+
pushToAzure(fullImageId, registryDomain) {
|
|
3028
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
3029
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
3030
|
+
var _a, _b;
|
|
3031
|
+
const result = new contracts_1.Result(false);
|
|
3032
|
+
try {
|
|
3033
|
+
// if (!Boolean(registryDomain))
|
|
3034
|
+
// throw new CodiacError('Registry URL is required for push method of AzureContainerRegistryClient.')
|
|
3035
|
+
// let fullImageId = `${this.acrConnection.registryDomainName}/${imageName}:${tag}`;
|
|
3036
|
+
// await this.setRelevantAzSubscription(); // <--- this is no longer doing anything...
|
|
3037
|
+
// Does this select the right az creds? How can it?
|
|
3038
|
+
// TODO: We need to save the subscription Id with the codiac project, so we can select prevent az account mismatches.
|
|
3039
|
+
// Q: When would we gather the subscriptionId? A: Upon image declaration (and then whenever we mod the registry for it)
|
|
3040
|
+
let cmdLogin = `az acr login --name ${(registryDomain !== null && registryDomain !== void 0 ? registryDomain : '').split(".")[0]}`;
|
|
3041
|
+
let loginEnv = Object.assign({}, process.env);
|
|
3042
|
+
let workingDir = process.cwd();
|
|
3043
|
+
// this.logger.notice(`Logging in and pushing [${this.styler.hilite(scopedImageName)}] to registry as [${this.styler.hilite(fullImageId)}]...`);
|
|
3044
|
+
this.logger.notice(`Logging in and pushing [${fullImageId}] to registry...`);
|
|
3045
|
+
let cmdLoginAndPush = cmdLogin.concat(` && docker push ${fullImageId}`);
|
|
3046
|
+
yield this._cliExec.spawnAndLog(cmdLoginAndPush, workingDir, loginEnv, IBetterLogger_1.LogLevel.detail);
|
|
3047
|
+
result.success = true;
|
|
3048
|
+
}
|
|
3049
|
+
catch (error) {
|
|
3050
|
+
result.error = error;
|
|
3051
|
+
result.message = `Error pushing image "${fullImageId}" to [${registryDomain}]: ${(_a = error.name) !== null && _a !== void 0 ? _a : ""} ${(_b = error.message) !== null && _b !== void 0 ? _b : ""}.`;
|
|
3052
|
+
}
|
|
3053
|
+
finally {
|
|
3054
|
+
resolve(result);
|
|
3055
|
+
}
|
|
3056
|
+
}));
|
|
3057
|
+
});
|
|
3058
|
+
}
|
|
3059
|
+
/** Ensures that the current azure subscription matches the one that owns the registry for the given image. */
|
|
3060
|
+
setRelevantAzSubscription() {
|
|
3061
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
3062
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
3063
|
+
try {
|
|
3064
|
+
// TIP: When outputting a single value from an az cli command, use "-o tsv" to remove the quotes from the output.
|
|
3065
|
+
let whoami = `az account show -o json`; // retrieves current az username
|
|
3066
|
+
let azTenantUser = yield this._cliExec.execAsyncJson(whoami, { cwd: process.cwd() }, IBetterLogger_1.LogLevel.debug);
|
|
3067
|
+
this.logger.debug(`Current Azure user subscription: ${azTenantUser.name}, ${azTenantUser.id}`, azTenantUser);
|
|
3068
|
+
// TODO: Enforce consistency betw AZ subscriptionId for the project and the current azure account
|
|
3069
|
+
// if (azTenantUser.id != this.subxIdForRegistry) {
|
|
3070
|
+
// // let getMySubs = `az account list --query "[?id == '${subxIdForRegistry}']" -o json`;
|
|
3071
|
+
// // let mySubs = await this._cliExec.execAsyncJson<AzureTenantUser[]>(getMySubs, { cwd: process.cwd() }, LogLevel.debug);
|
|
3072
|
+
// // if (mySubs.length > 0) {
|
|
3073
|
+
// // // Switch to the relevant account
|
|
3074
|
+
// // let setSubx = `az account set --subscription ${subxIdForRegistry}`;
|
|
3075
|
+
// // azTenantUser = await this._cliExec.execAsyncJson<AzureTenantUser>(setSubx, { cwd: process.cwd() }, LogLevel.debug);
|
|
3076
|
+
// // }
|
|
3077
|
+
// }
|
|
3078
|
+
resolve();
|
|
3079
|
+
}
|
|
3080
|
+
catch (err) {
|
|
3081
|
+
reject(err);
|
|
3082
|
+
}
|
|
3083
|
+
}));
|
|
3084
|
+
});
|
|
3085
|
+
}
|
|
3086
|
+
/** Fires off the given commands
|
|
3087
|
+
* and commits the changes to source control.
|
|
3088
|
+
* @param commands The list of cli statements to execute
|
|
3089
|
+
* @param desc The comment applied to the commit; should be a description of the overall operation.
|
|
3090
|
+
* @param workingDirectory The fully qualified path from which to run the given commands and the source control commit statements...
|
|
3091
|
+
*/
|
|
3092
|
+
execAndCommit(commands, desc, workingDirectory) {
|
|
3093
|
+
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
3094
|
+
try {
|
|
3095
|
+
let execOptions = { cwd: workingDirectory };
|
|
3096
|
+
yield this._cliExec.execMany(commands, desc, execOptions);
|
|
3097
|
+
if (yield this.gitHasChanges(workingDirectory)) {
|
|
3098
|
+
yield this._cliExec.execAsyncStdOut(`git add -A`, execOptions);
|
|
3099
|
+
yield this._cliExec.execAsyncStdOut(`git commit -m '${desc}'`, execOptions);
|
|
3100
|
+
}
|
|
3101
|
+
resolve();
|
|
3102
|
+
}
|
|
3103
|
+
catch (err) {
|
|
3104
|
+
reject(err);
|
|
3105
|
+
}
|
|
3106
|
+
}));
|
|
3107
|
+
}
|
|
3108
|
+
};
|
|
3109
|
+
LocalOps = tslib_1.__decorate([
|
|
3110
|
+
(0, inversify_1.injectable)(),
|
|
3111
|
+
tslib_1.__metadata("design:paramtypes", [inversify_1.Container
|
|
3112
|
+
// , @inject(CliEnviro) public cliEnviro: CliEnviro
|
|
3113
|
+
// , @inject(ProjectEnviro) private projEnviro: ProjectEnviro
|
|
3114
|
+
// , @inject(CliContextRepo) private _cfgRepo: CliContextRepo
|
|
3115
|
+
// , @inject(INTERFACES_OPS.IUserInputProvider) private ux: IUserInputProvider
|
|
3116
|
+
// , @inject(INTERFACES_OPS.IOutputStyler) private styler: IOutputStyler
|
|
3117
|
+
// , @inject(CliExec) private _cliExec: CliExec
|
|
3118
|
+
// , @inject(INTERFACES.IBetterLogger) private logger: IBetterLogger
|
|
3119
|
+
])
|
|
3120
|
+
], LocalOps);
|
|
3121
|
+
exports.LocalOps = LocalOps;
|
|
3122
|
+
//# sourceMappingURL=LocalOps.js.map
|