Skip to content

Commit

Permalink
[server] infer extensions and add a comment
Browse files Browse the repository at this point in the history
This commit adds vcode extensions to the inferred .gitpod.yml
and adds a comment to the top, that links to the documentation.
  • Loading branch information
svenefftinge authored and roboquat committed Jan 4, 2022
1 parent 46df01a commit 46d55a7
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 12 deletions.
92 changes: 84 additions & 8 deletions components/server/src/config/config-inferrer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,36 @@ async function expect(files: {[path:string]:string}, config: WorkspaceConfig): P
chai.assert.equal(JSON.stringify(result, null, ' '), JSON.stringify(config, null, ' '));
}

describe('config serializer', () => {
it('serialized proper YAML',
async () => {
const config: WorkspaceConfig = {
tasks: [
{
'init': "yarn install",
'command': "yarn run build"
}
],
vscode: {
extensions: [
'foo', 'bar'
]
}
}
const cf = new ConfigInferrer()
chai.assert.equal(cf.toYaml(config),
`tasks:
- init: yarn install
command: yarn run build
vscode:
extensions:
- foo
- bar
`);
}
)
});

describe('config inferrer', () => {
it('check node',
async () => expect({
Expand All @@ -43,7 +73,12 @@ describe('config inferrer', () => {
init: "yarn install && yarn run build",
command: "yarn run watch"
}
]
],
vscode: {
extensions: [
'dbaeumer.vscode-eslint'
]
}
})
),
it('[java] mvn wrapper',
Expand All @@ -55,7 +90,14 @@ describe('config inferrer', () => {
{
init: "./mvnw install -DskipTests=false"
}
]
],
vscode: {
extensions: [
'redhat.java',
'vscjava.vscode-java-debug',
'vscjava.vscode-maven'
]
}
})
),
it('[java] mvn',
Expand All @@ -66,7 +108,14 @@ describe('config inferrer', () => {
{
init: "mvn install -DskipTests=false"
}
]
],
vscode: {
extensions: [
'redhat.java',
'vscjava.vscode-java-debug',
'vscjava.vscode-maven'
]
}
})
),
it('[java] gradle',
Expand All @@ -78,7 +127,13 @@ describe('config inferrer', () => {
{
init: "gradle build"
}
]
],
vscode: {
extensions: [
'redhat.java',
'vscjava.vscode-java-debug'
]
}
})
),
it('[java] gradle wrapper',
Expand All @@ -90,7 +145,13 @@ describe('config inferrer', () => {
{
init: "./gradlew build"
}
]
],
vscode: {
extensions: [
'redhat.java',
'vscjava.vscode-java-debug'
]
}
})
),
it('[python] pip install',
Expand All @@ -101,7 +162,12 @@ describe('config inferrer', () => {
{
init: "pip install -r requirements.txt"
}
]
],
vscode: {
extensions: [
'ms-python.python'
]
}
})
),
it('[go] go install',
Expand All @@ -113,7 +179,12 @@ describe('config inferrer', () => {
init: "go get && go build ./... && go test ./...",
command: "go run"
}
]
],
vscode: {
extensions: [
'golang.go'
]
}
})
),
it('[rust] cargo',
Expand All @@ -125,7 +196,12 @@ describe('config inferrer', () => {
init: "cargo build",
command: "cargo watch -x run"
}
]
],
vscode: {
extensions: [
'matklad.rust-analyzer'
]
}
})
),
it('[make] make',
Expand Down
38 changes: 38 additions & 0 deletions components/server/src/config/config-inferrer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class ConfigInferrer {
} catch (e) {
console.log(e, pckjsonContent);
}
this.addExtension(ctx, 'dbaeumer.vscode-eslint');
}

protected async checkJava(ctx: Context): Promise<void> {
Expand All @@ -74,6 +75,8 @@ export class ConfigInferrer {
cmd = './gradlew';
}
this.addCommand(ctx.config, cmd + ' build', 'init');
this.addExtension(ctx, 'redhat.java');
this.addExtension(ctx, 'vscjava.vscode-java-debug');
return;
}
if (await ctx.exists('pom.xml')) {
Expand All @@ -82,10 +85,23 @@ export class ConfigInferrer {
cmd = './mvnw';
}
this.addCommand(ctx.config, cmd + ' install -DskipTests=false', 'init');
this.addExtension(ctx, 'redhat.java');
this.addExtension(ctx, 'vscjava.vscode-java-debug');
this.addExtension(ctx, 'vscjava.vscode-maven');
return;
}
}

protected addExtension(ctx: Context, extensionName: string) {
if (!ctx.config.vscode || !ctx.config.vscode.extensions) {
ctx.config.vscode = {
extensions: []
};
}
if (ctx.config.vscode.extensions?.indexOf(extensionName) === -1)
ctx.config.vscode.extensions!.push(extensionName);
}

protected async isMake(ctx: Context) {
return await ctx.exists('Makefile') || await ctx.exists('makefile');
}
Expand All @@ -105,15 +121,20 @@ export class ConfigInferrer {
}
if (await ctx.exists('requirements.txt')) {
this.addCommand(ctx.config, 'pip install -r requirements.txt', 'init');
this.addExtension(ctx, 'ms-python.python');
} else if (await ctx.exists('setup.py')) {
this.addCommand(ctx.config, 'pip install .', 'init');
this.addExtension(ctx, 'ms-python.python');
}
if (await ctx.exists('main.py')) {
this.addCommand(ctx.config, 'python main.py', 'command');
this.addExtension(ctx, 'ms-python.python');
} else if (await ctx.exists('app.py')) {
this.addCommand(ctx.config, 'python app.py', 'command');
this.addExtension(ctx, 'ms-python.python');
} else if (await ctx.exists('runserver.py')) {
this.addCommand(ctx.config, 'python runserver.py', 'command');
this.addExtension(ctx, 'ms-python.python');
}
}

Expand All @@ -123,13 +144,15 @@ export class ConfigInferrer {
this.addCommand(ctx.config, 'go build ./...', 'init');
this.addCommand(ctx.config, 'go test ./...', 'init');
this.addCommand(ctx.config, 'go run', 'command');
this.addExtension(ctx, 'golang.go');
}
}

protected async checkRust(ctx: Context) {
if (await ctx.exists('Cargo.toml')) {
this.addCommand(ctx.config, 'cargo build', 'init');
this.addCommand(ctx.config, 'cargo watch -x run', 'command');
this.addExtension(ctx, 'matklad.rust-analyzer');
}
}

Expand Down Expand Up @@ -166,4 +189,19 @@ export class ConfigInferrer {
}
config.tasks[0][phase] = (existing ? existing + ' && ' : '') + command;
}

toYaml(config: WorkspaceConfig): string {
const i = ' ';
let tasks = '';
if (config.tasks) {
tasks = `tasks:\n${i}- ${config.tasks.map(task => Object.entries(task).map(([phase, command]) => `${phase}: ${command}`).join('\n ')).join('\n - ')}`
}
let vscode = '';
if (config.vscode?.extensions) {
vscode = `vscode:\n${i}extensions:\n${config.vscode.extensions.map(extension => `${i + i}- ${extension}`).join('\n')}`
}
return `${tasks}
${vscode}
`;
}
}
13 changes: 9 additions & 4 deletions components/server/src/config/configuration-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,22 @@ export class ConfigurationService {
}
// eagerly fetch for all files that the inferrer usually asks for.
this.requestedPaths.forEach(path => !(path in cache) && readFile(path));
const config: WorkspaceConfig = await new ConfigInferrer().getConfig({
const configInferrer = new ConfigInferrer();
const config: WorkspaceConfig = await configInferrer.getConfig({
config: {},
read: readFile,
exists: async (path: string) => !!(await readFile(path)),
});
if (!config.tasks) {
return;
}
const configString = `tasks:\n - ${config.tasks.map(task => Object.entries(task).map(([phase, command]) => `${phase}: ${command}`).join('\n ')).join('\n - ')}`;
return configString;
const configString = configInferrer.toYaml(config);
return `# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
# and commit this file to your remote git repository to share the goodness with others.
${configString}
`;
}

async fetchRepositoryConfiguration(ctx: TraceContext, user: User, contextURL: string): Promise<string | undefined> {
Expand All @@ -54,7 +60,6 @@ export class ConfigurationService {
return configString;
}


protected async getRepositoryFileProviderAndCommitContext(ctx: TraceContext, user: User, contextURLOrContext: string | CommitContext): Promise<{fileProvider: FileProvider, commitContext: CommitContext}> {
let commitContext: CommitContext;
if (typeof contextURLOrContext === 'string') {
Expand Down

0 comments on commit 46d55a7

Please sign in to comment.