From 108c06040366276cf1e68483c7dab3252a7ff4a3 Mon Sep 17 00:00:00 2001 From: Steve Hetzel Date: Thu, 19 Dec 2024 14:10:46 -0700 Subject: [PATCH 1/7] feat: support generating a manifest from an org with include and exclude metadata lists --- command-snapshot.json | 1 + messages/manifest.generate.md | 14 +++++++++ package.json | 2 +- src/commands/project/generate/manifest.ts | 35 ++++++++++++++++------- test/tsconfig.json | 6 +++- tsconfig.json | 5 +++- yarn.lock | 19 ++++++++++++ 7 files changed, 69 insertions(+), 13 deletions(-) diff --git a/command-snapshot.json b/command-snapshot.json index 69009d71..3f897963 100644 --- a/command-snapshot.json +++ b/command-snapshot.json @@ -239,6 +239,7 @@ "flagChars": ["c", "d", "m", "n", "p", "t"], "flags": [ "api-version", + "exclude-metadata", "flags-dir", "from-org", "include-packages", diff --git a/messages/manifest.generate.md b/messages/manifest.generate.md index be2d5549..5fcd969c 100644 --- a/messages/manifest.generate.md +++ b/messages/manifest.generate.md @@ -19,6 +19,8 @@ Use --name to specify a custom name for the generated manifest if the pre-define To include multiple metadata components, either set multiple --metadata flags or a single --metadata flag with multiple names separated by spaces. Enclose names that contain spaces in one set of double quotes. The same syntax applies to --include-packages and --source-dir. +To build a manifest from the metadata in an org use the --from-org flag optionally combining it with the --metadata flag to only include certain metadata types, or the --exclude-metadata flag to exclude certain metadata types. When building a manifest from an org, the command makes many API calls concurrently to discover the metadata that exists in the org. To limit the number of concurrent requests use the `SF_LIST_METADATA_BATCH_SIZE` environment variable and set it to a size that works best for your org and environment. If you are experiencing timeouts and/or inconsistent manifest contents then setting this environment variable should improve accuracy. However, the command will take longer to run since it sends fewer requests at a time. + # examples - Create a manifest for deploying or retrieving all Apex classes and custom objects: @@ -37,10 +39,22 @@ To include multiple metadata components, either set multiple --metadata f $ <%= config.bin %> <%= command.id %> --from-org test@myorg.com --include-packages unlocked +- Create a manifest from specific metadata types in an org: + + $ <%= config.bin %> <%= command.id %> --from-org test@myorg.com --metadata ApexClass,CustomObject,CustomLabels + +- Create a manifest from all metadata components in an org excluding specific metadata types: + + $ <%= config.bin %> <%= command.id %> --from-org test@myorg.com --exclude-metadata StandardValueSet + # flags.include-packages.summary Package types (managed, unlocked) whose metadata is included in the manifest; by default, metadata in managed and unlocked packages is excluded. Metadata in unmanaged packages is always included. +# flags.exclude-metadata.summary + +Metadata types (types only; not names) to exclude when building a manifest from an org. + # flags.from-org.summary Username or alias of the org that contains the metadata components from which to build a manifest. diff --git a/package.json b/package.json index 4f39be22..7f00484d 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@salesforce/kit": "^3.2.3", "@salesforce/plugin-info": "^3.4.23", "@salesforce/sf-plugins-core": "^12.0.11", - "@salesforce/source-deploy-retrieve": "^12.10.2", + "@salesforce/source-deploy-retrieve": "12.10.4-dev-17431548.0", "@salesforce/source-tracking": "^7.1.17", "@salesforce/ts-types": "^2.0.12", "ansis": "^3.3.2", diff --git a/src/commands/project/generate/manifest.ts b/src/commands/project/generate/manifest.ts index 3d04f9d3..a38c9979 100644 --- a/src/commands/project/generate/manifest.ts +++ b/src/commands/project/generate/manifest.ts @@ -38,7 +38,7 @@ export type ManifestGenerateCommandResult = { path: string; }; -const xorFlags = ['metadata', 'source-dir', 'from-org']; +const atLeastOneOfFlags = ['metadata', 'source-dir', 'from-org']; export class ManifestGenerate extends SfCommand { public static readonly summary = messages.getMessage('summary'); @@ -53,14 +53,14 @@ export class ManifestGenerate extends SfCommand { metadata: arrayWithDeprecation({ char: 'm', summary: messages.getMessage('flags.metadata.summary'), - exactlyOne: xorFlags, + exclusive: ['source-dir'], }), 'source-dir': arrayWithDeprecation({ char: 'p', aliases: ['sourcepath'], deprecateAliases: true, summary: messages.getMessage('flags.source-dir.summary'), - exactlyOne: xorFlags, + exclusive: ['metadata'], }), name: Flags.string({ char: 'n', @@ -85,11 +85,18 @@ export class ManifestGenerate extends SfCommand { char: 'c', dependsOn: ['from-org'], }), + 'exclude-metadata': Flags.string({ + multiple: true, + delimiter: ',', + summary: messages.getMessage('flags.exclude-metadata.summary'), + dependsOn: ['from-org'], + exclusive: ['metadata'], + }), 'from-org': Flags.custom({ summary: messages.getMessage('flags.from-org.summary'), - exactlyOne: xorFlags, aliases: ['fromorg'], deprecateAliases: true, + exclusive: ['source-dir'], parse: async (input: string | undefined) => (input ? Org.create({ aliasOrUsername: input }) : undefined), })(), 'output-dir': Flags.string({ @@ -102,6 +109,12 @@ export class ManifestGenerate extends SfCommand { public async run(): Promise { const { flags } = await this.parse(ManifestGenerate); + + // We need at least one of these flags (but could be more than 1): 'metadata', 'source-dir', 'from-org' + if (!Object.keys(flags).some((f) => atLeastOneOfFlags.includes(f))) { + throw Error(`provided flags must include at least one of: ${atLeastOneOfFlags.toString()}`); + } + // convert the manifesttype into one of the "official" manifest names // if no manifesttype flag passed, use the manifestname?flag // if no manifestname flag, default to 'package.xml' @@ -114,12 +127,14 @@ export class ManifestGenerate extends SfCommand { const componentSet = await ComponentSetBuilder.build({ apiversion: flags['api-version'] ?? (await getSourceApiVersion()), sourcepath: flags['source-dir'], - metadata: flags.metadata - ? { - metadataEntries: flags.metadata, - directoryPaths: await getPackageDirs(), - } - : undefined, + metadata: + flags.metadata ?? flags['exclude-metadata'] + ? { + metadataEntries: flags.metadata ?? [], + directoryPaths: await getPackageDirs(), + excludedEntries: flags['exclude-metadata'], + } + : undefined, org: flags['from-org'] ? { username: flags['from-org'].getUsername() as string, diff --git a/test/tsconfig.json b/test/tsconfig.json index a5f451cf..b62002f0 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -2,6 +2,10 @@ "extends": "@salesforce/dev-config/tsconfig-test-strict-esm", "include": ["./**/*.ts"], "compilerOptions": { - "skipLibCheck": true + "skipLibCheck": true, + "baseUrl": "..", + "paths": { + "@salesforce/source-deploy-retrieve": ["node_modules/@salesforce/source-deploy-retrieve"] + } } } diff --git a/tsconfig.json b/tsconfig.json index 1fa9d631..5dbc2628 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,10 @@ "outDir": "lib", "rootDir": "src", "skipLibCheck": true, - "baseUrl": "." + "baseUrl": ".", + "paths": { + "@salesforce/source-deploy-retrieve": ["node_modules/@salesforce/source-deploy-retrieve"] + } }, "include": ["./src/**/*.ts"] } diff --git a/yarn.lock b/yarn.lock index 29710894..7e031d39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1671,6 +1671,25 @@ cli-progress "^3.12.0" terminal-link "^3.0.0" +"@salesforce/source-deploy-retrieve@12.10.4-dev-17431548.0": + version "12.10.4-dev-17431548.0" + resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-12.10.4-dev-17431548.0.tgz#3d1214fa7b69c9e4eaf68912cad198d55208b15c" + integrity sha512-tAvqDNp3Oa0QDGhs1rJCOJQYvRO7pfKxzWutjVN2g7fbxn/ej5U5ZX6hKfCp411+NmI7MsN5wUpjQOs185h0mA== + dependencies: + "@salesforce/core" "^8.8.0" + "@salesforce/kit" "^3.2.2" + "@salesforce/ts-types" "^2.0.12" + fast-levenshtein "^3.0.0" + fast-xml-parser "^4.5.0" + got "^11.8.6" + graceful-fs "^4.2.11" + ignore "^5.3.2" + isbinaryfile "^5.0.2" + jszip "^3.10.1" + mime "2.6.0" + minimatch "^9.0.5" + proxy-agent "^6.4.0" + "@salesforce/source-deploy-retrieve@^12.10.2", "@salesforce/source-deploy-retrieve@^12.7.4": version "12.10.2" resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-12.10.2.tgz#c3737f3751f84cb4754b666edd83c014c91b87bb" From 92182574f1e5075160a0d21717d697a84fef897a Mon Sep 17 00:00:00 2001 From: Steve Hetzel Date: Thu, 19 Dec 2024 14:33:53 -0700 Subject: [PATCH 2/7] fix: tsc issue --- src/commands/project/delete/source.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/commands/project/delete/source.ts b/src/commands/project/delete/source.ts index 103cc03d..67dc8284 100644 --- a/src/commands/project/delete/source.ts +++ b/src/commands/project/delete/source.ts @@ -404,9 +404,7 @@ export class Source extends SfCommand { .filter(sourceComponentIsNotInMixedDeployDelete(this.mixedDeployDelete)) .flatMap((c) => // for custom labels, print each custom label to be deleted, not the whole file - isNonDecomposedCustomLabelsOrCustomLabel(c) - ? [`${c.type.name}:${c.fullName}`] - : [c.xml, ...c.walkContent()] ?? [] + isNonDecomposedCustomLabelsOrCustomLabel(c) ? [`${c.type.name}:${c.fullName}`] : [c.xml, ...c.walkContent()] ) .concat(this.mixedDeployDelete.delete.map((fr) => `${fr.fullName} (${fr.filePath})`)); From c51330c2f21df5ecfbceb88b5a8e2a30facca353 Mon Sep 17 00:00:00 2001 From: Steve Hetzel Date: Thu, 19 Dec 2024 15:00:56 -0700 Subject: [PATCH 3/7] fix: flag name and help text edits --- command-snapshot.json | 2 +- messages/manifest.generate.md | 8 ++++---- src/commands/project/generate/manifest.ts | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/command-snapshot.json b/command-snapshot.json index 3f897963..7e29bd18 100644 --- a/command-snapshot.json +++ b/command-snapshot.json @@ -239,7 +239,7 @@ "flagChars": ["c", "d", "m", "n", "p", "t"], "flags": [ "api-version", - "exclude-metadata", + "excluded-metadata", "flags-dir", "from-org", "include-packages", diff --git a/messages/manifest.generate.md b/messages/manifest.generate.md index 5fcd969c..92285e5f 100644 --- a/messages/manifest.generate.md +++ b/messages/manifest.generate.md @@ -19,7 +19,7 @@ Use --name to specify a custom name for the generated manifest if the pre-define To include multiple metadata components, either set multiple --metadata flags or a single --metadata flag with multiple names separated by spaces. Enclose names that contain spaces in one set of double quotes. The same syntax applies to --include-packages and --source-dir. -To build a manifest from the metadata in an org use the --from-org flag optionally combining it with the --metadata flag to only include certain metadata types, or the --exclude-metadata flag to exclude certain metadata types. When building a manifest from an org, the command makes many API calls concurrently to discover the metadata that exists in the org. To limit the number of concurrent requests use the `SF_LIST_METADATA_BATCH_SIZE` environment variable and set it to a size that works best for your org and environment. If you are experiencing timeouts and/or inconsistent manifest contents then setting this environment variable should improve accuracy. However, the command will take longer to run since it sends fewer requests at a time. +To build a manifest from the metadata in an org, use the --from-org flag. You can combine --from-org with the --metadata flag to include only certain metadata types, or with the --excluded-metadata flag to exclude certain metadata types. When building a manifest from an org, the command makes many concurrent API calls to discover the metadata that exists in the org. To limit the number of concurrent requests, use the SF_LIST_METADATA_BATCH_SIZE environment variable and set it to a size that works best for your org and environment. If you experience timeouts or inconsistent manifest contents, then setting this environment variable can improve accuracy. However, the command takes longer to run because it sends fewer requests at a time. # examples @@ -45,15 +45,15 @@ To build a manifest from the metadata in an org use the --from-org flag optional - Create a manifest from all metadata components in an org excluding specific metadata types: - $ <%= config.bin %> <%= command.id %> --from-org test@myorg.com --exclude-metadata StandardValueSet + $ <%= config.bin %> <%= command.id %> --from-org test@myorg.com --excluded-metadata StandardValueSet # flags.include-packages.summary Package types (managed, unlocked) whose metadata is included in the manifest; by default, metadata in managed and unlocked packages is excluded. Metadata in unmanaged packages is always included. -# flags.exclude-metadata.summary +# flags.excluded-metadata.summary -Metadata types (types only; not names) to exclude when building a manifest from an org. +Metadata types to exclude when building a manifest from an org. Specify the name of the type, not the name of a specific component. # flags.from-org.summary diff --git a/src/commands/project/generate/manifest.ts b/src/commands/project/generate/manifest.ts index a38c9979..b800f430 100644 --- a/src/commands/project/generate/manifest.ts +++ b/src/commands/project/generate/manifest.ts @@ -85,10 +85,10 @@ export class ManifestGenerate extends SfCommand { char: 'c', dependsOn: ['from-org'], }), - 'exclude-metadata': Flags.string({ + 'excluded-metadata': Flags.string({ multiple: true, delimiter: ',', - summary: messages.getMessage('flags.exclude-metadata.summary'), + summary: messages.getMessage('flags.excluded-metadata.summary'), dependsOn: ['from-org'], exclusive: ['metadata'], }), @@ -128,11 +128,11 @@ export class ManifestGenerate extends SfCommand { apiversion: flags['api-version'] ?? (await getSourceApiVersion()), sourcepath: flags['source-dir'], metadata: - flags.metadata ?? flags['exclude-metadata'] + flags.metadata ?? flags['excluded-metadata'] ? { metadataEntries: flags.metadata ?? [], directoryPaths: await getPackageDirs(), - excludedEntries: flags['exclude-metadata'], + excludedEntries: flags['excluded-metadata'], } : undefined, org: flags['from-org'] From 8514583795b9a57581d9a81d8e84f8e4060e9d81 Mon Sep 17 00:00:00 2001 From: svc-cli-bot Date: Thu, 19 Dec 2024 22:29:57 +0000 Subject: [PATCH 4/7] chore(release): 3.16.2-dev-17431548.0 [skip ci] --- README.md | 57 ++++++++++++++++++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 75fa4005..f50e4ce3 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ FLAG DESCRIPTIONS If you specify this flag, don’t specify --metadata or --source-dir. ``` -_See code: [src/commands/project/convert/mdapi.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/convert/mdapi.ts)_ +_See code: [src/commands/project/convert/mdapi.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/convert/mdapi.ts)_ ## `sf project convert source` @@ -214,7 +214,7 @@ FLAG DESCRIPTIONS Override the api version used for api requests made by this command ``` -_See code: [src/commands/project/convert/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/convert/source.ts)_ +_See code: [src/commands/project/convert/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/convert/source.ts)_ ## `sf project convert source-behavior` @@ -272,7 +272,7 @@ EXAMPLES $ sf project convert source-behavior --behavior decomposePermissionSetBeta --dry-run --preserve-temp-dir ``` -_See code: [src/commands/project/convert/source-behavior.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/convert/source-behavior.ts)_ +_See code: [src/commands/project/convert/source-behavior.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/convert/source-behavior.ts)_ ## `sf project delete source` @@ -412,7 +412,7 @@ FLAG DESCRIPTIONS - Separate the test names with spaces: --tests Test1 Test2 "Test With Space" ``` -_See code: [src/commands/project/delete/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/delete/source.ts)_ +_See code: [src/commands/project/delete/source.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/delete/source.ts)_ ## `sf project delete tracking` @@ -449,7 +449,7 @@ EXAMPLES $ sf project delete tracking --target-org my-scratch ``` -_See code: [src/commands/project/delete/tracking.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/delete/tracking.ts)_ +_See code: [src/commands/project/delete/tracking.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/delete/tracking.ts)_ ## `sf project deploy cancel` @@ -521,7 +521,7 @@ FLAG DESCRIPTIONS project deploy report". ``` -_See code: [src/commands/project/deploy/cancel.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/deploy/cancel.ts)_ +_See code: [src/commands/project/deploy/cancel.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/deploy/cancel.ts)_ ## `sf project deploy preview` @@ -604,7 +604,7 @@ FLAG DESCRIPTIONS All child components are included. If you specify this flag, don’t specify --metadata or --source-dir. ``` -_See code: [src/commands/project/deploy/preview.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/deploy/preview.ts)_ +_See code: [src/commands/project/deploy/preview.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/deploy/preview.ts)_ ## `sf project deploy quick` @@ -688,7 +688,7 @@ FLAG DESCRIPTIONS deploy report". ``` -_See code: [src/commands/project/deploy/quick.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/deploy/quick.ts)_ +_See code: [src/commands/project/deploy/quick.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/deploy/quick.ts)_ ## `sf project deploy report` @@ -780,7 +780,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/report.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/deploy/report.ts)_ +_See code: [src/commands/project/deploy/report.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/deploy/report.ts)_ ## `sf project deploy resume` @@ -865,7 +865,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/resume.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/deploy/resume.ts)_ +_See code: [src/commands/project/deploy/resume.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/deploy/resume.ts)_ ## `sf project deploy start` @@ -1101,7 +1101,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/start.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/deploy/start.ts)_ +_See code: [src/commands/project/deploy/start.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/deploy/start.ts)_ ## `sf project deploy validate` @@ -1274,7 +1274,7 @@ FLAG DESCRIPTIONS --coverage-formatters lcov --coverage-formatters clover ``` -_See code: [src/commands/project/deploy/validate.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.1/src/commands/project/deploy/validate.ts)_ +_See code: [src/commands/project/deploy/validate.ts](https://github.com/salesforcecli/plugin-deploy-retrieve/blob/3.16.2-dev-17431548.0/src/commands/project/deploy/validate.ts)_ ## `sf project generate manifest` @@ -1282,8 +1282,9 @@ Create a project manifest that lists the metadata components you want to deploy ``` USAGE - $ sf project generate manifest [--json] [--flags-dir ] [--api-version ] [-m ...] [-p ...] [-n - | -t pre|post|destroy|package] [-c managed|unlocked... --from-org ] [-d ] + $ sf project generate manifest [--json] [--flags-dir ] [--api-version ] [-m ... | -p ...] [-n + | -t pre|post|destroy|package] [-c managed|unlocked... --from-org ] [--excluded-metadata ... ] + [-d ] FLAGS -c, --include-packages=