function bitrot()

in dev-utils/bitrot.js [257:375]


function bitrot(moduleNames) {
  log.debug({ moduleNames }, 'bitrot');
  var tavYmls = [
    yaml.load(fs.readFileSync('.tav.yml', 'utf8')),
    yaml.load(fs.readFileSync('./test/opentelemetry-bridge/.tav.yml', 'utf8')),
    yaml.load(
      fs.readFileSync('./test/opentelemetry-metrics/fixtures/.tav.yml', 'utf8'),
    ),
    yaml.load(
      fs.readFileSync(
        'test/instrumentation/modules/next/a-nextjs-app/.tav.yml',
        'utf8',
      ),
    ),
  ];
  var supported = loadSupportedDoc();

  // Merge into one data structure we can iterate through.
  var rangesFromName = {};
  var ensureKey = (name) => {
    if (!(name in rangesFromName)) {
      rangesFromName[name] = { tavRanges: [], supRanges: [] };
    }
  };
  tavYmls.forEach((tavYml) => {
    for (const [label, tavInfo] of Object.entries(tavYml)) {
      var name = tavInfo.name || label;
      ensureKey(name);
      rangesFromName[name].tavRanges.push(tavInfo.versions);
    }
  });
  for (const supInfo of supported) {
    ensureKey(supInfo.name);
    rangesFromName[supInfo.name].supRanges.push(supInfo.versions);
  }

  // Reduce to `moduleNames` if given.
  if (moduleNames && moduleNames.length > 0) {
    var allNames = Object.keys(rangesFromName);
    moduleNames.forEach((name) => {
      if (!(name in rangesFromName)) {
        throw new Error(
          `unknown module name: ${name} (known module names: ${allNames.join(
            ', ',
          )})`,
        );
      }
    });
    allNames.forEach((name) => {
      if (!moduleNames.includes(name)) {
        delete rangesFromName[name];
      }
    });
  }
  log.debug({ rangesFromName }, 'rangesFromName');

  // Check each module name.
  var namesToCheck = Object.keys(rangesFromName).sort();
  namesToCheck.forEach((name) => {
    var npmInfo = getNpmInfo(name);
    log.trace(
      { name, 'dist-tags': npmInfo['dist-tags'], time: npmInfo.time },
      'npmInfo',
    );

    // If the current latest version is in the supported and
    // tav ranges, then all is good.
    var latest = npmInfo['dist-tags'].latest;
    var tavGood = false;
    if (EXCUSE_FROM_TAV[name]) {
      tavGood = true;
    } else {
      for (const range of rangesFromName[name].tavRanges) {
        if (semver.satisfies(latest, range, { includePrerelease: true })) {
          tavGood = true;
          break;
        }
      }
    }
    var supGood = false;
    if (EXCUSE_FROM_SUPPORTED_TECHNOLOGIES_DOC[name]) {
      supGood = true;
    } else {
      for (const range of rangesFromName[name].supRanges) {
        if (semver.satisfies(latest, range, { includePrerelease: true })) {
          supGood = true;
          break;
        }
      }
    }
    if (tavGood && supGood) {
      log.debug(
        `latest ${name}@${latest} is in tav and supported ranges (a good thing)`,
      );
      return;
    }
    var issues = [];
    if (!tavGood) {
      issues.push(
        `is not in .tav.yml ranges (${rangesFromName[name].tavRanges.join(
          ', ',
        )})`,
      );
    }
    if (!supGood) {
      issues.push(
        `is not in supported-technologies.asciidoc ranges (${rangesFromName[
          name
        ].supRanges.join(', ')})`,
      );
    }
    rot(
      name,
      `latest ${name}@${latest} (released ${
        npmInfo.time[latest].split('T')[0]
      }): ${issues.join(', ')}`,
    );
  });
}