-
-
Notifications
You must be signed in to change notification settings - Fork 388
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
Adopt OS-native Filesystem Location for File Caching #777
Conversation
d28e99c
to
901935e
Compare
I did just realize that the migration could be attempted again at a later date if That might make it necessary to more forcibly tell users to manually delete Or maybe something more extreme like specifying a |
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.
Broadly looks good (although there's obviously tests and a changelog file still needed).
Some high level comments:
- Is cache path the right option?
- macOS File System Programming Guide says "app created support files" go in app support; data caches should include "transient, downloadable content"; the system may delete the Caches directory, so your app must be able to recreate or download files as needed. The contents of
~.briefcase
it could be almost entirely reproduced, as it's downloads; but it is also user specific, and I'm not sure Briefcase would take to kindly to having parts of it's files deleted (especially if parts of the cache directory are going to be deleted). It's definitely not transient. - The XDG specification says user-specific non-essential data files should be stored in caches; "user specific data files" go in data. Briefcase's downloads are definitely essential.
- The difference on Windows is a subdirectory, so I doubt there's a policy distinction.
- Is migration actually needed at all? I know I mentioned migration in my initial comment, but the example I give (Android emulator configs) won't actually be fixed by this; so it's worth questioning whether a migration is needed. Briefcase is still in the early stages of development. Adding the migration scheme is definitely a nice user affordance; but it comes at the cost of us needing to maintain a body of code that will improve the lives of a relatively small segment of users - people who are actively using Briefcase today. We would also need to make a decision about when we remove the migration support... which, frankly, if we did that after a single point release would probably have fixed every configuration that is likely to be affected. I'm not opposed to adding migration if folks think it's worthwhile; I just don't want to end up going down the path of maintaining it because of a quick comment 2+ years ago.
- I'm not concerned about macOS/Linux not having a vendor name in the path. I'm not sure we gain anything in particular by having that additional layer. However, I think we should continue to use the AppDirs API like it suggests on the box, even if the vendor detail isn't actually used on most platforms.
- The mainline seems like a reasonable place to put the migration; but we will want to put a comments in the code that let us know what we're migrating and why, and what the condition is for removing the migration in the future.
src/briefcase/commands/base.py
Outdated
migration_cookie.touch() | ||
try: | ||
with self.input.wait_bar("Copying caches..."): | ||
self.shutil.copytree(dot_briefcase_path, self.cache_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.
Is there a "move" vs "copy" option we should consider here? The briefcase path could easily be 2+GB... that's a lot of data to duplicate.
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.
A move should be possible....my preference to copy was it is more easily recoverable from if something goes wrong midway. Although, I think the larger discussion on the need for a migration may make this moot.
I vacillated between using the cache or data dirs in this initial implementation....even at one point putting only the
I see 3 options:
Ultimately, I think this is an executive decision for the briefcase maintainers since they will inherit all responsibility of support...in reality, I think that's primarily you :) FWIW, (as you said) given this project is still in early dev and has a relatively small user base, I think option 2 strikes the best balance. I'd expect most users to have fast enough internet access to simply re-download everything without too much delay (that said, I've had gigabit internet for a while and may have forgotten the pain)....but a simple backdoor of telling the user they can move the data themselves technically provides a straightforward way for users to avoid repeating these downloads. I am also not 100% clear if the migration is "safe". That is, if everything being migrated will still work in a new location. Based on my testing on Windows for Android, my existing emulators seemed to still work okay. Additionally, everything I've seen seems to be relative-path based suggesting a move wouldn't be detrimental. Finally, want to bump the |
59f25b8
to
18793d7
Compare
I think a hybrid of 1 and 2 might be best. If the startup logic is:
then Briefcase won't ever be destructive, but the user will be clearly advised that (a) there's a migration path available, or (b) they haven't followed the migration advice.
Yeah - that's my biggest concern with the migration approach. To paraphrase Tolstoy - every working systems are alike; but every broken system is broken in it's own way. And diagnosing those edge cases is going to be painful.
One possible improvement - it's possible to configure the cookiecutter directories ( |
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.
Fairly uncontroversial, once the core of the migration decision is made. Other than that, one fairly minor tweak inline.
@@ -268,19 +270,18 @@ def run(self, args, env=None, **kwargs): | |||
docker_args.append(self.command.docker_image_tag(self.app)) | |||
|
|||
# ... then add the command (and its arguments) to run in the container | |||
for arg in args: | |||
arg = str(arg) | |||
for arg in map(str, args): |
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.
Very elegant 👍
src/briefcase/integrations/docker.py
Outdated
os.fsdecode(self.command.dot_briefcase_path), | ||
"/home/brutus/.briefcase", | ||
os.fsdecode(self.command.tools_path), | ||
f"{docker_data_path / 'tools'}", |
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.
Why replacing the tools path specifically, rather than the more generic base data path? I can't think of a specific case where this will be a problem, but it seems weird to specifically do a substitution on a path that is known to be a subdirectory.
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.
Ahh, good catch. I think this carried over when I was experimenting with the support
and tools
directories being in separate base directories. Updated to remap the single base directory.
src/briefcase/commands/base.py
Outdated
@@ -143,6 +145,85 @@ def __init__(self, base_path, home_path=Path.home(), apps=None, input_enabled=Tr | |||
self.logger = Log() | |||
self.save_log = False | |||
|
|||
def migrate_to_os_cache(self): |
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 haven't reviewed this method, on the basis that it's likely going to be gutted based on the discussion about the light-touch migration strategy.
eb92c6c
to
80cffc4
Compare
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've flagged one minor testing issue, but I'm happy to fix that in the merge process. Thanks for another awesome contribution!
cmd.data_path = tmp_path / "data_dir" | ||
cmd.data_path.mkdir(parents=True) | ||
cmd.input.boolean_input = MagicMock() | ||
cmd.input.boolean_input.return_value = True |
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.
This won't be called - we should add a check to verify there won't be any user input requested.
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.
Added check that boolean_input()
is not called.
I added a Moreover, during my testing, I noticed that if the briefcase was invoked in the right way at the right time, then Docker could create the data directory as owned by root. Given this is possible, it may be good to integrate a Finally, I'm not a big fan of a log file being created if the user chooses not to continue....but avoiding that felt like a lot more work than it was worth... |
src/briefcase/commands/base.py
Outdated
** NOTICE: Briefcase is changing it's data directory ** | ||
************************************************************************* | ||
|
||
Briefcase is moving it's data directory from: | ||
|
||
{dot_briefcase_path} | ||
|
||
to: | ||
|
||
{self.data_path} | ||
|
||
If you continue, Briefcase will re-download the tools and data it | ||
uses to build and package applications. | ||
|
||
To avoid potentially large downloads and long installations, you | ||
can manually move the old data directory to the new location. | ||
|
||
If you continue and allow Briefcase to re-download it's tools, the | ||
old data directory can be safely deleted. |
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.
minor typos (3 occurrences): it's -> its
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.
/me grumbles... :-)
…es are clear on locations.
Codecov Report
|
Thank you for implementing this! I have a couple of comments - unfortunately I only got notified when the original issue was resolved, so these are a bit late now... The I was going to complain about not using the cache directories, but after reading the Apple and XDG documentation linked above, I think you're actually right with choosing the normal "user data" directories. Briefcase's tools are indeed more than just caches, in that they are directly used during normal operation. It would be more correct to put downloaded archives into the cache directory, but AFAICT Briefcase already deletes all archives after they've been extracted, so this isn't a problem in practice. (That said, I don't think there's a real danger of macOS randomly deleting only some files in the cache directory - the documentation says that "the system may delete the I'm a bit disappointed that I'll still have to manually exclude the Briefcase data from my backups, but there's no easy solution to that I think - there are no standardized directories that are less transient than the cache directory, but still considered "unimportant" enough to not be backed up. At least on Windows the Briefcase tools will no longer be roamed across machines, which is good. Finally, thanks for prompting the user before redownloading all of the files. I'm lucky enough that my home internet connection has decent bandwidth and no data cap, but it's not that way for everyone or all the time sadly. So the option to migrate the downloads is appreciated, even if it's a manual process. |
@dgelessus Thanks for that heads up about platformdirs - that seems like a change that might be worth making, especially if that's what pip is relying on (even if that is via vendoring) |
…hitespace in Android SDK path)
…hitespace in Android SDK path)
…hitespace in Android SDK path)
Fixes #374.
Scope
Store and maintain file caches in an OS-native cache directory and provide a migration for existing users.
Design
The
appdirs
package provides a simple API to access a (hopefully) unique filesystem directory to store and maintain file caches.Linux:
~/.local/share/briefcase
macOS:
~/Library/Application Support/briefcase
Windows:
~\AppData\Local\BeeWare\briefcase
Interestingly,
BeeWare
is only incorporated in to the cache filepath for Windows... Based on the design of their API, we could simply useappdirs.user_cache_dir()
without specifyingappname
orappauthor
to get the base location of caches for the platform and manually specifyBeeWare/briefcase
from there.When a user runs briefcase with this change, it will notify users of the data directory change.
Additionally,
cookiecutter
uses two directories in the user's home directory. This can be changed, though, via config file forcookiecutter
. If its useful, I can try to getcookiecutter
to use this new cache as well.I'll add and fix tests once the design is agreed on.
PR Checklist: