Rewrite using one docker container
This commit is contained in:
parent
3b81958e12
commit
8a397c79ce
6 changed files with 325 additions and 110 deletions
|
@ -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
12
Dockerfile
Normal 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
|
142
abgabesystem.py
142
abgabesystem.py
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
205
tubs_checks.xml
Normal 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>
|
Loading…
Add table
Add a link
Reference in a new issue