@eclipse-che/che-devworkspace-generator 0.0.1-a00c266 → 0.0.1-b3f6c7c

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 (82) hide show
  1. package/README.md +42 -14
  2. package/lib/bitbucket/bitbucket-module.d.ts +12 -0
  3. package/lib/bitbucket/bitbucket-module.js +21 -0
  4. package/lib/bitbucket/bitbucket-module.js.map +1 -0
  5. package/lib/bitbucket/bitbucket-resolver.d.ts +17 -0
  6. package/lib/bitbucket/bitbucket-resolver.js +56 -0
  7. package/lib/bitbucket/bitbucket-resolver.js.map +1 -0
  8. package/lib/bitbucket/bitbucket-url.d.ts +22 -0
  9. package/lib/bitbucket/bitbucket-url.js +38 -0
  10. package/lib/bitbucket/bitbucket-url.js.map +1 -0
  11. package/lib/bitbucket-server/bitbucket-server-module.d.ts +12 -0
  12. package/lib/bitbucket-server/bitbucket-server-module.js +21 -0
  13. package/lib/bitbucket-server/bitbucket-server-module.js.map +1 -0
  14. package/lib/bitbucket-server/bitbucket-server-resolver.d.ts +17 -0
  15. package/lib/bitbucket-server/bitbucket-server-resolver.js +64 -0
  16. package/lib/bitbucket-server/bitbucket-server-resolver.js.map +1 -0
  17. package/lib/bitbucket-server/bitbucket-server-url.d.ts +24 -0
  18. package/lib/bitbucket-server/bitbucket-server-url.js +43 -0
  19. package/lib/bitbucket-server/bitbucket-server-url.js.map +1 -0
  20. package/lib/devfile/dev-container-component-finder.d.ts +2 -1
  21. package/lib/devfile/dev-container-component-finder.js +20 -7
  22. package/lib/devfile/dev-container-component-finder.js.map +1 -1
  23. package/lib/devfile/dev-container-component-inserter.d.ts +18 -0
  24. package/lib/devfile/dev-container-component-inserter.js +98 -0
  25. package/lib/devfile/dev-container-component-inserter.js.map +1 -0
  26. package/lib/devfile/devfile-module.js +2 -0
  27. package/lib/devfile/devfile-module.js.map +1 -1
  28. package/lib/generate.d.ts +3 -3
  29. package/lib/generate.js +29 -21
  30. package/lib/generate.js.map +1 -1
  31. package/lib/github/github-module.js +3 -1
  32. package/lib/github/github-module.js.map +1 -1
  33. package/lib/github/github-resolver.d.ts +6 -7
  34. package/lib/github/github-resolver.js +10 -5
  35. package/lib/github/github-resolver.js.map +1 -1
  36. package/lib/github/github-url.d.ts +5 -6
  37. package/lib/github/github-url.js +7 -9
  38. package/lib/github/github-url.js.map +1 -1
  39. package/lib/inversify/inversify-binding.js +6 -0
  40. package/lib/inversify/inversify-binding.js.map +1 -1
  41. package/lib/main.d.ts +4 -1
  42. package/lib/main.js +41 -27
  43. package/lib/main.js.map +1 -1
  44. package/lib/plugin-registry/plugin-registry-resolver.js +1 -1
  45. package/lib/plugin-registry/plugin-registry-resolver.js.map +1 -1
  46. package/lib/resolve/git-url-resolver.d.ts +5 -0
  47. package/lib/resolve/git-url-resolver.js +43 -0
  48. package/lib/resolve/git-url-resolver.js.map +1 -0
  49. package/lib/resolve/resolve-module.d.ts +12 -0
  50. package/lib/resolve/resolve-module.js +19 -0
  51. package/lib/resolve/resolve-module.js.map +1 -0
  52. package/lib/resolve/resolver.d.ts +22 -0
  53. package/lib/resolve/resolver.js +12 -0
  54. package/lib/resolve/resolver.js.map +1 -0
  55. package/lib/resolve/url.d.ts +35 -0
  56. package/lib/resolve/url.js +12 -0
  57. package/lib/resolve/url.js.map +1 -0
  58. package/lib/types.d.ts +13 -0
  59. package/lib/types.js +17 -0
  60. package/lib/types.js.map +1 -0
  61. package/package.json +1 -1
  62. package/src/bitbucket/bitbucket-module.ts +21 -0
  63. package/src/bitbucket/bitbucket-resolver.ts +46 -0
  64. package/src/bitbucket/bitbucket-url.ts +41 -0
  65. package/src/bitbucket-server/bitbucket-server-module.ts +21 -0
  66. package/src/bitbucket-server/bitbucket-server-resolver.ts +53 -0
  67. package/src/bitbucket-server/bitbucket-server-url.ts +51 -0
  68. package/src/devfile/dev-container-component-finder.ts +23 -4
  69. package/src/devfile/dev-container-component-inserter.ts +49 -0
  70. package/src/devfile/devfile-module.ts +2 -0
  71. package/src/generate.ts +52 -20
  72. package/src/github/github-module.ts +4 -1
  73. package/src/github/github-resolver.ts +17 -9
  74. package/src/github/github-url.ts +8 -9
  75. package/src/inversify/inversify-binding.ts +6 -0
  76. package/src/main.ts +47 -23
  77. package/src/plugin-registry/plugin-registry-resolver.ts +1 -1
  78. package/src/resolve/git-url-resolver.ts +30 -0
  79. package/src/resolve/resolve-module.ts +18 -0
  80. package/src/resolve/resolver.ts +25 -0
  81. package/src/resolve/url.ts +40 -0
  82. package/src/types.ts +14 -0
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,15 +23,30 @@ 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
52
  if (outputFile) {
@@ -46,7 +63,12 @@ export class Generate {
46
63
  return context;
47
64
  }
48
65
 
49
- 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> {
50
72
  const devfile = jsYaml.load(devfileContent);
51
73
 
52
74
  // const originalDevfile = Object.assign({}, devfile);
@@ -57,7 +79,7 @@ export class Generate {
57
79
  const editorDevfile = jsYaml.load(editorContent);
58
80
 
59
81
  // transform it into a devWorkspace template
60
- const metadata = editorDevfile.metadata;
82
+ const metadata = this.createDevWorkspaceMetadata(editorDevfile);
61
83
  // add sufix
62
84
  metadata.name = `${metadata.name}-${suffix}`;
63
85
  delete editorDevfile.metadata;
@@ -70,7 +92,7 @@ export class Generate {
70
92
  };
71
93
 
72
94
  // transform it into a devWorkspace
73
- const devfileMetadata = devfile.metadata;
95
+ const devfileMetadata = this.createDevWorkspaceMetadata(devfile, true);
74
96
  const devfileCopy = Object.assign({}, devfile);
75
97
  delete devfileCopy.schemaVersion;
76
98
  delete devfileCopy.metadata;
@@ -86,6 +108,7 @@ export class Generate {
86
108
  metadata: devfileMetadata,
87
109
  spec: {
88
110
  started: true,
111
+ routingClass: 'che',
89
112
  template: devfileCopy,
90
113
  contributions: [editorSpecContribution],
91
114
  },
@@ -101,19 +124,28 @@ export class Generate {
101
124
  suffix,
102
125
  };
103
126
 
104
- // grab container where to inject controller.devfile.io/merge-contribution attribute
105
- let devContainer: V1alpha2DevWorkspaceSpecTemplateComponents = await this.devContainerComponentFinder.find(context);
106
-
107
- // add attributes
108
- let devContainerAttributes = devContainer.attributes;
109
- if (!devContainerAttributes) {
110
- devContainerAttributes = {};
111
- devContainerAttributes[Generate.MERGE_CONTRIBUTION] = true;
112
- devContainer.attributes = devContainerAttributes;
113
- } else {
114
- devContainerAttributes[Generate.MERGE_CONTRIBUTION] = true;
115
- }
127
+ // find devContainer component, add a default one if not found
128
+ await this.devContainerComponentFinder.find(context, injectDefaultComponent, defaultComponentImage);
116
129
 
117
130
  return context;
118
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
+ }
119
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);
package/src/main.ts CHANGED
@@ -11,13 +11,13 @@
11
11
  import * as axios from 'axios';
12
12
  import * as fs from 'fs-extra';
13
13
  import { Generate } from './generate';
14
- import { GithubResolver } from './github/github-resolver';
15
14
  import * as jsYaml from 'js-yaml';
16
15
  import { InversifyBinding } from './inversify/inversify-binding';
17
16
  import { UrlFetcher } from './fetch/url-fetcher';
18
17
  import { PluginRegistryResolver } from './plugin-registry/plugin-registry-resolver';
19
18
  import { V1alpha2DevWorkspaceSpecTemplate } from '@devfile/api';
20
19
  import { DevfileContext } from './api/devfile-context';
20
+ import { GitUrlResolver } from './resolve/git-url-resolver';
21
21
 
22
22
  export class Main {
23
23
  /**
@@ -34,21 +34,27 @@ export class Main {
34
34
  devfileContent?: string;
35
35
  outputFile?: string;
36
36
  editorPath?: string;
37
- pluginRegistryUrl?: string;
37
+ editorContent?: string;
38
38
  editorEntry?: string;
39
+ pluginRegistryUrl?: string;
39
40
  projects: { name: string; location: string }[];
41
+ injectDefaultComponent?: string;
42
+ defaultComponentImage?: string;
40
43
  },
41
44
  axiosInstance: axios.AxiosInstance
42
45
  ): Promise<DevfileContext> {
43
- let { devfilePath, devfileUrl, outputFile, editorPath, pluginRegistryUrl, editorEntry, projects } = params;
44
-
45
- if (!editorPath && !editorEntry) {
46
- throw new Error('missing editorPath or editorEntry');
46
+ if (!params.editorPath && !params.editorEntry && !params.editorContent) {
47
+ throw new Error('missing editorPath or editorEntry or editorContent');
47
48
  }
48
- if (!devfilePath && !devfileUrl && !params.devfileContent) {
49
+ if (!params.devfilePath && !params.devfileUrl && !params.devfileContent) {
49
50
  throw new Error('missing devfilePath or devfileUrl or devfileContent');
50
51
  }
51
- if (!pluginRegistryUrl) {
52
+
53
+ let pluginRegistryUrl: string;
54
+
55
+ if (params.pluginRegistryUrl) {
56
+ pluginRegistryUrl = params.pluginRegistryUrl;
57
+ } else {
52
58
  pluginRegistryUrl = 'https://eclipse-che.github.io/che-plugin-registry/main/v3';
53
59
  console.log(`No plug-in registry url. Setting to ${pluginRegistryUrl}`);
54
60
  }
@@ -63,12 +69,12 @@ export class Main {
63
69
  let devfileContent;
64
70
  let editorContent;
65
71
 
66
- // gets the github URL
67
- if (devfileUrl) {
68
- const githubResolver = container.get(GithubResolver);
69
- const githubUrl = githubResolver.resolve(devfileUrl);
72
+ // gets the repo URL
73
+ if (params.devfileUrl) {
74
+ const resolver = container.get(GitUrlResolver);
75
+ const url = resolver.resolve(params.devfileUrl);
70
76
  // user devfile
71
- devfileContent = await container.get(UrlFetcher).fetchText(githubUrl.getContentUrl('devfile.yaml'));
77
+ devfileContent = await container.get(UrlFetcher).fetchText(url.getContentUrl('devfile.yaml'));
72
78
 
73
79
  // load content
74
80
  const devfileParsed = jsYaml.load(devfileContent);
@@ -78,35 +84,43 @@ export class Main {
78
84
  // no, so add the current project being cloned
79
85
  devfileParsed.projects = [
80
86
  {
81
- name: githubUrl.getRepoName(),
87
+ name: url.getRepoName(),
82
88
  git: {
83
- remotes: { origin: githubUrl.getCloneUrl() },
84
- checkoutFrom: { revision: githubUrl.getBranchName() },
89
+ remotes: { origin: url.getCloneUrl() },
90
+ checkoutFrom: { revision: url.getBranchName() },
85
91
  },
86
92
  },
87
93
  ];
88
94
  }
89
95
  // get back the content
90
96
  devfileContent = jsYaml.dump(devfileParsed);
91
- } else if (devfilePath) {
92
- devfileContent = await fs.readFile(devfilePath);
97
+ } else if (params.devfilePath) {
98
+ devfileContent = await fs.readFile(params.devfilePath);
93
99
  } else {
94
100
  devfileContent = params.devfileContent;
95
101
  }
96
102
 
97
103
  // enhance projects
98
- devfileContent = this.replaceIfExistingProjects(devfileContent, projects);
104
+ devfileContent = this.replaceIfExistingProjects(devfileContent, params.projects);
99
105
 
100
- if (editorEntry) {
106
+ if (params.editorContent) {
107
+ editorContent = params.editorContent;
108
+ } else if (params.editorEntry) {
101
109
  // devfile of the editor
102
- const editorDevfile = await container.get(PluginRegistryResolver).loadDevfilePlugin(editorEntry);
110
+ const editorDevfile = await container.get(PluginRegistryResolver).loadDevfilePlugin(params.editorEntry);
103
111
  editorContent = jsYaml.dump(editorDevfile);
104
112
  } else {
105
- editorContent = await fs.readFile(editorPath);
113
+ editorContent = await fs.readFile(params.editorPath);
106
114
  }
107
115
 
108
116
  const generate = container.get(Generate);
109
- return generate.generate(devfileContent, editorContent, outputFile);
117
+ return generate.generate(
118
+ devfileContent,
119
+ editorContent,
120
+ params.outputFile,
121
+ params.injectDefaultComponent,
122
+ params.defaultComponentImage
123
+ );
110
124
  }
111
125
 
112
126
  // Update project entry based on the projects passed as parameter
@@ -143,6 +157,8 @@ export class Main {
143
157
  let editorPath: string | undefined;
144
158
  let pluginRegistryUrl: string | undefined;
145
159
  let editorEntry: string | undefined;
160
+ let injectDefaultComponent: string | undefined;
161
+ let defaultComponentImage: string | undefined;
146
162
  const projects: { name: string; location: string }[] = [];
147
163
 
148
164
  const args = process.argv.slice(2);
@@ -172,6 +188,12 @@ export class Main {
172
188
 
173
189
  projects.push({ name, location });
174
190
  }
191
+ if (arg.startsWith('--injectDefaultComponent:')) {
192
+ injectDefaultComponent = arg.substring('--injectDefaultComponent:'.length);
193
+ }
194
+ if (arg.startsWith('--defaultComponentImage:')) {
195
+ defaultComponentImage = arg.substring('--defaultComponentImage:'.length);
196
+ }
175
197
  });
176
198
 
177
199
  try {
@@ -193,6 +215,8 @@ export class Main {
193
215
  pluginRegistryUrl,
194
216
  editorEntry,
195
217
  projects,
218
+ injectDefaultComponent,
219
+ defaultComponentImage,
196
220
  },
197
221
  axios.default
198
222
  );
@@ -26,7 +26,7 @@ export class PluginRegistryResolver {
26
26
  @inject(UrlFetcher)
27
27
  private urlFetcher: UrlFetcher;
28
28
 
29
- // FQN id (like eclipse/che-theia/next)
29
+ // FQN id (like che-incubator/che-code/next)
30
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
31
  async loadDevfilePlugin(devfileId: string): Promise<any> {
32
32
  const devfileUrl = `${this.pluginRegistryUrl}/plugins/${devfileId}/devfile.yaml`;
@@ -0,0 +1,30 @@
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 { injectable, multiInject } from 'inversify';
11
+ import { Url } from './url';
12
+ import { TYPES } from '../types';
13
+ import { Resolver } from './resolver';
14
+
15
+ const { Resolver } = TYPES;
16
+
17
+ @injectable()
18
+ export class GitUrlResolver {
19
+ @multiInject(Resolver)
20
+ private resolvers: Resolver[];
21
+
22
+ resolve(link: string): Url {
23
+ const resolver = this.resolvers.find(r => r.isValid(link));
24
+ if (resolver) {
25
+ return resolver.resolve(link);
26
+ } else {
27
+ throw new Error('Can not resolver the URL');
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,18 @@
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 { GitUrlResolver } from './git-url-resolver';
13
+
14
+ const resolveModule = new ContainerModule((bind: interfaces.Bind) => {
15
+ bind(GitUrlResolver).toSelf().inSingletonScope();
16
+ });
17
+
18
+ export { resolveModule };
@@ -0,0 +1,25 @@
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 './url';
12
+
13
+ export interface Resolver {
14
+ /**
15
+ * Validates the string url for belonging to a specific Git provider.
16
+ * @param url string representation of Url.
17
+ */
18
+ isValid(url: string): boolean;
19
+
20
+ /**
21
+ * Resolves repository string URL to a {@class Url} object.
22
+ * @param url string representation of Url.
23
+ */
24
+ resolve(url: string): Url;
25
+ }
@@ -0,0 +1,40 @@
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
+ /**
12
+ * Url object
13
+ */
14
+ export interface Url {
15
+ /**
16
+ * Provides RAW file content url
17
+ * @param path file path
18
+ */
19
+ getContentUrl(path: string);
20
+
21
+ /**
22
+ * Provides repositories Url
23
+ */
24
+ getUrl(): string;
25
+
26
+ /**
27
+ * Provides Git clone url
28
+ */
29
+ getCloneUrl(): string;
30
+
31
+ /**
32
+ * Provides repository name
33
+ */
34
+ getRepoName(): string;
35
+
36
+ /**
37
+ * Provides branch name if initialised.
38
+ */
39
+ getBranchName(): string;
40
+ }
package/src/types.ts ADDED
@@ -0,0 +1,14 @@
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
+ const TYPES = {
11
+ Resolver: Symbol.for('Resolver'),
12
+ };
13
+
14
+ export { TYPES };