-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathutils.js
107 lines (90 loc) · 3.15 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const walk = require('walk');
const MAX_FILE_SIZE_BYTES = 26214400; // 25MB.
module.exports = {
sha256hash(content) {
return crypto
.createHash('sha256')
.update(content, 'utf8')
.digest('hex');
},
base64encode(content) {
return Buffer.from(content).toString('base64');
},
getMissingResources(response) {
return (
(response &&
response.body &&
response.body.data &&
response.body.data.relationships &&
response.body.data.relationships['missing-resources'] &&
response.body.data.relationships['missing-resources'].data) ||
[]
);
},
// Synchronously walk a directory of compiled assets, read each file and calculate its SHA 256
// hash, and create an array of Resource objects.
gatherBuildResources(percyClient, rootDir, options = {}) {
// The base of the URL that will be prepended to every resource URL, such as "/assets".
options.baseUrlPath = options.baseUrlPath || '';
options.skippedPathRegexes = options.skippedPathRegexes || [];
options.followLinks = options.followLinks || true;
let resources = [];
let fileWalker = function(root, fileStats, next) {
let absolutePath = path.join(root, fileStats.name);
let resourceUrl = absolutePath.replace(rootDir, '');
if (path.sep == '\\') {
// Windows support: transform filesystem backslashes into forward-slashes for the URL.
resourceUrl = resourceUrl.replace(/\\/g, '/');
}
// Prepend the baseUrlPath if it is given. We normalize it to make sure it does not have
// a trailing slash, or it's a blank string.
let normalizedBaseUrlPath = (options.baseUrlPath || '/').replace(/\/$/, '');
resourceUrl = normalizedBaseUrlPath + resourceUrl;
// Skip excluded paths.
for (let i in options.skippedPathRegexes) {
if (resourceUrl.match(options.skippedPathRegexes[i])) {
next();
return;
}
}
// Skip large files.
if (fs.statSync(absolutePath)['size'] > MAX_FILE_SIZE_BYTES) {
// eslint-disable-next-line no-console
console.warn('\n[percy][WARNING] Skipping large build resource: ', resourceUrl);
return;
}
// Note: this is synchronous and potentially memory intensive, but we don't keep a
// reference to the content around so each should be garbage collected. Reevaluate?
let content = fs.readFileSync(absolutePath);
let sha = crypto
.createHash('sha256')
.update(content)
.digest('hex');
let resource = percyClient.makeResource({
resourceUrl: encodeURI(resourceUrl),
sha: sha,
localPath: absolutePath,
});
resources.push(resource);
next();
};
let walkOptions = {
// Follow symlinks because assets may be just symlinks.
followLinks: options.followLinks,
listeners: {
file: fileWalker,
},
};
walk.walkSync(rootDir, walkOptions);
return resources;
},
reverseString(str) {
return str
.split('')
.reverse()
.join('');
},
};