<commit_before>// @flow

import type {ActivityList} from './activity-list.js'
import type Configuration from '../../configuration/configuration.js'
import type Formatter from '../../formatters/formatter.js'
import type {LinkTargetList} from './link-target-list.js'

const ActivityTypeManager = require('./activity-type-manager.js')
const ActivityListBuilder = require('./activity-list-builder')
const {cyan} = require('chalk')
const fs = require('fs-extra')
const LinkTargetListBuilder = require('./link-target-list-builder.js')
const MarkdownParser = require('../../parsers/markdown/markdown-parser')
const path = require('path')
const UnprintedUserError = require('../../errors/unprinted-user-error.js')
const util = require('util')

// Runs the given Markdown file
class MarkdownFileRunner {
  filePath: string
  formatter: Formatter
  activityTypesManager: ActivityTypeManager
  configuration: Configuration
  parser: MarkdownParser
  activityListBuilder: ActivityListBuilder
  linkTargetBuilder: LinkTargetListBuilder
  runData: ActivityList

  constructor (value: {filePath: string, formatter: Formatter, activityTypesManager: ActivityTypeManager, configuration: Configuration, linkTargets: LinkTargetList}) {
    this.filePath = value.filePath
    this.formatter = value.formatter
    this.configuration = value.configuration
    this.parser = new MarkdownParser()
    this.activityListBuilder = new ActivityListBuilder({
      activityTypesManager: value.activityTypesManager,
      filePath: this.filePath,
      formatter: this.formatter,
      configuration: this.configuration,
      linkTargets: value.linkTargets})
    this.linkTargetBuilder = new LinkTargetListBuilder({linkTargets: value.linkTargets})
  }

  // Prepares this runner
  async prepare (): Promise<void> {
    // Need to start the file here
    // so that the formatter has the filename
    // in case there are errors preparing.
    this.formatter.startFile(this.filePath)
    var markdownText = await fs.readFile(this.filePath, {encoding: 'utf8'})
    markdownText = markdownText.trim()
    if (markdownText.length === 0) {
      throw new UnprintedUserError(`found empty file ${cyan(path.relative(process.cwd(), this.filePath))}`)
    }
    const astNodeList = this.parser.parse(markdownText)
    const linkTargets = this.linkTargetBuilder.buildLinkTargets(this.filePath, astNodeList)
    this.runData = this.activityListBuilder.build(linkTargets)
  }

  // Runs this runner
  // (after it has been prepared)
  async run (): Promise<number> {
    this.formatter.startFile(this.filePath)
    for (let block of this.runData) {
      await this._runBlock(block)
    }
    return this.runData.length
  }

  // TODO: rename "block" to "activity"
  async _runBlock (block) {
    // TODO: remove the if here, block.startLine is always there now
    if (block.startLine != null && block.endLine != null) {
      this.formatter.setLines(block.startLine, block.endLine)
    }
    this.formatter.startActivity(block.activityTypeName)
    try {
      if (block.runner.length === 1) {
        // synchronous activity or returns a promise
        await Promise.resolve(block.runner(block))
      } else {
        // asynchronous activity
        const promisified = util.promisify(block.runner)
        await promisified(block)
      }
      block.formatter.success()
    } catch (err) {
      if (isUserError(err)) {
        throw new UnprintedUserError(err)
      } else {
        // here we have a developer error
        throw err
      }
    }
  }
}

function isUserError (err: Error): boolean {
  return err.name === 'Error'
}

module.exports = MarkdownFileRunner
<commit_msg>Remove todo (#231)<commit_after>// @flow

import type {ActivityList} from './activity-list.js'
import type Configuration from '../../configuration/configuration.js'
import type Formatter from '../../formatters/formatter.js'
import type {LinkTargetList} from './link-target-list.js'

const ActivityTypeManager = require('./activity-type-manager.js')
const ActivityListBuilder = require('./activity-list-builder')
const {cyan} = require('chalk')
const fs = require('fs-extra')
const LinkTargetListBuilder = require('./link-target-list-builder.js')
const MarkdownParser = require('../../parsers/markdown/markdown-parser')
const path = require('path')
const UnprintedUserError = require('../../errors/unprinted-user-error.js')
const util = require('util')

// Runs the given Markdown file
class MarkdownFileRunner {
  filePath: string
  formatter: Formatter
  activityTypesManager: ActivityTypeManager
  configuration: Configuration
  parser: MarkdownParser
  activityListBuilder: ActivityListBuilder
  linkTargetBuilder: LinkTargetListBuilder
  runData: ActivityList

  constructor (value: {filePath: string, formatter: Formatter, activityTypesManager: ActivityTypeManager, configuration: Configuration, linkTargets: LinkTargetList}) {
    this.filePath = value.filePath
    this.formatter = value.formatter
    this.configuration = value.configuration
    this.parser = new MarkdownParser()
    this.activityListBuilder = new ActivityListBuilder({
      activityTypesManager: value.activityTypesManager,
      filePath: this.filePath,
      formatter: this.formatter,
      configuration: this.configuration,
      linkTargets: value.linkTargets})
    this.linkTargetBuilder = new LinkTargetListBuilder({linkTargets: value.linkTargets})
  }

  // Prepares this runner
  async prepare (): Promise<void> {
    // Need to start the file here
    // so that the formatter has the filename
    // in case there are errors preparing.
    this.formatter.startFile(this.filePath)
    var markdownText = await fs.readFile(this.filePath, {encoding: 'utf8'})
    markdownText = markdownText.trim()
    if (markdownText.length === 0) {
      throw new UnprintedUserError(`found empty file ${cyan(path.relative(process.cwd(), this.filePath))}`)
    }
    const astNodeList = this.parser.parse(markdownText)
    const linkTargets = this.linkTargetBuilder.buildLinkTargets(this.filePath, astNodeList)
    this.runData = this.activityListBuilder.build(linkTargets)
  }

  // Runs this runner
  // (after it has been prepared)
  async run (): Promise<number> {
    this.formatter.startFile(this.filePath)
    for (let activity of this.runData) {
      await this._runActivity(activity)
    }
    return this.runData.length
  }

  async _runActivity (activity) {
    this.formatter.setLines(activity.startLine, activity.endLine != null ? activity.endLine : activity.startLine)
    this.formatter.startActivity(activity.activityTypeName)
    try {
      if (activity.runner.length === 1) {
        // synchronous activity or returns a promise
        await Promise.resolve(activity.runner(activity))
      } else {
        // asynchronous activity
        const promisified = util.promisify(activity.runner)
        await promisified(activity)
      }
      activity.formatter.success()
    } catch (err) {
      if (isUserError(err)) {
        throw new UnprintedUserError(err)
      } else {
        // here we have a developer error
        throw err
      }
    }
  }
}

function isUserError (err: Error): boolean {
  return err.name === 'Error'
}

module.exports = MarkdownFileRunner

{'fraction_non_alphanumeric': 0.11014131338320865, 'fraction_numerical': 0.0012468827930174563, 'mean_word_length': 3.6664511958629604, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '2480454', 'n_tokens_mistral': 2052, 'n_tokens_neox': 1996, 'n_words': 499}