anchor.diff:    final String analyzerSeparator = globals.platform.isWindows ? '-' : '•';
   
     group('analyze once', () {
  -    Directory tempDir;
  -    String projectPath;
  -    File libMain;
  -
       setUpAll(() {
         Cache.disableLocking();
  -      tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_1.').absolute;
  -      projectPath = globals.fs.path.join(tempDir.path, 'flutter_project');
  -      libMain = globals.fs.file(globals.fs.path.join(projectPath, 'lib', 'main.dart'));
  -    });
  -
  -    tearDownAll(() {
  -      tryToDelete(tempDir);
  -    });
  -
  -    // Create a project to be analyzed
  -    testUsingContext('flutter create', () async {
  -      await runCommand(
  -        command: CreateCommand(),
  -        arguments: <String>['--no-wrap', 'create', projectPath],
  -        statusTextContains: <String>[
  -          'All done!',
  -          'Your application code is in ${globals.fs.path.normalize(globals.fs.path.join(globals.fs.path.relative(projectPath), 'lib', 'main.dart'))}',
  -        ],
  -      );
  -      expect(libMain.existsSync(), isTrue);
  -    }, overrides: <Type, Generator>{
  -      Pub: () => const Pub(),
  -    });
  -
  -    // Analyze in the current directory - no arguments
  -    testUsingContext('working directory', () async {
  -      await runCommand(
  -        command: AnalyzeCommand(workingDirectory: globals.fs.directory(projectPath)),
  -        arguments: <String>['analyze'],
  -        statusTextContains: <String>['No issues found!'],
  -      );
  -    }, overrides: <Type, Generator>{
  -      Pub: () => const Pub(),
  -    });
  -
  -    // Analyze a specific file outside the current directory
  -    testUsingContext('passing one file throws', () async {
  -      await runCommand(
  -        command: AnalyzeCommand(),
  -        arguments: <String>['analyze', libMain.path],
  -        toolExit: true,
  -        exitMessageContains: 'is not a directory',
  -      );
  -    }, overrides: <Type, Generator>{
  -      Pub: () => const Pub(),
  -    });
  -
  -    // Analyze in the current directory - no arguments
  -    testUsingContext('working directory with errors', () async {
  -      // Break the code to produce the "The parameter 'onPressed' is required" hint
  -      // that is upgraded to a warning in package:flutter/analysis_options_user.yaml
  -      // to assert that we are using the default Flutter analysis options.
  -      // Also insert a statement that should not trigger a lint here
  -      // but will trigger a lint later on when an analysis_options.yaml is added.
  -      String source = await libMain.readAsString();
  -      source = source.replaceFirst(
  -        'onPressed: _incrementCounter,',
  -        '// onPressed: _incrementCounter,',
  -      );
  -      source = source.replaceFirst(
  -        '_counter++;',
  -        '_counter++; throw "an error message";',
  -      );
  -      await libMain.writeAsString(source);
  +      Cache.flutterRoot = FlutterCommandRunner.defaultFlutterRoot;
  +    });
  +
  +    void _createDotPackages(String projectPath) {
  +      final StringBuffer flutterRootUri = StringBuffer('file://');
  +      final String canonicalizedFlutterRootPath = globals.fs.path.canonicalize(Cache.flutterRoot);
  +      if (globals.platform.isWindows) {
  +        flutterRootUri
  +            ..write('/')
  +            ..write(canonicalizedFlutterRootPath.replaceAll('\\', '/'));
  +      } else {
  +        flutterRootUri.write(canonicalizedFlutterRootPath);
  +      }
  +      final String dotPackagesSrc = '''# Generated
  +flutter:$flutterRootUri/packages/flutter/lib/
  +sky_engine:$flutterRootUri/bin/cache/pkg/sky_engine/lib/
  +flutter_project:lib/
  +''';
  +      globals.fs.file(globals.fs.path.join(projectPath, '.packages'))
  +          ..createSync(recursive: true)
  +          ..writeAsStringSync(dotPackagesSrc);
  +    }
  +
  +    group('default libMain', () {
  +      Directory tempDir;
  +      String projectPath;
  +      File libMain;
  +
  +      setUpAll(() async {
  +        tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_1.').absolute;
  +        projectPath = globals.fs.path.join(tempDir.path, 'flutter_project');
  +        globals.fs.file(globals.fs.path.join(projectPath, 'pubspec.yaml'))
  +            ..createSync(recursive: true)
  +            ..writeAsStringSync(pubspecYamlSrc);
  +        _createDotPackages(projectPath);
  +      });
  +
  +      setUp(() {
  +        libMain = globals.fs.file(globals.fs.path.join(projectPath, 'lib', 'main.dart'))
  +            ..createSync(recursive: true)
  +            ..writeAsStringSync(mainDartSrc);
  +      });
  +
  +      tearDownAll(() {
  +        tryToDelete(tempDir);
  +      });
   
         // Analyze in the current directory - no arguments
  -      await runCommand(
  -        command: AnalyzeCommand(workingDirectory: globals.fs.directory(projectPath)),
  -        arguments: <String>['analyze'],
  -        statusTextContains: <String>[
  -          'Analyzing',
  -          'warning $analyzerSeparator The parameter \'onPressed\' is required',
  -          'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
  -        ],
  -        exitMessageContains: '2 issues found.',
  -        toolExit: true,
  -      );
  -    }, overrides: <Type, Generator>{
  -      Pub: () => const Pub(),
  -      ...noColorTerminalOverride,
  -    });
  -
  -    // Analyze in the current directory - no arguments
  -    testUsingContext('working directory with local options', () async {
  -      // Insert an analysis_options.yaml file in the project
  -      // which will trigger a lint for broken code that was inserted earlier
  -      final File optionsFile = globals.fs.file(globals.fs.path.join(projectPath, 'analysis_options.yaml'));
  -      await optionsFile.writeAsString('''
  -  include: package:flutter/analysis_options_user.yaml
  -  linter:
  -    rules:
  -      - only_throw_errors
  -  ''');
  +      testUsingContext('working directory', () async {
  +        await runCommand(
  +          command: AnalyzeCommand(workingDirectory: globals.fs.directory(projectPath)),
  +          arguments: <String>['analyze', '--no-pub'],
  +          statusTextContains: <String>['No issues found!'],
  +        );
  +      });
  +
  +      // Analyze a specific file outside the current directory
  +      testUsingContext('passing one file throws', () async {
  +        await runCommand(
  +          command: AnalyzeCommand(),
  +          arguments: <String>['analyze', '--no-pub', libMain.path],
  +          toolExit: true,
  +          exitMessageContains: 'is not a directory',
  +        );
  +      });
   
         // Analyze in the current directory - no arguments
  -      await runCommand(
  -        command: AnalyzeCommand(workingDirectory: globals.fs.directory(projectPath)),
  -        arguments: <String>['analyze'],
  -        statusTextContains: <String>[
  -          'Analyzing',
  -          'warning $analyzerSeparator The parameter \'onPressed\' is required',
  -          'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
  -          'info $analyzerSeparator Only throw instances of classes extending either Exception or Error',
  -        ],
  -        exitMessageContains: '3 issues found.',
  -        toolExit: true,
  -      );
  -    }, overrides: <Type, Generator>{
  -      Pub: () => const Pub(),
  -      ...noColorTerminalOverride
  +      testUsingContext('working directory with errors', () async {
  +        // Break the code to produce the "Avoid empty else" hint
  +        // that is upgraded to a warning in package:flutter/analysis_options_user.yaml
  +        // to assert that we are using the default Flutter analysis options.
  +        // Also insert a statement that should not trigger a lint here
  +        // but will trigger a lint later on when an analysis_options.yaml is added.
  +        String source = await libMain.readAsString();
  +        source = source.replaceFirst(
  +          'return MaterialApp(',
  +          'if (debugPrintRebuildDirtyWidgets) {} else ; return MaterialApp(',
  +        );
  +        source = source.replaceFirst(
  +          'onPressed: _incrementCounter,',
  +          '// onPressed: _incrementCounter,',
  +        );
  +        source = source.replaceFirst(
  +            '_counter++;',
  +            '_counter++; throw "an error message";',
  +          );
  +        libMain.writeAsStringSync(source);
  +
  +        // Analyze in the current directory - no arguments
  +        await runCommand(
  +          command: AnalyzeCommand(workingDirectory: globals.fs.directory(projectPath)),
  +          arguments: <String>['analyze', '--no-pub'],
  +          statusTextContains: <String>[
  +            'Analyzing',
  +            'info $analyzerSeparator Avoid empty else statements',
  +            'info $analyzerSeparator Avoid empty statements',
  +            'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
  +          ],
  +          exitMessageContains: '3 issues found.',
  +          toolExit: true,
  +        );
  +      });
  +
  +      // Analyze in the current directory - no arguments
  +      testUsingContext('working directory with local options', () async {
  +        // Insert an analysis_options.yaml file in the project
  +        // which will trigger a lint for broken code that was inserted earlier
  +        final File optionsFile = globals.fs.file(globals.fs.path.join(projectPath, 'analysis_options.yaml'));
  +        try {
  +          optionsFile.writeAsStringSync('''
  +      include: package:flutter/analysis_options_user.yaml
  +      linter:
  +        rules:
  +          - only_throw_errors
  +      ''');
  +          String source = libMain.readAsStringSync();
  +          source = source.replaceFirst(
  +            'onPressed: _incrementCounter,',
  +            '// onPressed: _incrementCounter,',
  +          );
  +          source = source.replaceFirst(
  +            '_counter++;',
  +            '_counter++; throw "an error message";',
  +          );
  +          libMain.writeAsStringSync(source);
  +
  +          // Analyze in the current directory - no arguments
  +          await runCommand(
  +            command: AnalyzeCommand(workingDirectory: globals.fs.directory(projectPath)),
  +            arguments: <String>['analyze', '--no-pub'],
  +            statusTextContains: <String>[
  +              'Analyzing',
  +              'info $analyzerSeparator The declaration \'_incrementCounter\' isn\'t',
  +              'info $analyzerSeparator Only throw instances of classes extending either Exception or Error',
  +            ],
  +            exitMessageContains: '2 issues found.',
  +            toolExit: true,
  +          );
  +        } finally {
  +          if (optionsFile.existsSync()) {
  +            optionsFile.deleteSync();
  +          }
  +        }
  +      });
       });
   
       testUsingContext('no duplicate issues', () async {
         final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_2.').absolute;
  +      _createDotPackages(tempDir.path);
   
         try {
           final File foo = globals.fs.file(globals.fs.path.join(tempDir.path, 'foo.dart'));
  
positive.code: StringBuffer bar = StringBuffer('baz');
  ''';
        final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_analyze_once_test_3.');
        tempDir.childFile('main.dart').writeAsStringSync(contents);
        try {
          await runCommand(
            command: AnalyzeCommand(workingDirectory: globals.fs.directory(tempDir)),
            arguments: <String>['analyze'],
            statusTextContains: <String>['No issues found!'],
          );
        } finally {
          tryToDelete(tempDir);
        }
      }, overrides: <Type, Generator>{
        Pub: () => const Pub(),
        ...noColorTerminalOverride
      });
  
  
negative.code: 
    testLogger.clear();
  }
  
  const String mainDartSrc = r'''
  import 'package:flutter/material.dart';
  
  void main() => runApp(MyApp());
  
  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(title: 'Flutter Demo Home Page'),
      );
    }
  }
  
  class MyHomePage extends StatefulWidget {
    MyHomePage({Key key, this.title}) : super(key: key);
  
    final String title;
  
    @override
    _MyHomePageState createState() => _MyHomePageState();
  }
  
  class _MyHomePageState extends State<MyHomePage> {
    int _counter = 0;
  
    void _incrementCounter() {
      setState(() {
        _counter++;
      });
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'You have pushed the button this many times:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.display1,
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      );
    }
  }
  ''';
  
  const String pubspecYamlSrc = r'''name: flutter_project
  environment:
    sdk: ">=2.1.0 <3.0.0"
  
  dependencies:
    flutter:
      sdk: flutter
  ''';
  