Commit 05f496ab authored by Devon Carew's avatar Devon Carew

Merge pull request #2105 from devoncarew/validate_atom

add a validator for Atom
parents 3f8fdb66 9367b86a
...@@ -7,7 +7,7 @@ import '../globals.dart'; ...@@ -7,7 +7,7 @@ import '../globals.dart';
import 'android_sdk.dart'; import 'android_sdk.dart';
class AndroidWorkflow extends Workflow { class AndroidWorkflow extends Workflow {
AndroidWorkflow() : super('Android'); String get label => 'Android toolchain';
bool get appliesToHostPlatform => true; bool get appliesToHostPlatform => true;
...@@ -17,11 +17,11 @@ class AndroidWorkflow extends Workflow { ...@@ -17,11 +17,11 @@ class AndroidWorkflow extends Workflow {
ValidationResult validate() { ValidationResult validate() {
Validator androidValidator = new Validator( Validator androidValidator = new Validator(
'$name toolchain', label,
description: 'develop for Android devices' description: 'develop for Android devices'
); );
Function _sdkExists = () { ValidationType sdkExists() {
return androidSdk == null ? ValidationType.missing : ValidationType.installed; return androidSdk == null ? ValidationType.missing : ValidationType.installed;
}; };
...@@ -29,7 +29,7 @@ class AndroidWorkflow extends Workflow { ...@@ -29,7 +29,7 @@ class AndroidWorkflow extends Workflow {
'Android SDK', 'Android SDK',
description: 'enable development for Android devices', description: 'enable development for Android devices',
resolution: 'Download at https://developer.android.com/sdk/', resolution: 'Download at https://developer.android.com/sdk/',
validatorFunction: _sdkExists validatorFunction: sdkExists
)); ));
return androidValidator.validate(); return androidValidator.validate();
......
...@@ -146,8 +146,7 @@ class ApplicationPackageStore { ...@@ -146,8 +146,7 @@ class ApplicationPackageStore {
case TargetPlatform.iOS: case TargetPlatform.iOS:
case TargetPlatform.iOSSimulator: case TargetPlatform.iOSSimulator:
if (iOS == null) iOS ??= new IOSApp.fromBuildConfiguration(config);
iOS = new IOSApp.fromBuildConfiguration(config);
break; break;
case TargetPlatform.mac: case TargetPlatform.mac:
......
...@@ -2,20 +2,27 @@ ...@@ -2,20 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:io';
import 'android/android_workflow.dart'; import 'android/android_workflow.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/process.dart';
import 'globals.dart'; import 'globals.dart';
import 'ios/ios_workflow.dart'; import 'ios/ios_workflow.dart';
// TODO(devoncarew): Make it easy to add version information to the `doctor` printout.
class Doctor { class Doctor {
Doctor() { Doctor() {
_iosWorkflow = new IOSWorkflow(); _iosWorkflow = new IOSWorkflow();
if (_iosWorkflow.appliesToHostPlatform) if (_iosWorkflow.appliesToHostPlatform)
_workflows.add(_iosWorkflow); _validators.add(_iosWorkflow);
_androidWorkflow = new AndroidWorkflow(); _androidWorkflow = new AndroidWorkflow();
if (_androidWorkflow.appliesToHostPlatform) if (_androidWorkflow.appliesToHostPlatform)
_workflows.add(_androidWorkflow); _validators.add(_androidWorkflow);
_validators.add(new _AtomValidator());
} }
static void initGlobal() { static void initGlobal() {
...@@ -30,9 +37,9 @@ class Doctor { ...@@ -30,9 +37,9 @@ class Doctor {
AndroidWorkflow get androidWorkflow => _androidWorkflow; AndroidWorkflow get androidWorkflow => _androidWorkflow;
List<Workflow> _workflows = <Workflow>[]; List<DoctorValidator> _validators = <DoctorValidator>[];
List<Workflow> get workflows => _workflows; Iterable<Workflow> get workflows => _validators.where((DoctorValidator validator) => validator is Workflow);
/// Print a summary of the state of the tooling, as well as how to get more info. /// Print a summary of the state of the tooling, as well as how to get more info.
void summary() => printStatus(summaryText); void summary() => printStatus(summaryText);
...@@ -42,9 +49,9 @@ class Doctor { ...@@ -42,9 +49,9 @@ class Doctor {
bool allGood = true; bool allGood = true;
for (Workflow workflow in workflows) { for (DoctorValidator validator in _validators) {
ValidationResult result = workflow.validate(); ValidationResult result = validator.validate();
buffer.write('${result.leadingBox} The ${workflow.name} toolchain is '); buffer.write('${result.leadingBox} The ${validator.label} is ');
if (result.type == ValidationType.missing) if (result.type == ValidationType.missing)
buffer.writeln('not installed.'); buffer.writeln('not installed.');
else if (result.type == ValidationType.partial) else if (result.type == ValidationType.partial)
...@@ -65,10 +72,12 @@ class Doctor { ...@@ -65,10 +72,12 @@ class Doctor {
/// Print verbose information about the state of installed tooling. /// Print verbose information about the state of installed tooling.
void diagnose() { void diagnose() {
for (int i = 0; i < workflows.length; i++) { bool firstLine = true;
if (i > 0) for (DoctorValidator validator in _validators) {
if (!firstLine)
printStatus(''); printStatus('');
workflows[i].diagnose(); firstLine = false;
validator.diagnose();
} }
} }
...@@ -77,12 +86,17 @@ class Doctor { ...@@ -77,12 +86,17 @@ class Doctor {
bool get canLaunchAnything => workflows.any((Workflow workflow) => workflow.canLaunchDevices); bool get canLaunchAnything => workflows.any((Workflow workflow) => workflow.canLaunchDevices);
} }
/// A series of tools and required install steps for a target platform (iOS or Android). abstract class DoctorValidator {
abstract class Workflow { String get label;
Workflow(this.name);
final String name; ValidationResult validate();
/// Print verbose information about the state of the workflow.
void diagnose();
}
/// A series of tools and required install steps for a target platform (iOS or Android).
abstract class Workflow extends DoctorValidator {
/// Whether the workflow applies to this platform (as in, should we ever try and use it). /// Whether the workflow applies to this platform (as in, should we ever try and use it).
bool get appliesToHostPlatform; bool get appliesToHostPlatform;
...@@ -91,13 +105,6 @@ abstract class Workflow { ...@@ -91,13 +105,6 @@ abstract class Workflow {
/// Could this thing launch *something*? It may still have minor issues. /// Could this thing launch *something*? It may still have minor issues.
bool get canLaunchDevices; bool get canLaunchDevices;
ValidationResult validate();
/// Print verbose information about the state of the workflow.
void diagnose();
String toString() => name;
} }
enum ValidationType { enum ValidationType {
...@@ -206,3 +213,50 @@ class ValidationResult { ...@@ -206,3 +213,50 @@ class ValidationResult {
return results; return results;
} }
} }
class _AtomValidator extends DoctorValidator {
String get label => 'Atom development environment';
ValidationResult validate() {
Validator atomValidator = new Validator(
label,
description: 'a lightweight development environment for Flutter'
);
ValidationType atomExists() {
return exitsHappy(<String>['atom', '--version']) ? ValidationType.installed : ValidationType.missing;
};
ValidationType flutterPluginExists() {
try {
// apm list -b -p -i
ProcessResult result = Process.runSync('apm', <String>['list', '-b', '-p', '-i']);
if (result.exitCode != 0)
return ValidationType.missing;
bool available = (result.stdout as String).split('\n').any((String line) {
return line.startsWith('flutter@');
});
return available ? ValidationType.installed : ValidationType.missing;
} catch (error) {
return ValidationType.missing;
}
};
atomValidator.addValidator(new Validator(
'Atom editor',
resolution: 'Download at https://atom.io',
validatorFunction: atomExists
));
atomValidator.addValidator(new Validator(
'Flutter plugin',
description: 'adds Flutter specific functionality to Atom',
resolution: "Install the 'flutter' plugin in Atom or run 'apm install flutter'",
validatorFunction: flutterPluginExists
));
return atomValidator.validate();
}
void diagnose() => validate().print();
}
...@@ -10,7 +10,7 @@ import '../globals.dart'; ...@@ -10,7 +10,7 @@ import '../globals.dart';
import 'mac.dart'; import 'mac.dart';
class IOSWorkflow extends Workflow { class IOSWorkflow extends Workflow {
IOSWorkflow() : super('iOS'); String get label => 'iOS toolchain';
bool get appliesToHostPlatform => Platform.isMacOS; bool get appliesToHostPlatform => Platform.isMacOS;
...@@ -23,33 +23,33 @@ class IOSWorkflow extends Workflow { ...@@ -23,33 +23,33 @@ class IOSWorkflow extends Workflow {
ValidationResult validate() { ValidationResult validate() {
Validator iosValidator = new Validator( Validator iosValidator = new Validator(
'$name toolchain', label,
description: 'develop for iOS devices' description: 'develop for iOS devices'
); );
Function _xcodeExists = () { ValidationType xcodeExists() {
return xcode.isInstalled ? ValidationType.installed : ValidationType.missing; return xcode.isInstalled ? ValidationType.installed : ValidationType.missing;
}; };
Function _xcodeVersionSatisfactory = () { ValidationType xcodeVersionSatisfactory() {
return xcode.isInstalledAndMeetsVersionCheck ? ValidationType.installed : ValidationType.missing; return xcode.isInstalledAndMeetsVersionCheck ? ValidationType.installed : ValidationType.missing;
}; };
Function _xcodeEulaSigned = () { ValidationType xcodeEulaSigned() {
return xcode.eulaSigned ? ValidationType.installed : ValidationType.missing; return xcode.eulaSigned ? ValidationType.installed : ValidationType.missing;
}; };
Function _brewExists = () { ValidationType brewExists() {
return exitsHappy(<String>['brew', '-v']) return exitsHappy(<String>['brew', '-v'])
? ValidationType.installed : ValidationType.missing; ? ValidationType.installed : ValidationType.missing;
}; };
Function _ideviceinstallerExists = () { ValidationType ideviceinstallerExists() {
return exitsHappy(<String>['ideviceinstaller', '-h']) return exitsHappy(<String>['ideviceinstaller', '-h'])
? ValidationType.installed : ValidationType.missing; ? ValidationType.installed : ValidationType.missing;
}; };
Function _iosdeployExists = () { ValidationType iosdeployExists() {
return hasIdeviceId ? ValidationType.installed : ValidationType.missing; return hasIdeviceId ? ValidationType.installed : ValidationType.missing;
}; };
...@@ -57,7 +57,7 @@ class IOSWorkflow extends Workflow { ...@@ -57,7 +57,7 @@ class IOSWorkflow extends Workflow {
'XCode', 'XCode',
description: 'enable development for iOS devices', description: 'enable development for iOS devices',
resolution: 'Download at https://developer.apple.com/xcode/download/', resolution: 'Download at https://developer.apple.com/xcode/download/',
validatorFunction: _xcodeExists validatorFunction: xcodeExists
); );
iosValidator.addValidator(xcodeValidator); iosValidator.addValidator(xcodeValidator);
...@@ -66,21 +66,21 @@ class IOSWorkflow extends Workflow { ...@@ -66,21 +66,21 @@ class IOSWorkflow extends Workflow {
'version', 'version',
description: 'Xcode minimum version of $kXcodeRequiredVersionMajor.$kXcodeRequiredVersionMinor.0', description: 'Xcode minimum version of $kXcodeRequiredVersionMajor.$kXcodeRequiredVersionMinor.0',
resolution: 'Download the latest version or update via the Mac App Store', resolution: 'Download the latest version or update via the Mac App Store',
validatorFunction: _xcodeVersionSatisfactory validatorFunction: xcodeVersionSatisfactory
)); ));
xcodeValidator.addValidator(new Validator( xcodeValidator.addValidator(new Validator(
'EULA', 'EULA',
description: 'XCode end user license agreement', description: 'XCode end user license agreement',
resolution: "Open XCode or run the command 'sudo xcodebuild -license'", resolution: "Open XCode or run the command 'sudo xcodebuild -license'",
validatorFunction: _xcodeEulaSigned validatorFunction: xcodeEulaSigned
)); ));
Validator brewValidator = new Validator( Validator brewValidator = new Validator(
'brew', 'brew',
description: 'install additional development packages', description: 'install additional development packages',
resolution: 'Download at http://brew.sh/', resolution: 'Download at http://brew.sh/',
validatorFunction: _brewExists validatorFunction: brewExists
); );
iosValidator.addValidator(brewValidator); iosValidator.addValidator(brewValidator);
...@@ -89,14 +89,14 @@ class IOSWorkflow extends Workflow { ...@@ -89,14 +89,14 @@ class IOSWorkflow extends Workflow {
'ideviceinstaller', 'ideviceinstaller',
description: 'discover connected iOS devices', description: 'discover connected iOS devices',
resolution: "Install via 'brew install ideviceinstaller'", resolution: "Install via 'brew install ideviceinstaller'",
validatorFunction: _ideviceinstallerExists validatorFunction: ideviceinstallerExists
)); ));
brewValidator.addValidator(new Validator( brewValidator.addValidator(new Validator(
'ios-deploy', 'ios-deploy',
description: 'deploy to connected iOS devices', description: 'deploy to connected iOS devices',
resolution: "Install via 'brew install ios-deploy'", resolution: "Install via 'brew install ios-deploy'",
validatorFunction: _iosdeployExists validatorFunction: iosdeployExists
)); ));
return iosValidator.validate(); return iosValidator.validate();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment