tasks/lib/GruntLogListener.js
function tree2archy (node) {
  var dependencies = mout.object.values(node.dependencies);
  var version = !node.missing ? node.pkgMeta._release || node.pkgMeta.version : null;
  var label = node.endpoint.name + (version ? '#' + version : '');
  var update;

  if (node.root) {
    label += ' ' + node.canonicalDir;
  }

  // State labels
  if (node.missing) {
    label += chalk.red(' not installed');
    return label;
  }

  if (node.different) {
    label += chalk.red(' different');
  }

  if (node.linked) {
    label += chalk.magenta(' linked');
  }

  if (node.incompatible) {
    label += chalk.yellow(' incompatible') + ' with ' + node.endpoint.target;
  } else if (node.extraneous) {
    label += chalk.green(' extraneous');
  }

  // New versions
  if (node.update) {
    update = '';

    if (node.update.target && node.pkgMeta.version !== node.update.target) {
        update += node.update.target + ' available';
    }

    if (node.update.latest !== node.update.target) {
        update += (update ? ', ' : '');
        update += 'latest is ' + node.update.latest;
    }

    if (update) {
        label += ' (' + chalk.cyan(update) + ')';
    }
  }

  if (!dependencies.length) {
    return label;
  }

  return {
    label: label,
    nodes: mout.object.values(dependencies).map(tree2archy)
  };
}
function tree2archy (node) {
  var dependencies = mout.object.values(node.dependencies);
  var version = !node.missing ? node.pkgMeta._release || node.pkgMeta.version : null;
  var label = node.endpoint.name + (version ? '#' + version : '');
  var update;

  if (node.root) {
    label += ' ' + node.canonicalDir;
  }

  // State labels
  if (node.missing) {
    label += chalk.red(' not installed');
    return label;
  }

  if (node.different) {
    label += chalk.red(' different');
  }

  if (node.linked) {
    label += chalk.magenta(' linked');
  }

  if (node.incompatible) {
    label += chalk.yellow(' incompatible') + ' with ' + node.endpoint.target;
  } else if (node.extraneous) {
    label += chalk.green(' extraneous');
  }

  // New versions
  if (node.update) {
    update = '';

    if (node.update.target && node.pkgMeta.version !== node.update.target) {
        update += node.update.target + ' available';
    }

    if (node.update.latest !== node.update.target) {
        update += (update ? ', ' : '');
        update += 'latest is ' + node.update.latest;
    }

    if (update) {
        label += ' (' + chalk.cyan(update) + ')';
    }
  }

  if (!dependencies.length) {
    return label;
  }

  return {
    label: label,
    nodes: mout.object.values(dependencies).map(tree2archy)
  };
}
function tree2archy ( node ) { var dependencies = mout . object . values ( node . dependencies ) ; var version = ! node . missing ? node . pkgMeta . _release || node . pkgMeta . version : null ; var label = node . endpoint . name + ( version ? '#' + version : '' ) ; var update ; if ( node . root ) { label += ' ' + node . canonicalDir ; } // State labels if ( node . missing ) { label += chalk . red ( ' not installed' ) ; return label ; } if ( node . different ) { label += chalk . red ( ' different' ) ; } if ( node . linked ) { label += chalk . magenta ( ' linked' ) ; } if ( node . incompatible ) { label += chalk . yellow ( ' incompatible' ) + ' with ' + node . endpoint . target ; } else if ( node . extraneous ) { label += chalk . green ( ' extraneous' ) ; } // New versions if ( node . update ) { update = '' ; if ( node . update . target && node . pkgMeta . version !== node . update . target ) { update += node . update . target + ' available' ; } if ( node . update . latest !== node . update . target ) { update += ( update ? ', ' : '' ) ; update += 'latest is ' + node . update . latest ; } if ( update ) { label += ' (' + chalk . cyan ( update ) + ')' ; } } if ( ! dependencies . length ) { return label ; } return { label : label , nodes : mout . object . values ( dependencies ) . map ( tree2archy ) } ; }
the _tree2archy function, taken directly from bower source
https://github.com/bower/bower/blob/master/lib/renderers/StandardRenderer.js#L424-480

bower renderers are not a separate module, or else we wouldn't need this,
see: https://github.com/bower/bower/issues/874
the _tree2archy function taken directly from bower source https : // github . com / bower / bower / blob / master / lib / renderers / StandardRenderer . js#L424 - 480