Search code examples
gulp

Gulp update contents of file with hash of another file


I am struggling with this gulp task. I have a file that I need to modify post build which is a file that is part of a PWA package using Angular Service Worker. As a result of the modification I need to recalculate the hash and update the entry in the ngsw.json file whose contents look like this.

 "hashTable": {
    "/1.a634d7bd57cc0b60b07a.js": "f67c68837f048be737dcb1359072fc40c1f93144",
    "/10.b18571adf198206cc401.js": "c59d8f124964b73456f22ed3a51efec0493ce7c5",
    "/100.625f7b4770945172db3e.js": "da62af393973a8eb002874406e8a1dd828faecaf",
    "/main.5be263c044e031156b6b.js": "5bfa4ec8a86ee2ab4a5f2f999b0742ac4a5ddbc7"
}

I know the filename of the file that needs the hash updating and I have this function

let hashsum = require("gulp-hashsum");
function getHash() {
    gulp.src(["www/main*.js"]).pipe(hashsum({
            stream: true,
            json: true
        }
    )).pipe(gulp.dest( 
      // How to replace ngsw.json 'hashTable' entry with this response? )); 
    }

I am not very familiar with gulp and any help would be appreciated.


Solution

  • You can write a plugin that'll take the result from hashsum and simply use fs to modify your json.

    Here's a naive implementation:

    const fs = require('fs')
    const path = require('path')
    const through = require('through2')
    const hashsum = require('gulp-hashsum')
    
    const modifyJson = ({ fileName, src, property }) => through.obj((file, _, cb) => {
      const { name } = path.parse(file.path)
      if (name !== fileName) return cb(null, file)
    
      const pathToJson = path.resolve(__dirname, src)
      if (!fs.existsSync(pathToJson)) {
        return cb(new Error(`${src} doesn't exist.`), file)
      }
      const json = JSON.parse(fs.readFileSync(pathToJson, 'utf8'))
    
      const content = JSON.parse(file.contents)
      if (typeof json[property] === 'undefined') console.warn(`${src} doesn't has any property named '${property}' A new one will be created.`)
      json[property] = content
       fs.writeFileSync(pathToJson, JSON.stringify(json))
    
      return cb(null, file)
    })
    

    Usage:

    exports.modifyJson = () =>
      src(['app/**/*.js'])
      .pipe(hashsum({
        stream: true,
        json: true,
      }))
      .pipe(modifyJson({
        fileName: 'SHA1SUMS',
        src: './test.json',
        property: 'hashTable',
      }))
    

    I have this code up on a gist here.