mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-29 09:20:03 +02:00
event refactor and errors
This commit is contained in:
parent
4f30ad73a8
commit
3d1890bb3b
3 changed files with 111 additions and 36 deletions
23
src/errors.js
Normal file
23
src/errors.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
function CommandProcessError(msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandProcessError.prototype = _.copy(Error.prototype);
|
||||||
|
|
||||||
|
CommandProcessError.prototype.toString = function() {
|
||||||
|
return 'Command Process Error: ' + this.msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
function CommandResult(msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandResult.prototype = _.copy(Error.prototype);
|
||||||
|
|
||||||
|
CommandResult.prototype.toString = function() {
|
||||||
|
return 'Command Result: ' + this.msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
CommandResult.prototype.toResult = function() {
|
||||||
|
return this.msg.replace('\n', '</br>');
|
||||||
|
};
|
48
src/git.js
48
src/git.js
|
@ -14,15 +14,17 @@ function GitEngine() {
|
||||||
this.id_gen = 0;
|
this.id_gen = 0;
|
||||||
this.branches = [];
|
this.branches = [];
|
||||||
|
|
||||||
this._init();
|
events.on('gitCommandReady', _.bind(this.dispatch, this));
|
||||||
|
|
||||||
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
GitEngine.prototype._init = function() {
|
GitEngine.prototype.init = function() {
|
||||||
// make an initial commit and a master branch
|
// make an initial commit and a master branch
|
||||||
this.rootCommit = new Commit({rootCommit: true});
|
this.rootCommit = new Commit({rootCommit: true});
|
||||||
this.refs[this.rootCommit.get('id')] = this.rootCommit;
|
this.refs[this.rootCommit.get('id')] = this.rootCommit;
|
||||||
|
|
||||||
var master = this._makeBranch('master', this.rootCommit);
|
var master = this.makeBranch('master', this.rootCommit);
|
||||||
this.HEAD = new Ref({
|
this.HEAD = new Ref({
|
||||||
id: 'HEAD',
|
id: 'HEAD',
|
||||||
target: master
|
target: master
|
||||||
|
@ -40,7 +42,7 @@ GitEngine.prototype.getDetachedHead = function() {
|
||||||
return targetType !== 'branch';
|
return targetType !== 'branch';
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._validateBranchName = function(name) {
|
GitEngine.prototype.validateBranchName = function(name) {
|
||||||
name = name.replace(/\s/g, '');
|
name = name.replace(/\s/g, '');
|
||||||
if (!/^[a-zA-Z0-9]+$/.test(name)) {
|
if (!/^[a-zA-Z0-9]+$/.test(name)) {
|
||||||
throw new Error('woah bad branch name!! This is not ok: ' + name);
|
throw new Error('woah bad branch name!! This is not ok: ' + name);
|
||||||
|
@ -51,8 +53,8 @@ GitEngine.prototype._validateBranchName = function(name) {
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._makeBranch = function(id, target) {
|
GitEngine.prototype.makeBranch = function(id, target) {
|
||||||
id = this._validateBranchName(id);
|
id = this.validateBranchName(id);
|
||||||
if (this.refs[id]) {
|
if (this.refs[id]) {
|
||||||
throw new Error('that branch id already exists!');
|
throw new Error('that branch id already exists!');
|
||||||
}
|
}
|
||||||
|
@ -84,7 +86,7 @@ GitEngine.prototype.printBranches = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._makeCommit = function(parent) {
|
GitEngine.prototype.makeCommit = function(parent) {
|
||||||
var commit = new Commit({
|
var commit = new Commit({
|
||||||
parents: [parent]
|
parents: [parent]
|
||||||
});
|
});
|
||||||
|
@ -102,18 +104,18 @@ GitEngine.prototype.commit = function() {
|
||||||
targetCommit = targetBranch.get('target');
|
targetCommit = targetBranch.get('target');
|
||||||
}
|
}
|
||||||
|
|
||||||
var newCommit = this._makeCommit(targetCommit);
|
var newCommit = this.makeCommit(targetCommit);
|
||||||
targetBranch.set('target', newCommit);
|
targetBranch.set('target', newCommit);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._resolveId = function(idOrTarget) {
|
GitEngine.prototype.resolveId = function(idOrTarget) {
|
||||||
if (typeof idOrTarget !== 'string') {
|
if (typeof idOrTarget !== 'string') {
|
||||||
return idOrTarget;
|
return idOrTarget;
|
||||||
}
|
}
|
||||||
return this._resolveStringRef(idOrTarget);
|
return this.resolveStringRef(idOrTarget);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._resolveStringRef = function(ref) {
|
GitEngine.prototype.resolveStringRef = function(ref) {
|
||||||
if (this.refs[ref]) {
|
if (this.refs[ref]) {
|
||||||
return this.refs[ref];
|
return this.refs[ref];
|
||||||
}
|
}
|
||||||
|
@ -146,13 +148,13 @@ GitEngine.prototype._resolveStringRef = function(ref) {
|
||||||
if (!this.refs[startRef]) {
|
if (!this.refs[startRef]) {
|
||||||
throw new Error('the ref ' + startRef +' does not exist.');
|
throw new Error('the ref ' + startRef +' does not exist.');
|
||||||
}
|
}
|
||||||
var commit = this._getCommitFromRef(startRef);
|
var commit = this.getCommitFromRef(startRef);
|
||||||
|
|
||||||
return this._numBackFrom(commit, numBack);
|
return this.numBackFrom(commit, numBack);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._getCommitFromRef = function(ref) {
|
GitEngine.prototype.getCommitFromRef = function(ref) {
|
||||||
var start = this._resolveId(ref);
|
var start = this.resolveId(ref);
|
||||||
// works for both HEAD and just a single layer. aka branch
|
// works for both HEAD and just a single layer. aka branch
|
||||||
while (start.get('type') !== 'commit') {
|
while (start.get('type') !== 'commit') {
|
||||||
start = start.get('target');
|
start = start.get('target');
|
||||||
|
@ -160,7 +162,7 @@ GitEngine.prototype._getCommitFromRef = function(ref) {
|
||||||
return start;
|
return start;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._numBackFrom = function(commit, numBack) {
|
GitEngine.prototype.numBackFrom = function(commit, numBack) {
|
||||||
// going back '3' from a given ref is not trivial, for you might have
|
// going back '3' from a given ref is not trivial, for you might have
|
||||||
// a bunch of merge commits and such. like this situation:
|
// a bunch of merge commits and such. like this situation:
|
||||||
//
|
//
|
||||||
|
@ -204,7 +206,7 @@ GitEngine.prototype._numBackFrom = function(commit, numBack) {
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.checkout = function(idOrTarget) {
|
GitEngine.prototype.checkout = function(idOrTarget) {
|
||||||
var target = this._resolveId(idOrTarget);
|
var target = this.resolveId(idOrTarget);
|
||||||
if (target.get('id') === 'HEAD') {
|
if (target.get('id') === 'HEAD') {
|
||||||
// meaningless command but i used to do this back in the day
|
// meaningless command but i used to do this back in the day
|
||||||
return;
|
return;
|
||||||
|
@ -223,17 +225,17 @@ GitEngine.prototype.branch = function(name, ref, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (options['-d'] || options['-D']) {
|
if (options['-d'] || options['-D']) {
|
||||||
this._deleteBranch(name);
|
this.deleteBranch(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = this._getCommitFromRef(ref);
|
var target = this.getCommitFromRef(ref);
|
||||||
this._makeBranch(name, target);
|
this.makeBranch(name, target);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype._deleteBranch = function(name) {
|
GitEngine.prototype.deleteBranch = function(name) {
|
||||||
// trying to delete, lets check our refs
|
// trying to delete, lets check our refs
|
||||||
var target = this._resolveId(name);
|
var target = this.resolveId(name);
|
||||||
if (target.get('type') !== 'branch') {
|
if (target.get('type') !== 'branch') {
|
||||||
throw new Error("You can't delete things that arent branches with branch command");
|
throw new Error("You can't delete things that arent branches with branch command");
|
||||||
}
|
}
|
||||||
|
@ -250,7 +252,7 @@ GitEngine.prototype._deleteBranch = function(name) {
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.dispatch = function(commandObj) {
|
GitEngine.prototype.dispatch = function(commandObj) {
|
||||||
// TODO: parse arguments
|
// TODO: parse arguments as well
|
||||||
this[commandObj.method]();
|
this[commandObj.method]();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
76
src/views.js
76
src/views.js
|
@ -28,24 +28,36 @@ var CommandLineView = Backbone.View.extend({
|
||||||
this.submit();
|
this.submit();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
processError: function(err) {
|
||||||
|
// in this demo, every command that's not a git command will
|
||||||
|
// throw an exception. Some of these errors might be just to
|
||||||
|
// short-circuit the normal programatic flow, so we handle them
|
||||||
|
// here
|
||||||
|
if (err instanceof CommandProcessError) {
|
||||||
|
events.trigger('commandProcessError', err);
|
||||||
|
} else if (err instanceof CommandResult) {
|
||||||
|
events.trigger('commandResultPrint', err);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
submit: function() {
|
submit: function() {
|
||||||
var value = this.$('#commandTextField').val();
|
var value = this.$('#commandTextField').val();
|
||||||
this.$('#commandTextField').val('');
|
this.$('#commandTextField').val('');
|
||||||
events.trigger('commandConsumed', value);
|
|
||||||
|
|
||||||
if (!value.length) {
|
|
||||||
// return early, just want a blank line
|
|
||||||
}
|
|
||||||
console.log('the value');
|
|
||||||
console.log(value);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var command = new Command(value);
|
var command = new Command(value);
|
||||||
console.log(command);
|
console.log(command);
|
||||||
// immediately execute for now TODO
|
// immediately execute for now, will change later
|
||||||
gitEngine.dispatch(command);
|
events.trigger('gitCommandReady', command);
|
||||||
} catch (e) {
|
} catch (err) {
|
||||||
alert('Error with that command: ' + String(e));
|
if (err instanceof CommandProcessError) {
|
||||||
|
events.trigger('commandProcessError', err);
|
||||||
|
} else if (err instanceof CommandResultError) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -56,12 +68,26 @@ var CommandLineHistoryView = Backbone.View.extend({
|
||||||
this.addCommand, this
|
this.addCommand, this
|
||||||
));
|
));
|
||||||
|
|
||||||
|
events.on('commandProcessError', _.bind(
|
||||||
|
this.commandError, this
|
||||||
|
));
|
||||||
|
|
||||||
|
events.on('commandResultPrint', _.bind(
|
||||||
|
this.commandResultPrint, this
|
||||||
|
));
|
||||||
|
|
||||||
this.commandTemplate = ' \
|
this.commandTemplate = ' \
|
||||||
<p class="commandLine <%= name %>"> \
|
<p class="commandLine <%= class %>"> \
|
||||||
<span class="arrows">> > ></span> \
|
<span class="arrows">> > ></span> \
|
||||||
<%= command %> \
|
<%= command %> \
|
||||||
</p> \
|
</p> \
|
||||||
';
|
';
|
||||||
|
|
||||||
|
this.resultTemplate = ' \
|
||||||
|
<p class="commandResult <%= class %>"> \
|
||||||
|
<%= result %>
|
||||||
|
</p>
|
||||||
|
';
|
||||||
},
|
},
|
||||||
|
|
||||||
addCommand: function(commandText) {
|
addCommand: function(commandText) {
|
||||||
|
@ -74,5 +100,29 @@ var CommandLineHistoryView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
commandError: function(err) {
|
||||||
|
this.$('#commandDisplay').append(
|
||||||
|
_.template(
|
||||||
|
this.resultTemplate,
|
||||||
|
{
|
||||||
|
class: 'errorResult',
|
||||||
|
result: err.toResult()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
commandResultPrint: function(err) {
|
||||||
|
this.$('#commandDisplay').append(
|
||||||
|
_.template(
|
||||||
|
this.resultTemplate,
|
||||||
|
{
|
||||||
|
class; 'commandResult',
|
||||||
|
result: err.toResult()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue