diff --git a/packages/patrol_cli/CHANGELOG.md b/packages/patrol_cli/CHANGELOG.md index f72483f2a..12c37d5ed 100644 --- a/packages/patrol_cli/CHANGELOG.md +++ b/packages/patrol_cli/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.0.0 + +- **Breaking:** Use `java` version from `flutter doctor` + ## 2.8.1 - Fix parsing non string values from --dart-define-from-file (#2243). diff --git a/packages/patrol_cli/lib/src/android/android_test_backend.dart b/packages/patrol_cli/lib/src/android/android_test_backend.dart index efb277ccf..b9d1c72fa 100644 --- a/packages/patrol_cli/lib/src/android/android_test_backend.dart +++ b/packages/patrol_cli/lib/src/android/android_test_backend.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io' show Process; import 'package:adb/adb.dart'; @@ -37,8 +38,11 @@ class AndroidTestBackend { final FileSystem _fs; final DisposeScope _disposeScope; final Logger _logger; + late final String javaPath; Future build(AndroidAppOptions options) async { + await loadJavaPathFromFlutterDoctor(options.flutter.command.executable); + await _disposeScope.run((scope) async { final subject = options.description; final task = _logger.task('Building $subject'); @@ -52,6 +56,9 @@ class AndroidTestBackend { options.toGradleAssembleInvocation(isWindows: _platform.isWindows), runInShell: true, workingDirectory: _fs.currentDirectory.childDirectory('android').path, + environment: { + 'JAVA_HOME': javaPath, + }, ) ..disposedBy(scope); process.listenStdOut((l) => _logger.detail('\t: $l')).disposedBy(scope); @@ -73,6 +80,9 @@ class AndroidTestBackend { options.toGradleAssembleTestInvocation(isWindows: _platform.isWindows), runInShell: true, workingDirectory: _fs.currentDirectory.childDirectory('android').path, + environment: { + 'JAVA_HOME': javaPath, + }, ) ..disposedBy(scope); process.listenStdOut((l) => _logger.detail('\t: $l')).disposedBy(scope); @@ -92,6 +102,40 @@ class AndroidTestBackend { }); } + Future loadJavaPathFromFlutterDoctor(String commandExecutable) async { + final javaCompleterPath = Completer(); + + await _disposeScope.run((scope) async { + final process = await _processManager.start( + [ + commandExecutable, + 'doctor', + '--verbose', + ], + runInShell: true, + ) + ..disposedBy(scope); + + process.listenStdOut( + (line) async { + if (line.contains('• Java binary at:') && + javaCompleterPath.isCompleted == false) { + final path = line + .replaceAll('• Java binary at:', '') + .replaceAll( + _platform.isWindows ? r'\bin\java' : '/bin/java', + '', + ) + .trim(); + javaCompleterPath.complete(path); + } + }, + ).disposedBy(scope); + }); + + javaPath = await javaCompleterPath.future ?? ''; + } + /// Executes the tests of the given [options] on the given [device]. /// /// [build] must be called before this method. @@ -110,7 +154,10 @@ class AndroidTestBackend { final process = await _processManager.start( options.toGradleConnectedTestInvocation(isWindows: _platform.isWindows), runInShell: true, - environment: {'ANDROID_SERIAL': device.id}, + environment: { + 'ANDROID_SERIAL': device.id, + 'JAVA_HOME': javaPath, + }, workingDirectory: _fs.currentDirectory.childDirectory('android').path, ) ..disposedBy(scope); diff --git a/packages/patrol_cli/lib/src/base/constants.dart b/packages/patrol_cli/lib/src/base/constants.dart index b210ecc57..65d54af6e 100644 --- a/packages/patrol_cli/lib/src/base/constants.dart +++ b/packages/patrol_cli/lib/src/base/constants.dart @@ -1,3 +1,3 @@ /// Version of Patrol CLI. Must be kept in sync with pubspec.yaml. /// If you update this, make sure that compatibility-table.mdx is updated (if needed) -const version = '2.8.1'; +const version = '3.0.0'; diff --git a/packages/patrol_cli/lib/src/commands/develop.dart b/packages/patrol_cli/lib/src/commands/develop.dart index 4f054eb47..d9e1effd8 100644 --- a/packages/patrol_cli/lib/src/commands/develop.dart +++ b/packages/patrol_cli/lib/src/commands/develop.dart @@ -94,10 +94,6 @@ class DevelopCommand extends PatrolCommand { ), ); - await _compatibilityChecker.checkVersionsCompatibility( - flutterCommand: flutterCommand, - ); - final targets = stringsArg('target'); if (targets.isEmpty) { throwToolExit('No target provided with --target'); @@ -134,6 +130,11 @@ class DevelopCommand extends PatrolCommand { ); final device = devices.single; + await _compatibilityChecker.checkVersionsCompatibility( + flutterCommand: flutterCommand, + targetPlatform: device.targetPlatform, + ); + // `flutter logs` doesn't work on macOS, so we don't support it for now // https://github.com/leancodepl/patrol/issues/1974 if (device.targetPlatform == TargetPlatform.macOS) { diff --git a/packages/patrol_cli/lib/src/commands/test.dart b/packages/patrol_cli/lib/src/commands/test.dart index 877fc860e..6e69aad6e 100644 --- a/packages/patrol_cli/lib/src/commands/test.dart +++ b/packages/patrol_cli/lib/src/commands/test.dart @@ -84,10 +84,6 @@ class TestCommand extends PatrolCommand { ), ); - await _compatibilityChecker.checkVersionsCompatibility( - flutterCommand: flutterCommand, - ); - final config = _pubspecReader.read(); final testFileSuffix = config.testFileSuffix; @@ -141,6 +137,11 @@ See https://github.com/leancodepl/patrol/issues/1316 to learn more. final device = devices.single; + await _compatibilityChecker.checkVersionsCompatibility( + flutterCommand: flutterCommand, + targetPlatform: device.targetPlatform, + ); + final packageName = stringArg('package-name') ?? config.android.packageName; final bundleId = stringArg('bundle-id') ?? config.ios.bundleId; final macosBundleId = stringArg('bundle-id') ?? config.macos.bundleId; diff --git a/packages/patrol_cli/lib/src/compatibility_checker.dart b/packages/patrol_cli/lib/src/compatibility_checker.dart index 4af7965fb..48837fb87 100644 --- a/packages/patrol_cli/lib/src/compatibility_checker.dart +++ b/packages/patrol_cli/lib/src/compatibility_checker.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:io' as io; import 'package:dispose_scope/dispose_scope.dart'; import 'package:file/file.dart'; @@ -7,6 +6,7 @@ import 'package:patrol_cli/src/base/constants.dart' as constants; import 'package:patrol_cli/src/base/exceptions.dart'; import 'package:patrol_cli/src/base/logger.dart'; import 'package:patrol_cli/src/base/process.dart'; +import 'package:patrol_cli/src/devices.dart'; import 'package:patrol_cli/src/runner/flutter_command.dart'; import 'package:process/process.dart'; import 'package:version/version.dart'; @@ -28,10 +28,12 @@ class CompatibilityChecker { Future checkVersionsCompatibility({ required FlutterCommand flutterCommand, + required TargetPlatform targetPlatform, }) async { - if (io.Platform.isAndroid) { + if (targetPlatform == TargetPlatform.android) { await _checkJavaVersion( - _disposeScope, + flutterCommand.executable, + DisposeScope(), _processManager, _projectRoot, _logger, @@ -91,30 +93,36 @@ class CompatibilityChecker { } Future _checkJavaVersion( + String flutterExecutable, DisposeScope disposeScope, ProcessManager processManager, Directory projectRoot, Logger logger, ) async { Version? javaVersion; - final javaCompleter = Completer(); + final javaCompleterVersion = Completer(); await disposeScope.run((scope) async { final process = await processManager.start( - ['javac', '--version'], + [flutterExecutable, 'doctor', '--verbose'], workingDirectory: projectRoot.path, runInShell: true, ) ..disposedBy(scope); - process.listenStdOut((line) async { - if (line.startsWith('javac')) { - javaCompleter.complete(Version.parse(line.split(' ').last)); - } - }).disposedBy(scope); + process.listenStdOut( + (line) async { + if (line.contains('• Java version') && + javaCompleterVersion.isCompleted == false) { + final versionString = line.split(' ').last.replaceAll(')', ''); + javaCompleterVersion.complete(Version.parse(versionString)); + } + }, + ).disposedBy(scope); }); - javaVersion = await javaCompleter.future; + javaVersion = await javaCompleterVersion.future; + if (javaVersion == null) { throwToolExit( 'Failed to read Java version. Make sure you have Java installed and added to PATH', diff --git a/packages/patrol_cli/pubspec.yaml b/packages/patrol_cli/pubspec.yaml index 4a6ef8a23..b545bbd93 100644 --- a/packages/patrol_cli/pubspec.yaml +++ b/packages/patrol_cli/pubspec.yaml @@ -1,7 +1,7 @@ name: patrol_cli description: > Command-line tool for Patrol, a powerful Flutter-native UI testing framework. -version: 2.8.1 # Must be kept in sync with constants.dart +version: 3.0.0 # Must be kept in sync with constants.dart homepage: https://patrol.leancode.co repository: https://github.com/leancodepl/patrol/tree/master/packages/patrol_cli issue_tracker: https://github.com/leancodepl/patrol/issues?q=is%3Aopen+is%3Aissue+label%3A%22package%3A+patrol_cli%22