Skip to content

Commit

Permalink
Chrisdias/dotnet (#273)
Browse files Browse the repository at this point in the history
* fixes #264
  • Loading branch information
chrisdias authored May 23, 2018
1 parent d91c7c0 commit cca84aa
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 52 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.0.28 - XX May 2018
* Update .NET Core Dockerfile generation [#264](https://github.com/Microsoft/vscode-docker/issues/264). Per the .NET team, don't generate `docker-compose` files for .NET Core

## 0.0.27 - 19 May 2018
* Fixes indentation problem with Python docker-compose.yml files (thanks @brettcannon) [#242](https://github.com/Microsoft/vscode-docker/pull/242)
* Adds support for showing the Docker explorer in a new viewlet
Expand Down
21 changes: 17 additions & 4 deletions configureWorkspace/config-utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import vscode = require('vscode');

export async function promptForPort(): Promise<string>{
export async function promptForPort(port: number): Promise<string>{
var opt: vscode.InputBoxOptions = {
placeHolder: '3000',
placeHolder: `${port}`,
prompt: 'What port does your app listen on?',
value: '3000'
value: `${port}`
}

return vscode.window.showInputBox(opt);
Expand All @@ -20,10 +20,23 @@ export async function quickPickPlatform(): Promise<string>{
const items: string[] = [];
items.push('Go');
items.push('Java');
items.push('.NET Core');
items.push('.NET Core Console');
items.push('ASP.NET Core');
items.push('Node.js');
items.push('Python');
items.push('Other');

return vscode.window.showQuickPick(items, opt);
}

export async function quickPickOS(): Promise<string> {
var opt: vscode.QuickPickOptions = {
matchOnDescription: true,
matchOnDetail: true,
placeHolder: 'Select Operating System'
}

const items: string[] = ['Windows', 'Linux'];

return vscode.window.showQuickPick(items, opt);
}
221 changes: 188 additions & 33 deletions configureWorkspace/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import * as path from 'path';
import * as fs from 'fs';
import * as pomParser from 'pom-parser';
import * as gradleParser from 'gradle-to-js/lib/parser';
import { promptForPort, quickPickPlatform } from './config-utils';
import * as glob from 'glob';
import { promptForPort, quickPickPlatform, quickPickOS } from './config-utils';
import { reporter } from '../telemetry/telemetry';
import { match } from 'minimatch';

function genDockerFile(serviceName: string, platform: string, port: string, { cmd, author, version, artifactName }: PackageJson): string {
function genDockerFile(serviceName: string, platform: string, os: string, port: string, { cmd, author, version, artifactName }: PackageJson): string {
switch (platform.toLowerCase()) {
case 'node.js':

Expand Down Expand Up @@ -39,17 +41,100 @@ LABEL Name=${serviceName} Version=${version}
EXPOSE ${port}
`;

case '.net core':
case '.net core console':

return `
FROM microsoft/aspnetcore:1
LABEL Name=${serviceName} Version=${version}
ARG source=.
if (os.toLowerCase() === 'windows') {
return `
FROM microsoft/dotnet:2.0-runtime-nanoserver-1709 AS base
WORKDIR /app
FROM microsoft/dotnet:2.0-sdk-nanoserver-1709 AS build
WORKDIR /src
COPY ${serviceName}.csproj ${serviceName}/
RUN dotnet restore ${serviceName}/${serviceName}.csproj
WORKDIR /src/${serviceName}
COPY . .
RUN dotnet build ${serviceName}.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish ${serviceName}.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "${serviceName}.dll"]
`;
} else {
return `
FROM microsoft/dotnet:2.0-runtime AS base
WORKDIR /app
FROM microsoft/dotnet:2.0-sdk AS build
WORKDIR /src
COPY ${serviceName}.csproj ${serviceName}/
RUN dotnet restore ${serviceName}/${serviceName}.csproj
WORKDIR /src/${serviceName}
COPY . .
RUN dotnet build ${serviceName}.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish ${serviceName}.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "${serviceName}.dll"]
`;
}

case 'asp.net core':

if (os.toLowerCase() === 'windows') {
return `
FROM microsoft/aspnetcore:2.0-nanoserver-1709 AS base
WORKDIR /app
EXPOSE ${port}
FROM microsoft/aspnetcore-build:2.0-nanoserver-1709 AS build
WORKDIR /src
COPY ${serviceName}.csproj ${serviceName}/
RUN dotnet restore ${serviceName}/${serviceName}.csproj
WORKDIR /src/${serviceName}
COPY . .
RUN dotnet build ${serviceName}.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish ${serviceName}.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "${serviceName}.dll"]
`;
} else {
return `
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE ${port}
COPY $source .
ENTRYPOINT dotnet ${serviceName}.dll
FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY ${serviceName}.csproj ${serviceName}/
RUN dotnet restore ${serviceName}/${serviceName}.csproj
WORKDIR /src/${serviceName}
COPY . .
RUN dotnet build ${serviceName}.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish ${serviceName}.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "${serviceName}.dll"]
`;
}

case 'python':

Expand Down Expand Up @@ -109,7 +194,7 @@ CMD /usr/games/fortune -a | cowsay
}
}

function genDockerCompose(serviceName: string, platform: string, port: string): string {
function genDockerCompose(serviceName: string, platform: string, os: string, port: string): string {
switch (platform.toLowerCase()) {
case 'node.js':
return `version: '2.1'
Expand All @@ -133,7 +218,19 @@ services:
ports:
- ${port}:${port}`;

case '.net core':
case '.net core console':
// we don't generate compose files for .net core
return `version: '2.1'
services:
${serviceName}:
image: ${serviceName}
build: .
ports:
- ${port}:${port}`;

case 'asp.net core':
// we don't generate compose files for .net core
return `version: '2.1'
services:
Expand Down Expand Up @@ -175,7 +272,7 @@ services:
}
}

function genDockerComposeDebug(serviceName: string, platform: string, port: string, { fullCommand: cmd }: PackageJson): string {
function genDockerComposeDebug(serviceName: string, platform: string, os: string, port: string, { fullCommand: cmd }: PackageJson): string {
switch (platform.toLowerCase()) {
case 'node.js':

Expand Down Expand Up @@ -213,25 +310,27 @@ services:
- ${port}:${port}
`;

case '.net core':
case '.net core console':
// we don't generate compose files for .net core
return `version: '2.1'
services:
${serviceName}:
build:
args:
source: obj/Docker/empty/
labels:
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- DOTNET_USE_POLLING_FILE_WATCHER=1
volumes:
- .:/app
- ~/.nuget/packages:/root/.nuget/packages:ro
- ~/clrdbg:/clrdbg:ro
entrypoint: tail -f /dev/null
`;
image: ${serviceName}
build: .
ports:
- ${port}:${port}`;

case 'asp.net core':
// we don't generate compose files for .net core
return `version: '2.1'
services:
${serviceName}:
image: ${serviceName}
build: .
ports:
- ${port}:${port}`;

case 'python':
return `version: '2.1'
Expand Down Expand Up @@ -277,7 +376,7 @@ services:
}
}

function genDockerIgnoreFile(service, platformType, port) {
function genDockerIgnoreFile(service: string, platformType: string, os: string, port: string) {
// TODO: Add support for other platform types
return `node_modules
npm-debug.log
Expand Down Expand Up @@ -390,6 +489,41 @@ async function readPomOrGradle(folder: vscode.WorkspaceFolder): Promise<PackageJ
return pkg;
}

async function findCSProjFile(folder: vscode.WorkspaceFolder): Promise<string> {
const opt: vscode.QuickPickOptions = {
matchOnDescription: true,
matchOnDetail: true,
placeHolder: 'Select Project'
}

const projectFiles: string[] = await new Promise<string[]>((resolve, reject) => {

glob('**/*.csproj', { cwd: folder.uri.fsPath }, (err, matches: string[]) => {
if (err) {
reject();
} else {
resolve(matches);
}
});

});

if (!projectFiles) {
return;
}

if (projectFiles.length > 1) {
const res = await vscode.window.showQuickPick(projectFiles, opt);
if (res) {
return res.slice(0, -'.csproj'.length);
} else {
return;
}
}

return projectFiles[0].slice(0, -'.csproj'.length);

}
const DOCKER_FILE_TYPES = {
'docker-compose.yml': genDockerCompose,
'docker-compose.debug.yml': genDockerComposeDebug,
Expand Down Expand Up @@ -428,10 +562,28 @@ export async function configure(): Promise<void> {
const platformType = await quickPickPlatform();
if (!platformType) return;

const port = await promptForPort();
var os;
if (platformType.toLowerCase().includes('.net')) {
os = await quickPickOS();
if (!os) return;
}

var port;
if (platformType.toLowerCase().includes('.net')) {
port = await promptForPort(80);
} else {
port = await promptForPort(3000);
}
if (!port) return;

const serviceName = path.basename(folder.uri.fsPath).toLowerCase();
var serviceName: string;
if (platformType.toLowerCase().includes('.net')) {
serviceName = await findCSProjFile(folder);
} else {
serviceName = path.basename(folder.uri.fsPath).toLowerCase();
}
if (!serviceName) return;

let pkg: PackageJson = getDefaultPackageJson();
if (platformType.toLowerCase() === 'java') {
pkg = await readPomOrGradle(folder);
Expand All @@ -440,7 +592,10 @@ export async function configure(): Promise<void> {
}

await Promise.all(Object.keys(DOCKER_FILE_TYPES).map((fileName) => {
return createWorkspaceFileIfNotExists(fileName, DOCKER_FILE_TYPES[fileName]);
// don't generate docker-compose files for .NET Core apps
if (platformType.toLowerCase().includes('.net') && !fileName.includes('docker-compose')) {
return createWorkspaceFileIfNotExists(fileName, DOCKER_FILE_TYPES[fileName]);
}
}));

/* __GDPR__
Expand All @@ -459,10 +614,10 @@ export async function configure(): Promise<void> {
if (fs.existsSync(workspacePath)) {
const item: vscode.MessageItem = await vscode.window.showErrorMessage(`A ${fileName} already exists. Would you like to override it?`, ...YES_OR_NO_PROMPT);
if (item.title.toLowerCase() === 'yes') {
fs.writeFileSync(workspacePath, writerFunction(serviceName, platformType, port, pkg), { encoding: 'utf8' });
fs.writeFileSync(workspacePath, writerFunction(serviceName, platformType, os, port, pkg), { encoding: 'utf8' });
}
} else {
fs.writeFileSync(workspacePath, writerFunction(serviceName, platformType, port, pkg), { encoding: 'utf8' });
fs.writeFileSync(workspacePath, writerFunction(serviceName, platformType, os, port, pkg), { encoding: 'utf8' });
}
}
}
Loading

0 comments on commit cca84aa

Please sign in to comment.