import contextlib
import os
import errno
import shutil
import subprocess
import sys


@contextlib.contextmanager
def cd(dirname):
    cur_dir = os.getcwd()
    try:
        os.chdir(dirname)
        yield
    finally:
        os.chdir(cur_dir)


class Task:

    def __init__(self, url, repository, commit):
        self._url = url
        self._repository = self._convert(repository)
        self._commit = commit
        self._build_dir = self._create_dir('build', commit)
        self._output_dir = self._create_dir('out')

    def _create_dir(self, prefix, suffix=''):
        path = os.path.join(os.getcwd(), prefix, self._repository, suffix)
        try:
            os.makedirs(path)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise
        return path

    @staticmethod
    def _convert(url):
        if url.startswith('https://'):
            return url + '.git'
        return url

    def _clone(self):
        if subprocess.call(['git', 'clone', self._url, self._build_dir]) != 0:
            raise RuntimeError('git clone failed!')

    def _makeindex(self, file):
        with cd(self._build_dir):
            subprocess.call(['makeindex', file])

    def _compile(self, file):
        output_path = self._output_dir
        with cd(self._build_dir):
            if subprocess.call(['pdflatex', '-interaction=nonstopmode', '-aux-directory=' + output_path,
                                '-output-directory=' + output_path, file]) != 0:
                raise RuntimeError('pdflatex compilation failed!')

    def _clean(self):
        shutil.rmtree(self._build_dir)

    def run(self):
        def error(*objs):
            print("ERROR: ", *objs, end='\n', file=sys.stderr)
        try:
            self._clone()
            self._makeindex('main.tex')
            self._compile('main.tex')
            # Run twice for cross-references
            self._compile('main.tex')
        except Exception as e:
            error(e)
        finally:
            self._clean()


class LogHandler:
    def __init__(self, path):
        self._path = path

    def _lines(self):
        if not os.path.isfile(self._path):
            raise RuntimeError("The logfile does not exist")
        log_file = open(self._path, "r", encoding='latin-1')
        return log_file.readlines()

    def get_errors(self):
        error_prefix = "! "
        errors = []
        for line in self._lines():
            if line.startswith(error_prefix):
                errors.append(line.replace(error_prefix, ""))
        return errors

    def get_wanrings(self):
        return ''

    def get_all(self):
        return self._lines()
@@ -1128,37 +1128,38 @@
   with cd(self._
-build
+output
 _dir):%0A         
@@ -1233,47 +1233,8 @@
 e):%0A
-        output_path = self._output_dir%0A
     
@@ -1311,215 +1311,540 @@
 x', 
-'-interaction=nonstopmode', '-aux-directory=' + output_path,%0A                                '-
+file%5D) != 0:%0A                raise RuntimeError('pdflatex compilation failed!')%0A%0A    def _copy(self, pdf_file, log_file):%0A        # PDF File%0A        pdf_source_path = os.path.join(self._build_dir, pdf_file)%0A        pdf_dest_path = os.path.join(self._
 output
--directory=' + output_path, file%5D) != 0:%0A                raise RuntimeError('pdflatex compilation failed!'
+_dir, pdf_file)%0A        shutil.copyfile(pdf_source_path, pdf_dest_path)%0A        # Log File%0A        log_source_path = os.path.join(self._build_dir, log_file)%0A        log_dest_path = os.path.join(self._output_dir, log_file)%0A        shutil.copyfile(log_source_path, log_dest_path
 )%0A%0A 
@@ -2069,25 +2069,23 @@
   self._
-makeindex
+compile
 ('main.t
@@ -2107,32 +2107,34 @@
   self._
-compile
+makeindex
 ('main.
-te
+id
 x')%0A    
@@ -2145,40 +2145,33 @@
     
-# Run twice for cross-references
+self._compile('main.tex')
 %0A   
@@ -2183,39 +2183,47 @@
     self._co
-mpile
+py
 ('main.
-tex
+pdf','main.log
 ')%0A        e

Work now done in local dir. Necessary files copied afterwards.