mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
[flutter_tools] tool exit access denied during symlinking (#106213)
This commit is contained in:
parent
9f4b9bfd49
commit
788c8b8ad4
@ -1004,20 +1004,32 @@ void createPluginSymlinks(FlutterProject project, {bool force = false, @visibleF
|
||||
void handleSymlinkException(FileSystemException e, {
|
||||
required Platform platform,
|
||||
required OperatingSystemUtils os,
|
||||
required String destination,
|
||||
required String source,
|
||||
}) {
|
||||
if (platform.isWindows && (e.osError?.errorCode ?? 0) == 1314) {
|
||||
final String? versionString = RegExp(r'[\d.]+').firstMatch(os.name)?.group(0);
|
||||
final Version? version = Version.parse(versionString);
|
||||
// Windows 10 14972 is the oldest version that allows creating symlinks
|
||||
// just by enabling developer mode; before that it requires running the
|
||||
// terminal as Administrator.
|
||||
// https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/
|
||||
final String instructions = (version != null && version >= Version(10, 0, 14972))
|
||||
? 'Please enable Developer Mode in your system settings. Run\n'
|
||||
' start ms-settings:developers\n'
|
||||
'to open settings.'
|
||||
: 'You must build from a terminal run as administrator.';
|
||||
throwToolExit('Building with plugins requires symlink support.\n\n$instructions');
|
||||
if (platform.isWindows) {
|
||||
// ERROR_ACCESS_DENIED
|
||||
if (e.osError?.errorCode == 5) {
|
||||
throwToolExit(
|
||||
'ERROR_ACCESS_DENIED file system exception thrown while trying to '
|
||||
'create a symlink from $source to $destination',
|
||||
);
|
||||
}
|
||||
// ERROR_PRIVILEGE_NOT_HELD, user cannot symlink
|
||||
if (e.osError?.errorCode == 1314) {
|
||||
final String? versionString = RegExp(r'[\d.]+').firstMatch(os.name)?.group(0);
|
||||
final Version? version = Version.parse(versionString);
|
||||
// Windows 10 14972 is the oldest version that allows creating symlinks
|
||||
// just by enabling developer mode; before that it requires running the
|
||||
// terminal as Administrator.
|
||||
// https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/
|
||||
final String instructions = (version != null && version >= Version(10, 0, 14972))
|
||||
? 'Please enable Developer Mode in your system settings. Run\n'
|
||||
' start ms-settings:developers\n'
|
||||
'to open settings.'
|
||||
: 'You must build from a terminal run as administrator.';
|
||||
throwToolExit('Building with plugins requires symlink support.\n\n$instructions');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1043,7 +1055,13 @@ void _createPlatformPluginSymlinks(Directory symlinkDirectory, List<Object?>? pl
|
||||
try {
|
||||
link.createSync(path);
|
||||
} on FileSystemException catch (e) {
|
||||
handleSymlinkException(e, platform: globals.platform, os: globals.os);
|
||||
handleSymlinkException(
|
||||
e,
|
||||
platform: globals.platform,
|
||||
os: globals.os,
|
||||
destination: 'dest',
|
||||
source: 'source',
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ void main() {
|
||||
// using it instead of fs must re-run any necessary setup (e.g.,
|
||||
// setUpProject).
|
||||
late FileSystem fsWindows;
|
||||
const String pubCachePath = '/path/to/.pub-cache/hosted/pub.dartlang.org/foo-1.2.3';
|
||||
const String ephemeralPackagePath = '/path/to/app/linux/flutter/ephemeral/foo-1.2.3';
|
||||
|
||||
// Adds basic properties to the flutterProject and its subprojects.
|
||||
void setUpProject(FileSystem fileSystem) {
|
||||
@ -1612,8 +1614,36 @@ flutter:
|
||||
|
||||
const FileSystemException e = FileSystemException('', '', OSError('', 1314));
|
||||
|
||||
expect(() => handleSymlinkException(e, platform: platform, os: os),
|
||||
throwsToolExit(message: 'start ms-settings:developers'));
|
||||
expect(
|
||||
() => handleSymlinkException(
|
||||
e,
|
||||
platform: platform,
|
||||
os: os,
|
||||
source: pubCachePath,
|
||||
destination: ephemeralPackagePath,
|
||||
),
|
||||
throwsToolExit(message: 'start ms-settings:developers'),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('Symlink ERROR_ACCESS_DENIED failures show developers paths that were used', () async {
|
||||
final Platform platform = FakePlatform(operatingSystem: 'windows');
|
||||
final FakeOperatingSystemUtils os = FakeOperatingSystemUtils('Microsoft Windows [Version 10.0.14972.1]');
|
||||
|
||||
const FileSystemException e = FileSystemException('', '', OSError('', 5));
|
||||
|
||||
expect(
|
||||
() => handleSymlinkException(
|
||||
e,
|
||||
platform: platform,
|
||||
os: os,
|
||||
source: pubCachePath,
|
||||
destination: ephemeralPackagePath,
|
||||
),
|
||||
throwsToolExit(
|
||||
message: 'ERROR_ACCESS_DENIED file system exception thrown while trying to create a symlink from $pubCachePath to $ephemeralPackagePath',
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('Symlink failures instruct developers to run as administrator on older versions of Windows', () async {
|
||||
@ -1622,8 +1652,16 @@ flutter:
|
||||
|
||||
const FileSystemException e = FileSystemException('', '', OSError('', 1314));
|
||||
|
||||
expect(() => handleSymlinkException(e, platform: platform, os: os),
|
||||
throwsToolExit(message: 'administrator'));
|
||||
expect(
|
||||
() => handleSymlinkException(
|
||||
e,
|
||||
platform: platform,
|
||||
os: os,
|
||||
source: pubCachePath,
|
||||
destination: ephemeralPackagePath,
|
||||
),
|
||||
throwsToolExit(message: 'administrator'),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('Symlink failures only give instructions for specific errors', () async {
|
||||
@ -1632,7 +1670,16 @@ flutter:
|
||||
|
||||
const FileSystemException e = FileSystemException('', '', OSError('', 999));
|
||||
|
||||
expect(() => handleSymlinkException(e, platform: platform, os: os), returnsNormally);
|
||||
expect(
|
||||
() => handleSymlinkException(
|
||||
e,
|
||||
platform: platform,
|
||||
os: os,
|
||||
source: pubCachePath,
|
||||
destination: ephemeralPackagePath,
|
||||
),
|
||||
returnsNormally,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user