Skip to content

[server] infer extensions and add a comment #7392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Comment on lines +49 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the phrasing "to share the goodness with others", but I don't have a better proposal right now.

@gtsiolis Would you have any suggestions to improve this comment? (It's added to every auto-generated .gitpod.yml when you open a Gitpod workspace for any repository that doesn't already have one.)

Note: Let's not block this PR, but work on a better comment in a follow-up PR.


${configString}
`;
Comment on lines +53 to +54
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to add a second empty line at the bottom of the file (can also be fixed in a follow-up):

Suggested change
${configString}
`;
${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