Example #1
0
def open_assignment(conf, args):
    """Adds each student in the roster to their respective homework
    repositories as Developers so they can pull/commit/push their work.
    """
    hw_name = args.name
    host = conf.gitlab_host
    namespace = conf.namespace
    token = conf.token
    semester = conf.semester

    roster = get_filtered_roster(conf.roster, args.section, args.student)

    count = 0
    for student in roster:
        username = student["username"]
        student_section = student["section"]
        full_name = StudentRepo.name(semester, student_section,
                                     hw_name, username)

        try:
            repo = StudentRepo(host, namespace, full_name, token)
            if "id" not in student:
                student["id"] = Repo.get_user_id(username, host, token)

            repo.add_member(student["id"], Access.developer)
            count += 1
        except RepoError:
            logging.warn("Could not add {} to {}.".format(username, full_name))
        except HTTPError:
            raise

    print("Granted access to {} repositories.".format(count))
Example #2
0
def manage_users(args, level):
    if args.dry_run:
        raise NotImplementedError("'--dry-run' is not implemented")
    if args.student:
        raise NotImplementedError("'--student' is not implemented")

    with config(args.config) as conf:
        count = 0
        for student in conf['roster']:
            name = StudentRepo.name(conf['semester'], student['section'], args.name, student['username'])

            if 'id' in student:
                try:
                    repo = StudentRepo(conf['gitlab-host'], conf['namespace'], name, conf['token'])
                    repo.edit_member(student['id'], level)
                    count += 1
                except HTTPError as e:
                    raise
                    if e.response.status_code == 404:
                        logging.warning("Repository %s does not exist.", name)
                    else:
                        raise
            else:
                logging.warning("Student %s does not have a gitlab account.", student['username'])

    print("Changed ", count, " repositories.")
Example #3
0
def assign(args):
    if args.dry_run:
        raise NotImplementedError("'--dry-run' is not implemented")
    if args.student:
        raise NotImplementedError("'--student' is not implemented")

    with config(args.config) as conf, tempfile.TemporaryDirectory() as tmpdirname:
        base = BaseRepo(conf['gitlab-host'], conf['namespace'], args.name, conf['token'])
        base.clone_to(tmpdirname)

        count = 0
        for student in conf['roster']:
            try:
                name = StudentRepo.name(conf['semester'], student['section'], args.name, student['username'])

                repo = StudentRepo(conf['gitlab-host'], conf['namespace'], name, conf['token'])
                repo.info

                logging.warning("Student repository %s already exists.", repo.name)

                if args.force:
                    logging.warning("Deleting...")
                    repo.delete()
                    repo = StudentRepo.new(base, conf['semester'], student['section'], student['username'], conf['token'])
                    repo.push(base)
                    count += 1
                else:
                    logging.warning("Skipping...")

            except HTTPError as e:
                if e.response.status_code == 404:
                    repo = StudentRepo.new(base, conf['semester'], student['section'], student['username'], conf['token'])
                    repo.push(base)
                    count += 1
                else:
                    raise

    print("Assigned homework ", args.name, " to ", count, " students")
Example #4
0
def open_assignment(args):
    with config(args.config) as conf:
        count = 0
        for student in conf['roster']:
            name = StudentRepo.name(conf['semester'], student['section'], args.name, student['username'])

            try:
                repo = StudentRepo(conf['gitlab-host'], conf['namespace'], name, conf['token'])
                if 'id' not in student:
                    student['id'] = Repo.get_user_id(student['username'], conf['gitlab-host'], conf['token'])

                repo.add_member(student['id'], Access.developer)
                count += 1
            except RepoError:
                logging.warn("Could not add %s to %s", student['username'], name)
            except HTTPError as e:
                raise
                if e.response.status_code == 404:
                    logging.warn("Repository %s does not exist.", name)
                else:
                    raise

    print("Granted access to ", count, " repositories")
Example #5
0
def get(args):
    if args.student:
        raise NotImplementedError("'--student' is not implemented")

    with config(args.config) as conf:
        path = os.path.join(args.path, args.name)
        os.makedirs(path, mode=0o700, exist_ok=True)

        count = 0
        for student in conf['roster']:
            name = StudentRepo.name(conf['semester'], student['section'], args.name, student['username'])

            try:
                repo = StudentRepo(conf['gitlab-host'], conf['namespace'], name, conf['token'])
                repo.clone_to(os.path.join(path, student['username']))
                count += 1
            except HTTPError as e:
                if e.response.status_code == 404:
                    logging.warn("Repository %s does not exist.", name)
                else:
                    raise

    print("Cloned ", count, " repositories")
Example #6
0
def manage_users(conf, args, level):
    """Creates a folder for the assignment in the CWD (or <path>, if specified)
    and clones each students' repository into subfolders.
    """
    hw_name = args.name
    dry_run = args.dry_run

    if dry_run:
        raise NotImplementedError("'--dry-run' is not implemented")

    host = conf.gitlab_host
    namespace = conf.namespace
    token = conf.token
    semester = conf.semester

    roster = get_filtered_roster(conf.roster, args.section, args.student)

    count = 0
    for student in roster:
        username = student["username"]
        student_section = student["section"]
        if "id" not in student:
            logging.warning(
                "Student {} does not have a gitlab account.".format(username)
            )
            continue
        full_name = StudentRepo.name(semester, student_section,
                                     hw_name, username)

        try:
            repo = StudentRepo(host, namespace, full_name, token)
            repo.edit_member(student["id"], level)
            count += 1
        except HTTPError:
            raise

    print("Changed {} repositories.".format(count))
Example #7
0
def get(conf, args):
    """Creates a folder for the assignment in the CWD (or <path>, if specified)
    and clones each students' repository into subfolders.
    """
    hw_name = args.name
    hw_path = args.path
    host = conf.gitlab_host
    namespace = conf.namespace
    token = conf.token
    semester = conf.semester

    roster = get_filtered_roster(conf.roster, args.section, args.student)

    path = os.path.join(hw_path, hw_name)
    os.makedirs(path, mode=0o700, exist_ok=True)

    count = 0
    for student in roster:
        username = student["username"]
        student_section = student["section"]
        full_name = StudentRepo.name(semester, student_section,
                                     hw_name, username)

        try:
            repo = StudentRepo(host, namespace, full_name, token)
            repo.clone_to(os.path.join(path, username))
            count += 1
        except RepoError as e:
            logging.warn(str(e))
        except HTTPError as e:
            if e.response.status_code == 404:
                logging.warn("Repository {} does not exist.".format(full_name))
            else:
                raise

    print("Cloned {} repositories.".format(count))
Example #8
0
def manage_repos(conf, args, action):
    """Performs an action (archive|unarchive) on all student repos
    """
    hw_name = args.name
    dry_run = args.dry_run

    if dry_run:
        raise NotImplementedError("'--dry-run' is not implemented")
    if action not in ['archive', 'unarchive']:
        raise ValueError("Unexpected action '{}', accepted actions are 'archive' and 'unarchive'.".format(action))

    host = conf.gitlab_host
    namespace = conf.namespace
    token = conf.token
    semester = conf.semester

    roster = get_filtered_roster(conf.roster, args.section, args.student)

    count = 0
    for student in roster:
        username = student["username"]
        student_section = student["section"]
        if "id" not in student:
            logging.warning(
                "Student {} does not have a gitlab account.".format(username)
            )
            continue
        full_name = StudentRepo.name(semester, student_section,
                                     hw_name, username)

        try:
            repo = StudentRepo(host, namespace, full_name, token)
            if action == 'archive':
                repo.archive()
            else:
                repo.unarchive()
            count += 1
        except HTTPError:
            raise

    print("Changed {} repositories.".format(count))
Example #9
0
def assign(conf, args):
    """Creates homework repositories for an assignment for each student
    in the roster.
    """
    hw_name = args.name
    if args.branch:
        branch = args.branch
    else:
        branch = "master"
    dry_run = args.dry_run
    force = args.force
    host = conf.gitlab_host
    namespace = conf.namespace
    token = conf.token
    semester = conf.semester

    roster = get_filtered_roster(conf.roster, args.section, args.student)

    actual_count = 0  # Represents the number of repos actually pushed to
    student_count = len(roster)

    with tempfile.TemporaryDirectory() as tmpdirname:
        print("Assigning '{}' to {} student{} in {}.".format(
            hw_name, student_count,
            "s" if student_count != 1 else "",
            "section " + args.section if args.section else "all sections")
        )
        base = BaseRepo(host, namespace, hw_name, token)
        if not dry_run:
            base.clone_to(tmpdirname, branch)
        if force:
            logging.warning("Repos will be overwritten.")
        for i, student in enumerate(roster):
            username = student["username"]
            student_section = student["section"]
            full_name = StudentRepo.name(semester, student_section,
                                         hw_name, username)
            repo = StudentRepo(host, namespace, full_name, token)

            print("{}/{} - {}".format(i+1, student_count, full_name))
            if not repo.already_exists():
                if not dry_run:
                    repo = StudentRepo.new(base, semester, student_section,
                                           username, token)
                    repo.push(base, branch)
                actual_count += 1
                logging.debug("Assigned.")
            elif force:
                logging.info("{}: Already exists.".format(full_name))
                logging.info("{}: Deleting...".format(full_name))
                if not dry_run:
                    repo.delete()
                    # HACK: Gitlab will throw a 400 if you delete and immediately recreate a repo.
                    # A bit more than half a second was experimentally determined to prevent this issue.
                    time.sleep(0.55)
                    repo = StudentRepo.new(base, semester, student_section,
                                           username, token)
                    repo.push(base, branch)
                actual_count += 1
                logging.debug("Assigned.")
            elif args.branch:
                logging.info("{}: Already exists.".format(full_name))
                # If we have an explicit branch, push anyways
                repo.push(base, branch) if not dry_run else None
                actual_count += 1
                logging.debug("Assigned.")
            else:
                logging.warning("Skipping...")
            i += 1

    print("Assigned '{}' to {} student{}.".format(
        hw_name,
        actual_count,
        "s" if actual_count != 1 else ""
    ))
    if actual_count == 0:
        logging.warning(
            "Consider using --force if you want to override existing repos."
        )