diff --git a/src/pfe/file-watcher/server/src/controllers/projectsController.ts b/src/pfe/file-watcher/server/src/controllers/projectsController.ts index 2f5434750..ef7971060 100644 --- a/src/pfe/file-watcher/server/src/controllers/projectsController.ts +++ b/src/pfe/file-watcher/server/src/controllers/projectsController.ts @@ -146,7 +146,7 @@ export async function createProject(req: ICreateProjectParams): Promise { const projectMetadata = getProjectMetadataById(projectID); const projectInfo: ProjectInfo = await getProjectInfoFromFile(projectMetadata.infoFile); const projectLocation = projectInfo.location; - const projectName = projectUtil.getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); logger.logProjectTrace("Retrieved project information for project " + projectMetadata.infoFile, projectID); logger.logProjectTrace(JSON.stringify(projectInfo), projectID); @@ -1154,7 +1154,7 @@ export function saveProjectInfo(projectID: string, projectInfo: ProjectInfo, sav const projectJSON = JSON.stringify(projectInfo); const infoFile = getProjectMetadataById(projectID).infoFile; projectInfoCache[infoFile] = projectJSON; - const projectName = projectUtil.getProjectNameFromPath(projectInfo.location); + const projectName = utils.getProjectNameFromPath(projectInfo.location); logger.logProjectTrace(JSON.stringify(projectInfoCache), projectID); if (saveIntoJsonFile) { fs.writeFile(infoFile, projectJSON, "utf8", (err) => { diff --git a/src/pfe/file-watcher/server/src/extensions/projectExtensions.ts b/src/pfe/file-watcher/server/src/extensions/projectExtensions.ts index f113b2772..6ce80fdb2 100644 --- a/src/pfe/file-watcher/server/src/extensions/projectExtensions.ts +++ b/src/pfe/file-watcher/server/src/extensions/projectExtensions.ts @@ -24,7 +24,6 @@ import { DockerProject } from "../projects/DockerProject"; import { ShellExtensionProject } from "../projects/ShellExtensionProject"; import { OdoExtensionProject } from "../projects/OdoExtensionProject"; import { ProjectInfo, ProjectCapabilities, defaultProjectCapabilities } from "../projects/Project"; -import { getProjectNameFromPath } from "../projects/projectUtil"; import { workspaceConstants } from "../projects/constants"; export const DOCKER_TYPE = "docker"; @@ -165,7 +164,7 @@ export function getAllProjectTypes(): Array { async function getExtensionProjectHandler(projectInfo: ProjectInfo): Promise { const key = projectInfo.projectID; - const projectName = getProjectNameFromPath(projectInfo.location); + const projectName = utils.getProjectNameFromPath(projectInfo.location); let handler = extensionProjectHandlers[key]; // is there an extension handler for the project? diff --git a/src/pfe/file-watcher/server/src/projects/OdoExtensionProject.ts b/src/pfe/file-watcher/server/src/projects/OdoExtensionProject.ts index bbdf7ce8e..65e7a38fa 100644 --- a/src/pfe/file-watcher/server/src/projects/OdoExtensionProject.ts +++ b/src/pfe/file-watcher/server/src/projects/OdoExtensionProject.ts @@ -22,6 +22,7 @@ import { ProjectInfo, BuildLog, AppLog, ProjectCapabilities, defaultProjectCapab import { Validator } from "./Validator"; import { IExtensionProject } from "../extensions/IExtensionProject"; import { IFileChangeEvent } from "../utils/fileChanges"; +import { getProjectNameFromPath } from "../utils/utils"; // skeleton for the logs originated from the extension json const logsOrigin: logHelper.ILogTypes = { @@ -207,7 +208,7 @@ export class OdoExtensionProject implements IExtensionProject { */ getContainerName = async (projectID: string, projectLocation: string): Promise => { let podName: string = undefined; - const projectName: string = projectUtil.getProjectNameFromPath(projectLocation); + const projectName: string = getProjectNameFromPath(projectLocation); const componentName: string = await projectUtil.getComponentName(projectName); const args: string[] = [ projectLocation, @@ -246,7 +247,7 @@ export class OdoExtensionProject implements IExtensionProject { let appName: string = undefined; const projectInfo: ProjectInfo = await projectUtil.getProjectInfo(projectID); const projectLocation = projectInfo.location; - const projectName = projectUtil.getProjectNameFromPath(projectLocation); + const projectName = getProjectNameFromPath(projectLocation); const args: string[] = [ projectLocation, "", @@ -284,7 +285,7 @@ export class OdoExtensionProject implements IExtensionProject { let appPort: string = undefined; const projectInfo: ProjectInfo = await projectUtil.getProjectInfo(projectID); const projectLocation = projectInfo.location; - const projectName = projectUtil.getProjectNameFromPath(projectLocation); + const projectName = getProjectNameFromPath(projectLocation); const componentName: string = await projectUtil.getComponentName(projectName); const args: string[] = [ projectLocation, @@ -323,7 +324,7 @@ export class OdoExtensionProject implements IExtensionProject { let appBaseURL: string = undefined; const projectInfo: ProjectInfo = await projectUtil.getProjectInfo(projectID); const projectLocation = projectInfo.location; - const projectName = projectUtil.getProjectNameFromPath(projectLocation); + const projectName = getProjectNameFromPath(projectLocation); const componentName: string = await projectUtil.getComponentName(projectName); const args: string[] = [ projectLocation, diff --git a/src/pfe/file-watcher/server/src/projects/ShellExtensionProject.ts b/src/pfe/file-watcher/server/src/projects/ShellExtensionProject.ts index 1c1fab639..d63b34f1b 100644 --- a/src/pfe/file-watcher/server/src/projects/ShellExtensionProject.ts +++ b/src/pfe/file-watcher/server/src/projects/ShellExtensionProject.ts @@ -14,6 +14,7 @@ import fs from "fs-extra"; import * as path from "path"; import * as projectUtil from "./projectUtil"; +import { getProjectNameFromPath } from "../utils/utils"; import { Operation } from "./operation"; import { ProjectInfo, BuildLog, AppLog, ProjectCapabilities, defaultProjectCapabilities } from "./Project"; import { Validator } from "./Validator"; @@ -112,7 +113,7 @@ export class ShellExtensionProject implements IExtensionProject { private setLanguage = async (projectInfo: ProjectInfo): Promise => { const logDir = await logHelper.getLogDir( - projectInfo.projectID, projectUtil.getProjectNameFromPath(projectInfo.location)); + projectInfo.projectID, getProjectNameFromPath(projectInfo.location)); const args = [ projectInfo.location, diff --git a/src/pfe/file-watcher/server/src/projects/Validator.ts b/src/pfe/file-watcher/server/src/projects/Validator.ts index 70a0200b4..90dcebf23 100644 --- a/src/pfe/file-watcher/server/src/projects/Validator.ts +++ b/src/pfe/file-watcher/server/src/projects/Validator.ts @@ -14,7 +14,6 @@ import * as io from "../utils/socket"; import * as locale from "../utils/locale"; import * as logger from "../utils/logger"; import { Operation } from "./operation"; -import { getProjectNameFromPath } from "./projectUtil"; /** * @class @@ -58,7 +57,7 @@ export class Validator { async validateRequiredFiles (requiredFiles: string[]): Promise { if (requiredFiles) { const projectID = this.projectID; - const projectName = getProjectNameFromPath(this.location); + const projectName = utils.getProjectNameFromPath(this.location); const OR_SPLIT = "|"; try { @@ -180,7 +179,7 @@ export class Validator { */ sendResult(): void { const projectID = this.projectID; - const projectName = getProjectNameFromPath(this.location); + const projectName = utils.getProjectNameFromPath(this.location); logger.logProjectInfo("Sending validation result", projectID, projectName); io.emitOnListener("projectValidated", this.result()); } diff --git a/src/pfe/file-watcher/server/src/projects/actions.ts b/src/pfe/file-watcher/server/src/projects/actions.ts index 4fda7f0a6..71897f298 100644 --- a/src/pfe/file-watcher/server/src/projects/actions.ts +++ b/src/pfe/file-watcher/server/src/projects/actions.ts @@ -57,7 +57,7 @@ export const validate = async function(args: IProjectActionParams): Promise<{ op "projectType": projectType, "location": location } as ProjectInfo; - const projectName = projectUtil.getProjectNameFromPath(location); + const projectName = utils.getProjectNameFromPath(location); if (args.extensionID) { projectInfo.extensionID = args.extensionID; } @@ -131,7 +131,7 @@ export const enableautobuild = async function (args: IProjectActionParams): Prom async function enableAndBuild(projectInfo: ProjectInfo): Promise { const projectHandler = await projectExtensions.getProjectHandler(projectInfo); const projectID = projectInfo.projectID; - const projectName = projectUtil.getProjectNameFromPath(projectInfo.location); + const projectName = utils.getProjectNameFromPath(projectInfo.location); if (projectHandler.hasOwnProperty("setAutoBuild")) { const operation = new Operation("enableautobuild", projectInfo); diff --git a/src/pfe/file-watcher/server/src/projects/projectUtil.ts b/src/pfe/file-watcher/server/src/projects/projectUtil.ts index 762b782f3..e4d0913c3 100644 --- a/src/pfe/file-watcher/server/src/projects/projectUtil.ts +++ b/src/pfe/file-watcher/server/src/projects/projectUtil.ts @@ -104,7 +104,7 @@ export async function containerCreate(operation: Operation, script: string, comm const event = "projectCreation"; const projectLocation = operation.projectInfo.location; const projectID = operation.projectInfo.projectID; - const projectName = getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); const projectType = operation.projectInfo.projectType; if (projectList.indexOf(projectID) === -1) projectList.push(projectID); @@ -211,7 +211,7 @@ export async function containerUpdate(operation: Operation, script: string, comm const projectLocation = operation.projectInfo.location; const projectID = operation.projectInfo.projectID; - const projectName = getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); const projectType = operation.projectInfo.projectType; logger.logProjectInfo("Updating container for " + operation.projectInfo.projectType + " project " + projectLocation, projectID, projectName); operation.containerName = await getContainerName(operation.projectInfo); @@ -316,7 +316,7 @@ export async function containerUpdate(operation: Operation, script: string, comm async function executeBuildScript(operation: Operation, script: string, args: Array, event: string): Promise { const projectID = operation.projectInfo.projectID; const projectLocation = operation.projectInfo.location; - const projectName = getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); const projectInfo = { operationId: operation.operationId, projectID: operation.projectInfo.projectID @@ -612,7 +612,7 @@ export async function getProjectMavenSettings(projectInfo: ProjectInfo): Promise export async function getProjectLogs(projectInfo: ProjectInfo): Promise { const projectID = projectInfo.projectID; const projectLocation = projectInfo.location; - const projectName = getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); const projectType = projectInfo.projectType; const projectLogDir = await logHelper.getLogDir(projectID, projectName); const logDirectory = path.join(projectConstants.projectsLogDir, projectLogDir); @@ -655,7 +655,7 @@ export async function getProjectLogs(projectInfo: ProjectInfo): Promise { const projectID = projectInfo.projectID; - const projectName = getProjectNameFromPath(projectInfo.location); + const projectName = utils.getProjectNameFromPath(projectInfo.location); const containerName = await getContainerName(projectInfo); const imagePushRegistry = projectInfo.deploymentRegistry; logger.logProjectInfo("containerDelete: Kill running processes and remove container... ", projectID, projectName); @@ -725,7 +725,7 @@ export function getLogName(projectID: string, projectLocation: string): string { const hash = crypto.createHash("sha1", "utf8").update(projectLocation); let logName = projectConstants.containerPrefix + projectID + "-" + hash.digest("hex"); - const projectName = getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); if (process.env.IN_K8 === "true" && logName.length > 53) { logName = logName.substring(0, 53); @@ -751,7 +751,7 @@ export function getDefaultContainerName(projectID: string, projectLocation: stri } // Sanitize project name to ensure project name only supports lower case letter and number - const projectNameOrigin: string = getProjectNameFromPath(projectLocation); + const projectNameOrigin: string = utils.getProjectNameFromPath(projectLocation); const letterNumber: RegExp = /[A-Za-z0-9]/; const upperCaseLetter: RegExp = /[A-Z]/; const defaultProjectName: string = "cw"; @@ -1249,7 +1249,7 @@ export async function runScript(projectInfo: ProjectInfo, script: string, comman const containerName = await getContainerName(projectInfo); const logName = getLogName(projectInfo.projectID, projectInfo.location); const logDir = await logHelper.getLogDir(projectInfo.projectID, projectInfo.projectName); - const projectName = getProjectNameFromPath(projectInfo.location); + const projectName = utils.getProjectNameFromPath(projectInfo.location); let args = [projectInfo.location, LOCAL_WORKSPACE, projectID, command, containerName, String(projectInfo.autoBuildEnabled), logName, projectInfo.startMode, projectInfo.debugPort, "NONE", logDir]; @@ -1290,7 +1290,7 @@ export async function buildAndRun(operation: Operation, command: string): Promis const projectLocation = operation.projectInfo.location; const projectID = operation.projectInfo.projectID; - const projectName = getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); if (projectList.indexOf(projectID) === -1) projectList.push(projectID); @@ -1446,7 +1446,7 @@ export async function buildAndRun(operation: Operation, command: string): Promis */ async function containerBuildAndRun(event: string, buildInfo: BuildRequest, operation: Operation): Promise { const normalizedProjectLocation = path.resolve(buildInfo.projectLocation); - const projectName = getProjectNameFromPath(normalizedProjectLocation); + const projectName = utils.getProjectNameFromPath(normalizedProjectLocation); const logDir = await logHelper.getLogDir(buildInfo.projectID, projectName); const dockerBuildLog = path.resolve(buildInfo.projectLocation + "/../.logs/" + logDir, logHelper.buildLogs.dockerBuild + logHelper.logExtension); if (process.env.IN_K8 === "true") { @@ -1668,7 +1668,7 @@ async function containerBuildAndRun(event: string, buildInfo: BuildRequest, oper */ async function runLocalContainer(buildInfo: BuildRequest): Promise { const normalizedProjectLocation = path.resolve(buildInfo.projectLocation); - const projectName = getProjectNameFromPath(normalizedProjectLocation); + const projectName = utils.getProjectNameFromPath(normalizedProjectLocation); const logDir = await logHelper.getLogDir(buildInfo.projectID, projectName); const appLog = path.resolve(buildInfo.projectLocation + "/../.logs/" + logDir, logHelper.appLogs.app + logHelper.logExtension); try { @@ -1799,7 +1799,7 @@ export async function isApplicationPodUp(buildInfo: BuildRequest, projectName: s export async function removeProject(projectInfo: ProjectInfo): Promise { const projectID = projectInfo.projectID; - const projectName = getProjectNameFromPath(projectInfo.location); + const projectName = utils.getProjectNameFromPath(projectInfo.location); const containerName = await getContainerName(projectInfo); logger.logProjectInfo("removeProject: Kill running processes and remove container... ", projectID, projectName); logger.logProjectInfo("Project ID: " + projectInfo.projectID, projectID, projectName); @@ -1903,7 +1903,7 @@ async function getPODInfoAndSendToPortal(operation: Operation, event: string = " const projectInfo = operation.projectInfo; const projectLocation = projectInfo.location; const projectID = projectInfo.projectID; - const projectName = getProjectNameFromPath(projectLocation); + const projectName = utils.getProjectNameFromPath(projectLocation); const keyValuePair: UpdateProjectInfoPair = { key: "buildRequest", value: false @@ -2203,26 +2203,8 @@ export async function updateDetailedAppStatus(projectID: string, ip: string, por export async function exposeOverIngress(projectInfo: ProjectInfo, appPort?: number): Promise { if (process.env.IN_K8) { const projectID = projectInfo.projectID; - const projectName = getProjectNameFromPath(projectInfo.location); + const projectName = utils.getProjectNameFromPath(projectInfo.location); projectInfo.appBaseURL = await kubeutil.exposeOverIngress(projectID, projectName, projectInfo.isHttps, appPort, projectInfo.appBaseURL); await projectsController.saveProjectInfo(projectID, projectInfo, true); } } - -/** - * Get the projectName from a path - * - * @param location The project's location - */ -export function getProjectNameFromPath(location: string): string { - const splitPaths = location.split("/"); - const cwIndex = splitPaths.indexOf("codewind-workspace"); - if (cwIndex === -1) { - logger.logError("Unable to get project name from path: codewind-workspace isn't in the path"); - // Fall back to old method if codewind-workspace isn't in the path - return path.basename(location); - } - // Project name is the directory after codewind-workspace - const projectName = splitPaths[cwIndex + 1]; - return projectName; -} diff --git a/src/pfe/file-watcher/server/src/utils/kubeutil.ts b/src/pfe/file-watcher/server/src/utils/kubeutil.ts index 0c9385586..2676543f3 100644 --- a/src/pfe/file-watcher/server/src/utils/kubeutil.ts +++ b/src/pfe/file-watcher/server/src/utils/kubeutil.ts @@ -21,7 +21,7 @@ import * as processManager from "./processManager"; import { ProcessResult } from "./processManager"; import { ProjectInfo } from "../projects/Project"; import * as logHelper from "../projects/logHelper"; -import { getProjectNameFromPath } from "../projects/projectUtil"; +import { getProjectNameFromPath } from "./utils"; const k8s = require("@kubernetes/client-node"); // tslint:disable-line:no-require-imports diff --git a/src/pfe/file-watcher/server/src/utils/logger.ts b/src/pfe/file-watcher/server/src/utils/logger.ts index df05a4292..53c6b3dee 100644 --- a/src/pfe/file-watcher/server/src/utils/logger.ts +++ b/src/pfe/file-watcher/server/src/utils/logger.ts @@ -15,7 +15,7 @@ import * as path from "path"; import { promisify } from "util"; import * as constants from "../projects/constants"; import * as stackTrace from "stack-trace"; -import { getProjectNameFromPath } from "../projects/projectUtil"; +import { getProjectNameFromPath } from "./utils"; const chalk = require("chalk"); // tslint:disable-line:no-require-imports const GENERAL_LOG_FILE_NAME = "Turbine.log"; diff --git a/src/pfe/file-watcher/server/src/utils/utils.ts b/src/pfe/file-watcher/server/src/utils/utils.ts index b448228da..1046bfecb 100644 --- a/src/pfe/file-watcher/server/src/utils/utils.ts +++ b/src/pfe/file-watcher/server/src/utils/utils.ts @@ -13,6 +13,7 @@ import * as fs from "fs"; import * as util from "util"; import * as logger from "./logger"; import * as fse from "fs-extra"; +import * as path from "path"; const promisify = util.promisify; const accessAsync = promisify(fs.access); @@ -156,3 +157,21 @@ export async function asyncReadDir(dir: string): Promise> { return undefined; } } + +/** + * Get the projectName from a path + * + * @param location The project's location + */ +export function getProjectNameFromPath(location: string): string { + const splitPaths = location.split("/"); + const cwIndex = splitPaths.indexOf("codewind-workspace"); + if (cwIndex === -1) { + logger.logError("Unable to get project name from path: codewind-workspace isn't in the path"); + // Fall back to old method if codewind-workspace isn't in the path + return path.basename(location); + } + // Project name is the directory after codewind-workspace + const projectName = splitPaths[cwIndex + 1]; + return projectName; +} diff --git a/src/pfe/file-watcher/server/test/unit-test/tests/projectUtil.module.test.ts b/src/pfe/file-watcher/server/test/unit-test/tests/projectUtil.module.test.ts index 8605be19e..0258eeb7a 100644 --- a/src/pfe/file-watcher/server/test/unit-test/tests/projectUtil.module.test.ts +++ b/src/pfe/file-watcher/server/test/unit-test/tests/projectUtil.module.test.ts @@ -449,35 +449,4 @@ export function projectUtilTestModule(): void { }); } }); - - describe("getProjectNameFromPath", () => { - const tests = [ - { - title: "should return 'projectName' when it's the directory after 'codewind-workspace'", - path: '/codewind-workspace/projectName', - want: 'projectName', - }, - { - title: "should return 'projectName' when the path is normalized", - path: path.resolve('/codewind-workspace/projectName'), - want: 'projectName', - }, - { - title: "should return 'projectName' when subdirectories are given", - path: path.resolve('/codewind-workspace/projectName/templates/default'), - want: 'projectName', - }, - { - title: "returns 'finalDir' as 'codewind-workspace' isn't in the path", - path: path.resolve('/projectName/templates/default/finalDir'), - want: 'finalDir', - }, - ]; - tests.forEach(({ title, path, want }) => { - it(`should return '${want}' when the input is '${path}'`, () => { - const got = projectUtil.getProjectNameFromPath(path); - expect(got).to.equal(want); - }); - }); - }); } diff --git a/src/pfe/file-watcher/server/test/unit-test/tests/utils.module.test.ts b/src/pfe/file-watcher/server/test/unit-test/tests/utils.module.test.ts index 68b664855..8a34ce18e 100644 --- a/src/pfe/file-watcher/server/test/unit-test/tests/utils.module.test.ts +++ b/src/pfe/file-watcher/server/test/unit-test/tests/utils.module.test.ts @@ -362,4 +362,35 @@ export function utilsTestModule(): void { } }); + describe("getProjectNameFromPath", () => { + const tests = [ + { + title: "should return 'projectName' when it's the directory after 'codewind-workspace'", + path: '/codewind-workspace/projectName', + want: 'projectName', + }, + { + title: "should return 'projectName' when the path is normalized", + path: path.resolve('/codewind-workspace/projectName'), + want: 'projectName', + }, + { + title: "should return 'projectName' when subdirectories are given", + path: path.resolve('/codewind-workspace/projectName/templates/default'), + want: 'projectName', + }, + { + title: "returns 'finalDir' as 'codewind-workspace' isn't in the path", + path: path.resolve('/projectName/templates/default/finalDir'), + want: 'finalDir', + }, + ]; + tests.forEach(({ title, path, want }) => { + it(`should return '${want}' when the input is '${path}'`, () => { + const got = utils.getProjectNameFromPath(path); + expect(got).to.equal(want); + }); + }); + }); + }