Skip to content

Commit 137cd39

Browse files
committed
feat: trackingFiles handle deleted bundle members
1 parent 0aedbd5 commit 137cd39

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

src/shared/functions.ts

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77

8+
import { SourceComponent } from '@salesforce/source-deploy-retrieve';
89
import { RemoteChangeElement, ChangeResult } from './types';
910

1011
export const getMetadataKey = (metadataType: string, metadataName: string): string => {
@@ -17,3 +18,5 @@ export const getKeyFromObject = (element: RemoteChangeElement | ChangeResult): s
1718
}
1819
throw new Error(`unable to complete key from ${JSON.stringify(element)}`);
1920
};
21+
22+
export const isBundle = (cmp: SourceComponent): boolean => cmp.type.strategies?.adapter === 'bundle';

src/sourceTracking.ts

+35-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77
import * as fs from 'fs';
8-
import { isAbsolute, relative, resolve, normalize } from 'path';
8+
import { isAbsolute, relative, resolve, sep, normalize } from 'path';
99
import { EOL } from 'os';
1010
import { NamedPackageDir, Logger, Org, SfdxProject } from '@salesforce/core';
1111
import { AsyncCreatable } from '@salesforce/kit';
@@ -34,7 +34,7 @@ import {
3434
RemoteChangeElement,
3535
} from './shared/types';
3636
import { sourceComponentGuard, metadataMemberGuard } from './shared/guards';
37-
import { getKeyFromObject, getMetadataKey } from './shared/functions';
37+
import { getKeyFromObject, getMetadataKey, isBundle } from './shared/functions';
3838

3939
export interface SourceTrackingOptions {
4040
org: Org;
@@ -83,7 +83,6 @@ export class SourceTracking extends AsyncCreatable {
8383
*/
8484
public async localChangesAsComponentSet(byPackageDir = false): Promise<ComponentSet[]> {
8585
const [projectConfig] = await Promise.all([this.project.resolveProjectConfig(), this.ensureLocalTracking()]);
86-
// path may have been cloned from the other OS
8786
this.forceIgnore ??= ForceIgnore.findAndCreate(this.project.getDefaultPackage().name);
8887

8988
const sourceApiVersion = getString(projectConfig, 'sourceApiVersion');
@@ -138,11 +137,7 @@ export class SourceTracking extends AsyncCreatable {
138137
.filter(sourceComponentGuard)
139138
.map((component) => {
140139
// if the component is a file in a bundle type AND there are files from the bundle that are not deleted, set the bundle for deploy, not for delete
141-
if (
142-
component.type.strategies?.adapter === 'bundle' &&
143-
component.content &&
144-
fs.existsSync(component.content)
145-
) {
140+
if (isBundle(component) && component.content && fs.existsSync(component.content)) {
146141
// all bundle types have a directory name
147142
try {
148143
resolverForNonDeletes
@@ -343,9 +338,39 @@ export class SourceTracking extends AsyncCreatable {
343338
*/
344339
public async updateLocalTracking(options: LocalUpdateOptions): Promise<void> {
345340
await this.ensureLocalTracking();
341+
342+
// relative paths make smaller trees AND isogit wants them relative
343+
const relativeOptions = {
344+
files: (options.files ?? []).map((file) => this.ensureRelative(file)),
345+
deletedFiles: (options.deletedFiles ?? []).map((file) => this.ensureRelative(file)),
346+
};
347+
// plot twist: if you delete a member of a bundle (ex: lwc/foo/foo.css) and push, it'll not be in the fileResponses (deployedFiles) or deletedFiles
348+
// what got deleted? Any local changes NOT in the fileResponses but part of a successfully deployed bundle
349+
const deployedFilesAsVirtualComponentSet = ComponentSet.fromSource({
350+
// resolve from highest possible level. TODO: can we use [.]
351+
fsPaths: relativeOptions.files.length ? [relativeOptions.files[0].split(sep)[0]] : [],
352+
tree: VirtualTreeContainer.fromFilePaths(relativeOptions.files),
353+
});
354+
// these are top-level bundle paths like lwc/foo
355+
const bundlesWithDeletedFiles = (
356+
await this.getChanges<SourceComponent>({ origin: 'local', state: 'delete', format: 'SourceComponent' })
357+
)
358+
.filter(isBundle)
359+
.filter((cmp) => deployedFilesAsVirtualComponentSet.has({ type: cmp.type, fullName: cmp.fullName }))
360+
.map((cmp) => cmp.content)
361+
.filter(isString);
362+
346363
await this.localRepo.commitChanges({
347-
deployedFiles: options.files?.map((file) => this.ensureRelative(file)),
348-
deletedFiles: options.deletedFiles?.map((file) => this.ensureRelative(file)),
364+
deployedFiles: relativeOptions.files,
365+
deletedFiles: relativeOptions.deletedFiles.concat(
366+
(
367+
await this.localRepo.getDeleteFilenames()
368+
).filter(
369+
(deployedFile) =>
370+
bundlesWithDeletedFiles.some((bundlePath) => deployedFile.startsWith(bundlePath)) &&
371+
!relativeOptions.files.includes(deployedFile)
372+
)
373+
),
349374
});
350375
}
351376

0 commit comments

Comments
 (0)