-
Notifications
You must be signed in to change notification settings - Fork 592
introduce abstractions to make Flatpak integration easier #555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4573cc2
b6f6e3a
da9bf48
b435a98
85a28b8
a3e2d0b
f46a87b
2846fd2
abc817f
d9793be
3bbef90
bdbb31a
5095b70
06c7481
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,11 @@ | ||
| export interface IFoundEditor<T> { | ||
| readonly editor: T | ||
| readonly path: string | ||
| /** | ||
| * Indicate to Desktop to launch the editor with the `shell: true` option included. | ||
| * | ||
| * This is available to all platforms, but is only currently used by some Windows | ||
| * editors as their launch programs end in `.cmd` | ||
| */ | ||
| readonly usesShell?: boolean | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| import { join } from 'path' | ||
| import { pathExists as pathExistsInternal } from 'fs-extra' | ||
| import { | ||
| ChildProcess, | ||
| spawn, | ||
| SpawnOptionsWithoutStdio, | ||
| SpawnOptions, | ||
| } from 'child_process' | ||
|
|
||
| export function isFlatpakBuild() { | ||
| return __LINUX__ && process.env.FLATPAK_HOST === '1' | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I started with a helper method to detect whether we're in a flatpak build. This is now all internal, so I can drop the |
||
| } | ||
|
|
||
| /** | ||
| * Convert an executable path to be relative to the flatpak host | ||
| * | ||
| * @param path a path to an executable relative to the root of the filesystem | ||
| * | ||
| */ | ||
| export function convertToFlatpakPath(path: string) { | ||
| if (!__LINUX__) { | ||
| return path | ||
| } | ||
|
|
||
| if (path.startsWith('/opt/')) { | ||
| return path | ||
| } | ||
|
|
||
| return join('/var/run/host', path) | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 if there are cases where we shouldn't be applying this pattern let me know, ideally with the expected inputs and resulting paths. Having to adapt this behaviour based on the path type might make this a bit more complex, but I still think this approach is feasible... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh cool, you answered the question I just posted here #555 (comment) - thanks! |
||
| } | ||
|
|
||
| /** | ||
| * Checks the file path on disk exists before attempting to launch a specific shell | ||
| * | ||
| * @param path | ||
| * | ||
| * @returns `true` if the path can be resolved, or `false` otherwise | ||
| */ | ||
| export async function pathExists(path: string): Promise<boolean> { | ||
| if (isFlatpakBuild()) { | ||
| path = convertToFlatpakPath(path) | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 as I understand it, we want to convert program paths before checking if we're running in a flatpak context as they exist in a special location, but we don't need to do this when we want to launch the program - Let me know if this logic is incorrect, or if I've misunderstood. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yup this is correct. the path outside the container should be real but detection for binaries in
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about for other special directories we're using for editors:
Should those also go through this conversion process before we try and open them with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏻 I'm assuming that the |
||
| } | ||
|
|
||
| try { | ||
| return await pathExistsInternal(path) | ||
| } catch { | ||
| return false | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Spawn a particular shell in a way that works for Flatpak-based usage | ||
| * | ||
| * @param path path to shell, relative to the root of the filesystem | ||
| * @param args arguments to provide to the shell | ||
| * @param options additional options to provide to spawn function | ||
| * | ||
| * @returns a child process to observe and monitor | ||
| */ | ||
| export function spawnShell( | ||
| path: string, | ||
| args: string[], | ||
| options?: SpawnOptionsWithoutStdio | ||
| ): ChildProcess { | ||
| if (isFlatpakBuild()) { | ||
| return spawn('flatpak-spawn', ['--host', path, ...args], options) | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 I think this is the convention for mapping the original command (and parameters) to work with |
||
| } | ||
|
|
||
| return spawn(path, args, options) | ||
| } | ||
|
|
||
| /** | ||
| * Spawn a given editor in a way that works for Flatpak-based usage | ||
| * | ||
| * @param path path to editor, relative to the root of the filesystem | ||
| * @param workingDirectory working directory to open initially in editor | ||
| * @param options additional options to provide to spawn function | ||
| */ | ||
| export function spawnEditor( | ||
| path: string, | ||
| workingDirectory: string, | ||
| options: SpawnOptions | ||
| ): ChildProcess { | ||
| if (isFlatpakBuild()) { | ||
| return spawn( | ||
| 'flatpak-spawn', | ||
| ['--host', path, `"${workingDirectory}"`], | ||
| options | ||
| ) | ||
| } else { | ||
| return spawn(path, [workingDirectory], options) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { convertToFlatpakPath } from '../../../src/lib/helpers/linux' | ||
|
|
||
| describe('convertToFlatpakPath()', () => { | ||
| if (__LINUX__) { | ||
| it('converts /usr paths', () => { | ||
| const path = '/usr/bin/subl' | ||
| const expectedPath = '/var/run/host/usr/bin/subl' | ||
| expect(convertToFlatpakPath(path)).toEqual(expectedPath) | ||
| }) | ||
|
|
||
| it('preserves /opt paths', () => { | ||
| const path = '/opt/slickedit-pro2018/bin/vs' | ||
| expect(convertToFlatpakPath(path)).toEqual(path) | ||
| }) | ||
| } | ||
|
|
||
| if (__WIN32__) { | ||
| it('returns same path', () => { | ||
| const path = 'C:\\Windows\\System32\\Notepad.exe' | ||
| expect(convertToFlatpakPath(path)).toEqual(path) | ||
| }) | ||
| } | ||
|
|
||
| if (__DARWIN__) { | ||
| it('returns same path', () => { | ||
| const path = '/usr/local/bin/code' | ||
| expect(convertToFlatpakPath(path)).toEqual(path) | ||
| }) | ||
| } | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎨 I plan to upstream this change as this context was helpful and perhaps overlooked at the time