<commit_before>import fs from 'fs';
import path from 'path';
import eslint from 'eslint';
import ZoneInfo from '../resources/zone_info.js';
import contentList from '../resources/content_list.js';
import ZoneId from '../resources/zone_id.js';

// Used for trigger eval.
import Regexes from '../resources/regexes.js';
import NetRegexes from '../resources/netregexes.js';
import Conditions from '../resources/conditions.js';
import { Responses, triggerFunctions, triggerOutputFunctions, builtInResponseStr } from '../resources/responses.js';

// Paths are relative to current file.
// We can't import the manifest directly from util/ because that's webpack magic,
// so need to do the same processing its loader would do.
const raidbossManifest = '../ui/raidboss/data/manifest.txt';
const oopsyManifest = '../ui/oopsyraidsy/data/manifest.txt';
const outputFileName = 'coverage/coverage_report.js';

const readManifest = (filename) => {
  const contents = fs.readFileSync(filename);
  if (!contents)
    return [];
  const lines = contents.toString().split(/[\r\n]+/);
  return lines;
};

const processTriggerFile = (triggerFile, zoneId, triggerSet, timelineContents, coverage) => {
  let numTriggers = 0;
  if (triggerSet.triggers)
    numTriggers += triggerSet.triggers.length;
  if (triggerSet.timelineTriggers)
    numTriggers += triggerSet.timelineTriggers.length;

  // TODO: have find_missing_timeline_translations.js return a set of
  // translations that are missing so that we can include percentage translated
  // here as well.

  // TODO: also include oopsy

  coverage[zoneId] = coverage[zoneId] || {};

  const timelineEntry = {};
  if (timelineContents)
    timelineEntry.hasFile = true;
  if (triggerSet.timelineNeedsFixing)
    timelineEntry.timelineNeedsFixing = true;

  Object.assign(coverage[zoneId], {
    triggers: {
      num: numTriggers,
    },
    timeline: timelineEntry,
  });
};

const processRaidbossCoverage = async (manifest, coverage) => {
  const manifestLines = readManifest(manifest);
  const dataDir = path.dirname(manifest);
  for (const line of manifestLines) {
    if (!line.endsWith('.js'))
      continue;
    const triggerFileName = path.join(dataDir, line).replace(/\\/g, '/');
    const triggerSet = (await import(triggerFileName)).default;

    let timelineContents = null;<commit_msg>util: ignore stub timelines in coverage report<commit_after>import fs from 'fs';
import path from 'path';
import eslint from 'eslint';
import ZoneInfo from '../resources/zone_info.js';
import contentList from '../resources/content_list.js';
import ZoneId from '../resources/zone_id.js';

// Used for trigger eval.
import Regexes from '../resources/regexes.js';
import NetRegexes from '../resources/netregexes.js';
import Conditions from '../resources/conditions.js';
import { Responses, triggerFunctions, triggerOutputFunctions, builtInResponseStr } from '../resources/responses.js';

// Paths are relative to current file.
// We can't import the manifest directly from util/ because that's webpack magic,
// so need to do the same processing its loader would do.
const raidbossManifest = '../ui/raidboss/data/manifest.txt';
const oopsyManifest = '../ui/oopsyraidsy/data/manifest.txt';
const outputFileName = 'coverage/coverage_report.js';

const readManifest = (filename) => {
  const contents = fs.readFileSync(filename);
  if (!contents)
    return [];
  const lines = contents.toString().split(/[\r\n]+/);
  return lines;
};

const processTriggerFile = (triggerFile, zoneId, triggerSet, timelineContents, coverage) => {
  let numTriggers = 0;
  if (triggerSet.triggers)
    numTriggers += triggerSet.triggers.length;
  if (triggerSet.timelineTriggers)
    numTriggers += triggerSet.timelineTriggers.length;

  // TODO: have find_missing_timeline_translations.js return a set of
  // translations that are missing so that we can include percentage translated
  // here as well.

  // TODO: also include oopsy

  coverage[zoneId] = coverage[zoneId] || {};

  const timelineEntry = {};
  // 1000 here is an arbitrary limit to ignore stub timeline files that haven't been filled out.
  // ifrit-nm is the shortest real timeline, at 1800 characters.
  // TODO: consider processing the timeline and finding the max time? or some other heuristic.
  if (timelineContents && timelineContents.length > 1000)
    timelineEntry.hasFile = true;
  if (triggerSet.timelineNeedsFixing)
    timelineEntry.timelineNeedsFixing = true;

  Object.assign(coverage[zoneId], {
    triggers: {
      num: numTriggers,
    },
    timeline: timelineEntry,
  });
};

const processRaidbossCoverage = async (manifest, coverage) => {
  const manifestLines = readManifest(manifest);
  const dataDir = path.dirname(manifest);
  for (const line of manifestLines) {
    if (!line.endsWith('.js'))
      continue;
    const triggerFileName = path.join(dataDir, line).replace(/\\/g, '/');
    const triggerSet = (await import(triggerFileName)).default;

    let timelineContents = null;
{'fraction_non_alphanumeric': 0.1202328382175833, 'fraction_numerical': 0.0028101164191087916, 'mean_word_length': 4.1477272727272725, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7529306', 'n_tokens_mistral': 1484, 'n_tokens_neox': 1436, 'n_words': 426}