def force_remove_path_side_effect(path): # we need to delete the path, or tests followed will fail force_remove_path(path) raise OSError("my os error")
def set_up_new_course(request): # type: (http.HttpRequest) -> http.HttpResponse if request.method == "POST": form = CourseCreationForm(request.POST) if form.is_valid(): new_course = form.save(commit=False) from course.content import get_course_repo_path repo_path = get_course_repo_path(new_course) try: import os os.makedirs(repo_path) repo = None try: with transaction.atomic(): repo = Repo.init(repo_path) client, remote_path = \ get_dulwich_client_and_remote_path_from_course( new_course) fetch_pack_result = client.fetch(remote_path, repo) if not fetch_pack_result.refs: raise RuntimeError( _("No refs found in remote repository" " (i.e. no master branch, no HEAD). " "This looks very much like a blank repository. " "Please create course.yml in the remote " "repository before creating your course.")) transfer_remote_refs(repo, fetch_pack_result) new_sha = repo[b"HEAD"] = fetch_pack_result.refs[ b"HEAD"] vrepo = repo if new_course.course_root_path: from course.content import SubdirRepoWrapper vrepo = SubdirRepoWrapper( vrepo, new_course.course_root_path) from course.validation import validate_course_content validate_course_content( # type: ignore vrepo, new_course.course_file, new_course.events_file, new_sha) del vrepo new_course.active_git_commit_sha = new_sha.decode() new_course.save() # {{{ set up a participation for the course creator part = Participation() part.user = request.user part.course = new_course part.status = participation_status.active part.save() part.roles.set([ # created by signal handler for course creation ParticipationRole.objects.get( course=new_course, identifier="instructor") ]) # }}} messages.add_message( request, messages.INFO, _("Course content validated, creation " "succeeded.")) except Exception as e: # Don't coalesce this handler with the one below. We only want # to delete the directory if we created it. Trust me. # Make sure files opened for 'repo' above are actually closed. if repo is not None: # noqa repo.close() # noqa from relate.utils import force_remove_path try: force_remove_path(repo_path) except OSError: messages.add_message( request, messages.WARNING, gettext("Failed to delete unused " "repository directory '%s'.") % repo_path) # We don't raise the OSError thrown by force_remove_path # This is to ensure correct error msg for PY2. raise e else: assert repo is not None repo.close() except Exception as e: from traceback import print_exc print_exc() messages.add_message( request, messages.ERROR, string_concat(_("Course creation failed"), ": %(err_type)s: %(err_str)s") % { "err_type": type(e).__name__, "err_str": str(e) }) else: return redirect("relate-course_page", new_course.identifier) else: form = CourseCreationForm() return render(request, "generic-form.html", { "form_description": _("Set up new course"), "form": form })