Advertisement
Guest User

Untitled

a guest
Sep 20th, 2017
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.28 KB | None | 0 0
  1. /*
  2.  
  3. Usage looks like this:
  4.  
  5. ```
  6. $ node auto-patch.js get \
  7. --original node_modules/epub.js/build/epub.js \
  8. --changed epubjs.changed > patches/epubjs.patch
  9. $ node auto-patch.js apply patches/epubjs.patch
  10. ```
  11.  
  12. The patch knows the hash of the resulting file, so, before applying,
  13. it checks if the hashes are different. If they are the same,
  14. it silently skips patching, so the second command above can be rerun
  15. multiple times without corrupting the file.
  16.  
  17. Example automatic patching with npm:
  18. {
  19. ...,
  20. "scripts": {
  21. "patch-epubjs": "node auto-patch.js apply patches/epubjs.patch",
  22. "prepare": "npm run patch-epubjs",
  23. ...
  24. }
  25. }
  26.  
  27. Requires: "node": ">=8.5.0"
  28.  
  29. */
  30.  
  31. const Crypto = require('crypto')
  32. const DiffMatchPatch = new (require('diff-match-patch'))
  33. const Fs = require('fs')
  34.  
  35. const debug = require('debug')('auto-patch')
  36.  
  37. const getHash = (s) =>
  38. {
  39. const hash = Crypto.createHash('sha256')
  40. hash.update(s)
  41. return hash.digest('hex')
  42. }
  43.  
  44. const getPatch = (originalString, changedString) =>
  45. {
  46. const patches = DiffMatchPatch.patch_make(originalString, changedString)
  47. return DiffMatchPatch.patch_toText(patches)
  48. }
  49.  
  50. const applyPatch = (string, patch) =>
  51. {
  52. const patches = DiffMatchPatch.patch_fromText(patch)
  53. return DiffMatchPatch.patch_apply(patches, string)[0]
  54. }
  55.  
  56. const getStringContents = (path) => String(Fs.readFileSync(path))
  57.  
  58. const getAutoPatch = (originalFile, changedFile, optPath = undefined) =>
  59. {
  60.  
  61. const originalString = getStringContents(originalFile)
  62. const changedString = getStringContents(changedFile)
  63.  
  64. const path = optPath || originalFile
  65. const hash = getHash(changedString)
  66. const patch = getPatch(originalString, changedString)
  67.  
  68. const json =
  69. {
  70. path,
  71. hash,
  72. patch
  73. }
  74.  
  75. return json
  76.  
  77. }
  78.  
  79. const overwriteFile = (path, stringContents) =>
  80. Fs.writeFileSync(path, stringContents)
  81.  
  82. const backupOriginal = (path) => Fs.copyFileSync(path, path + '.unpatched')
  83.  
  84. const applyAutoPatch = (autoPatch) =>
  85. {
  86.  
  87. const path = autoPatch.path
  88. const currentString = getStringContents(path)
  89. const currentHash = getHash(currentString)
  90.  
  91. if (currentHash == autoPatch.hash) {
  92. debug(`${path} is already patched. Skipping.`)
  93. return
  94. }
  95.  
  96. const patchedString = applyPatch(currentString, autoPatch.patch)
  97.  
  98. if (autoPatch.hash != getHash(patchedString)) {
  99. console.error(
  100. `Patch for ${path} is corrupted,` +
  101. ` specified hash does not match the resulting hash.`
  102. )
  103. return
  104. }
  105.  
  106. debug(`Backing up and patching ${path}.`)
  107.  
  108. backupOriginal(path)
  109.  
  110. overwriteFile(path, patchedString)
  111.  
  112. }
  113.  
  114. const argv = require('minimist')(process.argv.slice(2));
  115.  
  116. switch (true) {
  117. case argv._[0] == 'get':
  118. // usage:
  119. // `node auto-patch.js get --original original.js --changed changed.js`
  120. // optionally, --path, that the resulting patch will patch,
  121. // can be specified separately. otherwise will be same as --original.
  122. {
  123. const patch = getAutoPatch(argv.original, argv.changed, argv.path)
  124. const json = JSON.stringify(patch)
  125. process.stdout.write(json)
  126. }
  127. break
  128. case argv._[0] == 'apply':
  129. // usage: node auto-patch.js apply path/to/the.patch
  130. {
  131. const json = getStringContents(argv._[1])
  132. const patch = JSON.parse(json)
  133. applyAutoPatch(patch)
  134. }
  135. break
  136. default:
  137. console.error('Wrong arguments.')
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement