Rewrite using one docker container

This commit is contained in:
Tim Schubert 2018-05-15 17:48:09 +02:00
parent 3b81958e12
commit 8a397c79ce
6 changed files with 325 additions and 110 deletions

View file

@ -1,20 +1,44 @@
image: $CI_REGISTRY/abgabesystem/abgabesystem:latest
variables:
BASECODE: test_solutions
stages:
- sync
- deadlines
- plagiates
before_script:
- cp python-gitlab.cfg $HOME/.python-gitlab.cfg
- echo "private_token = ${PRIVATE_API_TOKEN}" >> $HOME/.python-gitlab.cfg
- pip install -r requirements.txt
create_tags:
image: python:3
deadlines:
stage: deadlines
only:
- master
tags:
- abgabesystem
script:
- python abgabesystem.py deadlines
- python abgabesystem.py deadline $CI_COMMIT_REF_NAME
plagiates:
stage: plagiates
tags:
- abgabesystem
script:
- python abgabesystem.py plagiates $CI_COMMIT_REF_NAME
artifacts:
paths:
- results/
sync:
stage: sync
tags:
- abgabesystem
script:
python abgabesystem.py sync
only:
- master

12
Dockerfile Normal file
View file

@ -0,0 +1,12 @@
FROM alpine:latest
WORKDIR /app
ADD tubs_checks.xml .
ADD requirements.txt .
ENV JPLAG_VERSION=2.11.9-SNAPSHOT
RUN apk add --no-cache openjdk8 python3 curl git
RUN curl -sL https://github.com/jplag/jplag/releases/download/v${JPLAG_VERSION}/jplag-${JPLAG_VERSION}-jar-with-dependencies.jar -o jplag.jar
RUN pip3 install -r requirements.txt

View file

@ -3,34 +3,11 @@
import argparse
import yaml
import gitlab
import datetime
import logging as log
import csv
import secrets
class Deadline(yaml.YAMLObject):
"""A deadline"""
yaml_tag = 'Deadline'
def __init__(self, tag, time, ref):
self.tag = tag
self.time = time
self.ref = ref
def trigger(self, project):
"""Create protected tag on ref"""
print('Creating tag %s' % self.tag)
project.tags.create({
'tag_name': self.tag,
'ref': self.ref
})
def test(self):
return self.time < datetime.date.today()
import subprocess
import os
class Course(yaml.YAMLObject):
@ -86,30 +63,6 @@ class Course(yaml.YAMLObject):
}
self.base.commits.create(data)
def sync_plagiates(self, gl, ref):
"""Does not work"""
pass
self.group = self.sync_group(gl)
found = self.group.projects.list(search=self.plagiates)
if len(found) == 0:
self.plagiates = gl.projects.create({
'name': self.plagiates,
'namespace_id': self.group.id,
'visibility': 'private'
})
log.info('%s: Created project plagiates repo' % self.name)
else:
self.plagiates = gl.projects.get(found[0].id)
projects = self.group.projects.list()
for project in projects:
if project.name != self.plagiates.name:
# TODO
pass
plagiates.add_submodule(project)
def sync_projects(self, gl):
self.sync_base(gl)
@ -200,21 +153,15 @@ def sync_project(gl, course, student):
project.save()
def deadlines(gl, conf, args):
"""Checks deadlines for course and triggers deadline if it is reached"""
def create_tag(project, tag, ref):
"""Create protected tag on ref"""
for course in conf['courses']:
group = gl.groups.list(search=course.name)[0]
course.group = gl.groups.get(group.id)
for project in course.group.projects.list(all=True):
project = gl.projects.get(project.id)
print(project.name)
for deadline in course.deadlines:
if deadline.test():
try:
deadline.trigger(project)
except gitlab.exceptions.GitlabCreateError as e:
print(e)
print('Project %s. Creating tag %s' % (project.name, tag))
project.tags.create({
'tag_name': tag,
'ref': ref
})
def sync(gl, conf, args):
@ -224,15 +171,13 @@ def sync(gl, conf, args):
one-way sync!!!
"""
for course in conf['courses']:
course = conf['course']
print(course.name)
course.group = course.sync_group(gl)
course.sync_base(gl)
with open(course.students, encoding='latin1') as csvfile:
for student in Student.from_csv(csvfile):
print(student.user)
try:
student.user = student.sync_user(gl, conf['ldap'])
print("%s %s" % (student.user.username, student.user.name))
@ -241,13 +186,8 @@ def sync(gl, conf, args):
log.warn(e)
def plagiates(gl, conf, args):
for course in conf['courses']:
course.sync_plagiates(gl, args.exercise)
def list_projects(gl, conf, args):
groups = gl.groups.list(search=args.course)
groups = gl.groups.list(search=conf['course']['name'])
print(groups)
if len(groups) == 0:
pass
@ -258,8 +198,46 @@ def list_projects(gl, conf, args):
print(project.ssh_url_to_repo)
def get_base_project(gl, conf, args):
return conf['course']['base']
def deadline(gl, conf, args):
"""Checks deadlines for course and triggers deadline if it is reached"""
deadline_name = args.deadline_name
course = conf['course']
group = gl.groups.list(search=course.name)[0]
course.group = gl.groups.get(group.id)
for project in course.group.projects.list(all=True):
project = gl.projects.get(project.id)
print(project.name)
try:
create_tag(project, deadline_name, 'master')
except gitlab.exceptions.GitlabCreateError as e:
print(e)
def plagiates(gl, conf, args):
groups = gl.groups.list(search=conf['course']['name'])
tag = args.deadline_name
print(groups)
if len(groups) == 0:
pass
for g in groups:
if g.name == args.course:
os.mkdir('results')
for project in g.projects.list(all=True):
project = gl.projects.get(project.id)
subprocess.run(
['git', 'clone', '--branch', tag, project.ssh_url_to_repo, 'repos'])
subprocess.run(
['java', '-jar', '/jplag/jplag.jar', '-s', 'repos', '-p', 'java', '-r', 'results', '-bc', '$BASECODE', '-l', 'java18'])
def parseconf(conf):
"""Reads courses from config file"""
"""Reads course from config file"""
with open(args.config[0], 'r') as conf:
return yaml.load(conf)
@ -282,18 +260,18 @@ if __name__ == '__main__':
help='students and courses from Stud.IP and LDAP')
sync_parser.set_defaults(func=sync)
deadline_parser = subparsers.add_parser('deadlines',
description='trigger deadlines')
deadline_parser.set_defaults(func=deadlines)
plagiates_parser = subparsers.add_parser('plagiates', description='sync plagiates')
plagiates_parser.set_defaults(func=plagiates)
plagiates_parser.add_argument('exercise', default='master')
projects_parser = subparsers.add_parser('projects', description='list projects for course')
projects_parser = subparsers.add_parser(
'projects',
description='list projects for course')
projects_parser.set_defaults(func=list_projects)
projects_parser.add_argument('course')
deadline_parser = subparsers.add_parser(
'deadline',
description='set tags at deadline')
deadline_parser.set_defaults(func=deadline)
deadline_parser.add_argument('deadline_name')
args = parser.parse_args()
conf = parseconf(args.config)

View file

@ -1,13 +1,8 @@
ldap:
basedn: "ou=people,dc=tu-bs,dc=de"
provider: main
courses:
- !!python/object:abgabesystem.Course
course:
!!python/object:abgabesystem.Course
name: test_course
base: test_base
students: Students.csv
deadlines:
- !!python/object:abgabesystem.Deadline
tag: test_deadline
time: !!timestamp 2018-04-29
ref: master

View file

@ -25,3 +25,4 @@ service-factory==0.1.5
six==1.11.0
urllib3==1.22
Werkzeug==0.14.1
yq==2.3.4

205
tubs_checks.xml Normal file
View file

@ -0,0 +1,205 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<!--
Checkstyle configuration that checks the sun coding conventions from:
- the Java Language Specification at
http://java.sun.com/docs/books/jls/second_edition/html/index.html
- the Sun Code Conventions at http://java.sun.com/docs/codeconv/
- the Javadoc guidelines at
http://java.sun.com/j2se/javadoc/writingdoccomments/index.html
- the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html
- some best practices
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
Most Checks are configurable, be sure to consult the documentation.
To completely disable a check, just comment it out or delete it from the file.
Finally, it is worth reading the documentation.
-->
<module name="Checker">
<!-- Checks that a package.html file exists for each package. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html#PackageHtml -->
<!-- <module name="PackageHtml"/> -->
<!-- Checks whether files end with a new line. -->
<!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
<!--module name="NewlineAtEndOfFile">
<property name="fileExtensions" value="java"/>
</module-->
<!-- Checks that property files contain the same keys. -->
<!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
<!--module name="Translation"/-->
<module name="FileLength"/>
<!-- keine tabs erlauben -->
<!--module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module-->
<!-- <module name="JavadocPackage"/> -->
<module name="TreeWalker">
<property name="tabWidth" value="4"/>
<!-- Strings werden nicht mit == oder != verglichen -->
<module name="StringLiteralEquality"/>
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocStyle">
<property name="scope" value="private"/>
<property name="excludeScope" value="package"/>
<property name="checkFirstSentence" value="false"/>
<property name="checkEmptyJavadoc" value="true"/>
</module>
<module name="JavadocMethod">
<property name="allowMissingPropertyJavadoc" value="true"/>
<property name="scope" value="package"/>
<property name="ignoreMethodNamesRegex" value="^main$"/>
</module>
<module name="JavadocType">
<property name="authorFormat" value="^.+ [0-9]{7}\s+(Gruppe|[gG]roup)\s+[1-9][0-9]?[a-zA-Z]?" />
</module>
<module name="JavadocVariable">
<property name="scope" value="public"/>
<property name="tokens" value="VARIABLE_DEF"/>
</module>
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName"/>
<!-- <module name="LocalFinalVariableName"/> -->
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for Headers -->
<!-- See http://checkstyle.sf.net/config_header.html -->
<!-- <module name="Header"> -->
<!-- The follow property value demonstrates the ability -->
<!-- to have access to ANT properties. In this case it uses -->
<!-- the ${basedir} property to allow Checkstyle to be run -->
<!-- from any directory within a project. See property -->
<!-- expansion, -->
<!-- http://checkstyle.sf.net/config.html#properties -->
<!-- <property -->
<!-- name="headerFile" -->
<!-- value="${basedir}/java.header"/> -->
<!-- </module> -->
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<!-- <module name="AvoidStarImport"/> -->
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<!-- module name="MethodLength"/ -->
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<!-- module name="EmptyForInitializerPad">
<property name="option" value="space"/>
</module -->
<!-- module name="EmptyForIteratorPad">
<property name="option" value="space"/>
</module -->
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<!-- module name="ModifierOrder"/ -->
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<!-- module name="AvoidNestedBlocks"/ -->
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<!-- <module name="AvoidInlineConditionals"/> -->
<module name="EmptyStatement"/>
<!-- <module name="EqualsHashCode"/> -->
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<!-- module name="MissingSwitchDefault"/-->
<!-- module name="FallThrough"/-->
<module name="DefaultComesLast"/>
<module name="OneStatementPerLine"/>
<!-- <module name="StringLiteralEquality"/> -->
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!-- <module name="DesignForExtension"/> -->
<module name="FinalClass"/>
<!-- <module name="FinalLocalVariable"/> -->
<!-- <module name="HideUtilityClassConstructor"/> -->
<module name="LineLength">
<property name="max" value="150"/>
</module>
<module name="VisibilityModifier"/>
<!-- module name="DeclarationOrder"/ -->
<!-- <module name="RequireThis"/> -->
<!-- module name="RequireThis">
<property name="checkFields" value="false"/>
<property name="checkMethods" value="false"/>
</module -->
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle"/>
<module name="GenericWhitespace"/>
<module name="TodoComment"/>
<module name="UpperEll"/>
<module name="Indentation"> <!-- einrueckung von 4 leerzeichen -->
<property name="basicOffset" value="4"/>
<property name="caseIndent" value="4"/>
</module>
<!-- <module name="CyclomaticComplexity"> -->
<!-- <property name="max" value="7"/> -->
<!-- </module> -->
<module name="IllegalCatch"/>
<module name="IllegalThrows"/>
</module>
</module>