Skip to content

Commit eeb3a40

Browse files
authored
Revert "[ios][tools]do not log "bonjour not found" at all (unless verbose)" (flutter#173879)
Reverts flutter#173569 Sorry I have to revert this one as it didn't work. # Why didn't work From the comment, it looks like `echoError` is only used for verbose mode, and `streamOutput` is used for non-verbose mode (I am still looking into how this is setup) https://github.com/flutter/flutter/blob/e4f27cd09734db6c6ed94e104ab5333c48dfc544/packages/flutter_tools/bin/xcode_backend.dart#L151 # How to fix ## Possible Fix 1 I tested this works, by changing this line: https://github.com/flutter/flutter/blob/master/packages/flutter_tools/bin/xcode_backend.dart#L159 into this: ``` if (!verbose && exitCode == 0 && !skipErrorLog) ``` ## Possible fix 2: Surprisingly this also works: ``` if (!verbose && exitCode == 0) { streamOutput(errorOutput.string().replaceAll('error', ''); } ``` Although we made sure `errorOutput` doesn't start with `error:`, there's an `error:` in the middle of the string. Possibly because of this code in `mac.dart`: https://github.com/flutter/flutter/blob/e4f27cd09734db6c6ed94e104ab5333c48dfc544/packages/flutter_tools/lib/src/ios/mac.dart#L431-L433 # Why we missed it? I tested my initial code code and assumed updated code would work, because I incorrectly thought `echoError` was the one triggered the output in non-verbose mode. I should have verified it.
1 parent 37848d1 commit eeb3a40

File tree

3 files changed

+95
-284
lines changed

3 files changed

+95
-284
lines changed

packages/flutter_tools/bin/xcode_backend.dart

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,14 @@ class Context {
102102

103103
Directory directoryFromPath(String path) => Directory(path);
104104

105-
/// Run given command ([bin]) in a synchronous subprocess.
106-
///
107-
/// If [allowFail] is true, an exception will not be thrown even if the process returns a
108-
/// non-zero exit code. Also, `error:` will not be prefixed to the output to prevent Xcode
109-
/// complication failures.
110-
///
111-
/// If [skipErrorLog] is true, `stderr` from the process will not be output unless in [verbose]
112-
/// mode. If in [verbose], pipes `stderr` to `stdout`.
105+
/// Run given command in a synchronous subprocess.
113106
///
114107
/// Will throw [Exception] if the exit code is not 0.
115108
ProcessResult runSync(
116109
String bin,
117110
List<String> args, {
118111
bool verbose = false,
119112
bool allowFail = false,
120-
bool skipErrorLog = false,
121113
String? workingDirectory,
122114
}) {
123115
if (verbose) {
@@ -130,22 +122,15 @@ class Context {
130122
final String resultStderr = result.stderr.toString().trim();
131123
if (resultStderr.isNotEmpty) {
132124
final errorOutput = StringBuffer();
125+
// If allowFail, do not fail Xcode build. An example is on macOS 26,
126+
// plutil reports NSBonjourServices key not found via stderr (rather than
127+
// stdout on older macOS), and it should not cause compile failure.
133128
if (!allowFail && result.exitCode != 0) {
134129
// "error:" prefix makes this show up as an Xcode compilation error.
135130
errorOutput.write('error: ');
136131
}
137132
errorOutput.write(resultStderr);
138-
if (skipErrorLog) {
139-
// Pipe stderr to stdout under verbose mode.
140-
// An example is on macOS 26, plutil reports NSBonjourServices key not found
141-
// via stderr (rather than stdout on older macOS), and logging the message
142-
// in stderr would be confusing, since not having the key is one of the expected states.
143-
if (verbose) {
144-
echo(errorOutput.toString());
145-
}
146-
} else {
147-
echoError(errorOutput.toString());
148-
}
133+
echoError(errorOutput.toString());
149134

150135
// Stream stderr to the Flutter build process.
151136
// When in verbose mode, `echoError` above will show the logs. So only
@@ -439,17 +424,16 @@ class Context {
439424
return;
440425
}
441426

442-
final bool verbose = (environment['VERBOSE_SCRIPT_LOGGING'] ?? '').isNotEmpty;
443-
444427
// If there are already NSBonjourServices specified by the app (uncommon),
445428
// insert the vmService service name to the existing list.
446-
ProcessResult result = runSync(
447-
'plutil',
448-
<String>['-extract', 'NSBonjourServices', 'xml1', '-o', '-', builtProductsPlist],
449-
verbose: verbose,
450-
allowFail: true,
451-
skipErrorLog: true,
452-
);
429+
ProcessResult result = runSync('plutil', <String>[
430+
'-extract',
431+
'NSBonjourServices',
432+
'xml1',
433+
'-o',
434+
'-',
435+
builtProductsPlist,
436+
], allowFail: true);
453437
if (result.exitCode == 0) {
454438
runSync('plutil', <String>[
455439
'-insert',
@@ -474,13 +458,14 @@ class Context {
474458
// specified (uncommon). This text will appear below the "Your app would
475459
// like to find and connect to devices on your local network" permissions
476460
// popup.
477-
result = runSync(
478-
'plutil',
479-
<String>['-extract', 'NSLocalNetworkUsageDescription', 'xml1', '-o', '-', builtProductsPlist],
480-
verbose: verbose,
481-
allowFail: true,
482-
skipErrorLog: true,
483-
);
461+
result = runSync('plutil', <String>[
462+
'-extract',
463+
'NSLocalNetworkUsageDescription',
464+
'xml1',
465+
'-o',
466+
'-',
467+
builtProductsPlist,
468+
], allowFail: true);
484469
if (result.exitCode != 0) {
485470
runSync('plutil', <String>[
486471
'-insert',

packages/flutter_tools/test/general.shard/xcode_backend_test.dart

Lines changed: 55 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -390,211 +390,70 @@ void main() {
390390
);
391391
});
392392

393-
test(
394-
'Missing NSBonjourServices key in Info.plist should not fail Xcode compilation, and no plutil error in stdout without verbose mode',
395-
() {
396-
final Directory buildDir = fileSystem.directory('/path/to/builds')
397-
..createSync(recursive: true);
398-
final File infoPlist = buildDir.childFile('Info.plist')..createSync();
399-
const plutilErrorMessage =
400-
'Could not extract value, error: No value at that key path or invalid key path: NSBonjourServices';
401-
402-
final context = TestContext(
403-
<String>['test_vm_service_bonjour_service'],
404-
<String, String>{
405-
'CONFIGURATION': 'Debug',
406-
'BUILT_PRODUCTS_DIR': buildDir.path,
407-
'INFOPLIST_PATH': 'Info.plist',
408-
},
409-
commands: <FakeCommand>[
410-
FakeCommand(
411-
command: <String>[
412-
'plutil',
413-
'-extract',
414-
'NSBonjourServices',
415-
'xml1',
416-
'-o',
417-
'-',
418-
infoPlist.path,
419-
],
420-
exitCode: 1,
421-
stderr: plutilErrorMessage,
422-
),
423-
FakeCommand(
424-
command: <String>[
425-
'plutil',
426-
'-insert',
427-
'NSBonjourServices',
428-
'-json',
429-
'["_dartVmService._tcp"]',
430-
infoPlist.path,
431-
],
432-
),
433-
FakeCommand(
434-
command: <String>[
435-
'plutil',
436-
'-extract',
437-
'NSLocalNetworkUsageDescription',
438-
'xml1',
439-
'-o',
440-
'-',
441-
infoPlist.path,
442-
],
443-
),
444-
],
445-
fileSystem: fileSystem,
446-
)..run();
447-
expect(context.stderr, isNot(startsWith('error: ')));
448-
expect(context.stderr, isNot(contains(plutilErrorMessage)));
449-
expect(context.stdout, isNot(contains(plutilErrorMessage)));
450-
},
451-
);
452-
453-
test(
454-
'Missing NSBonjourServices key in Info.plist should not fail Xcode compilation, and has plutil error in stdout under verbose mode',
455-
() {
456-
final Directory buildDir = fileSystem.directory('/path/to/builds')
457-
..createSync(recursive: true);
458-
final File infoPlist = buildDir.childFile('Info.plist')..createSync();
459-
const plutilErrorMessage =
460-
'Could not extract value, error: No value at that key path or invalid key path: NSBonjourServices';
461-
462-
final context = TestContext(
463-
<String>['test_vm_service_bonjour_service'],
464-
<String, String>{
465-
'CONFIGURATION': 'Debug',
466-
'BUILT_PRODUCTS_DIR': buildDir.path,
467-
'INFOPLIST_PATH': 'Info.plist',
468-
'VERBOSE_SCRIPT_LOGGING': 'YES',
469-
},
470-
commands: <FakeCommand>[
471-
FakeCommand(
472-
command: <String>[
473-
'plutil',
474-
'-extract',
475-
'NSBonjourServices',
476-
'xml1',
477-
'-o',
478-
'-',
479-
infoPlist.path,
480-
],
481-
exitCode: 1,
482-
stderr: plutilErrorMessage,
483-
),
484-
FakeCommand(
485-
command: <String>[
486-
'plutil',
487-
'-insert',
488-
'NSBonjourServices',
489-
'-json',
490-
'["_dartVmService._tcp"]',
491-
infoPlist.path,
492-
],
493-
),
494-
FakeCommand(
495-
command: <String>[
496-
'plutil',
497-
'-extract',
498-
'NSLocalNetworkUsageDescription',
499-
'xml1',
500-
'-o',
501-
'-',
502-
infoPlist.path,
503-
],
504-
),
505-
],
506-
fileSystem: fileSystem,
507-
)..run();
508-
expect(context.stderr, isNot(startsWith('error: ')));
509-
expect(context.stderr, isNot(contains(plutilErrorMessage)));
510-
expect(context.stdout, contains(plutilErrorMessage));
511-
},
512-
);
513-
514-
test(
515-
'Missing NSLocalNetworkUsageDescription in Info.plist should not fail Xcode compilation, and no plutil error in stdout without verbose mode',
516-
() {
517-
final Directory buildDir = fileSystem.directory('/path/to/builds')
518-
..createSync(recursive: true);
519-
final File infoPlist = buildDir.childFile('Info.plist')..createSync();
520-
const plutilErrorMessage =
521-
'Could not extract value, error: No value at that key path or invalid key path: NSLocalNetworkUsageDescription';
522-
final context = TestContext(
523-
<String>['test_vm_service_bonjour_service'],
524-
<String, String>{
525-
'CONFIGURATION': 'Debug',
526-
'BUILT_PRODUCTS_DIR': buildDir.path,
527-
'INFOPLIST_PATH': 'Info.plist',
528-
},
529-
commands: <FakeCommand>[
530-
FakeCommand(
531-
command: <String>[
532-
'plutil',
533-
'-extract',
534-
'NSBonjourServices',
535-
'xml1',
536-
'-o',
537-
'-',
538-
infoPlist.path,
539-
],
540-
),
541-
FakeCommand(
542-
command: <String>[
543-
'plutil',
544-
'-insert',
545-
'NSBonjourServices.0',
546-
'-string',
547-
'_dartVmService._tcp',
548-
infoPlist.path,
549-
],
550-
),
551-
FakeCommand(
552-
command: <String>[
553-
'plutil',
554-
'-extract',
555-
'NSLocalNetworkUsageDescription',
556-
'xml1',
557-
'-o',
558-
'-',
559-
infoPlist.path,
560-
],
561-
exitCode: 1,
562-
stderr: plutilErrorMessage,
563-
),
564-
FakeCommand(
565-
command: <String>[
566-
'plutil',
567-
'-insert',
568-
'NSLocalNetworkUsageDescription',
569-
'-string',
570-
'Allow Flutter tools on your computer to connect and debug your application. This prompt will not appear on release builds.',
571-
infoPlist.path,
572-
],
573-
),
574-
],
575-
fileSystem: fileSystem,
576-
)..run();
577-
expect(context.stderr, isNot(startsWith('error: ')));
578-
expect(context.stderr, isNot(contains(plutilErrorMessage)));
579-
expect(context.stdout, isNot(contains(plutilErrorMessage)));
580-
},
581-
);
393+
test('Missing NSBonjourServices key in Info.plist should not fail Xcode compilation', () {
394+
final Directory buildDir = fileSystem.directory('/path/to/builds')
395+
..createSync(recursive: true);
396+
final File infoPlist = buildDir.childFile('Info.plist')..createSync();
397+
final context = TestContext(
398+
<String>['test_vm_service_bonjour_service'],
399+
<String, String>{
400+
'CONFIGURATION': 'Debug',
401+
'BUILT_PRODUCTS_DIR': buildDir.path,
402+
'INFOPLIST_PATH': 'Info.plist',
403+
},
404+
commands: <FakeCommand>[
405+
FakeCommand(
406+
command: <String>[
407+
'plutil',
408+
'-extract',
409+
'NSBonjourServices',
410+
'xml1',
411+
'-o',
412+
'-',
413+
infoPlist.path,
414+
],
415+
exitCode: 1,
416+
stderr: 'No value at that key path or invalid key path: NSBonjourServices',
417+
),
418+
FakeCommand(
419+
command: <String>[
420+
'plutil',
421+
'-insert',
422+
'NSBonjourServices',
423+
'-json',
424+
'["_dartVmService._tcp"]',
425+
infoPlist.path,
426+
],
427+
),
428+
FakeCommand(
429+
command: <String>[
430+
'plutil',
431+
'-extract',
432+
'NSLocalNetworkUsageDescription',
433+
'xml1',
434+
'-o',
435+
'-',
436+
infoPlist.path,
437+
],
438+
),
439+
],
440+
fileSystem: fileSystem,
441+
)..run();
442+
expect(context.stderr, isNot(contains('error: ')));
443+
});
582444

583445
test(
584-
'Missing NSLocalNetworkUsageDescription in Info.plist should not fail Xcode compilation, and has plutil error in stdout under verbose mode',
446+
'Missing NSLocalNetworkUsageDescription in Info.plist should not fail Xcode compilation',
585447
() {
586448
final Directory buildDir = fileSystem.directory('/path/to/builds')
587449
..createSync(recursive: true);
588450
final File infoPlist = buildDir.childFile('Info.plist')..createSync();
589-
const plutilErrorMessage =
590-
'Could not extract value, error: No value at that key path or invalid key path: NSLocalNetworkUsageDescription';
591451
final context = TestContext(
592452
<String>['test_vm_service_bonjour_service'],
593453
<String, String>{
594454
'CONFIGURATION': 'Debug',
595455
'BUILT_PRODUCTS_DIR': buildDir.path,
596456
'INFOPLIST_PATH': 'Info.plist',
597-
'VERBOSE_SCRIPT_LOGGING': 'YES',
598457
},
599458
commands: <FakeCommand>[
600459
FakeCommand(
@@ -629,7 +488,8 @@ void main() {
629488
infoPlist.path,
630489
],
631490
exitCode: 1,
632-
stderr: plutilErrorMessage,
491+
stderr:
492+
'No value at that key path or invalid key path: NSLocalNetworkUsageDescription',
633493
),
634494
FakeCommand(
635495
command: <String>[
@@ -644,9 +504,7 @@ void main() {
644504
],
645505
fileSystem: fileSystem,
646506
)..run();
647-
expect(context.stderr, isNot(startsWith('error: ')));
648-
expect(context.stderr, isNot(contains(plutilErrorMessage)));
649-
expect(context.stdout, contains(plutilErrorMessage));
507+
expect(context.stderr, isNot(contains('error: ')));
650508
},
651509
);
652510
});

0 commit comments

Comments
 (0)