2014-02-12 12:27:43 -05:00
|
|
|
Path = require "path"
|
|
|
|
Settings = require "settings-sharelatex"
|
|
|
|
logger = require "logger-sharelatex"
|
|
|
|
Metrics = require "./Metrics"
|
2018-03-05 06:02:31 -05:00
|
|
|
CommandRunner = require "./CommandRunner"
|
2014-02-12 12:27:43 -05:00
|
|
|
|
2016-07-14 09:47:36 -04:00
|
|
|
ProcessTable = {} # table of currently running jobs (pids or docker container names)
|
|
|
|
|
2014-02-12 12:27:43 -05:00
|
|
|
module.exports = LatexRunner =
|
|
|
|
runLatex: (project_id, options, callback = (error) ->) ->
|
2019-05-10 11:51:40 -04:00
|
|
|
{directory, mainFile, compiler, timeout, image, environment, flags} = options
|
2014-02-12 12:27:43 -05:00
|
|
|
compiler ||= "pdflatex"
|
|
|
|
timeout ||= 60000 # milliseconds
|
|
|
|
|
2019-05-10 11:51:40 -04:00
|
|
|
logger.log directory: directory, compiler: compiler, timeout: timeout, mainFile: mainFile, environment: environment, flags:flags, "starting compile"
|
2014-02-12 12:27:43 -05:00
|
|
|
|
2014-04-04 09:56:20 -04:00
|
|
|
# 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")
|
2014-02-12 12:27:43 -05:00
|
|
|
|
|
|
|
if compiler == "pdflatex"
|
2019-05-10 11:51:40 -04:00
|
|
|
command = LatexRunner._pdflatexCommand mainFile, flags
|
2014-02-12 12:27:43 -05:00
|
|
|
else if compiler == "latex"
|
2019-05-10 11:51:40 -04:00
|
|
|
command = LatexRunner._latexCommand mainFile, flags
|
2014-02-12 12:27:43 -05:00
|
|
|
else if compiler == "xelatex"
|
2019-05-10 11:51:40 -04:00
|
|
|
command = LatexRunner._xelatexCommand mainFile, flags
|
2014-02-12 12:27:43 -05:00
|
|
|
else if compiler == "lualatex"
|
2019-05-10 11:51:40 -04:00
|
|
|
command = LatexRunner._lualatexCommand mainFile, flags
|
2014-02-12 12:27:43 -05:00
|
|
|
else
|
|
|
|
return callback new Error("unknown compiler: #{compiler}")
|
2019-05-10 11:51:40 -04:00
|
|
|
|
2016-03-29 11:45:06 -04:00
|
|
|
if Settings.clsi?.strace
|
2016-03-30 05:59:01 -04:00
|
|
|
command = ["strace", "-o", "strace", "-ff"].concat(command)
|
2014-02-12 12:27:43 -05:00
|
|
|
|
2016-07-14 09:47:36 -04:00
|
|
|
id = "#{project_id}" # record running project under this id
|
|
|
|
|
2016-07-26 07:30:29 -04:00
|
|
|
ProcessTable[id] = CommandRunner.run project_id, command, directory, image, timeout, environment, (error, output) ->
|
2016-07-14 09:47:36 -04:00
|
|
|
delete ProcessTable[id]
|
2016-03-15 10:04:37 -04:00
|
|
|
return callback(error) if error?
|
|
|
|
runs = output?.stderr?.match(/^Run number \d+ of .*latex/mg)?.length or 0
|
|
|
|
failed = if output?.stdout?.match(/^Latexmk: Errors/m)? then 1 else 0
|
|
|
|
# counters from latexmk output
|
|
|
|
stats = {}
|
|
|
|
stats["latexmk-errors"] = failed
|
|
|
|
stats["latex-runs"] = runs
|
|
|
|
stats["latex-runs-with-errors"] = if failed then runs else 0
|
|
|
|
stats["latex-runs-#{runs}"] = 1
|
|
|
|
stats["latex-runs-with-errors-#{runs}"] = if failed then 1 else 0
|
2016-05-09 11:00:24 -04:00
|
|
|
# timing information from /usr/bin/time
|
|
|
|
timings = {}
|
2016-05-10 04:12:13 -04:00
|
|
|
stderr = output?.stderr
|
|
|
|
timings["cpu-percent"] = stderr?.match(/Percent of CPU this job got: (\d+)/m)?[1] or 0
|
|
|
|
timings["cpu-time"] = stderr?.match(/User time.*: (\d+.\d+)/m)?[1] or 0
|
|
|
|
timings["sys-time"] = stderr?.match(/System time.*: (\d+.\d+)/m)?[1] or 0
|
2016-05-09 11:00:24 -04:00
|
|
|
callback error, output, stats, timings
|
2014-02-12 12:27:43 -05:00
|
|
|
|
2016-07-14 09:47:36 -04:00
|
|
|
killLatex: (project_id, callback = (error) ->) ->
|
|
|
|
id = "#{project_id}"
|
|
|
|
logger.log {id:id}, "killing running compile"
|
|
|
|
if not ProcessTable[id]?
|
2017-06-20 04:18:15 -04:00
|
|
|
logger.warn {id}, "no such project to kill"
|
|
|
|
return callback(null)
|
2016-07-14 09:47:36 -04:00
|
|
|
else
|
|
|
|
CommandRunner.kill ProcessTable[id], callback
|
|
|
|
|
2019-05-10 11:51:40 -04:00
|
|
|
_latexmkBaseCommand: (flags) ->
|
|
|
|
args = ["latexmk", "-cd", "-f", "-jobname=output", "-auxdir=$COMPILE_DIR", "-outdir=$COMPILE_DIR", "-synctex=1","-interaction=batchmode"]
|
|
|
|
if flags
|
|
|
|
args = args.concat(flags)
|
|
|
|
(Settings?.clsi?.latexmkCommandPrefix || []).concat(args)
|
2014-02-12 12:27:43 -05:00
|
|
|
|
2019-05-10 11:51:40 -04:00
|
|
|
_pdflatexCommand: (mainFile, flags) ->
|
|
|
|
LatexRunner._latexmkBaseCommand(flags).concat [
|
2017-03-02 11:43:35 -05:00
|
|
|
"-pdf",
|
2014-02-12 12:27:43 -05:00
|
|
|
Path.join("$COMPILE_DIR", mainFile)
|
|
|
|
]
|
2019-05-10 11:51:40 -04:00
|
|
|
|
|
|
|
_latexCommand: (mainFile, flags) ->
|
|
|
|
LatexRunner._latexmkBaseCommand(flags).concat [
|
2017-03-02 11:43:35 -05:00
|
|
|
"-pdfdvi",
|
2014-02-12 12:27:43 -05:00
|
|
|
Path.join("$COMPILE_DIR", mainFile)
|
|
|
|
]
|
|
|
|
|
2019-05-10 11:51:40 -04:00
|
|
|
_xelatexCommand: (mainFile, flags) ->
|
|
|
|
LatexRunner._latexmkBaseCommand(flags).concat [
|
2017-03-02 11:43:35 -05:00
|
|
|
"-xelatex",
|
2014-02-12 12:27:43 -05:00
|
|
|
Path.join("$COMPILE_DIR", mainFile)
|
|
|
|
]
|
|
|
|
|
2019-05-10 11:51:40 -04:00
|
|
|
_lualatexCommand: (mainFile, flags) ->
|
|
|
|
LatexRunner._latexmkBaseCommand(flags).concat [
|
2017-03-02 11:43:35 -05:00
|
|
|
"-lualatex",
|
2014-02-12 12:27:43 -05:00
|
|
|
Path.join("$COMPILE_DIR", mainFile)
|
|
|
|
]
|
|
|
|
|