Skip to content

Instantly share code, notes, and snippets.

@Gozala
Created April 15, 2010 13:17
Show Gist options
  • Save Gozala/367073 to your computer and use it in GitHub Desktop.
Save Gozala/367073 to your computer and use it in GitHub Desktop.
Design for bespin fs-mount

Filesystem

Overview

Filesystem is one of the core components of Bespin, providing high-level API for files / directory manipulations. It is a wrapper of FileSources a low-level files / directory access providers.

Filesystem API is exposed to the plugins through editorapp module's files property and through the same named property on env object / argument that is passed to the extension endpoints.

Proposal

Filesystem can allow FileSource "mounting" to any given point on the filesystem, or on a custom URI scheme, much like it is in unix. This will allow plugins to expose access to a different resources in a standard manner just by implementing a few core filesource access functions. Good plugin examples may be:

  • Github plugin exposing user gists under certain mounting point
  • Jetpack based plugin exposing a local file system.

Plugins interested in providing access to a custom filsources would have to provide "filsource" extension, Implementing FileSource Interface. Big part of the FileSystem source from current implementation will move to a FileSource, leaving FileSystem with a role of a router between mounted FileSystems.

It will be possible to mount any FileSource to any mounting point on file-system by bespin console. Some configuration system will allow to keep mountings alive across the sessions.

Specification

###Filesystem###

  • mount(pathOrURIScheme:String, fileSource:FileSource)
    Mounts filesource to a specified path / uri scheme. After successful mount all the file filesystem operations on the subpaths will be done using registered fileSource. In case if multiple filesystems will end up being mounted to the same mounting point the last registered will be used.

    • pathOrURIScheme - String representing one of of the followings:
      • '/' Root of the filesystem
      • Path representing an entry of the existing directory in the filesystem (Assuming that filesystem root exists even if no filesource is mounted yet.)
      • Custom uri scheme like "gist:"
    • fileSource - Object implementing FileSource interface (described in next section)
  • unmount(pathOrURIScheme:String, fileSource:FileSource)
    Unmounts filesource from specified path / uri scheme if it was mounted before. If this fileSource was overriding another one after unmount previously overrided filesystem will become active.

###FileSource###

Mandatory

  • invalidate(path:String)
  • read(path:String):Promise
  • write(path:String):Promise
  • list(path:String):Promise
  • remove(path:String):Promise
  • makeDirectory(path:String):Promise

Optional (may provide faster implementation)

  • isFile(path:String):Promise
  • isDirectory(path:String):Promise
  • rename(path:String, name:String):Promise
  • move(path):Promise
  • makeTree(path):Promise
  • copy(source, target):Promise
  • copyTree(source, target):Promise
  • listTree(path):Promise

Example

Plugins example

"define metadata";
{
    "description": "Provides the gist filesystem",
    "dependencies": {
        "filesystem": "0.0",
		"settings": "0.0",
        "github": "0.0"
    },
    "provides": [
        {
            "ep": "filesource",
            "name": "gist",
            "pointer": "#source"
        }
    ]
}
"end";

var Promise = require('bespin:promise').Promise;
var gist = require('github/yql-gist'); 
var settings = require('settings').settings;

var user = settings.get("github-user");
var token = settings.get("github-token");

function getId(path) {
	return path.substr(path.lastIndexOf('/'));
}
exports.source = {
	read: function(path) {
		var result = new Promise();
		gist.read({
			repo: getId(path),
			user: user,
			token: token
		}, function(content) {
			result.resolve(content);
		}, promise.reject)
		return result;
	},
	write: function(path, content) {
		var result = new Promise();
		gist.write({
			repo: getId(path),
			user: user,
			token: token,
			content: content
		}, function(id) {
			result.resolve(this.mountPoint + id);
		}, promise.reject)
		return result;
	},
	list: function(path) {
		var result = new Promise();
		gist.write({
			user: user,
			token: token
		}, function(gists) {
			result.resolve(gists.map(function(id)
				return this.mountPoint + id;
			));
		}, promise.reject)
		return result;
	},
	remove: function(path) {
		var result = new Promise();
		gist.remove({
			repo: getId(path),
			user: user,
			token: token
		}, result.resolve, promise.reject)
		return result;
	}
	makeDirectory: function(path) {
		// You can't have dirs in 
	},
	invalidate: function(path) {
		// I don't cache anything so not much to invalidate
	}
};

// To mount gist filesystem you can type in cmd
mount gist: gist
// will open gist with id 1734
open gist:1734
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment