Skip to content

Commit

Permalink
fixes #8 and fixes #10
Browse files Browse the repository at this point in the history
  • Loading branch information
kbremner committed Sep 14, 2014
1 parent 77eb4a5 commit 2cbafe5
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 81 deletions.
3 changes: 2 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ module.exports = function(grunt) {
dev: {
options: {
access_token: process.env.dropbox_access_token,
version_name: process.env.TRAVIS_BUILD_NUMBER
version_name: process.env.TRAVIS_BUILD_NUMBER,
verbose: false
},
files: {
'grunt-dropbox': ['dist/**/*.*']
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ Required: `True`

A string value that is used to authenticate with Dropbox. Note that as this task is meant to be unattended, it is assummed that an access token has already been obtained. See [this wiki page](https://github.com/kbremner/grunt-dropbox/wiki/Creating-a-Dropbox-Access-Token) for more details.

#### options.verbose
Type: `Boolean`
Required: `False`

An optional boolean value that is used to determine if additional information should be logged when the task is executed. It is not recommended to enable this option for CI builds as it will log sensitive information, such as the name of the holder of the dropbox account which the access token is associated with.

### Usage Examples

Define a `dev` task that will upload the `dist` directory to `uploads/sample-project/` in the dropbox account associated with the provided token:
Expand Down Expand Up @@ -75,9 +81,12 @@ grunt.initConfig({
Please feel free to raise issues and submit pull requests. I'll try and reply to issues as quickly as possible.

## Release History
* 0.1.3
* Added verbose option, only logs account holder name when this option is set to true (fixes #8)
* Fixed the check for a destination so that "" can be specified, allowing upload to the root of the Dropbox account (fixes #10)
* 0.1.2
* Made version_name optional
* Removed default value for access_token
* Made version\_name optional
* Removed default value for access\_token
* Updated documentation
* 0.1.1
* moved to using promises, other code cleanup
Expand Down
31 changes: 15 additions & 16 deletions lib/dropbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
* Licensed under the MIT license.
*/

'use strict';
module.exports = function () {
'use strict';
var Promise = require('bluebird'),
request = Promise.promisify(require('request')),
accountInfoUrl = "https://api.dropbox.com/1/account/info",
uploadUrl = "https://api-content.dropbox.com/1/files_put/auto/";

module.exports = function() {
var Promise = require('bluebird');
var request = Promise.promisify(require('request'));
var accountInfoUrl = "https://api.dropbox.com/1/account/info";
var uploadUrl = "https://api-content.dropbox.com/1/files_put/auto/";

this.getAccountInfo = function(options) {
function parseBody(resp) {
return JSON.parse(resp[1]);
}

this.getAccountInfo = function (options) {
var reqOptions = {
method: "GET",
url: accountInfoUrl,
Expand All @@ -24,9 +27,9 @@ module.exports = function() {
};

return request(reqOptions).then(parseBody);
}
};

this.upload = function(options) {
this.upload = function (options) {
var reqOptions = {
method: "PUT",
body: options.fileBuffer,
Expand All @@ -37,9 +40,5 @@ module.exports = function() {
};

return request(reqOptions).then(parseBody);
}

function parseBody(resp) {
return JSON.parse(resp[1]);
}
}
};
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "grunt-dropbox",
"description": "Grunt plugin to sync build artifacts to dropbox",
"version": "0.1.2",
"version": "0.1.3",
"homepage": "https://github.com/kbremner/grunt-dropbox",
"author": {
"name": "Kyle Bremner",
Expand Down
134 changes: 73 additions & 61 deletions tasks/dropbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,64 +6,10 @@
* Licensed under the MIT license.
*/

'use strict';

module.exports = function(grunt) {
var Dropbox = require('../lib/dropbox');
var dropboxClient = new Dropbox();

// Please see the Grunt documentation for more information regarding task
// creation: http://gruntjs.com/creating-tasks
grunt.registerMultiTask('dropbox', 'Grunt plugin to sync build artifacts to dropbox', function() {
var task = this;
var done = this.async();

// Merge task-specific and/or target-specific options with these defaults.
var options = this.options();

verifyOptions(options);

// get the name of the account holder for debugging
var promise = dropboxClient.getAccountInfo(options).then(function(resp) {
grunt.log.writeln("Uploading to dropbox account for " + resp.display_name + "...");
});

// loop through all the file objects
task.files.forEach(function(f) {
// ensure that a destination has been specified
if(!f.dest) {
grunt.fail.fatal("a destination must be specified for all files");
}

// loop through all the src files, uploading them
f.src.filter(isFile).map(function(filepath) {
// set the root promise to a continuation
promise = promise.then(function() {
// get the name of the file and construct the url for uploading it
var filename = getFilename(filepath);
var dropboxPath = f.dest + (options.version_name ? ("/" + options.version_name + "/") : "/") + filepath;

grunt.log.writeln("Uploading " + filepath + " to " + dropboxPath + "...");

// read the file and start the upload, decrementing the in-flight count when complete
// Use encoding = null to keep the file as a Buffer
var reqOptions = {
access_token: options.access_token,
dropboxPath: dropboxPath,
fileBuffer: grunt.file.read(filepath, { encoding : null })
};

// return the upload promise
return dropboxClient.upload(reqOptions);
});
});
});

// well all the continuations are done, finish this async task
promise.then(function() {
done();
});
});
module.exports = function (grunt) {
'use strict';
var Dropbox = require('../lib/dropbox'),
dropboxClient = new Dropbox();

function getFilename(filepath) {
var splitPath = filepath.split("/");
Expand All @@ -74,18 +20,84 @@ module.exports = function(grunt) {
if (!grunt.file.exists(filepath)) {
grunt.log.warn('Source file "' + filepath + '" not found.');
return false;
} else if(grunt.file.isDir(filepath)) {
} else if (grunt.file.isDir(filepath)) {
grunt.log.warn('"' + filepath + '" is a directory. Please ensure that the file pattern does not include directories.');
return false;
}
return true;
}

function hasDestination(file) {
if(file.dest === undefined) {
grunt.fail.fatal("a destination must be specified for all files");
}
return true;
}

function verifyOptions(options) {
['access_token'].forEach(function(option) {
if(!options[option]) {
['access_token'].forEach(function (option) {
if (!options[option]) {
grunt.fail.fatal(option + ' option must be specified');
}
});
}

// returns a function that creates a promise to upload the file to the destination
function createUploadPromise(filepath, destination, options) {
return function () {
// get the name of the file and construct the url for uploading it
var filename = getFilename(filepath),
dropboxPath = destination + (options.version_name ? ("/" + options.version_name + "/") : "/") + filepath,
// read the file and start the upload, decrementing the in-flight count when complete
// Use encoding = null to keep the file as a Buffer
reqOptions = {
access_token: options.access_token,
dropboxPath: dropboxPath,
fileBuffer: grunt.file.read(filepath, { encoding : null })
};

grunt.log.writeln("Uploading " + filepath + " to " + dropboxPath + "...");

// return the upload promise
return dropboxClient.upload(reqOptions);
};
}

// create the task
grunt.registerMultiTask('dropbox', 'Grunt plugin to sync build artifacts to dropbox', function () {
var task = this,
promise,
done = this.async(),
options = this.options({ verbose: false });

verifyOptions(options);

// get the name of the account holder for debugging
if(options.verbose === true) {
promise = dropboxClient.getAccountInfo(options).then(function (resp) {
grunt.log.writeln("Uploading to dropbox account for " + resp.display_name + "...");
});
}

// loop through all the file objects
task.files.filter(hasDestination).forEach(function (f) {
// loop through all the src files, uploading them
f.src.filter(isFile).map(function (filepath) {
// create the function that creates the upload promise
var uploadPromise = createUploadPromise(filepath, f.dest, options);
if(promise === undefined) {
// start the promise
promise = uploadPromise();
} else {
// set the promise to start when the current one finishes
promise = promise.then(uploadPromise);
}
});
});

// well all the continuations are done, finish this async task
promise.then(function () {
done();
});
});
};

0 comments on commit 2cbafe5

Please sign in to comment.