hunk.code_window:     .then(() => waitForAnyProcessOutputToMatch(
           /webpack: bundle is now VALID|webpack: Compiled successfully./, 5000))
       // Count the bundles.
       .then(({ stdout }) => {
         let newNumberOfChunks = stdout.split(chunkRegExp).length;
  
hunk.labels: keep replace keep keep keep
hunk.after_edit:         /webpack: bundle is now VALID|webpack: Compiled successfully./, 10000))
  
hunk.file_path: tests/e2e/tests/build/rebuild.ts
hunk.type: replace
file: import * as fs from 'fs';
  import * as path from 'path';
  
  import { oneLine, stripIndent } from 'common-tags';
  
  const stringUtils = require('ember-cli-string-utils');
  const Command = require('../ember-cli/lib/models/command');
  const lookupCommand = require('../ember-cli/lib/cli/lookup-command');
  
  function extractOptions(opts: any): String {
    const output: String[] = [];
  
    for (let index = 0; index < opts.length; index++) {
      const element = opts[index];
      output.push('--' + element.name);
      if (element.aliases) {
        output.push('-' + element.aliases[0]);
      }
    }
  
    return output.sort().join(' ');
  }
  
  export interface CompletionCommandOptions {
    all?: boolean;
    bash?: boolean;
    zsh?: boolean;
  };
  
  const commandsToIgnore = [
    'easter-egg',
    'destroy',
    'github-pages-deploy' // errors because there is no base github-pages command
  ];
  
  const optsNg: String[] = [];
  
  const CompletionCommand = Command.extend({
    name: 'completion',
    description: 'Adds autocomplete functionality to `ng` commands and subcommands',
    works: 'everywhere',
    availableOptions: [
      { name: 'all',   type: Boolean, default: true,  aliases: ['a'] },
      { name: 'bash',  type: Boolean, default: false, aliases: ['b'] },
      { name: 'zsh',   type: Boolean, default: false, aliases: ['z'] }
    ],
  
    run: function (commandOptions: CompletionCommandOptions) {
      commandOptions.all = !commandOptions.bash && !commandOptions.zsh;
  
      const commandFiles = fs.readdirSync(__dirname)
        .filter(file => file.match(/\.ts$/) && !file.match(/\.run.ts$/))
        .map(file => path.parse(file).name)
        .filter(file => {
          return commandsToIgnore.indexOf(file) < 0;
        })
        .map(file => file.toLowerCase());
  
      const commandMap = commandFiles.reduce((acc: any, curr: string) => {
        let classifiedName = stringUtils.classify(curr);
        let defaultImport = require(`./${curr}`).default;
  
        acc[classifiedName] = defaultImport;
  
        return acc;
      }, {});
  
      let caseBlock = '';
  
      commandFiles.forEach(cmd => {
        const Command = lookupCommand(commandMap, cmd);
        const com: String[] = [];
  
        const command = new Command({
          ui: this.ui,
          project: this.project,
          commands: this.commands,
          tasks: this.tasks
        });
  
        optsNg.push(command.name);
        com.push(command.name);
  
        if (command.aliases) {
          command.aliases.forEach((element: String) => {
            optsNg.push(element);
            com.push(element);
          });
        }
  
        if (command.availableOptions && command.availableOptions[0]) {
          let opts = extractOptions (command.availableOptions);
          caseBlock = caseBlock + '    ' + com.sort().join('|') + ') opts="' + opts + '" ;;\n';
        }
      });
  
      caseBlock = 'ng|help) opts="' + optsNg.sort().join(' ') + '" ;;\n' +
                  caseBlock +
                  '    *) opts="" ;;';
  
      console.log(stripIndent`
        ###-begin-ng-completion###
        #
  
        # ng command completion script
        #   This command supports 3 cases.
        #   1. (Default case) It prints a common completion initialisation for both Bash and Zsh.
        #      It is the result of either calling "ng completion" or "ng completion -a".
        #   2. Produce Bash-only completion: "ng completion -b" or "ng completion --bash".
        #   3. Produce Zsh-only completion: "ng completion -z" or "ng completion --zsh".
        #
        # Installation: ng completion -b >> ~/.bashrc
        #           or  ng completion -z >> ~/.zshrc
        #`);
  
      if (commandOptions.all && !commandOptions.bash) {
        console.log('if test ".$(type -t complete 2>/dev/null || true)" = ".builtin"; then');
      }
  
      if (commandOptions.all || commandOptions.bash) {
        console.log(stripIndent`
            _ng_completion() {
             local cword pword opts
  
             COMPREPLY=()
             cword=\${COMP_WORDS[COMP_CWORD]}
             pword=\${COMP_WORDS[COMP_CWORD - 1]}
  
             case \${pword} in
               ${caseBlock}
             esac
  
             COMPREPLY=( $(compgen -W '\${opts}' -- $cword) )
  
             return 0
           }
  
           complete -o default -F _ng_completion ng
           `);
      }
  
      if (commandOptions.all) {
        console.log(stripIndent`
          elif test ".$(type -w compctl 2>/dev/null || true)" = ".compctl: builtin" ; then
          `);
      }
  
      if (commandOptions.all || commandOptions.zsh) {
        console.log(stripIndent`
            _ng_completion () {
              local words cword opts
              read -Ac words
              read -cn cword
              let cword-=1
  
              case $words[cword] in
                ${caseBlock}
              esac
  
              setopt shwordsplit
              reply=($opts)
              unset shwordsplit
            }
  
            compctl -K _ng_completion ng
            `);
      }
  
      if (commandOptions.all) {
        console.log(stripIndent`
          else
            echo "Builtin command 'complete' or 'compctl' is redefined; cannot produce completion."
            return 1
          fi`);
      }
  
      console.log('###-end-ng-completion###');
  
    }
  });
  
  export default CompletionCommand;
  