forked from microsoft/react-native-code-push
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerateBundledResourcesHash.js
More file actions
92 lines (76 loc) · 3.86 KB
/
generateBundledResourcesHash.js
File metadata and controls
92 lines (76 loc) · 3.86 KB
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
/*
* This script generates a hash of all the React Native bundled assets and writes it into
* into the APK. The hash in "updateCheck" requests to prevent downloading an identical
* update to the one already present in the binary.
*
* It first creates a snapshot of the contents in the resource directory by creating
* a map with the modified time of all the files in the directory. It then compares this
* snapshot with the one saved earlier in "recordFilesBeforeBundleCommand.js" to figure
* out which files were generated by the "react-native bundle" command. It then computes
* the hash for each file to generate a manifest, and then computes a hash over the entire
* manifest to generate the final hash, which is saved to the APK's assets directory.
*/
var crypto = require("crypto");
var fs = require("fs");
var path = require("path");
var getFilesInFolder = require("./getFilesInFolder");
var CODE_PUSH_FOLDER_PREFIX = "CodePush";
var CODE_PUSH_HASH_FILE_NAME = "CodePushHash.json";
var HASH_ALGORITHM = "sha256";
var TEMP_FILE_PATH = path.join(require("os").tmpdir(), "CodePushResourcesMap.json");
var resourcesDir = process.argv[2];
var jsBundleFilePath = process.argv[3];
var assetsDir = process.argv[4];
var resourceFiles = [];
getFilesInFolder(resourcesDir, resourceFiles);
var oldFileToModifiedTimeMap = require(TEMP_FILE_PATH);
var newFileToModifiedTimeMap = {};
resourceFiles.forEach(function(resourceFile) {
newFileToModifiedTimeMap[resourceFile.path.substring(resourcesDir.length)] = resourceFile.mtime;
});
var bundleGeneratedAssetFiles = [];
for (var newFilePath in newFileToModifiedTimeMap) {
if (!oldFileToModifiedTimeMap[newFilePath] || oldFileToModifiedTimeMap[newFilePath] < newFileToModifiedTimeMap[newFilePath].getTime()) {
bundleGeneratedAssetFiles.push(newFilePath);
}
}
var manifest = [];
if (bundleGeneratedAssetFiles.length) {
bundleGeneratedAssetFiles.forEach(function(assetFile) {
// Generate hash for each asset file
var readStream = fs.createReadStream(resourcesDir + assetFile);
var hashStream = crypto.createHash(HASH_ALGORITHM);
readStream.pipe(hashStream)
.on("error", function(error) {
throw error;
})
.on("finish", function() {
hashStream.end();
var buffer = hashStream.read();
var fileHash = buffer.toString("hex");
manifest.push(CODE_PUSH_FOLDER_PREFIX + assetFile.replace(/\\/g, "/") + ":" + fileHash);
if (manifest.length === bundleGeneratedAssetFiles.length) {
// Generate hash for JS bundle
readStream = fs.createReadStream(jsBundleFilePath);
hashStream = crypto.createHash(HASH_ALGORITHM);
readStream.pipe(hashStream)
.on("error", function(error) {
throw error;
})
.on("finish", function() {
hashStream.end();
var buffer = hashStream.read();
var fileHash = buffer.toString("hex");
manifest.push(CODE_PUSH_FOLDER_PREFIX + "/" + path.basename(jsBundleFilePath) + ":" + fileHash);
manifest = manifest.sort();
var finalHash = crypto.createHash(HASH_ALGORITHM)
.update(JSON.stringify(manifest))
.digest("hex");
var savedResourcesManifestPath = assetsDir + "/" + CODE_PUSH_HASH_FILE_NAME;
fs.writeFileSync(savedResourcesManifestPath, finalHash);
});
}
});
});
}
fs.unlinkSync(TEMP_FILE_PATH);