예제 #1
0
 def transaction(self):
     repository_path = getattr(self.instance, problem_field).repository_path
     commit_id = getattr(self.instance, commit_field)
     return Transaction(
         repository_path=repository_path,
         commit_id=commit_id
     )
예제 #2
0
 def parse_code(self, problem_code):
     problem_id, commit_id = problem_code.split('_')
     problem = Problem.objects.get(pk=problem_id)
     transaction = Transaction(repository_path=problem.repository_path,
                               commit_id=commit_id)
     problem_commit = ProblemCommit.objects.with_transaction(
         transaction).get()
     return problem_commit
예제 #3
0
    def execute(self, repo_dir, commit_id, out_dir):
        command = "verify"
        tempdir = tempfile.mkdtemp()
        logger.debug('temp directory at %s' % tempdir)
        environment = os.environ.copy()
        environment["WEB_TERMINAL"] = "true"

        transaction = Transaction(repository_path=repo_dir,
                                  commit_id=commit_id)
        revision = ProblemCommit.objects.with_transaction(transaction).get()
        revision.verification_status = VerificationStatus.Verifying
        revision.save()

        os.system(
            'git --git-dir="{repo_dir}" worktree add {work_dir} {commit_id}'.
            format(repo_dir=repo_dir, work_dir=tempdir, commit_id=commit_id))

        out_file = os.path.join(out_dir,
                                '{command}_out.txt'.format(command=command))
        err_file = os.path.join(out_dir,
                                '{command}_err.txt'.format(command=command))

        failed = False

        with open(out_file, "w") as out_desc:
            with open(err_file, "w") as err_desc:
                exit_code = subprocess.call(['tps', command],
                                            stdout=out_desc,
                                            stderr=err_desc,
                                            cwd=tempdir,
                                            env=environment)

        failed &= exit_code != 0

        code = revision.problem.code
        name = revision.problem_data.code
        if code != name:
            with open(err_file, "w+") as err_desc:
                err_desc.write(
                    'The problem code does not match the name given in problem.json'
                )
            failed = True

        if failed:
            revision.verification_status = VerificationStatus.Failed
        else:
            revision.verification_status = VerificationStatus.Successful
        revision.save()

        try:
            shutil.rmtree(tempdir)
            os.system('git --git-dir="{repo_dir}" worktree prune'.format(
                repo_dir=repo_dir, work_dir=tempdir, commit_id=commit_id))
        except Exception as e:
            logger.error(e, exc_info=e)
예제 #4
0
    def execute(self, repo_dir, commit_id, out_dir):
        command = "gen"
        tempdir = tempfile.mkdtemp()
        logger.warning('temp directory at %s' % tempdir)
        environment = os.environ.copy()
        environment["WEB_TERMINAL"] = "true"

        transaction = Transaction(repository_path=repo_dir,
                                  commit_id=commit_id)
        revision = ProblemCommit.objects.with_transaction(transaction).get()
        revision.generation_status = GenerationStatus.Generating
        revision.save()

        os.system(
            'git --git-dir="{repo_dir}" worktree add {work_dir} {commit_id}'.
            format(repo_dir=repo_dir, work_dir=tempdir, commit_id=commit_id))

        out_file = os.path.join(out_dir,
                                '{command}_out.txt'.format(command=command))
        err_file = os.path.join(out_dir,
                                '{command}_err.txt'.format(command=command))

        with open(out_file, "w") as out_desc:
            with open(err_file, "w") as err_desc:
                exit_code = subprocess.call(['tps', command],
                                            stdout=out_desc,
                                            stderr=err_desc,
                                            cwd=tempdir,
                                            env=environment)

        if exit_code != 0:
            revision.generation_status = GenerationStatus.GenerationFailed
        else:
            try:
                tests_src = os.path.join(tempdir, 'tests')
                tests_dst = os.path.join(out_dir, 'tests')
                if os.path.exists(tests_dst):
                    shutil.rmtree(tests_dst)
                shutil.copytree(tests_src, tests_dst)
            except Exception as e:
                with open(err_file, "a") as err_desc:
                    err_desc.write(str(e))
                revision.generation_status = GenerationStatus.GenerationFailed
            else:
                revision.generation_status = GenerationStatus.GenerationSuccessful

        revision.save()
        try:
            shutil.rmtree(tempdir)
            os.system('git --git-dir="{repo_dir}" worktree prune'.format(
                repo_dir=repo_dir, work_dir=tempdir, commit_id=commit_id))
        except Exception as e:
            logger.error(e, exc_info=e)
예제 #5
0
 def pk_object_hook(json_dict):
     if 'django_pk_encoded' in json_dict:
         from django.apps import apps
         model = apps.get_model(json_dict['app_label'], json_dict['model_name'])
         return model.objects.get(pk=json_dict['pk'])
     elif 'git_pk_encoded' in json_dict:
         from django.apps import apps
         model = apps.get_model(json_dict['app_label'], json_dict['model_name'])
         transaction = Transaction(
             repository_path=json_dict['repository_path'],
             commit_id=json_dict['commit_id'],
         )
         return model.objects.with_transaction(transaction).get(pk=json_dict['pk'])
     else:
         return json_dict
예제 #6
0
 def save(self, *args, **kwargs):
     repository = self._transaction.repo
     current_branch = self._transaction.repo.branches.local.get(
         self.initial_pk, )
     if current_branch is None:
         if isinstance(self.inited_head, str):
             commit = repository[Oid(hex=self.inited_head)]
         elif isinstance(self.inited_head, ProblemCommit):
             commit = repository[self.inited_head.commit_id]
         else:
             raise ValueError("Invalid head")
         current_branch = self._transaction.repo.branches.local.create(
             self.name, commit)
     if self.initial_pk != self.pk:
         current_branch.rename(self.pk)
     self._transaction = Transaction(repository_path=repository.path,
                                     branch_name=self.name)
예제 #7
0
 def __get__(self, instance, owner):
     if instance is None:
         return self
     repository_path = getattr(instance, self.problem_field_name).repository_path
     commit_id = getattr(instance, self.commit_id_field_name)
     if not hasattr(instance, self.get_cache_name()):
         pk = getattr(instance, self.field.attname, self.field.get_default())
         git_transaction = Transaction(
             repository_path=repository_path,
             commit_id=commit_id
         )
         if pk is None:
             obj = None
         else:
             obj = self.field.target.objects.with_transaction(git_transaction).get(pk=pk)
         setattr(instance, self.get_cache_name(), obj)
     return getattr(instance, self.get_cache_name())
예제 #8
0
def extract_revision_data(problem_code, revision_slug, user):
    problem = get_object_or_404(Problem, code=problem_code)
    try:
        transaction = Transaction(repository_path=problem.repository_path,
                                  commit_id=revision_slug)
    except (KeyError, ValueError):
        if getattr(settings, "DISABLE_BRANCHES", False):
            if revision_slug != "master":
                raise Http404
            branch, _ = problem.branches.get_or_create(
                name=revision_slug,
                defaults={"head": problem.get_master_branch().head})
        else:
            try:
                branch = problem.branches.get(name=revision_slug)
            except ObjectDoesNotExist:
                raise Http404
        revision = branch.head
    else:
        revision = ProblemCommit.objects.with_transaction(transaction).get()
        branch = None

    return problem, branch, revision
예제 #9
0
 def branches(self):
     transaction = Transaction(repository_path=self.repository_path)
     return NewProblemBranch.objects.with_transaction(transaction).all()
예제 #10
0
 def _get_instance(cls, transaction, pk):
     obj = cls(pk=pk)
     if len(transaction.parents) == 0:
         transaction = Transaction(transaction.repo.path, branch_name=pk)
     obj._transaction = transaction
     return obj