diff --git a/bagit/bagger.js b/bagit/bagger.js index 69c39911e..68fd11978 100644 --- a/bagit/bagger.js +++ b/bagit/bagger.js @@ -198,6 +198,7 @@ class Bagger extends EventEmitter { // Wait until entire directory is added before // attaching finish listener, else queue will // drain more than once. + this.formatWriter.directories[relDestPath] = stats; await this._addDirectory(absPath, relDestPath, stats); } } @@ -285,6 +286,8 @@ class Bagger extends EventEmitter { let relDestPath = bagger._getRelDestPath(fullPath); if (entry.fileStat.isFile()) { bagger._addFile(fullPath, relDestPath, entry.fileStat); + } else if (entry.fileStat.isDirectory()) { + bagger.formatWriter.directories[relDestPath] = entry.fileStat; } }); fsReader.on('error', function(err) { diff --git a/bagit/bagger.test.js b/bagit/bagger.test.js index d38886e2d..d15619c3d 100644 --- a/bagit/bagger.test.js +++ b/bagit/bagger.test.js @@ -61,6 +61,10 @@ test('create() with one dir', done => { console.log(result.errors) } + // DEBUG + // console.log(bagger.formatWriter.directories) + // DEBUG + expect(result.errors.length).toEqual(0); expect(result.succeeded()).toEqual(true); expect(result.started).not.toBeNull(); diff --git a/plugins/formats/write/base_writer.js b/plugins/formats/write/base_writer.js index 8bc6a301a..1364e4541 100644 --- a/plugins/formats/write/base_writer.js +++ b/plugins/formats/write/base_writer.js @@ -106,6 +106,16 @@ class BaseWriter extends Plugin { * @type {number} */ this.filesWritten = 0; + + /** + * This is a map of directory stats. Key is relDestPath, + * value is fs.Stats object. For example, key will be + * "/data/subdir". Value will be the stats of the original + * directory being bagged. This allows us to preserve directory + * attributes such as uid, gid, mode, and mtime when creating + * tar files. + */ + this.directories = {}; } /** diff --git a/plugins/formats/write/tar_writer.js b/plugins/formats/write/tar_writer.js index e7e903797..c692f10b3 100644 --- a/plugins/formats/write/tar_writer.js +++ b/plugins/formats/write/tar_writer.js @@ -104,10 +104,21 @@ class TarWriter extends BaseWriter { let dir = ''; for (let i=0; i < parts.length -1; i++) { dir = dir + parts[i] + '/'; + // We cached the stats for the directory in the + // directories map. The key is relDestPath, minus + // the bag name, with no traling slash. E.g. key for + // "MyBag/data/subdir/" is "/data/subdir". + var key = "" + if (i > 0) { + key = dir.split("/").slice(1).join("/").replace(/\/$/, "") + } if (!this._directoriesAdded.has(dir)) { - let data = Object.assign({}, template); + var data = this.directories[key] + if (!data) { + data = Object.assign({}, template); + data.mtime = new Date(); + } data.relDestPath = dir; - data.mtime = new Date(); this._mkdir(data); } }