This repository has been archived by the owner on Mar 10, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
License: MIT Signed-off-by: achingbrain <[email protected]>
- Loading branch information
1 parent
5d189a6
commit 682c478
Showing
10 changed files
with
297 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
'use strict' | ||
|
||
module.exports = { | ||
command: 'rm <path>', | ||
|
||
describe: 'Remove a file or directory', | ||
|
||
builder: { | ||
recursive: { | ||
alias: 'r', | ||
type: 'boolean', | ||
default: false, | ||
describe: 'Remove directories recursively' | ||
} | ||
}, | ||
|
||
handler (argv) { | ||
let { | ||
path, | ||
ipfs, | ||
recursive | ||
} = argv | ||
|
||
ipfs.mfs.rm(path, { | ||
recursive | ||
}, (error) => { | ||
if (error) { | ||
throw error | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
'use strict' | ||
|
||
const promisify = require('promisify-es6') | ||
const UnixFs = require('ipfs-unixfs') | ||
const waterfall = require('async/waterfall') | ||
const { | ||
DAGNode | ||
} = require('ipld-dag-pb') | ||
const CID = require('cids') | ||
const { | ||
traverseTo, | ||
updateTree, | ||
updateMfsRoot, | ||
FILE_SEPARATOR | ||
} = require('./utils') | ||
|
||
const defaultOptions = { | ||
recursive: false | ||
} | ||
|
||
module.exports = function mfsRm (ipfs) { | ||
return promisify(function (path, options, callback) { | ||
if (typeof path === 'function') { | ||
return path(new Error('Please specify a path to remove')) | ||
} | ||
|
||
if (!callback) { | ||
callback = options | ||
options = {} | ||
} | ||
|
||
options = Object.assign({}, defaultOptions, options) | ||
|
||
path = path.trim() | ||
|
||
if (path === FILE_SEPARATOR) { | ||
return callback(new Error('Cannot delete root')) | ||
} | ||
|
||
waterfall([ | ||
(cb) => traverseTo(ipfs, path, { | ||
withCreateHint: false | ||
}, cb), | ||
(result, cb) => { | ||
const meta = UnixFs.unmarshal(result.node.data) | ||
|
||
if (meta.type === 'directory' && !options.recursive) { | ||
return cb(new Error(`${path} is a directory, use -r to remove directories`)) | ||
} | ||
|
||
waterfall([ | ||
(next) => DAGNode.rmLink(result.parent.node, result.name, next), | ||
(newParentNode, next) => { | ||
ipfs.dag.put(newParentNode, { | ||
cid: new CID(newParentNode.hash || newParentNode.multihash) | ||
}, (error) => next(error, newParentNode)) | ||
}, | ||
(newParentNode, next) => { | ||
result.parent.node = newParentNode | ||
|
||
updateTree(ipfs, result.parent, next) | ||
}, | ||
(newRoot, next) => updateMfsRoot(ipfs, newRoot.node.multihash, next) | ||
], cb) | ||
} | ||
], callback) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/* eslint-env mocha */ | ||
'use strict' | ||
|
||
const chai = require('chai') | ||
chai.use(require('dirty-chai')) | ||
const expect = chai.expect | ||
const bufferStream = require('./fixtures/buffer-stream') | ||
|
||
const { | ||
createMfs | ||
} = require('./fixtures') | ||
|
||
const { | ||
FILE_SEPARATOR | ||
} = require('../src/core/utils') | ||
|
||
describe('rm', function () { | ||
this.timeout(30000) | ||
|
||
let mfs | ||
|
||
before(() => { | ||
return createMfs() | ||
.then(instance => { | ||
mfs = instance | ||
}) | ||
}) | ||
|
||
after((done) => { | ||
mfs.node.stop(done) | ||
}) | ||
|
||
it('refuses to remove files without arguments', () => { | ||
return mfs.rm() | ||
.then(() => { | ||
throw new Error('No error was thrown for missing paths') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain('Please specify a path to remove') | ||
}) | ||
}) | ||
|
||
it('refuses to remove the root path', () => { | ||
return mfs.rm(FILE_SEPARATOR) | ||
.then(() => { | ||
throw new Error('No error was thrown for missing paths') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain('Cannot delete root') | ||
}) | ||
}) | ||
|
||
it('refuses to remove a directory without the recursive flag', () => { | ||
const path = `/directory-${Math.random()}` | ||
|
||
return mfs.mkdir(path) | ||
.then(() => mfs.rm(path)) | ||
.then(() => { | ||
throw new Error('No error was thrown for missing recursive flag') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain(`${path} is a directory, use -r to remove directories`) | ||
}) | ||
}) | ||
|
||
it('removes a file', () => { | ||
const file = `/some-file-${Math.random()}.txt` | ||
|
||
return mfs.write(file, bufferStream(100), { | ||
create: true, | ||
parents: true | ||
}) | ||
.then(() => mfs.rm(file, { | ||
recursive: true | ||
})) | ||
.then(() => mfs.stat(file)) | ||
.then(() => { | ||
throw new Error('File was not removed') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain(`Path ${file} did not exist`) | ||
}) | ||
}) | ||
|
||
it('removes a directory', () => { | ||
const directory = `/directory-${Math.random()}` | ||
|
||
return mfs.mkdir(directory) | ||
.then(() => mfs.rm(directory, { | ||
recursive: true | ||
})) | ||
.then(() => mfs.stat(directory)) | ||
.then(() => { | ||
throw new Error('Directory was not removed') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain(`Path ${directory} did not exist`) | ||
}) | ||
}) | ||
|
||
it('recursively removes a directory', () => { | ||
const directory = `/directory-${Math.random()}` | ||
const subdirectory = `/directory-${Math.random()}` | ||
const path = `${directory}${subdirectory}` | ||
|
||
return mfs.mkdir(path) | ||
.then(() => mfs.rm(directory, { | ||
recursive: true | ||
})) | ||
.then(() => mfs.stat(subdirectory)) | ||
.then(() => { | ||
throw new Error('File was not removed') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain(`Path ${subdirectory} did not exist`) | ||
}) | ||
.then(() => mfs.stat(directory)) | ||
.then(() => { | ||
throw new Error('Directory was not removed') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain(`Path ${directory} did not exist`) | ||
}) | ||
}) | ||
|
||
it('recursively removes a directory with files in', () => { | ||
const directory = `directory-${Math.random()}` | ||
const file = `/${directory}/some-file-${Math.random()}.txt` | ||
|
||
return mfs.write(file, bufferStream(100), { | ||
create: true, | ||
parents: true | ||
}) | ||
.then(() => mfs.rm(`/${directory}`, { | ||
recursive: true | ||
})) | ||
.then(() => mfs.stat(file)) | ||
.then(() => { | ||
throw new Error('File was not removed') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain(`Path ${file} did not exist`) | ||
}) | ||
.then(() => mfs.stat(`/${directory}`)) | ||
.then(() => { | ||
throw new Error('Directory was not removed') | ||
}) | ||
.catch(error => { | ||
expect(error.message).to.contain(`${directory} did not exist`) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.