Skip to content

Commit

Permalink
Merge pull request #70 from onmodulus/enhancement/download-source
Browse files Browse the repository at this point in the history
Download project source from CLI
  • Loading branch information
theworkflow committed Apr 19, 2016
2 parents dd015e1 + 31b7b99 commit e38f4a9
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 1 deletion.
43 changes: 42 additions & 1 deletion lib/commands/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,6 @@ project.scale = function (instances, projectName, cb) {

//--------------------------------------------------------------------
project.runApp = function(projectName, nodeEnv, cb) {
console.log(arguments);
async.waterfall([
function getUserProjects (fn) {
projectController.find({ userId: userConfig.data.userId }, function (err, projects) {
Expand Down Expand Up @@ -1040,6 +1039,48 @@ project.getMainFile = function(cb) {
}
};

//-----------------------------------------------------------------------------
/**
* Description - Downloads the source code for a specific project.
* @param {string} projectName - name of the project to retrieve logs from.
* @param {string} output - filename to download the tarball at
* @param {function} cb Callback invoked with log data.
*/
// -----------------------------------------------------------------------------
project.download = function (projectName, output, cb) {
projectController.find({
userId: userConfig.data.userId
},
function (err, projects) {
if (err) {
err = error.handleApiError(err, 'GET_PROJECT_SOURCE', cb);
if (err.length > 0) return cb(err);
}

if (projects.length === 0) {
modulus.io.error('You currently have no projects. You can create one with "project create".');
return cb();
}

project.chooseProjectPrompt(projects, projectName, function (err, result) {
if (err) return cb(err);
if (!result) return cb('You must select a project.');
if (result.status === 'NONE') return cb('You must deploy to your project in order to download the source.');

projectController.download(result.id, result.name, output, function (err, res) {
if (err) {
modulus.io.error('Problem downloading source.');
return cb();
}

modulus.io.success(res.msg);
cb();
});
});
}
);
};

//-------------------------------------------------------------------------------------------------
project._createProjectPrompt = function (cb) {
modulus.io.prompt.get([{
Expand Down
46 changes: 46 additions & 0 deletions lib/controllers/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,52 @@ Project.prototype.scale = function (projectId, instances, await, callback) {
});
};

// -----------------------------------------------------------------------------
/**
* Downloads the source code as a tarball for the specified project id.
* @param {string} projectId - the ID of the project.
* @param {string} projectName - the name of the project
* @param {string} outLocation - the path to the directory where the tarball should be downloaded
* @param {function} callback - function invoked with the file stream. Responsible for the actual download.
*/
// -----------------------------------------------------------------------------
Project.prototype.download = function (projectId, projectName, outLocation, callback) {
librarian.project.download(projectId, userConfig.data.apiKey, function (err, req, res) {
var message, date, outFile, dir, stream, result = {};

if (err) return callback(Errors.getMessage(err));

date = new Date().toISOString().replace(/:/g, '.');
outFile = projectName + '_' + date + '.zip';

if (typeof outLocation === 'string') {
outFile = outLocation;
outFile = outFile.replace(/\//g, '/');
if (outFile.substring(outFile.length-4) !== '.zip') outFile += '.zip';

message = 'Directory ' + path.dirname(outLocation) + ' does not exist.';
if (!fs.existsSync(path.dirname(outLocation))) return callback(message);
}

if (path.dirname(outLocation) === '.') dir = process.cwd();
else dir = path.dirname(path.resolve(outLocation));

outFile = outFile.replace(/ /g, '_').replace(/:/g,'.').replace(/[[\]{}@~`<>()*+=%&!?,\\^$|#\s]/g,'');

stream = fs.createWriteStream(outFile);

res.pipe(stream).on('finish', function (err, stdout, stderr) {
if (err) return callback(Errors.getMessage(err));
if (stderr) result.stderr = stderr;
if (stdout) result.stdout = stdout;

result.msg = path.basename(outFile) + ' downloaded to ' + dir + '.';
result.outFile = outFile;
callback(null, result);
});
});
};

//-----------------------------------------------------------------------------
/**
* Archives a project's files.
Expand Down
8 changes: 8 additions & 0 deletions lib/librarian/librarian.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,14 @@ librarian.project.scale = function(projectId, instances, authToken, callback) {
}
};

//-----------------------------------------------------------------------------
librarian.project.download = function (projectId, authToken, callback) {
var route = '/project/%s/download?authToken=%s';
if (checkInit(callback)) {
librarian._http.raw(util.format(route, projectId, authToken), 'GET', callback);
}
};

//-----------------------------------------------------------------------------
// ADDONS
//-----------------------------------------------------------------------------
Expand Down
23 changes: 23 additions & 0 deletions lib/routes/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,29 @@ module.exports = function (modulus) {
modulus.runCommand(modulus.commands.project.runApp, [modulus.program.projectName, modulus.program.nodeEnv], true);
});

help.add('download', function () {
this.line('project download'.verbose);
this.line('Gets source for the selected project.'.input);
this.line(' options:'.input);
this.line(' -p, --project-name Name of the project to retrieve logs from. Prompts are skipped when specified.'.input);
this.line(' -o, --output Specifies the file to download to. Must be file type zip'.input);
this.line('');
});

modulus.program
.command('project download')
.description('Gets source for the selected project.')
.on('--help', function () {
help.commands.download();
})
.action(function () {
modulus.runCommand(
modulus.commands.project.download,
[modulus.program.projectName, modulus.program.output],
true
);
});

// Generic help for project commands
modulus.program
.command('project')
Expand Down

0 comments on commit e38f4a9

Please sign in to comment.