Skip to content

Commit 9fb5eee

Browse files
committed
[server] infer extensions and add a comment
This commit adds vcode extensions to the inferred .gitpod.yml and adds a comment to the top, that links to the documentation.
1 parent 91c09f7 commit 9fb5eee

File tree

3 files changed

+163
-16
lines changed

3 files changed

+163
-16
lines changed

components/server/src/config/config-inferrer.spec.ts

Lines changed: 116 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,36 @@ async function expect(files: {[path:string]:string}, config: WorkspaceConfig): P
2323
chai.assert.equal(JSON.stringify(result, null, ' '), JSON.stringify(config, null, ' '));
2424
}
2525

26+
describe('config serializer', () => {
27+
it('serialized proper YAML',
28+
async () => {
29+
const config: WorkspaceConfig = {
30+
tasks: [
31+
{
32+
'init': "yarn install",
33+
'command': "yarn run build"
34+
}
35+
],
36+
vscode: {
37+
extensions: [
38+
'foo', 'bar'
39+
]
40+
}
41+
}
42+
const cf = new ConfigInferrer()
43+
chai.assert.equal(cf.toYaml(config),
44+
`tasks:
45+
- init: yarn install
46+
command: yarn run build
47+
vscode:
48+
extensions:
49+
- foo
50+
- bar
51+
`);
52+
}
53+
)
54+
});
55+
2656
describe('config inferrer', () => {
2757
it('check node',
2858
async () => expect({
@@ -43,7 +73,13 @@ describe('config inferrer', () => {
4373
init: "yarn install && yarn run build",
4474
command: "yarn run watch"
4575
}
46-
]
76+
],
77+
vscode: {
78+
extensions: [
79+
'dbaeumer.vscode-eslint',
80+
'redhat.vscode-yaml'
81+
]
82+
}
4783
})
4884
),
4985
it('[java] mvn wrapper',
@@ -55,7 +91,15 @@ describe('config inferrer', () => {
5591
{
5692
init: "./mvnw install -DskipTests=false"
5793
}
58-
]
94+
],
95+
vscode: {
96+
extensions: [
97+
'redhat.java',
98+
'vscjava.vscode-java-debug',
99+
'vscjava.vscode-maven',
100+
'redhat.vscode-yaml'
101+
]
102+
}
59103
})
60104
),
61105
it('[java] mvn',
@@ -66,7 +110,15 @@ describe('config inferrer', () => {
66110
{
67111
init: "mvn install -DskipTests=false"
68112
}
69-
]
113+
],
114+
vscode: {
115+
extensions: [
116+
'redhat.java',
117+
'vscjava.vscode-java-debug',
118+
'vscjava.vscode-maven',
119+
'redhat.vscode-yaml'
120+
]
121+
}
70122
})
71123
),
72124
it('[java] gradle',
@@ -78,7 +130,14 @@ describe('config inferrer', () => {
78130
{
79131
init: "gradle build"
80132
}
81-
]
133+
],
134+
vscode: {
135+
extensions: [
136+
'redhat.java',
137+
'vscjava.vscode-java-debug',
138+
'redhat.vscode-yaml'
139+
]
140+
}
82141
})
83142
),
84143
it('[java] gradle wrapper',
@@ -90,7 +149,14 @@ describe('config inferrer', () => {
90149
{
91150
init: "./gradlew build"
92151
}
93-
]
152+
],
153+
vscode: {
154+
extensions: [
155+
'redhat.java',
156+
'vscjava.vscode-java-debug',
157+
'redhat.vscode-yaml'
158+
]
159+
}
94160
})
95161
),
96162
it('[python] pip install',
@@ -101,7 +167,13 @@ describe('config inferrer', () => {
101167
{
102168
init: "pip install -r requirements.txt"
103169
}
104-
]
170+
],
171+
vscode: {
172+
extensions: [
173+
'ms-python.python',
174+
'redhat.vscode-yaml'
175+
]
176+
}
105177
})
106178
),
107179
it('[go] go install',
@@ -113,7 +185,13 @@ describe('config inferrer', () => {
113185
init: "go get && go build ./... && go test ./...",
114186
command: "go run"
115187
}
116-
]
188+
],
189+
vscode: {
190+
extensions: [
191+
'golang.go',
192+
'redhat.vscode-yaml'
193+
]
194+
}
117195
})
118196
),
119197
it('[rust] cargo',
@@ -125,7 +203,13 @@ describe('config inferrer', () => {
125203
init: "cargo build",
126204
command: "cargo watch -x run"
127205
}
128-
]
206+
],
207+
vscode: {
208+
extensions: [
209+
'matklad.rust-analyzer',
210+
'redhat.vscode-yaml'
211+
]
212+
}
129213
})
130214
),
131215
it('[make] make',
@@ -136,7 +220,12 @@ describe('config inferrer', () => {
136220
{
137221
init: "make"
138222
}
139-
]
223+
],
224+
vscode: {
225+
extensions: [
226+
'redhat.vscode-yaml'
227+
]
228+
}
140229
})
141230
),
142231
it('[make] cmake',
@@ -147,7 +236,12 @@ describe('config inferrer', () => {
147236
{
148237
init: "cmake ."
149238
}
150-
]
239+
],
240+
vscode: {
241+
extensions: [
242+
'redhat.vscode-yaml'
243+
]
244+
}
151245
})
152246
),
153247
it('[dotnet] nuget',
@@ -158,7 +252,12 @@ describe('config inferrer', () => {
158252
{
159253
init: 'nuget install'
160254
}
161-
]
255+
],
256+
vscode: {
257+
extensions: [
258+
'redhat.vscode-yaml'
259+
]
260+
}
162261
})
163262
),
164263
it('[ruby] gemfile',
@@ -169,7 +268,12 @@ describe('config inferrer', () => {
169268
{
170269
init: 'bundle install'
171270
}
172-
]
271+
],
272+
vscode: {
273+
extensions: [
274+
'redhat.vscode-yaml'
275+
]
276+
}
173277
})
174278
)
175279
})

components/server/src/config/config-inferrer.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export class ConfigInferrer {
6565
} catch (e) {
6666
console.log(e, pckjsonContent);
6767
}
68+
this.addExtension(ctx, 'dbaeumer.vscode-eslint');
6869
}
6970

7071
protected async checkJava(ctx: Context): Promise<void> {
@@ -74,6 +75,8 @@ export class ConfigInferrer {
7475
cmd = './gradlew';
7576
}
7677
this.addCommand(ctx.config, cmd + ' build', 'init');
78+
this.addExtension(ctx, 'redhat.java');
79+
this.addExtension(ctx, 'vscjava.vscode-java-debug');
7780
return;
7881
}
7982
if (await ctx.exists('pom.xml')) {
@@ -82,10 +85,23 @@ export class ConfigInferrer {
8285
cmd = './mvnw';
8386
}
8487
this.addCommand(ctx.config, cmd + ' install -DskipTests=false', 'init');
88+
this.addExtension(ctx, 'redhat.java');
89+
this.addExtension(ctx, 'vscjava.vscode-java-debug');
90+
this.addExtension(ctx, 'vscjava.vscode-maven');
8591
return;
8692
}
8793
}
8894

95+
protected addExtension(ctx: Context, extensionName: string) {
96+
if (!ctx.config.vscode || !ctx.config.vscode.extensions) {
97+
ctx.config.vscode = {
98+
extensions: []
99+
};
100+
}
101+
if (ctx.config.vscode.extensions?.indexOf(extensionName) === -1)
102+
ctx.config.vscode.extensions!.push(extensionName);
103+
}
104+
89105
protected async isMake(ctx: Context) {
90106
return await ctx.exists('Makefile') || await ctx.exists('makefile');
91107
}
@@ -105,15 +121,20 @@ export class ConfigInferrer {
105121
}
106122
if (await ctx.exists('requirements.txt')) {
107123
this.addCommand(ctx.config, 'pip install -r requirements.txt', 'init');
124+
this.addExtension(ctx, 'ms-python.python');
108125
} else if (await ctx.exists('setup.py')) {
109126
this.addCommand(ctx.config, 'pip install .', 'init');
127+
this.addExtension(ctx, 'ms-python.python');
110128
}
111129
if (await ctx.exists('main.py')) {
112130
this.addCommand(ctx.config, 'python main.py', 'command');
131+
this.addExtension(ctx, 'ms-python.python');
113132
} else if (await ctx.exists('app.py')) {
114133
this.addCommand(ctx.config, 'python app.py', 'command');
134+
this.addExtension(ctx, 'ms-python.python');
115135
} else if (await ctx.exists('runserver.py')) {
116136
this.addCommand(ctx.config, 'python runserver.py', 'command');
137+
this.addExtension(ctx, 'ms-python.python');
117138
}
118139
}
119140

@@ -123,13 +144,15 @@ export class ConfigInferrer {
123144
this.addCommand(ctx.config, 'go build ./...', 'init');
124145
this.addCommand(ctx.config, 'go test ./...', 'init');
125146
this.addCommand(ctx.config, 'go run', 'command');
147+
this.addExtension(ctx, 'golang.go');
126148
}
127149
}
128150

129151
protected async checkRust(ctx: Context) {
130152
if (await ctx.exists('Cargo.toml')) {
131153
this.addCommand(ctx.config, 'cargo build', 'init');
132154
this.addCommand(ctx.config, 'cargo watch -x run', 'command');
155+
this.addExtension(ctx, 'matklad.rust-analyzer');
133156
}
134157
}
135158

@@ -166,4 +189,19 @@ export class ConfigInferrer {
166189
}
167190
config.tasks[0][phase] = (existing ? existing + ' && ' : '') + command;
168191
}
192+
193+
toYaml(config: WorkspaceConfig): string {
194+
const i = ' ';
195+
let tasks = '';
196+
if (config.tasks) {
197+
tasks = `tasks:\n${i}- ${config.tasks.map(task => Object.entries(task).map(([phase, command]) => `${phase}: ${command}`).join('\n ')).join('\n - ')}`
198+
}
199+
let vscode = '';
200+
if (config.vscode?.extensions) {
201+
vscode = `vscode:\n${i}extensions:\n${config.vscode.extensions.map(extension => `${i + i}- ${extension}`).join('\n')}`
202+
}
203+
return `${tasks}
204+
${vscode}
205+
`;
206+
}
169207
}

components/server/src/config/configuration-service.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,22 @@ export class ConfigurationService {
3636
}
3737
// eagerly fetch for all files that the inferrer usually asks for.
3838
this.requestedPaths.forEach(path => !(path in cache) && readFile(path));
39-
const config: WorkspaceConfig = await new ConfigInferrer().getConfig({
39+
const configInferrer = new ConfigInferrer();
40+
const config: WorkspaceConfig = await configInferrer.getConfig({
4041
config: {},
4142
read: readFile,
4243
exists: async (path: string) => !!(await readFile(path)),
4344
});
4445
if (!config.tasks) {
4546
return;
4647
}
47-
const configString = `tasks:\n - ${config.tasks.map(task => Object.entries(task).map(([phase, command]) => `${phase}: ${command}`).join('\n ')).join('\n - ')}`;
48-
return configString;
48+
const configString = configInferrer.toYaml(config);
49+
return `# This configuration file was automatically generated by Gitpod.
50+
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
51+
# and commit this file to your remote git repository to share the goodness with others.
52+
53+
${configString}
54+
`;
4955
}
5056

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

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

0 commit comments

Comments
 (0)