init.py 4.88 KB
Newer Older
Alan Marchiori's avatar
initial  
Alan Marchiori committed
1
2
3
4
5
import click
import os
import os.path
import config
import config.validation as validation
Alan Marchiori's avatar
Alan Marchiori committed
6
7
import shutil
from config.echo import *
Alan Marchiori's avatar
initial  
Alan Marchiori committed
8
from utils.gitlab import GitLab
Alan Marchiori's avatar
Alan Marchiori committed
9
import courses
Alan Marchiori's avatar
initial  
Alan Marchiori committed
10
11
12
13
14
15
16
17
18
19

@click.command()
@click.argument('course', callback=validation.course)
@click.argument('section', callback=validation.section)
@click.argument('semester', callback=validation.semester)
def init(course, semester, section):
    """Initializes the lab tool structure on your local system
    and on gitlab for a given COURSE, SECTION, and SEMESTER. Example: init CSCI206 S20 61.
    """

Alan Marchiori's avatar
Alan Marchiori committed
20
21
22
23
24
    coursedef = courses.all[config.course_objf_fmt.format(
                course=course,
                semester=semester,
                section=section)]

Alan Marchiori's avatar
initial  
Alan Marchiori committed
25
26
27
28
29
30
31
32
33
34
    coursename = config.course_name_fmt.format(
                course=course,
                semester=semester,
                section=section)

    lp = os.path.expanduser(config.local_home.format(
                course=course,
                semester=semester,
                section=section))

Alan Marchiori's avatar
Alan Marchiori committed
35
    if confirm("Initialize {} into {}?".format(coursename, lp)):
Alan Marchiori's avatar
initial  
Alan Marchiori committed
36
        labdir = os.path.join(lp, config.labs_subdir)
Alan Marchiori's avatar
Alan Marchiori committed
37
38
39
40
41
42
43
44

        if os.path.exists(lp):
            # prompt to wipe it.
            warn("The path already exists!")
            if warn_confirm("Would you like me to WIPE {} and re-create (this will DELETE ALL files)".format(lp)):
                shutil.rmtree(lp)
                success("Deleted {}".format(lp))

Alan Marchiori's avatar
initial  
Alan Marchiori committed
45
46
47
48
49
50
        if not os.path.exists(lp):
            # make the root folder, plus the labs subfolder
            # ensure permissions are not globally readable
            for d in [lp, labdir]:
                os.makedirs(d)
                os.chmod(d,mode=0o0770)
Alan Marchiori's avatar
Alan Marchiori committed
51
            success("Created {}".format(lp))
Alan Marchiori's avatar
initial  
Alan Marchiori committed
52
        else:
Alan Marchiori's avatar
Alan Marchiori committed
53
            warn("Skipping directory creation.")
Alan Marchiori's avatar
initial  
Alan Marchiori committed
54
55
56
57
58
59
60
61

        with config.UserConfig() as uc:
            uc.add_course(
                name=coursename,
                path=labdir)

            gl = GitLab()
            while not 'api_token' in uc.cfg or not gl.check_token():
Alan Marchiori's avatar
Alan Marchiori committed
62
                api_token = prompt("Got to {} and create a personal access token with the \"api scope\" checked. Copy-paste the value here".format(
Alan Marchiori's avatar
initial  
Alan Marchiori committed
63
64
65
66
67
68
69
70
                    config.gitlab_api_token_url
                ))
                uc.add_string(
                    name='api_token',
                    value=api_token
                )
                # needed to refresh the new token cached in the GitLab module
                gl = GitLab()
Alan Marchiori's avatar
Alan Marchiori committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

            # check if it already exists
            p = gl.search_for_project(coursename)
            if len(p) > 0:
                for prj in p:
                    if warn_confirm(
                        "Gitlab repo \"{}\" already exists--should I DELETE it?".format(
                            prj['name_with_namespace'])):
                        if gl.remove_project(prj['id']):
                            success("Removed \"{}\"".format(prj['name_with_namespace']))
                        else:
                            error("Failed to remove \"{}\"".format(prj['name_with_namespace']))
                # try again
                p = gl.search_for_project(coursename)

            if len(p) == 0:
                repo = gl.create_project(coursename)
                if 'id' in repo:
                    success("Created gitlab repo \"{}\" at {}".format(
                        repo['name_with_namespace'],
                        repo['web_url']))

            # try again (2nd time)
            p = gl.search_for_project(coursename)
            if len(p) == 1:
                repo = p[0]
                # add members
                for name in coursedef['instructors'] + coursedef['tas']:
                    uobj = gl.get_users(username=name)
                    if len(uobj)==0:
                        warn('No gitlab user "{}" found!.'.format(name))
                    elif len(uobj)==1:
                        mem = gl.add_member_to_project(
                            repo['id'],
                            uobj[0]['id'],
                            40)
                        if mem:
                            success("Added {}, {} ({}) to \"{}\"".format(
                                mem['name'],
                                mem['username'],
                                mem['id'],
                                repo['name_with_namespace']
                            ))
                        else:
                            warn("Adding member {}, {} ({}) to \"{}\" failed.".format(
                                uobj[0]['name'],
                                uobj[0]['username'],
                                uobj[0]['id'],
                                repo['name_with_namespace']
                            ))
                    else: warn('Cannot add member -- multiple gitlab accounts for {}: {}'.format(
                        name, uobj))
            else:
                warn("Skipped repo creation and member addition.")