});
}
-function put(filePath, otherFilePaths, options) {
- checkConfig(options);
-
- var destination = '';
-
- // take the last argument as destination
- if (otherFilePaths.length > 0) {
- destination = otherFilePaths.pop();
- if (otherFilePaths.length > 0 && destination[destination.length-1] !== '/') destination += '/';
+function putOne(filePath, destination, options, callback) {
+ const absoluteFilePath = path.resolve(filePath);
+ const stat = safe.fs.statSync(absoluteFilePath);
+ if (!stat) return callback(`Could not stat ${filePath}: ${safe.error.message}`);
+
+ let files, base;
+
+ if (stat.isFile()) {
+ base = destination + path.basename(filePath);
+ files = [ absoluteFilePath ];
+ } else if (stat.isDirectory()) {
+ base = destination + (filePath.endsWith('.') ? '' : path.basename(filePath) + '/');
+ files = collectFiles([ absoluteFilePath ], options);
+ } else {
+ return callback(); // ignore
}
- var files = collectFiles([ filePath ].concat(otherFilePaths), options);
-
async.eachSeries(files, function (file, callback) {
- var relativeFilePath;
-
- if (path.isAbsolute(file)) {
- relativeFilePath = path.basename(file);
- } else if (path.resolve(file).indexOf(process.cwd()) === 0) { // relative to current dir
- relativeFilePath = path.resolve(file).slice(process.cwd().length + 1);
- } else { // relative but somewhere else
- relativeFilePath = path.basename(file);
- }
-
- var destinationPath = (destination ? '/' + destination : '') + '/' + relativeFilePath;
- console.log('Uploading file %s -> %s', relativeFilePath.cyan, destinationPath.cyan);
+ let relativeFilePath = file.slice(absoluteFilePath.length + 1); // will be '' when filePath is a file
+ let destinationPath = base + relativeFilePath;
+ console.log('Uploading file %s -> %s', file.cyan, destinationPath.cyan);
superagent.post(gServer + API + destinationPath).query(gQuery).attach('file', file).end(function (error, result) {
if (result && result.statusCode === 403) return callback(new Error('Upload destination ' + destinationPath + ' not allowed'));
callback(null);
});
- }, function (error) {
+ }, callback);
+}
+
+function put(filePaths, options) {
+ checkConfig(options);
+
+ if (filePaths.length < 2) {
+ console.log('target directory is required.'.red);
+ process.exit(1);
+ }
+
+ let destination = filePaths.pop();
+ if (!path.isAbsolute(destination)) {
+ console.log('target directory must be absolute'.red);
+ process.exit(1);
+ }
+ if (!destination.endsWith('/')) destination += '/';
+
+ async.eachSeries(filePaths, (filePath, iteratorDone) => putOne(filePath, destination, options, iteratorDone), function (error) {
if (error) {
console.log('Failed to put file.', error.message.red);
process.exit(1);
.description('Logout from server')
.action(actions.logout);
-program.command('put <file|dir> [files...]')
+program.command('put <file|dir...>')
.option('-a --all', 'Also include hidden files and folders.', false)
- .description('Put a file, last argument is destination if provided')
- .action(actions.put);
+ .description('Puts a list of files or dirs to the destination. The last argument is destination dir')
+ .action(actions.put)
+ .on('--help', function() {
+ console.log();
+ console.log(' Examples:');
+ console.log();
+ console.log(' $ surfer put file.txt / # puts to /file.txt');
+ console.log(' $ surfer put file.txt /data # puts to /data/file.txt');
+ console.log(' $ surfer put dir /data # puts dir/* as /data/dir/*');
+ console.log(' $ surfer put dir/. / # puts dir/* as /app/data/*');
+ console.log(' $ surfer put dir1 dir2 file1 / # puts as /dir1/* /dir2/* and /file');
+ console.log();
+ });
program.command('get [file|dir]')
.description('Get a file or directory listing')