Skip to content

Commit c02e555

Browse files
authored
fix(codecatalyst): workaround for mystery devfile location
Problem: - Currently on prod the devfile location from MDE may resolve as ${workspaceRoot}/devfile.yaml instead of just "devfile.yaml". This causes issues because getDevfileLocation will return /projects/WebApplication/WebApplication/devfile.yaml which doesn't exist. Solution: - Build the devfile location depending on if the the user enters MDE in the /projects directory or /projects/[repo]
1 parent ef71786 commit c02e555

File tree

2 files changed

+151
-2
lines changed

2 files changed

+151
-2
lines changed

src/codecatalyst/model.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import { ensureDependencies, HOST_NAME_PREFIX } from './tools'
2727
import { isCodeCatalystVSCode } from './utils'
2828
import { Timeout } from '../shared/utilities/timeoutUtils'
2929
import { Commands } from '../shared/vscode/commands2'
30+
import { areEqual } from '../shared/utilities/pathUtils'
31+
import { fileExists } from '../shared/filesystemUtilities'
3032

3133
export type DevEnvironmentId = Pick<DevEnvironment, 'id' | 'org' | 'project'>
3234

@@ -289,14 +291,47 @@ export async function getDevfileLocation(client: DevEnvClient, root?: vscode.Uri
289291
throw new Error('No root directory or Dev Environment folder found')
290292
}
291293

294+
async function checkDefaultLocations(rootDirectory: vscode.Uri): Promise<vscode.Uri> {
295+
// Check the projects root location
296+
const devfileRoot = vscode.Uri.joinPath(vscode.Uri.parse('/projects'), 'devfile.yaml')
297+
if (await fileExists(devfileRoot.fsPath)) {
298+
return devfileRoot
299+
}
300+
301+
// Check the location relative to the current directory
302+
const projectRoot = vscode.Uri.joinPath(rootDirectory, 'devfile.yaml')
303+
if (await fileExists(projectRoot.fsPath)) {
304+
return projectRoot
305+
}
306+
307+
throw new Error('Devfile location was not found')
308+
}
309+
292310
// TODO(sijaden): should make this load greedily and continously poll
293311
// latency is very high for some reason
294312
const devfileLocation = await client.getStatus().then(r => r.location)
295313
if (!devfileLocation) {
296-
throw new Error('Devfile location was not found')
314+
return checkDefaultLocations(rootDirectory)
315+
}
316+
317+
if (areEqual(undefined, rootDirectory.fsPath, '/projects')) {
318+
return vscode.Uri.joinPath(rootDirectory, devfileLocation)
319+
}
320+
321+
// we have /projects/repo, where MDE may or may not return [repo]/devfile.yaml
322+
const repo = path.basename(rootDirectory.fsPath)
323+
const splitDevfilePath = devfileLocation.split('/')
324+
const devfilePath = vscode.Uri.joinPath(rootDirectory, 'devfile.yaml')
325+
if (repo === splitDevfilePath[0] && (await fileExists(devfilePath.fsPath))) {
326+
return devfilePath
327+
}
328+
329+
const baseLocation = vscode.Uri.joinPath(rootDirectory, devfileLocation)
330+
if (await fileExists(baseLocation.fsPath)) {
331+
return baseLocation
297332
}
298333

299-
return vscode.Uri.joinPath(rootDirectory, devfileLocation)
334+
return checkDefaultLocations(rootDirectory)
300335
}
301336

302337
/**
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*!
2+
* Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as assert from 'assert'
7+
import * as vscode from 'vscode'
8+
import { getDevfileLocation } from '../../codecatalyst/model'
9+
import { DevEnvClient } from '../../shared/clients/devenvClient'
10+
import * as sinon from 'sinon'
11+
const fileSystemUtils = require('../../shared/filesystemUtilities')
12+
13+
describe('getDevfileLocation', function () {
14+
let sandbox: sinon.SinonSandbox
15+
16+
beforeEach(function () {
17+
sandbox = sinon.createSandbox()
18+
})
19+
20+
afterEach(function () {
21+
sandbox.restore()
22+
})
23+
24+
function mockClient(location: string | undefined): DevEnvClient {
25+
const devEnvClient = new DevEnvClient()
26+
if (!location) {
27+
sandbox.stub(devEnvClient, 'getStatus').resolves({})
28+
} else {
29+
sandbox.stub(devEnvClient, 'getStatus').resolves({
30+
location: location,
31+
})
32+
}
33+
return devEnvClient
34+
}
35+
36+
it('devfile found at root', async function () {
37+
const client = mockClient('devfile.yaml')
38+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects'))
39+
assert.strictEqual(location.toString(), 'file:///projects/devfile.yaml')
40+
})
41+
42+
it('devfile with repo found in subfolder', async function () {
43+
const client = mockClient('WebApplication/devfile.yaml')
44+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects'))
45+
assert.strictEqual(location.toString(), 'file:///projects/WebApplication/devfile.yaml')
46+
})
47+
48+
it('devfile without repo found in workspace root', async function () {
49+
const devfilePath = vscode.Uri.parse('/projects/WebApplication/devfile.yaml').fsPath
50+
sandbox.stub(fileSystemUtils, 'fileExists').callsFake(function (p: string) {
51+
return p === devfilePath
52+
})
53+
const client = mockClient('devfile.yaml')
54+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects/WebApplication'))
55+
assert.strictEqual(location.toString(), 'file:///projects/WebApplication/devfile.yaml')
56+
})
57+
58+
it('devfile found in subfolder with repo', async function () {
59+
const devfilePath = vscode.Uri.parse('/projects/WebApplication/devfile.yaml').fsPath
60+
sandbox.stub(fileSystemUtils, 'fileExists').callsFake(function (p: string) {
61+
return p === devfilePath
62+
})
63+
const client = mockClient('WebApplication/devfile.yaml')
64+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects/WebApplication'))
65+
assert.strictEqual(location.toString(), 'file:///projects/WebApplication/devfile.yaml')
66+
})
67+
68+
it('throws when devfile is not found', async function () {
69+
sandbox.stub(fileSystemUtils, 'fileExists').resolves(false)
70+
const client = mockClient('test/devfile.yaml')
71+
const location = getDevfileLocation(client, vscode.Uri.parse('/projects/WebApplication'))
72+
assert.rejects(location, new Error('Devfile location was not found'))
73+
})
74+
75+
it('falls back to default projects location when devfile cannot be located', async function () {
76+
const devfilePath = vscode.Uri.parse('/projects/devfile.yaml').fsPath
77+
sandbox.stub(fileSystemUtils, 'fileExists').callsFake(function (p: string) {
78+
return p === devfilePath
79+
})
80+
const client = mockClient('WebApplication/devfile.yaml')
81+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects/WebApplication'))
82+
assert.strictEqual(location.toString(), 'file:///projects/devfile.yaml')
83+
})
84+
85+
it('falls back to default workspace location when devfile cannot be located', async function () {
86+
const devfilePath = vscode.Uri.parse('/projects/WebApplication/devfile.yaml').fsPath
87+
sandbox.stub(fileSystemUtils, 'fileExists').callsFake(function (p: string) {
88+
return p === devfilePath
89+
})
90+
const client = mockClient('devfile.yaml')
91+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects/WebApplication'))
92+
assert.strictEqual(location.toString(), 'file:///projects/WebApplication/devfile.yaml')
93+
})
94+
95+
it('checks project root for devfile when location isnt specified', async function () {
96+
const devfilePath = vscode.Uri.parse('/projects/devfile.yaml').fsPath
97+
sandbox.stub(fileSystemUtils, 'fileExists').callsFake(function (p: string) {
98+
return p === devfilePath
99+
})
100+
const client = mockClient(undefined)
101+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects'))
102+
assert.strictEqual(location.toString(), 'file:///projects/devfile.yaml')
103+
})
104+
105+
it('checks workspace root for devfile when location isnt specified', async function () {
106+
const devfilePath = vscode.Uri.parse('/projects/WebApplication/devfile.yaml').fsPath
107+
sandbox.stub(fileSystemUtils, 'fileExists').callsFake(function (p: string) {
108+
return p === devfilePath
109+
})
110+
const client = mockClient(undefined)
111+
const location = await getDevfileLocation(client, vscode.Uri.parse('/projects/WebApplication'))
112+
assert.strictEqual(location.toString(), 'file:///projects/WebApplication/devfile.yaml')
113+
})
114+
})

0 commit comments

Comments
 (0)