diff --git a/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart b/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart index 56312cf5d27..bcb78aedcdd 100644 --- a/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart +++ b/packages/devtools_app/lib/src/extensions/embedded/_controller_web.dart @@ -11,6 +11,7 @@ import 'package:devtools_app_shared/utils.dart'; import 'package:devtools_extensions/api.dart'; import 'package:path/path.dart' as path; +import '../../shared/development_helpers.dart'; import '../../shared/globals.dart'; import '../../shared/primitives/utils.dart'; import 'controller.dart'; @@ -37,6 +38,10 @@ class EmbeddedExtensionControllerImpl extends EmbeddedExtensionController late final viewId = 'ext-${extensionConfig.name}-${_viewIdIncrementer++}'; String get extensionUrl { + if (debugDevToolsExtensions) { + return 'https://flutter.dev/'; + } + final baseUri = path.join( html.window.location.origin, 'devtools_extensions', diff --git a/packages/devtools_app/lib/src/shared/config_specific/server/_server_stub.dart b/packages/devtools_app/lib/src/shared/config_specific/server/_server_stub.dart index 31fcf2fa077..6361bb8574b 100644 --- a/packages/devtools_app/lib/src/shared/config_specific/server/_server_stub.dart +++ b/packages/devtools_app/lib/src/shared/config_specific/server/_server_stub.dart @@ -7,8 +7,8 @@ import 'dart:async'; import 'package:devtools_shared/devtools_extensions.dart'; -import 'package:flutter/foundation.dart'; +import '../../development_helpers.dart'; import '../../primitives/utils.dart'; const unsupportedMessage = @@ -81,7 +81,7 @@ Future requestTestAppSizeFile(String path) async { Future> refreshAvailableExtensions( String rootPath, ) async { - return kDebugMode ? _debugExtensions : []; + return debugHandleRefreshAvailableExtensions(rootPath); } Future extensionEnabledState({ @@ -89,13 +89,10 @@ Future extensionEnabledState({ required String extensionName, bool? enable, }) async { - if (enable != null) { - _stubEnabledStates[extensionName] = - enable ? ExtensionEnabledState.enabled : ExtensionEnabledState.disabled; - } - return _stubEnabledStates.putIfAbsent( - extensionName, - () => ExtensionEnabledState.none, + return debugHandleExtensionEnabledState( + rootPath: rootPath, + extensionName: extensionName, + enable: enable, ); } @@ -105,33 +102,3 @@ Future> requestAndroidBuildVariants(String path) async => void logWarning() { throw Exception(unsupportedMessage); } - -/// Stubbed activation states so we can develop DevTools extensions without a -/// server connection on Desktop. -final _stubEnabledStates = {}; - -/// Stubbed extensions so we can develop DevTools Extensions without a server -/// connection on Desktop. -final List _debugExtensions = [ - DevToolsExtensionConfig.parse({ - DevToolsExtensionConfig.nameKey: 'foo', - DevToolsExtensionConfig.issueTrackerKey: 'www.google.com', - DevToolsExtensionConfig.versionKey: '1.0.0', - DevToolsExtensionConfig.pathKey: '/path/to/foo', - }), - DevToolsExtensionConfig.parse({ - DevToolsExtensionConfig.nameKey: 'bar', - DevToolsExtensionConfig.issueTrackerKey: 'www.google.com', - DevToolsExtensionConfig.versionKey: '2.0.0', - DevToolsExtensionConfig.materialIconCodePointKey: 0xe638, - DevToolsExtensionConfig.pathKey: '/path/to/bar', - }), - DevToolsExtensionConfig.parse({ - DevToolsExtensionConfig.nameKey: 'provider', - DevToolsExtensionConfig.issueTrackerKey: - 'https://github.com/rrousselGit/provider/issues', - DevToolsExtensionConfig.versionKey: '3.0.0', - DevToolsExtensionConfig.materialIconCodePointKey: 0xe50a, - DevToolsExtensionConfig.pathKey: '/path/to/provider', - }), -]; diff --git a/packages/devtools_app/lib/src/shared/config_specific/server/_server_web.dart b/packages/devtools_app/lib/src/shared/config_specific/server/_server_web.dart index fa862a36ca7..7fa7d03e4bc 100644 --- a/packages/devtools_app/lib/src/shared/config_specific/server/_server_web.dart +++ b/packages/devtools_app/lib/src/shared/config_specific/server/_server_web.dart @@ -13,6 +13,7 @@ import 'package:devtools_shared/devtools_extensions.dart'; import 'package:devtools_shared/devtools_shared.dart'; import 'package:logging/logging.dart'; +import '../../development_helpers.dart'; import '../../primitives/utils.dart'; final _log = Logger('_server_web'); @@ -365,6 +366,8 @@ Future> refreshAvailableExtensions( logWarning(resp, ExtensionsApi.apiServeAvailableExtensions); return []; } + } else if (debugDevToolsExtensions) { + return debugHandleRefreshAvailableExtensions(rootPath); } return []; } @@ -398,6 +401,12 @@ Future extensionEnabledState({ } else { logWarning(resp, ExtensionsApi.apiExtensionEnabledState); } + } else if (debugDevToolsExtensions) { + return debugHandleExtensionEnabledState( + rootPath: rootPath, + extensionName: extensionName, + enable: enable, + ); } return ExtensionEnabledState.error; } diff --git a/packages/devtools_app/lib/src/shared/development_helpers.dart b/packages/devtools_app/lib/src/shared/development_helpers.dart new file mode 100644 index 00000000000..d33547bbea9 --- /dev/null +++ b/packages/devtools_app/lib/src/shared/development_helpers.dart @@ -0,0 +1,65 @@ +// Copyright 2023 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_shared/devtools_extensions.dart'; + +/// Whether to build DevTools for conveniently debugging DevTools extensions. +/// +/// Turning this flag to [true] allows for debugging the extensions framework +/// without a server connection. +/// +/// This flag should never be checked in with a value of true - this is covered +/// by a test. +const debugDevToolsExtensions = false; + +List debugHandleRefreshAvailableExtensions( + String rootPath, +) { + return debugExtensions; +} + +ExtensionEnabledState debugHandleExtensionEnabledState({ + required String rootPath, + required String extensionName, + bool? enable, +}) { + if (enable != null) { + stubExtensionEnabledStates[extensionName] = + enable ? ExtensionEnabledState.enabled : ExtensionEnabledState.disabled; + } + return stubExtensionEnabledStates.putIfAbsent( + extensionName, + () => ExtensionEnabledState.none, + ); +} + +/// Stubbed activation states so we can develop DevTools extensions without a +/// server connection. +final stubExtensionEnabledStates = {}; + +/// Stubbed extensions so we can develop DevTools Extensions without a server +/// connection. +final List debugExtensions = [ + DevToolsExtensionConfig.parse({ + DevToolsExtensionConfig.nameKey: 'foo', + DevToolsExtensionConfig.issueTrackerKey: 'www.google.com', + DevToolsExtensionConfig.versionKey: '1.0.0', + DevToolsExtensionConfig.pathKey: '/path/to/foo', + }), + DevToolsExtensionConfig.parse({ + DevToolsExtensionConfig.nameKey: 'bar', + DevToolsExtensionConfig.issueTrackerKey: 'www.google.com', + DevToolsExtensionConfig.versionKey: '2.0.0', + DevToolsExtensionConfig.materialIconCodePointKey: 0xe638, + DevToolsExtensionConfig.pathKey: '/path/to/bar', + }), + DevToolsExtensionConfig.parse({ + DevToolsExtensionConfig.nameKey: 'provider', + DevToolsExtensionConfig.issueTrackerKey: + 'https://github.com/rrousselGit/provider/issues', + DevToolsExtensionConfig.versionKey: '3.0.0', + DevToolsExtensionConfig.materialIconCodePointKey: 0xe50a, + DevToolsExtensionConfig.pathKey: '/path/to/provider', + }), +]; diff --git a/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj b/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj index 8c0425600c6..3f8a110d5c9 100644 --- a/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj @@ -27,7 +27,6 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 893BA9428DE5E316869DE5C4 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6C766AD6438D06406C3E001 /* Pods_RunnerTests.framework */; }; E678665441E5C0F7F629BAD5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5062035DDDD18FB35E98D5B6 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ @@ -80,14 +79,10 @@ 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 5062035DDDD18FB35E98D5B6 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 608AA24C7CDF709B7E4143CD /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 672942658D54F1279CDE731D /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 68C587FFA5A0B8F46A0C5150 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; A7CE48BF63861DD9F3A9FA2F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - D67789D76F0E16A04F21F412 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - D6C766AD6438D06406C3E001 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -95,7 +90,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 893BA9428DE5E316869DE5C4 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -191,9 +185,6 @@ 11BB555C0F1767B9B5CB7CE0 /* Pods-Runner.debug.xcconfig */, 68C587FFA5A0B8F46A0C5150 /* Pods-Runner.release.xcconfig */, A7CE48BF63861DD9F3A9FA2F /* Pods-Runner.profile.xcconfig */, - D67789D76F0E16A04F21F412 /* Pods-RunnerTests.debug.xcconfig */, - 608AA24C7CDF709B7E4143CD /* Pods-RunnerTests.release.xcconfig */, - 672942658D54F1279CDE731D /* Pods-RunnerTests.profile.xcconfig */, ); name = Pods; path = Pods; @@ -203,7 +194,6 @@ isa = PBXGroup; children = ( 5062035DDDD18FB35E98D5B6 /* Pods_Runner.framework */, - D6C766AD6438D06406C3E001 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -215,7 +205,6 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - 7B9F0C2F41EF56D3E527D3DD /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -360,28 +349,6 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; - 7B9F0C2F41EF56D3E527D3DD /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; DC1C8B6797A659BE5B59B986 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -472,7 +439,6 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D67789D76F0E16A04F21F412 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -487,7 +453,6 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 608AA24C7CDF709B7E4143CD /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -502,7 +467,6 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 672942658D54F1279CDE731D /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; diff --git a/packages/devtools_app/test/shared/development_helpers_test.dart b/packages/devtools_app/test/shared/development_helpers_test.dart new file mode 100644 index 00000000000..ea0089c6382 --- /dev/null +++ b/packages/devtools_app/test/shared/development_helpers_test.dart @@ -0,0 +1,12 @@ +// Copyright 2023 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app/src/shared/development_helpers.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('debug flags are false', () { + expect(debugDevToolsExtensions, isFalse); + }); +}