Skip to content

Commit

Permalink
Merge pull request #247 from forcedotcom/develop
Browse files Browse the repository at this point in the history
chore: merge develop to master
  • Loading branch information
rvwatch authored Jul 1, 2020
2 parents eadeec4 + de63b67 commit e2252f0
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 59 deletions.
61 changes: 6 additions & 55 deletions examples/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -418,13 +418,6 @@ [email protected], diff@^3.1.0, diff@^3.2.0, diff@^3.5.0:
resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==

dtrace-provider@~0.6:
version "0.6.0"
resolved "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz#0b078d5517937d873101452d9146737557b75e51"
integrity sha1-CweNVReTfYcxAUUtkUZzdVe3XlE=
dependencies:
nan "^2.0.8"

ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
Expand Down Expand Up @@ -564,17 +557,6 @@ [email protected]:
once "^1.3.0"
path-is-absolute "^1.0.0"

glob@^6.0.1:
version "6.0.4"
resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=
dependencies:
inflight "^1.0.4"
inherits "2"
minimatch "2 || 3"
once "^1.3.0"
path-is-absolute "^1.0.0"

glob@^7.1.1:
version "7.1.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
Expand Down Expand Up @@ -877,7 +859,7 @@ mimic-fn@^1.0.0:
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==

"minimatch@2 || 3", [email protected], minimatch@^3.0.4:
[email protected], minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
Expand All @@ -894,7 +876,7 @@ minimist@^1.2.0:
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=

[email protected], mkdirp@^0.5.1, mkdirp@~0.5.1:
[email protected], mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
Expand All @@ -918,7 +900,7 @@ mocha@^5.2.0:
mkdirp "0.5.1"
supports-color "5.4.0"

[email protected], moment@^2.10.6:
[email protected]:
version "2.24.0"
resolved "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
Expand Down Expand Up @@ -951,25 +933,6 @@ [email protected]:
resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=

mv@~2:
version "2.1.1"
resolved "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2"
integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=
dependencies:
mkdirp "~0.5.1"
ncp "~2.0.0"
rimraf "~2.4.0"

nan@^2.0.8:
version "2.12.1"
resolved "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==

ncp@~2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=

nise@^1.2.0, nise@^1.4.5:
version "1.4.8"
resolved "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz#ce91c31e86cf9b2c4cac49d7fcd7f56779bfd6b0"
Expand Down Expand Up @@ -1125,13 +1088,6 @@ restore-cursor@^2.0.0:
onetime "^2.0.0"
signal-exit "^3.0.2"

rimraf@~2.4.0:
version "2.4.5"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da"
integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=
dependencies:
glob "^6.0.1"

run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
Expand All @@ -1151,11 +1107,6 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==

safe-json-stringify@~1:
version "1.2.0"
resolved "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd"
integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==

"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
Expand Down Expand Up @@ -1474,9 +1425,9 @@ websocket-driver@>=0.5.1:
websocket-extensions ">=0.1.1"

websocket-extensions@>=0.1.1:
version "0.1.3"
resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
version "0.1.4"
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==

wrappy@1:
version "1.0.2"
Expand Down
66 changes: 66 additions & 0 deletions src/util/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@

import { parseJson, parseJsonMap } from '@salesforce/kit';
import { AnyJson, JsonMap, Optional } from '@salesforce/ts-types';
import * as crypto from 'crypto';
import * as fsLib from 'fs';
import * as mkdirpLib from 'mkdirp';
import * as path from 'path';
import { promisify } from 'util';
import { SfdxError } from '../sfdxError';

type PerformFunction = (filePath: string, file?: string, dir?: string) => Promise<void>;

export const fs = {
/**
* The default file system mode to use when creating directories.
Expand Down Expand Up @@ -172,5 +175,68 @@ export const fs = {
} catch (err) {
return false;
}
},

/**
* Recursively act on all files or directories in a directory
*
* @param dir path to directory
* @param perform function to be run on contents of dir
* @param onType optional parameter to specify type to actOn
* @returns void
*/

actOn: async (dir: string, perform: PerformFunction, onType: 'file' | 'dir' = 'file'): Promise<void> => {
for (const file of await fs.readdir(dir)) {
const filePath = path.join(dir, file);
const stat = await fs.stat(filePath);

if (stat) {
if (stat.isDirectory()) {
await fs.actOn(filePath, perform, onType);
if (onType === 'dir') {
await perform(filePath);
}
} else if (stat.isFile() && onType === 'file') {
await perform(filePath, file, dir);
}
}
}
},

/**
* Checks if files are the same
*
* @param file1Path the first file path to check
* @param file2Path the second file path to check
* @returns boolean
*/
areFilesEqual: async (file1Path: string, file2Path: string): Promise<boolean> => {
try {
const file1Size = (await fs.stat(file1Path)).size;
const file2Size = (await fs.stat(file2Path)).size;
if (file1Size !== file2Size) {
return false;
}

const contentA = await fs.readFile(file1Path);
const contentB = await fs.readFile(file2Path);

return fs.getContentHash(contentA) === fs.getContentHash(contentB);
} catch (err) {
throw new SfdxError(`The path: ${err.path} doesn't exist or access is denied.`, 'DirMissingOrNoAccess');
}
},

/**
* Creates a hash for the string that's passed in
* @param contents The string passed into the function
* @returns string
*/
getContentHash(contents: string | Buffer) {
return crypto
.createHash('sha1')
.update(contents)
.digest('hex');
}
};
126 changes: 126 additions & 0 deletions test/unit/util/fsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,130 @@ describe('util/fs', () => {
expect(exists).to.be.false;
});
});

describe('areFilesEqual', () => {
afterEach(() => {
$$.SANDBOX.restore();
});

it('should return false if the files stat.size are different', async () => {
$$.SANDBOX.stub(fs, 'readFile')
.onCall(0)
.resolves({})
.onCall(1)
.resolves({});
$$.SANDBOX.stub(fs, 'stat')
.onCall(0)
.resolves({
size: 1
})
.onCall(1)
.resolves({
size: 2
});

const results = await fs.areFilesEqual('foo/bar.json', 'foo/bar2.json');
expect(results).to.be.false;
});

it('should return true if the file hashes are the same', async () => {
$$.SANDBOX.stub(fs, 'readFile')
.onCall(0)
.resolves(
`{
"key": 12345,
"value": true,
}`
)
.onCall(1)
.resolves(
`{
"key": 12345,
"value": true,
}`
);
$$.SANDBOX.stub(fs, 'stat')
.onCall(0)
.resolves({})
.onCall(1)
.resolves({});

const results = await fs.areFilesEqual('foo/bar.json', 'foo/bar2.json');
expect(results).to.be.true;
});

it('should return false if the file hashes are different', async () => {
$$.SANDBOX.stub(fs, 'readFile')
.onCall(0)
.resolves(
`{
"key": 12345,
"value": true,
}`
)
.onCall(1)
.resolves(
`{
"key": 12345,
"value": false,
}`
);

$$.SANDBOX.stub(fs, 'stat')
.onCall(0)
.resolves({})
.onCall(1)
.resolves({});
const results = await fs.areFilesEqual('foo/bar.json', 'foo/bsar2.json');
expect(results).to.be.false;
});

it('should return error when fs.readFile throws error', async () => {
$$.SANDBOX.stub(fs, 'stat')
.onCall(0)
.resolves({
size: 1
})
.onCall(1)
.resolves({
size: 2
});
try {
await fs.areFilesEqual('foo', 'bar');
} catch (e) {
expect(e.name).to.equal('DirMissingOrNoAccess');
}
});

it('should return error when fs.stat throws error', async () => {
try {
await fs.areFilesEqual('foo', 'bar');
} catch (e) {
expect(e.name).to.equal('DirMissingOrNoAccess');
}
});
});

describe('actOn', () => {
afterEach(() => {
$$.SANDBOX.restore();
});

it('should run custom functions against contents of a directory', async () => {
const actedOnArray = [];
$$.SANDBOX.stub(fs, 'readdir').resolves(['test1.json', 'test2.json']);
$$.SANDBOX.stub(fs, 'stat').resolves({
isDirectory: () => false,
isFile: () => true
});
const pathToFolder = pathJoin(osTmpdir(), 'foo');

await fs.actOn(pathToFolder, async file => {
actedOnArray.push(file), 'file';
});
const example = [pathJoin(pathToFolder, 'test1.json'), pathJoin(pathToFolder, 'test2.json')];

expect(actedOnArray).to.eql(example);
});
});
});
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@
typedoc-plugin-external-module-name "1.1.3"
xunit-file "^1"

"@salesforce/kit@^1.0.0":
"@salesforce/kit@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@salesforce/kit/-/kit-1.2.2.tgz#9efaee2f520fba4c87a1e138fb31579cc5de69bd"
integrity sha512-MQXUh8Ka8oB1SOPUF1kOynXQWcLeZ8YWOyqPtg6j8U9NxLlkTF2vfUfhZEm//jXjejDy7CEes5rEKRHm2df/OA==
Expand Down Expand Up @@ -7089,9 +7089,9 @@ websocket-driver@>=0.5.1:
websocket-extensions ">=0.1.1"

websocket-extensions@>=0.1.1:
version "0.1.3"
resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
version "0.1.4"
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==

which-module@^2.0.0:
version "2.0.0"
Expand Down

0 comments on commit e2252f0

Please sign in to comment.