anchor.diff:  //        .init(doCheckout: !skipCheckout);
   //  }
   
  -  // ------- up to
  -
   //  @u.SubCommand(help: 'Sets up for the start of development on a new feature')
   //  start(String featureName,
   //      {@u.Option(help: 'The directory that contains the root of the projecs',
  
positive.code:     return install(gitUri, installDirectory: installDirectory);
    }
  
    Future install(String gitUri,
        {String installDirectory: '.'}) async {
      final Directory installDir = new Directory(installDirectory);
      final ProjectGroup projectGroup =
      await ProjectGroup.install(installDir, gitUri);
  
      await (await projectGroup.rootJefeProjects).lifecycle.init();
    }
  
negative.code:         .lifecycle
          .init(doCheckout: !skipCheckout);
    }
  }
  
  class Start extends Command {
    final name = "start";
    final description = 'Sets up for the start of development on a new feature';
  
    Start() {
      argParser.addOption('featureName',
          help: 'The name of the feature to start', abbr: 'f');
      argParser.addOption('rootDirectory',
          help: 'The directory that contains the root of the projecs',
          abbr: 'd',
          defaultsTo: '.');
      argParser.addOption('projects',
          help:
              'A project name filter. Only projects whose name contains the text will run',
          abbr: 'p');
    }
  
    Future run() {
      final featureName = argResults['featureName'];
      final rootDirectory = argResults['rootDirectory'];
      final projects = argResults['projects'];
      return start(featureName, rootDirectory: rootDirectory, projects: projects);
    }
  
    start(String featureName,
        {String rootDirectory: '.', String projects}) async {
      final graph = await _loadGraph(rootDirectory);
      return graph
          .multiProjectCommands(projectFilter: projectNameFilter(projects))
          .lifecycle
          .startNewFeature(featureName);
    }
  }
  
  class Finish extends Command {
    final name = "finish";
    final description = 'Completes feature and returns to development branch';
  
    Finish() {
      argParser.addOption('rootDirectory',
          help: 'The directory that contains the root of the projecs',
          abbr: 'd',
          defaultsTo: '.');
      argParser.addOption('projects',
          help:
              'A project name filter. Only projects whose name contains the text will run',
          abbr: 'p');
    }
  
    Future run() {
      final rootDirectory = argResults['rootDirectory'];
      final projects = argResults['projects'];
      return finish(rootDirectory: rootDirectory, projects: projects);
    }
  
    finish({String rootDirectory: '.', String projects}) async {
      final graph = await _loadGraph(rootDirectory);
      return graph
          .multiProjectCommands(projectFilter: projectNameFilter(projects))
          .lifecycle
          .completeFeature();
    }
  }
  
  class Exec extends Command {
    final name = "exec";
    final description = 'Runs the given command in all projects';
  
    Exec() {
      argParser.addOption('command', help: 'The command to execute', abbr: 'c');
      argParser.addOption('rootDirectory',
          help: 'The directory that contains the root of the projecs',
          abbr: 'd',
          defaultsTo: '.');
      argParser.addOption('projects',
          help:
              'A project name filter. Only projects whose name contains the text will run',
          abbr: 'p');
      argParser.addFlag('executeSerially',
          help:
              'Instead of running the commands concurrently on the projects, run only one command on one project at a time',
          abbr: 's',
          defaultsTo: false);
    }
  
    Future run() {
      final commandArgs = argResults.rest.toList();
      final command = argResults['command'];
      final rootDirectory = argResults['rootDirectory'];
      final projects = argResults['projects'];
      final executeSerially = argResults['executeSerially'];
      final fred = 'fuck';
  
      return exec(command, commandArgs,
          rootDirectory: rootDirectory,
          projects: projects,
          executeSerially: executeSerially);
    }
  
    exec(String command, List<String> args,
        {String rootDirectory: '.',
        String projects,
        bool executeSerially: false}) async {
      final graph = await _loadGraph(rootDirectory);
  
      final processCommands = graph
          .multiProjectCommands(
              projectFilter: projectNameFilter(projects),
              defaultConcurrencyMode: executeSerially
                  ? CommandConcurrencyMode.serialDepthFirst
                  : CommandConcurrencyMode.concurrentProject)
          .processCommands;
  
      final result = await processCommands.execute(command, args);
      final output = result.map((r) => r.toReportString()).join('\n');
      stdout.write(output);
    }
  }
  
  //class Jefe extends Command {
  