OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 | |
6 /// Helper program for killing and resetting all Safari settings to a known | 5 /// Helper program for killing and resetting all Safari settings to a known |
7 /// state that works well for testing dart2js output in Safari. | 6 /// state that works well for testing dart2js output in Safari. |
8 /// | 7 /// |
9 /// Warning: this will delete all your Safari settings and bookmarks. | 8 /// Warning: this will delete all your Safari settings and bookmarks. |
10 library testing.reset_safari; | 9 library testing.reset_safari; |
11 | 10 |
12 import 'dart:async' show | 11 import 'dart:async' show Future, Timer; |
13 Future, | |
14 Timer; | |
15 | 12 |
16 import 'dart:io' show | 13 import 'dart:io' show Directory, File, Platform, Process, ProcessResult; |
17 Directory, | |
18 File, | |
19 Platform, | |
20 Process, | |
21 ProcessResult; | |
22 | 14 |
23 const String defaultSafariBundleLocation = "/Applications/Safari.app/"; | 15 const String defaultSafariBundleLocation = "/Applications/Safari.app/"; |
24 | 16 |
25 const String relativeSafariLocation = "Contents/MacOS/Safari"; | 17 const String relativeSafariLocation = "Contents/MacOS/Safari"; |
26 | 18 |
27 const String lsofLocation = "/usr/sbin/lsof"; | 19 const String lsofLocation = "/usr/sbin/lsof"; |
28 | 20 |
29 const String killLocation = "/bin/kill"; | 21 const String killLocation = "/bin/kill"; |
30 | 22 |
31 const String pkillLocation = "/usr/bin/pkill"; | 23 const String pkillLocation = "/usr/bin/pkill"; |
32 | 24 |
33 const String safari = "com.apple.Safari"; | 25 const String safari = "com.apple.Safari"; |
34 | 26 |
35 const String defaultsLocation = "/usr/bin/defaults"; | 27 const String defaultsLocation = "/usr/bin/defaults"; |
36 | 28 |
37 final List<String> safariSettings = <String>[ | 29 final List<String> safariSettings = <String>[ |
38 "Library/Caches/$safari", | 30 "Library/Caches/$safari", |
39 "Library/Safari", | 31 "Library/Safari", |
40 "Library/Saved Application State/$safari.savedState", | 32 "Library/Saved Application State/$safari.savedState", |
41 "Library/Caches/Metadata/Safari", | 33 "Library/Caches/Metadata/Safari", |
42 "Library/Preferences/$safari.plist", | 34 "Library/Preferences/$safari.plist", |
43 ]; | 35 ]; |
44 | 36 |
45 const Duration defaultPollDelay = const Duration(milliseconds: 1); | 37 const Duration defaultPollDelay = const Duration(milliseconds: 1); |
46 | 38 |
47 final String cpgi = "$safari.ContentPageGroupIdentifier"; | 39 final String cpgi = "$safari.ContentPageGroupIdentifier"; |
48 | 40 |
49 final String knownSafariPreference = ''' | 41 final String knownSafariPreference = ''' |
50 { | 42 { |
51 DefaultBrowserPromptingState2 = 2; | 43 DefaultBrowserPromptingState2 = 2; |
52 StartPageViewControllerMode = 0; | 44 StartPageViewControllerMode = 0; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 InstallExtensionUpdatesAutomatically = 0; | 92 InstallExtensionUpdatesAutomatically = 0; |
101 | 93 |
102 ShowFullURLInSmartSearchField = 1; | 94 ShowFullURLInSmartSearchField = 1; |
103 | 95 |
104 "$cpgi.WebKit2PlugInSnapshottingEnabled" = 0; | 96 "$cpgi.WebKit2PlugInSnapshottingEnabled" = 0; |
105 } | 97 } |
106 '''; | 98 '''; |
107 | 99 |
108 Future<Null> get pollDelay => new Future.delayed(defaultPollDelay); | 100 Future<Null> get pollDelay => new Future.delayed(defaultPollDelay); |
109 | 101 |
110 String signalArgument( | 102 String signalArgument(String defaultSignal, |
111 String defaultSignal, | 103 {bool force: false, bool testOnly: false}) { |
112 {bool force: false, | |
113 bool testOnly: false}) { | |
114 if (force && testOnly) { | 104 if (force && testOnly) { |
115 throw new ArgumentError("[force] and [testOnly] can't both be true."); | 105 throw new ArgumentError("[force] and [testOnly] can't both be true."); |
116 } | 106 } |
117 if (force) return "-KILL"; | 107 if (force) return "-KILL"; |
118 if (testOnly) return "-0"; | 108 if (testOnly) return "-0"; |
119 return defaultSignal; | 109 return defaultSignal; |
120 } | 110 } |
121 | 111 |
122 Future<int> kill( | 112 Future<int> kill(List<String> pids, |
123 List<String> pids, | 113 {bool force: false, bool testOnly: false}) async { |
124 {bool force: false, | 114 List<String> arguments = <String>[ |
125 bool testOnly: false}) async { | 115 signalArgument("-TERM", force: force, testOnly: testOnly) |
126 List<String> arguments = | 116 ]..addAll(pids); |
127 <String>[signalArgument("-TERM", force: force, testOnly: testOnly)] | |
128 ..addAll(pids); | |
129 ProcessResult result = await Process.run(killLocation, arguments); | 117 ProcessResult result = await Process.run(killLocation, arguments); |
130 return result.exitCode; | 118 return result.exitCode; |
131 } | 119 } |
132 | 120 |
133 Future<int> pkill( | 121 Future<int> pkill(String pattern, |
134 String pattern, | 122 {bool force: false, bool testOnly: false}) async { |
135 {bool force: false, | |
136 bool testOnly: false}) async { | |
137 List<String> arguments = <String>[ | 123 List<String> arguments = <String>[ |
138 signalArgument("-HUP", force: force, testOnly: testOnly), | 124 signalArgument("-HUP", force: force, testOnly: testOnly), |
139 pattern]; | 125 pattern |
| 126 ]; |
140 ProcessResult result = await Process.run(pkillLocation, arguments); | 127 ProcessResult result = await Process.run(pkillLocation, arguments); |
141 return result.exitCode; | 128 return result.exitCode; |
142 } | 129 } |
143 | 130 |
144 Uri validatedBundleName(Uri bundle) { | 131 Uri validatedBundleName(Uri bundle) { |
145 if (bundle == null) return Uri.base.resolve(defaultSafariBundleLocation); | 132 if (bundle == null) return Uri.base.resolve(defaultSafariBundleLocation); |
146 if (!bundle.path.endsWith("/")) { | 133 if (!bundle.path.endsWith("/")) { |
147 throw new ArgumentError( | 134 throw new ArgumentError("Bundle ('$bundle') must end with a slash ('/')."); |
148 "Bundle ('$bundle') must end with a slash ('/')."); | |
149 } | 135 } |
150 return bundle; | 136 return bundle; |
151 } | 137 } |
152 | 138 |
153 Future<Null> killSafari({Uri bundle}) async { | 139 Future<Null> killSafari({Uri bundle}) async { |
154 bundle = validatedBundleName(bundle); | 140 bundle = validatedBundleName(bundle); |
155 Uri safariBinary = bundle.resolve(relativeSafariLocation); | 141 Uri safariBinary = bundle.resolve(relativeSafariLocation); |
156 ProcessResult result = await Process.run( | 142 ProcessResult result = |
157 lsofLocation, ["-t", safariBinary.toFilePath()]); | 143 await Process.run(lsofLocation, ["-t", safariBinary.toFilePath()]); |
158 if (result.exitCode == 0) { | 144 if (result.exitCode == 0) { |
159 String stdout = result.stdout; | 145 String stdout = result.stdout; |
160 List<String> pids = new List<String>.from( | 146 List<String> pids = new List<String>.from( |
161 stdout.split("\n").where((String line) => !line.isEmpty)); | 147 stdout.split("\n").where((String line) => !line.isEmpty)); |
162 Timer timer = new Timer(const Duration(seconds: 10), () { | 148 Timer timer = new Timer(const Duration(seconds: 10), () { |
163 print("Kill -9 Safari $pids"); | 149 print("Kill -9 Safari $pids"); |
164 kill(pids, force: true); | 150 kill(pids, force: true); |
165 }); | 151 }); |
166 int exitCode = await kill(pids); | 152 int exitCode = await kill(pids); |
167 while (exitCode == 0) { | 153 while (exitCode == 0) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 | 188 |
203 Future<Null> resetSafariSettings() async { | 189 Future<Null> resetSafariSettings() async { |
204 String home = Platform.environment["HOME"]; | 190 String home = Platform.environment["HOME"]; |
205 if (!home.endsWith("/")) { | 191 if (!home.endsWith("/")) { |
206 home = "$home/"; | 192 home = "$home/"; |
207 } | 193 } |
208 Uri homeDirectory = Uri.base.resolve(home); | 194 Uri homeDirectory = Uri.base.resolve(home); |
209 for (String setting in safariSettings) { | 195 for (String setting in safariSettings) { |
210 await deleteIfExists(homeDirectory.resolve(setting)); | 196 await deleteIfExists(homeDirectory.resolve(setting)); |
211 } | 197 } |
212 ProcessResult result = await Process.run( | 198 ProcessResult result = await Process |
213 defaultsLocation, <String>["write", safari, knownSafariPreference]); | 199 .run(defaultsLocation, <String>["write", safari, knownSafariPreference]); |
214 if (result.exitCode != 0) { | 200 if (result.exitCode != 0) { |
215 throw "Unable to reset Safari settings: ${result.stdout}${result.stderr}"; | 201 throw "Unable to reset Safari settings: ${result.stdout}${result.stderr}"; |
216 } | 202 } |
217 } | 203 } |
218 | 204 |
219 Future<Null> killAndResetSafari({Uri bundle}) async { | 205 Future<Null> killAndResetSafari({Uri bundle}) async { |
220 bundle = validatedBundleName(bundle); | 206 bundle = validatedBundleName(bundle); |
221 await killSafari(bundle: bundle); | 207 await killSafari(bundle: bundle); |
222 await resetSafariSettings(); | 208 await resetSafariSettings(); |
223 } | 209 } |
224 | 210 |
225 Future<Null> main() async { | 211 Future<Null> main() async { |
226 await killAndResetSafari(); | 212 await killAndResetSafari(); |
227 } | 213 } |
OLD | NEW |