diff --git a/editor/js/main.js b/editor/js/main.js index f97374b0e..b900fd28f 100644 --- a/editor/js/main.js +++ b/editor/js/main.js @@ -214,6 +214,18 @@ } ] } + } else if (msg.error === "missing_package_file") { + if (RED.user.hasPermission("projects.write")) { + options.buttons = [ + { + text: "Create default package file", + click: function() { + persistentNotifications[notificationId].hideNotification(); + RED.projects.createDefaultPackageFile(); + } + } + ] + } } else if (msg.error === "project_empty") { if (RED.user.hasPermission("projects.write")) { options.buttons = [ diff --git a/editor/js/ui/projects/projects.js b/editor/js/ui/projects/projects.js index 022799ca9..d7c2787d8 100644 --- a/editor/js/ui/projects/projects.js +++ b/editor/js/ui/projects/projects.js @@ -2251,6 +2251,43 @@ RED.projects = (function() { createProjectOptions = {}; show('default-files',{existingProject: true}); } + function createDefaultPackageFile() { + RED.deploy.setDeployInflight(true); + RED.projects.settings.switchProject(activeProject.name); + + var method = "PUT"; + var url = "projects/"+activeProject.name; + var createProjectOptions = { + initialise: true + }; + sendRequest({ + url: url, + type: method, + requireCleanWorkspace: true, + handleAuthFail: false, + responses: { + 200: function(data) { }, + 400: { + 'git_error': function(error) { + console.log("git error",error); + }, + 'missing_flow_file': function(error) { + // This is a natural next error - but let the runtime event + // trigger the dialog rather than double-report it. + $( dialog ).dialog( "close" ); + }, + '*': function(error) { + reportUnexpectedError(error); + $( dialog ).dialog( "close" ); + } + } + } + },createProjectOptions).always(function() { + setTimeout(function() { + RED.deploy.setDeployInflight(false); + },500); + }) + } function refresh(done) { $.getJSON("projects",function(data) { @@ -2330,6 +2367,7 @@ RED.projects = (function() { RED.projects.settings.show('deps'); }, createDefaultFileSet: createDefaultFileSet, + createDefaultPackageFile: createDefaultPackageFile, // showSidebar: showSidebar, refresh: refresh, editProject: function() { diff --git a/red/api/editor/locales/en-US/editor.json b/red/api/editor/locales/en-US/editor.json index 189dbaba7..ed74b8232 100644 --- a/red/api/editor/locales/en-US/editor.json +++ b/red/api/editor/locales/en-US/editor.json @@ -93,6 +93,7 @@ "credentials_load_failed": "

Flows stopped as the credentials could not be decrypted.

The flow credential file is encrypted, but the project's encryption key is missing or invalid.

", "credentials_load_failed_reset":"

Credentials could not be decrypted

The flow credential file is encrypted, but the project's encryption key is missing or invalid.

The flow credential file will be reset on the next deployment. Any existing flow credentials will be cleared.

", "missing_flow_file": "

Project flow file not found.

The project is not configured with a flow file.

", + "missing_package_file": "

Project package file not found.

The project is missing a package.json file.

", "project_empty": "

The project is empty.

Do you want to create a default set of project files?
Otherwise, you will have to manually add files to the project outside of the editor.

", "project_not_found": "

Project '__project__' not found.

", "git_merge_conflict": "

Automatic merging of changes failed.

Fix the unmerged conflicts then commit the results.

" diff --git a/red/runtime/storage/localfilesystem/projects/Project.js b/red/runtime/storage/localfilesystem/projects/Project.js index aa2693001..72682c25c 100644 --- a/red/runtime/storage/localfilesystem/projects/Project.js +++ b/red/runtime/storage/localfilesystem/projects/Project.js @@ -81,9 +81,7 @@ Project.prototype.load = function () { var promises = []; return checkProjectFiles(project).then(function(missingFiles) { - if (missingFiles.length > 0) { - project.missingFiles = 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) { @@ -135,9 +133,9 @@ Project.prototype.load = function () { Project.prototype.initialise = function(user,data) { var project = this; - if (!this.empty) { - throw new Error("Cannot initialise non-empty project"); - } + // if (!this.empty) { + // throw new Error("Cannot initialise non-empty project"); + // } var files = Object.keys(defaultFileSet); var promises = []; @@ -148,17 +146,25 @@ Project.prototype.initialise = function(user,data) { promises.push(settings.set('projects',projects)); } - project.files.flow = data.files.flow; - project.files.credentials = data.files.credentials; - var flowFilePath = fspath.join(project.path,project.files.flow); - var credsFilePath = getCredentialsFilename(flowFilePath); - promises.push(util.writeFile(flowFilePath,"[]")); - promises.push(util.writeFile(credsFilePath,"{}")); - files.push(project.files.flow); - files.push(project.files.credentials); + if (data.hasOwnProperty('files')) { + if (data.files.hasOwnProperty('flow') && data.files.hasOwnProperty('credentials')) { + project.files.flow = data.files.flow; + project.files.credentials = data.files.credentials; + var flowFilePath = fspath.join(project.path,project.files.flow); + var credsFilePath = getCredentialsFilename(flowFilePath); + promises.push(util.writeFile(flowFilePath,"[]")); + promises.push(util.writeFile(credsFilePath,"{}")); + files.push(project.files.flow); + files.push(project.files.credentials); + } + } for (var file in defaultFileSet) { if (defaultFileSet.hasOwnProperty(file)) { - promises.push(util.writeFile(fspath.join(project.path,file),defaultFileSet[file](project))); + var path = fspath.join(project.path,file); + if (!fs.existsSync(path)) { + promises.push(util.writeFile(path,defaultFileSet[file](project))); + } + } } diff --git a/red/runtime/storage/localfilesystem/projects/index.js b/red/runtime/storage/localfilesystem/projects/index.js index 7c24845ab..4c7539260 100644 --- a/red/runtime/storage/localfilesystem/projects/index.js +++ b/red/runtime/storage/localfilesystem/projects/index.js @@ -479,6 +479,12 @@ function getFlows() { error.code = "project_empty"; return when.reject(error); } + if (activeProject.missingFiles && activeProject.missingFiles.indexOf('package.json') !== -1) { + log.warn("Project missing package.json"); + error = new Error("Project missing package.json"); + error.code = "missing_package_file"; + return when.reject(error); + } if (!activeProject.getFlowFile()) { log.warn("Project has no flow file"); error = new Error("Project has no flow file");