[go: nahoru, domu]

Skip to content

Commit

Permalink
[flutter_tools] normalize windows file path cases in flutter validato…
Browse files Browse the repository at this point in the history
…r (#115889)

* normalize windows file path cases in flutter validator

* fix

* make comparison more accurate by checking .startsWith() rather than .contains()

* fix method name

* call path.canonicalize

* fix
  • Loading branch information
christopherfujino committed Nov 29, 2022
1 parent a9c2f8b commit 9532b91
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 21 deletions.
9 changes: 8 additions & 1 deletion packages/flutter_tools/lib/src/doctor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ class FlutterValidator extends DoctorValidator {
);
}
final String resolvedFlutterPath = flutterBin.resolveSymbolicLinksSync();
if (!resolvedFlutterPath.contains(flutterRoot)) {
if (!_filePathContainsDirPath(flutterRoot, resolvedFlutterPath)) {
final String hint = 'Warning: `$binary` on your path resolves to '
'$resolvedFlutterPath, which is not inside your current Flutter '
'SDK checkout at $flutterRoot. Consider adding $flutterBinDir to '
Expand All @@ -629,6 +629,13 @@ class FlutterValidator extends DoctorValidator {
return null;
}

bool _filePathContainsDirPath(String directory, String file) {
// calling .canonicalize() will normalize for alphabetic case and path
// separators
return (_fileSystem.path.canonicalize(file))
.startsWith(_fileSystem.path.canonicalize(directory) + _fileSystem.path.separator);
}

ValidationMessage _getFlutterUpstreamMessage(FlutterVersion version) {
final String? repositoryUrl = version.repositoryUrl;
final VersionCheckError? upstreamValidationError = VersionUpstreamValidator(version: version, platform: _platform).run();
Expand Down
123 changes: 103 additions & 20 deletions packages/flutter_tools/test/general.shard/flutter_validator_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void main() {
userMessages: UserMessages(),
artifacts: artifacts,
fileSystem: fileSystem,
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
processManager: FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
Expand Down Expand Up @@ -93,7 +93,7 @@ void main() {
fileSystem: MemoryFileSystem.test(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Windows'),
processManager: FakeProcessManager.empty(),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

// gen_snapshot is downloaded on demand, and the doctor should not
Expand All @@ -115,14 +115,14 @@ void main() {
fileSystem: MemoryFileSystem.test(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Windows'),
processManager: FakeProcessManager.empty(),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
validationType: ValidationType.partial,
statusInfo: 'Channel beta, 0.0.0, on Windows, locale en_US.UTF-8',
messages: containsAll(const <ValidationMessage>[
ValidationMessage('Flutter version 0.0.0 on channel beta at sdk/flutter'),
ValidationMessage('Flutter version 0.0.0 on channel beta at /sdk/flutter'),
ValidationMessage.error('version error'),
]),
));
Expand Down Expand Up @@ -152,7 +152,7 @@ void main() {
fileSystem: fileSystem,
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Windows'),
flutterRoot: () => 'sdk/flutter'
flutterRoot: () => '/sdk/flutter'
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
Expand Down Expand Up @@ -183,7 +183,7 @@ void main() {
fileSystem: MemoryFileSystem.test(),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
Expand Down Expand Up @@ -213,15 +213,15 @@ void main() {
fileSystem: MemoryFileSystem.test(),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
validationType: ValidationType.partial,
statusInfo: 'Channel unknown, 1.0.0, on Linux, locale en_US.UTF-8',
messages: containsAll(<ValidationMessage>[
const ValidationMessage.hint(
'Flutter version 1.0.0 on channel unknown at sdk/flutter\n'
'Flutter version 1.0.0 on channel unknown at /sdk/flutter\n'
'Currently on an unknown channel. Run `flutter channel` to switch to an official channel.\n'
"If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install."
),
Expand All @@ -246,15 +246,15 @@ void main() {
fileSystem: MemoryFileSystem.test(),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
validationType: ValidationType.partial,
statusInfo: 'Channel beta, 0.0.0-unknown, on Linux, locale en_US.UTF-8',
messages: containsAll(<ValidationMessage>[
const ValidationMessage.hint(
'Flutter version 0.0.0-unknown on channel beta at sdk/flutter\n'
'Flutter version 0.0.0-unknown on channel beta at /sdk/flutter\n'
'Cannot resolve current version, possibly due to local changes.\n'
'Reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.'
),
Expand All @@ -280,7 +280,7 @@ void main() {
fileSystem: MemoryFileSystem.test(),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
Expand Down Expand Up @@ -371,7 +371,7 @@ void main() {
fileSystem: MemoryFileSystem.test(),
processManager: FakeProcessManager.any(),
operatingSystemUtils: FakeOperatingSystemUtils(name: 'Linux'),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
Expand All @@ -387,6 +387,7 @@ void main() {
});

testWithoutContext('detects no flutter and dart on path', () async {
const String flutterRoot = 'sdk/flutter';
final FlutterValidator flutterValidator = FlutterValidator(
platform: FakePlatform(localeName: 'en_US.UTF-8'),
flutterVersion: () => FakeFlutterVersion(
Expand All @@ -402,14 +403,96 @@ void main() {
name: 'Linux',
whichLookup: const <String, File>{},
),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => flutterRoot,
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
validationType: ValidationType.partial,
statusInfo: 'Channel beta, 1.0.0, on Linux, locale en_US.UTF-8',
messages: contains(const ValidationMessage.hint(
'The flutter binary is not on your path. Consider adding sdk/flutter/bin to your path.',
'The flutter binary is not on your path. Consider adding $flutterRoot/bin to your path.',
)),
));
});

testWithoutContext('allows case differences in paths on Windows', () async {
const String flutterRoot = r'c:\path\to\flutter-sdk';
const String osName = 'Microsoft Windows';
final MemoryFileSystem fs = MemoryFileSystem.test(
style: FileSystemStyle.windows,
);
// The windows' file system is not case sensitive, so changing the case
// here should not matter.
final File flutterBinary = fs.file('${flutterRoot.toUpperCase()}\\bin\\flutter')
..createSync(recursive: true);
final FlutterValidator flutterValidator = FlutterValidator(
platform: FakePlatform(operatingSystem: 'windows', localeName: 'en_US.UTF-8'),
flutterVersion: () => FakeFlutterVersion(
frameworkVersion: '1.0.0',
channel: 'beta'
),
devToolsVersion: () => '2.8.0',
userMessages: UserMessages(),
artifacts: Artifacts.test(),
fileSystem: fs,
processManager: FakeProcessManager.empty(),
operatingSystemUtils: FakeOperatingSystemUtils(
name: osName,
whichLookup: <String, File>{
'flutter': flutterBinary,
},
),
flutterRoot: () => flutterRoot,
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
validationType: ValidationType.partial,
statusInfo: 'Channel beta, 1.0.0, on $osName, locale en_US.UTF-8',
messages: everyElement(isA<ValidationMessage>().having(
(ValidationMessage message) => message.message,
'message',
isNot(contains('Warning: `flutter` on your path resolves to')),
)),
));
});

testWithoutContext('allows different separator types in paths on Windows', () async {
const String flutterRoot = r'c:\path\to\flutter-sdk';
const String osName = 'Microsoft Windows';
final MemoryFileSystem fs = MemoryFileSystem.test(
style: FileSystemStyle.windows,
);
const String filePath = '$flutterRoot\\bin\\flutter';
// force posix style path separators
final File flutterBinary = fs.file(filePath.replaceAll(r'\', '/'))
..createSync(recursive: true);
final FlutterValidator flutterValidator = FlutterValidator(
platform: FakePlatform(operatingSystem: 'windows', localeName: 'en_US.UTF-8'),
flutterVersion: () => FakeFlutterVersion(
frameworkVersion: '1.0.0',
channel: 'beta'
),
devToolsVersion: () => '2.8.0',
userMessages: UserMessages(),
artifacts: Artifacts.test(),
fileSystem: fs,
processManager: FakeProcessManager.empty(),
operatingSystemUtils: FakeOperatingSystemUtils(
name: osName,
whichLookup: <String, File>{
'flutter': flutterBinary,
},
),
flutterRoot: () => flutterRoot,
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
validationType: ValidationType.partial,
statusInfo: 'Channel beta, 1.0.0, on $osName, locale en_US.UTF-8',
messages: everyElement(isA<ValidationMessage>().having(
(ValidationMessage message) => message.message,
'message',
isNot(contains('Warning: `flutter` on your path resolves to')),
)),
));
});
Expand All @@ -430,20 +513,20 @@ void main() {
operatingSystemUtils: FakeOperatingSystemUtils(
name: 'Linux',
whichLookup: <String, File>{
'flutter': fs.file('/usr/bin/flutter')..createSync(recursive: true),
'dart': fs.file('/usr/bin/dart')..createSync(recursive: true),
'flutter': fs.file('/sdk/flutter-beta')..createSync(recursive: true),
'dart': fs.file('/sdk/flutter-beta')..createSync(recursive: true),
},
),
flutterRoot: () => 'sdk/flutter',
flutterRoot: () => '/sdk/flutter',
);

expect(await flutterValidator.validate(), _matchDoctorValidation(
validationType: ValidationType.partial,
statusInfo: 'Channel beta, 1.0.0, on Linux, locale en_US.UTF-8',
messages: contains(const ValidationMessage.hint(
'Warning: `flutter` on your path resolves to /usr/bin/flutter, which '
'is not inside your current Flutter SDK checkout at sdk/flutter. '
'Consider adding sdk/flutter/bin to the front of your path.',
'Warning: `flutter` on your path resolves to /sdk/flutter-beta, which '
'is not inside your current Flutter SDK checkout at /sdk/flutter. '
'Consider adding /sdk/flutter/bin to the front of your path.',
)),
));
});
Expand Down

0 comments on commit 9532b91

Please sign in to comment.