big refactor looking a lot better now

This commit is contained in:
Peter Cottle 2013-07-28 12:12:00 -07:00
parent e422bdb181
commit 0aadae766f
12 changed files with 1539 additions and 1355 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

1
build/bundle.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -439,7 +439,7 @@
For a much easier time perusing the source, see the individual files at: For a much easier time perusing the source, see the individual files at:
https://github.com/pcottle/learnGitBranching https://github.com/pcottle/learnGitBranching
--> -->
<script src="build/bundle.min.f16f04ad.js"></script> <script src="build/bundle.js"></script>
<!-- The advantage of github pages: super-easy, simple, slick static hostic. <!-- The advantage of github pages: super-easy, simple, slick static hostic.
The downside? No raw logs to parse for analytics, so I have to include The downside? No raw logs to parse for analytics, so I have to include

View file

@ -7,347 +7,510 @@ var Errors = require('../util/errors');
var GitError = Errors.GitError; var GitError = Errors.GitError;
var CommandResult = Errors.CommandResult; var CommandResult = Errors.CommandResult;
var commandConfig;
var Commands = { var Commands = {
commit: function(engine, command) { execute: function(name, engine, commandObj) {
var commandOptions = command.getSupportedMap(); if (!commandConfig[name]) {
command.acceptNoGeneralArgs(); throw new Error('i dont have a command for ' + name);
if (commandOptions['-am'] && (
commandOptions['-a'] || commandOptions['-m'])) {
throw new GitError({
msg: intl.str('git-error-options')
});
} }
commandConfig[name].execute.call(this, engine, commandObj);
var msg = null;
var args = null;
if (commandOptions['-a']) {
command.addWarning(intl.str('git-warning-add'));
}
if (commandOptions['-am']) {
args = commandOptions['-am'];
command.validateArgBounds(args, 1, 1, '-am');
msg = args[0];
}
if (commandOptions['-m']) {
args = commandOptions['-m'];
command.validateArgBounds(args, 1, 1, '-m');
msg = args[0];
}
var newCommit = engine.commit({
isAmend: commandOptions['--amend']
});
if (msg) {
msg = msg
.replace(/&quot;/g, '"')
.replace(/^"/g, '')
.replace(/"$/g, '');
newCommit.set('commitMessage', msg);
}
var promise = engine.animationFactory.playCommitBirthPromiseAnimation(
newCommit,
engine.gitVisuals
);
engine.animationQueue.thenFinish(promise);
}, },
cherrypick: function(engine, command) { getRegex: function(name) {
var commandOptions = command.getSupportedMap(); name = name.replace(/-/g, ''); // ugh cherry-pick @____@
var generalArgs = command.getGeneralArgs(); if (!commandConfig[name]) {
throw new Error('i dont have a regex for ' + name);
}
return commandConfig[name].regex;
},
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE); isCommandSupported: function(name) {
return !!commandConfig[name];
},
var set = engine.getUpstreamSet('HEAD'); getShortcutMap: function() {
// first resolve all the refs (as an error check) var map = {};
var toCherrypick = _.map(generalArgs, function(arg) { this.loop(function(config, name) {
var commit = engine.getCommitFromRef(arg); if (!config.sc) {
// and check that its not upstream return;
if (set[commit.get('id')]) { }
map['git ' + name] = config.sc;
}, this);
return map;
},
getOptionMap: function() {
var optionMap = {};
this.loop(function(config, name) {
var displayName = config.displayName || name;
var thisMap = {};
// start all options off as disabled
_.each(config.options, function(option) {
thisMap[option] = false;
});
optionMap[displayName] = thisMap;
});
return optionMap;
},
getRegexMap: function() {
var map = {};
this.loop(function(config, name) {
var displayName = 'git ' + (config.displayName || name);
map[displayName] = config.regex;
});
return map;
},
/**
* which commands count for the git golf game
*/
getCommandsThatCount: function() {
var counted = [];
this.loop(function(config, name) {
if (config.dontCountForGolf) {
return;
}
counted.push(name);
});
return counted;
},
loop: function(callback, context) {
_.each(commandConfig, callback);
}
};
commandConfig = {
commit: {
sc: /^(gc|git ci)($|\s)/,
regex: /^git +commit($|\s)/,
options: [
'--amend',
'-a',
'-am',
'-m'
],
execute: function(engine, command) {
var commandOptions = command.getSupportedMap();
command.acceptNoGeneralArgs();
if (commandOptions['-am'] && (
commandOptions['-a'] || commandOptions['-m'])) {
throw new GitError({ throw new GitError({
msg: intl.str( msg: intl.str('git-error-options')
'git-error-already-exists',
{ commit: commit.get('id') }
)
}); });
} }
return commit;
}, this);
engine.setupCherrypickChain(toCherrypick); var msg = null;
}, var args = null;
pull: function(engine, command) {
if (!engine.hasOrigin()) {
throw new GitError({
msg: intl.str('git-error-origin-required')
});
}
var commandOptions = command.getSupportedMap();
command.acceptNoGeneralArgs();
engine.pull({
isRebase: commandOptions['--rebase']
});
},
fakeTeamwork: function(engine, command) {
var generalArgs = command.getGeneralArgs();
if (!engine.hasOrigin()) {
throw new GitError({
msg: intl.str('git-error-origin-required')
});
}
command.validateArgBounds(generalArgs, 0, 2);
// allow formats of: git Faketeamwork 2 or git Faketeamwork side 3
var branch = (engine.origin.refs[generalArgs[0]]) ?
generalArgs[0] : 'master';
var numToMake = parseInt(generalArgs[0], 10) || generalArgs[1] || 1;
// make sure its a branch and exists
var destBranch = engine.origin.resolveID(branch);
if (destBranch.get('type') !== 'branch') {
throw new GitError({
msg: intl.str('git-error-options')
});
}
engine.fakeTeamwork(numToMake, branch);
},
clone: function(engine, command) {
command.acceptNoGeneralArgs();
engine.makeOrigin(engine.printTree());
},
fetch: function(engine, command) {
if (!engine.hasOrigin()) {
throw new GitError({
msg: intl.str('git-error-origin-required')
});
}
command.acceptNoGeneralArgs();
engine.fetch();
},
branch: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
var args = null;
// handle deletion first
if (commandOptions['-d'] || commandOptions['-D']) {
var names = commandOptions['-d'] || commandOptions['-D'];
command.validateArgBounds(names, 1, Number.MAX_VALUE, '-d');
_.each(names, function(name) {
engine.deleteBranch(name);
});
return;
}
if (commandOptions['--contains']) {
args = commandOptions['--contains'];
command.validateArgBounds(args, 1, 1, '--contains');
engine.printBranchesWithout(args[0]);
return;
}
if (commandOptions['-f']) {
args = commandOptions['-f'];
command.twoArgsImpliedHead(args, '-f');
// we want to force a branch somewhere
engine.forceBranch(args[0], args[1]);
return;
}
if (generalArgs.length === 0) {
var branches;
if (commandOptions['-a']) { if (commandOptions['-a']) {
branches = engine.getBranches(); command.addWarning(intl.str('git-warning-add'));
} else if (commandOptions['-r']) {
branches = engine.getRemoteBranches();
} else {
branches = engine.getLocalBranches();
} }
engine.printBranches(branches);
return; if (commandOptions['-am']) {
args = commandOptions['-am'];
command.validateArgBounds(args, 1, 1, '-am');
msg = args[0];
}
if (commandOptions['-m']) {
args = commandOptions['-m'];
command.validateArgBounds(args, 1, 1, '-m');
msg = args[0];
}
var newCommit = engine.commit({
isAmend: commandOptions['--amend']
});
if (msg) {
msg = msg
.replace(/&quot;/g, '"')
.replace(/^"/g, '')
.replace(/"$/g, '');
newCommit.set('commitMessage', msg);
}
var promise = engine.animationFactory.playCommitBirthPromiseAnimation(
newCommit,
engine.gitVisuals
);
engine.animationQueue.thenFinish(promise);
} }
command.twoArgsImpliedHead(generalArgs);
engine.branch(generalArgs[0], generalArgs[1]);
}, },
add: function() { cherrypick: {
throw new CommandResult({ displayName: 'cherry-pick',
msg: intl.str('git-error-staging') regex: /^git +cherry-pick($|\s)/,
}); execute: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE);
var set = engine.getUpstreamSet('HEAD');
// first resolve all the refs (as an error check)
var toCherrypick = _.map(generalArgs, function(arg) {
var commit = engine.getCommitFromRef(arg);
// and check that its not upstream
if (set[commit.get('id')]) {
throw new GitError({
msg: intl.str(
'git-error-already-exists',
{ commit: commit.get('id') }
)
});
}
return commit;
}, this);
engine.setupCherrypickChain(toCherrypick);
}
}, },
reset: function(engine, command) { pull: {
var commandOptions = command.getSupportedMap(); regex: /^git +pull($|\s)/,
var generalArgs = command.getGeneralArgs(); options: [
'--rebase'
],
execute: function(engine, command) {
if (!engine.hasOrigin()) {
throw new GitError({
msg: intl.str('git-error-origin-required')
});
}
if (commandOptions['--soft']) { var commandOptions = command.getSupportedMap();
throw new GitError({ command.acceptNoGeneralArgs();
engine.pull({
isRebase: commandOptions['--rebase']
});
}
},
fakeTeamwork: {
regex: /^git +fakeTeamwork($|\s)/,
execute: function(engine, command) {
var generalArgs = command.getGeneralArgs();
if (!engine.hasOrigin()) {
throw new GitError({
msg: intl.str('git-error-origin-required')
});
}
command.validateArgBounds(generalArgs, 0, 2);
// allow formats of: git Faketeamwork 2 or git Faketeamwork side 3
var branch = (engine.origin.refs[generalArgs[0]]) ?
generalArgs[0] : 'master';
var numToMake = parseInt(generalArgs[0], 10) || generalArgs[1] || 1;
// make sure its a branch and exists
var destBranch = engine.origin.resolveID(branch);
if (destBranch.get('type') !== 'branch') {
throw new GitError({
msg: intl.str('git-error-options')
});
}
engine.fakeTeamwork(numToMake, branch);
}
},
clone: {
regex: /^git +clone *?$/,
execute: function(engine, command) {
command.acceptNoGeneralArgs();
engine.makeOrigin(engine.printTree());
}
},
fetch: {
regex: /^git +fetch *?$/,
execute: function(engine, command) {
if (!engine.hasOrigin()) {
throw new GitError({
msg: intl.str('git-error-origin-required')
});
}
command.acceptNoGeneralArgs();
engine.fetch();
}
},
branch: {
sc: /^(gb|git br)($|\s)/,
regex: /^git +branch($|\s)/,
options: [
'-d',
'-D',
'-f',
'-a',
'-r',
'--contains'
],
execute: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
var args = null;
// handle deletion first
if (commandOptions['-d'] || commandOptions['-D']) {
var names = commandOptions['-d'] || commandOptions['-D'];
command.validateArgBounds(names, 1, Number.MAX_VALUE, '-d');
_.each(names, function(name) {
engine.deleteBranch(name);
});
return;
}
if (commandOptions['--contains']) {
args = commandOptions['--contains'];
command.validateArgBounds(args, 1, 1, '--contains');
engine.printBranchesWithout(args[0]);
return;
}
if (commandOptions['-f']) {
args = commandOptions['-f'];
command.twoArgsImpliedHead(args, '-f');
// we want to force a branch somewhere
engine.forceBranch(args[0], args[1]);
return;
}
if (generalArgs.length === 0) {
var branches;
if (commandOptions['-a']) {
branches = engine.getBranches();
} else if (commandOptions['-r']) {
branches = engine.getRemoteBranches();
} else {
branches = engine.getLocalBranches();
}
engine.printBranches(branches);
return;
}
command.twoArgsImpliedHead(generalArgs);
engine.branch(generalArgs[0], generalArgs[1]);
}
},
add: {
dontCountForGolf: true,
sc: /^ga($|\s)/,
regex: /^git +add($|\s)/,
execute: function() {
throw new CommandResult({
msg: intl.str('git-error-staging') msg: intl.str('git-error-staging')
}); });
} }
if (commandOptions['--hard']) { },
command.addWarning(
intl.str('git-warning-hard') reset: {
regex: /^git +reset($|\s)/,
options: [
'--hard',
'--soft'
],
execute: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
if (commandOptions['--soft']) {
throw new GitError({
msg: intl.str('git-error-staging')
});
}
if (commandOptions['--hard']) {
command.addWarning(
intl.str('git-warning-hard')
);
// dont absorb the arg off of --hard
generalArgs = generalArgs.concat(commandOptions['--hard']);
}
command.validateArgBounds(generalArgs, 1, 1);
if (engine.getDetachedHead()) {
throw new GitError({
msg: intl.str('git-error-reset-detached')
});
}
engine.reset(generalArgs[0]);
}
},
revert: {
regex: /^git +revert($|\s)/,
execute: function(engine, command) {
var generalArgs = command.getGeneralArgs();
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE);
engine.revert(generalArgs);
}
},
merge: {
regex: /^git +merge($|\s)/,
execute: function(engine, command) {
var generalArgs = command.getGeneralArgs();
command.validateArgBounds(generalArgs, 1, 1);
var newCommit = engine.merge(generalArgs[0]);
if (newCommit === undefined) {
// its just a fast forwrard
engine.animationFactory.refreshTree(
engine.animationQueue, engine.gitVisuals
);
return;
}
engine.animationFactory.genCommitBirthAnimation(
engine.animationQueue, newCommit, engine.gitVisuals
); );
// dont absorb the arg off of --hard
generalArgs = generalArgs.concat(commandOptions['--hard']);
} }
command.validateArgBounds(generalArgs, 1, 1);
if (engine.getDetachedHead()) {
throw new GitError({
msg: intl.str('git-error-reset-detached')
});
}
engine.reset(generalArgs[0]);
}, },
revert: function(engine, command) { log: {
var generalArgs = command.getGeneralArgs(); dontCountForGolf: true,
regex: /^git +log($|\s)/,
execute: function(engine, command) {
var generalArgs = command.getGeneralArgs();
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE); if (generalArgs.length == 2) {
engine.revert(generalArgs); // do fancy git log branchA ^branchB
}, if (generalArgs[1][0] == '^') {
engine.logWithout(generalArgs[0], generalArgs[1]);
merge: function(engine, command) { } else {
var generalArgs = command.getGeneralArgs(); throw new GitError({
command.validateArgBounds(generalArgs, 1, 1); msg: intl.str('git-error-options')
});
var newCommit = engine.merge(generalArgs[0]); }
if (newCommit === undefined) {
// its just a fast forwrard
engine.animationFactory.refreshTree(
engine.animationQueue, engine.gitVisuals
);
return;
}
engine.animationFactory.genCommitBirthAnimation(
engine.animationQueue, newCommit, engine.gitVisuals
);
},
log: function(engine, command) {
var generalArgs = command.getGeneralArgs();
if (generalArgs.length == 2) {
// do fancy git log branchA ^branchB
if (generalArgs[1][0] == '^') {
engine.logWithout(generalArgs[0], generalArgs[1]);
} else {
throw new GitError({
msg: intl.str('git-error-options')
});
}
}
command.oneArgImpliedHead(generalArgs);
engine.log(generalArgs[0]);
},
show: function(engine, command) {
var generalArgs = command.getGeneralArgs();
command.oneArgImpliedHead(generalArgs);
engine.show(generalArgs[0]);
},
rebase: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
if (commandOptions['-i']) {
var args = commandOptions['-i'];
command.twoArgsImpliedHead(args, ' -i');
engine.rebaseInteractive(args[0], args[1]);
return;
}
command.twoArgsImpliedHead(generalArgs);
engine.rebase(generalArgs[0], generalArgs[1]);
},
status: function(engine) {
// no parsing at all
engine.status();
},
checkout: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
var args = null;
if (commandOptions['-b']) {
if (generalArgs.length) {
throw new GitError({
msg: intl.str('git-error-options')
});
} }
// the user is really trying to just make a branch and then switch to it. so first: command.oneArgImpliedHead(generalArgs);
args = commandOptions['-b']; engine.log(generalArgs[0]);
command.twoArgsImpliedHead(args, '-b');
var validId = engine.validateBranchName(args[0]);
engine.branch(validId, args[1]);
engine.checkout(validId);
return;
} }
},
if (commandOptions['-']) { show: {
// get the heads last location dontCountForGolf: true,
var lastPlace = engine.HEAD.get('lastLastTarget'); regex: /^git +show($|\s)/,
if (!lastPlace) { execute: function(engine, command) {
var generalArgs = command.getGeneralArgs();
command.oneArgImpliedHead(generalArgs);
engine.show(generalArgs[0]);
}
},
rebase: {
sc: /^gr($|\s)/,
options: [
'-i'
],
regex: /^git +rebase($|\s)/,
execute: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
if (commandOptions['-i']) {
var args = commandOptions['-i'];
command.twoArgsImpliedHead(args, ' -i');
engine.rebaseInteractive(args[0], args[1]);
return;
}
command.twoArgsImpliedHead(generalArgs);
engine.rebase(generalArgs[0], generalArgs[1]);
}
},
status: {
dontCountForGolf: true,
sc: /^(gst|gs|git st)($|\s)/,
regex: /^git +status($|\s)/,
execute: function(engine) {
// no parsing at all
engine.status();
}
},
checkout: {
sc: /^(go|git co)($|\s)/,
regex: /^git +checkout($|\s)/,
options: [
'-b',
'-B',
'-'
],
execute: function(engine, command) {
var commandOptions = command.getSupportedMap();
var generalArgs = command.getGeneralArgs();
var args = null;
if (commandOptions['-b']) {
if (generalArgs.length) {
throw new GitError({
msg: intl.str('git-error-options')
});
}
// the user is really trying to just make a branch and then switch to it. so first:
args = commandOptions['-b'];
command.twoArgsImpliedHead(args, '-b');
var validId = engine.validateBranchName(args[0]);
engine.branch(validId, args[1]);
engine.checkout(validId);
return;
}
if (commandOptions['-']) {
// get the heads last location
var lastPlace = engine.HEAD.get('lastLastTarget');
if (!lastPlace) {
throw new GitError({
msg: intl.str('git-result-nothing')
});
}
engine.HEAD.set('target', lastPlace);
return;
}
if (commandOptions['-B']) {
args = commandOptions['-B'];
command.twoArgsImpliedHead(args, '-B');
engine.forceBranch(args[0], args[1]);
engine.checkout(args[0]);
return;
}
command.validateArgBounds(generalArgs, 1, 1);
engine.checkout(engine.crappyUnescape(generalArgs[0]));
}
},
push: {
regex: /^git +push($|\s)/,
execute: function(engine, command) {
if (!engine.hasOrigin()) {
throw new GitError({ throw new GitError({
msg: intl.str('git-result-nothing') msg: intl.str('git-error-origin-required')
}); });
} }
engine.HEAD.set('target', lastPlace); command.acceptNoGeneralArgs();
return; engine.push();
} }
}
if (commandOptions['-B']) {
args = commandOptions['-B'];
command.twoArgsImpliedHead(args, '-B');
engine.forceBranch(args[0], args[1]);
engine.checkout(args[0]);
return;
}
command.validateArgBounds(generalArgs, 1, 1);
engine.checkout(engine.crappyUnescape(generalArgs[0]));
},
push: function(engine, command) {
if (!engine.hasOrigin()) {
throw new GitError({
msg: intl.str('git-error-origin-required')
});
}
command.acceptNoGeneralArgs();
engine.push();
},
noComma: 123
}; };
module.exports = Commands; module.exports = Commands;

View file

@ -1,24 +1,15 @@
var _ = require('underscore'); var _ = require('underscore');
var intl = require('../intl'); var intl = require('../intl');
var Commands = require('../commands');
var Errors = require('../util/errors'); var Errors = require('../util/errors');
var CommandProcessError = Errors.CommandProcessError; var CommandProcessError = Errors.CommandProcessError;
var GitError = Errors.GitError; var GitError = Errors.GitError;
var Warning = Errors.Warning; var Warning = Errors.Warning;
var CommandResult = Errors.CommandResult; var CommandResult = Errors.CommandResult;
var shortcutMap = {
'git commit': /^(gc|git ci)($|\s)/,
'git add': /^ga($|\s)/,
'git checkout': /^(go|git co)($|\s)/,
'git rebase': /^gr($|\s)/,
'git branch': /^(gb|git br)($|\s)/,
'git status': /^(gst|gs|git st)($|\s)/,
'git help': /^git$/
};
var instantCommands = [ var instantCommands = [
[/^git help($|\s)/, function() { [/^(git help($|\s)|git$)/, function() {
var lines = [ var lines = [
intl.str('git-version'), intl.str('git-version'),
'<br/>', '<br/>',
@ -28,8 +19,7 @@ var instantCommands = [
intl.str('git-supported-commands'), intl.str('git-supported-commands'),
'<br/>' '<br/>'
]; ];
var commands = GitOptionParser.prototype.getMasterOptionMap(); var commands = Commands.getOptionMap();
// build up a nice display of what we support // build up a nice display of what we support
_.each(commands, function(commandOptions, command) { _.each(commands, function(commandOptions, command) {
lines.push('git ' + command); lines.push('git ' + command);
@ -47,59 +37,12 @@ var instantCommands = [
}] }]
]; ];
var regexMap = {
// ($|\s) means that we either have to end the string
// after the command or there needs to be a space for options
'git commit': /^git +commit($|\s)/,
'git add': /^git +add($|\s)/,
'git checkout': /^git +checkout($|\s)/,
'git rebase': /^git +rebase($|\s)/,
'git reset': /^git +reset($|\s)/,
'git branch': /^git +branch($|\s)/,
'git revert': /^git +revert($|\s)/,
'git log': /^git +log($|\s)/,
'git merge': /^git +merge($|\s)/,
'git show': /^git +show($|\s)/,
'git status': /^git +status($|\s)/,
'git cherry-pick': /^git +cherry-pick($|\s)/,
'git fakeTeamwork': /^git +fakeTeamwork($|\s)/,
'git fetch': /^git +fetch *?$/,
'git pull': /^git +pull($|\s)/,
'git push': /^git +push($|\s)/,
'git clone': /^git +clone *?$/
};
/**
* Maintain this list to keep track of which commands we track
* for the "git golf" minigame
*/
var commandsThatCount = (function() {
var toCount = [
'git commit',
'git checkout',
'git rebase',
'git reset',
'git branch',
'git revert',
'git merge',
'git clone',
'git cherry-pick'
];
var whichCountMap = {};
_.each(toCount, function(method) {
if (!regexMap[method]) { throw new Error('wut no regex'); }
whichCountMap[method] = regexMap[method];
});
return whichCountMap;
})();
var parse = function(str) { var parse = function(str) {
var method; var method;
var options; var options;
// see if we support this particular command // see if we support this particular command
_.each(regexMap, function(regex, thisMethod) { _.each(Commands.getRegexMap(), function(regex, thisMethod) {
if (regex.exec(str)) { if (regex.exec(str)) {
options = str.slice(thisMethod.length + 1); options = str.slice(thisMethod.length + 1);
method = thisMethod.slice('git '.length); method = thisMethod.slice('git '.length);
@ -112,7 +55,7 @@ var parse = function(str) {
// we support this command! // we support this command!
// parse off the options and assemble the map / general args // parse off the options and assemble the map / general args
var parsedOptions = new GitOptionParser(method, options); var parsedOptions = new CommandOptionParser(method, options);
return { return {
toSet: { toSet: {
generalArgs: parsedOptions.generalArgs, generalArgs: parsedOptions.generalArgs,
@ -125,13 +68,13 @@ var parse = function(str) {
}; };
/** /**
* GitOptionParser * CommandOptionParser
*/ */
function GitOptionParser(method, options) { function CommandOptionParser(method, options) {
this.method = method; this.method = method;
this.rawOptions = options; this.rawOptions = options;
this.supportedMap = this.getMasterOptionMap()[method]; this.supportedMap = Commands.getOptionMap()[method];
if (this.supportedMap === undefined) { if (this.supportedMap === undefined) {
throw new Error('No option map for ' + method); throw new Error('No option map for ' + method);
} }
@ -140,61 +83,27 @@ function GitOptionParser(method, options) {
this.explodeAndSet(); this.explodeAndSet();
} }
GitOptionParser.prototype.getMasterOptionMap = function() { var optionMap = {};
// here a value of false means that we support it, even if its just a Commands.loop(function(config, name) {
// pass-through option. If the value is not here (aka will be undefined var displayName = config.displayName || name;
// when accessed), we do not support it. if (optionMap[displayName] !== undefined) {
return { return;
commit: { }
'--amend': false,
'-a': false, // warning
'-am': false, // warning
'-m': false
},
status: {},
log: {},
add: {},
'cherry-pick': {},
branch: {
'-d': false,
'-D': false,
'-f': false,
'-a': false,
'-r': false,
'--contains': false
},
checkout: {
'-b': false,
'-B': false,
'-': false
},
reset: {
'--hard': false,
'--soft': false // this will raise an error but we catch it in gitEngine
},
merge: {},
rebase: {
'-i': false // the mother of all options
},
revert: {},
show: {},
clone: {},
fetch: {},
pull: {
'--rebase': false
},
push: {},
fakeTeamwork: {}
};
};
GitOptionParser.prototype.explodeAndSet = function() { var thisMap = {};
_.each(config.options, function(option) {
thisMap[option] = false;
});
optionMap[displayName] = thisMap;
});
CommandOptionParser.prototype.explodeAndSet = function() {
// TODO -- this is ugly
// split on spaces, except when inside quotes // split on spaces, except when inside quotes
var exploded = this.rawOptions.match(/('.*?'|".*?"|\S+)/g) || []; var exploded = this.rawOptions.match(/('.*?'|".*?"|\S+)/g) || [];
for (var i = 0; i < exploded.length; i++) { for (var i = 0; i < exploded.length; i++) {
var part = exploded[i]; var part = exploded[i];
if (part.slice(0,1) == '-') { if (part.slice(0,1) == '-') {
// it's an option, check supportedMap // it's an option, check supportedMap
if (this.supportedMap[part] === undefined) { if (this.supportedMap[part] === undefined) {
@ -224,9 +133,6 @@ GitOptionParser.prototype.explodeAndSet = function() {
} }
}; };
exports.shortcutMap = shortcutMap;
exports.commandsThatCount = commandsThatCount;
exports.instantCommands = instantCommands; exports.instantCommands = instantCommands;
exports.parse = parse; exports.parse = parse;
exports.regexMap = regexMap;

View file

@ -1732,7 +1732,7 @@ GitEngine.prototype.dispatch = function(command, deferred) {
try { try {
var methodName = command.get('method').replace(/-/g, ''); var methodName = command.get('method').replace(/-/g, '');
Commands[methodName](this, this.command); Commands.execute(methodName, this, this.command);
} catch (err) { } catch (err) {
this.filterError(err); this.filterError(err);
// short circuit animation by just setting error and returning // short circuit animation by just setting error and returning

View file

@ -2,6 +2,7 @@ var _ = require('underscore');
var intl = require('../intl'); var intl = require('../intl');
var GitCommands = require('../git/commands'); var GitCommands = require('../git/commands');
var Commands = require('../commands');
var Errors = require('../util/errors'); var Errors = require('../util/errors');
var GitError = Errors.GitError; var GitError = Errors.GitError;
@ -26,7 +27,7 @@ DisabledMap.prototype.getInstantCommands = function() {
}; };
_.each(this.disabledMap, function(val, disabledCommand) { _.each(this.disabledMap, function(val, disabledCommand) {
var gitRegex = GitCommands.regexMap[disabledCommand]; var gitRegex = Commands.getRegexMap()[disabledCommand];
if (!gitRegex) { if (!gitRegex) {
throw new Error('wuttttt this disbaled command' + disabledCommand + throw new Error('wuttttt this disbaled command' + disabledCommand +
' has no regex matching'); ' has no regex matching');

View file

@ -10,12 +10,14 @@ var log = require('../log');
var Errors = require('../util/errors'); var Errors = require('../util/errors');
var Sandbox = require('../level/sandbox').Sandbox; var Sandbox = require('../level/sandbox').Sandbox;
var Constants = require('../util/constants'); var Constants = require('../util/constants');
var Commands = require('../commands');
var Visualization = require('../visuals/visualization').Visualization; var Visualization = require('../visuals/visualization').Visualization;
var ParseWaterfall = require('../level/parseWaterfall').ParseWaterfall; var ParseWaterfall = require('../level/parseWaterfall').ParseWaterfall;
var DisabledMap = require('../level/disabledMap').DisabledMap; var DisabledMap = require('../level/disabledMap').DisabledMap;
var Command = require('../models/commandModel').Command; var Command = require('../models/commandModel').Command;
var GitShim = require('../git/gitShim').GitShim; var GitShim = require('../git/gitShim').GitShim;
var GitCommands = require('../git/commands');
var MultiView = require('../views/multiView').MultiView; var MultiView = require('../views/multiView').MultiView;
var CanvasTerminalHolder = require('../views').CanvasTerminalHolder; var CanvasTerminalHolder = require('../views').CanvasTerminalHolder;
@ -44,7 +46,6 @@ var Level = Sandbox.extend({
this.level = options.level; this.level = options.level;
this.gitCommandsIssued = []; this.gitCommandsIssued = [];
this.commandsThatCount = this.getCommandsThatCount();
this.solved = false; this.solved = false;
this.initGoalData(options); this.initGoalData(options);
@ -297,11 +298,6 @@ var Level = Sandbox.extend({
}); });
}, },
getCommandsThatCount: function() {
var GitCommands = require('../git/commands');
return GitCommands.commandsThatCount;
},
undo: function() { undo: function() {
this.gitCommandsIssued.pop(); this.gitCommandsIssued.pop();
Level.__super__.undo.apply(this, arguments); Level.__super__.undo.apply(this, arguments);
@ -314,7 +310,8 @@ var Level = Sandbox.extend({
} }
var matched = false; var matched = false;
_.each(this.commandsThatCount, function(regex) { _.each(Commands.getCommandsThatCount(), function(name) {
var regex = Commands.getRegex(name);
matched = matched || regex.test(command.get('rawStr')); matched = matched || regex.test(command.get('rawStr'));
}); });
if (matched) { if (matched) {

View file

@ -1,6 +1,7 @@
var _ = require('underscore'); var _ = require('underscore');
var GitCommands = require('../git/commands'); var GitCommands = require('../git/commands');
var Commands = require('../commands');
var SandboxCommands = require('../level/sandboxCommands'); var SandboxCommands = require('../level/sandboxCommands');
// more or less a static class // more or less a static class
@ -8,7 +9,7 @@ var ParseWaterfall = function(options) {
options = options || {}; options = options || {};
this.options = options; this.options = options;
this.shortcutWaterfall = options.shortcutWaterfall || [ this.shortcutWaterfall = options.shortcutWaterfall || [
GitCommands.shortcutMap Commands.getShortcutMap()
]; ];
this.instantWaterfall = options.instantWaterfall || [ this.instantWaterfall = options.instantWaterfall || [

View file

@ -4,6 +4,7 @@ var util = require('../util');
var constants = require('../util/constants'); var constants = require('../util/constants');
var intl = require('../intl'); var intl = require('../intl');
var Commands = require('../commands');
var Errors = require('../util/errors'); var Errors = require('../util/errors');
var CommandProcessError = Errors.CommandProcessError; var CommandProcessError = Errors.CommandProcessError;
var GitError = Errors.GitError; var GitError = Errors.GitError;
@ -120,7 +121,7 @@ var getAllCommands = function() {
var allCommands = _.extend( var allCommands = _.extend(
{}, {},
require('../git/commands').regexMap, require('../commands').getRegexMap(),
require('../level').regexMap, require('../level').regexMap,
regexMap regexMap
); );

View file

@ -22,7 +22,7 @@ Origin things:
Medium things: Medium things:
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ ] factor regexes and instant commands into one module [ ] figure out what to do with instant commands (and parse waterfall and the like)
Cases to handle / things to edit Cases to handle / things to edit
======================= =======================
@ -42,6 +42,9 @@ Ideas for cleaning
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] factor out golf thing too
[x] factor regexes and instant commands into one module
[x] big command refactor to get everything in one place
[x] get demonstration view to show origin / remote -- z index ugliness [x] get demonstration view to show origin / remote -- z index ugliness
[x] get goal visualization to show origin / remote.... hrm :O [x] get goal visualization to show origin / remote.... hrm :O
[x] MASSIVE EFFIN REFACTOR of all command options outside of git engine and into separate module [x] MASSIVE EFFIN REFACTOR of all command options outside of git engine and into separate module