diff --git a/src/shell.js b/src/shell.js index c1f18b5..06957ea 100644 --- a/src/shell.js +++ b/src/shell.js @@ -2,8 +2,6 @@ define(function(require) { var Path = require('src/path'); - - function Shell(fs, options) { options = options || {}; @@ -22,36 +20,55 @@ define(function(require) { // We include `cd` on the this vs. proto so that // we can access cwd without exposing it externally. this.cd = function(path) { - + this.cwd = Path.resolve(this.cwd, path); }; } - Shell.prototype.ls = function(path) { - - }; - - Shell.prototype.rm = function(path, options, callback) { - - }; - - Shell.prototype.mv = function(path) { - - }; - - Shell.prototype.cp = function(path) { - - }; - - Shell.prototype.mkdir = function(path) { + /** + * Execute the .js command located at `path`. Such commands + * should assume the existence of 3 arguments, which will be + * defined at runtime: + * + * * options - an object containing any arguments, data, etc. + * * callback - a callback function(error, result) to call when done. + * + * The .js command's contents should be the body of a function + * that looks like this: + * + * function(fs, options, callback) { + * // .js code here + * } + */ + Shell.prototype.exec = function(path, options, callback) { + var fs = this.fs; + if(typeof options === 'function') { + callback = options; + options = {}; + } + options = options || {}; + callback = callback || function(){}; + path = Path.resolve(this.cwd, path); + fs.readFile(path, "utf8", function(error, data) { + if(error) { + callback(error); + return; + } + try { + var cmd = new Function('fs', 'options', 'callback', data); + cmd(fs, options, callback); + } catch(e) { + callback(e); + } + }); }; /** * Create a file if it does not exist, or update access and * modified times if it does. Valid options include: * - * * create - whether to create the file if missing (defaults to true) + * * updateOnly - whether to create the file if missing (defaults to false) * * date - use the provided Date value instead of current date/time */ Shell.prototype.touch = function(path, options, callback) { @@ -60,6 +77,8 @@ define(function(require) { callback = options; options = {}; } + options = options || {}; + callback = callback || function(){}; path = Path.resolve(this.cwd, path); function createFile(path) { @@ -80,8 +99,7 @@ define(function(require) { fs.stat(path, function(error, stats) { if(error) { - // Skip file creation if create is `false` - if(options.create === false) { + if(options.updateOnly === true) { callback(); } else { createFile(path); @@ -92,10 +110,6 @@ define(function(require) { }); }; - Shell.prototype.ln = function(path) { - - }; - return Shell; }); diff --git a/tests/spec/shell/exec.spec.js b/tests/spec/shell/exec.spec.js new file mode 100644 index 0000000..6f325a0 --- /dev/null +++ b/tests/spec/shell/exec.spec.js @@ -0,0 +1,33 @@ +define(["Filer", "util"], function(Filer, util) { + + describe('FileSystemShell.exec', function() { + beforeEach(util.setup); + afterEach(util.cleanup); + + it('should be a function', function() { + var shell = util.shell(); + expect(shell.exec).to.be.a('function'); + }); + + it('should be able to execute a command .js file from the filesystem', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + var cmdString = "fs.writeFile(options.path, options.data, callback);"; + + fs.writeFile('/cmd.js', cmdString, function(error) { + if(error) throw error; + + shell.exec('/cmd.js', {path: '/test', data: 'hello world'}, function(error, result) { + if(error) throw error; + + fs.readFile('/test', 'utf8', function(error, data) { + if(error) throw error; + expect(data).to.equal('hello world'); + done(); + }); + }); + }); + }); + }); + +}); diff --git a/tests/spec/shell/touch.spec.js b/tests/spec/shell/touch.spec.js index ba86827..3b3a12a 100644 --- a/tests/spec/shell/touch.spec.js +++ b/tests/spec/shell/touch.spec.js @@ -31,11 +31,11 @@ define(["Filer", "util"], function(Filer, util) { }); }); - it('should skip creating a new file if options.create is false', function(done) { + it('should skip creating a new file if options.updateOnly is true', function(done) { var fs = util.fs(); var shell = fs.Shell(); - shell.touch('/newfile', { create: false }, function(error) { + shell.touch('/newfile', { updateOnly: true }, function(error) { if(error) throw error; fs.stat('/newfile', function(error, stats) { diff --git a/tests/test-manifest.js b/tests/test-manifest.js index f7f77e4..3faf91d 100644 --- a/tests/test-manifest.js +++ b/tests/test-manifest.js @@ -44,6 +44,7 @@ define([ // Filer.FileSystemShell.* "spec/shell/touch.spec", + "spec/shell/exec.spec", // Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test) "spec/node-js/simple/test-fs-mkdir",