From 233fe3591944702e3579d6a47f25f960e78f38ce Mon Sep 17 00:00:00 2001 From: Zoran Obradovic Date: Mon, 16 Apr 2012 03:39:32 +0200 Subject: [PATCH] fixed mv, cp, some more TODO points --- README | 14 ++-- cd.js | 243 +++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 174 insertions(+), 83 deletions(-) diff --git a/README b/README index 5a8cd56..f55a30b 100644 --- a/README +++ b/README @@ -51,7 +51,7 @@ do lots of stuff: CONSTRUCTOR: -cd(path) - start a new fs interaction, change the current directory to cd +cd(path) - start a new fs method queue, change the current directory to cd PROPERTIES cwd: current directory @@ -59,9 +59,9 @@ cwd: current directory GENERAL: .cd(path): change current directory -TODO .up(): +.up(): cd .. -TODO .root(): +.root(): cd / .echo(args): output args for debugging purposes. uses console.log by default, can be overriden at CD.echo. @@ -93,7 +93,7 @@ FILE OPERATIONS: remove matching files .mv(glob,dest,cbNotFound) move matching entries to the destination directory, or move a single entry to the destination path, or throw an error if neither is possible -TODO .cp(glob,dest,cbNotFound) +.cp(glob,dest,cbNotFound) copy matching entries to the destination directory, or copy a single entry to the destination path, or throw an error .rmrf(glob,cbNotFound) recursively remove matching directories @@ -145,15 +145,17 @@ function cb (done,arg) {...} the callback's context (i.e. this) will be the same CD object. any methods called on it will be placed in the queue and executed after cb exits. if the callback needs to make any async calls, it can return true and call done() manually when the async calls are complete. + + if the callback is a non-truthy value, it is ignored TODO: if the callback is not a function, an error is thrown - TODO: if the callback is a non-truthy value, it is ignored glob: EITHER, an absolute or a relative path from the current directory, possibly including wildcards (* and ?) in the last part (after the last slash), - TODO OR, a fileEntry object + OR, an entry object + OR, a an array of entry objects TODO OR, an array of either will throw an error if the directory (the path before the last slash) does not exist, or if the glob is misformed diff --git a/cd.js b/cd.js index 6f25200..2a5d800 100644 --- a/cd.js +++ b/cd.js @@ -61,8 +61,11 @@ Queue.prototype = { function CD (dir) { this._onerror = function(e) { - console.log(e); + for (var i in e) if (e[i] == e) { e=e[i]; break; } + console.trace(); + console.log(e,arguments.callee.cd.lastPath); }; + this._onerror.cd = this; this.queue = new Queue(this); this.cwd = CD.fs.root; this.counter = 0; @@ -79,7 +82,9 @@ function CD (dir) { /* I N I T */ - +CD.errors = { + +}, CD._onready = []; CD._init = function() { @@ -115,12 +120,15 @@ CD.echo = function () { CD.splitPath = function(path,from) { from = from || '/'; from = from && from.fullPath ? from.fullPath : from; + path = path.fullPath || path; + if (path[0]=='/') { from = ''; } path = from+'/'+path; var p1 = path.split(/[/]+/); var p2 = []; + p2.file = p1.pop(); while (p1.length) { var chunk = p1.shift(); if (!chunk) continue; @@ -131,10 +139,14 @@ CD.splitPath = function(path,from) { } p2.push(chunk); } + p2.dir = '/'+p2.join('/'); + + p2.push(p2.file); + p2.path = '/'+p2.join('/'); return p2; } CD.normalize = function(path,from) { - return '/'+CD.splitPath(path,from).join('/'); + return CD.splitPath(path,from).path } /* @@ -147,6 +159,7 @@ CD.prototype = { Q U E U E TODO: integrate Queue from above */ then: function then (fn,data) { + if (!fn) return; var cnt = this.counter ++; var me = this; //console.log('add',cnt); @@ -154,7 +167,7 @@ CD.prototype = { //console.log('exec',cnt); var Q = me.queue._methods; me.queue._methods = []; - var done = function() { + var done = function(res) { setTimeout(function() { //console.log('done',cnt); if (Q!==null) { @@ -165,53 +178,75 @@ CD.prototype = { },0) } var res = fn.apply(me,[done,data]); - if (res!==true) done() + if (res!==true) done(); }); return this; }, + /* + path helpers + */ + splitPath: function (path,from) { + return CD.splitPath(path,from || this.cwd); + }, + normalize: function (path,from) { + return CD.normalize(path,from || this.cwd); + }, /* FS helpers */ + _getEntry: function(path,cb1,cb2) { + var me = this; + path = this.normalize(path); + + CD.fs.root.getDirectory(path,{},function(entry){ + cb1.apply(me,[entry]) + },function() { + CD.fs.root.getFile(path,{},function(entry){ + cb1.apply(me,[entry]) + }, me._wrap(cb2 || me._onerror)); + }); + }, _getFile: function(path,cb1,cb2) { var me = this; - path = CD.normalize(path); + path = this.normalize(path); + me.lastPath = 'get file '+path; CD.fs.root.getFile(path,{},function(entry){ cb1.apply(me,[entry]) - }, cb2 || me._onerror); + }, me._wrap(cb2 || me._onerror)); }, _getDir: function(path,cb1,cb2) { var me = this; - path = CD.normalize(path); + path = this.normalize(path); + me.lastPath = 'get dir '+path; CD.fs.root.getDirectory(path,{},function(entry){ - cb1.apply(me,[entry]) - }, cb2 || me._onerror); + cb1.apply(me,[entry]) + }, me._wrap(cb2 || me._onerror)); }, - _getEntry: function(path,cb1,cb2) { + _getParent: function(path,cb1,cb2) { var me = this; - path = CD.normalize(path); - CD.fs.root.getDirectory(path,{},function(entry){ - cb1.apply(me,[entry]) - },function() { - CD.fs.root.getFile(path,{},function(entry){ + path = this.splitPath(path); + me.lastPath = 'get parent '+path.dir; + CD.fs.root.getDirectory(path.dir,{},function(entry){ cb1.apply(me,[entry]) - }, cb2 || me._onerror); - }); + }, me._wrap(cb2 || me._onerror)); }, _createFile: function(path,cb1,cb2) { var me = this; - path = CD.normalize(path); + path = this.normalize(path); + me.lastPath = path; CD.fs.root.getFile(path,{create:true},function(entry){ cb1.apply(me,[entry]) - }, cb2 || me._onerror); + }, me._wrap(cb2 || me._onerror)); }, _createDir: function(path,cb1,cb2) { var me = this; - path = CD.normalize(path); + path = this.normalize(path); + me.lastPath = path; CD.fs.root.getDirectory(path,{create:true},function(entry){ cb1.apply(me,[entry]) - }, cb2 || me._onerror); + }, me._wrap(cb2 || me._onerror)); }, /* @@ -229,15 +264,22 @@ CD.prototype = { cd: function cd(dir) { var me = this; this.then(function(done) { - me.cwd.getDirectory(dir, {}, function(dirEntry) { - me.cwd = dirEntry; + this._getDir(dir, function(dirEntry) { + this.cwd = dirEntry; done(); - }, me._onerror); + }); return true; }); return this; }, - + up: function() { + this.cd('..'); + return this; + }, + root: function() { + this.cd('/'); + return this; + }, /* D I R E C T O R Y I T E R A T O R S */ @@ -245,55 +287,59 @@ CD.prototype = { for: function for_(glob,cbFound,cbNotFound) { var me = this; + function loop(entries, done) { + //console.log('found',glob,entries); + if (!entries.length) { + me.then(cbNotFound); + done(); + return true; + } + entries.sort(function(a,b) { + return a.name > b.name ? 1 : -1; + }); + for ( var i = 0; i b.name ? 1 : -1; - }); - for ( var i = 0, entry; entry = entries[i]; i++) { - entry.list = entries; - entry.index = i; - me.then(cbFound, entry); - } - done(); + //console.log('globbed',glob); + loop(entries,done); } else { for (var i = 0, e; e = results[i]; i++) if(e.name.match(re)) entries.push(e); readEntries(me); @@ -310,7 +356,7 @@ CD.prototype = { ls: function ls(glob,cbFound,cbNotFound) { var me = this; this.echo('ls',glob||'*'); - this.for(glob,function(done,f) { + this.for(glob||'*',function(done,f) { f.getMetadata(function(data) { me.echo(f.fullPath, data.modificationTime); f.metaData = data; @@ -401,46 +447,80 @@ CD.prototype = { } me.then(function(done) { fnDone = done; - var pathArray = CD.splitPath(path,me.cwd); + var pathArray = me.splitPath(path); doMkdir(CD.fs.root,pathArray); }); return this; }, - rm: function rm(glob) { + rm: function rm(glob,cbNotFound) { var me = this; this.for(glob, function(done,file) { if (file.isFile) { file.remove(done, me._onerror); return true; } - }) + },cbNotFound) return this; }, - rmrf: function rm(glob) { + rmrf: function (glob,cbNotFound) { var me = this; this.for(glob, function(done,file) { file[ file.isFile ? 'remove' : 'removeRecursively' ] (done, me._onerror); - }) + },cbNotFound) return this; }, - - mv: function mv(glob,dest) { - this.byType(dest, function(dest) { - if (!dest.single) { - this._onerror(); + _mvcpSingle: function (action,glob,dest,done,cbNotFound) { + var me = this; + console.log('mv',glob,me.cwd.fullPath); + this.for(glob, function(done,entry) { + console.log('mv',glob,me.cwd.fullPath); + if (!entry.single) { + this._onerror('destination not single'); return true; } - this._getEntry(dest, function(destEntry) { - if (destEntry.isDirectory) { - this.for(glob, function(entry,done) { - entry.moveTo(destDir,null,done); - return true; - }); - } else { - - }; + var p = me.splitPath(dest); + this._getDir(p.dir, function (destEntry) { + console.log(action,destEntry.fullPath,p.file); + entry[action+'To'](destEntry,p.file,done,this._onerror); }); + return true; + },cbNotFound); + }, + mv: function (glob,dest,cbNotFound) { + this.for(dest, function(done,destEntry) { + if (!destEntry.single) { + this._onerror(); + } + if (destEntry.isDirectory) { + this.for(glob, function(entry,done) { + entry.moveTo(destEntry,null,done,this._onerror); + },cbNotFound); + } else { + this._mvcpSingle('move',glob,dest,done,cbNotFound); + }; + return true; + }, function(done) { + this._mvcpSingle('move',glob,dest,done,cbNotFound); + return true; + }) + return this; + }, + cp: function (glob,dest,cbNotFound) { + this.for(dest, function(done,destEntry) { + if (!destEntry.single) { + this._onerror('cp - destination not single'); + } + if (destEntry.isDirectory) { + this.for(glob, function(entry,done) { + entry.copyTo(destEntry,null,done,this._onerror); + },,cbNotFound); + } else { + this._mvcpSingle('copy',glob,dest,done,cbNotFound); + }; + return true; + }, function(done) { + this._mvcpSingle('copy',glob,dest,done,cbNotFound); }) return this; }, @@ -463,6 +543,15 @@ CD.prototype = { }); return this; }, + throw: function(errorCode) { + }, + _wrap: function(fn) { + var me = this; + return function() { + console.log('wrapped',arguments); + fn.apply(me,arguments); + } + } };