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, {
|
void handleSymlinkException(FileSystemException e, {
|
||||||
required Platform platform,
|
required Platform platform,
|
||||||
required OperatingSystemUtils os,
|
required OperatingSystemUtils os,
|
||||||
|
required String destination,
|
||||||
|
required String source,
|
||||||
}) {
|
}) {
|
||||||
if (platform.isWindows && (e.osError?.errorCode ?? 0) == 1314) {
|
if (platform.isWindows) {
|
||||||
final String? versionString = RegExp(r'[\d.]+').firstMatch(os.name)?.group(0);
|
// ERROR_ACCESS_DENIED
|
||||||
final Version? version = Version.parse(versionString);
|
if (e.osError?.errorCode == 5) {
|
||||||
// Windows 10 14972 is the oldest version that allows creating symlinks
|
throwToolExit(
|
||||||
// just by enabling developer mode; before that it requires running the
|
'ERROR_ACCESS_DENIED file system exception thrown while trying to '
|
||||||
// terminal as Administrator.
|
'create a symlink from $source to $destination',
|
||||||
// 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'
|
// ERROR_PRIVILEGE_NOT_HELD, user cannot symlink
|
||||||
' start ms-settings:developers\n'
|
if (e.osError?.errorCode == 1314) {
|
||||||
'to open settings.'
|
final String? versionString = RegExp(r'[\d.]+').firstMatch(os.name)?.group(0);
|
||||||
: 'You must build from a terminal run as administrator.';
|
final Version? version = Version.parse(versionString);
|
||||||
throwToolExit('Building with plugins requires symlink support.\n\n$instructions');
|
// 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 {
|
try {
|
||||||
link.createSync(path);
|
link.createSync(path);
|
||||||
} on FileSystemException catch (e) {
|
} 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;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,8 @@ void main() {
|
|||||||
// using it instead of fs must re-run any necessary setup (e.g.,
|
// using it instead of fs must re-run any necessary setup (e.g.,
|
||||||
// setUpProject).
|
// setUpProject).
|
||||||
late FileSystem fsWindows;
|
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.
|
// Adds basic properties to the flutterProject and its subprojects.
|
||||||
void setUpProject(FileSystem fileSystem) {
|
void setUpProject(FileSystem fileSystem) {
|
||||||
@ -1612,8 +1614,36 @@ flutter:
|
|||||||
|
|
||||||
const FileSystemException e = FileSystemException('', '', OSError('', 1314));
|
const FileSystemException e = FileSystemException('', '', OSError('', 1314));
|
||||||
|
|
||||||
expect(() => handleSymlinkException(e, platform: platform, os: os),
|
expect(
|
||||||
throwsToolExit(message: 'start ms-settings:developers'));
|
() => 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 {
|
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));
|
const FileSystemException e = FileSystemException('', '', OSError('', 1314));
|
||||||
|
|
||||||
expect(() => handleSymlinkException(e, platform: platform, os: os),
|
expect(
|
||||||
throwsToolExit(message: 'administrator'));
|
() => handleSymlinkException(
|
||||||
|
e,
|
||||||
|
platform: platform,
|
||||||
|
os: os,
|
||||||
|
source: pubCachePath,
|
||||||
|
destination: ephemeralPackagePath,
|
||||||
|
),
|
||||||
|
throwsToolExit(message: 'administrator'),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('Symlink failures only give instructions for specific errors', () async {
|
testWithoutContext('Symlink failures only give instructions for specific errors', () async {
|
||||||
@ -1632,7 +1670,16 @@ flutter:
|
|||||||
|
|
||||||
const FileSystemException e = FileSystemException('', '', OSError('', 999));
|
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