| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- /* eslint-disable
- camelcase,
- handle-callback-err,
- no-return-assign,
- no-unused-vars,
- */
- // TODO: This file was created by bulk-decaffeinate.
- // Fix any style issues and re-enable lint.
- /*
- * decaffeinate suggestions:
- * DS102: Remove unnecessary code created because of implicit returns
- * DS103: Rewrite code to no longer use __guard__
- * DS207: Consider shorter variations of null checks
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
- */
- let LatexRunner
- const Path = require('path')
- const Settings = require('settings-sharelatex')
- const logger = require('logger-sharelatex')
- const Metrics = require('./Metrics')
- const CommandRunner = require('./CommandRunner')
- const fs = require('fs')
- const ProcessTable = {} // table of currently running jobs (pids or docker container names)
- module.exports = LatexRunner = {
- runLatex(project_id, options, callback) {
- let command
- if (callback == null) {
- callback = function (error) {}
- }
- let {
- directory,
- mainFile,
- compiler,
- timeout,
- image,
- environment,
- flags,
- compileGroup
- } = options
- if (!compiler) {
- compiler = 'pdflatex'
- }
- if (!timeout) {
- timeout = 60000
- } // milliseconds
- logger.log(
- {
- directory,
- compiler,
- timeout,
- mainFile,
- environment,
- flags,
- compileGroup
- },
- 'starting compile'
- )
- // We want to run latexmk on the tex file which we will automatically
- // generate from the Rtex/Rmd/md file.
- mainFile = mainFile.replace(/\.(Rtex|md|Rmd)$/, '.tex')
- if (compiler === 'pdflatex') {
- command = LatexRunner._pdflatexCommand(mainFile, flags)
- } else if (compiler === 'latex') {
- command = LatexRunner._latexCommand(mainFile, flags)
- } else if (compiler === 'xelatex') {
- command = LatexRunner._xelatexCommand(mainFile, flags)
- } else if (compiler === 'lualatex') {
- command = LatexRunner._lualatexCommand(mainFile, flags)
- } else {
- return callback(new Error(`unknown compiler: ${compiler}`))
- }
- if (Settings.clsi != null ? Settings.clsi.strace : undefined) {
- command = ['strace', '-o', 'strace', '-ff'].concat(command)
- }
- const id = `${project_id}` // record running project under this id
- return (ProcessTable[id] = CommandRunner.run(
- project_id,
- command,
- directory,
- image,
- timeout,
- environment,
- compileGroup,
- function (error, output) {
- delete ProcessTable[id]
- if (error != null) {
- return callback(error)
- }
- const runs =
- __guard__(
- __guard__(output != null ? output.stderr : undefined, (x1) =>
- x1.match(/^Run number \d+ of .*latex/gm)
- ),
- (x) => x.length
- ) || 0
- const failed =
- __guard__(output != null ? output.stdout : undefined, (x2) =>
- x2.match(/^Latexmk: Errors/m)
- ) != null
- ? 1
- : 0
- // counters from latexmk output
- const stats = {}
- stats['latexmk-errors'] = failed
- stats['latex-runs'] = runs
- stats['latex-runs-with-errors'] = failed ? runs : 0
- stats[`latex-runs-${runs}`] = 1
- stats[`latex-runs-with-errors-${runs}`] = failed ? 1 : 0
- // timing information from /usr/bin/time
- const timings = {}
- const stderr = output != null ? output.stderr : undefined
- timings['cpu-percent'] =
- __guard__(
- stderr != null
- ? stderr.match(/Percent of CPU this job got: (\d+)/m)
- : undefined,
- (x3) => x3[1]
- ) || 0
- timings['cpu-time'] =
- __guard__(
- stderr != null
- ? stderr.match(/User time.*: (\d+.\d+)/m)
- : undefined,
- (x4) => x4[1]
- ) || 0
- timings['sys-time'] =
- __guard__(
- stderr != null
- ? stderr.match(/System time.*: (\d+.\d+)/m)
- : undefined,
- (x5) => x5[1]
- ) || 0
- // record output files
- LatexRunner.writeLogOutput(project_id, directory, output, () => {
- return callback(error, output, stats, timings)
- })
- }
- ))
- },
- writeLogOutput(project_id, directory, output, callback) {
- if (!output) {
- return callback()
- }
- // internal method for writing non-empty log files
- function _writeFile(file, content, cb) {
- if (content && content.length > 0) {
- fs.writeFile(file, content, (err) => {
- if (err) {
- logger.error({ project_id, file }, 'error writing log file') // don't fail on error
- }
- cb()
- })
- } else {
- cb()
- }
- }
- // write stdout and stderr, ignoring errors
- _writeFile(Path.join(directory, 'output.stdout'), output.stdout, () => {
- _writeFile(Path.join(directory, 'output.stderr'), output.stderr, () => {
- callback()
- })
- })
- },
- killLatex(project_id, callback) {
- if (callback == null) {
- callback = function (error) {}
- }
- const id = `${project_id}`
- logger.log({ id }, 'killing running compile')
- if (ProcessTable[id] == null) {
- logger.warn({ id }, 'no such project to kill')
- return callback(null)
- } else {
- return CommandRunner.kill(ProcessTable[id], callback)
- }
- },
- _latexmkBaseCommand(flags) {
- let args = [
- 'latexmk',
- '-cd',
- '-f',
- '-jobname=output',
- '-auxdir=$COMPILE_DIR',
- '-outdir=$COMPILE_DIR',
- '-synctex=1',
- '-interaction=batchmode'
- ]
- if (flags) {
- args = args.concat(flags)
- }
- return (
- __guard__(
- Settings != null ? Settings.clsi : undefined,
- (x) => x.latexmkCommandPrefix
- ) || []
- ).concat(args)
- },
- _pdflatexCommand(mainFile, flags) {
- return LatexRunner._latexmkBaseCommand(flags).concat([
- '-pdf',
- Path.join('$COMPILE_DIR', mainFile)
- ])
- },
- _latexCommand(mainFile, flags) {
- return LatexRunner._latexmkBaseCommand(flags).concat([
- '-pdfdvi',
- Path.join('$COMPILE_DIR', mainFile)
- ])
- },
- _xelatexCommand(mainFile, flags) {
- return LatexRunner._latexmkBaseCommand(flags).concat([
- '-xelatex',
- Path.join('$COMPILE_DIR', mainFile)
- ])
- },
- _lualatexCommand(mainFile, flags) {
- return LatexRunner._latexmkBaseCommand(flags).concat([
- '-lualatex',
- Path.join('$COMPILE_DIR', mainFile)
- ])
- }
- }
- function __guard__(value, transform) {
- return typeof value !== 'undefined' && value !== null
- ? transform(value)
- : undefined
- }
|