Skip to content

[flutter_tools] Don't fail copying files if the destination is not writable#71215

Merged
fluttergithubbot merged 1 commit intoflutter:masterfrom
jiahaog:copy-permissions
Nov 25, 2020
Merged

[flutter_tools] Don't fail copying files if the destination is not writable#71215
fluttergithubbot merged 1 commit intoflutter:masterfrom
jiahaog:copy-permissions

Conversation

@jiahaog
Copy link
Member

@jiahaog jiahaog commented Nov 25, 2020

Description

When dart:io is used to copy files on macOS, it is able to clobber read-only files. This check for writable files is unnecessary.

resultFile.openSync(mode: FileMode.writeOnly).closeSync();

The check also breaks Google3 hot restart (on iOS) because the source files are Bazel runfiles which are readonly.

  1. When the application is first started (equivalent of flutter run), assets are copied to the simulator directory using copySync here. The file permissions remain the same after they are copied, and remain readonly.
  2. During hot restart, the assets are copied over again to the simulator directory. However, in this case, the destination files already exist, and have readonly permissions. This check fails and causes the tool to exit, when the next operation to copy the files will work just fine.

I wasn't sure about dart:io being able to override readonly file, so I created a script and built it into a VM binary to be sure:

import 'dart:io';
void main(List<String> args) => File(args[0]).copySync(args[1]);
$ echo hello > hello
$ echo bye > bye

# Make the destination file readonly.
$ chmod -w hello
$ ls -lah
total 16
drwxr-xr-x    4 jiahaog  wheel   128B Nov 25 16:33 .
drwxrwxrwt  246 root     wheel   7.7K Nov 25 16:18 ..
-rw-r--r--    1 jiahaog  wheel     4B Nov 25 16:33 bye
-r--r--r--    1 jiahaog  wheel     6B Nov 25 16:33 hello

# `cp` doesn't work.
$ cp bye hello
cp: hello: Permission denied

# But `copySync` in Dart does.
$ /Users/jiahaog/dev/cp_dart/bin/cp_dart.exe bye hello

$ cat hello
bye
$ ls -lah
total 16
drwxr-xr-x    4 jiahaog  wheel   128B Nov 25 16:33 .
drwxrwxrwt  246 root     wheel   7.7K Nov 25 16:18 ..
-rw-r--r--    1 jiahaog  wheel     4B Nov 25 16:33 bye
-rw-r--r--    1 jiahaog  wheel     4B Nov 25 16:33 hello

This behavior above only happens on macOS, but not on Linux. On linux dart:io's copySync still throws the permission error, but I didn't investigate further why. I think removing the check should still be fine though, because the subsequent fallback checks (below) will rethrow the same error when the permission check fails.

sink = resultFile.openSync(mode: FileMode.writeOnly);

Related Issues

Issue was introduced in #69000

Tests

I added the following tests:

  • Added a new test that mocks a non-writable file, but I'm not sure if this is necessary

Breaking Change

Did any tests fail when you ran them? Please read Handling breaking changes.

  • No, no existing tests failed, so this is not a breaking change.

@flutter-dashboard flutter-dashboard bot added the tool Affects the "flutter" command-line tool. See also t: labels. label Nov 25, 2020
@google-cla google-cla bot added the cla: yes label Nov 25, 2020
Copy link
Contributor

@jonahwilliams jonahwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@fluttergithubbot fluttergithubbot merged commit 8de7212 into flutter:master Nov 25, 2020
@jiahaog jiahaog deleted the copy-permissions branch November 25, 2020 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants