mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Allow a project to be located below the root of repo
This commit is contained in:
@@ -53,6 +53,7 @@ function getGitUser(user) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function Project(path) {
|
||||
this.path = path;
|
||||
this.name = fspath.basename(path);
|
||||
@@ -72,7 +73,7 @@ Project.prototype.load = function () {
|
||||
projectSettings = globalProjectSettings.projects[this.name] || {};
|
||||
}
|
||||
}
|
||||
|
||||
this.paths.root = projectSettings.rootPath || "";
|
||||
this.credentialSecret = projectSettings.credentialSecret;
|
||||
this.git = projectSettings.git || { user:{} };
|
||||
|
||||
@@ -83,8 +84,8 @@ Project.prototype.load = function () {
|
||||
return checkProjectFiles(project).then(function(missingFiles) {
|
||||
project.missingFiles = missingFiles;
|
||||
if (missingFiles.indexOf('package.json') === -1) {
|
||||
project.paths['package.json'] = fspath.join(project.path,"package.json");
|
||||
promises.push(fs.readFile(project.paths['package.json'],"utf8").then(function(content) {
|
||||
project.paths['package.json'] = fspath.join(project.paths.root,"package.json");
|
||||
promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(function(content) {
|
||||
try {
|
||||
project.package = util.parseJSON(content);
|
||||
if (project.package.hasOwnProperty('node-red')) {
|
||||
@@ -101,17 +102,19 @@ Project.prototype.load = function () {
|
||||
project.package = {};
|
||||
}
|
||||
}));
|
||||
if (missingFiles.indexOf('README.md') === -1) {
|
||||
project.paths['README.md'] = fspath.join(project.paths.root,"README.md");
|
||||
promises.push(fs.readFile(fspath.join(project.path,project.paths['README.md']),"utf8").then(function(content) {
|
||||
project.description = content;
|
||||
}));
|
||||
} else {
|
||||
project.description = "";
|
||||
}
|
||||
} else {
|
||||
project.package = {};
|
||||
}
|
||||
if (missingFiles.indexOf('README.md') === -1) {
|
||||
project.paths['README.md'] = fspath.join(project.path,"README.md");
|
||||
promises.push(fs.readFile(project.paths['README.md'],"utf8").then(function(content) {
|
||||
project.description = content;
|
||||
}));
|
||||
} else {
|
||||
project.description = "";
|
||||
}
|
||||
|
||||
// if (missingFiles.indexOf('flow.json') !== -1) {
|
||||
// console.log("MISSING FLOW FILE");
|
||||
// } else {
|
||||
@@ -131,6 +134,10 @@ Project.prototype.load = function () {
|
||||
});
|
||||
};
|
||||
|
||||
Project.prototype.getFilePath = function(file) {
|
||||
return fspath.join(this.path,this.paths.root,this.paths[file])
|
||||
}
|
||||
|
||||
Project.prototype.initialise = function(user,data) {
|
||||
var project = this;
|
||||
// if (!this.empty) {
|
||||
@@ -224,6 +231,7 @@ Project.prototype.parseRemoteBranch = function (remoteBranch) {
|
||||
Project.prototype.isEmpty = function () {
|
||||
return this.empty;
|
||||
};
|
||||
|
||||
Project.prototype.isMerging = function() {
|
||||
return this.merging;
|
||||
}
|
||||
@@ -243,6 +251,7 @@ Project.prototype.update = function (user, data) {
|
||||
var savePackage = false;
|
||||
var flowFilesChanged = false;
|
||||
var credentialSecretChanged = false;
|
||||
var reloadProject = false;
|
||||
|
||||
var globalProjectSettings = settings.get("projects");
|
||||
if (!globalProjectSettings.projects.hasOwnProperty(this.name)) {
|
||||
@@ -250,7 +259,6 @@ Project.prototype.update = function (user, data) {
|
||||
saveSettings = true;
|
||||
}
|
||||
|
||||
|
||||
if (data.credentialSecret && data.credentialSecret !== this.credentialSecret) {
|
||||
var existingSecret = data.currentCredentialSecret;
|
||||
var isReset = data.resetCredentialSecret;
|
||||
@@ -278,6 +286,55 @@ Project.prototype.update = function (user, data) {
|
||||
credentialSecretChanged = true;
|
||||
}
|
||||
|
||||
if (this.missingFiles.indexOf('package.json') !== -1) {
|
||||
if (!data.files || !data.files.package) {
|
||||
// Cannot update a project that doesn't have a known package.json
|
||||
return Promise.reject("Cannot update project with missing package.json");
|
||||
}
|
||||
}
|
||||
|
||||
if (data.hasOwnProperty('files')) {
|
||||
this.package['node-red'] = this.package['node-red'] || { settings: {}};
|
||||
if (data.files.hasOwnProperty('package') && data.files.package !== fspath.join(this.paths.root,"package.json")) {
|
||||
// We have a package file. It could be one that doesn't exist yet, or
|
||||
// does exist and we need to load it.
|
||||
if (!/package\.json$/.test(data.files.package)) {
|
||||
return Promise.reject("Invalid package file: "+data.files.package)
|
||||
}
|
||||
var root = data.files.package.substring(0,data.files.package.length-12);
|
||||
this.paths.root = root;
|
||||
this.paths['package.json'] = 'package.json';
|
||||
globalProjectSettings.projects[this.name].rootPath = root;
|
||||
saveSettings = true;
|
||||
// 1. check if it exists
|
||||
if (fs.existsSync(fspath.join(this.path,this.paths.root,this.paths['package.json']))) {
|
||||
// Load the existing one....
|
||||
} else {
|
||||
var newPackage = defaultFileSet["package.json"](this);
|
||||
fs.writeFileSync(fspath.join(this.path,this.paths.root,this.paths['package.json']),newPackage);
|
||||
this.package = JSON.parse(newPackage);
|
||||
}
|
||||
reloadProject = true;
|
||||
flowFilesChanged = true;
|
||||
}
|
||||
|
||||
if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) {
|
||||
this.paths.flowFile = data.files.flow;
|
||||
this.package['node-red'].settings.flowFile = data.files.flow;
|
||||
savePackage = true;
|
||||
flowFilesChanged = true;
|
||||
}
|
||||
if (data.files.hasOwnProperty('credentials') && this.package['node-red'].settings.credentialsFile !== data.files.credentials) {
|
||||
this.paths.credentialsFile = data.files.credentials;
|
||||
this.package['node-red'].settings.credentialsFile = data.files.credentials;
|
||||
// Don't know if the credSecret is invalid or not so clear the flag
|
||||
delete this.credentialSecretInvalid;
|
||||
|
||||
savePackage = true;
|
||||
flowFilesChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.hasOwnProperty('description')) {
|
||||
saveREADME = true;
|
||||
this.description = data.description;
|
||||
@@ -333,47 +390,32 @@ Project.prototype.update = function (user, data) {
|
||||
}
|
||||
}
|
||||
|
||||
if (data.hasOwnProperty('files')) {
|
||||
this.package['node-red'] = this.package['node-red'] || { settings: {}};
|
||||
if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) {
|
||||
this.paths.flowFile = data.files.flow;
|
||||
this.package['node-red'].settings.flowFile = data.files.flow;
|
||||
savePackage = true;
|
||||
flowFilesChanged = true;
|
||||
}
|
||||
if (data.files.hasOwnProperty('credentials') && this.package['node-red'].settings.credentialsFile !== data.files.credentials) {
|
||||
this.paths.credentialsFile = data.files.credentials;
|
||||
this.package['node-red'].settings.credentialsFile = data.files.credentials;
|
||||
// Don't know if the credSecret is invalid or not so clear the flag
|
||||
delete this.credentialSecretInvalid;
|
||||
|
||||
savePackage = true;
|
||||
flowFilesChanged = true;
|
||||
}
|
||||
}
|
||||
if (saveSettings) {
|
||||
promises.push(settings.set("projects",globalProjectSettings));
|
||||
}
|
||||
if (saveREADME) {
|
||||
promises.push(util.writeFile(this.paths['README.md'], this.description));
|
||||
promises.push(util.writeFile(fspath.join(this.path,this.paths['README.md']), this.description));
|
||||
}
|
||||
if (savePackage) {
|
||||
promises.push(fs.readFile(project.paths['package.json'],"utf8").then(content => {
|
||||
promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(content => {
|
||||
var currentPackage = {};
|
||||
try {
|
||||
currentPackage = util.parseJSON(content);
|
||||
} catch(err) {
|
||||
}
|
||||
this.package = Object.assign(currentPackage,this.package);
|
||||
return util.writeFile(this.paths['package.json'], JSON.stringify(this.package,"",4));
|
||||
return util.writeFile(fspath.join(project.path,this.paths['package.json']), JSON.stringify(this.package,"",4));
|
||||
}));
|
||||
}
|
||||
return when.settle(promises).then(function(res) {
|
||||
return {
|
||||
return when.settle(promises).then(res => {
|
||||
if (reloadProject) {
|
||||
return this.load()
|
||||
}
|
||||
}).then(() => { return {
|
||||
flowFilesChanged: flowFilesChanged,
|
||||
credentialSecretChanged: credentialSecretChanged
|
||||
}
|
||||
})
|
||||
}})
|
||||
};
|
||||
|
||||
Project.prototype.getFiles = function () {
|
||||
@@ -384,12 +426,15 @@ Project.prototype.getFiles = function () {
|
||||
throw err;
|
||||
});
|
||||
};
|
||||
|
||||
Project.prototype.stageFile = function(file) {
|
||||
return gitTools.stageFile(this.path,file);
|
||||
};
|
||||
|
||||
Project.prototype.unstageFile = function(file) {
|
||||
return gitTools.unstageFile(this.path,file);
|
||||
}
|
||||
|
||||
Project.prototype.commit = function(user, options) {
|
||||
var self = this;
|
||||
return gitTools.commit(this.path,options.message,getGitUser(user)).then(function() {
|
||||
@@ -399,9 +444,11 @@ Project.prototype.commit = function(user, options) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Project.prototype.getFileDiff = function(file,type) {
|
||||
return gitTools.getFileDiff(this.path,file,type);
|
||||
}
|
||||
|
||||
Project.prototype.getCommits = function(options) {
|
||||
return gitTools.getCommits(this.path,options).catch(function(err) {
|
||||
if (/bad default revision/i.test(err.message) || /ambiguous argument/i.test(err.message) || /does not have any commits yet/i.test(err.message)) {
|
||||
@@ -414,9 +461,11 @@ Project.prototype.getCommits = function(options) {
|
||||
throw err;
|
||||
})
|
||||
}
|
||||
|
||||
Project.prototype.getCommit = function(sha) {
|
||||
return gitTools.getCommit(this.path,sha);
|
||||
}
|
||||
|
||||
Project.prototype.getFile = function (filePath,treeish) {
|
||||
if (treeish !== "_") {
|
||||
return gitTools.getFile(this.path, filePath, treeish);
|
||||
@@ -424,6 +473,7 @@ 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() {
|
||||
@@ -431,8 +481,6 @@ Project.prototype.revertFile = function (filePath) {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
Project.prototype.status = function(user, includeRemote) {
|
||||
var self = this;
|
||||
|
||||
@@ -615,6 +663,7 @@ Project.prototype.resolveMerge = function (file,resolutions) {
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
Project.prototype.abortMerge = function () {
|
||||
var self = this;
|
||||
return gitTools.abortMerge(this.path).then(function() {
|
||||
@@ -675,12 +724,11 @@ Project.prototype.setBranch = function (branchName, isCreate) {
|
||||
return self.load();
|
||||
})
|
||||
};
|
||||
|
||||
Project.prototype.getBranchStatus = function (branchName) {
|
||||
return gitTools.getBranchStatus(this.path,branchName);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Project.prototype.getRemotes = function (user) {
|
||||
return gitTools.getRemotes(this.path).then(function(remotes) {
|
||||
var result = [];
|
||||
@@ -693,12 +741,14 @@ Project.prototype.getRemotes = function (user) {
|
||||
return {remotes:result};
|
||||
})
|
||||
};
|
||||
|
||||
Project.prototype.addRemote = function(user,remote,options) {
|
||||
var project = this;
|
||||
return gitTools.addRemote(this.path,remote,options).then(function() {
|
||||
return project.loadRemotes()
|
||||
});
|
||||
}
|
||||
|
||||
Project.prototype.updateRemote = function(user,remote,options) {
|
||||
var username;
|
||||
if (!user) {
|
||||
@@ -716,6 +766,7 @@ Project.prototype.updateRemote = function(user,remote,options) {
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
Project.prototype.removeRemote = function(user, remote) {
|
||||
// TODO: if this was the last remote using this url, then remove the authCache
|
||||
// details.
|
||||
@@ -725,11 +776,10 @@ Project.prototype.removeRemote = function(user, remote) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Project.prototype.getFlowFile = function() {
|
||||
// console.log("Project.getFlowFile = ",this.paths.flowFile);
|
||||
if (this.paths.flowFile) {
|
||||
return fspath.join(this.path,this.paths.flowFile);
|
||||
return fspath.join(this.path,this.paths.root,this.paths.flowFile);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -742,14 +792,16 @@ Project.prototype.getFlowFileBackup = function() {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Project.prototype.getCredentialsFile = function() {
|
||||
// console.log("Project.getCredentialsFile = ",this.paths.credentialsFile);
|
||||
if (this.paths.credentialsFile) {
|
||||
return fspath.join(this.path,this.paths.credentialsFile);
|
||||
return fspath.join(this.path,this.paths.root,this.paths.credentialsFile);
|
||||
} else {
|
||||
return this.paths.credentialsFile;
|
||||
}
|
||||
}
|
||||
|
||||
Project.prototype.getCredentialsFileBackup = function() {
|
||||
return getBackupFilename(this.getCredentialsFile());
|
||||
}
|
||||
@@ -763,10 +815,11 @@ Project.prototype.export = function () {
|
||||
dependencies: this.package.dependencies||{},
|
||||
empty: this.empty,
|
||||
settings: {
|
||||
credentialsEncrypted: (typeof this.credentialSecret === "string"),
|
||||
credentialsEncrypted: (typeof this.credentialSecret === "string") && this.credentialSecret.length > 0,
|
||||
credentialSecretInvalid: this.credentialSecretInvalid
|
||||
},
|
||||
files: {
|
||||
package: this.paths['package.json'],
|
||||
flow: this.paths.flowFile,
|
||||
credentials: this.paths.credentialsFile
|
||||
},
|
||||
@@ -777,7 +830,6 @@ Project.prototype.export = function () {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function getCredentialsFilename(filename) {
|
||||
filename = filename || "undefined";
|
||||
// TODO: DRY - ./index.js
|
||||
@@ -793,7 +845,6 @@ function getBackupFilename(filename) {
|
||||
var ffDir = fspath.dirname(filename);
|
||||
return fspath.join(ffDir,"."+ffName+".backup");
|
||||
}
|
||||
|
||||
function checkProjectExists(projectPath) {
|
||||
return fs.pathExists(projectPath).then(function(exists) {
|
||||
if (!exists) {
|
||||
@@ -805,7 +856,6 @@ function checkProjectExists(projectPath) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createDefaultProject(user, project) {
|
||||
var projectPath = fspath.join(projectsDir,project.name);
|
||||
// Create a basic skeleton of a project
|
||||
@@ -869,15 +919,15 @@ function createDefaultProject(user, project) {
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function checkProjectFiles(project) {
|
||||
var projectPath = project.path;
|
||||
var projectRoot = project.paths.root;
|
||||
var promises = [];
|
||||
var paths = [];
|
||||
for (var file in defaultFileSet) {
|
||||
if (defaultFileSet.hasOwnProperty(file)) {
|
||||
paths.push(file);
|
||||
promises.push(fs.stat(fspath.join(projectPath,file)));
|
||||
promises.push(fs.stat(fspath.join(projectPath,projectRoot,file)));
|
||||
}
|
||||
}
|
||||
return when.settle(promises).then(function(results) {
|
||||
@@ -900,7 +950,6 @@ function checkProjectFiles(project) {
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
function createProject(user, metadata) {
|
||||
var username;
|
||||
if (!user) {
|
||||
@@ -933,6 +982,9 @@ function createProject(user, metadata) {
|
||||
}
|
||||
projects.projects[project] = {};
|
||||
if (metadata.hasOwnProperty('credentialSecret')) {
|
||||
if (metadata.credentialSecret === "") {
|
||||
metadata.credentialSecret = false;
|
||||
}
|
||||
projects.projects[project].credentialSecret = metadata.credentialSecret;
|
||||
}
|
||||
return settings.set('projects',projects);
|
||||
@@ -970,7 +1022,6 @@ function createProject(user, metadata) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function deleteProject(user, projectPath) {
|
||||
return checkProjectExists(projectPath).then(function() {
|
||||
return fs.remove(projectPath).then(function() {
|
||||
@@ -981,14 +1032,12 @@ function deleteProject(user, projectPath) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function loadProject(projectPath) {
|
||||
return checkProjectExists(projectPath).then(function() {
|
||||
var project = new Project(projectPath);
|
||||
return project.load();
|
||||
});
|
||||
}
|
||||
|
||||
function init(_settings, _runtime) {
|
||||
settings = _settings;
|
||||
runtime = _runtime;
|
||||
|
Reference in New Issue
Block a user