diff --git a/README.md b/README.md index 79e6d4a..352c164 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,38 @@ If you are using DigitalOcean spaces you need to set this setting to `false`. *Default:* `true` +### fetchInitialRevisionsFunc + +The function that is called when `fetchInitialRevisions` is called on this plugin (e.g. when a user runs `ember deploy`). + +The main purpose of this function is to gather the "before" state of your s3 buckets so that you can produce a useful change or +audit log. + +The default implementation of this will loop over all revisions found in S3. This can be slow if you have a long history of +deployments. You may find that in your usages that you don't need to gather this information in this way so you may want to +overwrite it to just return an empty array e.g. + +```js +fetchInitialRevisionsFunc(/* context */) { + return () => ({ initialRevisions: [] }); +} +```` + +### fetchRevisionsFunc + +The function that is called when `fetchRevisions` is called on this plugin (e.g. when a user runs `ember deploy:list`). + + +The default implementation of this will loop over all revisions found in S3. This can be slow if you have a long history of +deployments. You may find that in your usages there are times that it's not ncessary to load this data so you may want to +overwrite it to just return an empty array e.g. + +```js +fetchRevisionsFunc(/* context */) { + return () => ({ revisions: [] }); +}, +```` + ### How do I activate a revision? A user can activate a revision by either: diff --git a/index.js b/index.js index bb1edaa..176b508 100644 --- a/index.js +++ b/index.js @@ -34,6 +34,26 @@ module.exports = { brotliCompressedFiles: function(context) { return context.brotliCompressedFiles || []; }, + fetchRevisionsFunc: function(context) { + return function() { + return this._list(context) + .then(function(revisions) { + return { + revisions: revisions + }; + }); + } + }, + fetchInitialRevisionsFunc: function(context) { + return function() { + return this._list(context) + .then(function(revisions) { + return { + initialRevisions: revisions + }; + }); + } + }, allowOverwrite: false }, @@ -106,22 +126,12 @@ module.exports = { return s3.activate(options); }, - fetchRevisions: function(context) { - return this._list(context) - .then(function(revisions) { - return { - revisions: revisions - }; - }); + fetchRevisions: function(/* context */) { + return this.readConfig('fetchRevisionsFunc').call(this); }, - fetchInitialRevisions: function(context) { - return this._list(context) - .then(function(revisions) { - return { - initialRevisions: revisions - }; - }); + fetchInitialRevisions: function(/* context */) { + return this.readConfig('fetchInitialRevisionsFunc').call(this); }, _list: function(/* context */) { diff --git a/lib/s3.js b/lib/s3.js index c821371..2e6d180 100644 --- a/lib/s3.js +++ b/lib/s3.js @@ -62,6 +62,7 @@ module.exports = CoreObject.extend({ var isGzipped = gzippedFilePaths.indexOf(options.filePattern) !== -1; var isBrotliCompressed = brotliCompressedFilePaths.indexOf(options.filePattern) !== -1; var serverSideEncryption = options.serverSideEncryption; + var checkForOverwrite = RSVP.resolve(); var params = { Bucket: bucket, @@ -83,13 +84,17 @@ module.exports = CoreObject.extend({ params.ContentEncoding = 'br'; } - return this.findRevision(options) - .then(function(found) { - if (found !== undefined && !allowOverwrite) { - return RSVP.reject("REVISION ALREADY UPLOADED! (set `allowOverwrite: true` if you want to support overwriting revisions)"); - } - return RSVP.resolve(); - }) + if (!allowOverwrite) { + checkForOverwrite = this.findRevision(options) + .then(function(found) { + if (found !== undefined) { + return RSVP.reject("REVISION ALREADY UPLOADED! (set `allowOverwrite: true` if you want to support overwriting revisions)"); + } + return RSVP.resolve(); + }) + } + + return checkForOverwrite .then(readFile.bind(this, options.filePath)) .then(function(fileContents) { params.Body = fileContents; @@ -174,7 +179,7 @@ module.exports = CoreObject.extend({ }); }, - listAllObjects: function(options) { + listAllObjects: function(options, until) { var client = this._client; var listObjects = RSVP.denodeify(client.listObjects.bind(client)); var allRevisions = []; @@ -183,13 +188,14 @@ module.exports = CoreObject.extend({ return listObjects(options).then(function(response) { [].push.apply(allRevisions, response.Contents); - if (response.IsTruncated) { - var nextMarker = response.Contents[response.Contents.length - 1].Key; - options.Marker = nextMarker; - return listObjectRecursively(options); - } else { + var isComplete = !response.IsTruncated || (until && response.Contents.some(until)); + + if (isComplete) { return allRevisions; } + var nextMarker = response.Contents[response.Contents.length - 1].Key; + options.Marker = nextMarker; + return listObjectRecursively(options); }); }