ronantakizawa/codereview-bench huggingface dataset:
Repository: go-gitea/gitea
File: models/actions/run_job_list.go (Go)

Code before:
// SPDX-License-Identifier: MIT

package actions

import (
	"context"

	"code.gitea.io/gitea/models/db"
	repo_model "code.gitea.io/gitea/models/repo"
	"code.gitea.io/gitea/modules/container"
	"code.gitea.io/gitea/modules/timeutil"

	"xorm.io/builder"
)

type ActionJobList []*ActionRunJob

func (jobs ActionJobList) GetRunIDs() []int64 {
	return container.FilterSlice(jobs, func(j *ActionRunJob) (int64, bool) {
		return j.RunID, j.RunID != 0
	})
}

func (jobs ActionJobList) LoadRepos(ctx context.Context) error {
	repoIDs := container.FilterSlice(jobs, func(j *ActionRunJob) (int64, bool) {
		return j.RepoID, j.RepoID != 0
	})
	if len(repoIDs) == 0 {
		return nil
	}

	repos := make(map[int64]*repo_model.Repository, len(repoIDs))
	if err := db.GetEngine(ctx).In("id", repoIDs).Find(&repos); err != nil {
		return err
	}
	for _, j := range jobs {
		if j.RepoID > 0 && j.Repo == nil {
			j.Repo = repos[j.RepoID]
		}
	}
	return nil
}

func (jobs ActionJobList) LoadRuns(ctx context.Context, withRepo bool) error {
	if withRepo {
		if err := jobs.LoadRepos(ctx); err != nil {
			return err
		}
	}

	runIDs := jobs.GetRunIDs()

Review comment (suggestion):
Per if in line 38, maybe not worth it to change
```suggestion
		return j.RepoID, j.RepoID != 0 && j.Repo == nil
```

Code after:
// SPDX-License-Identifier: MIT

package actions

import (
	"context"

	"code.gitea.io/gitea/models/db"
	repo_model "code.gitea.io/gitea/models/repo"
	"code.gitea.io/gitea/modules/container"
	"code.gitea.io/gitea/modules/timeutil"

	"xorm.io/builder"
)

type ActionJobList []*ActionRunJob

func (jobs ActionJobList) GetRunIDs() []int64 {
	return container.FilterSlice(jobs, func(j *ActionRunJob) (int64, bool) {
		return j.RunID, j.RunID != 0
	})
}

func (jobs ActionJobList) LoadRepos(ctx context.Context) error {
	repoIDs := container.FilterSlice(jobs, func(j *ActionRunJob) (int64, bool) {
		return j.RepoID, j.RepoID != 0 && j.Repo == nil
	})
	if len(repoIDs) == 0 {
		return nil
	}

	repos := make(map[int64]*repo_model.Repository, len(repoIDs))
	if err := db.GetEngine(ctx).In("id", repoIDs).Find(&repos); err != nil {
		return err
	}
	for _, j := range jobs {
		if j.RepoID > 0 && j.Repo == nil {
			j.Repo = repos[j.RepoID]
		}
	}
	return nil
}

func (jobs ActionJobList) LoadRuns(ctx context.Context, withRepo bool) error {
	if withRepo {
		if err := jobs.LoadRepos(ctx); err != nil {
			return err
		}
	}

	runIDs := jobs.GetRunIDs()
Repository: go-gitea/gitea
File: routers/common/qos.go (Go)

Code before:
			} else {
				defer c.Release()
			}

			next.ServeHTTP(w, req)
		})
	}
}

// requestPriority assigns a priority value for a request based upon
// whether the user is logged in and how expensive the endpoint is
func requestPriority(ctx context.Context) Priority {
	// If the user is logged in, assign high priority.
	data := middleware.GetContextData(ctx)
	if _, ok := data[middleware.ContextDataKeySignedUser].(*user_model.User); ok {
		return HighPriority
	}

	rctx := chi.RouteContext(ctx)
	if rctx == nil {
		return DefaultPriority
	}

	// If we're operating in the context of a repo, assign low priority
	routePattern := rctx.RoutePattern()
	if strings.HasPrefix(routePattern, "/{username}/{reponame}") {
		return LowPriority
	}

	return DefaultPriority
}


Review comment (suggestion):
I do not think it is right, if a crawler is heavily visiting the target site, then real anonymous users can't open the repo's home page,  the real users just keep seeing 503 error but can do nothing.

Code after:

			// Release long-polling immediately, so they don't always
			// take up an in-flight request
			if strings.Contains(req.URL.Path, "/user/events") {
				c.Release()
			} else {
				defer c.Release()
			}

			next.ServeHTTP(w, req)
		})
	}
}

// requestPriority assigns a priority value for a request based upon
// whether the user is logged in and how expensive the endpoint is
func requestPriority(ctx context.Context) Priority {
	// If the user is logged in, assign high priority.
	data := middleware.GetContextData(ctx)
	if _, ok := data[middleware.ContextDataKeySignedUser].(*user_model.User); ok {
		return HighPriority
	}

	rctx := chi.RouteContext(ctx)
	if rctx == nil {
		return DefaultPriority
	}

	// If we're operating in the context of a repo, assign low priority
	routePattern := rctx.RoutePattern()
	if strings.HasPrefix(routePattern, "/{username}/{reponame}/") {
		return LowPriority
	}

	return DefaultPriority
}

// renderServiceUnavailable will render an HTTP 503 Service
// Unavailable page, providing HTML if the client accepts it.
func renderServiceUnavailable(w http.ResponseWriter, req *http.Request) {
	acceptsHTML := false
	for _, part := range req.Header["Accept"] {
		if strings.Contains(part, "text/html") {
			acceptsHTML = true
			break
		}
	}

	// If the client doesn't accept HTML, then render a plain text response
	if !acceptsHTML {
		http.Error(w, "503 Service Unavailable", http.StatusServiceUnavailable)
Repository: go-gitea/gitea
File: web_src/js/markup/codecopy.ts (TypeScript)

Code before:
import {svg} from '../svg.ts';
import {queryElems} from '../utils/dom.ts';

export function makeCodeCopyButton(): HTMLButtonElement {
  const button = document.createElement('button');
  button.classList.add('code-copy', 'ui', 'button');
  button.innerHTML = svg('octicon-copy');
  return button;
}

export function initMarkupCodeCopy(elMarkup: HTMLElement): void {
  // .markup .code-block code
  queryElems(elMarkup, '.code-block code', (el) => {
    if (!el.textContent) return;
    const btn = makeCodeCopyButton();
    // remove final trailing newline introduced during HTML rendering
    btn.setAttribute('data-clipboard-text', el.textContent.replace(/\r?\n$/, ''));
    const btnContainer = el.closest('.code-block-container') ?? el.closest('.code-block');
    btnContainer.append(btn);
  });
}


Review comment (suggestion):
```suggestion
    const btnContainer = el.closest('.code-block-container, .code-block');
```

I think this is equivalent, but shorter.

Code after:
import {svg} from '../svg.ts';
import {queryElems} from '../utils/dom.ts';

export function makeCodeCopyButton(): HTMLButtonElement {
  const button = document.createElement('button');
  button.classList.add('code-copy', 'ui', 'button');
  button.innerHTML = svg('octicon-copy');
  return button;
}

export function initMarkupCodeCopy(elMarkup: HTMLElement): void {
  // .markup .code-block code
  queryElems(elMarkup, '.code-block code', (el) => {
    if (!el.textContent) return;
    const btn = makeCodeCopyButton();
    // remove final trailing newline introduced during HTML rendering
    btn.setAttribute('data-clipboard-text', el.textContent.replace(/\r?\n$/, ''));
    // we only want to use `.code-block-container` if it exists, no matter `.code-block` exists or not.
    const btnContainer = el.closest('.code-block-container') ?? el.closest('.code-block');
    btnContainer.append(btn);
  });
}
Repository: go-gitea/gitea
File: modules/badge/badge.go (Go)

Code before:
func (t Text) Width() int {
	return t.width
}

func (t Text) X() int {
	return t.x
}

func (t Text) TextLength() int {
	return int(float64(t.width-defaultOffset) * 10)
}

type Badge struct {
	IDPrefix   string
	FontFamily string
	Color      string
	FontSize   int
	Label      Text
	Message    Text
}

func (b Badge) Width() int {
	return b.Label.width + b.Message.width
}

// styles follows https://shields.io/badges
const (
	StyleFlat       = "flat"
	StyleFlatSquare = "flat-square"
)

const (
	defaultOffset     = 10
	defaultFontSize   = 11
	DefaultColor      = "#9f9f9f" // Grey
	DefaultFontFamily = "DejaVu Sans,Verdana,Geneva,sans-serif"
	DefaultStyle      = StyleFlat
)

var GlobalVars = sync.OnceValue(func() (ret struct {
	StatusColorMap       map[actions_model.Status]string
	DejaVuGlyphWidthData map[rune]uint8
	AllStyles            []string
},
) {
	ret.StatusColorMap = map[actions_model.Status]string{
		actions_model.StatusSuccess:   "#4c1",    // Green
		actions_model.StatusSkipped:   "#dfb317", // Yellow
		actions_model.StatusUnknown:   "#97ca00", // Light Green
		actions_model.StatusFailure:   "#e05d44", // Red
		actions_model.StatusCancelled: "#fe7d37", // Orange

Review comment (suggestion):
```suggestion
// Style follows https://shields.io/badges
```

Code after:
func (t Text) Width() int {
	return t.width
}

func (t Text) X() int {
	return t.x
}

func (t Text) TextLength() int {
	return int(float64(t.width-defaultOffset) * 10)
}

type Badge struct {
	IDPrefix   string
	FontFamily string
	Color      string
	FontSize   int
	Label      Text
	Message    Text
}

func (b Badge) Width() int {
	return b.Label.width + b.Message.width
}

// Style follows https://shields.io/badges
const (
	StyleFlat       = "flat"
	StyleFlatSquare = "flat-square"
)

const (
	defaultOffset     = 10
	defaultFontSize   = 11
	DefaultColor      = "#9f9f9f" // Grey
	DefaultFontFamily = "DejaVu Sans,Verdana,Geneva,sans-serif"
	DefaultStyle      = StyleFlat
)

var GlobalVars = sync.OnceValue(func() (ret struct {
	StatusColorMap       map[actions_model.Status]string
	DejaVuGlyphWidthData map[rune]uint8
	AllStyles            []string
},
) {
	ret.StatusColorMap = map[actions_model.Status]string{
		actions_model.StatusSuccess:   "#4c1",    // Green
		actions_model.StatusSkipped:   "#dfb317", // Yellow
		actions_model.StatusUnknown:   "#97ca00", // Light Green
		actions_model.StatusFailure:   "#e05d44", // Red
		actions_model.StatusCancelled: "#fe7d37", // Orange
Repository: go-gitea/gitea
File: web_src/js/utils/dom.ts (TypeScript)

Code before:
  }
}

export function toggleClass(el: ElementArg, className: string, force?: boolean) {
  elementsCall(el, (e: Element) => {
    if (force === true) {
      e.classList.add(className);
    } else if (force === false) {
      e.classList.remove(className);
    } else if (force === undefined) {
      e.classList.toggle(className);
    } else {
      throw new Error('invalid force argument');
    }
  });
}

/**
 * @param el Element
 * @param force force=true to show or force=false to hide, undefined to toggle
 */
function toggleShown(el: Element, force: boolean) {
  toggleClass(el, 'tw-hidden', !force);
}

export function showElem(el: ElementArg) {
  elementsCall(el, toggleShown, true);
}

export function hideElem(el: ElementArg) {
  elementsCall(el, toggleShown, false);
}

export function toggleElem(el: ElementArg, force?: boolean) {
  elementsCall(el, toggleShown, force);
}

export function isElemHidden(el: ElementArg) {
  const res: boolean[] = [];
  elementsCall(el, (e) => res.push(e.classList.contains('tw-hidden')));
  if (res.length > 1) throw new Error(`isElemHidden doesn't work for multiple elements`);
  return res[0];
}

function applyElemsCallback<T extends Element>(elems: ArrayLikeIterable<T>, fn?: ElementsCallback<T>): ArrayLikeIterable<T> {
  if (fn) {
    for (const el of elems) {
      fn(el);
    }
  }
  return elems;

Review comment (refactor):
`showElem -> elementsCall -> toggleShown -> toggleClass -> elementsCall`

Duplicate call doesn't seem good in this case.

Code after:
  }
}

export function toggleClass(el: ElementArg, className: string, force?: boolean) {
  elementsCall(el, (e: Element) => {
    if (force === true) {
      e.classList.add(className);
    } else if (force === false) {
      e.classList.remove(className);
    } else if (force === undefined) {
      e.classList.toggle(className);
    } else {
      throw new Error('invalid force argument');
    }
  });
}

/**
 * @param el ElementArg
 * @param force force=true to show or force=false to hide, undefined to toggle
 */
export function toggleElem(el: ElementArg, force?: boolean) {
  toggleClass(el, 'tw-hidden', !force);
}

export function showElem(el: ElementArg) {
  toggleElem(el, true);
}

export function hideElem(el: ElementArg) {
  toggleElem(el, false);
}

export function isElemHidden(el: ElementArg) {
  const res: boolean[] = [];
  elementsCall(el, (e) => res.push(e.classList.contains('tw-hidden')));
  if (res.length > 1) throw new Error(`isElemHidden doesn't work for multiple elements`);
  return res[0];
}

function applyElemsCallback<T extends Element>(elems: ArrayLikeIterable<T>, fn?: ElementsCallback<T>): ArrayLikeIterable<T> {
  if (fn) {
    for (const el of elems) {
      fn(el);
    }
  }
  return elems;
}

export function queryElemSiblings<T extends Element>(el: Element, selector = '*', fn?: ElementsCallback<T>): ArrayLikeIterable<T> {
  const elems = Array.from(el.parentNode.children) as T[];
Repository: go-gitea/gitea
File: routers/private/hook_verification.go (Go)

Code before:

func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
	stdoutReader, stdoutWriter, err := os.Pipe()
	if err != nil {
		log.Error("Unable to create pipe for %s: %v", repo.Path, err)
		return err
	}
	defer func() {
		_ = stdoutReader.Close()
		_ = stdoutWriter.Close()
	}()

	commitID := git.MustIDFromString(sha)

	return git.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
		Run(repo.Ctx, &git.RunOpts{
			Env:    env,
			Dir:    repo.Path,
			Stdout: stdoutWriter,
			PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
				_ = stdoutWriter.Close()
				commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
				if err != nil {
					return err
				}
				ctx = cache.WithCacheContext(ctx)
				verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
				if !verification.Verified {
					cancel()
					return &errUnverifiedCommit{
						commit.ID.String(),
					}
				}
				return nil
			},
		})
}

type errUnverifiedCommit struct {
	sha string
}

func (e *errUnverifiedCommit) Error() string {
	return "Unverified commit: " + e.sha
}

func isErrUnverifiedCommit(err error) bool {
	_, ok := err.(*errUnverifiedCommit)
	return ok
}


Review comment (bug):
The design of `WithCacheContext` is wrong.

It will return a out-scope context and lose the current "deadline" or "cancel" control.

Before a correct design, it should never be used anymore.

----

Update: Hmm, maybe misread, will take a deep look

Code after:
func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
	stdoutReader, stdoutWriter, err := os.Pipe()
	if err != nil {
		log.Error("Unable to create pipe for %s: %v", repo.Path, err)
		return err
	}
	defer func() {
		_ = stdoutReader.Close()
		_ = stdoutWriter.Close()
	}()

	commitID := git.MustIDFromString(sha)

	return git.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
		Run(repo.Ctx, &git.RunOpts{
			Env:    env,
			Dir:    repo.Path,
			Stdout: stdoutWriter,
			PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
				_ = stdoutWriter.Close()
				commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
				if err != nil {
					return err
				}
				verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
				if !verification.Verified {
					cancel()
					return &errUnverifiedCommit{
						commit.ID.String(),
					}
				}
				return nil
			},
		})
}

type errUnverifiedCommit struct {
	sha string
}

func (e *errUnverifiedCommit) Error() string {
	return "Unverified commit: " + e.sha
}

func isErrUnverifiedCommit(err error) bool {
	_, ok := err.(*errUnverifiedCommit)
	return ok
}
Repository: go-gitea/gitea
File: routers/private/hook_verification.go (Go)

Code before:

func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
	stdoutReader, stdoutWriter, err := os.Pipe()
	if err != nil {
		log.Error("Unable to create pipe for %s: %v", repo.Path, err)
		return err
	}
	defer func() {
		_ = stdoutReader.Close()
		_ = stdoutWriter.Close()
	}()

	commitID := git.MustIDFromString(sha)

	return git.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
		Run(repo.Ctx, &git.RunOpts{
			Env:    env,
			Dir:    repo.Path,
			Stdout: stdoutWriter,
			PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
				_ = stdoutWriter.Close()
				commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
				if err != nil {
					return err
				}
				ctx = cache.WithCacheContext(ctx)
				verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
				if !verification.Verified {
					cancel()
					return &errUnverifiedCommit{
						commit.ID.String(),
					}
				}
				return nil
			},
		})
}

type errUnverifiedCommit struct {
	sha string
}

func (e *errUnverifiedCommit) Error() string {
	return "Unverified commit: " + e.sha
}

func isErrUnverifiedCommit(err error) bool {
	_, ok := err.(*errUnverifiedCommit)
	return ok
}


Review comment (performance):
The "cache context" should have been provided by some contexts like `RequestContextHandler`, why it needs to create new "cache contexts" again and again?

Code after:
func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
	stdoutReader, stdoutWriter, err := os.Pipe()
	if err != nil {
		log.Error("Unable to create pipe for %s: %v", repo.Path, err)
		return err
	}
	defer func() {
		_ = stdoutReader.Close()
		_ = stdoutWriter.Close()
	}()

	commitID := git.MustIDFromString(sha)

	return git.NewCommand("cat-file", "commit").AddDynamicArguments(sha).
		Run(repo.Ctx, &git.RunOpts{
			Env:    env,
			Dir:    repo.Path,
			Stdout: stdoutWriter,
			PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
				_ = stdoutWriter.Close()
				commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
				if err != nil {
					return err
				}
				verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
				if !verification.Verified {
					cancel()
					return &errUnverifiedCommit{
						commit.ID.String(),
					}
				}
				return nil
			},
		})
}

type errUnverifiedCommit struct {
	sha string
}

func (e *errUnverifiedCommit) Error() string {
	return "Unverified commit: " + e.sha
}

func isErrUnverifiedCommit(err error) bool {
	_, ok := err.(*errUnverifiedCommit)
	return ok
}
Repository: go-gitea/gitea
File: services/migrations/github.go (Go)

Code before:
				ReviewerName: user.GetLogin(),
				State:        base.ReviewStateRequestReview,
				IssueIndex:   reviewable.GetLocalIndex(),
			}
			allReviews = append(allReviews, r)
		}
		// TODO: Handle Team requests
		if resp.NextPage == 0 {
			break
		}
		opt.Page = resp.NextPage
	}
	return allReviews, nil
}

// FormatCloneURL add authentication into remote URLs
func (g *GithubDownloaderV3) FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error) {
	u, err := url.Parse(remoteAddr)
	if err != nil {
		return "", err
	}
	if len(opts.AuthToken) > 0 {
		u.User = url.UserPassword("oauth2", strings.Split(opts.AuthToken, ",")[0])
	}
	return u.String(), nil
}


Review comment (security):
What about this comment?

```suggestion
		// "multiple tokens" are used to benefit more "API rate limit quota"
		// git clone doesn't count for rate limits, so only use the first token.
		u.User = url.UserPassword("oauth2", strings.Split(opts.AuthToken, ",")[0])
```

Code after:
				ReviewerName: user.GetLogin(),
				State:        base.ReviewStateRequestReview,
				IssueIndex:   reviewable.GetLocalIndex(),
			}
			allReviews = append(allReviews, r)
		}
		// TODO: Handle Team requests
		if resp.NextPage == 0 {
			break
		}
		opt.Page = resp.NextPage
	}
	return allReviews, nil
}

// FormatCloneURL add authentication into remote URLs
func (g *GithubDownloaderV3) FormatCloneURL(opts MigrateOptions, remoteAddr string) (string, error) {
	u, err := url.Parse(remoteAddr)
	if err != nil {
		return "", err
	}
	if len(opts.AuthToken) > 0 {
		// "multiple tokens" are used to benefit more "API rate limit quota"
		// git clone doesn't count for rate limits, so only use the first token.
		// source: https://github.com/orgs/community/discussions/44515
		u.User = url.UserPassword("oauth2", strings.Split(opts.AuthToken, ",")[0])
	}
	return u.String(), nil
}
Repository: go-gitea/gitea
File: models/repo/update.go (Go)

Code before:
	return util.ErrAlreadyExist
}

// ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error.
type ErrRepoFilesAlreadyExist struct {
	Uname string
	Name  string
}

// IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist.
func IsErrRepoFilesAlreadyExist(err error) bool {
	_, ok := err.(ErrRepoFilesAlreadyExist)
	return ok
}

func (err ErrRepoFilesAlreadyExist) Error() string {
	return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name)
}

func (err ErrRepoFilesAlreadyExist) Unwrap() error {
	return util.ErrAlreadyExist
}

// CheckCreateRepository check if could created a repository
func CheckCreateRepository(ctx context.Context, doer, u *user_model.User, name string, overwriteOrAdopt bool) error {
	if !u.CanCreateRepo() {
		return ErrReachLimitOfRepo{u.MaxRepoCreation}
	}

	if err := IsUsableRepoName(name); err != nil {
		return err
	}

	has, err := IsRepositoryModelOrDirExist(ctx, u, name)
	if err != nil {
		return fmt.Errorf("IsRepositoryExist: %w", err)
	} else if has {
		return ErrRepoAlreadyExist{u.Name, name}
	}

	repoPath := RepoPath(u.Name, name)
	isExist, err := util.IsExist(repoPath)
	if err != nil {
		log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
		return err
	}
	if !overwriteOrAdopt && isExist {
		return ErrRepoFilesAlreadyExist{u.Name, name}
	}
	return nil
}

Review comment (suggestion):
```suggestion
	if !doer.IsAdmin && !u.CanCreateRepo() {
```
Admin is exempt from the limit checks.

Code after:
	return util.ErrAlreadyExist
}

// ErrRepoFilesAlreadyExist represents a "RepoFilesAlreadyExist" kind of error.
type ErrRepoFilesAlreadyExist struct {
	Uname string
	Name  string
}

// IsErrRepoFilesAlreadyExist checks if an error is a ErrRepoAlreadyExist.
func IsErrRepoFilesAlreadyExist(err error) bool {
	_, ok := err.(ErrRepoFilesAlreadyExist)
	return ok
}

func (err ErrRepoFilesAlreadyExist) Error() string {
	return fmt.Sprintf("repository files already exist [uname: %s, name: %s]", err.Uname, err.Name)
}

func (err ErrRepoFilesAlreadyExist) Unwrap() error {
	return util.ErrAlreadyExist
}

// CheckCreateRepository check if doer could create a repository in new owner
func CheckCreateRepository(ctx context.Context, doer, owner *user_model.User, name string, overwriteOrAdopt bool) error {
	if !doer.CanCreateRepoIn(owner) {
		return ErrReachLimitOfRepo{owner.MaxRepoCreation}
	}

	if err := IsUsableRepoName(name); err != nil {
		return err
	}

	has, err := IsRepositoryModelOrDirExist(ctx, owner, name)
	if err != nil {
		return fmt.Errorf("IsRepositoryExist: %w", err)
	} else if has {
		return ErrRepoAlreadyExist{owner.Name, name}
	}

	repoPath := RepoPath(owner.Name, name)
	isExist, err := util.IsExist(repoPath)
	if err != nil {
		log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
		return err
	}
	if !overwriteOrAdopt && isExist {
		return ErrRepoFilesAlreadyExist{owner.Name, name}
	}
	return nil
}