Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dart_test_adapter): use valid SDK executable for tests #18

Closed
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: create SDK lookup methods
mrverdant13 committed Mar 15, 2022
commit 6d780d5ec1328cda9e88341bce5f7aa264693d52
82 changes: 82 additions & 0 deletions packages/dart_test_adapter/lib/src/sdk_lookup.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import 'dart:convert';

import 'package:path/path.dart' as p;
import 'package:universal_io/io.dart';

/// An SDK.
enum Sdk {
/// The Dart SDK.
dart,

/// The Flutter SDK.
flutter,
}

/// {@template sdk_not_found_exception}
/// The exception thrown when and [Sdk] is not found.
/// {@endtemplate}
class SdkNotFoundException implements Exception {
/// {@macro sdk_not_found_exception}
const SdkNotFoundException({
required this.sdk,
});

/// The [Sdk] that was not found.
final Sdk sdk;

@override
String toString() => '''
${sdk.capitalizedName} SDK not found.
Verify that the SDK path has been added to your PATH environment variable.''';
}

/// A set of utilities for working with an [Sdk].
extension ExtendedSdk on Sdk {
/// The capitalized name of the [Sdk].
String get capitalizedName => [
name[0].toUpperCase(),
name.substring(1),
].join();

/// The collection of valid extensions for the [Sdk] according to the current
/// platform.
///
/// The [Sdk]s installation always includes executables for all the supported
/// platforms. This set of extensions is used to determine which of those are
/// valid for the current platform.
Iterable<String> get _extensions =>
Platform.isWindows ? ['.bat', '.exe'] : ['.sh', ''];

/// The lookup command according to the current platform.
static final _lookupCommand = Platform.isWindows ? 'where.exe' : 'which';

static const _lineSplitter = LineSplitter();

/// The collection of valid executable paths for the [Sdk].
///
/// Might be empty if the [Sdk] is not found.
Future<Iterable<String>> getExecutablePaths({
required Map<String, String>? env,
}) async {
final commandLookupResult = await Process.run(
_lookupCommand,
[name],
environment: env,
);
final commandPaths = _lineSplitter
.convert(commandLookupResult.stdout as String)
.where((s) => _extensions.any((ext) => p.extension(s) == ext));
return commandPaths;
}

/// The default [Sdk] executable path.
///
/// Throws [SdkNotFoundException] if the [Sdk] is not found.
Future<String> getDefaultExecutablePath({
required Map<String, String>? env,
}) async {
final paths = await getExecutablePaths(env: env);
if (paths.isEmpty) throw SdkNotFoundException(sdk: this);
return paths.first;
}
}