import { readFileSync, existsSync, readdirSync } from 'fs'; import { join, basename } from 'path'; import { glob } from 'glob'; /** * Detect .NET project type and configuration */ export async function detectDotNet(projectPath) { // Find .csproj files const csprojFiles = await glob('*.csproj', { cwd: projectPath }); if (csprojFiles.length === 0) { // Check for .sln file (solution) const slnFiles = await glob('*.sln', { cwd: projectPath }); if (slnFiles.length > 0) { return { type: 'dotnet-solution', dockerizable: false, reason: 'Solution files require building individual projects', template: null }; } return null; } const csprojFile = csprojFiles[0]; const csprojPath = join(projectPath, csprojFile); const csprojContent = readFileSync(csprojPath, 'utf-8'); // Detect .NET version const targetFrameworkMatch = csprojContent.match(/([^<]+)<\/TargetFramework>/); const targetFramework = targetFrameworkMatch ? targetFrameworkMatch[1] : 'net8.0'; // Extract version number (e.g., net9.0 -> 9.0) const versionMatch = targetFramework.match(/net(\d+\.\d+)/); const dotnetVersion = versionMatch ? versionMatch[1] : '8.0'; // Detect project type const isBlazor = csprojContent.includes('Microsoft.AspNetCore.Components') || csprojContent.includes('MudBlazor') || csprojContent.includes('Blazor'); const isWebAPI = csprojContent.includes('Microsoft.NET.Sdk.Web') && !isBlazor; const isConsole = csprojContent.includes('Microsoft.NET.Sdk') && !csprojContent.includes('Microsoft.NET.Sdk.Web'); // Get assembly name for DLL const assemblyNameMatch = csprojContent.match(/([^<]+)<\/AssemblyName>/); const projectName = basename(csprojFile, '.csproj'); const assemblyName = assemblyNameMatch ? assemblyNameMatch[1] : projectName; const dllName = `${assemblyName}.dll`; if (isBlazor) { return { type: 'dotnet-blazor', dockerizable: true, template: 'dotnet/blazor', port: 8080, entryPoint: dllName, buildCommand: `dotnet publish -c Release`, description: 'Blazor web application', csprojFile, dllName, dotnetVersion, targetFramework }; } if (isWebAPI) { return { type: 'dotnet-webapi', dockerizable: true, template: 'dotnet/webapi', port: 8080, entryPoint: dllName, buildCommand: `dotnet publish -c Release`, description: '.NET Web API', csprojFile, dllName, dotnetVersion, targetFramework }; } if (isConsole) { return { type: 'dotnet-console', dockerizable: true, template: 'dotnet/console', port: null, entryPoint: dllName, buildCommand: `dotnet publish -c Release`, description: '.NET Console application', csprojFile, dllName, dotnetVersion, targetFramework }; } // Default to web return { type: 'dotnet-generic', dockerizable: true, template: 'dotnet/webapi', port: 8080, entryPoint: dllName, buildCommand: `dotnet publish -c Release`, description: '.NET application', csprojFile, dllName, dotnetVersion, targetFramework }; } /** * Get additional info about .NET project */ export async function getDotNetInfo(projectPath) { const csprojFiles = await glob('*.csproj', { cwd: projectPath }); if (csprojFiles.length === 0) { return null; } const csprojFile = csprojFiles[0]; const csprojPath = join(projectPath, csprojFile); const content = readFileSync(csprojPath, 'utf-8'); // Extract package references const packageRefs = content.match(/ { const match = ref.match(/Include="([^"]+)"/); return match ? match[1] : null; }).filter(Boolean); return { csprojFile, packages, hasLaunchSettings: existsSync(join(projectPath, 'Properties', 'launchSettings.json')), hasAppSettings: existsSync(join(projectPath, 'appsettings.json')), hasWwwroot: existsSync(join(projectPath, 'wwwroot')) }; }