Version 2.17.0-107.0.dev
Merge commit '4bd312d1e6b101e6aa61149b9af2d9b062bdc251' into 'dev'
diff --git a/.dart_tool/OWNERS b/.dart_tool/OWNERS
new file mode 100644
index 0000000..d52dde4
--- /dev/null
+++ b/.dart_tool/OWNERS
@@ -0,0 +1,2 @@
+# Generated file
+per-file package_config.json=*
diff --git a/.github/OWNERS b/.github/OWNERS
new file mode 100644
index 0000000..12997a6
--- /dev/null
+++ b/.github/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_PRODUCT
+file:/tools/OWNERS_INFRA
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..88fdd3c
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,23 @@
+# Global approvers - only to be used as a last resort.
+asiva@google.com #{LAST_RESORT_SUGGESTION}
+athom@google.com #{LAST_RESORT_SUGGESTION}
+kustermann@google.com #{LAST_RESORT_SUGGESTION}
+leafp@google.com #{LAST_RESORT_SUGGESTION}
+sigmund@google.com #{LAST_RESORT_SUGGESTION}
+vegorov@google.com #{LAST_RESORT_SUGGESTION}
+vsm@google.com #{LAST_RESORT_SUGGESTION}
+
+# DEPS
+per-file DEPS=/tools/OWNERS_ENG
+
+# Changelog, AUTHORS, and .git* do not require approval.
+per-file CHANGELOG.md,AUTHORS,.gitattributes,.gitconfig,.gitignore=*
+
+# Product documentation
+CONTRIBUTING.md,LICENSE,PATENT_GRANT,README.*,SECURITY.md=file:/tools/OWNERS_PRODUCT
+
+# Top level build files
+per-file .clang-format,BUILD.gn,sdk_args.gni=file:/tools/OWNERS_VM,file:/tools/OWNERS_INFRA
+
+# Generated file
+per-file .packages=*
diff --git a/benchmarks/OWNERS b/benchmarks/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/benchmarks/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/build/OWNERS b/build/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/build/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/docs/OWNERS b/docs/OWNERS
new file mode 100644
index 0000000..22a2e82
--- /dev/null
+++ b/docs/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION
+file:/tools/OWNERS_PRODUCT
diff --git a/pkg/OWNERS b/pkg/OWNERS
new file mode 100644
index 0000000..c3abcf9
--- /dev/null
+++ b/pkg/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION #{LAST_RESORT_SUGGESTION}
+file:/tools/OWNERS_INFRA #{LAST_RESORT_SUGGESTION}
diff --git a/pkg/_fe_analyzer_shared/OWNERS b/pkg/_fe_analyzer_shared/OWNERS
new file mode 100644
index 0000000..6fd2278
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_ANALYZER
+file:/tools/OWNERS_CFE
diff --git a/pkg/analysis_server/OWNERS b/pkg/analysis_server/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analysis_server/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index a782782..55257c6 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -208,6 +208,8 @@
static const InvalidFileLineCol = ErrorCodes(-32004);
static const UnknownCommand = ErrorCodes(-32005);
static const InvalidCommandArguments = ErrorCodes(-32006);
+
+ /// A file that is not part of the analyzed set.
static const FileNotAnalyzed = ErrorCodes(-32007);
static const FileHasErrors = ErrorCodes(-32008);
static const ClientFailedToApplyEdit = ErrorCodes(-32009);
@@ -215,6 +217,9 @@
static const RefactorFailed = ErrorCodes(-32011);
static const FeatureDisabled = ErrorCodes(-32012);
+ /// A file that is expected to be analyzed, but failed.
+ static const FileAnalysisFailed = ErrorCodes(-32013);
+
/// An error raised when the server detects that the server and client are out
/// of sync and cannot recover. For example if a textDocument/didChange notification
/// has invalid offsets, suggesting the client and server have become out of sync
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
index 81b9b85..84da8f2 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
@@ -23,7 +23,8 @@
ErrorOr<List<TextEdit>?> formatFile(String path) {
final file = server.resourceProvider.getFile(path);
if (!file.exists) {
- return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ return error(
+ ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
}
final result = server.getParsedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
index a6bbf90..f28ef15 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
@@ -23,7 +23,8 @@
ErrorOr<List<TextEdit>?> formatRange(String path, Range range) {
final file = server.resourceProvider.getFile(path);
if (!file.exists) {
- return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ return error(
+ ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
}
final result = server.getParsedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
index be75ccb..6ff4313 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
@@ -23,7 +23,8 @@
ErrorOr<List<TextEdit>?> formatFile(String path) {
final file = server.resourceProvider.getFile(path);
if (!file.exists) {
- return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ return error(
+ ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
}
final result = server.getParsedUnit(path);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index e0f497c..ddd82dc 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -56,7 +56,8 @@
final lineInfo = server.getLineInfo(path);
if (lineInfo == null) {
- return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ return error(ServerErrorCodes.InvalidFilePath,
+ 'Unable to obtain line information for file', path);
} else {
return success(lineInfo);
}
@@ -65,7 +66,19 @@
Future<ErrorOr<ResolvedUnitResult>> requireResolvedUnit(String path) async {
final result = await server.getResolvedUnit(path);
if (result == null) {
- return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ if (server.isAnalyzed(path)) {
+ // If the file was being analyzed and we got a null result, that usually
+ // indicators a parser or analysis failure, so provide a more specific
+ // message.
+ return error(ServerErrorCodes.FileAnalysisFailed,
+ 'Analysis failed for file', path);
+ } else {
+ return error(ServerErrorCodes.FileNotAnalyzed,
+ 'File is not being analyzed', path);
+ }
+ } else if (!result.exists) {
+ return error(
+ ServerErrorCodes.InvalidFilePath, 'File does not exist', path);
}
return success(result);
}
@@ -73,7 +86,16 @@
ErrorOr<ParsedUnitResult> requireUnresolvedUnit(String path) {
final result = server.getParsedUnit(path);
if (result == null) {
- return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ if (server.isAnalyzed(path)) {
+ // If the file was being analyzed and we got a null result, that usually
+ // indicators a parser or analysis failure, so provide a more specific
+ // message.
+ return error(ServerErrorCodes.FileAnalysisFailed,
+ 'Analysis failed for file', path);
+ } else {
+ return error(ServerErrorCodes.FileNotAnalyzed,
+ 'File is not being analyzed', path);
+ }
}
return success(result);
}
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 853fa09..ba6a1d6 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:io';
import 'dart:math';
import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart'
@@ -798,7 +799,18 @@
));
}
try {
- return ErrorOr<String>.success(uri.toFilePath());
+ final filePath = uri.toFilePath();
+ // On Windows, paths that start with \ and not a drive letter are not
+ // supported but will return `true` from `path.isAbsolute` so check for them
+ // specifically.
+ if (Platform.isWindows && filePath.startsWith(r'\')) {
+ return ErrorOr<String>.error(ResponseError(
+ code: lsp.ServerErrorCodes.InvalidFilePath,
+ message: 'URI was not an absolute file path (missing drive letter)',
+ data: uri.toString(),
+ ));
+ }
+ return ErrorOr<String>.success(filePath);
} catch (e) {
// Even if tryParse() works and file == scheme, toFilePath() can throw on
// Windows if there are invalid characters.
diff --git a/pkg/analysis_server/test/lsp/document_symbols_test.dart b/pkg/analysis_server/test/lsp/document_symbols_test.dart
index a37882a..48ddc1b 100644
--- a/pkg/analysis_server/test/lsp/document_symbols_test.dart
+++ b/pkg/analysis_server/test/lsp/document_symbols_test.dart
@@ -206,8 +206,10 @@
newFile(mainFilePath, content: content);
await initialize(allowEmptyRootUri: true);
- await expectLater(getDocumentSymbols(mainFileUri.toString()),
- throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)));
+ await expectLater(
+ getDocumentSymbols(mainFileUri.toString()),
+ throwsA(isResponseError(ServerErrorCodes.FileNotAnalyzed,
+ message: 'File is not being analyzed')));
}
Future<void> test_nonDartFile() async {
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 7ffff8a..f3d24e8 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -640,7 +640,8 @@
await expectLater(
formatDocument(
Uri.file(join(projectFolderPath, 'missing.dart')).toString()),
- throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'File does not exist')),
);
}
@@ -649,8 +650,9 @@
await expectLater(
// Add some invalid path characters to the end of a valid file:// URI.
- formatDocument(mainFileUri.toString() + '***.dart'),
- throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+ formatDocument(mainFileUri.toString() + r'***###\\\///:::.dart'),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'File URI did not contain a valid file path')),
);
}
@@ -659,7 +661,8 @@
await expectLater(
formatDocument('a:/a.dart'),
- throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'URI was not a valid file:// URI')),
);
}
diff --git a/pkg/analysis_server/test/lsp/server_test.dart b/pkg/analysis_server/test/lsp/server_test.dart
index 22608c0..48d0109 100644
--- a/pkg/analysis_server/test/lsp/server_test.dart
+++ b/pkg/analysis_server/test/lsp/server_test.dart
@@ -2,11 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:io';
+
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../tool/lsp_spec/matchers.dart';
import 'server_abstract.dart';
void main() {
@@ -44,6 +48,67 @@
await server.exited.timeout(const Duration(seconds: 10));
}
+ Future<void> test_path_doesNotExist() async {
+ final missingFileUri = Uri.file(join(projectFolderPath, 'missing.dart'));
+ await initialize();
+ await expectLater(
+ getHover(missingFileUri, startOfDocPos),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'File does not exist')),
+ );
+ }
+
+ Future<void> test_path_invalidFormat() async {
+ await initialize();
+ await expectLater(
+ // Add some invalid path characters to the end of a valid file:// URI.
+ formatDocument(mainFileUri.toString() + r'***###\\\///:::.dart'),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'File URI did not contain a valid file path')),
+ );
+ }
+
+ Future<void> test_path_missingDriveLetterWindows() async {
+ // This test is only valid on Windows, as a URI in the format:
+ // file:///foo/bar.dart
+ // is valid for non-Windows platforms, but not valid on Windows as it does
+ // not have a drive letter.
+ if (!Platform.isWindows) {
+ return;
+ }
+ final missingDriveLetterFileUri = Uri.file('/foo/bar.dart');
+ await initialize();
+ await expectLater(
+ getHover(missingDriveLetterFileUri, startOfDocPos),
+ // The Uri.file() above translates to a non-file:// URI of just 'a/b.dart'
+ // so will get the not-file-scheme error message.
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'URI was not an absolute file path (missing drive letter)')),
+ );
+ }
+
+ Future<void> test_path_notFileScheme() async {
+ final relativeFileUri = Uri(scheme: 'foo', path: '/a/b.dart');
+ await initialize();
+ await expectLater(
+ getHover(relativeFileUri, startOfDocPos),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'URI was not a valid file:// URI')),
+ );
+ }
+
+ Future<void> test_path_relative() async {
+ final relativeFileUri = Uri.file('a/b.dart');
+ await initialize();
+ await expectLater(
+ getHover(relativeFileUri, startOfDocPos),
+ // The Uri.file() above translates to a non-file:// URI of just 'a/b.dart'
+ // so will get the not-file-scheme error message.
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath,
+ message: 'URI was not a valid file:// URI')),
+ );
+ }
+
Future<void> test_shutdown_initialized() async {
await initialize();
final response = await sendShutdown();
diff --git a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
index a424ae1..65bb7ae 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
@@ -15,8 +15,13 @@
Matcher isMapOf(Matcher indexMatcher, Matcher valueMatcher) =>
MapTypeMatcher(wrapMatcher(indexMatcher), wrapMatcher(valueMatcher));
-Matcher isResponseError(ErrorCodes code) => const TypeMatcher<ResponseError>()
- .having((e) => e.code, 'code', equals(code));
+Matcher isResponseError(ErrorCodes code, {String? message}) {
+ final matcher = const TypeMatcher<ResponseError>()
+ .having((e) => e.code, 'code', equals(code));
+ return message != null
+ ? matcher.having((e) => e.message, 'message', equals(message))
+ : matcher;
+}
Matcher isSimpleType(String name) => SimpleTypeMatcher(name);
diff --git a/pkg/analysis_server_client/OWNERS b/pkg/analysis_server_client/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analysis_server_client/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer/OWNERS b/pkg/analyzer/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer_cli/OWNERS b/pkg/analyzer_cli/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer_cli/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer_plugin/OWNERS b/pkg/analyzer_plugin/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer_plugin/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/analyzer_utilities/OWNERS b/pkg/analyzer_utilities/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/analyzer_utilities/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/async_helper/OWNERS b/pkg/async_helper/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/async_helper/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/build_integration/OWNERS b/pkg/build_integration/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/build_integration/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/compiler/OWNERS b/pkg/compiler/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/compiler/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2js_info/OWNERS b/pkg/dart2js_info/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dart2js_info/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2js_runtime_metrics/OWNERS b/pkg/dart2js_runtime_metrics/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dart2js_runtime_metrics/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2js_tools/OWNERS b/pkg/dart2js_tools/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dart2js_tools/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/dart2native/OWNERS b/pkg/dart2native/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/dart2native/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/dart_internal/OWNERS b/pkg/dart_internal/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/dart_internal/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/dartdev/OWNERS b/pkg/dartdev/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/dartdev/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/dds/OWNERS b/pkg/dds/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/dds/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/dds_service_extensions/OWNERS b/pkg/dds_service_extensions/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/dds_service_extensions/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/dev_compiler/OWNERS b/pkg/dev_compiler/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/dev_compiler/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/diagnostic/OWNERS b/pkg/diagnostic/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/diagnostic/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/expect/OWNERS b/pkg/expect/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/pkg/expect/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/pkg/front_end/OWNERS b/pkg/front_end/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/front_end/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/frontend_server/OWNERS b/pkg/frontend_server/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/frontend_server/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/js/OWNERS b/pkg/js/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/js/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/js_ast/OWNERS b/pkg/js_ast/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/js_ast/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/js_runtime/OWNERS b/pkg/js_runtime/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/js_runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/kernel/OWNERS b/pkg/kernel/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/kernel/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/language_versioning_2.7_test/OWNERS b/pkg/language_versioning_2.7_test/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/language_versioning_2.7_test/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/meta/OWNERS b/pkg/meta/OWNERS
new file mode 100644
index 0000000..80d5ff4
--- /dev/null
+++ b/pkg/meta/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_ANALYZER
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/modular_test/OWNERS b/pkg/modular_test/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/modular_test/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/native_stack_traces/OWNERS b/pkg/native_stack_traces/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/native_stack_traces/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/nnbd_migration/OWNERS b/pkg/nnbd_migration/OWNERS
new file mode 100644
index 0000000..80d5ff4
--- /dev/null
+++ b/pkg/nnbd_migration/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_ANALYZER
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/scrape/OWNERS b/pkg/scrape/OWNERS
new file mode 100644
index 0000000..876a884
--- /dev/null
+++ b/pkg/scrape/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_FOUNDATION
diff --git a/pkg/smith/OWNERS b/pkg/smith/OWNERS
new file mode 100644
index 0000000..1e73a64
--- /dev/null
+++ b/pkg/smith/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_INFRA
diff --git a/pkg/sourcemap_testing/OWNERS b/pkg/sourcemap_testing/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/pkg/sourcemap_testing/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/pkg/status_file/OWNERS b/pkg/status_file/OWNERS
new file mode 100644
index 0000000..1e73a64
--- /dev/null
+++ b/pkg/status_file/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_INFRA
diff --git a/pkg/telemetry/OWNERS b/pkg/telemetry/OWNERS
new file mode 100644
index 0000000..1592b3e
--- /dev/null
+++ b/pkg/telemetry/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ANALYZER
diff --git a/pkg/test_runner/OWNERS b/pkg/test_runner/OWNERS
new file mode 100644
index 0000000..1e73a64
--- /dev/null
+++ b/pkg/test_runner/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_INFRA
diff --git a/pkg/testing/OWNERS b/pkg/testing/OWNERS
new file mode 100644
index 0000000..33947e7
--- /dev/null
+++ b/pkg/testing/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_CFE
diff --git a/pkg/vm/OWNERS b/pkg/vm/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/vm/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/vm_service/OWNERS b/pkg/vm_service/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/vm_service/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/pkg/vm_snapshot_analysis/OWNERS b/pkg/vm_snapshot_analysis/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/pkg/vm_snapshot_analysis/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/runtime/OWNERS b/runtime/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 2e80b0a..3461f25 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -502,7 +502,8 @@
ASSERT(flags != nullptr);
#if defined(DART_PRECOMPILED_RUNTIME)
- // AOT: All isolates start from the app snapshot.
+ // AOT: The service isolate is included in any AOT snapshot in non-PRODUCT
+ // mode - so we launch the vm-service from the main app AOT snapshot.
const uint8_t* isolate_snapshot_data = app_isolate_snapshot_data;
const uint8_t* isolate_snapshot_instructions =
app_isolate_snapshot_instructions;
@@ -693,11 +694,31 @@
AppSnapshot* app_snapshot = NULL;
#if defined(DART_PRECOMPILED_RUNTIME)
- // AOT: All isolates start from the app snapshot.
+ const uint8_t* isolate_snapshot_data = nullptr;
+ const uint8_t* isolate_snapshot_instructions = nullptr;
+ if (is_main_isolate) {
+ isolate_snapshot_data = app_isolate_snapshot_data;
+ isolate_snapshot_instructions = app_isolate_snapshot_instructions;
+ } else {
+ // AOT: All isolates need to be run from AOT compiled snapshots.
+ const bool kForceLoadElfFromMemory = false;
+ app_snapshot =
+ Snapshot::TryReadAppSnapshot(script_uri, kForceLoadElfFromMemory);
+ if (app_snapshot == nullptr) {
+ *error = Utils::StrDup(
+ "The uri provided to `Isolate.spawnUri()` does not "
+ "contain a valid AOT snapshot.");
+ return nullptr;
+ }
+
+ const uint8_t* ignore_vm_snapshot_data;
+ const uint8_t* ignore_vm_snapshot_instructions;
+ app_snapshot->SetBuffers(
+ &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
+ &isolate_snapshot_data, &isolate_snapshot_instructions);
+ }
+
bool isolate_run_app_snapshot = true;
- const uint8_t* isolate_snapshot_data = app_isolate_snapshot_data;
- const uint8_t* isolate_snapshot_instructions =
- app_isolate_snapshot_instructions;
flags->null_safety =
Dart_DetectNullSafety(nullptr, nullptr, nullptr, isolate_snapshot_data,
isolate_snapshot_instructions, nullptr, -1);
diff --git a/runtime/tests/vm/dart/spawn_uri_aot_test.dart b/runtime/tests/vm/dart/spawn_uri_aot_test.dart
new file mode 100644
index 0000000..ded95ce
--- /dev/null
+++ b/runtime/tests/vm/dart/spawn_uri_aot_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+ if (!isAOTRuntime) {
+ return; // Running in JIT: AOT binaries not available.
+ }
+
+ if (Platform.isAndroid) {
+ return; // SDK tree and gen_snapshot not available on the test device.
+ }
+
+ // These are the tools we need to be available to run on a given platform:
+ if (!await testExecutable(genSnapshot)) {
+ throw "Cannot run test as $genSnapshot not available";
+ }
+ if (!await testExecutable(aotRuntime)) {
+ throw "Cannot run test as $aotRuntime not available";
+ }
+ if (!File(platformDill).existsSync()) {
+ throw "Cannot run test as $platformDill does not exist";
+ }
+
+ await withTempDir('dwarf-flag-test', (String dir) async {
+ File(path.join(dir, 'main.dart')).writeAsStringSync('''
+ import 'dart:isolate';
+ main(List<String> args) async {
+ final rp = ReceivePort();
+ try {
+ await Isolate.spawnUri(Uri.parse(args.single), <String>[], rp.sendPort);
+ final result = await rp.first;
+ if (result != 'hello from spawnee') throw 'failed';
+ print('got spawnee message');
+ print('success');
+ } finally {
+ rp.close();
+ }
+ }
+ ''');
+ for (final basename in ['spawnee', 'spawnee_checked']) {
+ File(path.join(dir, '$basename.dart')).writeAsStringSync('''
+ import 'dart:isolate';
+ main(List<String> args, dynamic sendPort) {
+ print('spawnee started');
+ (sendPort as SendPort).send('hello from spawnee');
+ }
+ ''');
+ }
+
+ for (final basename in ['main', 'spawnee', 'spawnee_checked']) {
+ final script = path.join(dir, '$basename.dart');
+ final scriptDill = path.join(dir, '$basename.dart.dill');
+ final bool checked = basename.endsWith('_checked');
+
+ await run(genKernel, <String>[
+ if (checked) '--enable-asserts',
+ '--aot',
+ '--platform=$platformDill',
+ '-o',
+ scriptDill,
+ script,
+ ]);
+
+ final scriptAot = path.join(dir, '$basename.dart.dill.so');
+ await run(genSnapshot, <String>[
+ if (checked) '--enable-asserts',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptAot',
+ scriptDill,
+ ]);
+ }
+
+ // Successful run
+ final result1 = await runOutput(aotRuntime, <String>[
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'spawnee.dart.dill.so'),
+ ]);
+ Expect.deepEquals([
+ 'spawnee started',
+ 'got spawnee message',
+ 'success',
+ ], result1);
+
+ // File exists and is AOT snapshot but was compiled with different flags
+ // (namely --enable-asserts)
+ final result2 = await runHelper(aotRuntime, [
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'spawnee_checked.dart.dill.so'),
+ ]);
+ Expect.notEquals(0, result2.exitCode);
+ Expect.contains('Snapshot not compatible with the current VM configuration',
+ result2.stderr);
+
+ // File exists and is AOT snapshot but was compiled with different flags
+ // (namely --enable-asserts)
+ final result3 = await runHelper(aotRuntime, [
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'does_not_exist.dart.dill.so'),
+ ]);
+ Expect.notEquals(0, result3.exitCode);
+ Expect.contains(
+ 'The uri provided to `Isolate.spawnUri()` does not contain a valid AOT '
+ 'snapshot',
+ result3.stderr);
+ });
+}
diff --git a/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart b/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart
new file mode 100644
index 0000000..b3e3c21
--- /dev/null
+++ b/runtime/tests/vm/dart_2/spawn_uri_aot_test.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+ if (!isAOTRuntime) {
+ return; // Running in JIT: AOT binaries not available.
+ }
+
+ if (Platform.isAndroid) {
+ return; // SDK tree and gen_snapshot not available on the test device.
+ }
+
+ // These are the tools we need to be available to run on a given platform:
+ if (!await testExecutable(genSnapshot)) {
+ throw "Cannot run test as $genSnapshot not available";
+ }
+ if (!await testExecutable(aotRuntime)) {
+ throw "Cannot run test as $aotRuntime not available";
+ }
+ if (!File(platformDill).existsSync()) {
+ throw "Cannot run test as $platformDill does not exist";
+ }
+
+ await withTempDir('dwarf-flag-test', (String dir) async {
+ File(path.join(dir, 'main.dart')).writeAsStringSync('''
+ import 'dart:isolate';
+ main(List<String> args) async {
+ final rp = ReceivePort();
+ try {
+ await Isolate.spawnUri(Uri.parse(args.single), <String>[], rp.sendPort);
+ final result = await rp.first;
+ if (result != 'hello from spawnee') throw 'failed';
+ print('got spawnee message');
+ print('success');
+ } finally {
+ rp.close();
+ }
+ }
+ ''');
+ for (final basename in ['spawnee', 'spawnee_checked']) {
+ File(path.join(dir, '$basename.dart')).writeAsStringSync('''
+ import 'dart:isolate';
+ main(List<String> args, dynamic sendPort) {
+ print('spawnee started');
+ (sendPort as SendPort).send('hello from spawnee');
+ }
+ ''');
+ }
+
+ for (final basename in ['main', 'spawnee', 'spawnee_checked']) {
+ final script = path.join(dir, '$basename.dart');
+ final scriptDill = path.join(dir, '$basename.dart.dill');
+ final bool checked = basename.endsWith('_checked');
+
+ await run(genKernel, <String>[
+ if (checked) '--enable-asserts',
+ '--aot',
+ '--platform=$platformDill',
+ '-o',
+ scriptDill,
+ script,
+ ]);
+
+ final scriptAot = path.join(dir, '$basename.dart.dill.so');
+ await run(genSnapshot, <String>[
+ if (checked) '--enable-asserts',
+ '--snapshot-kind=app-aot-elf',
+ '--elf=$scriptAot',
+ scriptDill,
+ ]);
+ }
+
+ // Successful run
+ final result1 = await runOutput(aotRuntime, <String>[
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'spawnee.dart.dill.so'),
+ ]);
+ Expect.deepEquals([
+ 'spawnee started',
+ 'got spawnee message',
+ 'success',
+ ], result1);
+
+ // File exists and is AOT snapshot but was compiled with different flags
+ // (namely --enable-asserts)
+ final result2 = await runHelper(aotRuntime, [
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'spawnee_checked.dart.dill.so'),
+ ]);
+ Expect.notEquals(0, result2.exitCode);
+ Expect.contains('Snapshot not compatible with the current VM configuration',
+ result2.stderr);
+
+ // File exists and is AOT snapshot but was compiled with different flags
+ // (namely --enable-asserts)
+ final result3 = await runHelper(aotRuntime, [
+ path.join(dir, 'main.dart.dill.so'),
+ path.join(dir, 'does_not_exist.dart.dill.so'),
+ ]);
+ Expect.notEquals(0, result3.exitCode);
+ Expect.contains(
+ 'The uri provided to `Isolate.spawnUri()` does not contain a valid AOT '
+ 'snapshot',
+ result3.stderr);
+ });
+}
diff --git a/samples-dev/OWNERS b/samples-dev/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/samples-dev/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/samples/OWNERS b/samples/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/samples/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/samples_2/OWNERS b/samples_2/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/samples_2/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/sdk/OWNERS b/sdk/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/sdk/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/sdk/lib/_internal/js_dev_runtime/OWNERS b/sdk/lib/_internal/js_dev_runtime/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/sdk/lib/_internal/js_dev_runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/sdk/lib/_internal/js_runtime/OWNERS b/sdk/lib/_internal/js_runtime/OWNERS
new file mode 100644
index 0000000..f5bd90c
--- /dev/null
+++ b/sdk/lib/_internal/js_runtime/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_WEB
diff --git a/sdk/lib/_internal/vm/OWNERS b/sdk/lib/_internal/vm/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/sdk/lib/_internal/vm/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/tests/OWNERS b/tests/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/tests/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG
diff --git a/tests/lib/isolate/weak_reference_message_2_test.dart b/tests/lib/isolate/weak_reference_message_2_test.dart
index f925185..cc70985 100644
--- a/tests/lib/isolate/weak_reference_message_2_test.dart
+++ b/tests/lib/isolate/weak_reference_message_2_test.dart
@@ -2,10 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:typed_data';
+import 'dart:io';
import "dart:isolate";
+import 'dart:typed_data';
-import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
void main(List<String> arguments, Object? message) async {
@@ -19,8 +19,11 @@
Future<void> runTest() async {
final port = ReceivePort();
+ // By spawning the isolate from an uri the newly isolate will run in it's own
+ // isolate group. This way we can test the message snapshot serialization
+ // code.
await Isolate.spawnUri(
- Uri.parse('weak_reference_message_2_test.dart'),
+ Platform.script,
['helper'],
port.sendPort,
);
diff --git a/tests/lib_2/isolate/weak_reference_message_2_test.dart b/tests/lib_2/isolate/weak_reference_message_2_test.dart
index bd9cb92..1c18735 100644
--- a/tests/lib_2/isolate/weak_reference_message_2_test.dart
+++ b/tests/lib_2/isolate/weak_reference_message_2_test.dart
@@ -4,10 +4,10 @@
// @dart = 2.9
-import 'dart:typed_data';
+import 'dart:io';
import "dart:isolate";
+import 'dart:typed_data';
-import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
void main(List<String> arguments, Object message) async {
@@ -21,8 +21,11 @@
Future<void> runTest() async {
final port = ReceivePort();
+ // By spawning the isolate from an uri the newly isolate will run in it's own
+ // isolate group. This way we can test the message snapshot serialization
+ // code.
await Isolate.spawnUri(
- Uri.parse('weak_reference_message_2_test.dart'),
+ Platform.script,
['helper'],
port.sendPort,
);
diff --git a/third_party/OWNERS b/third_party/OWNERS
new file mode 100644
index 0000000..c3abcf9
--- /dev/null
+++ b/third_party/OWNERS
@@ -0,0 +1,2 @@
+file:/tools/OWNERS_FOUNDATION #{LAST_RESORT_SUGGESTION}
+file:/tools/OWNERS_INFRA #{LAST_RESORT_SUGGESTION}
diff --git a/third_party/tcmalloc/OWNERS b/third_party/tcmalloc/OWNERS
new file mode 100644
index 0000000..dc3a1d0
--- /dev/null
+++ b/third_party/tcmalloc/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_VM
diff --git a/tools/OWNERS b/tools/OWNERS
new file mode 100644
index 0000000..e2eae44
--- /dev/null
+++ b/tools/OWNERS
@@ -0,0 +1,10 @@
+file:/OWNERS_INFRA
+
+# Groups administrate themselves.
+per-file OWNERS_ANALYZER=file:OWNERS_ANALYZER
+per-file OWNERS_CFE=file:OWNERS_CFE
+per-file OWNERS_FOUNDATION=file:OWNERS_FOUNDATION
+per-file OWNERS_INFRA=file:OWNERS_INFRA
+per-file OWNERS_PRODUCT=file:OWNERS_PRODUCT
+per-file OWNERS_VM=file:OWNERS_VM
+per-file OWNERS_WEB=file:OWNERS_WEB
diff --git a/tools/OWNERS_ANALYZER b/tools/OWNERS_ANALYZER
new file mode 100644
index 0000000..dfcbd53
--- /dev/null
+++ b/tools/OWNERS_ANALYZER
@@ -0,0 +1,6 @@
+brianwilkerson@google.com
+jcollins@google.com
+leafp@google.com
+paulberry@google.com
+scheglov@google.com
+srawlins@google.com
diff --git a/tools/OWNERS_CFE b/tools/OWNERS_CFE
new file mode 100644
index 0000000..ceb75971
--- /dev/null
+++ b/tools/OWNERS_CFE
@@ -0,0 +1,4 @@
+cstefantsova@google.com
+jensj@google.com
+johnniwinther@google.com
+vegorov@google.com
diff --git a/tools/OWNERS_ENG b/tools/OWNERS_ENG
new file mode 100644
index 0000000..6857872
--- /dev/null
+++ b/tools/OWNERS_ENG
@@ -0,0 +1,7 @@
+# All engineering teams
+file:OWNERS_ANALYZER
+file:OWNERS_CFE
+file:OWNERS_FOUNDATION
+file:OWNERS_INFRA
+file:OWNERS_VM
+file:OWNERS_WEB
diff --git a/tools/OWNERS_FOUNDATION b/tools/OWNERS_FOUNDATION
new file mode 100644
index 0000000..b23483a
--- /dev/null
+++ b/tools/OWNERS_FOUNDATION
@@ -0,0 +1,7 @@
+eernst@google.com
+jakemac@google.com
+leafp@google.com
+lrn@google.com
+nbosch@google.com
+paulberry@google.com
+rnystrom@google.com
diff --git a/tools/OWNERS_INFRA b/tools/OWNERS_INFRA
new file mode 100644
index 0000000..838001e
--- /dev/null
+++ b/tools/OWNERS_INFRA
@@ -0,0 +1,3 @@
+athom@google.com
+sortie@google.com
+whesse@google.com
diff --git a/tools/OWNERS_PRODUCT b/tools/OWNERS_PRODUCT
new file mode 100644
index 0000000..c2c62b9
--- /dev/null
+++ b/tools/OWNERS_PRODUCT
@@ -0,0 +1,2 @@
+kevmoo@google.com
+mit@google.com
diff --git a/tools/OWNERS_VM b/tools/OWNERS_VM
new file mode 100644
index 0000000..018eb47
--- /dev/null
+++ b/tools/OWNERS_VM
@@ -0,0 +1,13 @@
+aam@google.com
+alexmarkov@google.com
+asiva@google.com
+askesc@google.com
+bkonyi@google.com
+bquinlan@google.com
+cskau@google.com
+dacoharkes@google.com
+kustermann@google.com
+liama@google.com
+rmacnak@google.com
+sstrickl@google.com
+vegorov@google.com
diff --git a/tools/OWNERS_WEB b/tools/OWNERS_WEB
new file mode 100644
index 0000000..df81259
--- /dev/null
+++ b/tools/OWNERS_WEB
@@ -0,0 +1,15 @@
+annagrin@google.com
+elliottbrooks@google.com
+fishythefish@google.com
+grouma@google.com
+jacobr@google.com
+joshualitt@google.com
+kevmoo@google.com
+leonsenft@google.com
+markzipan@google.com
+nshahan@google.com
+rileyporter@google.com
+sigmund@google.com
+sra@google.com
+srujzs@google.com
+vsm@google.com
diff --git a/tools/VERSION b/tools/VERSION
index 4400c24..f17707f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 106
+PRERELEASE 107
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/utils/OWNERS b/utils/OWNERS
new file mode 100644
index 0000000..2b67506
--- /dev/null
+++ b/utils/OWNERS
@@ -0,0 +1 @@
+file:/tools/OWNERS_ENG