Skip to content

[flutter_tools] [dap] Add support for passing env variables to spawned processes #107415

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

Merged
merged 4 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
13 changes: 11 additions & 2 deletions packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,11 @@ class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments
...?userArgs,
];

await launchAsProcess(executable, processArgs);
await launchAsProcess(
executable: executable,
processArgs: processArgs,
env: args.env,
);

// Delay responding until the app is launched and (optionally) the debugger
// is connected.
Expand All @@ -316,12 +320,17 @@ class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments
}

@visibleForOverriding
Future<void> launchAsProcess(String executable, List<String> processArgs) async {
Future<void> launchAsProcess({
required String executable,
required List<String> processArgs,
required Map<String, String>? env,
}) async {
logger?.call('Spawning $executable with $processArgs in ${args.cwd}');
final Process process = await Process.start(
executable,
processArgs,
workingDirectory: args.cwd,
environment: env,
);
_process = process;
pidsToTerminate.add(process.pid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class FlutterAttachRequestArguments
super.restart,
super.name,
super.cwd,
super.env,
super.additionalProjectPaths,
super.debugSdkLibraries,
super.debugExternalPackageLibraries,
Expand Down Expand Up @@ -91,6 +92,7 @@ class FlutterLaunchRequestArguments
super.restart,
super.name,
super.cwd,
super.env,
super.additionalProjectPaths,
super.debugSdkLibraries,
super.debugExternalPackageLibraries,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ class FlutterTestDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArgum
...?args.args,
];

await launchAsProcess(executable, processArgs);
await launchAsProcess(
executable: executable,
processArgs: processArgs,
env: args.env,
);

// Delay responding until the debugger is connected.
if (debug) {
Expand All @@ -144,12 +148,17 @@ class FlutterTestDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArgum
}

@visibleForOverriding
Future<void> launchAsProcess(String executable, List<String> processArgs) async {
Future<void> launchAsProcess({
required String executable,
required List<String> processArgs,
required Map<String, String>? env,
}) async {
logger?.call('Spawning $executable with $processArgs in ${args.cwd}');
final Process process = await Process.start(
executable,
processArgs,
workingDirectory: args.cwd,
environment: env,
);
_process = process;
pidsToTerminate.add(process.pid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,39 @@

import 'dart:async';

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/debug_adapters/flutter_adapter_args.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/globals.dart' as globals show platform;
import 'package:test/fake.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';

import 'mocks.dart';

void main() {
// Use the real platform as a base so that Windows bots test paths.
final FakePlatform platform = FakePlatform.fromPlatform(globals.platform);
final FileSystemStyle fsStyle = platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;

group('flutter adapter', () {
final String expectedFlutterExecutable = globals.platform.isWindows
final String expectedFlutterExecutable = platform.isWindows
? r'C:\fake\flutter\bin\flutter.bat'
: '/fake/flutter/bin/flutter';

setUpAll(() {
Cache.flutterRoot = globals.platform.isWindows
Cache.flutterRoot = platform.isWindows
? r'C:\fake\flutter'
: '/fake/flutter';
});


group('launchRequest', () {
test('runs "flutter run" with --machine', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
group('launchRequest', () {
test('runs "flutter run" with --machine', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -43,8 +51,33 @@ void main() {
expect(adapter.processArgs, containsAllInOrder(<String>['run', '--machine']));
});

test('includes env variables', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
cwd: '/project',
program: 'foo.dart',
env: <String, String>{
'MY_TEST_ENV': 'MY_TEST_VALUE',
},
);

await adapter.configurationDoneRequest(MockRequest(), null, () {});
await adapter.launchRequest(MockRequest(), args, responseCompleter.complete);
await responseCompleter.future;

expect(adapter.env!['MY_TEST_ENV'], 'MY_TEST_VALUE');
});

test('does not record the VMs PID for terminating', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -65,10 +98,12 @@ void main() {
});
});


group('attachRequest', () {
test('runs "flutter attach" with --machine', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
group('attachRequest', () {
test('runs "flutter attach" with --machine', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterAttachRequestArguments args = FlutterAttachRequestArguments(
Expand All @@ -83,7 +118,10 @@ void main() {
});

test('does not record the VMs PID for terminating', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterAttachRequestArguments args = FlutterAttachRequestArguments(
Expand All @@ -105,7 +143,10 @@ void main() {

group('--start-paused', () {
test('is passed for debug mode', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -121,7 +162,10 @@ void main() {
});

test('is not passed for noDebug mode', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -138,7 +182,10 @@ void main() {
});

test('is not passed if toolArgs contains --profile', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -155,7 +202,10 @@ void main() {
});

test('is not passed if toolArgs contains --release', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -173,7 +223,10 @@ void main() {
});

test('includes toolArgs', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();

final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -193,7 +246,10 @@ void main() {

group('includes customTool', () {
test('with no args replaced', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
cwd: '/project',
program: 'foo.dart',
Expand All @@ -212,7 +268,10 @@ void main() {
});

test('with all args replaced', () async {
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(fileSystem: globals.fs, platform: globals.platform);
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
cwd: '/project',
program: 'foo.dart',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,35 @@

import 'dart:async';

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/debug_adapters/flutter_adapter_args.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/globals.dart' as globals show platform;
import 'package:test/test.dart';

import 'mocks.dart';

void main() {
// Use the real platform as a base so that Windows bots test paths.
final FakePlatform platform = FakePlatform.fromPlatform(globals.platform);
final FileSystemStyle fsStyle = platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix;

group('flutter test adapter', () {
final String expectedFlutterExecutable = globals.platform.isWindows
final String expectedFlutterExecutable = platform.isWindows
? r'C:\fake\flutter\bin\flutter.bat'
: '/fake/flutter/bin/flutter';

setUpAll(() {
Cache.flutterRoot = globals.platform.isWindows
Cache.flutterRoot = platform.isWindows
? r'C:\fake\flutter'
: '/fake/flutter';
});

test('includes toolArgs', () async {
final MockFlutterTestDebugAdapter adapter = MockFlutterTestDebugAdapter(
fileSystem: globals.fs,
platform: globals.platform,
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
Expand All @@ -45,10 +51,34 @@ void main() {
expect(adapter.processArgs, contains('tool_arg'));
});

test('includes env variables', () async {
final MockFlutterTestDebugAdapter adapter = MockFlutterTestDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
cwd: '/project',
program: 'foo.dart',
env: <String, String>{
'MY_TEST_ENV': 'MY_TEST_VALUE',
},
);

await adapter.configurationDoneRequest(request, null, () {});
await adapter.launchRequest(request, args, responseCompleter.complete);
await responseCompleter.future;

expect(adapter.env!['MY_TEST_ENV'], 'MY_TEST_VALUE');
});

group('includes customTool', () {
test('with no args replaced', () async {
final MockFlutterTestDebugAdapter adapter = MockFlutterTestDebugAdapter(fileSystem: globals.fs,
platform: globals.platform,);
final MockFlutterTestDebugAdapter adapter = MockFlutterTestDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand All @@ -68,8 +98,10 @@ void main() {
});

test('with all args replaced', () async {
final MockFlutterTestDebugAdapter adapter = MockFlutterTestDebugAdapter(fileSystem: globals.fs,
platform: globals.platform,);
final MockFlutterTestDebugAdapter adapter = MockFlutterTestDebugAdapter(
fileSystem: MemoryFileSystem.test(style: fsStyle),
platform: platform,
);
final Completer<void> responseCompleter = Completer<void>();
final MockRequest request = MockRequest();
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
Expand Down
Loading