filter = (allLanguages, includes) => {
  if (!includes || includes.length === 0) { return reorderDependencies(allLanguages); }

  let languages = [];
  for (const item of includes) {
    if (isGroup(item)) {
      languages = languages.concat(languagesByGroup(allLanguages, item));
    } else {
      const languageName = item;
      const found = allLanguages.find((el) => el.name === languageName);
      if (found) { languages.push(found); } else {
        console.error(`[ERROR] Language '${languageName}' could not be found.`);
        process.exit(1);
      }
    }
  }

  // resolve requires
  for (const lang of languages) {
    lang.requires.forEach(needed => {
      if (!languages.find((el) => el.name === needed)) {
        console.info(`[INFO] Adding ${needed}... ${lang.name} requires ${needed}.`);
        languages.push(allLanguages.find((el) => el.name === needed));
      }
    });
  }

  // make sure our dependencies are in the correct order
  return reorderDependencies(languages);
}
Filters languages by a list of languages or categories

This also resolves any requires and dependency ordering issues.
The returned list can be registered sequentially and should "just work".

@param {array<Lanuage>} allLanguages - full list of languages
@param {array<name|group_name>} includes - which languages or groups to include
  example: ":common elixir ruby"
@returns {array<Language>} filtered list if languages