@eclipse-che/che-devworkspace-generator 0.0.1-d7aefd7 → 7.69.0-8717dbc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +56 -0
  2. package/lib/api/devfile-context.d.ts +19 -0
  3. package/lib/bitbucket/bitbucket-module.d.ts +12 -0
  4. package/lib/bitbucket/bitbucket-module.js +21 -0
  5. package/lib/bitbucket/bitbucket-module.js.map +1 -0
  6. package/lib/bitbucket/bitbucket-resolver.d.ts +17 -0
  7. package/lib/bitbucket/bitbucket-resolver.js +56 -0
  8. package/lib/bitbucket/bitbucket-resolver.js.map +1 -0
  9. package/lib/bitbucket/bitbucket-url.d.ts +22 -0
  10. package/lib/bitbucket/bitbucket-url.js +38 -0
  11. package/lib/bitbucket/bitbucket-url.js.map +1 -0
  12. package/lib/bitbucket-server/bitbucket-server-module.d.ts +12 -0
  13. package/lib/bitbucket-server/bitbucket-server-module.js +21 -0
  14. package/lib/bitbucket-server/bitbucket-server-module.js.map +1 -0
  15. package/lib/bitbucket-server/bitbucket-server-resolver.d.ts +17 -0
  16. package/lib/bitbucket-server/bitbucket-server-resolver.js +64 -0
  17. package/lib/bitbucket-server/bitbucket-server-resolver.js.map +1 -0
  18. package/lib/bitbucket-server/bitbucket-server-url.d.ts +24 -0
  19. package/lib/bitbucket-server/bitbucket-server-url.js +43 -0
  20. package/lib/bitbucket-server/bitbucket-server-url.js.map +1 -0
  21. package/lib/devfile/dev-container-component-finder.d.ts +18 -0
  22. package/lib/devfile/dev-container-component-finder.js +20 -7
  23. package/lib/devfile/dev-container-component-finder.js.map +1 -1
  24. package/lib/devfile/dev-container-component-inserter.d.ts +18 -0
  25. package/lib/devfile/dev-container-component-inserter.js +98 -0
  26. package/lib/devfile/dev-container-component-inserter.js.map +1 -0
  27. package/lib/devfile/devfile-module.d.ts +12 -0
  28. package/lib/devfile/devfile-module.js +2 -0
  29. package/lib/devfile/devfile-module.js.map +1 -1
  30. package/lib/entrypoint.d.ts +11 -0
  31. package/lib/fetch/fetch-module.d.ts +12 -0
  32. package/lib/fetch/url-fetcher.d.ts +9 -0
  33. package/lib/generate.d.ts +16 -0
  34. package/lib/generate.js +32 -21
  35. package/lib/generate.js.map +1 -1
  36. package/lib/github/github-module.d.ts +12 -0
  37. package/lib/github/github-module.js +3 -1
  38. package/lib/github/github-module.js.map +1 -1
  39. package/lib/github/github-resolver.d.ts +17 -0
  40. package/lib/github/github-resolver.js +10 -5
  41. package/lib/github/github-resolver.js.map +1 -1
  42. package/lib/github/github-url.d.ts +27 -0
  43. package/lib/github/github-url.js +7 -9
  44. package/lib/github/github-url.js.map +1 -1
  45. package/lib/inversify/inversify-binding.d.ts +26 -0
  46. package/lib/inversify/inversify-binding.js +6 -0
  47. package/lib/inversify/inversify-binding.js.map +1 -1
  48. package/lib/main.d.ts +38 -0
  49. package/lib/main.js +106 -66
  50. package/lib/main.js.map +1 -1
  51. package/lib/plugin-registry/plugin-registry-module.d.ts +12 -0
  52. package/lib/plugin-registry/plugin-registry-resolver.d.ts +17 -0
  53. package/lib/plugin-registry/plugin-registry-resolver.js +1 -1
  54. package/lib/plugin-registry/plugin-registry-resolver.js.map +1 -1
  55. package/lib/resolve/git-url-resolver.d.ts +5 -0
  56. package/lib/resolve/git-url-resolver.js +43 -0
  57. package/lib/resolve/git-url-resolver.js.map +1 -0
  58. package/lib/resolve/resolve-module.d.ts +12 -0
  59. package/lib/resolve/resolve-module.js +19 -0
  60. package/lib/resolve/resolve-module.js.map +1 -0
  61. package/lib/resolve/resolver.d.ts +22 -0
  62. package/lib/resolve/resolver.js +12 -0
  63. package/lib/resolve/resolver.js.map +1 -0
  64. package/lib/resolve/url.d.ts +35 -0
  65. package/lib/resolve/url.js +12 -0
  66. package/lib/resolve/url.js.map +1 -0
  67. package/lib/types.d.ts +13 -0
  68. package/lib/types.js +17 -0
  69. package/lib/types.js.map +1 -0
  70. package/package.json +6 -4
  71. package/src/bitbucket/bitbucket-module.ts +21 -0
  72. package/src/bitbucket/bitbucket-resolver.ts +46 -0
  73. package/src/bitbucket/bitbucket-url.ts +41 -0
  74. package/src/bitbucket-server/bitbucket-server-module.ts +21 -0
  75. package/src/bitbucket-server/bitbucket-server-resolver.ts +53 -0
  76. package/src/bitbucket-server/bitbucket-server-url.ts +51 -0
  77. package/src/devfile/dev-container-component-finder.ts +23 -4
  78. package/src/devfile/dev-container-component-inserter.ts +49 -0
  79. package/src/devfile/devfile-module.ts +2 -0
  80. package/src/generate.ts +59 -25
  81. package/src/github/github-module.ts +4 -1
  82. package/src/github/github-resolver.ts +17 -9
  83. package/src/github/github-url.ts +8 -9
  84. package/src/inversify/inversify-binding.ts +6 -0
  85. package/src/main.ts +126 -62
  86. package/src/plugin-registry/plugin-registry-resolver.ts +1 -1
  87. package/src/resolve/git-url-resolver.ts +30 -0
  88. package/src/resolve/resolve-module.ts +18 -0
  89. package/src/resolve/resolver.ts +25 -0
  90. package/src/resolve/url.ts +40 -0
  91. package/src/types.ts +14 -0
@@ -0,0 +1,46 @@
1
+ /**********************************************************************
2
+ * Copyright (c) 2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ ***********************************************************************/
10
+
11
+ import { BitbucketUrl } from './bitbucket-url';
12
+ import { injectable } from 'inversify';
13
+ import { Url } from '../resolve/url';
14
+ import { Resolver } from '../resolve/resolver';
15
+
16
+ @injectable()
17
+ export class BitbucketResolver implements Resolver {
18
+ // eslint-disable-next-line max-len
19
+ static readonly BITBUCKET_URL_PATTERN: RegExp =
20
+ /^https:\/\/.*@?bitbucket\.org\/(?<workspaceId>[^\/]+)\/(?<repoName>[^\/]+)(\/(src|branch)\/(?<branchName>[^\/]+))?\/?$/;
21
+
22
+ isValid(url: string): boolean {
23
+ return BitbucketResolver.BITBUCKET_URL_PATTERN.test(url);
24
+ }
25
+
26
+ resolve(url: string): Url {
27
+ const match = BitbucketResolver.BITBUCKET_URL_PATTERN.exec(url);
28
+ if (!match) {
29
+ throw new Error(`Invalid bitbucket URL: ${url}`);
30
+ }
31
+ const workspaceId = this.getGroup(match, 'workspaceId');
32
+ let repoName = this.getGroup(match, 'repoName');
33
+ if (/^[\w-][\w.-]*?\.git$/.test(repoName)) {
34
+ repoName = repoName.substring(0, repoName.length - 4);
35
+ }
36
+ const branchName = this.getGroup(match, 'branchName', 'HEAD');
37
+ return new BitbucketUrl(workspaceId, repoName, branchName);
38
+ }
39
+
40
+ private getGroup(match: RegExpExecArray, groupName: string, defaultValue?: string) {
41
+ if (match.groups && match.groups[groupName]) {
42
+ return match.groups[groupName];
43
+ }
44
+ return defaultValue;
45
+ }
46
+ }
@@ -0,0 +1,41 @@
1
+ /**********************************************************************
2
+ * Copyright (c) 2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ ***********************************************************************/
10
+
11
+ import { Url } from '../resolve/url';
12
+
13
+ export class BitbucketUrl implements Url {
14
+ private static readonly BITBUCKET_URL = 'https://bitbucket.org';
15
+
16
+ constructor(
17
+ private readonly workspaceId: string,
18
+ private readonly repoName: string,
19
+ private readonly branchName: string
20
+ ) {}
21
+
22
+ getContentUrl(path: string): string {
23
+ return `${BitbucketUrl.BITBUCKET_URL}/${this.workspaceId}/${this.repoName}/raw/${this.branchName}/${path}`;
24
+ }
25
+
26
+ getUrl(): string {
27
+ return `${BitbucketUrl.BITBUCKET_URL}/${this.workspaceId}/${this.repoName}/src/${this.branchName}`;
28
+ }
29
+
30
+ getCloneUrl(): string {
31
+ return `${BitbucketUrl.BITBUCKET_URL}/${this.workspaceId}/${this.repoName}.git`;
32
+ }
33
+
34
+ getRepoName(): string {
35
+ return this.repoName;
36
+ }
37
+
38
+ getBranchName(): string {
39
+ return this.branchName;
40
+ }
41
+ }
@@ -0,0 +1,21 @@
1
+ /**********************************************************************
2
+ * Copyright (c) 2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ ***********************************************************************/
10
+ import { ContainerModule, interfaces } from 'inversify';
11
+
12
+ import { BitbucketServerResolver } from './bitbucket-server-resolver';
13
+ import { TYPES } from '../types';
14
+
15
+ const { Resolver } = TYPES;
16
+
17
+ const bitbucketServerModule = new ContainerModule((bind: interfaces.Bind) => {
18
+ bind(Resolver).to(BitbucketServerResolver).inSingletonScope();
19
+ });
20
+
21
+ export { bitbucketServerModule };
@@ -0,0 +1,53 @@
1
+ /**********************************************************************
2
+ * Copyright (c) 2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ ***********************************************************************/
10
+
11
+ import { BitbucketServerUrl } from './bitbucket-server-url';
12
+ import { injectable } from 'inversify';
13
+ import { Url } from '../resolve/url';
14
+ import { Resolver } from '../resolve/resolver';
15
+
16
+ @injectable()
17
+ export class BitbucketServerResolver implements Resolver {
18
+ // eslint-disable-next-line max-len
19
+ static readonly BITBUCKET_URL_PATTERNS: RegExp[] = [
20
+ /^(?<scheme>https?):\/\/(?<host>.*)\/scm\/~(?<user>[^\/]+)\/(?<repo>.*).git$/,
21
+ /^(?<scheme>https?):\/\/(?<host>.*)\/users\/(?<user>[^\/]+)\/repos\/(?<repo>[^\/]+)\/browse(\?at=(?<branch>.*))?$/,
22
+ /^(?<scheme>https?):\/\/(?<host>.*)\/scm\/(?<project>[^\/~]+)\/(?<repo>[^\/]+).git$/,
23
+ /^(?<scheme>https?):\/\/(?<host>.*)\/projects\/(?<project>[^\/]+)\/repos\/(?<repo>[^\/]+)\/browse(\?at=(?<branch>.*))?$/,
24
+ ];
25
+
26
+ isValid(url: string): boolean {
27
+ return BitbucketServerResolver.BITBUCKET_URL_PATTERNS.some(p => p.test(url));
28
+ }
29
+
30
+ resolve(url: string): Url {
31
+ const regExp = BitbucketServerResolver.BITBUCKET_URL_PATTERNS.find(p => p.test(url));
32
+ if (!regExp) {
33
+ throw new Error(`Invalid bitbucket-server URL: ${url}`);
34
+ }
35
+ const match = regExp.exec(url);
36
+ const scheme = this.getGroup(match, 'scheme');
37
+ const hostName = this.getGroup(match, 'host');
38
+ const user = this.getGroup(match, 'user');
39
+ const project = this.getGroup(match, 'project');
40
+ const repo = this.getGroup(match, 'repo');
41
+ let branch = this.getGroup(match, 'branch');
42
+ if (branch !== undefined && branch.startsWith('refs%2Fheads%2F')) {
43
+ branch = branch.substring(15);
44
+ }
45
+ return new BitbucketServerUrl(scheme, hostName, user, project, repo, branch);
46
+ }
47
+
48
+ private getGroup(match: RegExpExecArray, groupName: string): string | undefined {
49
+ if (match.groups && match.groups[groupName]) {
50
+ return match.groups[groupName];
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,51 @@
1
+ /**********************************************************************
2
+ * Copyright (c) 2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ ***********************************************************************/
10
+
11
+ import { Url } from '../resolve/url';
12
+
13
+ export class BitbucketServerUrl implements Url {
14
+ constructor(
15
+ private readonly scheme: string,
16
+ private readonly hostName: string,
17
+ private readonly user: string | undefined,
18
+ private readonly project: string | undefined,
19
+ private readonly repo: string,
20
+ private readonly branch: string | undefined
21
+ ) {}
22
+
23
+ getContentUrl(path: string): string {
24
+ const isUser = this.user !== undefined;
25
+ return `${this.scheme}://${this.hostName}/${isUser ? 'users' : 'projects'}/${
26
+ isUser ? this.user : this.project
27
+ }/repos/${this.repo}/raw/${path}${this.branch !== undefined ? '?/at=' + this.branch : ''}`;
28
+ }
29
+
30
+ getUrl(): string {
31
+ const isUser = this.user !== undefined;
32
+ return `${this.scheme}://${this.hostName}/${isUser ? 'users' : 'projects'}/${
33
+ isUser ? this.user : this.project
34
+ }/repos/${this.repo}${this.branch !== undefined ? '/browse?at=' + this.branch : ''}`;
35
+ }
36
+
37
+ getCloneUrl(): string {
38
+ const isUser = this.user !== undefined;
39
+ return `${this.scheme}://${this.hostName}/scm/${isUser ? '~' + this.user : this.project.toLowerCase()}/${
40
+ this.repo
41
+ }.git`;
42
+ }
43
+
44
+ getRepoName(): string {
45
+ return this.repo;
46
+ }
47
+
48
+ getBranchName(): string {
49
+ return this.branch;
50
+ }
51
+ }
@@ -10,14 +10,26 @@
10
10
 
11
11
  import { DevfileContext } from '../api/devfile-context';
12
12
  import { V1alpha2DevWorkspaceSpecTemplateComponents } from '@devfile/api';
13
- import { injectable } from 'inversify';
13
+ import { inject, injectable } from 'inversify';
14
+ import { DevContainerComponentInserter } from './dev-container-component-inserter';
14
15
 
15
16
  /**
16
17
  * Need to find dev container from main dev workspace
17
18
  */
18
19
  @injectable()
19
20
  export class DevContainerComponentFinder {
20
- async find(devfileContext: DevfileContext): Promise<V1alpha2DevWorkspaceSpecTemplateComponents | undefined> {
21
+ @inject(DevContainerComponentInserter)
22
+ private devContainerComponentInserter: DevContainerComponentInserter;
23
+
24
+ async find(
25
+ devfileContext: DevfileContext,
26
+ injectDefaultComponent?: string,
27
+ defaultComponentImage?: string
28
+ ): Promise<V1alpha2DevWorkspaceSpecTemplateComponents | undefined> {
29
+ // if a devfile contains a parent, we should not add a default dev container
30
+ if (devfileContext.devfile?.parent) {
31
+ return undefined;
32
+ }
21
33
  // search in main devWorkspace
22
34
  const devComponents = devfileContext.devWorkspace.spec?.template?.components
23
35
  ?.filter(component => component.container)
@@ -26,9 +38,16 @@ export class DevContainerComponentFinder {
26
38
  component => component.container && component.container.mountSources !== false
27
39
  );
28
40
 
29
- // only one, fine, else error
30
41
  if (!devComponents || devComponents.length === 0) {
31
- throw new Error('Not able to find any dev container component in DevWorkspace');
42
+ // do not inject a default component if injectDefaultComponent parameter is false
43
+ if (!injectDefaultComponent || injectDefaultComponent !== 'true') {
44
+ return undefined;
45
+ }
46
+ this.devContainerComponentInserter.insert(devfileContext, defaultComponentImage);
47
+
48
+ let devComponents = devfileContext.devWorkspace.spec.template.components.filter(component => component.container);
49
+
50
+ return devComponents[0];
32
51
  } else if (devComponents.length === 1) {
33
52
  return devComponents[0];
34
53
  } else {
@@ -0,0 +1,49 @@
1
+ /**********************************************************************
2
+ * Copyright (c) 2023 Red Hat, Inc.
3
+ *
4
+ * This program and the accompanying materials are made
5
+ * available under the terms of the Eclipse Public License 2.0
6
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
7
+ *
8
+ * SPDX-License-Identifier: EPL-2.0
9
+ ***********************************************************************/
10
+
11
+ import { DevfileContext } from '../api/devfile-context';
12
+ import { V1alpha2DevWorkspaceSpecTemplateComponents } from '@devfile/api';
13
+ import { injectable } from 'inversify';
14
+
15
+ /**
16
+ * Adds a new component on empty devfile with specific name and image
17
+ */
18
+ @injectable()
19
+ export class DevContainerComponentInserter {
20
+ readonly DEFAULT_DEV_CONTAINER_IMAGE = 'quay.io/devfile/universal-developer-image:ubi8-latest';
21
+ readonly DEFAULT_DEV_CONTAINER_NAME = 'dev';
22
+
23
+ async insert(devfileContext: DevfileContext, defaultComponentImage?: string): Promise<void> {
24
+ if (!devfileContext.devWorkspace.spec) {
25
+ devfileContext.devWorkspace.spec = {
26
+ started: true,
27
+ };
28
+ }
29
+ if (!devfileContext.devWorkspace.spec.template) {
30
+ devfileContext.devWorkspace.spec.template = {};
31
+ }
32
+ if (!devfileContext.devWorkspace.spec.template.components) {
33
+ devfileContext.devWorkspace.spec.template.components = [];
34
+ }
35
+
36
+ const devContainerImage = defaultComponentImage ? defaultComponentImage : this.DEFAULT_DEV_CONTAINER_IMAGE;
37
+ console.log(
38
+ `No container component has been found. A default container component with image ${devContainerImage} will be added.`
39
+ );
40
+ const devContainerComponent: V1alpha2DevWorkspaceSpecTemplateComponents = {
41
+ name: this.DEFAULT_DEV_CONTAINER_NAME,
42
+ container: {
43
+ image: devContainerImage,
44
+ },
45
+ };
46
+
47
+ devfileContext.devWorkspace.spec.template.components.push(devContainerComponent);
48
+ }
49
+ }
@@ -10,9 +10,11 @@
10
10
  import { ContainerModule, interfaces } from 'inversify';
11
11
 
12
12
  import { DevContainerComponentFinder } from './dev-container-component-finder';
13
+ import { DevContainerComponentInserter } from './dev-container-component-inserter';
13
14
 
14
15
  const devfileModule = new ContainerModule((bind: interfaces.Bind) => {
15
16
  bind(DevContainerComponentFinder).toSelf().inSingletonScope();
17
+ bind(DevContainerComponentInserter).toSelf().inSingletonScope();
16
18
  });
17
19
 
18
20
  export { devfileModule };
package/src/generate.ts CHANGED
@@ -9,9 +9,11 @@
9
9
  ***********************************************************************/
10
10
 
11
11
  import {
12
+ V221Devfile,
13
+ V221DevfileMetadata,
12
14
  V1alpha2DevWorkspace,
15
+ V1alpha2DevWorkspaceMetadata,
13
16
  V1alpha2DevWorkspaceSpecContributions,
14
- V1alpha2DevWorkspaceSpecTemplateComponents,
15
17
  V1alpha2DevWorkspaceTemplate,
16
18
  V1alpha2DevWorkspaceTemplateSpec,
17
19
  } from '@devfile/api';
@@ -21,30 +23,52 @@ import * as fs from 'fs-extra';
21
23
  import { DevfileContext } from './api/devfile-context';
22
24
  import { DevContainerComponentFinder } from './devfile/dev-container-component-finder';
23
25
 
26
+ type DevfileLike = V221Devfile & {
27
+ metadata: V221DevfileMetadata & {
28
+ generateName?: string;
29
+ };
30
+ };
31
+
24
32
  @injectable()
25
33
  export class Generate {
26
- static readonly MERGE_CONTRIBUTION = 'controller.devfile.io/merge-contribution';
27
-
28
34
  @inject(DevContainerComponentFinder)
29
35
  private devContainerComponentFinder: DevContainerComponentFinder;
30
36
 
31
- async generate(devfileContent: string, editorContent: string, outputFile: string): Promise<DevfileContext> {
32
- const context = await this.generateContent(devfileContent, editorContent);
37
+ async generate(
38
+ devfileContent: string,
39
+ editorContent: string,
40
+ outputFile?: string,
41
+ injectDefaultComponent?: string,
42
+ defaultComponentImage?: string
43
+ ): Promise<DevfileContext> {
44
+ const context = await this.generateContent(
45
+ devfileContent,
46
+ editorContent,
47
+ injectDefaultComponent,
48
+ defaultComponentImage
49
+ );
33
50
 
34
51
  // write the result
35
- // write templates and then DevWorkspace in a single file
36
- const allContentArray = context.devWorkspaceTemplates.map(template => jsYaml.dump(template));
37
- allContentArray.push(jsYaml.dump(context.devWorkspace));
52
+ if (outputFile) {
53
+ // write templates and then DevWorkspace in a single file
54
+ const allContentArray = context.devWorkspaceTemplates.map(template => jsYaml.dump(template));
55
+ allContentArray.push(jsYaml.dump(context.devWorkspace));
38
56
 
39
- const generatedContent = allContentArray.join('---\n');
57
+ const generatedContent = allContentArray.join('---\n');
40
58
 
41
- await fs.writeFile(outputFile, generatedContent, 'utf-8');
59
+ await fs.writeFile(outputFile, generatedContent, 'utf-8');
60
+ }
42
61
 
43
62
  console.log(`DevWorkspace ${context.devWorkspaceTemplates[0].metadata.name} was generated.`);
44
63
  return context;
45
64
  }
46
65
 
47
- async generateContent(devfileContent: string, editorContent: string): Promise<DevfileContext> {
66
+ async generateContent(
67
+ devfileContent: string,
68
+ editorContent: string,
69
+ injectDefaultComponent?: string,
70
+ defaultComponentImage?: string
71
+ ): Promise<DevfileContext> {
48
72
  const devfile = jsYaml.load(devfileContent);
49
73
 
50
74
  // const originalDevfile = Object.assign({}, devfile);
@@ -55,7 +79,7 @@ export class Generate {
55
79
  const editorDevfile = jsYaml.load(editorContent);
56
80
 
57
81
  // transform it into a devWorkspace template
58
- const metadata = editorDevfile.metadata;
82
+ const metadata = this.createDevWorkspaceMetadata(editorDevfile);
59
83
  // add sufix
60
84
  metadata.name = `${metadata.name}-${suffix}`;
61
85
  delete editorDevfile.metadata;
@@ -68,7 +92,7 @@ export class Generate {
68
92
  };
69
93
 
70
94
  // transform it into a devWorkspace
71
- const devfileMetadata = devfile.metadata;
95
+ const devfileMetadata = this.createDevWorkspaceMetadata(devfile, true);
72
96
  const devfileCopy = Object.assign({}, devfile);
73
97
  delete devfileCopy.schemaVersion;
74
98
  delete devfileCopy.metadata;
@@ -84,6 +108,7 @@ export class Generate {
84
108
  metadata: devfileMetadata,
85
109
  spec: {
86
110
  started: true,
111
+ routingClass: 'che',
87
112
  template: devfileCopy,
88
113
  contributions: [editorSpecContribution],
89
114
  },
@@ -99,19 +124,28 @@ export class Generate {
99
124
  suffix,
100
125
  };
101
126
 
102
- // grab container where to inject controller.devfile.io/merge-contribution attribute
103
- let devContainer: V1alpha2DevWorkspaceSpecTemplateComponents = await this.devContainerComponentFinder.find(context);
104
-
105
- // add attributes
106
- let devContainerAttributes = devContainer.attributes;
107
- if (!devContainerAttributes) {
108
- devContainerAttributes = {};
109
- devContainerAttributes[Generate.MERGE_CONTRIBUTION] = true;
110
- devContainer.attributes = devContainerAttributes;
111
- } else {
112
- devContainerAttributes[Generate.MERGE_CONTRIBUTION] = true;
113
- }
127
+ // find devContainer component, add a default one if not found
128
+ await this.devContainerComponentFinder.find(context, injectDefaultComponent, defaultComponentImage);
114
129
 
115
130
  return context;
116
131
  }
132
+
133
+ private createDevWorkspaceMetadata(devfile: DevfileLike, addDevfileContent = false): V1alpha2DevWorkspaceMetadata {
134
+ const devWorkspaceMetadata = {} as V1alpha2DevWorkspaceMetadata;
135
+ const devfileMetadata = devfile.metadata;
136
+
137
+ if (devfileMetadata.name) {
138
+ devWorkspaceMetadata.name = devfileMetadata.name;
139
+ }
140
+ if (devfileMetadata.generateName) {
141
+ devWorkspaceMetadata.generateName = devfileMetadata.generateName;
142
+ }
143
+ if (addDevfileContent) {
144
+ devWorkspaceMetadata.annotations = {
145
+ 'che.eclipse.org/devfile': jsYaml.dump(devfile),
146
+ };
147
+ }
148
+
149
+ return devWorkspaceMetadata;
150
+ }
117
151
  }
@@ -10,9 +10,12 @@
10
10
  import { ContainerModule, interfaces } from 'inversify';
11
11
 
12
12
  import { GithubResolver } from './github-resolver';
13
+ import { TYPES } from '../types';
14
+
15
+ const { Resolver } = TYPES;
13
16
 
14
17
  const githubModule = new ContainerModule((bind: interfaces.Bind) => {
15
- bind(GithubResolver).toSelf().inSingletonScope();
18
+ bind(Resolver).to(GithubResolver).inSingletonScope();
16
19
  });
17
20
 
18
21
  export { githubModule };
@@ -10,29 +10,37 @@
10
10
 
11
11
  import { GithubUrl } from './github-url';
12
12
  import { injectable } from 'inversify';
13
+ import { Url } from '../resolve/url';
14
+ import { Resolver } from '../resolve/resolver';
13
15
 
14
- /**
15
- * Provides a github URL object allowing to interact
16
- */
17
16
  @injectable()
18
- export class GithubResolver {
17
+ export class GithubResolver implements Resolver {
19
18
  // eslint-disable-next-line max-len
20
19
  static readonly GITHUB_URL_PATTERN =
21
- /^(?:http)(?:s)?(?:\:\/\/)github\.com\/(?<repoUser>[^\/]+)\/(?<repoName>[^\/]+)((\/)|(?:\/(blob|tree)\/(?<branchName>[^\/]+)(?:\/(?<subFolder>.*))?))?$/;
20
+ /^(?<scheme>https?):\/\/(?<host>github(\..+)?\.[^\/]+)\/(?<repoUser>[^\/]+)\/(?<repoName>[^\/]+)((\/)|\/(blob|tree)\/(?<branchName>[^\/]+)(?:\/(?<subFolder>.*))?)?$/;
22
21
 
23
- resolve(link: string): GithubUrl {
22
+ isValid(url: string): boolean {
23
+ return GithubResolver.GITHUB_URL_PATTERN.test(url);
24
+ }
25
+
26
+ resolve(link: string): Url {
24
27
  const match = GithubResolver.GITHUB_URL_PATTERN.exec(link);
25
28
  if (!match) {
26
29
  throw new Error(`Invalid github URL: ${link}`);
27
30
  }
31
+ const scheme = this.getGroup(match, 'scheme');
32
+ const hostName = this.getGroup(match, 'host');
28
33
  const repoUser = this.getGroup(match, 'repoUser');
29
- const repoName = this.getGroup(match, 'repoName');
34
+ let repoName = this.getGroup(match, 'repoName');
35
+ if (/^[\w-][\w.-]*?\.git$/.test(repoName)) {
36
+ repoName = repoName.substring(0, repoName.length - 4);
37
+ }
30
38
  const branchName = this.getGroup(match, 'branchName', 'HEAD');
31
39
  const subFolder = this.getGroup(match, 'subFolder');
32
- return new GithubUrl(repoUser, repoName, branchName, subFolder);
40
+ return new GithubUrl(scheme, hostName, repoUser, repoName, branchName, subFolder);
33
41
  }
34
42
 
35
- getGroup(match: RegExpExecArray, groupName: string, defaultValue?: string) {
43
+ private getGroup(match: RegExpExecArray, groupName: string, defaultValue?: string) {
36
44
  if (match.groups && match.groups[groupName]) {
37
45
  return match.groups[groupName];
38
46
  }
@@ -8,14 +8,12 @@
8
8
  * SPDX-License-Identifier: EPL-2.0
9
9
  ***********************************************************************/
10
10
 
11
- /**
12
- * Provides helper methods on top of github URL to get for example raw content of get relative links
13
- */
14
- export class GithubUrl {
15
- // raw link
16
- static readonly RAW_LINK = 'https://raw.githubusercontent.com';
11
+ import { Url } from '../resolve/url';
17
12
 
13
+ export class GithubUrl implements Url {
18
14
  constructor(
15
+ private readonly scheme: string,
16
+ private readonly hostName: string,
19
17
  private readonly repoUser: string,
20
18
  private readonly repoName: string,
21
19
  private readonly branchName: string,
@@ -26,15 +24,16 @@ export class GithubUrl {
26
24
  * Provides the raw link to the given path based on the current repository information
27
25
  */
28
26
  getContentUrl(path: string): string {
29
- return `${GithubUrl.RAW_LINK}/${this.repoUser}/${this.repoName}/${this.branchName}/${path}`;
27
+ const hostName = this.hostName === 'github.com' ? 'githubusercontent.com' : this.hostName;
28
+ return `${this.scheme}://raw.${hostName}/${this.repoUser}/${this.repoName}/${this.branchName}/${path}`;
30
29
  }
31
30
 
32
31
  getUrl(): string {
33
- return `https://github.com/${this.repoUser}/${this.repoName}/tree/${this.branchName}/${this.subFolder}`;
32
+ return `${this.scheme}://${this.hostName}/${this.repoUser}/${this.repoName}/tree/${this.branchName}/${this.subFolder}`;
34
33
  }
35
34
 
36
35
  getCloneUrl(): string {
37
- return `https://github.com/${this.repoUser}/${this.repoName}.git`;
36
+ return `${this.scheme}://${this.hostName}/${this.repoUser}/${this.repoName}.git`;
38
37
  }
39
38
 
40
39
  getRepoName(): string {
@@ -14,7 +14,10 @@ import { Container } from 'inversify';
14
14
  import { devfileModule } from '../devfile/devfile-module';
15
15
  import { fetchModule } from '../fetch/fetch-module';
16
16
  import { githubModule } from '../github/github-module';
17
+ import { resolveModule } from '../resolve/resolve-module';
17
18
  import { pluginRegistryModule } from '../plugin-registry/plugin-registry-module';
19
+ import { bitbucketModule } from '../bitbucket/bitbucket-module';
20
+ import { bitbucketServerModule } from '../bitbucket-server/bitbucket-server-module';
18
21
 
19
22
  /**
20
23
  * Manage all bindings for inversify
@@ -28,6 +31,9 @@ export class InversifyBinding {
28
31
  this.container.load(devfileModule);
29
32
  this.container.load(fetchModule);
30
33
  this.container.load(githubModule);
34
+ this.container.load(bitbucketModule);
35
+ this.container.load(bitbucketServerModule);
36
+ this.container.load(resolveModule);
31
37
  this.container.load(pluginRegistryModule);
32
38
 
33
39
  this.container.bind(Symbol.for('AxiosInstance')).toConstantValue(options.axiosInstance);