Skip to content

Commit

Permalink
Component create from Git fails if a devfile exists in git repo redha…
Browse files Browse the repository at this point in the history
…t-developer#3386

Fixes: redhat-developer#3386

Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
  • Loading branch information
vrubezhny committed Oct 10, 2023
1 parent 7466bf1 commit 1827f46
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/webview/common/devfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { StarterProject } from '../../odo/componentTypeDescription';
export type Devfile = {
name: string;
id: string;
port: number;
port?: number;
registryName: string;
description: string;
logoUrl: string;
logoUrl?: string;
supportsDebug: boolean;
supportsDeploy: boolean;
tags: string[];
Expand Down
17 changes: 11 additions & 6 deletions src/webview/common/devfileListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Check, Close } from '@mui/icons-material';
import { Box, Chip, Stack, Tooltip, Typography } from '@mui/material';
import * as React from 'react';
import { Devfile } from '../common/devfile';
import DevfileLogo from '../../../images/context/devfile.png';

export type DevfileListItemProps = {
devfile: Devfile;
Expand Down Expand Up @@ -56,7 +57,7 @@ function DevfileListContent(props: DevfileListItemProps) {
borderRadius: '4px',
}}
>
<img src={props.devfile.logoUrl} style={{ maxWidth: '6em', maxHeight: '6em' }} />
<img src={props.devfile.logoUrl ? props.devfile.logoUrl : DevfileLogo} style={{ maxWidth: '6em', maxHeight: '6em' }} />
</Box>
<Stack
direction="column"
Expand All @@ -76,7 +77,11 @@ function DevfileListContent(props: DevfileListItemProps) {
{props.devfile.name}
</Typography>
<Typography variant="body2" fontStyle="italic">
from {props.devfile.registryName}
from {
(props.devfile.registryName ?
props.devfile.registryName
: 'Custom Devfile')
}
</Typography>
</Stack>
<Typography
Expand All @@ -98,17 +103,17 @@ function DevfileListContent(props: DevfileListItemProps) {
icon={props.devfile.supportsDeploy ? <Check /> : <Close />}
color={props.devfile.supportsDeploy ? 'success' : 'error'}
/>
{props.devfile.tags.map((tag, i) => {
{(props.devfile.tags && props.devfile.tags.map((tag, i) => {
if (i >= 4) {
return;
}
return <Chip size="small" label={tag} key={tag} />;
})}
{props.devfile.tags.length > 4 && (
}))}
{(props.devfile.tags && props.devfile.tags.length > 4 && (
<Tooltip title={props.devfile.tags.slice(4).join(', ')}>
<Chip size="small" label="• • •" />
</Tooltip>
)}
))}
</Stack>
</Stack>
</Stack>
Expand Down
89 changes: 82 additions & 7 deletions src/webview/create-component/createComponentLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from '../common-ext/createComponentHelpers';
import { loadWebviewHtml, validateGitURL } from '../common-ext/utils';
import { Devfile, DevfileRegistry, TemplateProjectIdentifier } from '../common/devfile';
import { DevfileV1 } from '../../util/devfileV1Type';

interface CloneProcess {
status: boolean;
Expand Down Expand Up @@ -281,11 +282,19 @@ export default class CreateComponentLoader {
action: 'cloneFailed',
});
} else {
const isGirDevfileExists = await isDevfileExists(tmpFolder);
void CreateComponentLoader.panel.webview.postMessage({
action: 'devfileExists',
data: await isDevfileExists(tmpFolder),
data: isGirDevfileExists,
});
void CreateComponentLoader.getRecommendedDevfile(tmpFolder);

if (isGirDevfileExists) {
// Use the Devfile existing in Gir-repo
void CreateComponentLoader.getExistingDevfile(tmpFolder);
} else {
// Use recommended Devfile
void CreateComponentLoader.getRecommendedDevfile(tmpFolder);
}
}
break;
}
Expand All @@ -295,7 +304,7 @@ export default class CreateComponentLoader {
case 'createComponent': {
const componentName: string = message.data.componentName;
const portNumber: number = message.data.portNumber;
let componentFolder: string;
let componentFolder: string = '';
try {
if (message.data.isFromTemplateProject) {
// from template project
Expand Down Expand Up @@ -337,14 +346,19 @@ export default class CreateComponentLoader {
await fse.copy(tmpFolder.fsPath, componentFolder);
}
const devfileType = getDevfileType(message.data.devfileDisplayName);
if (!await isDevfileExists(Uri.file(componentFolder))) {
const componentFolderUri = Uri.file(componentFolder);
if (!await isDevfileExists(componentFolderUri)) {
await Odo.Instance.createComponentFromLocation(
devfileType,
componentName,
portNumber,
Uri.file(componentFolder),
);
} else {
// Update component devfile with component's selected name
await CreateComponentLoader.updateDevfileWithComponentName(componentFolderUri, componentName);
}

await sendTelemetry('newComponentCreated', {
strategy,
// eslint-disable-next-line camelcase
Expand Down Expand Up @@ -424,6 +438,67 @@ export default class CreateComponentLoader {
}
}

static async updateDevfileWithComponentName(ucomponentFolderUri: vscode.Uri, componentName: string): Promise<void> {
const devFilePath = path.join(ucomponentFolderUri.fsPath, 'devfile.yaml');
const file = await fs.readFile(devFilePath, 'utf8');
const devfile = JSYAML.load(file.toString()) as any;
if (devfile?.metadata?.name !== componentName) {
devfile.metadata.name = componentName;
await fs.unlink(devFilePath);
const yaml = JSYAML.dump(devfile, { sortKeys: true });
await fs.writeFile(devFilePath, yaml.toString(), 'utf-8');
}
}

static async getExistingDevfile(uri: Uri): Promise<void> {
const devFileYamlPath = path.join(tmpFolder.fsPath, 'devfile.yaml');
let rawDevfile: any;
let supportsDebug = false; // Initial value
let supportsDeploy = false; // Initial value
try {
void CreateComponentLoader.panel.webview.postMessage({
action: 'getRecommendedDevfileStart'
});
const componentDescription = await Odo.Instance.describeComponent(uri.fsPath);
if (componentDescription) {
rawDevfile = componentDescription.devfileData.devfile;
supportsDebug = componentDescription.devfileData.supportedOdoFeatures.debug;
supportsDeploy = componentDescription.devfileData.supportedOdoFeatures.deploy;
}
} catch (Error) {
// Will try reading the raw devfile
} finally {
if (!rawDevfile) {
//Try reading the raw devfile
const file = await fs.readFile(devFileYamlPath, 'utf8');
rawDevfile = JSYAML.load(file.toString());
}

void CreateComponentLoader.panel.webview.postMessage({
action: 'getRecommendedDevfile'
});

const devfile: Devfile = {
description: rawDevfile.metadata.description,
registryName: devFileYamlPath,
name: rawDevfile.metadata.displayName ? rawDevfile.metadata.displayName : rawDevfile.metadata.name,
id: rawDevfile.metadata.name,
starterProjects: rawDevfile.starterProjects,
tags: [],
yaml: JSYAML.dump(rawDevfile),
supportsDebug,
supportsDeploy,
} as Devfile;

void CreateComponentLoader.panel.webview.postMessage({
action: 'recommendedDevfile',
data: {
devfile,
},
});
}
}

static async getRecommendedDevfile(uri: Uri): Promise<void> {
let analyzeRes: AnalyzeResponse[] = [];
let compDescriptions: ComponentTypeDescription[] = [];
Expand All @@ -444,7 +519,7 @@ export default class CreateComponentLoader {
try {
const devFileV1Path = path.join(uri.fsPath, 'devfile.yaml');
const file = await fs.readFile(devFileV1Path, 'utf8');
const devfileV1 = JSYAML.load(file.toString());
const devfileV1 = JSYAML.load(file.toString()) as DevfileV1;
await fs.unlink(devFileV1Path);
analyzeRes = await Odo.Instance.analyze(uri.fsPath);
compDescriptions = getCompDescription(analyzeRes);
Expand Down Expand Up @@ -475,7 +550,7 @@ export default class CreateComponentLoader {
});
const devfileRegistry: DevfileRegistry[] = getDevfileRegistries();
const allDevfiles: Devfile[] = devfileRegistry.flatMap((registry) => registry.devfiles);
const devfile: Devfile =
const devfile: Devfile | undefined =
compDescriptions.length !== 0
? allDevfiles.find(
(devfile) => devfile.name === compDescriptions[0].displayName,
Expand Down Expand Up @@ -515,7 +590,7 @@ function getDevfileType(devfileDisplayName: string): string {
const devfileDescription: ComponentTypeDescription = Array.from(compDescriptions).find(
(description) => description.displayName === devfileDisplayName,
);
return devfileDescription.name;
return devfileDescription ? devfileDescription.name : devfileDisplayName;
}

function getEndPoints(compDescription: ComponentTypeDescription): Endpoint[] {
Expand Down
10 changes: 8 additions & 2 deletions src/webview/create-component/pages/fromExistingGitRepo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,15 @@ export function FromExistingGitRepo({ setCurrentView }) {
setCurrentPage('fromGitRepo');
}}
createComponent={createComponentFromGitRepo}
devfile={recommendedDevfile.isDevfileExistsInRepo ? undefined : selectedDevfile ? selectedDevfile : recommendedDevfile.devfile}
devfile={
recommendedDevfile.isDevfileExistsInRepo ?
recommendedDevfile.devfile // An existing Git-Repo devfile
: selectedDevfile ?
selectedDevfile // A selected Devfile
: recommendedDevfile.devfile // A recommended Devfile
}
initialComponentName={buildSanitizedComponentName(gitURL.url)}
/>
/>
);
case 'selectDifferentDevfile':
return (
Expand Down

0 comments on commit 1827f46

Please sign in to comment.