mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-28 17:00:04 +02:00
YAYYYyyy giatn refactor
This commit is contained in:
parent
171e4c8351
commit
d497bea70c
7 changed files with 654 additions and 451 deletions
685
build/bundle.js
685
build/bundle.js
|
@ -10996,7 +10996,7 @@ var Errors = require('../util/errors');
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
var GitOptionParser = GitCommands.GitOptionParser;
|
var GitOptionParser = GitCommands.GitOptionParser;
|
||||||
|
|
||||||
var sandboxInstantCommands = require('../level/sandboxCommands').sandboxInstantCommands;
|
var ParseWaterfall = require('../level/parseWaterfall').ParseWaterfall;
|
||||||
|
|
||||||
var CommandProcessError = Errors.CommandProcessError;
|
var CommandProcessError = Errors.CommandProcessError;
|
||||||
var GitError = Errors.GitError;
|
var GitError = Errors.GitError;
|
||||||
|
@ -11008,38 +11008,47 @@ var Command = Backbone.Model.extend({
|
||||||
status: 'inqueue',
|
status: 'inqueue',
|
||||||
rawStr: null,
|
rawStr: null,
|
||||||
result: '',
|
result: '',
|
||||||
|
createTime: null,
|
||||||
|
|
||||||
error: null,
|
error: null,
|
||||||
warnings: null,
|
warnings: null,
|
||||||
|
parseWaterfall: new ParseWaterfall(),
|
||||||
|
|
||||||
generalArgs: null,
|
generalArgs: null,
|
||||||
supportedMap: null,
|
supportedMap: null,
|
||||||
options: null,
|
options: null,
|
||||||
method: null,
|
method: null
|
||||||
|
|
||||||
createTime: null
|
|
||||||
},
|
},
|
||||||
|
|
||||||
validateAtInit: function() {
|
initialize: function(options) {
|
||||||
// weird things happen with defaults if you dont
|
this.initDefaults();
|
||||||
// make new objects
|
this.validateAtInit();
|
||||||
this.set('generalArgs', []);
|
|
||||||
this.set('supportedMap', {});
|
|
||||||
this.set('warnings', []);
|
|
||||||
|
|
||||||
if (this.get('rawStr') === null) {
|
|
||||||
throw new Error('Give me a string!');
|
|
||||||
}
|
|
||||||
if (!this.get('createTime')) {
|
|
||||||
this.set('createTime', new Date().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.on('change:error', this.errorChanged, this);
|
this.on('change:error', this.errorChanged, this);
|
||||||
// catch errors on init
|
// catch errors on init
|
||||||
if (this.get('error')) {
|
if (this.get('error')) {
|
||||||
this.errorChanged();
|
this.errorChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.parseOrCatch();
|
||||||
|
},
|
||||||
|
|
||||||
|
initDefaults: function() {
|
||||||
|
// weird things happen with defaults if you dont
|
||||||
|
// make new objects
|
||||||
|
this.set('generalArgs', []);
|
||||||
|
this.set('supportedMap', {});
|
||||||
|
this.set('warnings', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
validateAtInit: function() {
|
||||||
|
if (this.get('rawStr') === null) {
|
||||||
|
throw new Error('Give me a string!');
|
||||||
|
}
|
||||||
|
if (!this.get('createTime')) {
|
||||||
|
this.set('createTime', new Date().toString());
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setResult: function(msg) {
|
setResult: function(msg) {
|
||||||
|
@ -11061,19 +11070,26 @@ var Command = Backbone.Model.extend({
|
||||||
return '<p>' + i + this.get('warnings').join('</p><p>' + i) + '</p>';
|
return '<p>' + i + this.get('warnings').join('</p><p>' + i) + '</p>';
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
|
||||||
this.validateAtInit();
|
|
||||||
this.parseOrCatch();
|
|
||||||
},
|
|
||||||
|
|
||||||
parseOrCatch: function() {
|
parseOrCatch: function() {
|
||||||
|
this.expandShortcuts(this.get('rawStr'));
|
||||||
try {
|
try {
|
||||||
this.parse();
|
this.processInstants();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Errors.filterError(err);
|
Errors.filterError(err);
|
||||||
// errorChanged() will handle status and all of that
|
// errorChanged() will handle status and all of that
|
||||||
this.set('error', err);
|
this.set('error', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.parseAll()) {
|
||||||
|
// something in our parse waterfall succeeded
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we reach here, this command is not supported :-/
|
||||||
|
this.set('error', new CommandProcessError({
|
||||||
|
msg: 'The command "' + this.get('rawStr') + '" isn\'t supported, sorry!'
|
||||||
|
})
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
errorChanged: function() {
|
errorChanged: function() {
|
||||||
|
@ -11093,65 +11109,35 @@ var Command = Backbone.Model.extend({
|
||||||
this.set('result', this.get('error').toResult());
|
this.set('result', this.get('error').toResult());
|
||||||
},
|
},
|
||||||
|
|
||||||
parse: function() {
|
expandShortcuts: function(str) {
|
||||||
|
str = this.get('parseWaterfall').expandAllShortcuts(str);
|
||||||
|
this.set('rawStr', str);
|
||||||
|
},
|
||||||
|
|
||||||
|
processInstants: function() {
|
||||||
var str = this.get('rawStr');
|
var str = this.get('rawStr');
|
||||||
// first if the string is empty, they just want a blank line
|
// first if the string is empty, they just want a blank line
|
||||||
if (!str.length) {
|
if (!str.length) {
|
||||||
throw new CommandResult({msg: ""});
|
throw new CommandResult({msg: ""});
|
||||||
}
|
}
|
||||||
|
|
||||||
str = GitCommands.expandShortcut(str);
|
// then instant commands that will throw
|
||||||
this.set('rawStr', str);
|
this.get('parseWaterfall').processAllInstants(str);
|
||||||
|
|
||||||
// then check if it's one of our sandbox commands
|
|
||||||
_.each(sandboxInstantCommands, function(tuple) {
|
|
||||||
var regex = tuple[0];
|
|
||||||
var results = regex.exec(str);
|
|
||||||
if (results) {
|
|
||||||
// this will throw a result
|
|
||||||
tuple[1](results);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// see if begins with git
|
|
||||||
if (str.slice(0,3) !== 'git') {
|
|
||||||
throw new CommandProcessError({
|
|
||||||
msg: 'That command is not supported, sorry!'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok, we have a (probably) valid command. actually parse it
|
|
||||||
this.gitParse(str);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
gitParse: function(str) {
|
parseAll: function() {
|
||||||
// now slice off command part
|
var str = this.get('rawStr');
|
||||||
var fullCommand = str.slice('git '.length);
|
var results = this.get('parseWaterfall').parseAll(str);
|
||||||
|
|
||||||
// see if we support this particular command
|
if (!results) {
|
||||||
_.each(GitCommands.getRegexMap(), function(regex, method) {
|
// nothing parsed successfully
|
||||||
if (regex.exec(fullCommand)) {
|
return false;
|
||||||
this.set('options', fullCommand.slice(method.length + 1));
|
|
||||||
this.set('method', method);
|
|
||||||
// we should stop iterating, but the regex will only match
|
|
||||||
// one command in practice. we could stop iterating if we used
|
|
||||||
// jqeurys for each but im using underscore (for no real reason other
|
|
||||||
// than style)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_.each(results.toSet, function(obj, key) {
|
||||||
|
this.set(key, obj);
|
||||||
}, this);
|
}, this);
|
||||||
|
return true;
|
||||||
if (!this.get('method')) {
|
|
||||||
throw new CommandProcessError({
|
|
||||||
msg: "Sorry, this demo does not support that git command: " + fullCommand
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse off the options and assemble the map / general args
|
|
||||||
var options = new GitOptionParser(this.get('method'), this.get('options'));
|
|
||||||
|
|
||||||
// steal these away so we can be completely JSON
|
|
||||||
this.set('generalArgs', options.generalArgs);
|
|
||||||
this.set('supportedMap', options.supportedMap);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11177,8 +11163,47 @@ var GitError = Errors.GitError;
|
||||||
var Warning = Errors.Warning;
|
var Warning = Errors.Warning;
|
||||||
var CommandResult = Errors.CommandResult;
|
var CommandResult = Errors.CommandResult;
|
||||||
|
|
||||||
var getRegexMap = function() {
|
var shortcutMap = {
|
||||||
return {
|
'git commit': /^gc($|\s)/,
|
||||||
|
'git add': /^ga($|\s)/,
|
||||||
|
'git checkout': /^go($|\s)/,
|
||||||
|
'git rebase': /^gr($|\s)/,
|
||||||
|
'git branch': /^gb($|\s)/,
|
||||||
|
'git status': /^gs($|\s)/,
|
||||||
|
'git help': /^git$/
|
||||||
|
};
|
||||||
|
|
||||||
|
var instantCommands = [
|
||||||
|
[/^git help($|\s)/, function() {
|
||||||
|
var lines = [
|
||||||
|
'Git Version PCOTTLE.1.0',
|
||||||
|
'<br/>',
|
||||||
|
'Usage:',
|
||||||
|
_.escape('\t git <command> [<args>]'),
|
||||||
|
'<br/>',
|
||||||
|
'Supported commands:',
|
||||||
|
'<br/>'
|
||||||
|
];
|
||||||
|
var commands = GitOptionParser.prototype.getMasterOptionMap();
|
||||||
|
|
||||||
|
// build up a nice display of what we support
|
||||||
|
_.each(commands, function(commandOptions, command) {
|
||||||
|
lines.push('git ' + command);
|
||||||
|
_.each(commandOptions, function(vals, optionName) {
|
||||||
|
lines.push('\t ' + optionName);
|
||||||
|
}, this);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
// format and throw
|
||||||
|
var msg = lines.join('\n');
|
||||||
|
msg = msg.replace(/\t/g, ' ');
|
||||||
|
throw new CommandResult({
|
||||||
|
msg: msg
|
||||||
|
});
|
||||||
|
}]
|
||||||
|
];
|
||||||
|
|
||||||
|
var regexMap = {
|
||||||
// ($|\s) means that we either have to end the string
|
// ($|\s) means that we either have to end the string
|
||||||
// after the command or there needs to be a space for options
|
// after the command or there needs to be a space for options
|
||||||
commit: /^commit($|\s)/,
|
commit: /^commit($|\s)/,
|
||||||
|
@ -11193,28 +11218,37 @@ var getRegexMap = function() {
|
||||||
show: /^show($|\s)/,
|
show: /^show($|\s)/,
|
||||||
status: /^status($|\s)/,
|
status: /^status($|\s)/,
|
||||||
'cherry-pick': /^cherry-pick($|\s)/
|
'cherry-pick': /^cherry-pick($|\s)/
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var getShortcutMap = function() {
|
var parse = function(str) {
|
||||||
return {
|
// now slice off command part
|
||||||
'git commit': /^gc($|\s)/,
|
var fullCommand = str.slice('git '.length);
|
||||||
'git add': /^ga($|\s)/,
|
var method;
|
||||||
'git checkout': /^go($|\s)/,
|
var options;
|
||||||
'git rebase': /^gr($|\s)/,
|
|
||||||
'git branch': /^gb($|\s)/,
|
|
||||||
'git status': /^gs($|\s)/
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var expandShortcut = function(commandStr) {
|
// see if we support this particular command
|
||||||
_.each(getShortcutMap(), function(regex, method) {
|
_.each(regexMap, function(regex, thisMethod) {
|
||||||
var results = regex.exec(commandStr);
|
if (regex.exec(fullCommand)) {
|
||||||
if (results) {
|
options = fullCommand.slice(thisMethod.length + 1);
|
||||||
commandStr = method + ' ' + commandStr.slice(results[0].length);
|
method = thisMethod;
|
||||||
}
|
}
|
||||||
});
|
}, this);
|
||||||
return commandStr;
|
|
||||||
|
if (!method) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we support this command!
|
||||||
|
// parse off the options and assemble the map / general args
|
||||||
|
var parsedOptions = new GitOptionParser(method, options);
|
||||||
|
return {
|
||||||
|
toSet: {
|
||||||
|
generalArgs: parsedOptions.generalArgs,
|
||||||
|
supportedMap: parsedOptions.supportedMap,
|
||||||
|
method: method,
|
||||||
|
options: options
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11305,13 +11339,85 @@ GitOptionParser.prototype.explodeAndSet = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.getRegexMap = getRegexMap;
|
exports.shortcutMap = shortcutMap;
|
||||||
exports.expandShortcut = expandShortcut;
|
exports.instantCommands = instantCommands;
|
||||||
exports.GitOptionParser = GitOptionParser;
|
exports.parse = parse;
|
||||||
|
exports.regexMap = regexMap;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
require.define("/src/js/level/sandboxCommands.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
require.define("/src/js/level/parseWaterfall.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
|
|
||||||
|
var GitCommands = require('../git/commands');
|
||||||
|
var SandboxCommands = require('../level/SandboxCommands');
|
||||||
|
|
||||||
|
// more or less a static class
|
||||||
|
function ParseWaterfall(options) {
|
||||||
|
this.shortcutWaterfall = [
|
||||||
|
GitCommands.shortcutMap
|
||||||
|
];
|
||||||
|
|
||||||
|
this.instantWaterfall = [
|
||||||
|
GitCommands.instantCommands,
|
||||||
|
SandboxCommands.instantCommands
|
||||||
|
];
|
||||||
|
|
||||||
|
this.parseWaterfall = [
|
||||||
|
GitCommands.parse
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.expandAllShortcuts = function(commandStr) {
|
||||||
|
_.each(this.shortcutWaterfall, function(shortcutMap) {
|
||||||
|
commandStr = this.expandShortcut(commandStr, shortcutMap);
|
||||||
|
}, this);
|
||||||
|
return commandStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.expandShortcut = function(commandStr, shortcutMap) {
|
||||||
|
_.each(shortcutMap, function(regex, method) {
|
||||||
|
var results = regex.exec(commandStr);
|
||||||
|
if (results) {
|
||||||
|
commandStr = method + ' ' + commandStr.slice(results[0].length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return commandStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.processAllInstants = function(commandStr) {
|
||||||
|
_.each(this.instantWaterfall, function(instantCommands) {
|
||||||
|
this.processInstant(commandStr, instantCommands);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.processInstant = function(commandStr, instantCommands) {
|
||||||
|
_.each(instantCommands, function(tuple) {
|
||||||
|
var regex = tuple[0];
|
||||||
|
var results = regex.exec(commandStr);
|
||||||
|
if (results) {
|
||||||
|
// this will throw a result
|
||||||
|
tuple[1](results);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.parseAll = function(commandStr) {
|
||||||
|
var toReturn = false;
|
||||||
|
_.each(this.parseWaterfall, function(parseFunc) {
|
||||||
|
var results = parseFunc(commandStr);
|
||||||
|
if (results) {
|
||||||
|
toReturn = results;
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.ParseWaterfall = ParseWaterfall;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
require.define("/src/js/level/SandboxCommands.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
|
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
var GitOptionParser = GitCommands.GitOptionParser;
|
var GitOptionParser = GitCommands.GitOptionParser;
|
||||||
|
@ -11322,7 +11428,7 @@ var GitError = Errors.GitError;
|
||||||
var Warning = Errors.Warning;
|
var Warning = Errors.Warning;
|
||||||
var CommandResult = Errors.CommandResult;
|
var CommandResult = Errors.CommandResult;
|
||||||
|
|
||||||
var sandboxInstantCommands = [
|
var instantCommands = [
|
||||||
[/^ls/, function() {
|
[/^ls/, function() {
|
||||||
throw new CommandResult({
|
throw new CommandResult({
|
||||||
msg: "DontWorryAboutFilesInThisDemo.txt"
|
msg: "DontWorryAboutFilesInThisDemo.txt"
|
||||||
|
@ -11333,45 +11439,6 @@ var sandboxInstantCommands = [
|
||||||
msg: "Directory Changed to '/directories/dont/matter/in/this/demo'"
|
msg: "Directory Changed to '/directories/dont/matter/in/this/demo'"
|
||||||
});
|
});
|
||||||
}],
|
}],
|
||||||
[/^git help($|\s)/, function() {
|
|
||||||
// sym link this to the blank git command
|
|
||||||
var allCommands = Command.prototype.getSandboxCommands();
|
|
||||||
// wow this is hacky :(
|
|
||||||
var equivalent = 'git';
|
|
||||||
_.each(allCommands, function(bits) {
|
|
||||||
var regex = bits[0];
|
|
||||||
if (regex.test(equivalent)) {
|
|
||||||
bits[1]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}],
|
|
||||||
[/^git$/, function() {
|
|
||||||
var lines = [
|
|
||||||
'Git Version PCOTTLE.1.0',
|
|
||||||
'<br/>',
|
|
||||||
'Usage:',
|
|
||||||
_.escape('\t git <command> [<args>]'),
|
|
||||||
'<br/>',
|
|
||||||
'Supported commands:',
|
|
||||||
'<br/>'
|
|
||||||
];
|
|
||||||
var commands = GitOptionParser.prototype.getMasterOptionMap();
|
|
||||||
|
|
||||||
// build up a nice display of what we support
|
|
||||||
_.each(commands, function(commandOptions, command) {
|
|
||||||
lines.push('git ' + command);
|
|
||||||
_.each(commandOptions, function(vals, optionName) {
|
|
||||||
lines.push('\t ' + optionName);
|
|
||||||
}, this);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// format and throw
|
|
||||||
var msg = lines.join('\n');
|
|
||||||
msg = msg.replace(/\t/g, ' ');
|
|
||||||
throw new CommandResult({
|
|
||||||
msg: msg
|
|
||||||
});
|
|
||||||
}],
|
|
||||||
[/^refresh$/, function() {
|
[/^refresh$/, function() {
|
||||||
var events = require('../app').getEvents();
|
var events = require('../app').getEvents();
|
||||||
|
|
||||||
|
@ -11391,7 +11458,7 @@ var sandboxInstantCommands = [
|
||||||
}]
|
}]
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.sandboxInstantCommands = sandboxInstantCommands;
|
exports.instantCommands = instantCommands;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -13776,7 +13843,6 @@ exports.VisEdge = VisEdge;
|
||||||
});
|
});
|
||||||
|
|
||||||
require.define("/src/js/level/inputWaterfall.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
require.define("/src/js/level/inputWaterfall.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
var Backbone = require('backbone');
|
|
||||||
|
|
||||||
var Main = require('../app');
|
var Main = require('../app');
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
|
@ -13832,6 +13898,7 @@ InputWaterfall.prototype.checkDisabledMap = function(command) {
|
||||||
try {
|
try {
|
||||||
this.loopDisabledMap(command);
|
this.loopDisabledMap(command);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
Errors.filterError(err);
|
||||||
command.set('error', err);
|
command.set('error', err);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -13841,7 +13908,7 @@ InputWaterfall.prototype.checkDisabledMap = function(command) {
|
||||||
|
|
||||||
InputWaterfall.prototype.loopDisabledMap = function(command) {
|
InputWaterfall.prototype.loopDisabledMap = function(command) {
|
||||||
var toTest = this.sliceGitOff(command.get('rawStr'));
|
var toTest = this.sliceGitOff(command.get('rawStr'));
|
||||||
var regexMap = GitCommands.getRegexMap();
|
var regexMap = GitCommands.regexMap;
|
||||||
|
|
||||||
_.each(this.disabledMap, function(val, disabledGitCommand) {
|
_.each(this.disabledMap, function(val, disabledGitCommand) {
|
||||||
disabledGitCommand = this.sliceGitOff(disabledGitCommand);
|
disabledGitCommand = this.sliceGitOff(disabledGitCommand);
|
||||||
|
@ -14201,8 +14268,47 @@ var GitError = Errors.GitError;
|
||||||
var Warning = Errors.Warning;
|
var Warning = Errors.Warning;
|
||||||
var CommandResult = Errors.CommandResult;
|
var CommandResult = Errors.CommandResult;
|
||||||
|
|
||||||
var getRegexMap = function() {
|
var shortcutMap = {
|
||||||
return {
|
'git commit': /^gc($|\s)/,
|
||||||
|
'git add': /^ga($|\s)/,
|
||||||
|
'git checkout': /^go($|\s)/,
|
||||||
|
'git rebase': /^gr($|\s)/,
|
||||||
|
'git branch': /^gb($|\s)/,
|
||||||
|
'git status': /^gs($|\s)/,
|
||||||
|
'git help': /^git$/
|
||||||
|
};
|
||||||
|
|
||||||
|
var instantCommands = [
|
||||||
|
[/^git help($|\s)/, function() {
|
||||||
|
var lines = [
|
||||||
|
'Git Version PCOTTLE.1.0',
|
||||||
|
'<br/>',
|
||||||
|
'Usage:',
|
||||||
|
_.escape('\t git <command> [<args>]'),
|
||||||
|
'<br/>',
|
||||||
|
'Supported commands:',
|
||||||
|
'<br/>'
|
||||||
|
];
|
||||||
|
var commands = GitOptionParser.prototype.getMasterOptionMap();
|
||||||
|
|
||||||
|
// build up a nice display of what we support
|
||||||
|
_.each(commands, function(commandOptions, command) {
|
||||||
|
lines.push('git ' + command);
|
||||||
|
_.each(commandOptions, function(vals, optionName) {
|
||||||
|
lines.push('\t ' + optionName);
|
||||||
|
}, this);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
// format and throw
|
||||||
|
var msg = lines.join('\n');
|
||||||
|
msg = msg.replace(/\t/g, ' ');
|
||||||
|
throw new CommandResult({
|
||||||
|
msg: msg
|
||||||
|
});
|
||||||
|
}]
|
||||||
|
];
|
||||||
|
|
||||||
|
var regexMap = {
|
||||||
// ($|\s) means that we either have to end the string
|
// ($|\s) means that we either have to end the string
|
||||||
// after the command or there needs to be a space for options
|
// after the command or there needs to be a space for options
|
||||||
commit: /^commit($|\s)/,
|
commit: /^commit($|\s)/,
|
||||||
|
@ -14217,28 +14323,37 @@ var getRegexMap = function() {
|
||||||
show: /^show($|\s)/,
|
show: /^show($|\s)/,
|
||||||
status: /^status($|\s)/,
|
status: /^status($|\s)/,
|
||||||
'cherry-pick': /^cherry-pick($|\s)/
|
'cherry-pick': /^cherry-pick($|\s)/
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var getShortcutMap = function() {
|
var parse = function(str) {
|
||||||
return {
|
// now slice off command part
|
||||||
'git commit': /^gc($|\s)/,
|
var fullCommand = str.slice('git '.length);
|
||||||
'git add': /^ga($|\s)/,
|
var method;
|
||||||
'git checkout': /^go($|\s)/,
|
var options;
|
||||||
'git rebase': /^gr($|\s)/,
|
|
||||||
'git branch': /^gb($|\s)/,
|
|
||||||
'git status': /^gs($|\s)/
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var expandShortcut = function(commandStr) {
|
// see if we support this particular command
|
||||||
_.each(getShortcutMap(), function(regex, method) {
|
_.each(regexMap, function(regex, thisMethod) {
|
||||||
var results = regex.exec(commandStr);
|
if (regex.exec(fullCommand)) {
|
||||||
if (results) {
|
options = fullCommand.slice(thisMethod.length + 1);
|
||||||
commandStr = method + ' ' + commandStr.slice(results[0].length);
|
method = thisMethod;
|
||||||
}
|
}
|
||||||
});
|
}, this);
|
||||||
return commandStr;
|
|
||||||
|
if (!method) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we support this command!
|
||||||
|
// parse off the options and assemble the map / general args
|
||||||
|
var parsedOptions = new GitOptionParser(method, options);
|
||||||
|
return {
|
||||||
|
toSet: {
|
||||||
|
generalArgs: parsedOptions.generalArgs,
|
||||||
|
supportedMap: parsedOptions.supportedMap,
|
||||||
|
method: method,
|
||||||
|
options: options
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14329,9 +14444,10 @@ GitOptionParser.prototype.explodeAndSet = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.getRegexMap = getRegexMap;
|
exports.shortcutMap = shortcutMap;
|
||||||
exports.expandShortcut = expandShortcut;
|
exports.instantCommands = instantCommands;
|
||||||
exports.GitOptionParser = GitOptionParser;
|
exports.parse = parse;
|
||||||
|
exports.regexMap = regexMap;
|
||||||
|
|
||||||
});
|
});
|
||||||
require("/src/js/git/commands.js");
|
require("/src/js/git/commands.js");
|
||||||
|
@ -16194,7 +16310,6 @@ exports.TreeCompare = TreeCompare;
|
||||||
require("/src/js/git/treeCompare.js");
|
require("/src/js/git/treeCompare.js");
|
||||||
|
|
||||||
require.define("/src/js/level/inputWaterfall.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
require.define("/src/js/level/inputWaterfall.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
var Backbone = require('backbone');
|
|
||||||
|
|
||||||
var Main = require('../app');
|
var Main = require('../app');
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
|
@ -16250,6 +16365,7 @@ InputWaterfall.prototype.checkDisabledMap = function(command) {
|
||||||
try {
|
try {
|
||||||
this.loopDisabledMap(command);
|
this.loopDisabledMap(command);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
Errors.filterError(err);
|
||||||
command.set('error', err);
|
command.set('error', err);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -16259,7 +16375,7 @@ InputWaterfall.prototype.checkDisabledMap = function(command) {
|
||||||
|
|
||||||
InputWaterfall.prototype.loopDisabledMap = function(command) {
|
InputWaterfall.prototype.loopDisabledMap = function(command) {
|
||||||
var toTest = this.sliceGitOff(command.get('rawStr'));
|
var toTest = this.sliceGitOff(command.get('rawStr'));
|
||||||
var regexMap = GitCommands.getRegexMap();
|
var regexMap = GitCommands.regexMap;
|
||||||
|
|
||||||
_.each(this.disabledMap, function(val, disabledGitCommand) {
|
_.each(this.disabledMap, function(val, disabledGitCommand) {
|
||||||
disabledGitCommand = this.sliceGitOff(disabledGitCommand);
|
disabledGitCommand = this.sliceGitOff(disabledGitCommand);
|
||||||
|
@ -16284,6 +16400,78 @@ exports.InputWaterfall = InputWaterfall;
|
||||||
});
|
});
|
||||||
require("/src/js/level/inputWaterfall.js");
|
require("/src/js/level/inputWaterfall.js");
|
||||||
|
|
||||||
|
require.define("/src/js/level/parseWaterfall.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
|
|
||||||
|
var GitCommands = require('../git/commands');
|
||||||
|
var SandboxCommands = require('../level/SandboxCommands');
|
||||||
|
|
||||||
|
// more or less a static class
|
||||||
|
function ParseWaterfall(options) {
|
||||||
|
this.shortcutWaterfall = [
|
||||||
|
GitCommands.shortcutMap
|
||||||
|
];
|
||||||
|
|
||||||
|
this.instantWaterfall = [
|
||||||
|
GitCommands.instantCommands,
|
||||||
|
SandboxCommands.instantCommands
|
||||||
|
];
|
||||||
|
|
||||||
|
this.parseWaterfall = [
|
||||||
|
GitCommands.parse
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.expandAllShortcuts = function(commandStr) {
|
||||||
|
_.each(this.shortcutWaterfall, function(shortcutMap) {
|
||||||
|
commandStr = this.expandShortcut(commandStr, shortcutMap);
|
||||||
|
}, this);
|
||||||
|
return commandStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.expandShortcut = function(commandStr, shortcutMap) {
|
||||||
|
_.each(shortcutMap, function(regex, method) {
|
||||||
|
var results = regex.exec(commandStr);
|
||||||
|
if (results) {
|
||||||
|
commandStr = method + ' ' + commandStr.slice(results[0].length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return commandStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.processAllInstants = function(commandStr) {
|
||||||
|
_.each(this.instantWaterfall, function(instantCommands) {
|
||||||
|
this.processInstant(commandStr, instantCommands);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.processInstant = function(commandStr, instantCommands) {
|
||||||
|
_.each(instantCommands, function(tuple) {
|
||||||
|
var regex = tuple[0];
|
||||||
|
var results = regex.exec(commandStr);
|
||||||
|
if (results) {
|
||||||
|
// this will throw a result
|
||||||
|
tuple[1](results);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.parseAll = function(commandStr) {
|
||||||
|
var toReturn = false;
|
||||||
|
_.each(this.parseWaterfall, function(parseFunc) {
|
||||||
|
var results = parseFunc(commandStr);
|
||||||
|
if (results) {
|
||||||
|
toReturn = results;
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.ParseWaterfall = ParseWaterfall;
|
||||||
|
|
||||||
|
});
|
||||||
|
require("/src/js/level/parseWaterfall.js");
|
||||||
|
|
||||||
require.define("/src/js/level/sandboxCommands.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
require.define("/src/js/level/sandboxCommands.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore');
|
||||||
|
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
|
@ -16295,7 +16483,7 @@ var GitError = Errors.GitError;
|
||||||
var Warning = Errors.Warning;
|
var Warning = Errors.Warning;
|
||||||
var CommandResult = Errors.CommandResult;
|
var CommandResult = Errors.CommandResult;
|
||||||
|
|
||||||
var sandboxInstantCommands = [
|
var instantCommands = [
|
||||||
[/^ls/, function() {
|
[/^ls/, function() {
|
||||||
throw new CommandResult({
|
throw new CommandResult({
|
||||||
msg: "DontWorryAboutFilesInThisDemo.txt"
|
msg: "DontWorryAboutFilesInThisDemo.txt"
|
||||||
|
@ -16306,45 +16494,6 @@ var sandboxInstantCommands = [
|
||||||
msg: "Directory Changed to '/directories/dont/matter/in/this/demo'"
|
msg: "Directory Changed to '/directories/dont/matter/in/this/demo'"
|
||||||
});
|
});
|
||||||
}],
|
}],
|
||||||
[/^git help($|\s)/, function() {
|
|
||||||
// sym link this to the blank git command
|
|
||||||
var allCommands = Command.prototype.getSandboxCommands();
|
|
||||||
// wow this is hacky :(
|
|
||||||
var equivalent = 'git';
|
|
||||||
_.each(allCommands, function(bits) {
|
|
||||||
var regex = bits[0];
|
|
||||||
if (regex.test(equivalent)) {
|
|
||||||
bits[1]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}],
|
|
||||||
[/^git$/, function() {
|
|
||||||
var lines = [
|
|
||||||
'Git Version PCOTTLE.1.0',
|
|
||||||
'<br/>',
|
|
||||||
'Usage:',
|
|
||||||
_.escape('\t git <command> [<args>]'),
|
|
||||||
'<br/>',
|
|
||||||
'Supported commands:',
|
|
||||||
'<br/>'
|
|
||||||
];
|
|
||||||
var commands = GitOptionParser.prototype.getMasterOptionMap();
|
|
||||||
|
|
||||||
// build up a nice display of what we support
|
|
||||||
_.each(commands, function(commandOptions, command) {
|
|
||||||
lines.push('git ' + command);
|
|
||||||
_.each(commandOptions, function(vals, optionName) {
|
|
||||||
lines.push('\t ' + optionName);
|
|
||||||
}, this);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// format and throw
|
|
||||||
var msg = lines.join('\n');
|
|
||||||
msg = msg.replace(/\t/g, ' ');
|
|
||||||
throw new CommandResult({
|
|
||||||
msg: msg
|
|
||||||
});
|
|
||||||
}],
|
|
||||||
[/^refresh$/, function() {
|
[/^refresh$/, function() {
|
||||||
var events = require('../app').getEvents();
|
var events = require('../app').getEvents();
|
||||||
|
|
||||||
|
@ -16364,7 +16513,7 @@ var sandboxInstantCommands = [
|
||||||
}]
|
}]
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.sandboxInstantCommands = sandboxInstantCommands;
|
exports.instantCommands = instantCommands;
|
||||||
|
|
||||||
});
|
});
|
||||||
require("/src/js/level/sandboxCommands.js");
|
require("/src/js/level/sandboxCommands.js");
|
||||||
|
@ -16486,7 +16635,7 @@ var Errors = require('../util/errors');
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
var GitOptionParser = GitCommands.GitOptionParser;
|
var GitOptionParser = GitCommands.GitOptionParser;
|
||||||
|
|
||||||
var sandboxInstantCommands = require('../level/sandboxCommands').sandboxInstantCommands;
|
var ParseWaterfall = require('../level/parseWaterfall').ParseWaterfall;
|
||||||
|
|
||||||
var CommandProcessError = Errors.CommandProcessError;
|
var CommandProcessError = Errors.CommandProcessError;
|
||||||
var GitError = Errors.GitError;
|
var GitError = Errors.GitError;
|
||||||
|
@ -16498,38 +16647,47 @@ var Command = Backbone.Model.extend({
|
||||||
status: 'inqueue',
|
status: 'inqueue',
|
||||||
rawStr: null,
|
rawStr: null,
|
||||||
result: '',
|
result: '',
|
||||||
|
createTime: null,
|
||||||
|
|
||||||
error: null,
|
error: null,
|
||||||
warnings: null,
|
warnings: null,
|
||||||
|
parseWaterfall: new ParseWaterfall(),
|
||||||
|
|
||||||
generalArgs: null,
|
generalArgs: null,
|
||||||
supportedMap: null,
|
supportedMap: null,
|
||||||
options: null,
|
options: null,
|
||||||
method: null,
|
method: null
|
||||||
|
|
||||||
createTime: null
|
|
||||||
},
|
},
|
||||||
|
|
||||||
validateAtInit: function() {
|
initialize: function(options) {
|
||||||
// weird things happen with defaults if you dont
|
this.initDefaults();
|
||||||
// make new objects
|
this.validateAtInit();
|
||||||
this.set('generalArgs', []);
|
|
||||||
this.set('supportedMap', {});
|
|
||||||
this.set('warnings', []);
|
|
||||||
|
|
||||||
if (this.get('rawStr') === null) {
|
|
||||||
throw new Error('Give me a string!');
|
|
||||||
}
|
|
||||||
if (!this.get('createTime')) {
|
|
||||||
this.set('createTime', new Date().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.on('change:error', this.errorChanged, this);
|
this.on('change:error', this.errorChanged, this);
|
||||||
// catch errors on init
|
// catch errors on init
|
||||||
if (this.get('error')) {
|
if (this.get('error')) {
|
||||||
this.errorChanged();
|
this.errorChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.parseOrCatch();
|
||||||
|
},
|
||||||
|
|
||||||
|
initDefaults: function() {
|
||||||
|
// weird things happen with defaults if you dont
|
||||||
|
// make new objects
|
||||||
|
this.set('generalArgs', []);
|
||||||
|
this.set('supportedMap', {});
|
||||||
|
this.set('warnings', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
validateAtInit: function() {
|
||||||
|
if (this.get('rawStr') === null) {
|
||||||
|
throw new Error('Give me a string!');
|
||||||
|
}
|
||||||
|
if (!this.get('createTime')) {
|
||||||
|
this.set('createTime', new Date().toString());
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setResult: function(msg) {
|
setResult: function(msg) {
|
||||||
|
@ -16551,19 +16709,26 @@ var Command = Backbone.Model.extend({
|
||||||
return '<p>' + i + this.get('warnings').join('</p><p>' + i) + '</p>';
|
return '<p>' + i + this.get('warnings').join('</p><p>' + i) + '</p>';
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
|
||||||
this.validateAtInit();
|
|
||||||
this.parseOrCatch();
|
|
||||||
},
|
|
||||||
|
|
||||||
parseOrCatch: function() {
|
parseOrCatch: function() {
|
||||||
|
this.expandShortcuts(this.get('rawStr'));
|
||||||
try {
|
try {
|
||||||
this.parse();
|
this.processInstants();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Errors.filterError(err);
|
Errors.filterError(err);
|
||||||
// errorChanged() will handle status and all of that
|
// errorChanged() will handle status and all of that
|
||||||
this.set('error', err);
|
this.set('error', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.parseAll()) {
|
||||||
|
// something in our parse waterfall succeeded
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we reach here, this command is not supported :-/
|
||||||
|
this.set('error', new CommandProcessError({
|
||||||
|
msg: 'The command "' + this.get('rawStr') + '" isn\'t supported, sorry!'
|
||||||
|
})
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
errorChanged: function() {
|
errorChanged: function() {
|
||||||
|
@ -16583,65 +16748,35 @@ var Command = Backbone.Model.extend({
|
||||||
this.set('result', this.get('error').toResult());
|
this.set('result', this.get('error').toResult());
|
||||||
},
|
},
|
||||||
|
|
||||||
parse: function() {
|
expandShortcuts: function(str) {
|
||||||
|
str = this.get('parseWaterfall').expandAllShortcuts(str);
|
||||||
|
this.set('rawStr', str);
|
||||||
|
},
|
||||||
|
|
||||||
|
processInstants: function() {
|
||||||
var str = this.get('rawStr');
|
var str = this.get('rawStr');
|
||||||
// first if the string is empty, they just want a blank line
|
// first if the string is empty, they just want a blank line
|
||||||
if (!str.length) {
|
if (!str.length) {
|
||||||
throw new CommandResult({msg: ""});
|
throw new CommandResult({msg: ""});
|
||||||
}
|
}
|
||||||
|
|
||||||
str = GitCommands.expandShortcut(str);
|
// then instant commands that will throw
|
||||||
this.set('rawStr', str);
|
this.get('parseWaterfall').processAllInstants(str);
|
||||||
|
|
||||||
// then check if it's one of our sandbox commands
|
|
||||||
_.each(sandboxInstantCommands, function(tuple) {
|
|
||||||
var regex = tuple[0];
|
|
||||||
var results = regex.exec(str);
|
|
||||||
if (results) {
|
|
||||||
// this will throw a result
|
|
||||||
tuple[1](results);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// see if begins with git
|
|
||||||
if (str.slice(0,3) !== 'git') {
|
|
||||||
throw new CommandProcessError({
|
|
||||||
msg: 'That command is not supported, sorry!'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok, we have a (probably) valid command. actually parse it
|
|
||||||
this.gitParse(str);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
gitParse: function(str) {
|
parseAll: function() {
|
||||||
// now slice off command part
|
var str = this.get('rawStr');
|
||||||
var fullCommand = str.slice('git '.length);
|
var results = this.get('parseWaterfall').parseAll(str);
|
||||||
|
|
||||||
// see if we support this particular command
|
if (!results) {
|
||||||
_.each(GitCommands.getRegexMap(), function(regex, method) {
|
// nothing parsed successfully
|
||||||
if (regex.exec(fullCommand)) {
|
return false;
|
||||||
this.set('options', fullCommand.slice(method.length + 1));
|
|
||||||
this.set('method', method);
|
|
||||||
// we should stop iterating, but the regex will only match
|
|
||||||
// one command in practice. we could stop iterating if we used
|
|
||||||
// jqeurys for each but im using underscore (for no real reason other
|
|
||||||
// than style)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_.each(results.toSet, function(obj, key) {
|
||||||
|
this.set(key, obj);
|
||||||
}, this);
|
}, this);
|
||||||
|
return true;
|
||||||
if (!this.get('method')) {
|
|
||||||
throw new CommandProcessError({
|
|
||||||
msg: "Sorry, this demo does not support that git command: " + fullCommand
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse off the options and assemble the map / general args
|
|
||||||
var options = new GitOptionParser(this.get('method'), this.get('options'));
|
|
||||||
|
|
||||||
// steal these away so we can be completely JSON
|
|
||||||
this.set('generalArgs', options.generalArgs);
|
|
||||||
this.set('supportedMap', options.supportedMap);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,47 @@ var GitError = Errors.GitError;
|
||||||
var Warning = Errors.Warning;
|
var Warning = Errors.Warning;
|
||||||
var CommandResult = Errors.CommandResult;
|
var CommandResult = Errors.CommandResult;
|
||||||
|
|
||||||
var getRegexMap = function() {
|
var shortcutMap = {
|
||||||
return {
|
'git commit': /^gc($|\s)/,
|
||||||
|
'git add': /^ga($|\s)/,
|
||||||
|
'git checkout': /^go($|\s)/,
|
||||||
|
'git rebase': /^gr($|\s)/,
|
||||||
|
'git branch': /^gb($|\s)/,
|
||||||
|
'git status': /^gs($|\s)/,
|
||||||
|
'git help': /^git$/
|
||||||
|
};
|
||||||
|
|
||||||
|
var instantCommands = [
|
||||||
|
[/^git help($|\s)/, function() {
|
||||||
|
var lines = [
|
||||||
|
'Git Version PCOTTLE.1.0',
|
||||||
|
'<br/>',
|
||||||
|
'Usage:',
|
||||||
|
_.escape('\t git <command> [<args>]'),
|
||||||
|
'<br/>',
|
||||||
|
'Supported commands:',
|
||||||
|
'<br/>'
|
||||||
|
];
|
||||||
|
var commands = GitOptionParser.prototype.getMasterOptionMap();
|
||||||
|
|
||||||
|
// build up a nice display of what we support
|
||||||
|
_.each(commands, function(commandOptions, command) {
|
||||||
|
lines.push('git ' + command);
|
||||||
|
_.each(commandOptions, function(vals, optionName) {
|
||||||
|
lines.push('\t ' + optionName);
|
||||||
|
}, this);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
// format and throw
|
||||||
|
var msg = lines.join('\n');
|
||||||
|
msg = msg.replace(/\t/g, ' ');
|
||||||
|
throw new CommandResult({
|
||||||
|
msg: msg
|
||||||
|
});
|
||||||
|
}]
|
||||||
|
];
|
||||||
|
|
||||||
|
var regexMap = {
|
||||||
// ($|\s) means that we either have to end the string
|
// ($|\s) means that we either have to end the string
|
||||||
// after the command or there needs to be a space for options
|
// after the command or there needs to be a space for options
|
||||||
commit: /^commit($|\s)/,
|
commit: /^commit($|\s)/,
|
||||||
|
@ -22,28 +61,37 @@ var getRegexMap = function() {
|
||||||
show: /^show($|\s)/,
|
show: /^show($|\s)/,
|
||||||
status: /^status($|\s)/,
|
status: /^status($|\s)/,
|
||||||
'cherry-pick': /^cherry-pick($|\s)/
|
'cherry-pick': /^cherry-pick($|\s)/
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var getShortcutMap = function() {
|
var parse = function(str) {
|
||||||
return {
|
// now slice off command part
|
||||||
'git commit': /^gc($|\s)/,
|
var fullCommand = str.slice('git '.length);
|
||||||
'git add': /^ga($|\s)/,
|
var method;
|
||||||
'git checkout': /^go($|\s)/,
|
var options;
|
||||||
'git rebase': /^gr($|\s)/,
|
|
||||||
'git branch': /^gb($|\s)/,
|
|
||||||
'git status': /^gs($|\s)/
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var expandShortcut = function(commandStr) {
|
// see if we support this particular command
|
||||||
_.each(getShortcutMap(), function(regex, method) {
|
_.each(regexMap, function(regex, thisMethod) {
|
||||||
var results = regex.exec(commandStr);
|
if (regex.exec(fullCommand)) {
|
||||||
if (results) {
|
options = fullCommand.slice(thisMethod.length + 1);
|
||||||
commandStr = method + ' ' + commandStr.slice(results[0].length);
|
method = thisMethod;
|
||||||
}
|
}
|
||||||
});
|
}, this);
|
||||||
return commandStr;
|
|
||||||
|
if (!method) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we support this command!
|
||||||
|
// parse off the options and assemble the map / general args
|
||||||
|
var parsedOptions = new GitOptionParser(method, options);
|
||||||
|
return {
|
||||||
|
toSet: {
|
||||||
|
generalArgs: parsedOptions.generalArgs,
|
||||||
|
supportedMap: parsedOptions.supportedMap,
|
||||||
|
method: method,
|
||||||
|
options: options
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,6 +182,7 @@ GitOptionParser.prototype.explodeAndSet = function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.getRegexMap = getRegexMap;
|
exports.shortcutMap = shortcutMap;
|
||||||
exports.expandShortcut = expandShortcut;
|
exports.instantCommands = instantCommands;
|
||||||
exports.GitOptionParser = GitOptionParser;
|
exports.parse = parse;
|
||||||
|
exports.regexMap = regexMap;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
var _ = require('underscore');
|
var _ = require('underscore');
|
||||||
var Backbone = require('backbone');
|
|
||||||
|
|
||||||
var Main = require('../app');
|
var Main = require('../app');
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
|
@ -55,6 +54,7 @@ InputWaterfall.prototype.checkDisabledMap = function(command) {
|
||||||
try {
|
try {
|
||||||
this.loopDisabledMap(command);
|
this.loopDisabledMap(command);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
Errors.filterError(err);
|
||||||
command.set('error', err);
|
command.set('error', err);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ InputWaterfall.prototype.checkDisabledMap = function(command) {
|
||||||
|
|
||||||
InputWaterfall.prototype.loopDisabledMap = function(command) {
|
InputWaterfall.prototype.loopDisabledMap = function(command) {
|
||||||
var toTest = this.sliceGitOff(command.get('rawStr'));
|
var toTest = this.sliceGitOff(command.get('rawStr'));
|
||||||
var regexMap = GitCommands.getRegexMap();
|
var regexMap = GitCommands.regexMap;
|
||||||
|
|
||||||
_.each(this.disabledMap, function(val, disabledGitCommand) {
|
_.each(this.disabledMap, function(val, disabledGitCommand) {
|
||||||
disabledGitCommand = this.sliceGitOff(disabledGitCommand);
|
disabledGitCommand = this.sliceGitOff(disabledGitCommand);
|
||||||
|
|
68
src/js/level/parseWaterfall.js
Normal file
68
src/js/level/parseWaterfall.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
var _ = require('underscore');
|
||||||
|
|
||||||
|
var GitCommands = require('../git/commands');
|
||||||
|
var SandboxCommands = require('../level/SandboxCommands');
|
||||||
|
|
||||||
|
// more or less a static class
|
||||||
|
function ParseWaterfall(options) {
|
||||||
|
this.shortcutWaterfall = [
|
||||||
|
GitCommands.shortcutMap
|
||||||
|
];
|
||||||
|
|
||||||
|
this.instantWaterfall = [
|
||||||
|
GitCommands.instantCommands,
|
||||||
|
SandboxCommands.instantCommands
|
||||||
|
];
|
||||||
|
|
||||||
|
this.parseWaterfall = [
|
||||||
|
GitCommands.parse
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.expandAllShortcuts = function(commandStr) {
|
||||||
|
_.each(this.shortcutWaterfall, function(shortcutMap) {
|
||||||
|
commandStr = this.expandShortcut(commandStr, shortcutMap);
|
||||||
|
}, this);
|
||||||
|
return commandStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.expandShortcut = function(commandStr, shortcutMap) {
|
||||||
|
_.each(shortcutMap, function(regex, method) {
|
||||||
|
var results = regex.exec(commandStr);
|
||||||
|
if (results) {
|
||||||
|
commandStr = method + ' ' + commandStr.slice(results[0].length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return commandStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.processAllInstants = function(commandStr) {
|
||||||
|
_.each(this.instantWaterfall, function(instantCommands) {
|
||||||
|
this.processInstant(commandStr, instantCommands);
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.processInstant = function(commandStr, instantCommands) {
|
||||||
|
_.each(instantCommands, function(tuple) {
|
||||||
|
var regex = tuple[0];
|
||||||
|
var results = regex.exec(commandStr);
|
||||||
|
if (results) {
|
||||||
|
// this will throw a result
|
||||||
|
tuple[1](results);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ParseWaterfall.prototype.parseAll = function(commandStr) {
|
||||||
|
var toReturn = false;
|
||||||
|
_.each(this.parseWaterfall, function(parseFunc) {
|
||||||
|
var results = parseFunc(commandStr);
|
||||||
|
if (results) {
|
||||||
|
toReturn = results;
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.ParseWaterfall = ParseWaterfall;
|
|
@ -9,7 +9,7 @@ var GitError = Errors.GitError;
|
||||||
var Warning = Errors.Warning;
|
var Warning = Errors.Warning;
|
||||||
var CommandResult = Errors.CommandResult;
|
var CommandResult = Errors.CommandResult;
|
||||||
|
|
||||||
var sandboxInstantCommands = [
|
var instantCommands = [
|
||||||
[/^ls/, function() {
|
[/^ls/, function() {
|
||||||
throw new CommandResult({
|
throw new CommandResult({
|
||||||
msg: "DontWorryAboutFilesInThisDemo.txt"
|
msg: "DontWorryAboutFilesInThisDemo.txt"
|
||||||
|
@ -20,45 +20,6 @@ var sandboxInstantCommands = [
|
||||||
msg: "Directory Changed to '/directories/dont/matter/in/this/demo'"
|
msg: "Directory Changed to '/directories/dont/matter/in/this/demo'"
|
||||||
});
|
});
|
||||||
}],
|
}],
|
||||||
[/^git help($|\s)/, function() {
|
|
||||||
// sym link this to the blank git command
|
|
||||||
var allCommands = Command.prototype.getSandboxCommands();
|
|
||||||
// wow this is hacky :(
|
|
||||||
var equivalent = 'git';
|
|
||||||
_.each(allCommands, function(bits) {
|
|
||||||
var regex = bits[0];
|
|
||||||
if (regex.test(equivalent)) {
|
|
||||||
bits[1]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}],
|
|
||||||
[/^git$/, function() {
|
|
||||||
var lines = [
|
|
||||||
'Git Version PCOTTLE.1.0',
|
|
||||||
'<br/>',
|
|
||||||
'Usage:',
|
|
||||||
_.escape('\t git <command> [<args>]'),
|
|
||||||
'<br/>',
|
|
||||||
'Supported commands:',
|
|
||||||
'<br/>'
|
|
||||||
];
|
|
||||||
var commands = GitOptionParser.prototype.getMasterOptionMap();
|
|
||||||
|
|
||||||
// build up a nice display of what we support
|
|
||||||
_.each(commands, function(commandOptions, command) {
|
|
||||||
lines.push('git ' + command);
|
|
||||||
_.each(commandOptions, function(vals, optionName) {
|
|
||||||
lines.push('\t ' + optionName);
|
|
||||||
}, this);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// format and throw
|
|
||||||
var msg = lines.join('\n');
|
|
||||||
msg = msg.replace(/\t/g, ' ');
|
|
||||||
throw new CommandResult({
|
|
||||||
msg: msg
|
|
||||||
});
|
|
||||||
}],
|
|
||||||
[/^refresh$/, function() {
|
[/^refresh$/, function() {
|
||||||
var events = require('../app').getEvents();
|
var events = require('../app').getEvents();
|
||||||
|
|
||||||
|
@ -78,4 +39,4 @@ var sandboxInstantCommands = [
|
||||||
}]
|
}]
|
||||||
];
|
];
|
||||||
|
|
||||||
exports.sandboxInstantCommands = sandboxInstantCommands;
|
exports.instantCommands = instantCommands;
|
||||||
|
|
|
@ -6,7 +6,7 @@ var Errors = require('../util/errors');
|
||||||
var GitCommands = require('../git/commands');
|
var GitCommands = require('../git/commands');
|
||||||
var GitOptionParser = GitCommands.GitOptionParser;
|
var GitOptionParser = GitCommands.GitOptionParser;
|
||||||
|
|
||||||
var sandboxInstantCommands = require('../level/sandboxCommands').sandboxInstantCommands;
|
var ParseWaterfall = require('../level/parseWaterfall').ParseWaterfall;
|
||||||
|
|
||||||
var CommandProcessError = Errors.CommandProcessError;
|
var CommandProcessError = Errors.CommandProcessError;
|
||||||
var GitError = Errors.GitError;
|
var GitError = Errors.GitError;
|
||||||
|
@ -18,38 +18,47 @@ var Command = Backbone.Model.extend({
|
||||||
status: 'inqueue',
|
status: 'inqueue',
|
||||||
rawStr: null,
|
rawStr: null,
|
||||||
result: '',
|
result: '',
|
||||||
|
createTime: null,
|
||||||
|
|
||||||
error: null,
|
error: null,
|
||||||
warnings: null,
|
warnings: null,
|
||||||
|
parseWaterfall: new ParseWaterfall(),
|
||||||
|
|
||||||
generalArgs: null,
|
generalArgs: null,
|
||||||
supportedMap: null,
|
supportedMap: null,
|
||||||
options: null,
|
options: null,
|
||||||
method: null,
|
method: null
|
||||||
|
|
||||||
createTime: null
|
|
||||||
},
|
},
|
||||||
|
|
||||||
validateAtInit: function() {
|
initialize: function(options) {
|
||||||
// weird things happen with defaults if you dont
|
this.initDefaults();
|
||||||
// make new objects
|
this.validateAtInit();
|
||||||
this.set('generalArgs', []);
|
|
||||||
this.set('supportedMap', {});
|
|
||||||
this.set('warnings', []);
|
|
||||||
|
|
||||||
if (this.get('rawStr') === null) {
|
|
||||||
throw new Error('Give me a string!');
|
|
||||||
}
|
|
||||||
if (!this.get('createTime')) {
|
|
||||||
this.set('createTime', new Date().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.on('change:error', this.errorChanged, this);
|
this.on('change:error', this.errorChanged, this);
|
||||||
// catch errors on init
|
// catch errors on init
|
||||||
if (this.get('error')) {
|
if (this.get('error')) {
|
||||||
this.errorChanged();
|
this.errorChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.parseOrCatch();
|
||||||
|
},
|
||||||
|
|
||||||
|
initDefaults: function() {
|
||||||
|
// weird things happen with defaults if you dont
|
||||||
|
// make new objects
|
||||||
|
this.set('generalArgs', []);
|
||||||
|
this.set('supportedMap', {});
|
||||||
|
this.set('warnings', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
validateAtInit: function() {
|
||||||
|
if (this.get('rawStr') === null) {
|
||||||
|
throw new Error('Give me a string!');
|
||||||
|
}
|
||||||
|
if (!this.get('createTime')) {
|
||||||
|
this.set('createTime', new Date().toString());
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setResult: function(msg) {
|
setResult: function(msg) {
|
||||||
|
@ -71,19 +80,26 @@ var Command = Backbone.Model.extend({
|
||||||
return '<p>' + i + this.get('warnings').join('</p><p>' + i) + '</p>';
|
return '<p>' + i + this.get('warnings').join('</p><p>' + i) + '</p>';
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
|
||||||
this.validateAtInit();
|
|
||||||
this.parseOrCatch();
|
|
||||||
},
|
|
||||||
|
|
||||||
parseOrCatch: function() {
|
parseOrCatch: function() {
|
||||||
|
this.expandShortcuts(this.get('rawStr'));
|
||||||
try {
|
try {
|
||||||
this.parse();
|
this.processInstants();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Errors.filterError(err);
|
Errors.filterError(err);
|
||||||
// errorChanged() will handle status and all of that
|
// errorChanged() will handle status and all of that
|
||||||
this.set('error', err);
|
this.set('error', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.parseAll()) {
|
||||||
|
// something in our parse waterfall succeeded
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we reach here, this command is not supported :-/
|
||||||
|
this.set('error', new CommandProcessError({
|
||||||
|
msg: 'The command "' + this.get('rawStr') + '" isn\'t supported, sorry!'
|
||||||
|
})
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
errorChanged: function() {
|
errorChanged: function() {
|
||||||
|
@ -103,65 +119,35 @@ var Command = Backbone.Model.extend({
|
||||||
this.set('result', this.get('error').toResult());
|
this.set('result', this.get('error').toResult());
|
||||||
},
|
},
|
||||||
|
|
||||||
parse: function() {
|
expandShortcuts: function(str) {
|
||||||
|
str = this.get('parseWaterfall').expandAllShortcuts(str);
|
||||||
|
this.set('rawStr', str);
|
||||||
|
},
|
||||||
|
|
||||||
|
processInstants: function() {
|
||||||
var str = this.get('rawStr');
|
var str = this.get('rawStr');
|
||||||
// first if the string is empty, they just want a blank line
|
// first if the string is empty, they just want a blank line
|
||||||
if (!str.length) {
|
if (!str.length) {
|
||||||
throw new CommandResult({msg: ""});
|
throw new CommandResult({msg: ""});
|
||||||
}
|
}
|
||||||
|
|
||||||
str = GitCommands.expandShortcut(str);
|
// then instant commands that will throw
|
||||||
this.set('rawStr', str);
|
this.get('parseWaterfall').processAllInstants(str);
|
||||||
|
|
||||||
// then check if it's one of our sandbox commands
|
|
||||||
_.each(sandboxInstantCommands, function(tuple) {
|
|
||||||
var regex = tuple[0];
|
|
||||||
var results = regex.exec(str);
|
|
||||||
if (results) {
|
|
||||||
// this will throw a result
|
|
||||||
tuple[1](results);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// see if begins with git
|
|
||||||
if (str.slice(0,3) !== 'git') {
|
|
||||||
throw new CommandProcessError({
|
|
||||||
msg: 'That command is not supported, sorry!'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok, we have a (probably) valid command. actually parse it
|
|
||||||
this.gitParse(str);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
gitParse: function(str) {
|
parseAll: function() {
|
||||||
// now slice off command part
|
var str = this.get('rawStr');
|
||||||
var fullCommand = str.slice('git '.length);
|
var results = this.get('parseWaterfall').parseAll(str);
|
||||||
|
|
||||||
// see if we support this particular command
|
if (!results) {
|
||||||
_.each(GitCommands.getRegexMap(), function(regex, method) {
|
// nothing parsed successfully
|
||||||
if (regex.exec(fullCommand)) {
|
return false;
|
||||||
this.set('options', fullCommand.slice(method.length + 1));
|
|
||||||
this.set('method', method);
|
|
||||||
// we should stop iterating, but the regex will only match
|
|
||||||
// one command in practice. we could stop iterating if we used
|
|
||||||
// jqeurys for each but im using underscore (for no real reason other
|
|
||||||
// than style)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_.each(results.toSet, function(obj, key) {
|
||||||
|
this.set(key, obj);
|
||||||
}, this);
|
}, this);
|
||||||
|
return true;
|
||||||
if (!this.get('method')) {
|
|
||||||
throw new CommandProcessError({
|
|
||||||
msg: "Sorry, this demo does not support that git command: " + fullCommand
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse off the options and assemble the map / general args
|
|
||||||
var options = new GitOptionParser(this.get('method'), this.get('options'));
|
|
||||||
|
|
||||||
// steal these away so we can be completely JSON
|
|
||||||
this.set('generalArgs', options.generalArgs);
|
|
||||||
this.set('supportedMap', options.supportedMap);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
4
todo.txt
4
todo.txt
|
@ -35,6 +35,10 @@ Big Bugs to fix:
|
||||||
Done things:
|
Done things:
|
||||||
(I only started this on Dec 17th 2012 to get a better sense of what was done)
|
(I only started this on Dec 17th 2012 to get a better sense of what was done)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
[x] ok fuckit here is the deal. Command model has minimal logic -- it calls
|
||||||
|
to a parse waterfall that expands any shortcuts needed, handles any instant
|
||||||
|
commands, and then finally will handle the dispatching. I think this will be
|
||||||
|
really nice :D
|
||||||
[x] disabled map for levels
|
[x] disabled map for levels
|
||||||
[x] better click events on branches and commits
|
[x] better click events on branches and commits
|
||||||
[x] change to returning a promise for multiview
|
[x] change to returning a promise for multiview
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue