Skip to content

Commit 4fe8c8d

Browse files
vrubezhnydatho7561
authored andcommitted
Component create from Git fails if a devfile exists in git repo #3386
Fixes: #3386 Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
1 parent 6037a2d commit 4fe8c8d

File tree

4 files changed

+110
-20
lines changed

4 files changed

+110
-20
lines changed

src/webview/common/devfile.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { StarterProject } from '../../odo/componentTypeDescription';
88
export type Devfile = {
99
name: string;
1010
id: string;
11-
port: number;
12-
registryName: string;
11+
port?: number;
12+
registryName?: string;
1313
description: string;
14-
logoUrl: string;
14+
logoUrl?: string;
1515
supportsDebug: boolean;
1616
supportsDeploy: boolean;
1717
tags: string[];

src/webview/common/devfileListItem.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Check, Close } from '@mui/icons-material';
66
import { Box, Chip, Stack, Tooltip, Typography } from '@mui/material';
77
import * as React from 'react';
88
import { Devfile } from '../common/devfile';
9+
import DevfileLogo from '../../../images/context/devfile.png';
910

1011
export type DevfileListItemProps = {
1112
devfile: Devfile;
@@ -56,7 +57,7 @@ function DevfileListContent(props: DevfileListItemProps) {
5657
borderRadius: '4px',
5758
}}
5859
>
59-
<img src={props.devfile.logoUrl} style={{ maxWidth: '6em', maxHeight: '6em' }} />
60+
<img src={props.devfile.logoUrl ? props.devfile.logoUrl : DevfileLogo} style={{ maxWidth: '6em', maxHeight: '6em' }} />
6061
</Box>
6162
<Stack
6263
direction="column"
@@ -75,9 +76,12 @@ function DevfileListContent(props: DevfileListItemProps) {
7576
>
7677
{props.devfile.name}
7778
</Typography>
78-
<Typography variant="body2" fontStyle="italic">
79-
from {props.devfile.registryName}
80-
</Typography>
79+
80+
{props.devfile.registryName && (
81+
<Typography variant="body2" fontStyle="italic">
82+
from {props.devfile.registryName}
83+
</Typography>
84+
)}
8185
</Stack>
8286
<Typography
8387
variant="body2"
@@ -98,17 +102,17 @@ function DevfileListContent(props: DevfileListItemProps) {
98102
icon={props.devfile.supportsDeploy ? <Check /> : <Close />}
99103
color={props.devfile.supportsDeploy ? 'success' : 'error'}
100104
/>
101-
{props.devfile.tags.map((tag, i) => {
105+
{(props.devfile.tags && props.devfile.tags.map((tag, i) => {
102106
if (i >= 4) {
103107
return;
104108
}
105109
return <Chip size="small" label={tag} key={tag} />;
106-
})}
107-
{props.devfile.tags.length > 4 && (
110+
}))}
111+
{(props.devfile.tags && props.devfile.tags.length > 4 && (
108112
<Tooltip title={props.devfile.tags.slice(4).join(', ')}>
109113
<Chip size="small" label="• • •" />
110114
</Tooltip>
111-
)}
115+
))}
112116
</Stack>
113117
</Stack>
114118
</Stack>

src/webview/create-component/createComponentLoader.ts

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
} from '../common-ext/createComponentHelpers';
3030
import { loadWebviewHtml, validateGitURL } from '../common-ext/utils';
3131
import { Devfile, DevfileRegistry, TemplateProjectIdentifier } from '../common/devfile';
32+
import { DevfileV1 } from '../../util/devfileV1Type';
3233

3334
interface CloneProcess {
3435
status: boolean;
@@ -281,11 +282,19 @@ export default class CreateComponentLoader {
281282
action: 'cloneFailed',
282283
});
283284
} else {
285+
const isGirDevfileExists = await isDevfileExists(tmpFolder);
284286
void CreateComponentLoader.panel.webview.postMessage({
285287
action: 'devfileExists',
286-
data: await isDevfileExists(tmpFolder),
288+
data: isGirDevfileExists,
287289
});
288-
void CreateComponentLoader.getRecommendedDevfile(tmpFolder);
290+
291+
if (isGirDevfileExists) {
292+
// Use the Devfile existing in Gir-repo
293+
void CreateComponentLoader.getExistingDevfile(tmpFolder);
294+
} else {
295+
// Use recommended Devfile
296+
void CreateComponentLoader.getRecommendedDevfile(tmpFolder);
297+
}
289298
}
290299
break;
291300
}
@@ -295,7 +304,7 @@ export default class CreateComponentLoader {
295304
case 'createComponent': {
296305
const componentName: string = message.data.componentName;
297306
const portNumber: number = message.data.portNumber;
298-
let componentFolder: string;
307+
let componentFolder: string = '';
299308
try {
300309
if (message.data.isFromTemplateProject) {
301310
// from template project
@@ -337,14 +346,19 @@ export default class CreateComponentLoader {
337346
await fse.copy(tmpFolder.fsPath, componentFolder);
338347
}
339348
const devfileType = getDevfileType(message.data.devfileDisplayName);
340-
if (!await isDevfileExists(Uri.file(componentFolder))) {
349+
const componentFolderUri = Uri.file(componentFolder);
350+
if (!await isDevfileExists(componentFolderUri)) {
341351
await Odo.Instance.createComponentFromLocation(
342352
devfileType,
343353
componentName,
344354
portNumber,
345355
Uri.file(componentFolder),
346356
);
357+
} else {
358+
// Update component devfile with component's selected name
359+
await CreateComponentLoader.updateDevfileWithComponentName(componentFolderUri, componentName);
347360
}
361+
348362
await sendTelemetry('newComponentCreated', {
349363
strategy,
350364
// eslint-disable-next-line camelcase
@@ -424,6 +438,66 @@ export default class CreateComponentLoader {
424438
}
425439
}
426440

441+
static async updateDevfileWithComponentName(ucomponentFolderUri: vscode.Uri, componentName: string): Promise<void> {
442+
const devFilePath = path.join(ucomponentFolderUri.fsPath, 'devfile.yaml');
443+
const file = await fs.readFile(devFilePath, 'utf8');
444+
const devfile = JSYAML.load(file.toString()) as any;
445+
if (devfile?.metadata?.name !== componentName) {
446+
devfile.metadata.name = componentName;
447+
await fs.unlink(devFilePath);
448+
const yaml = JSYAML.dump(devfile, { sortKeys: true });
449+
await fs.writeFile(devFilePath, yaml.toString(), 'utf-8');
450+
}
451+
}
452+
453+
static async getExistingDevfile(uri: Uri): Promise<void> {
454+
let rawDevfile: any;
455+
let supportsDebug = false; // Initial value
456+
let supportsDeploy = false; // Initial value
457+
try {
458+
void CreateComponentLoader.panel.webview.postMessage({
459+
action: 'getRecommendedDevfileStart'
460+
});
461+
const componentDescription = await Odo.Instance.describeComponent(uri.fsPath);
462+
if (componentDescription) {
463+
rawDevfile = componentDescription.devfileData.devfile;
464+
supportsDebug = componentDescription.devfileData.supportedOdoFeatures.debug;
465+
supportsDeploy = componentDescription.devfileData.supportedOdoFeatures.deploy;
466+
}
467+
} catch (Error) {
468+
// Will try reading the raw devfile
469+
} finally {
470+
if (!rawDevfile) {
471+
//Try reading the raw devfile
472+
const devFileYamlPath = path.join(tmpFolder.fsPath, 'devfile.yaml');
473+
const file = await fs.readFile(devFileYamlPath, 'utf8');
474+
rawDevfile = JSYAML.load(file.toString());
475+
}
476+
477+
void CreateComponentLoader.panel.webview.postMessage({
478+
action: 'getRecommendedDevfile'
479+
});
480+
481+
const devfile: Devfile = {
482+
description: rawDevfile.metadata.description,
483+
name: rawDevfile.metadata.displayName ? rawDevfile.metadata.displayName : rawDevfile.metadata.name,
484+
id: rawDevfile.metadata.name,
485+
starterProjects: rawDevfile.starterProjects,
486+
tags: [],
487+
yaml: JSYAML.dump(rawDevfile),
488+
supportsDebug,
489+
supportsDeploy,
490+
} as Devfile;
491+
492+
void CreateComponentLoader.panel.webview.postMessage({
493+
action: 'recommendedDevfile',
494+
data: {
495+
devfile,
496+
},
497+
});
498+
}
499+
}
500+
427501
static async getRecommendedDevfile(uri: Uri): Promise<void> {
428502
let analyzeRes: AnalyzeResponse[] = [];
429503
let compDescriptions: ComponentTypeDescription[] = [];
@@ -444,7 +518,7 @@ export default class CreateComponentLoader {
444518
try {
445519
const devFileV1Path = path.join(uri.fsPath, 'devfile.yaml');
446520
const file = await fs.readFile(devFileV1Path, 'utf8');
447-
const devfileV1 = JSYAML.load(file.toString());
521+
const devfileV1 = JSYAML.load(file.toString()) as DevfileV1;
448522
await fs.unlink(devFileV1Path);
449523
analyzeRes = await Odo.Instance.analyze(uri.fsPath);
450524
compDescriptions = getCompDescription(analyzeRes);
@@ -475,7 +549,7 @@ export default class CreateComponentLoader {
475549
});
476550
const devfileRegistry: DevfileRegistry[] = getDevfileRegistries();
477551
const allDevfiles: Devfile[] = devfileRegistry.flatMap((registry) => registry.devfiles);
478-
const devfile: Devfile =
552+
const devfile: Devfile | undefined =
479553
compDescriptions.length !== 0
480554
? allDevfiles.find(
481555
(devfile) => devfile.name === compDescriptions[0].displayName,
@@ -515,7 +589,7 @@ function getDevfileType(devfileDisplayName: string): string {
515589
const devfileDescription: ComponentTypeDescription = Array.from(compDescriptions).find(
516590
(description) => description.displayName === devfileDisplayName,
517591
);
518-
return devfileDescription.name;
592+
return devfileDescription ? devfileDescription.name : devfileDisplayName;
519593
}
520594

521595
function getEndPoints(compDescription: ComponentTypeDescription): Endpoint[] {

src/webview/create-component/pages/fromExistingGitRepo.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ export function FromExistingGitRepo({ setCurrentView }) {
149149
setRecommendedDevfile((prevState) => ({ ...prevState, isLoading: true, completionValue: 5 }));
150150
}
151151

152+
function getEffectiveDevfile() {
153+
return recommendedDevfile.isDevfileExistsInRepo ?
154+
recommendedDevfile.devfile // An existing Git-Repo devfile
155+
: selectedDevfile ?
156+
selectedDevfile // A selected Devfile
157+
: recommendedDevfile.devfile // A recommended Devfile
158+
}
159+
160+
function getInitialComponentName() {
161+
return getEffectiveDevfile()?.name;
162+
}
163+
152164
function createComponentFromGitRepo(
153165
projectFolder: string,
154166
componentName: string,
@@ -454,8 +466,8 @@ export function FromExistingGitRepo({ setCurrentView }) {
454466
setCurrentPage('fromGitRepo');
455467
}}
456468
createComponent={createComponentFromGitRepo}
457-
devfile={recommendedDevfile.isDevfileExistsInRepo ? undefined : selectedDevfile ? selectedDevfile : recommendedDevfile.devfile}
458-
initialComponentName={buildSanitizedComponentName(gitURL.url)}
469+
devfile={getEffectiveDevfile()}
470+
initialComponentName={buildSanitizedComponentName(getInitialComponentName())}
459471
/>
460472
);
461473
case 'selectDifferentDevfile':

0 commit comments

Comments
 (0)