Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into sh/deploy-zip-size
Browse files Browse the repository at this point in the history
  • Loading branch information
cristiand391 committed Aug 26, 2024
2 parents 7468cc7 + 5f819ec commit 8c68696
Show file tree
Hide file tree
Showing 10 changed files with 700 additions and 667 deletions.
1,275 changes: 639 additions & 636 deletions METADATA_SUPPORT.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"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",
Expand Down
11 changes: 9 additions & 2 deletions src/convert/replacements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
*/
import { readFile } from 'node:fs/promises';
import { Transform, Readable } from 'node:stream';
import { sep, posix, join, isAbsolute } from 'node:path';
import { sep, posix, join, isAbsolute, extname } from 'node:path';
import { Lifecycle, Messages, SfError, SfProject } from '@salesforce/core';
import { minimatch } from 'minimatch';
import { Env } from '@salesforce/kit';
import { ensureString, isString } from '@salesforce/ts-types';
import { isBinaryFileSync } from 'isbinaryfile';
import { SourcePath } from '../common/types';
import { SourceComponent } from '../resolve/sourceComponent';
import { MarkedReplacement, ReplacementConfig, ReplacementEvent } from './types';
Expand All @@ -20,14 +21,20 @@ const messages = Messages.loadMessages('@salesforce/source-deploy-retrieve', 'sd

const fileContentsCache = new Map<string, string>();

// First do a quick check for common text extensions
// If that fails, confirm that it is not a binary file
const textExtensions = new Set(['.cls', '.xml', '.json', '.js', '.css', '.html', '.htm', '.txt', '.md']);
const isTextFile = (path: string): boolean => textExtensions.has(extname(path)) || !isBinaryFileSync(path);

/** If a component has replacements, you get it piped through the replacementStream
* Otherwise, you'll get the original readable stream
* Ignore binary files, they will get corrupted in the replacement process
*/
export const getReplacementStreamForReadable = (
component: SourceComponent,
path: SourcePath
): Readable | ReplacementStream =>
component.replacements?.[path]
component.replacements?.[path] && isTextFile(path)
? component.tree.stream(path).pipe(new ReplacementStream(component.replacements?.[path]))
: component.tree.stream(path);

Expand Down
2 changes: 1 addition & 1 deletion test/collections/componentSet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ describe('ComponentSet', () => {
{ members: ['replaceStuff'], name: 'ApexClass' },
{ members: ['TestObj__c.FieldA__c'], name: 'CustomField' },
{ members: ['TestObj__c'], name: 'CustomObject' },
{ members: ['Test'], name: 'StaticResource' },
{ members: ['ImageTest', 'Test'], name: 'StaticResource' },
],
version,
});
Expand Down
24 changes: 24 additions & 0 deletions test/nuts/local/replacements/replacements.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,29 @@ describe('e2e replacements test', () => {
}
}
});
it('skips images in static resources to prevent file corruption', async () => {
const srZipPath = path.join(session.project.dir, 'unzipped', 'staticresources', 'ImageTest.resource');
expect(fs.existsSync(srZipPath)).to.be.true;
const srZip = await JSZip.loadAsync(fs.readFileSync(srZipPath));

// static resource zip should have 2 files:
// 1. test-image.png, 2. test-image.resource-meta.xml
expect(Object.entries(srZip.files).length).to.equal(2);

const imageMeta = srZip.file('test-image.resource-meta.xml');
if (imageMeta && !imageMeta.dir) {
const content = await imageMeta.async('nodebuffer');
const imageMetaAsString = content.toString();
expect(imageMetaAsString).to.not.include('placeholder');
expect(imageMetaAsString).to.include('foo');
}

const image = srZip.file('test-image.png');
if (image && !image.dir) {
const content = await image.async('nodebuffer');
// The file size would be much larger if it was corrupted via the string replacement method
expect(content.byteLength).to.equal(1562121);
}
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
<cacheControl>Private</cacheControl>
<contentType>application/zip</contentType>
<description>added from sfdx plugin</description>
<fullName>ImageTest</fullName>
</StaticResource>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
<cacheControl>Private</cacheControl>
<contentType>image/png</contentType>
<description>Test placeholder</description>
</StaticResource>
5 changes: 5 additions & 0 deletions test/nuts/local/replacements/testProj/sfdx-project.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
"glob": "**/*.css",
"replaceWithEnv": "THE_REPLACEMENT",
"stringToReplace": "placeholder"
},
{
"glob": "force-app/main/default/staticresources/ImageTest/**/**",
"replaceWithEnv": "THE_REPLACEMENT",
"stringToReplace": "placeholder"
}
],
"sfdcLoginUrl": "https://login.salesforce.com",
Expand Down
36 changes: 8 additions & 28 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3233,6 +3233,11 @@ isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==

isbinaryfile@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.2.tgz#fe6e4dfe2e34e947ffa240c113444876ba393ae0"
integrity sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==

isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
Expand Down Expand Up @@ -5066,16 +5071,7 @@ srcset@^5.0.0:
resolved "https://registry.yarnpkg.com/srcset/-/srcset-5.0.0.tgz#9df6c3961b5b44a02532ce6ae4544832609e2e3f"
integrity sha512-SqEZaAEhe0A6ETEa9O1IhSPC7MdvehZtCnTR0AftXk3QhY2UNgb+NApFOUPZILXk/YTDfFxMTNJOBpzrJsEdIA==

"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand Down Expand Up @@ -5134,14 +5130,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -5631,7 +5620,7 @@ workerpool@^6.5.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544"
integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -5649,15 +5638,6 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down

2 comments on commit 8c68696

@svc-cli-bot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 8c68696 Previous: 63d4813 Ratio
eda-componentSetCreate-linux 237 ms 233 ms 1.02
eda-sourceToMdapi-linux 2295 ms 2355 ms 0.97
eda-sourceToZip-linux 1933 ms 1867 ms 1.04
eda-mdapiToSource-linux 2933 ms 2874 ms 1.02
lotsOfClasses-componentSetCreate-linux 435 ms 429 ms 1.01
lotsOfClasses-sourceToMdapi-linux 3836 ms 3658 ms 1.05
lotsOfClasses-sourceToZip-linux 3206 ms 3112 ms 1.03
lotsOfClasses-mdapiToSource-linux 3659 ms 3555 ms 1.03
lotsOfClassesOneDir-componentSetCreate-linux 748 ms 752 ms 0.99
lotsOfClassesOneDir-sourceToMdapi-linux 6529 ms 6447 ms 1.01
lotsOfClassesOneDir-sourceToZip-linux 5671 ms 5457 ms 1.04
lotsOfClassesOneDir-mdapiToSource-linux 6374 ms 6462 ms 0.99

This comment was automatically generated by workflow using github-action-benchmark.

@svc-cli-bot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 8c68696 Previous: 63d4813 Ratio
eda-componentSetCreate-win32 616 ms 613 ms 1.00
eda-sourceToMdapi-win32 4311 ms 4297 ms 1.00
eda-sourceToZip-win32 2974 ms 2842 ms 1.05
eda-mdapiToSource-win32 5719 ms 5641 ms 1.01
lotsOfClasses-componentSetCreate-win32 1246 ms 1191 ms 1.05
lotsOfClasses-sourceToMdapi-win32 7704 ms 7612 ms 1.01
lotsOfClasses-sourceToZip-win32 5029 ms 4930 ms 1.02
lotsOfClasses-mdapiToSource-win32 7763 ms 7738 ms 1.00
lotsOfClassesOneDir-componentSetCreate-win32 2109 ms 2084 ms 1.01
lotsOfClassesOneDir-sourceToMdapi-win32 13899 ms 13549 ms 1.03
lotsOfClassesOneDir-sourceToZip-win32 9369 ms 8934 ms 1.05
lotsOfClassesOneDir-mdapiToSource-win32 14075 ms 13899 ms 1.01

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.