From 63ce40ecb3c98e423b5137b09c0d5e126df1bc62 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 25 Jun 2024 11:40:27 -0500 Subject: [PATCH 1/6] fix(perf): fewer adapter classes --- src/resolve/adapters/baseSourceAdapter.ts | 9 +-------- src/resolve/metadataResolver.ts | 23 ++++++++++++++++------- src/resolve/types.ts | 5 ----- test/resolve/registryTestUtil.ts | 1 - 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/resolve/adapters/baseSourceAdapter.ts b/src/resolve/adapters/baseSourceAdapter.ts index 2e232a1a9b..9f37ee05af 100644 --- a/src/resolve/adapters/baseSourceAdapter.ts +++ b/src/resolve/adapters/baseSourceAdapter.ts @@ -77,13 +77,6 @@ export abstract class BaseSourceAdapter implements SourceAdapter { return this.populate(path, component, isResolvingSource); } - /** - * Control whether metadata and content metadata files are allowed for an adapter. - */ - public allowMetadataWithContent(): boolean { - return this.metadataWithContent; - } - /** * If the path given to `getComponent` is the root metadata xml file for a component, * parse the name and return it. This is an optimization to not make a child adapter do @@ -114,7 +107,7 @@ export abstract class BaseSourceAdapter implements SourceAdapter { return folderMetadataXml; } - if (!this.allowMetadataWithContent()) { + if (!this.metadataWithContent) { return parseAsContentMetadataXml(this.type)(path); } } diff --git a/src/resolve/metadataResolver.ts b/src/resolve/metadataResolver.ts index 622f2c61f8..59cb6cef3f 100644 --- a/src/resolve/metadataResolver.ts +++ b/src/resolve/metadataResolver.ts @@ -125,16 +125,19 @@ export class MetadataResolver { } const type = resolveType(this.registry)(this.tree)(fsPath); if (type) { - const adapter = new SourceAdapterFactory(this.registry, this.tree).getAdapter(type, this.forceIgnore); // short circuit the component resolution unless this is a resolve for a // source path or allowed content-only path, otherwise the adapter // knows how to handle it - const shouldResolve = - isResolvingSource || - parseAsRootMetadataXml(fsPath) || - !parseAsContentMetadataXml(this.registry)(fsPath) || - !adapter.allowMetadataWithContent(); - return shouldResolve ? adapter.getComponent(fsPath, isResolvingSource) : undefined; + if ( + !isResolvingSource && + !parseAsRootMetadataXml(fsPath) && + parseAsContentMetadataXml(this.registry)(fsPath) && + typeAllowsMetadataWithContent(type) + ) { + return; + } + const adapter = new SourceAdapterFactory(this.registry, this.tree).getAdapter(type, this.forceIgnore); + return adapter.getComponent(fsPath, isResolvingSource); } if (isProbablyPackageManifest(this.tree)(fsPath)) return undefined; @@ -439,3 +442,9 @@ const pathIncludesDirName = * @param fsPath File path of a potential metadata xml file */ const parseAsRootMetadataXml = (fsPath: string): boolean => Boolean(parseMetadataXml(fsPath)); + +/** decomposed and default types are `false`, everything else is true */ +const typeAllowsMetadataWithContent = (type: MetadataType): boolean => + type.strategies?.adapter !== undefined && // another way of saying default + type.strategies.adapter !== 'decomposed' && + type.strategies.adapter !== 'default'; diff --git a/src/resolve/types.ts b/src/resolve/types.ts index 644dd1b7a4..6b1c23c8d0 100644 --- a/src/resolve/types.ts +++ b/src/resolve/types.ts @@ -52,9 +52,4 @@ export type SourceAdapter = { * @param isResolvingSource Whether the path to resolve is a single file */ getComponent(fsPath: SourcePath, isResolvingSource?: boolean): SourceComponent | undefined; - - /** - * Whether the adapter allows content-only metadata definitions. - */ - allowMetadataWithContent(): boolean; }; diff --git a/test/resolve/registryTestUtil.ts b/test/resolve/registryTestUtil.ts index 57dc23d8ef..ac9fbcb50c 100644 --- a/test/resolve/registryTestUtil.ts +++ b/test/resolve/registryTestUtil.ts @@ -48,7 +48,6 @@ export class RegistryTestUtil { } getAdapterStub.withArgs(entry.type).returns({ getComponent: (path: SourcePath) => componentMap[path], - allowMetadataWithContent: () => entry.allowContent ?? false, }); } } From fd4084058819fea040dca5742bb88745d370f2a7 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 25 Jun 2024 11:49:57 -0500 Subject: [PATCH 2/6] refactor: derive metadataWithContent directly from type, not type => adapter --- src/registry/registryAccess.ts | 6 ++++++ src/resolve/adapters/baseSourceAdapter.ts | 5 ++--- src/resolve/adapters/decomposedSourceAdapter.ts | 1 - src/resolve/adapters/defaultSourceAdapter.ts | 2 -- src/resolve/metadataResolver.ts | 8 +------- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/registry/registryAccess.ts b/src/registry/registryAccess.ts index 2b3c2c2d7e..25b7dbefb1 100644 --- a/src/registry/registryAccess.ts +++ b/src/registry/registryAccess.ts @@ -178,3 +178,9 @@ export class RegistryAccess { } } } + +/** decomposed and default types are `false`, everything else is true */ +export const typeAllowsMetadataWithContent = (type: MetadataType): boolean => + type.strategies?.adapter !== undefined && // another way of saying default + type.strategies.adapter !== 'decomposed' && + type.strategies.adapter !== 'default'; diff --git a/src/resolve/adapters/baseSourceAdapter.ts b/src/resolve/adapters/baseSourceAdapter.ts index 9f37ee05af..b1c5ec7dd0 100644 --- a/src/resolve/adapters/baseSourceAdapter.ts +++ b/src/resolve/adapters/baseSourceAdapter.ts @@ -14,7 +14,7 @@ import { NodeFSTreeContainer, TreeContainer } from '../treeContainers'; import { SourceComponent } from '../sourceComponent'; import { SourcePath } from '../../common/types'; import { MetadataType } from '../../registry/types'; -import { RegistryAccess } from '../../registry/registryAccess'; +import { RegistryAccess, typeAllowsMetadataWithContent } from '../../registry/registryAccess'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/source-deploy-retrieve', 'sdr'); @@ -30,7 +30,6 @@ export abstract class BaseSourceAdapter implements SourceAdapter { * folder, including its root metadata xml file. */ protected ownFolder = false; - protected metadataWithContent = true; public constructor( type: MetadataType, @@ -107,7 +106,7 @@ export abstract class BaseSourceAdapter implements SourceAdapter { return folderMetadataXml; } - if (!this.metadataWithContent) { + if (!typeAllowsMetadataWithContent(this.type)) { return parseAsContentMetadataXml(this.type)(path); } } diff --git a/src/resolve/adapters/decomposedSourceAdapter.ts b/src/resolve/adapters/decomposedSourceAdapter.ts index aef8af0ad4..b68f1d8d6a 100644 --- a/src/resolve/adapters/decomposedSourceAdapter.ts +++ b/src/resolve/adapters/decomposedSourceAdapter.ts @@ -43,7 +43,6 @@ const messages = Messages.loadMessages('@salesforce/source-deploy-retrieve', 'sd */ export class DecomposedSourceAdapter extends MixedContentSourceAdapter { protected ownFolder = true; - protected metadataWithContent = false; public getComponent(path: SourcePath, isResolvingSource = true): SourceComponent | undefined { let rootMetadata = super.parseAsRootMetadataXml(path); diff --git a/src/resolve/adapters/defaultSourceAdapter.ts b/src/resolve/adapters/defaultSourceAdapter.ts index 7f8a8a22c5..35218b9b9a 100644 --- a/src/resolve/adapters/defaultSourceAdapter.ts +++ b/src/resolve/adapters/defaultSourceAdapter.ts @@ -23,8 +23,6 @@ import { BaseSourceAdapter } from './baseSourceAdapter'; *``` */ export class DefaultSourceAdapter extends BaseSourceAdapter { - protected metadataWithContent = false; - /* istanbul ignore next */ // retained to preserve API // eslint-disable-next-line class-methods-use-this diff --git a/src/resolve/metadataResolver.ts b/src/resolve/metadataResolver.ts index 59cb6cef3f..e4f1fe1bca 100644 --- a/src/resolve/metadataResolver.ts +++ b/src/resolve/metadataResolver.ts @@ -7,7 +7,7 @@ import { basename, dirname, sep } from 'node:path'; import { Lifecycle, Messages, SfError, Logger } from '@salesforce/core'; import { extName, fnJoin, parentName, parseMetadataXml } from '../utils/path'; -import { RegistryAccess } from '../registry/registryAccess'; +import { RegistryAccess, typeAllowsMetadataWithContent } from '../registry/registryAccess'; import { MetadataType } from '../registry/types'; import { ComponentSet } from '../collections/componentSet'; import { META_XML_SUFFIX } from '../common/constants'; @@ -442,9 +442,3 @@ const pathIncludesDirName = * @param fsPath File path of a potential metadata xml file */ const parseAsRootMetadataXml = (fsPath: string): boolean => Boolean(parseMetadataXml(fsPath)); - -/** decomposed and default types are `false`, everything else is true */ -const typeAllowsMetadataWithContent = (type: MetadataType): boolean => - type.strategies?.adapter !== undefined && // another way of saying default - type.strategies.adapter !== 'decomposed' && - type.strategies.adapter !== 'default'; From 70cf34ca4a7987aab605ef093eabdda345434771 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 25 Jun 2024 11:55:21 -0500 Subject: [PATCH 3/6] test: remove invalid test case --- .../resolve/adapters/defaultSourceAdapter.test.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/test/resolve/adapters/defaultSourceAdapter.test.ts b/test/resolve/adapters/defaultSourceAdapter.test.ts index a1841300b6..fc3c0df558 100644 --- a/test/resolve/adapters/defaultSourceAdapter.test.ts +++ b/test/resolve/adapters/defaultSourceAdapter.test.ts @@ -12,7 +12,7 @@ import { META_XML_SUFFIX } from '../../../src/common'; describe('DefaultSourceAdapter', () => { it('should return a SourceComponent when given a metadata xml file', () => { - const type = registry.types.apexclass; + const type = registry.types.eventdelivery; const path = join('path', 'to', type.directoryName, `My_Test.${type.suffix}${META_XML_SUFFIX}`); const adapter = new DefaultSourceAdapter(type); expect(adapter.getComponent(path)).to.deep.equal( @@ -23,17 +23,4 @@ describe('DefaultSourceAdapter', () => { }) ); }); - - it('should return a SourceComponent when given a content-only metadata file', () => { - const type = registry.types.apexclass; - const path = join('path', 'to', type.directoryName, `My_Test.${type.suffix}`); - const adapter = new DefaultSourceAdapter(type); - expect(adapter.getComponent(path)).to.deep.equal( - new SourceComponent({ - name: 'My_Test', - type, - xml: path, - }) - ); - }); }); From 309513427ec1fdf24eca8b06cc20c81d6270882a Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 25 Jun 2024 12:03:14 -0500 Subject: [PATCH 4/6] chore: bump core for xnuts --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 6e03e3ffce..e2d4ac8d3a 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "node": ">=18.0.0" }, "dependencies": { - "@salesforce/core": "^8.0.3", + "@salesforce/core": "^8.0.5", "@salesforce/kit": "^3.1.6", "@salesforce/ts-types": "^2.0.10", "fast-levenshtein": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 86cebf8b9f..09ad68595f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -502,10 +502,10 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@jsforce/jsforce-node@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@jsforce/jsforce-node/-/jsforce-node-3.2.0.tgz#4b104613fc9bb74e0e38d2c00936ea2b228ba73a" - integrity sha512-3GjWNgWs0HFajVhIhwvBPb0B45o500wTBNEBYxy8XjeeRra+qw8A9xUrfVU7TAGev8kXuKhjJwaTiSzThpEnew== +"@jsforce/jsforce-node@^3.2.0", "@jsforce/jsforce-node@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@jsforce/jsforce-node/-/jsforce-node-3.2.1.tgz#00fab05919e0cbe91ae4d873377e56cfbc087b98" + integrity sha512-hjmZQbYVikm6ATmaErOp5NaKR2VofNZsrcGGHrdbGA+bAgpfg/+MA/HzRTb8BvYyPDq3RRc5A8Yk8gx9Vtcrxg== dependencies: "@sindresorhus/is" "^4" "@types/node" "^18.15.3" @@ -564,12 +564,12 @@ strip-ansi "6.0.1" ts-retry-promise "^0.8.1" -"@salesforce/core@^8.0.3": - version "8.0.3" - resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.0.3.tgz#8b25ce46100baef0a8e731b42d373edf508ab144" - integrity sha512-HirswUFGQIF5Ipaa+5l3kulBOf3L25Z3fzf5QqEI4vOxgBKN2bEdKHCA/PROufi3/ejFstiXcn9/jfgyjDdBqA== +"@salesforce/core@^8.0.3", "@salesforce/core@^8.0.5": + version "8.0.5" + resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.0.5.tgz#f3d4af7052ff39bf06ec89af3734339b3fabe879" + integrity sha512-+p1TYvKhXWlzah7qp+vnv5W63EZm6nn7zLRvivFsL6pza0B4siHWfx11ceJ4p7W8+kh/xeuygtkddwYoLS3KkA== dependencies: - "@jsforce/jsforce-node" "^3.2.0" + "@jsforce/jsforce-node" "^3.2.1" "@salesforce/kit" "^3.1.6" "@salesforce/schemas" "^1.9.0" "@salesforce/ts-types" "^2.0.10" From 9d17468c2820c2239d9501bdcc1477163efd579b Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 25 Jun 2024 17:43:39 -0500 Subject: [PATCH 5/6] chore: deps for xnuts? --- package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e2d4ac8d3a..f961ffb0a5 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "proxy-agent": "^6.4.0" }, "devDependencies": { - "@jsforce/jsforce-node": "^3.2.0", + "@jsforce/jsforce-node": "^3.2.1", "@salesforce/cli-plugins-testkit": "^5.3.16", "@salesforce/dev-scripts": "^10.2.2", "@types/deep-equal-in-any-order": "^1.0.1", diff --git a/yarn.lock b/yarn.lock index 09ad68595f..2279fb67ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -502,7 +502,7 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@jsforce/jsforce-node@^3.2.0", "@jsforce/jsforce-node@^3.2.1": +"@jsforce/jsforce-node@^3.2.1": version "3.2.1" resolved "https://registry.yarnpkg.com/@jsforce/jsforce-node/-/jsforce-node-3.2.1.tgz#00fab05919e0cbe91ae4d873377e56cfbc087b98" integrity sha512-hjmZQbYVikm6ATmaErOp5NaKR2VofNZsrcGGHrdbGA+bAgpfg/+MA/HzRTb8BvYyPDq3RRc5A8Yk8gx9Vtcrxg== From cb3a2197f9076d34d43a301e6e6bfc97af28f931 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 25 Jun 2024 17:44:31 -0500 Subject: [PATCH 6/6] chore: typo --- src/resolve/metadataResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolve/metadataResolver.ts b/src/resolve/metadataResolver.ts index e4f1fe1bca..0e1c41bb59 100644 --- a/src/resolve/metadataResolver.ts +++ b/src/resolve/metadataResolver.ts @@ -354,7 +354,7 @@ const resolveType = /** * Any file with a registered suffix is potentially a content metadata file. * - * @param registry a metadata registry to resolve types agsinst + * @param registry a metadata registry to resolve types against */ const parseAsContentMetadataXml = (registry: RegistryAccess) =>