Skip to content

Commit 968fce3

Browse files
[Fix] Native sideload failing because of relative path handler (#1156)
* [Fix] Native sideload failing because of relative path handler * chore: move fix to utils method * tests: updated tests and fix edge case --------- Co-authored-by: Flavio F Lima <[email protected]> Co-authored-by: Brett <[email protected]>
1 parent 583f1e3 commit 968fce3

File tree

3 files changed

+88
-9
lines changed

3 files changed

+88
-9
lines changed

src/backend/__tests__/utils.test.ts

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,15 @@ describe('backend/utils.ts', () => {
197197
expect(getExecutableAndArgs(input)).toEqual(expected)
198198
})
199199

200+
it('should correctly parse executable with .exe extension and no arguments', () => {
201+
const input = 'path/to/application.exe'
202+
const expected = {
203+
executable: 'path/to/application.exe',
204+
launchArgs: ''
205+
}
206+
expect(getExecutableAndArgs(input)).toEqual(expected)
207+
})
208+
200209
it('should correctly parse executable with .app extension and no arguments', () => {
201210
const input = 'path/to/application.app'
202211
const expected = {
@@ -226,10 +235,10 @@ describe('backend/utils.ts', () => {
226235
})
227236

228237
it('should return empty strings if no executable is found', () => {
229-
const input = '--arg1 --arg2'
238+
const input = ''
230239
const expected = {
231240
executable: '',
232-
launchArgs: '--arg1 --arg2'
241+
launchArgs: ''
233242
}
234243
expect(getExecutableAndArgs(input)).toEqual(expected)
235244
})
@@ -260,5 +269,41 @@ describe('backend/utils.ts', () => {
260269
}
261270
expect(getExecutableAndArgs(input)).toEqual(expected)
262271
})
272+
273+
it('should handle simple executable name without args', () => {
274+
const input = 'executable.exe'
275+
const expected = {
276+
executable: 'executable.exe',
277+
launchArgs: ''
278+
}
279+
expect(getExecutableAndArgs(input)).toEqual(expected)
280+
})
281+
282+
it('should handle simple executable name with args', () => {
283+
const input = 'steam --no-browser'
284+
const expected = {
285+
executable: 'steam',
286+
launchArgs: '--no-browser'
287+
}
288+
expect(getExecutableAndArgs(input)).toEqual(expected)
289+
})
290+
291+
it('should handle absolute path from /usr/bin', () => {
292+
const input = '/usr/bin/steam --no-browser'
293+
const expected = {
294+
executable: '/usr/bin/steam',
295+
launchArgs: '--no-browser'
296+
}
297+
expect(getExecutableAndArgs(input)).toEqual(expected)
298+
})
299+
300+
it('should handle absolute path from /usr/local/bin', () => {
301+
const input = '/usr/local/bin/custom-launcher --fullscreen'
302+
const expected = {
303+
executable: '/usr/local/bin/custom-launcher',
304+
launchArgs: '--fullscreen'
305+
}
306+
expect(getExecutableAndArgs(input)).toEqual(expected)
307+
})
263308
})
264309
})

src/backend/storeManagers/storeManagerCommon/games.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,13 @@ export async function launchGame(
358358
)
359359
// On Mac, it gives an error when changing the permissions of the file inside the app bundle. But we need it for other executables like scripts.
360360
if (isLinux || (isMac && !exeOnly.endsWith('.app'))) {
361-
await chmod(exeOnly, 0o775)
361+
try {
362+
await chmod(exeOnly, 0o775)
363+
} catch (error) {
364+
logWarning(
365+
'Was not possible to change permission to this file, maybe the owner is Root?'
366+
)
367+
}
362368
}
363369
}
364370

src/backend/utils.ts

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import {
5454
LogPrefix,
5555
logWarning
5656
} from './logger/logger'
57-
import { basename, dirname, join, normalize } from 'path'
57+
import { basename, dirname, isAbsolute, join, normalize } from 'path'
5858
import { runRunnerCommand as runLegendaryCommand } from 'backend/storeManagers/legendary/library'
5959
import {
6060
gameInfoStore,
@@ -1242,20 +1242,48 @@ export function getPlatformName(platform: string): PlatformName {
12421242
return platformMap[platform] || platform || 'Unknown'
12431243
}
12441244

1245+
const splitExeAndArgs = (executableWithArgs: string) => {
1246+
const executable = executableWithArgs.split(' -')[0]
1247+
const launchArgs = executableWithArgs.replace(executable, '').trim()
1248+
1249+
return [executable, launchArgs]
1250+
}
1251+
12451252
export function getExecutableAndArgs(executableWithArgs: string): {
12461253
executable: string
12471254
launchArgs: string
12481255
} {
1256+
if (!executableWithArgs) {
1257+
return { executable: '', launchArgs: '' }
1258+
}
1259+
1260+
// Handle absolute paths first
1261+
const isAbsolutePath = isAbsolute(executableWithArgs)
1262+
if (isAbsolutePath) {
1263+
const [exe, args] = splitExeAndArgs(executableWithArgs)
1264+
return { executable: exe, launchArgs: args }
1265+
}
1266+
1267+
// Handle .app paths
12491268
if (executableWithArgs.includes('.app')) {
1250-
const executable = executableWithArgs.split(' -')[0]
1269+
const [executable, launchArgs] = splitExeAndArgs(executableWithArgs)
1270+
return { executable, launchArgs }
1271+
}
1272+
1273+
// Handle common extensions
1274+
const matchWithExt = executableWithArgs.match(/^(.*?\.(exe|bin|sh))/i)
1275+
if (matchWithExt) {
1276+
const executable = matchWithExt[0]
12511277
const launchArgs = executableWithArgs.replace(executable, '').trim()
12521278
return { executable, launchArgs }
12531279
}
1254-
const match = executableWithArgs.match(/^(.*?\.(exe|bin|sh))/i)
1255-
const executable = match ? match[0] : ''
1256-
const launchArgs = executableWithArgs.replace(executable, '').trim()
12571280

1258-
return { executable, launchArgs }
1281+
// Handle executables without extension
1282+
const [executable, ...argParts] = splitExeAndArgs(executableWithArgs)
1283+
return {
1284+
executable,
1285+
launchArgs: argParts.join(' ')
1286+
}
12591287
}
12601288

12611289
function roundToTenth(x: number) {

0 commit comments

Comments
 (0)