mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Better auth handling in projects
This commit is contained in:
parent
10057de9b3
commit
5c88888e02
@ -17,6 +17,21 @@ RED.notify = (function() {
|
|||||||
var currentNotifications = [];
|
var currentNotifications = [];
|
||||||
var c = 0;
|
var c = 0;
|
||||||
return function(msg,type,fixed,timeout) {
|
return function(msg,type,fixed,timeout) {
|
||||||
|
var options = {};
|
||||||
|
if (typeof type === 'object') {
|
||||||
|
options = type;
|
||||||
|
fixed = options.fixed;
|
||||||
|
timeout = options.timeout;
|
||||||
|
type = options.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.modal) {
|
||||||
|
$("#header-shade").show();
|
||||||
|
$("#editor-shade").show();
|
||||||
|
$("#palette-shade").show();
|
||||||
|
$(".sidebar-shade").show();
|
||||||
|
}
|
||||||
|
|
||||||
if (currentNotifications.length > 4) {
|
if (currentNotifications.length > 4) {
|
||||||
var ll = currentNotifications.length;
|
var ll = currentNotifications.length;
|
||||||
for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) {
|
for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) {
|
||||||
@ -50,6 +65,12 @@ RED.notify = (function() {
|
|||||||
$(nn).slideUp(300, function() {
|
$(nn).slideUp(300, function() {
|
||||||
nn.parentNode.removeChild(nn);
|
nn.parentNode.removeChild(nn);
|
||||||
});
|
});
|
||||||
|
if (options.modal) {
|
||||||
|
$("#header-shade").hide();
|
||||||
|
$("#editor-shade").hide();
|
||||||
|
$("#palette-shade").hide();
|
||||||
|
$(".sidebar-shade").hide();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -411,6 +411,7 @@ RED.projects = (function() {
|
|||||||
sendRequest({
|
sendRequest({
|
||||||
url: "projects",
|
url: "projects",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
handleAuthFail: false,
|
||||||
responses: {
|
responses: {
|
||||||
200: function(data) {
|
200: function(data) {
|
||||||
dialog.dialog( "close" );
|
dialog.dialog( "close" );
|
||||||
@ -648,6 +649,70 @@ RED.projects = (function() {
|
|||||||
resultCallback = responses;
|
resultCallback = responses;
|
||||||
resultCallbackArgs = {error:responses.statusText};
|
resultCallbackArgs = {error:responses.statusText};
|
||||||
return;
|
return;
|
||||||
|
} else if (options.handleAuthFail !== false && xhr.responseJSON.error === 'git_auth_failed') {
|
||||||
|
var url = activeProject.remotes.origin.fetch;
|
||||||
|
var message = $('<div>'+
|
||||||
|
'<div class="form-row">Authentication required for repository:</div>'+
|
||||||
|
'<div class="form-row"><div style="margin-left: 20px;">'+url+'</div></div>'+
|
||||||
|
'<div class="form-row"><label for="projects-user-auth-username">Username</label><input id="projects-user-auth-username" type="text"></input></div>'+
|
||||||
|
'<div class="form-row"><label for=projects-user-auth-password">Password</label><input id="projects-user-auth-password" type="password"></input></div>'+
|
||||||
|
'<hr>'+
|
||||||
|
'<div class="ui-dialog-buttonset">'+
|
||||||
|
'<button>'+RED._("common.label.cancel")+'</button>'+
|
||||||
|
'<button><i class="fa fa-refresh"></i> Retry</button>'+
|
||||||
|
'</div>'+
|
||||||
|
'</div>');
|
||||||
|
$(message.find('button')[0]).click(function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
notification.close();
|
||||||
|
})
|
||||||
|
$(message.find('button')[1]).click(function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
var username = $('#projects-user-auth-username').val();
|
||||||
|
var password = $('#projects-user-auth-password').val();
|
||||||
|
body = body || {};
|
||||||
|
var done = function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Failed to update auth");
|
||||||
|
console.log(err);
|
||||||
|
} else {
|
||||||
|
sendRequest(options,body);
|
||||||
|
notification.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
sendRequest({
|
||||||
|
url: "projects/"+activeProject.name,
|
||||||
|
type: "PUT",
|
||||||
|
responses: {
|
||||||
|
0: function(error) {
|
||||||
|
done(error,null);
|
||||||
|
},
|
||||||
|
200: function(data) {
|
||||||
|
done(null,data);
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
'unexpected_error': function(error) {
|
||||||
|
done(error,null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
remote: {
|
||||||
|
origin: {
|
||||||
|
username: username,
|
||||||
|
password: password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
var notification = RED.notify(message,{
|
||||||
|
type:"error",
|
||||||
|
fixed: true,
|
||||||
|
modal: true
|
||||||
|
});
|
||||||
|
return;
|
||||||
} else if (responses[xhr.responseJSON.error]) {
|
} else if (responses[xhr.responseJSON.error]) {
|
||||||
resultCallback = responses[xhr.responseJSON.error];
|
resultCallback = responses[xhr.responseJSON.error];
|
||||||
resultCallbackArgs = xhr.responseJSON;
|
resultCallbackArgs = xhr.responseJSON;
|
||||||
|
@ -216,7 +216,21 @@ RED.sidebar.versionControl = (function() {
|
|||||||
utils = _utils;
|
utils = _utils;
|
||||||
|
|
||||||
RED.actions.add("core:show-version-control-tab",show);
|
RED.actions.add("core:show-version-control-tab",show);
|
||||||
|
RED.events.on("deploy", function() {
|
||||||
|
var activeProject = RED.projects.getActiveProject();
|
||||||
|
if (activeProject) {
|
||||||
|
// TODO: this is a full refresh of the files - should be able to
|
||||||
|
// just do an incremental refresh
|
||||||
|
allChanges = {};
|
||||||
|
unstagedChangesList.editableList('empty');
|
||||||
|
stagedChangesList.editableList('empty');
|
||||||
|
unmergedChangesList.editableList('empty');
|
||||||
|
|
||||||
|
$.getJSON("/projects/"+activeProject.name+"/status",function(result) {
|
||||||
|
refreshFiles(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
sidebarContent = $('<div>', {class:"sidebar-version-control"});
|
sidebarContent = $('<div>', {class:"sidebar-version-control"});
|
||||||
var stackContainer = $("<div>",{class:"sidebar-version-control-stack"}).appendTo(sidebarContent);
|
var stackContainer = $("<div>",{class:"sidebar-version-control-stack"}).appendTo(sidebarContent);
|
||||||
sections = RED.stack.create({
|
sections = RED.stack.create({
|
||||||
@ -414,8 +428,7 @@ RED.sidebar.versionControl = (function() {
|
|||||||
200: function(data) {
|
200: function(data) {
|
||||||
spinner.remove();
|
spinner.remove();
|
||||||
cancelCommitButton.click();
|
cancelCommitButton.click();
|
||||||
refreshFiles(data);
|
refresh(true);
|
||||||
refreshLocalCommits();
|
|
||||||
},
|
},
|
||||||
400: {
|
400: {
|
||||||
'unexpected_error': function(error) {
|
'unexpected_error': function(error) {
|
||||||
@ -442,7 +455,7 @@ RED.sidebar.versionControl = (function() {
|
|||||||
.appendTo(bg)
|
.appendTo(bg)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
refreshLocalCommits();
|
refresh(true);
|
||||||
})
|
})
|
||||||
|
|
||||||
var localBranchToolbar = $('<div class="sidebar-version-control-change-header" style="text-align: right;"></div>').appendTo(localHistory.content);
|
var localBranchToolbar = $('<div class="sidebar-version-control-change-header" style="text-align: right;"></div>').appendTo(localHistory.content);
|
||||||
@ -466,7 +479,15 @@ RED.sidebar.versionControl = (function() {
|
|||||||
},100);
|
},100);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var repoStatusButton = $('<button class="editor-button editor-button-small" style="margin-left: 10px;" id="sidebar-version-control-repo-status-button"><i class="fa fa-long-arrow-up"></i> <span id="sidebar-version-control-commits-ahead"></span> <i class="fa fa-long-arrow-down"></i> <span id="sidebar-version-control-commits-behind"></span></button>')
|
var repoStatusButton = $('<button class="editor-button editor-button-small" style="margin-left: 10px;" id="sidebar-version-control-repo-status-button">'+
|
||||||
|
'<span id="sidebar-version-control-repo-status-stats">'+
|
||||||
|
'<i class="fa fa-long-arrow-up"></i> <span id="sidebar-version-control-commits-ahead"></span> '+
|
||||||
|
'<i class="fa fa-long-arrow-down"></i> <span id="sidebar-version-control-commits-behind"></span>'+
|
||||||
|
'</span>'+
|
||||||
|
'<span id="sidebar-version-control-repo-status-auth-issue">'+
|
||||||
|
'<i class="fa fa-warning"></i>'+
|
||||||
|
'</span>'+
|
||||||
|
'</button>')
|
||||||
.appendTo(localBranchToolbar)
|
.appendTo(localBranchToolbar)
|
||||||
.click(function(evt) {
|
.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
@ -485,7 +506,7 @@ RED.sidebar.versionControl = (function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
localCommitList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0px; right:0; left:0;"}).appendTo(localHistory.content);
|
localCommitList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0px; right:0; left:0;"}).appendTo(localHistory.content);
|
||||||
localCommitListShade = $('<div class="component-shade"></div>').css('top',"30px").hide().appendTo(localHistory.content);
|
localCommitListShade = $('<div class="component-shade" style="z-Index: 3"></div>').css('top',"30px").hide().appendTo(localHistory.content);
|
||||||
localCommitList.editableList({
|
localCommitList.editableList({
|
||||||
addButton: false,
|
addButton: false,
|
||||||
scrollOnAdd: false,
|
scrollOnAdd: false,
|
||||||
@ -636,6 +657,39 @@ RED.sidebar.versionControl = (function() {
|
|||||||
|
|
||||||
$('<div id="sidebar-version-control-repo-toolbar-message" class="sidebar-version-control-slide-box-header" style="min-height: 100px;"></div>').appendTo(remoteBox);
|
$('<div id="sidebar-version-control-repo-toolbar-message" class="sidebar-version-control-slide-box-header" style="min-height: 100px;"></div>').appendTo(remoteBox);
|
||||||
|
|
||||||
|
|
||||||
|
var errorMessage = $('<div id="sidebar-version-control-repo-toolbar-error-message" class="sidebar-version-control-slide-box-header" style="min-height: 100px;"></div>').hide().appendTo(remoteBox);
|
||||||
|
$('<div style="margin-top: 10px;"><i class="fa fa-warning"></i> Unable to access remote repository</div>').appendTo(errorMessage)
|
||||||
|
var buttonRow = $('<div style="margin: 10px 30px; text-align: center"></div>').appendTo(errorMessage);
|
||||||
|
$('<button class="editor-button" style="width: 80%;"><i class="fa fa-refresh"></i> Retry</button>')
|
||||||
|
.appendTo(buttonRow)
|
||||||
|
.click(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var activeProject = RED.projects.getActiveProject();
|
||||||
|
var spinner = utils.addSpinnerOverlay(remoteBox).addClass("projects-dialog-spinner-contain");
|
||||||
|
utils.sendRequest({
|
||||||
|
url: "/projects/"+activeProject.name+"/branches/remote",
|
||||||
|
type: "GET",
|
||||||
|
responses: {
|
||||||
|
0: function(error) {
|
||||||
|
console.log(error);
|
||||||
|
// done(error,null);
|
||||||
|
},
|
||||||
|
200: function(data) {
|
||||||
|
refresh(true);
|
||||||
|
},
|
||||||
|
400: {
|
||||||
|
'unexpected_error': function(error) {
|
||||||
|
console.log(error);
|
||||||
|
// done(error,null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).always(function() {
|
||||||
|
spinner.remove();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
$('<div class="sidebar-version-control-slide-box-header" style="height: 20px;"><label id="sidebar-version-control-repo-toolbar-set-upstream-row" for="sidebar-version-control-repo-toolbar-set-upstream" class="hide"><input type="checkbox" id="sidebar-version-control-repo-toolbar-set-upstream"> Set as upstream branch</label></div>').appendTo(remoteBox);
|
$('<div class="sidebar-version-control-slide-box-header" style="height: 20px;"><label id="sidebar-version-control-repo-toolbar-set-upstream-row" for="sidebar-version-control-repo-toolbar-set-upstream" class="hide"><input type="checkbox" id="sidebar-version-control-repo-toolbar-set-upstream"> Set as upstream branch</label></div>').appendTo(remoteBox);
|
||||||
|
|
||||||
var remoteBranchSubRow = $('<div style="height: 0;overflow:hidden; transition: height 0.2s ease-in-out;"></div>').hide().appendTo(remoteBranchRow);
|
var remoteBranchSubRow = $('<div style="height: 0;overflow:hidden; transition: height 0.2s ease-in-out;"></div>').hide().appendTo(remoteBranchRow);
|
||||||
@ -891,14 +945,6 @@ RED.sidebar.versionControl = (function() {
|
|||||||
'unexpected_error': function(error) {
|
'unexpected_error': function(error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
// done(error,null);
|
// done(error,null);
|
||||||
},
|
|
||||||
'git_auth_failed': function(error) {
|
|
||||||
RED.notify('Authentication failed against remote repository','error');
|
|
||||||
$('#sidebar-version-control-repo-toolbar-message').text("Failed to fetch remote repository status");
|
|
||||||
$("#sidebar-version-control-repo-pull").attr('disabled',true);
|
|
||||||
$("#sidebar-version-control-repo-push").attr('disabled',true);
|
|
||||||
|
|
||||||
spinner.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1071,7 +1117,6 @@ RED.sidebar.versionControl = (function() {
|
|||||||
var activeProject = RED.projects.getActiveProject();
|
var activeProject = RED.projects.getActiveProject();
|
||||||
if (activeProject) {
|
if (activeProject) {
|
||||||
$.getJSON("/projects/"+activeProject.name+"/status",function(result) {
|
$.getJSON("/projects/"+activeProject.name+"/status",function(result) {
|
||||||
|
|
||||||
refreshFiles(result);
|
refreshFiles(result);
|
||||||
|
|
||||||
$('#sidebar-version-control-local-branch').text(result.branches.local);
|
$('#sidebar-version-control-local-branch').text(result.branches.local);
|
||||||
@ -1079,9 +1124,25 @@ RED.sidebar.versionControl = (function() {
|
|||||||
|
|
||||||
var commitsAhead = result.commits.ahead || 0;
|
var commitsAhead = result.commits.ahead || 0;
|
||||||
var commitsBehind = result.commits.behind || 0;
|
var commitsBehind = result.commits.behind || 0;
|
||||||
console.log(commitsBehind,commitsAhead);
|
|
||||||
|
|
||||||
if (activeProject.hasOwnProperty('remotes')) {
|
if (activeProject.hasOwnProperty('remotes')) {
|
||||||
|
if (result.branches.hasOwnProperty("remoteError")) {
|
||||||
|
$("#sidebar-version-control-repo-status-auth-issue").show();
|
||||||
|
$("#sidebar-version-control-repo-status-stats").hide();
|
||||||
|
$('#sidebar-version-control-repo-branch').attr('disabled',true);
|
||||||
|
$("#sidebar-version-control-repo-pull").attr('disabled',true);
|
||||||
|
$("#sidebar-version-control-repo-push").attr('disabled',true);
|
||||||
|
$('#sidebar-version-control-repo-toolbar-message').hide();
|
||||||
|
$('#sidebar-version-control-repo-toolbar-error-message').show();
|
||||||
|
} else {
|
||||||
|
$('#sidebar-version-control-repo-toolbar-message').show();
|
||||||
|
$('#sidebar-version-control-repo-toolbar-error-message').hide();
|
||||||
|
|
||||||
|
$("#sidebar-version-control-repo-status-auth-issue").hide();
|
||||||
|
$("#sidebar-version-control-repo-status-stats").show();
|
||||||
|
|
||||||
|
$('#sidebar-version-control-repo-branch').attr('disabled',false);
|
||||||
|
|
||||||
$("#sidebar-version-control-repo-status-button").show();
|
$("#sidebar-version-control-repo-status-button").show();
|
||||||
if (result.branches.hasOwnProperty('remote')) {
|
if (result.branches.hasOwnProperty('remote')) {
|
||||||
updateRemoteStatus(commitsAhead, commitsBehind);
|
updateRemoteStatus(commitsAhead, commitsBehind);
|
||||||
@ -1093,6 +1154,7 @@ RED.sidebar.versionControl = (function() {
|
|||||||
$("#sidebar-version-control-repo-pull").attr('disabled',true);
|
$("#sidebar-version-control-repo-pull").attr('disabled',true);
|
||||||
$("#sidebar-version-control-repo-push").attr('disabled',true);
|
$("#sidebar-version-control-repo-push").attr('disabled',true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$("#sidebar-version-control-repo-status-button").hide();
|
$("#sidebar-version-control-repo-status-button").hide();
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
&.sidebar-version-control-slide-box-top {
|
&.sidebar-version-control-slide-box-top {
|
||||||
z-index: 10;
|
z-index: 4;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
left: auto;
|
left: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -28,8 +28,8 @@ module.exports = {
|
|||||||
|
|
||||||
// Projects
|
// Projects
|
||||||
|
|
||||||
|
// List all projects
|
||||||
app.get("/", function(req,res) {
|
app.get("/", function(req,res) {
|
||||||
// List projects
|
|
||||||
runtime.storage.projects.listProjects().then(function(list) {
|
runtime.storage.projects.listProjects().then(function(list) {
|
||||||
var active = runtime.storage.projects.getActiveProject();
|
var active = runtime.storage.projects.getActiveProject();
|
||||||
var response = {
|
var response = {
|
||||||
@ -47,8 +47,8 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/", function(req,res) {
|
|
||||||
// Create project
|
// Create project
|
||||||
|
app.post("/", function(req,res) {
|
||||||
runtime.storage.projects.createProject(req.body).then(function(data) {
|
runtime.storage.projects.createProject(req.body).then(function(data) {
|
||||||
res.json(data);
|
res.json(data);
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
@ -61,8 +61,8 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
app.put("/:id", function(req,res) {
|
|
||||||
// Update a project
|
// Update a project
|
||||||
|
app.put("/:id", function(req,res) {
|
||||||
//TODO: validate the payload properly
|
//TODO: validate the payload properly
|
||||||
if (req.body.active) {
|
if (req.body.active) {
|
||||||
var currentProject = runtime.storage.projects.getActiveProject();
|
var currentProject = runtime.storage.projects.getActiveProject();
|
||||||
@ -83,7 +83,8 @@ module.exports = {
|
|||||||
req.body.hasOwnProperty('description') ||
|
req.body.hasOwnProperty('description') ||
|
||||||
req.body.hasOwnProperty('dependencies')||
|
req.body.hasOwnProperty('dependencies')||
|
||||||
req.body.hasOwnProperty('summary') ||
|
req.body.hasOwnProperty('summary') ||
|
||||||
req.body.hasOwnProperty('files')) {
|
req.body.hasOwnProperty('files') ||
|
||||||
|
req.body.hasOwnProperty('remote')) {
|
||||||
runtime.storage.projects.updateProject(req.params.id, req.body).then(function() {
|
runtime.storage.projects.updateProject(req.params.id, req.body).then(function() {
|
||||||
res.redirect(303,req.baseUrl + '/'+ req.params.id);
|
res.redirect(303,req.baseUrl + '/'+ req.params.id);
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
@ -96,11 +97,10 @@ module.exports = {
|
|||||||
} else {
|
} else {
|
||||||
res.status(400).json({error:"unexpected_error", message:"invalid_request"});
|
res.status(400).json({error:"unexpected_error", message:"invalid_request"});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/:id", function(req,res) {
|
|
||||||
// Get project metadata
|
// Get project metadata
|
||||||
|
app.get("/:id", function(req,res) {
|
||||||
runtime.storage.projects.getProject(req.params.id).then(function(data) {
|
runtime.storage.projects.getProject(req.params.id).then(function(data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
res.json(data);
|
res.json(data);
|
||||||
@ -113,13 +113,13 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Delete project - tbd
|
||||||
app.delete("/:id", function(req,res) {
|
app.delete("/:id", function(req,res) {
|
||||||
// Delete project
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Get project status - files, commit counts, branch info
|
||||||
app.get("/:id/status", function(req,res) {
|
app.get("/:id/status", function(req,res) {
|
||||||
// Get project metadata
|
|
||||||
runtime.storage.projects.getStatus(req.params.id).then(function(data) {
|
runtime.storage.projects.getStatus(req.params.id).then(function(data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
res.json(data);
|
res.json(data);
|
||||||
@ -133,8 +133,7 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Project Files
|
// Project file listing
|
||||||
|
|
||||||
app.get("/:id/files", function(req,res) {
|
app.get("/:id/files", function(req,res) {
|
||||||
runtime.storage.projects.getFiles(req.params.id).then(function(data) {
|
runtime.storage.projects.getFiles(req.params.id).then(function(data) {
|
||||||
console.log("TODO: REMOVE /:id/files as /:id/status is better!")
|
console.log("TODO: REMOVE /:id/files as /:id/status is better!")
|
||||||
@ -146,7 +145,8 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// /:project/files/:treeish/file-path
|
|
||||||
|
// Get file content in a given tree (index/stage)
|
||||||
app.get("/:id/files/:treeish/*", function(req,res) {
|
app.get("/:id/files/:treeish/*", function(req,res) {
|
||||||
var projectId = req.params.id;
|
var projectId = req.params.id;
|
||||||
var treeish = req.params.treeish;
|
var treeish = req.params.treeish;
|
||||||
@ -161,6 +161,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stage a file
|
||||||
app.post("/:id/stage/*", function(req,res) {
|
app.post("/:id/stage/*", function(req,res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var file = req.params[0];
|
var file = req.params[0];
|
||||||
@ -173,6 +174,8 @@ module.exports = {
|
|||||||
res.status(400).json({error:"unexpected_error", message:err.toString()});
|
res.status(400).json({error:"unexpected_error", message:err.toString()});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stage multiple files
|
||||||
app.post("/:id/stage", function(req,res) {
|
app.post("/:id/stage", function(req,res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var files = req.body.files;
|
var files = req.body.files;
|
||||||
@ -186,6 +189,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Commit changes
|
||||||
app.post("/:id/commit", function(req,res) {
|
app.post("/:id/commit", function(req,res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
|
|
||||||
@ -198,6 +202,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Unstage a file
|
||||||
app.delete("/:id/stage/*", function(req,res) {
|
app.delete("/:id/stage/*", function(req,res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var file = req.params[0];
|
var file = req.params[0];
|
||||||
@ -210,6 +215,8 @@ module.exports = {
|
|||||||
res.status(400).json({error:"unexpected_error", message:err.toString()});
|
res.status(400).json({error:"unexpected_error", message:err.toString()});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Unstage multiple files
|
||||||
app.delete("/:id/stage", function(req, res) {
|
app.delete("/:id/stage", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
runtime.storage.projects.unstageFile(projectName).then(function(data) {
|
runtime.storage.projects.unstageFile(projectName).then(function(data) {
|
||||||
@ -221,6 +228,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get a file diff
|
||||||
app.get("/:id/diff/:type/*", function(req,res) {
|
app.get("/:id/diff/:type/*", function(req,res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var type = req.params.type;
|
var type = req.params.type;
|
||||||
@ -236,6 +244,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get a list of commits
|
||||||
app.get("/:id/commits", function(req, res) {
|
app.get("/:id/commits", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var options = {
|
var options = {
|
||||||
@ -255,6 +264,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get an individual commit details
|
||||||
app.get("/:id/commits/:sha", function(req, res) {
|
app.get("/:id/commits/:sha", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var sha = req.params.sha;
|
var sha = req.params.sha;
|
||||||
@ -268,6 +278,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Push local commits to remote
|
||||||
app.post("/:id/push/?*", function(req,res) {
|
app.post("/:id/push/?*", function(req,res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var remoteBranchName = req.params[0]
|
var remoteBranchName = req.params[0]
|
||||||
@ -284,6 +295,8 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Pull remote commits
|
||||||
app.get("/:id/pull/?*", function(req,res) {
|
app.get("/:id/pull/?*", function(req,res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var remoteBranchName = req.params[0];
|
var remoteBranchName = req.params[0];
|
||||||
@ -301,6 +314,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Abort an ongoing merge
|
||||||
app.delete("/:id/merge", function(req, res) {
|
app.delete("/:id/merge", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
runtime.storage.projects.abortMerge(projectName).then(function(data) {
|
runtime.storage.projects.abortMerge(projectName).then(function(data) {
|
||||||
@ -316,6 +330,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Resolve a merge
|
||||||
app.post("/:id/resolve/*", function(req, res) {
|
app.post("/:id/resolve/*", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var file = req.params[0];
|
var file = req.params[0];
|
||||||
@ -333,6 +348,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get a list of local branches
|
||||||
app.get("/:id/branches", function(req, res) {
|
app.get("/:id/branches", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
runtime.storage.projects.getBranches(projectName,false).then(function(data) {
|
runtime.storage.projects.getBranches(projectName,false).then(function(data) {
|
||||||
@ -347,6 +363,8 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get a list of remote branches
|
||||||
app.get("/:id/branches/remote", function(req, res) {
|
app.get("/:id/branches/remote", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
runtime.storage.projects.getBranches(projectName,true).then(function(data) {
|
runtime.storage.projects.getBranches(projectName,true).then(function(data) {
|
||||||
@ -362,6 +380,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get branch status - commit counts/ahead/behind
|
||||||
app.get("/:id/branches/remote/*/status", function(req, res) {
|
app.get("/:id/branches/remote/*/status", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var branch = req.params[0];
|
var branch = req.params[0];
|
||||||
@ -378,7 +397,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set the active local branch
|
||||||
app.post("/:id/branches", function(req, res) {
|
app.post("/:id/branches", function(req, res) {
|
||||||
var projectName = req.params.id;
|
var projectName = req.params.id;
|
||||||
var branchName = req.body.name;
|
var branchName = req.body.name;
|
||||||
|
@ -29,10 +29,19 @@ var log;
|
|||||||
|
|
||||||
var projectsDir;
|
var projectsDir;
|
||||||
|
|
||||||
|
var authCache = {};
|
||||||
|
|
||||||
|
function getAuth(project,remote) {
|
||||||
|
if (authCache.hasOwnProperty(project) && authCache[project].hasOwnProperty(remote)) {
|
||||||
|
return authCache[project][remote];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
function Project(name) {
|
function Project(name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.path = fspath.join(projectsDir,name);
|
this.path = fspath.join(projectsDir,name);
|
||||||
this.paths = {};
|
this.paths = {};
|
||||||
|
this.auth = {origin:{}};
|
||||||
|
|
||||||
this.missingFiles = [];
|
this.missingFiles = [];
|
||||||
|
|
||||||
@ -169,7 +178,14 @@ Project.prototype.update = function (data) {
|
|||||||
savePackage = true;
|
savePackage = true;
|
||||||
this.package.description = data.summary;
|
this.package.description = data.summary;
|
||||||
}
|
}
|
||||||
|
if (data.hasOwnProperty('remote')) {
|
||||||
|
authCache[project.name] = authCache[project.name]||{};
|
||||||
|
for (var remote in data.remote) {
|
||||||
|
if (data.remote.hasOwnProperty(remote)) {
|
||||||
|
authCache[project.name][remote] = data.remote[remote];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (data.hasOwnProperty('files')) {
|
if (data.hasOwnProperty('files')) {
|
||||||
this.package['node-red'] = this.package['node-red'] || { settings: {}};
|
this.package['node-red'] = this.package['node-red'] || { settings: {}};
|
||||||
if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) {
|
if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) {
|
||||||
@ -221,24 +237,7 @@ Project.prototype.getFileDiff = function(file,type) {
|
|||||||
return gitTools.getFileDiff(this.path,file,type);
|
return gitTools.getFileDiff(this.path,file,type);
|
||||||
}
|
}
|
||||||
Project.prototype.getCommits = function(options) {
|
Project.prototype.getCommits = function(options) {
|
||||||
var self = this;
|
return gitTools.getCommits(this.path,options);
|
||||||
var fetchPromise;
|
|
||||||
if (this.remote) {
|
|
||||||
options.hasRemote = true;
|
|
||||||
fetchPromise = gitTools.fetch(this.path)
|
|
||||||
} else {
|
|
||||||
fetchPromise = when.resolve();
|
|
||||||
}
|
|
||||||
return fetchPromise.then(function() {
|
|
||||||
return gitTools.getCommits(self.path,options);
|
|
||||||
}).otherwise(function(e) {
|
|
||||||
if (e.code === 'git_auth_failed') {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
console.log("Fetch failed");
|
|
||||||
console.log(e);
|
|
||||||
return gitTools.getCommits(self.path,options);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
Project.prototype.getCommit = function(sha) {
|
Project.prototype.getCommit = function(sha) {
|
||||||
return gitTools.getCommit(this.path,sha);
|
return gitTools.getCommit(this.path,sha);
|
||||||
@ -253,10 +252,19 @@ Project.prototype.getFile = function (filePath,treeish) {
|
|||||||
|
|
||||||
Project.prototype.status = function() {
|
Project.prototype.status = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
var fetchPromise;
|
||||||
|
if (this.remote) {
|
||||||
|
fetchPromise = gitTools.fetch(this.path,getAuth(this.name,'origin'));
|
||||||
|
} else {
|
||||||
|
fetchPromise = when.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
var completeStatus = function(fetchError) {
|
||||||
var promises = [
|
var promises = [
|
||||||
gitTools.getStatus(this.path),
|
gitTools.getStatus(self.path),
|
||||||
fs.exists(fspath.join(this.path,".git","MERGE_HEAD"))
|
fs.exists(fspath.join(self.path,".git","MERGE_HEAD"))
|
||||||
]
|
];
|
||||||
return when.all(promises).then(function(results) {
|
return when.all(promises).then(function(results) {
|
||||||
var result = results[0];
|
var result = results[0];
|
||||||
if (results[1]) {
|
if (results[1]) {
|
||||||
@ -264,21 +272,36 @@ Project.prototype.status = function() {
|
|||||||
}
|
}
|
||||||
self.branches.local = result.branches.local;
|
self.branches.local = result.branches.local;
|
||||||
self.branches.remote = result.branches.remote;
|
self.branches.remote = result.branches.remote;
|
||||||
|
if (fetchError) {
|
||||||
|
result.branches.remoteError = {
|
||||||
|
code: fetchError.code
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return fetchPromise.then(completeStatus).catch(function(e) {
|
||||||
|
if (e.code === 'git_auth_failed') {
|
||||||
|
console.log("Fetch auth failed");
|
||||||
|
} else {
|
||||||
|
console.log("Fetch failed");
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
return completeStatus(e);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
Project.prototype.push = function (remoteBranchName,setRemote) {
|
Project.prototype.push = function (remoteBranchName,setRemote) {
|
||||||
return gitTools.push(this.path, remoteBranchName, setRemote);
|
return gitTools.push(this.path, remoteBranchName, setRemote, getAuth(this.name,'origin'));
|
||||||
};
|
};
|
||||||
|
|
||||||
Project.prototype.pull = function (remoteBranchName,setRemote) {
|
Project.prototype.pull = function (remoteBranchName,setRemote) {
|
||||||
if (setRemote) {
|
if (setRemote) {
|
||||||
return gitTools.setUpstream(this.path, remoteBranchName).then(function() {
|
return gitTools.setUpstream(this.path, remoteBranchName).then(function() {
|
||||||
return gitTools.pull(this.path);
|
return gitTools.pull(this.path, null, getAuth(this.name,'origin'));
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return gitTools.pull(this.path, remoteBranchName);
|
return gitTools.pull(this.path, remoteBranchName, getAuth(this.name,'origin'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -328,7 +351,16 @@ Project.prototype.abortMerge = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Project.prototype.getBranches = function (remote) {
|
Project.prototype.getBranches = function (remote) {
|
||||||
return gitTools.getBranches(this.path,remote);
|
var self = this;
|
||||||
|
var fetchPromise;
|
||||||
|
if (remote) {
|
||||||
|
fetchPromise = gitTools.fetch(this.path,getAuth(this.name,'origin'))
|
||||||
|
} else {
|
||||||
|
fetchPromise = when.resolve();
|
||||||
|
}
|
||||||
|
return fetchPromise.then(function() {
|
||||||
|
return gitTools.getBranches(self.path,remote);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
Project.prototype.setBranch = function (branchName, isCreate) {
|
Project.prototype.setBranch = function (branchName, isCreate) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -347,6 +379,7 @@ Project.prototype.getFlowFile = function() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Project.prototype.getFlowFileBackup = function() {
|
Project.prototype.getFlowFileBackup = function() {
|
||||||
return getBackupFilename(this.getFlowFile());
|
return getBackupFilename(this.getFlowFile());
|
||||||
}
|
}
|
||||||
@ -499,8 +532,18 @@ function createProject(metadata) {
|
|||||||
return settings.set('projects',projects);
|
return settings.set('projects',projects);
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
if (metadata.remote) {
|
if (metadata.remote) {
|
||||||
console.log(metadata.remote);
|
var auth;
|
||||||
return gitTools.clone(metadata.remote,projectPath).then(function(result) {
|
if (metadata.remote.hasOwnProperty("username") && metadata.remote.hasOwnProperty("password")) {
|
||||||
|
authCache[project] = {
|
||||||
|
origin: { // TODO: hardcoded remote name
|
||||||
|
username: metadata.remote.username,
|
||||||
|
password: metadata.remote.password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auth = authCache[project].origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitTools.clone(metadata.remote,auth,projectPath).then(function(result) {
|
||||||
// Check this is a valid project
|
// Check this is a valid project
|
||||||
// If it is empty
|
// If it is empty
|
||||||
// - if 'populate' flag is set, call populateProject
|
// - if 'populate' flag is set, call populateProject
|
||||||
|
@ -28,7 +28,7 @@ function getListenPath() {
|
|||||||
} else {
|
} else {
|
||||||
listenPath = path.join(process.env['XDG_RUNTIME_DIR'] || os.tmpdir(), fn);
|
listenPath = path.join(process.env['XDG_RUNTIME_DIR'] || os.tmpdir(), fn);
|
||||||
}
|
}
|
||||||
console.log(listenPath);
|
// console.log(listenPath);
|
||||||
return listenPath;
|
return listenPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ var ResponseServer = function(auth) {
|
|||||||
resolve({path:listenPath,close:function() { server.close(); }});
|
resolve({path:listenPath,close:function() { server.close(); }});
|
||||||
});
|
});
|
||||||
server.on('close', function() {
|
server.on('close', function() {
|
||||||
console.log("Closing response server");
|
// console.log("Closing response server");
|
||||||
fs.removeSync(listenPath);
|
fs.removeSync(listenPath);
|
||||||
});
|
});
|
||||||
server.on('error',function(err) {
|
server.on('error',function(err) {
|
||||||
|
@ -263,26 +263,6 @@ function parseLog(log) {
|
|||||||
return commits;
|
return commits;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function getCommitCounts(cwd, options) {
|
|
||||||
// var commands = [
|
|
||||||
// runGitCommand(['rev-list', 'HEAD', '--count'],cwd), // #commits on master
|
|
||||||
// ];
|
|
||||||
// if (options.hasRemote) {
|
|
||||||
// commands.push(runGitCommand(['rev-list', 'master','^origin/master', '--count'],cwd)); // #commits master ahead
|
|
||||||
// commands.push(runGitCommand(['rev-list', '^master','origin/master', '--count'],cwd)); // #commits master behind
|
|
||||||
// }
|
|
||||||
// return when.all(commands).then(function(results) {
|
|
||||||
// var result = {
|
|
||||||
// total: parseInt(results[0])
|
|
||||||
// }
|
|
||||||
// if (options.hasRemote) {
|
|
||||||
// result.ahead = parseInt(results[1]);
|
|
||||||
// result.behind = parseInt(results[2]);
|
|
||||||
// }
|
|
||||||
// return result;
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
function getRemotes(cwd) {
|
function getRemotes(cwd) {
|
||||||
return runGitCommand(['remote','-v'],cwd).then(function(output) {
|
return runGitCommand(['remote','-v'],cwd).then(function(output) {
|
||||||
var result;
|
var result;
|
||||||
@ -362,7 +342,7 @@ module.exports = {
|
|||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
push: function(cwd,remoteBranch,setUpstream) {
|
push: function(cwd,remoteBranch,setUpstream, auth) {
|
||||||
var args = ["push"];
|
var args = ["push"];
|
||||||
var m = /^(.*?)\/(.*)$/.exec(remoteBranch);
|
var m = /^(.*?)\/(.*)$/.exec(remoteBranch);
|
||||||
if (m) {
|
if (m) {
|
||||||
@ -375,7 +355,13 @@ module.exports = {
|
|||||||
args.push("origin");
|
args.push("origin");
|
||||||
}
|
}
|
||||||
args.push("--porcelain");
|
args.push("--porcelain");
|
||||||
return runGitCommand(args,cwd).otherwise(function(err) {
|
var promise;
|
||||||
|
if (auth) {
|
||||||
|
promise = runGitCommandWithAuth(args,cwd,auth);
|
||||||
|
} else {
|
||||||
|
promise = runGitCommand(args,cwd)
|
||||||
|
}
|
||||||
|
return promise.catch(function(err) {
|
||||||
if (err.code === 'git_error') {
|
if (err.code === 'git_error') {
|
||||||
if (/^!.*non-fast-forward/m.test(err.stdout)) {
|
if (/^!.*non-fast-forward/m.test(err.stdout)) {
|
||||||
err.code = 'git_push_failed';
|
err.code = 'git_push_failed';
|
||||||
@ -384,7 +370,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
clone: function(remote, cwd) {
|
clone: function(remote, auth, cwd) {
|
||||||
var args = ["clone",remote.url];
|
var args = ["clone",remote.url];
|
||||||
if (remote.name) {
|
if (remote.name) {
|
||||||
args.push("-o");
|
args.push("-o");
|
||||||
@ -395,8 +381,8 @@ module.exports = {
|
|||||||
args.push(remote.branch);
|
args.push(remote.branch);
|
||||||
}
|
}
|
||||||
args.push(".");
|
args.push(".");
|
||||||
if (remote.hasOwnProperty("username") && remote.hasOwnProperty("password")) {
|
if (auth) {
|
||||||
return runGitCommandWithAuth(args,cwd,remote);
|
return runGitCommandWithAuth(args,cwd,auth);
|
||||||
} else {
|
} else {
|
||||||
return runGitCommand(args,cwd);
|
return runGitCommand(args,cwd);
|
||||||
}
|
}
|
||||||
@ -441,8 +427,13 @@ module.exports = {
|
|||||||
args.push(file);
|
args.push(file);
|
||||||
return runGitCommand(args,cwd);
|
return runGitCommand(args,cwd);
|
||||||
},
|
},
|
||||||
fetch: function(cwd) {
|
fetch: function(cwd,auth) {
|
||||||
return runGitCommand(["fetch"],cwd);
|
var args = ["fetch"];
|
||||||
|
if (auth) {
|
||||||
|
return runGitCommandWithAuth(args,cwd,auth);
|
||||||
|
} else {
|
||||||
|
return runGitCommand(args,cwd);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getCommits: function(cwd,options) {
|
getCommits: function(cwd,options) {
|
||||||
var args = ["log", "--format=sha: %H%nparents: %p%nrefs: %D%nauthor: %an%ndate: %ct%nsubject: %s%n-----"];
|
var args = ["log", "--format=sha: %H%nparents: %p%nrefs: %D%nauthor: %an%ndate: %ct%nsubject: %s%n-----"];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user