Skip to content

Commit

Permalink
Component create from Git fails if a devfile exists in git repo #3386
Browse files Browse the repository at this point in the history
Fixes: #3386

Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
  • Loading branch information
vrubezhny committed Oct 11, 2023
1 parent 6037a2d commit 04e273e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 20 deletions.
6 changes: 3 additions & 3 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;
registryName: string;
port?: number;
registryName?: string;
description: string;
logoUrl: string;
logoUrl?: string;
supportsDebug: boolean;
supportsDeploy: boolean;
tags: string[];
Expand Down
20 changes: 12 additions & 8 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 @@ -75,9 +76,12 @@ function DevfileListContent(props: DevfileListItemProps) {
>
{props.devfile.name}
</Typography>
<Typography variant="body2" fontStyle="italic">
from {props.devfile.registryName}
</Typography>

{props.devfile.registryName && (
<Typography variant="body2" fontStyle="italic">
from {props.devfile.registryName}
</Typography>
)}
</Stack>
<Typography
variant="body2"
Expand All @@ -98,17 +102,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
88 changes: 81 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);

Check warning on line 285 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L285

Added line #L285 was not covered by tests
void CreateComponentLoader.panel.webview.postMessage({
action: 'devfileExists',
data: await isDevfileExists(tmpFolder),
data: isGirDevfileExists,
});
void CreateComponentLoader.getRecommendedDevfile(tmpFolder);

if (isGirDevfileExists) {

Check warning on line 291 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L291

Added line #L291 was not covered by tests
// Use the Devfile existing in Gir-repo
void CreateComponentLoader.getExistingDevfile(tmpFolder);

Check warning on line 293 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L293

Added line #L293 was not covered by tests
} else {
// Use recommended Devfile
void CreateComponentLoader.getRecommendedDevfile(tmpFolder);

Check warning on line 296 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L296

Added line #L296 was not covered by tests
}
}
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 = '';

Check warning on line 307 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L307

Added line #L307 was not covered by tests
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)) {

Check warning on line 350 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L349-L350

Added lines #L349 - L350 were not covered by tests
await Odo.Instance.createComponentFromLocation(
devfileType,
componentName,
portNumber,
Uri.file(componentFolder),
);
} else {
// Update component devfile with component's selected name
await CreateComponentLoader.updateDevfileWithComponentName(componentFolderUri, componentName);

Check warning on line 359 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L359

Added line #L359 was not covered by tests
}

await sendTelemetry('newComponentCreated', {
strategy,
// eslint-disable-next-line camelcase
Expand Down Expand Up @@ -424,6 +438,66 @@ 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');

Check warning on line 449 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L441-L449

Added lines #L441 - L449 were not covered by tests
}
}

static async getExistingDevfile(uri: Uri): Promise<void> {
let rawDevfile: any;
let supportsDebug = false; // Initial value
let supportsDeploy = false; // Initial value
try {
void CreateComponentLoader.panel.webview.postMessage({

Check warning on line 458 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L453-L458

Added lines #L453 - L458 were not covered by tests
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;

Check warning on line 465 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L461-L465

Added lines #L461 - L465 were not covered by tests
}
} catch (Error) {
// Will try reading the raw devfile
} finally {
if (!rawDevfile) {

Check warning on line 470 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L470

Added line #L470 was not covered by tests
//Try reading the raw devfile
const devFileYamlPath = path.join(tmpFolder.fsPath, 'devfile.yaml');
const file = await fs.readFile(devFileYamlPath, 'utf8');
rawDevfile = JSYAML.load(file.toString());

Check warning on line 474 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L472-L474

Added lines #L472 - L474 were not covered by tests
}

void CreateComponentLoader.panel.webview.postMessage({

Check warning on line 477 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L477

Added line #L477 was not covered by tests
action: 'getRecommendedDevfile'
});

const devfile: Devfile = {

Check warning on line 481 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L481

Added line #L481 was not covered by tests
description: rawDevfile.metadata.description,
name: rawDevfile.metadata.displayName ? rawDevfile.metadata.displayName : rawDevfile.metadata.name,

Check warning on line 483 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L483

Added line #L483 was not covered by tests
id: rawDevfile.metadata.name,
starterProjects: rawDevfile.starterProjects,
tags: [],
yaml: JSYAML.dump(rawDevfile),
supportsDebug,
supportsDeploy,
} as Devfile;

void CreateComponentLoader.panel.webview.postMessage({

Check warning on line 492 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L492

Added line #L492 was not covered by tests
action: 'recommendedDevfile',
data: {
devfile,
},
});
}
}

static async getRecommendedDevfile(uri: Uri): Promise<void> {
let analyzeRes: AnalyzeResponse[] = [];
let compDescriptions: ComponentTypeDescription[] = [];
Expand All @@ -444,7 +518,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;

Check warning on line 521 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L521

Added line #L521 was not covered by tests
await fs.unlink(devFileV1Path);
analyzeRes = await Odo.Instance.analyze(uri.fsPath);
compDescriptions = getCompDescription(analyzeRes);
Expand Down Expand Up @@ -475,7 +549,7 @@ export default class CreateComponentLoader {
});
const devfileRegistry: DevfileRegistry[] = getDevfileRegistries();
const allDevfiles: Devfile[] = devfileRegistry.flatMap((registry) => registry.devfiles);
const devfile: Devfile =
const devfile: Devfile | undefined =

Check warning on line 552 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L552

Added line #L552 was not covered by tests
compDescriptions.length !== 0
? allDevfiles.find(
(devfile) => devfile.name === compDescriptions[0].displayName,
Expand Down Expand Up @@ -515,7 +589,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;

Check warning on line 592 in src/webview/create-component/createComponentLoader.ts

View check run for this annotation

Codecov / codecov/patch

src/webview/create-component/createComponentLoader.ts#L592

Added line #L592 was not covered by tests
}

function getEndPoints(compDescription: ComponentTypeDescription): Endpoint[] {
Expand Down
16 changes: 14 additions & 2 deletions src/webview/create-component/pages/fromExistingGitRepo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ export function FromExistingGitRepo({ setCurrentView }) {
setRecommendedDevfile((prevState) => ({ ...prevState, isLoading: true, completionValue: 5 }));
}

function getEffectiveDevfile() {
return recommendedDevfile.isDevfileExistsInRepo ?
recommendedDevfile.devfile // An existing Git-Repo devfile
: selectedDevfile ?
selectedDevfile // A selected Devfile
: recommendedDevfile.devfile // A recommended Devfile
}

function getInitialComponentName() {
return getEffectiveDevfile()?.name;
}

function createComponentFromGitRepo(
projectFolder: string,
componentName: string,
Expand Down Expand Up @@ -454,8 +466,8 @@ export function FromExistingGitRepo({ setCurrentView }) {
setCurrentPage('fromGitRepo');
}}
createComponent={createComponentFromGitRepo}
devfile={recommendedDevfile.isDevfileExistsInRepo ? undefined : selectedDevfile ? selectedDevfile : recommendedDevfile.devfile}
initialComponentName={buildSanitizedComponentName(gitURL.url)}
devfile={getEffectiveDevfile()}
initialComponentName={buildSanitizedComponentName(getInitialComponentName())}
/>
);
case 'selectDifferentDevfile':
Expand Down

0 comments on commit 04e273e

Please sign in to comment.