mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch "projects"
This commit is contained in:
@@ -54,8 +54,10 @@ var storageModuleInterface = {
|
||||
} catch (e) {
|
||||
return when.reject(e);
|
||||
}
|
||||
if (storageModule.projects) {
|
||||
storageModuleInterface.projects = storageModule.projects;
|
||||
if (runtime.settings.hasOwnProperty("editorTheme") && runtime.settings.editorTheme.hasOwnProperty("projects")) {
|
||||
if (storageModule.projects) {
|
||||
storageModuleInterface.projects = storageModule.projects;
|
||||
}
|
||||
}
|
||||
if (storageModule.sshkeys) {
|
||||
storageModuleInterface.sshkeys = storageModule.sshkeys;
|
||||
|
@@ -235,7 +235,7 @@ Project.prototype.update = function (user, data) {
|
||||
if (data.git.hasOwnProperty('remotes')) {
|
||||
var remoteNames = Object.keys(data.git.remotes);
|
||||
var remotesChanged = false;
|
||||
var modifyRemotesPromise = when.resolve();
|
||||
var modifyRemotesPromise = Promise.resolve();
|
||||
remoteNames.forEach(function(name) {
|
||||
if (data.git.remotes[name].removed) {
|
||||
remotesChanged = true;
|
||||
@@ -330,6 +330,14 @@ Project.prototype.getFile = function (filePath,treeish) {
|
||||
return fs.readFile(fspath.join(this.path,filePath),"utf8");
|
||||
}
|
||||
};
|
||||
Project.prototype.revertFile = function (filePath) {
|
||||
var self = this;
|
||||
return gitTools.revertFile(this.path, filePath).then(function() {
|
||||
return self.load();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
Project.prototype.status = function(user) {
|
||||
var self = this;
|
||||
@@ -349,7 +357,7 @@ Project.prototype.status = function(user) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fetchPromise = when.resolve();
|
||||
fetchPromise = Promise.resolve();
|
||||
}
|
||||
|
||||
var completeStatus = function(fetchError) {
|
||||
@@ -462,18 +470,23 @@ Project.prototype.getBranches = function (user, isRemote) {
|
||||
if (isRemote) {
|
||||
fetchPromise = self.fetch(user);
|
||||
} else {
|
||||
fetchPromise = when.resolve();
|
||||
fetchPromise = Promise.resolve();
|
||||
}
|
||||
return fetchPromise.then(function() {
|
||||
return gitTools.getBranches(self.path,isRemote);
|
||||
});
|
||||
};
|
||||
|
||||
Project.prototype.deleteBranch = function (user, branch, isRemote, force) {
|
||||
// TODO: isRemote==true support
|
||||
// TODO: make sure we don't try to delete active branch
|
||||
return gitTools.deleteBranch(this.path,branch,isRemote, force);
|
||||
};
|
||||
|
||||
Project.prototype.fetch = function(user,remoteName) {
|
||||
var username;
|
||||
if (!user) {
|
||||
username = "_";
|
||||
console.log(new Error().stack);
|
||||
} else {
|
||||
username = user.username;
|
||||
}
|
||||
@@ -485,7 +498,7 @@ Project.prototype.fetch = function(user,remoteName) {
|
||||
})
|
||||
} else {
|
||||
var remotes = Object.keys(this.remotes);
|
||||
var promise = when.resolve();
|
||||
var promise = Promise.resolve();
|
||||
remotes.forEach(function(remote) {
|
||||
promise = promise.then(function() {
|
||||
return gitTools.fetch(project.path,remote,authCache.get(project.name,project.remotes[remote].fetch,username))
|
||||
@@ -662,7 +675,7 @@ function createProject(user, metadata) {
|
||||
}
|
||||
|
||||
var project = metadata.name;
|
||||
return when.promise(function(resolve,reject) {
|
||||
return new Promise(function(resolve,reject) {
|
||||
var projectPath = fspath.join(projectsDir,project);
|
||||
fs.stat(projectPath, function(err,stat) {
|
||||
if (!err) {
|
||||
|
@@ -23,6 +23,7 @@ var clone = require('clone');
|
||||
var path = require("path");
|
||||
|
||||
var gitCommand = "git";
|
||||
var gitVersion;
|
||||
var log;
|
||||
|
||||
function runGitCommand(args,cwd,env) {
|
||||
@@ -63,11 +64,9 @@ function runGitCommand(args,cwd,env) {
|
||||
err.code = "git_local_overwrite";
|
||||
} else if (/CONFLICT/.test(err.stdout)) {
|
||||
err.code = "git_pull_merge_conflict";
|
||||
} else if (/not fully merged/.test(stderr)) {
|
||||
err.code = "git_delete_branch_unmerged";
|
||||
}
|
||||
console.log("===============================================================");
|
||||
console.log('err:', err);
|
||||
console.log("===============================================================");
|
||||
|
||||
return reject(err);
|
||||
}
|
||||
resolve(stdout);
|
||||
@@ -297,17 +296,37 @@ function getRemotes(cwd) {
|
||||
}
|
||||
|
||||
function getBranches(cwd, remote) {
|
||||
var args = ['branch','--no-color'];
|
||||
var args = ['branch','-vv','--no-color'];
|
||||
if (remote) {
|
||||
args.push('-r');
|
||||
}
|
||||
var branchRE = /^([ \*] )(\S+) +(\S+)(?: \[(\S+?)(?:: (?:ahead (\d+)(?:, )?)?(?:behind (\d+))?)?\])? (.*)$/;
|
||||
return runGitCommand(args,cwd).then(function(output) {
|
||||
var branches = [];
|
||||
var lines = output.split("\n");
|
||||
branches = lines.map(function(l) { return l.substring(2)})
|
||||
.filter(function(l) {
|
||||
return !/HEAD ->/.test(l) && (l.length > 0)
|
||||
});
|
||||
branches = lines.map(function(l) {
|
||||
var m = branchRE.exec(l);
|
||||
var branch = null;
|
||||
if (m) {
|
||||
branch = {
|
||||
name: m[2],
|
||||
remote: m[4],
|
||||
status: {
|
||||
ahead: m[5]||0,
|
||||
behind: m[6]||0,
|
||||
},
|
||||
commit: {
|
||||
sha: m[3],
|
||||
subject: m[7]
|
||||
}
|
||||
}
|
||||
if (m[1] === '* ') {
|
||||
branch.current = true;
|
||||
}
|
||||
}
|
||||
return branch;
|
||||
}).filter(function(v) { return !!v && v.commit.sha !== '->' });
|
||||
|
||||
return {branches:branches};
|
||||
})
|
||||
}
|
||||
@@ -340,6 +359,15 @@ function removeRemote(cwd,name) {
|
||||
module.exports = {
|
||||
init: function(_settings,_runtime) {
|
||||
log = _runtime.log
|
||||
return new Promise(function(resolve,reject) {
|
||||
runGitCommand(["--version"]).then(function(output) {
|
||||
var m = / (\d\S+)/.exec(output);
|
||||
gitVersion = m[1];
|
||||
resolve(gitVersion);
|
||||
}).catch(function(err) {
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
},
|
||||
initRepo: function(cwd) {
|
||||
return runGitCommand(["init"],cwd);
|
||||
@@ -442,6 +470,10 @@ module.exports = {
|
||||
return status.files;
|
||||
})
|
||||
},
|
||||
revertFile: function(cwd, filePath) {
|
||||
var args = ["checkout",filePath];
|
||||
return runGitCommand(args,cwd);
|
||||
},
|
||||
stageFile: function(cwd,file) {
|
||||
var args = ["add"];
|
||||
if (Array.isArray(file)) {
|
||||
@@ -543,6 +575,19 @@ module.exports = {
|
||||
args.push(branchName);
|
||||
return runGitCommand(args,cwd);
|
||||
},
|
||||
deleteBranch: function(cwd, branchName, isRemote, force) {
|
||||
if (isRemote) {
|
||||
throw new Error("Deleting remote branches not supported");
|
||||
}
|
||||
var args = ['branch'];
|
||||
if (force) {
|
||||
args.push('-D');
|
||||
} else {
|
||||
args.push('-d');
|
||||
}
|
||||
args.push(branchName);
|
||||
return runGitCommand(args, cwd);
|
||||
},
|
||||
getBranchStatus: getBranchStatus,
|
||||
addRemote: addRemote,
|
||||
removeRemote: removeRemote
|
||||
|
@@ -29,6 +29,9 @@ var Projects = require("./Project");
|
||||
var settings;
|
||||
var runtime;
|
||||
|
||||
var projectsEnabled;
|
||||
var projectLogMessages = [];
|
||||
|
||||
var projectsDir;
|
||||
var activeProject
|
||||
|
||||
@@ -36,11 +39,15 @@ function init(_settings, _runtime) {
|
||||
settings = _settings;
|
||||
runtime = _runtime;
|
||||
log = runtime.log;
|
||||
gitTools.init(_settings, _runtime);
|
||||
|
||||
Projects.init(settings,runtime);
|
||||
|
||||
projectsDir = fspath.join(settings.userDir,"projects");
|
||||
try {
|
||||
if (settings.editorTheme.projects.enabled === false) {
|
||||
projectLogMessages.push(log._("storage.localfilesystem.projects.disabled"))
|
||||
projectsEnabled = false;
|
||||
}
|
||||
} catch(err) {
|
||||
projectsEnabled = true;
|
||||
}
|
||||
|
||||
if (settings.flowFile) {
|
||||
flowsFile = settings.flowFile;
|
||||
@@ -73,27 +80,39 @@ function init(_settings, _runtime) {
|
||||
credentialsFile = fspath.join(settings.userDir,ffBase+"_cred"+ffExt);
|
||||
credentialsFileBackup = getBackupFilename(credentialsFile)
|
||||
|
||||
if (!settings.readOnly) {
|
||||
return fs.ensureDir(projectsDir)
|
||||
//TODO: this is accessing settings from storage directly as settings
|
||||
// has not yet been initialised. That isn't ideal - can this be deferred?
|
||||
.then(storageSettings.getSettings)
|
||||
.then(function(globalSettings) {
|
||||
if (!globalSettings.projects) {
|
||||
// TODO: Migration Case
|
||||
console.log("TODO: Migration from single file to project");
|
||||
globalSettings.projects = {
|
||||
activeProject: "",
|
||||
projects: {}
|
||||
}
|
||||
return storageSettings.saveSettings(globalSettings);
|
||||
} else {
|
||||
activeProject = globalSettings.projects.activeProject;
|
||||
var setupProjectsPromise;
|
||||
|
||||
if (projectsEnabled) {
|
||||
return gitTools.init(_settings, _runtime).then(function(gitVersion) {
|
||||
if (!gitVersion) {
|
||||
projectLogMessages.push(log._("storage.localfilesystem.projects.git-not-found"))
|
||||
projectsEnabled = false;
|
||||
} else {
|
||||
Projects.init(settings,runtime);
|
||||
projectsDir = fspath.join(settings.userDir,"projects");
|
||||
if (!settings.readOnly) {
|
||||
return fs.ensureDir(projectsDir)
|
||||
//TODO: this is accessing settings from storage directly as settings
|
||||
// has not yet been initialised. That isn't ideal - can this be deferred?
|
||||
.then(storageSettings.getSettings)
|
||||
.then(function(globalSettings) {
|
||||
if (!globalSettings.projects) {
|
||||
// TODO: Migration Case
|
||||
console.log("TODO: Migration from single file to project");
|
||||
globalSettings.projects = {
|
||||
activeProject: "",
|
||||
projects: {}
|
||||
}
|
||||
return storageSettings.saveSettings(globalSettings);
|
||||
} else {
|
||||
activeProject = globalSettings.projects.activeProject;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return when.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
function getUserGitSettings(user) {
|
||||
@@ -173,7 +192,7 @@ function getFileDiff(user, project,file,type) {
|
||||
}
|
||||
function getCommits(user, project,options) {
|
||||
checkActiveProject(project);
|
||||
return activeProject.getCommits(options);
|
||||
return activeProject.getCommits(options);
|
||||
}
|
||||
function getCommit(user, project,sha) {
|
||||
checkActiveProject(project);
|
||||
@@ -184,6 +203,12 @@ function getFile(user, project,filePath,sha) {
|
||||
checkActiveProject(project);
|
||||
return activeProject.getFile(filePath,sha);
|
||||
}
|
||||
function revertFile(user, project,filePath) {
|
||||
checkActiveProject(project);
|
||||
return activeProject.revertFile(filePath).then(function() {
|
||||
return reloadActiveProject("revert");
|
||||
})
|
||||
}
|
||||
function push(user, project,remoteBranchName,setRemote) {
|
||||
checkActiveProject(project);
|
||||
return activeProject.push(user,remoteBranchName,setRemote);
|
||||
@@ -212,6 +237,12 @@ function getBranches(user, project,isRemote) {
|
||||
checkActiveProject(project);
|
||||
return activeProject.getBranches(user, isRemote);
|
||||
}
|
||||
|
||||
function deleteBranch(user, project, branch, isRemote, force) {
|
||||
checkActiveProject(project);
|
||||
return activeProject.deleteBranch(user, branch, isRemote, force);
|
||||
}
|
||||
|
||||
function setBranch(user, project,branchName,isCreate) {
|
||||
checkActiveProject(project);
|
||||
return activeProject.setBranch(branchName,isCreate).then(function() {
|
||||
@@ -251,9 +282,8 @@ function setActiveProject(user, projectName) {
|
||||
var globalProjectSettings = settings.get("projects");
|
||||
globalProjectSettings.activeProject = project.name;
|
||||
return settings.set("projects",globalProjectSettings).then(function() {
|
||||
log.info(log._("storage.localfilesystem.changing-project",{project:activeProject||"none"}));
|
||||
log.info(log._("storage.localfilesystem.projects.changing-project",{project:activeProject||"none"}));
|
||||
log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath}));
|
||||
|
||||
// console.log("Updated file targets to");
|
||||
// console.log(flowsFullPath)
|
||||
// console.log(credentialsFile)
|
||||
@@ -334,11 +364,16 @@ function getFlows() {
|
||||
log.info(log._("storage.localfilesystem.user-dir",{path:settings.userDir}));
|
||||
if (activeProject) {
|
||||
return loadProject(activeProject).then(function() {
|
||||
log.info(log._("storage.localfilesystem.active-project",{project:activeProject.name||"none"}));
|
||||
log.info(log._("storage.localfilesystem.projects.active-project",{project:activeProject.name||"none"}));
|
||||
log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath}));
|
||||
return getFlows();
|
||||
});
|
||||
} else {
|
||||
if (projectsEnabled) {
|
||||
log.warn(log._("storage.localfilesystem.projects.no-active-project"))
|
||||
} else {
|
||||
projectLogMessages.forEach(log.warn);
|
||||
}
|
||||
log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath}));
|
||||
}
|
||||
}
|
||||
@@ -407,6 +442,7 @@ module.exports = {
|
||||
updateProject: updateProject,
|
||||
getFiles: getFiles,
|
||||
getFile: getFile,
|
||||
revertFile: revertFile,
|
||||
stageFile: stageFile,
|
||||
unstageFile: unstageFile,
|
||||
commit: commit,
|
||||
@@ -419,6 +455,7 @@ module.exports = {
|
||||
resolveMerge: resolveMerge,
|
||||
abortMerge: abortMerge,
|
||||
getBranches: getBranches,
|
||||
deleteBranch: deleteBranch,
|
||||
setBranch: setBranch,
|
||||
getBranchStatus:getBranchStatus,
|
||||
|
||||
|
Reference in New Issue
Block a user