diff --git a/src/commands/deploy.ts b/src/commands/deploy.ts index fd880de..a376de1 100644 --- a/src/commands/deploy.ts +++ b/src/commands/deploy.ts @@ -575,7 +575,7 @@ Additionally, you can also retry the build with the debug flag: return body; } if (body.platformConfig.version) { - // node, dotnet, php, python + // node, dotnet, php, python, golang this.logKeyValue( `${config.platform} version`, body.platformConfig.version, @@ -623,6 +623,7 @@ Additionally, you can also retry the build with the debug flag: case 'python': case 'node': case 'dotnet': + case 'golang': platformVersion = await getPlatformVersion( config.platform, config.path, diff --git a/src/constants.ts b/src/constants.ts index 83d7178..9935e34 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -38,6 +38,7 @@ export const AVAILABLE_PLATFORMS = [ 'static', 'docker', 'next', + 'golang', ]; export const OBJ_PERMISSION = ['public', 'private']; diff --git a/src/services/get-platform-version.ts b/src/services/get-platform-version.ts index 70512af..c61e4b4 100644 --- a/src/services/get-platform-version.ts +++ b/src/services/get-platform-version.ts @@ -22,6 +22,7 @@ async function getPlatformVersion( php: 'php --version', node: 'node --version', dotnet: 'dotnet --version', + golang: 'go version', }; const platformsVersionTrim: { [key: string]: (rawVersion: string) => string; @@ -32,6 +33,8 @@ async function getPlatformVersion( rawVersion.trim().split(' ')[1].split('.').slice(0, 2).join('.'), // ex: 8.2 node: (rawVersion: string) => rawVersion.trim().slice(1).split('.')[0], // ex: 18 dotnet: (rawVersion: string) => rawVersion.trim()[0] + '.0', // ex: 5.0 + golang: (rawVersion: string) => + rawVersion.trim().split(' ')[2].slice(2).split('.').slice(0, 2).join('.'), // ex: 1.22 }; // Below codes are for derived platforms @@ -62,6 +65,9 @@ async function getPlatformVersion( case 'dotnet': pureVersion = await detectDotNetPlatformVersion(projectPath, debug); break; + case 'golang': + pureVersion = await detectGolangPlatformVersion(projectPath, debug); + break; } debug(`pureVersion: ${pureVersion}`); @@ -312,5 +318,56 @@ async function getRequiredDotNetVersion( throw error; } } +function getGolangPlatformVersion(goModData: string): string | null { + const goVersionRegex = /^go\s+([\d.]+)$/; + + const match = goModData + .split('\n') + .find((line) => goVersionRegex.test(line)) + ?.match(goVersionRegex); + + return match ? match[1].replace(/\.\d+$/, '').toString() : null; +} + +async function detectGolangPlatformVersion( + projectPath: string, + debug: DebugLogger, +) { + const supportedGolangVersions = ['1.21', '1.22', '1.23']; + + try { + const goModFile = await findFile(projectPath, 'go.mod'); + + if (!goModFile) { + debug(`Could not find go.mod file in ${projectPath}`); + return null; + } + + const goModData = fs.readFileSync(goModFile, 'utf8'); + + const golangVersion = getGolangPlatformVersion(goModData); + + if (!golangVersion) { + debug('Could not find go version in go.mod file'); + return null; + } + + if (!supportedGolangVersions.find((v) => golangVersion === v)) { + debug(`${golangVersion} is not a supported golang version.`); + return -1; + } + + return golangVersion; + } catch (error) { + if (error.syscall === 'open') { + debug( + `Could not open go.mod to detect the golang version. Skipping... message=${error.message}`, + ); + return null; + } + + throw error; + } +} export default getPlatformVersion; diff --git a/src/utils/detect-platform.ts b/src/utils/detect-platform.ts index 7fd9e83..f075047 100644 --- a/src/utils/detect-platform.ts +++ b/src/utils/detect-platform.ts @@ -14,6 +14,7 @@ export default function detectPlatform(projectPath: string) { const packageJsonFilePath = path.join(projectPath, 'package.json'); const composeJsonFilePath = path.join(projectPath, 'composer.json'); const requirementsTxtFilePath = path.join(projectPath, 'requirements.txt'); + const goModFilePath = path.join(projectPath, 'go.mod'); const [programCSFilePath] = globbySync('**/{Startup.cs,Program.cs}', { cwd: projectPath, @@ -30,6 +31,7 @@ export default function detectPlatform(projectPath: string) { const hasRequirementsTxtFile = existsSync(requirementsTxtFilePath); const hasDockerFile = existsSync(path.join(projectPath, 'Dockerfile')); const hasWPContent = existsSync(path.join(projectPath, 'wp-content')); + const hasGoModFile = existsSync(goModFilePath); const hasCSProjFile = programCSFilePath && @@ -159,6 +161,15 @@ Please specify your platform with --platform=wordpress or docker.`); return 'wordpress'; } + if (hasGoModFile && hasDockerFile) { + throw new Error(`The project contains both of the \`go.mod\` and \`Dockerfile\` files. +Please specify your platform with --platform=golang or docker.`); + } + + if (hasGoModFile) { + return 'golang'; + } + if (hasDockerFile) { return 'docker'; } diff --git a/src/utils/get-port.ts b/src/utils/get-port.ts index 37ac37f..eeaeb3e 100644 --- a/src/utils/get-port.ts +++ b/src/utils/get-port.ts @@ -22,6 +22,7 @@ export function getPort(platform: string): number { export function getDefaultPort(platform: string): number { const ports: IPorts = { dotnet: 80, + golang: 8080, }; return ports[platform] || 3000; }