code: func HashFilesInDir(rootDir string, dir string, hash []byte, tw *tar.Writer) ([]byte, error) {
  	currentDir := filepath.Join(rootDir, dir)
  	logger.Debugf("hashFiles %s", currentDir)
  	//ReadDir returns sorted list of files in dir
  	fis, err := ioutil.ReadDir(currentDir)
  	if err != nil {
  		return hash, fmt.Errorf("ReadDir failed %s\n", err)
  	}
  	for _, fi := range fis {
  		name := filepath.Join(dir, fi.Name())
  		if fi.IsDir() {
  			var err error
  			hash, err = HashFilesInDir(rootDir, name, hash, tw)
  			if err != nil {
  				return hash, err
  			}
  			continue
  		}
  		fqp := filepath.Join(rootDir, name)
  		buf, err := ioutil.ReadFile(fqp)
  		if err != nil {
  			logger.Errorf("Error reading %s\n", err)
  			return hash, err
  		}
  
  		//get the new hash from file contents
  		hash = ComputeHash(buf, hash)
  
  		if tw != nil {
  			is := bytes.NewReader(buf)
  			if err = cutil.WriteStreamToPackage(is, fqp, filepath.Join("src", name), tw); err != nil {
  				return hash, fmt.Errorf("Error adding file to tar %s", err)
  			}
  		}
  	}
  	return hash, nil
  }
docs: //HashFilesInDir computes h=hash(h,file bytes) for each file in a directory
  //Directory entries are traversed recursively. In the end a single
  //hash value is returned for the entire directory structure