Skip to content

Fixes #662 - Set a current working directory when running apps#803

Merged
freakboy3742 merged 7 commits into
beeware:mainfrom
freakboy3742:working-dir
Jul 30, 2022
Merged

Fixes #662 - Set a current working directory when running apps#803
freakboy3742 merged 7 commits into
beeware:mainfrom
freakboy3742:working-dir

Conversation

@freakboy3742

@freakboy3742 freakboy3742 commented Jul 28, 2022

Copy link
Copy Markdown
Member

By default, the Python interpreter will include the current working directory in the PYTHONPATH. As a result, if you create an app named helloworld, and create a helloworld.py in the root directory of the project, briefcase dev would pick up the helloworld.py in the project root, not the actual app code.

This would also affect Linux AppImage apps. As Linux AppImages are an embedded Python interpreter, the folder where you invoke the AppImage would implicitly be on the PYTHONPATH. If you gave a helloworld AppImage to an end-user who has helloworld.py in their local folder, the end-user's helloworld.py would be executed.

macOS and Windows aren't affected by this problem, as they use an embedded interpreter that doesn't add CWD to the PythonPath. However it doesn't hurt to set the CWD for those run calls.

iOS and Android aren't affected because they're running on device in a sandbox, so they can't be affected by local code.

Linux Flatpaks are affected by this in a slightly different way, as they run with a CWD of ~; so a helloworld.py in the user's home folder would get picked up. Adopting #628 (implemented in beeware/briefcase-linux-flatpak-template#3) would address this, as it would make Flatpaks isolated in the same way as Windows/macOS apps.

This PR addresses the problem by setting the CWD to the user's home folder when running the app, or when in dev mode. This doesn't provide perfect isolation in dev mode, but it's significantly better than the status quo, and leads to easier-to-diagnose end-user questions of "Why is Briefcase finding code in my home folder?", rather than "Why isn't briefcase finding the code in my project?" or "Why is briefcase picking up a stale version of my app?". Running apps aren't affected by this decision (other than the Flatpak leakage mentioned above, which is fixed in the linked template PR).

By way of debugging assistance, this PR also adds the CWD into the logged subprocess output.

beeware/briefcase-linux-appimage-template#17 includes a fix on the AppImage binary to force better isolation of the `AppImage itself.

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

@mhsmith

mhsmith commented Jul 28, 2022

Copy link
Copy Markdown
Member

This PR addresses the problem by setting the CWD to the user's home folder when running the app, or when in dev mode. This doesn't provide perfect isolation in dev mode, but it's significantly better than the status quo, and leads to easier-to-diagnose end-user questions of "Why is Briefcase finding code in my home folder?", rather than "Why isn't briefcase finding the code in my project?" or "Why is briefcase picking up a stale version of my app?".

I think unexpectedly running something in the home folder could still really confuse a user. And it's not unusual for someone to drop a file in their home directory and then forget about it for months.

Ideally we would simply tell Python not to add the current directory to sys.path. Unfortunately, it looks like there isn't an option for this until the upcoming Python 3.11, which adds a -P option that does exactly this. In older Python versions the only way I can find is to use -I, which has some other undesired effects.

However, we could still achieve the desired effect by changing the Python command line from this:

python -m helloworld

To this:

python -c 'import runpy, sys; sys.path.pop(0); runpy.run_module("helloworld", run_name="__main__")'

If that works for briefcase dev, then I don't see any reason to change the current directory for briefcase run either, because just remaining in the directory where the command was executed means one less thing for the user to learn.

Of course, for briefcase commands the current directory is always the project root directory, but an AppImage could be launched from anywhere. And adding a cd command to the launch script, as beeware/briefcase-linux-appimage-template#17 does, would make it impossible for the app to contain code that depends on the current directory. For example, relative paths on the app's command line wouldn't work correctly. So if the python -c technique works for briefcase dev, I think it should be used for AppImage as well.

@freakboy3742

Copy link
Copy Markdown
Member Author

I completely agree that cwd=~ isn't an ideal solution - it's more a case of the "best of a bunch of bad options" (at least within the scope of using cwd as the solution).

However, I think you're right that the runpy approach is a better one - as long as we also add alter_sys=True. Without that extra argument, sys.modules['__main__'].__package__ no longer identifies the app module used to start the app. Toga uses this as one (of multiple) approaches it uses to identify the running app. With alter_sys=True, I can't see any difference between runpy and -m module.

I think it's still worth retaining the cwd change though, if only to disconnect any perception that the app is running in the project directory. We get plenty of support queries that amount to "the app runs fine in dev mode, but breaks in app mode", which come down to absolute vs relative path handling; using a path that is very clearly not in the project can only help to reinforce this.

@codecov

codecov Bot commented Jul 29, 2022

Copy link
Copy Markdown

Codecov Report

Merging #803 (f5326dd) into main (0d7c359) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted Files Coverage Δ
src/briefcase/platforms/linux/appimage.py 97.43% <ø> (ø)
src/briefcase/commands/dev.py 95.16% <100.00%> (+0.07%) ⬆️
src/briefcase/integrations/subprocess.py 100.00% <100.00%> (ø)
src/briefcase/platforms/linux/flatpak.py 100.00% <100.00%> (ø)

@mhsmith

mhsmith commented Jul 29, 2022

Copy link
Copy Markdown
Member

I think it's still worth retaining the cwd change though, if only to disconnect any perception that the app is running in the project directory. We get plenty of support queries that amount to "the app runs fine in dev mode, but breaks in app mode", which come down to absolute vs relative path handling; using a path that is very clearly not in the project can only help to reinforce this.

Good point: I've seen from the Chaquopy issue tracker that a lot of beginner programmers don't understand the concept of a working directory at all. This should help catch that kind of bug earlier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants