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: stages:
- sync
- deadlines - deadlines
- plagiates - plagiates
before_script: before_script:
- cp python-gitlab.cfg $HOME/.python-gitlab.cfg - cp python-gitlab.cfg $HOME/.python-gitlab.cfg
- echo "private_token = ${PRIVATE_API_TOKEN}" >> $HOME/.python-gitlab.cfg - echo "private_token = ${PRIVATE_API_TOKEN}" >> $HOME/.python-gitlab.cfg
- pip install -r requirements.txt
create_tags: deadlines:
image: python:3
stage: deadlines stage: deadlines
only:
- master
tags: tags:
- abgabesystem - abgabesystem
script: 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 argparse
import yaml import yaml
import gitlab import gitlab
import datetime
import logging as log import logging as log
import csv import csv
import secrets import secrets
import subprocess
import os
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()
class Course(yaml.YAMLObject): class Course(yaml.YAMLObject):
@ -86,30 +63,6 @@ class Course(yaml.YAMLObject):
} }
self.base.commits.create(data) 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): def sync_projects(self, gl):
self.sync_base(gl) self.sync_base(gl)
@ -200,21 +153,15 @@ def sync_project(gl, course, student):
project.save() project.save()
def deadlines(gl, conf, args): def create_tag(project, tag, ref):
"""Checks deadlines for course and triggers deadline if it is reached""" """Create protected tag on ref"""
for course in conf['courses']: print('Project %s. Creating tag %s' % (project.name, tag))
group = gl.groups.list(search=course.name)[0]
course.group = gl.groups.get(group.id) project.tags.create({
for project in course.group.projects.list(all=True): 'tag_name': tag,
project = gl.projects.get(project.id) 'ref': ref
print(project.name) })
for deadline in course.deadlines:
if deadline.test():
try:
deadline.trigger(project)
except gitlab.exceptions.GitlabCreateError as e:
print(e)
def sync(gl, conf, args): def sync(gl, conf, args):
@ -224,30 +171,23 @@ def sync(gl, conf, args):
one-way sync!!! one-way sync!!!
""" """
for course in conf['courses']: course = conf['course']
print(course.name) print(course.name)
course.group = course.sync_group(gl) course.group = course.sync_group(gl)
course.sync_base(gl) course.sync_base(gl)
with open(course.students, encoding='latin1') as csvfile: with open(course.students, encoding='latin1') as csvfile:
for student in Student.from_csv(csvfile): for student in Student.from_csv(csvfile):
print(student.user) try:
student.user = student.sync_user(gl, conf['ldap'])
try: print("%s %s" % (student.user.username, student.user.name))
student.user = student.sync_user(gl, conf['ldap']) sync_project(gl, course, student)
print("%s %s" % (student.user.username, student.user.name)) except gitlab.exceptions.GitlabCreateError as e:
sync_project(gl, course, student) log.warn(e)
except gitlab.exceptions.GitlabCreateError as e:
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): def list_projects(gl, conf, args):
groups = gl.groups.list(search=args.course) groups = gl.groups.list(search=conf['course']['name'])
print(groups) print(groups)
if len(groups) == 0: if len(groups) == 0:
pass pass
@ -258,8 +198,46 @@ def list_projects(gl, conf, args):
print(project.ssh_url_to_repo) 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): def parseconf(conf):
"""Reads courses from config file""" """Reads course from config file"""
with open(args.config[0], 'r') as conf: with open(args.config[0], 'r') as conf:
return yaml.load(conf) return yaml.load(conf)
@ -282,18 +260,18 @@ if __name__ == '__main__':
help='students and courses from Stud.IP and LDAP') help='students and courses from Stud.IP and LDAP')
sync_parser.set_defaults(func=sync) sync_parser.set_defaults(func=sync)
deadline_parser = subparsers.add_parser('deadlines', projects_parser = subparsers.add_parser(
description='trigger deadlines') 'projects',
deadline_parser.set_defaults(func=deadlines) description='list projects for course')
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.set_defaults(func=list_projects) projects_parser.set_defaults(func=list_projects)
projects_parser.add_argument('course') 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() args = parser.parse_args()
conf = parseconf(args.config) conf = parseconf(args.config)

View file

@ -1,13 +1,8 @@
ldap: ldap:
basedn: "ou=people,dc=tu-bs,dc=de" basedn: "ou=people,dc=tu-bs,dc=de"
provider: main provider: main
courses: course:
- !!python/object:abgabesystem.Course !!python/object:abgabesystem.Course
name: test_course name: test_course
base: test_base base: test_base
students: Students.csv 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 six==1.11.0
urllib3==1.22 urllib3==1.22
Werkzeug==0.14.1 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>