// Copyright 2016 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 'dart:async'; import 'dart:io'; import 'package:path/path.dart' as path; import '../base/os.dart'; import '../base/process.dart'; import '../cache.dart'; import '../doctor.dart'; import '../globals.dart'; import '../runner/flutter_command.dart'; /// This setup command will install dependencies necessary for Flutter development. /// /// This is a hidden command, and is currently designed to work in a custom kiosk /// environment, but may be generalized in the future. class SetupCommand extends FlutterCommand { SetupCommand({ this.hidden: false }); @override final String name = 'setup'; @override final String description = 'Setup a machine to support Flutter development.'; @override final bool hidden; @override bool get requiresProjectRoot => false; @override Future<int> runInProject() async { printStatus('Running Flutter setup...'); // setup brew on mac if (os.isMacOS) { printStatus('\nChecking brew:'); if (os.which('brew') == null) { printError('homebrew is not installed; please install at http://brew.sh/.'); } else { printStatus('brew is installed.'); await runCommandAndStreamOutput(<String>['brew', 'install', 'ideviceinstaller']); await runCommandAndStreamOutput(<String>['brew', 'install', 'ios-deploy']); } } // setup atom printStatus('\nChecking Atom:'); String apmPath = os.which('apm')?.path; if (apmPath == null && FileSystemEntity.isFileSync('/usr/local/bin/apm')) apmPath = '/usr/local/bin/apm'; if (apmPath == null && FileSystemEntity.isFileSync('/usr/bin/apm')) apmPath = '/usr/bin/apm'; if (apmPath == null) { final String expectedLocation = '/Applications/Atom.app/Contents/Resources/app/apm/bin/apm'; if (FileSystemEntity.isFileSync(expectedLocation)) apmPath = expectedLocation; } if (apmPath == null) { printError('Unable to locate the Atom installation.'); } else { printStatus('apm command available at $apmPath'); AtomValidator atomValidator = new AtomValidator(); if (!atomValidator.hasPackage('dartlang')) await runCommandAndStreamOutput(<String>[apmPath, 'install', 'dartlang']); else printStatus('dartlang plugin installed'); if (!atomValidator.hasPackage('flutter')) await runCommandAndStreamOutput(<String>[apmPath, 'install', 'flutter']); else printStatus('flutter plugin installed'); // Set up the ~/.atom/config.cson file - make sure the path the the // flutter and dart sdks are correct. _updateAtomConfigFile(); } // run doctor printStatus('\nFlutter doctor:'); bool goodInstall = doctor.diagnose(); // Validate that flutter is available on the path. if (os.which('flutter') == null) { printError( '\nThe flutter command is not available on the path.\n' 'Please set up your PATH environment variable to point to the flutter/bin directory.' ); } else { printStatus('\nThe flutter command is available on the path.'); } if (goodInstall) printStatus('\nFlutter setup complete!'); return goodInstall ? 0 : 1; } // Quick-and-dirty manipulation of the cson file. void _updateAtomConfigFile() { // flutter: // flutterRoot: "..." // dartlang: // sdkLocation: "..." String flutterRoot = path.normalize(path.absolute(Cache.flutterRoot)); String sdkLocation = path.join(flutterRoot, 'bin/cache/dart-sdk'); File file = AtomValidator.getConfigFile(); if (file.existsSync()) { String cson = file.readAsStringSync(); cson = cson.trimRight() + '\n'; List<String> lines = cson.split('\n').map((String line) => line.trim()).toList(); if (!lines.contains('flutter:')) { cson += ''' flutter: flutterRoot: "$flutterRoot" '''; } if (!lines.contains('dartlang:')) { cson += ''' dartlang: sdkLocation: "$sdkLocation" '''; } if (cson.trim() != file.readAsStringSync().trim()) { printStatus('Updating ${file.path}'); file.writeAsStringSync(cson); } } else { // Create a new config file. printStatus('Creating ${file.path}'); String cson = ''' "*": flutter: flutterRoot: "$flutterRoot" dartlang: sdkLocation: "$sdkLocation" '''; file.writeAsStringSync(cson); } } }