Personal Git forge.

Code git clone ssh://git.poy.ooo:6969/~poyo/farga ZIP
db/repos.go / 3KiB #3dc8c431
Raw
package dbimport (	"errors"	"farga/db/types"	"farga/lib"	errs "farga/lib/errors"	lib_git "farga/lib/git"	"fmt"	"strings"	"github.com/go-git/go-git/v6"	"github.com/google/uuid"	"gorm.io/gorm/clause")// creates a new repo, both in-DB and on-disk.// it may fail with `errors.ErrRepoAlreadyExists` if the repo exists.// do not forget to close the git repo afterwards.func (db *DB) NewRepo(user types.User, repo types.Repo) (*git.Repository, error) {	branch := user.Config.GitDefaultBranch	if branch == "" {		branch = lib.GitDefaultBranch	}	if repoMeta, err := db.Repo(repo); err == nil && repoMeta.ID != uuid.Nil {		return nil, errs.ErrRepoAlreadyExists // check if it already exists on a DB level.	}	repo.Config = types.RepoConfig{		AllowAnonymousIssues: true, // default		AllowNewIssues:       true, // default	}	// create the record inside the db	err := db.Create(&repo).Error	if err != nil {		if strings.Contains(err.Error(), "UNIQUE constraint") {			return nil, errs.ErrRepoAlreadyExists // shouldn't happen but handle gracefully, just in case.		}		return nil, err	}	// create the actual git repo	gitRepo, err := lib_git.InitRepo(user.ID, repo.ID)	if err != nil {		// cleanup		suberr := db.Where(&repo).Delete(&repo).Error		if suberr != nil {			return nil, fmt.Errorf("init failed: %w; cleanup also failed: %w", err, suberr)		}		return nil, err	}	return gitRepo, nil}func (db *DB) Repo(repo types.Repo) (types.Repo, error) {	err := db.Preload(clause.Associations).Where(&repo).Find(&repo).Error	return repo, err}// gets a repo based off a user's handle and their repo's name.func (db *DB) RepoHandle(userHandle, repoName string) (types.Repo, error) {	var repo types.Repo	err := db.		Preload(clause.Associations).		Joins("JOIN users ON users.id = repos.user_id").		Where("users.handle = ? AND repos.name = ?", userHandle, repoName).		First(&repo).Error	return repo, err}// deletes a repofunc (db *DB) DeleteRepo(repoID uuid.UUID) error {	err := db.Model(&types.Repo{}).Delete(&types.Repo{}, repoID).Error	return err}// gets all repos from a given user.func (db *DB) UserRepos(userId *uuid.UUID) ([]types.Repo, error) {	var repos []types.Repo	err := db.Preload("User").Where(&types.Repo{UserID: userId}).Find(&repos).Error	return repos, err}// updates a given repo's default branchfunc (db *DB) SetRepoDefaultBranch(repo types.Repo, branch string) error {	return db.Model(&repo).Update("base_branch", branch).Error // be careful with other ways to update this since they get rid of EVERYTHING.}// gets a repo by its name and owner's ID.func (db *DB) RepoByName(ownerID *uuid.UUID, name string) (types.Repo, error) {	var repo types.Repo	err := db.Where(&types.Repo{UserID: ownerID, Name: name}).First(&repo).Error	return repo, err}// assigns a hackatime project to a repo. use the hackatime project name. if fed "", it'll be set to NULL.func (db *DB) SetRepoHackatimeName(repoID uuid.UUID, name string) error {	return db.Model(&types.Repo{}).		Where("id = ?", repoID).		Update("hackatime_name", name).		Error}// sets a given repo's visibility, true being public and false being private.func (db *DB) SetRepoVisibility(repoID uuid.UUID, public bool) error {	return db.Model(&types.Repo{}).Where(&types.Repo{UUID_ID: types.UUID_ID{ID: repoID}}).Update("is_private", !public).Error}var ErrEmptyArgument = errors.New("You fed an empty struct.")// updates a repo's configuration regarding Issues.func (db *DB) SetRepoIssueConfig(repoID uuid.UUID, allowAnonymousIssues bool, allowNewIssues bool) error {	cfg := types.RepoConfig{RepoID: repoID}	// if the repo does not have a config, insert one AND retrieve it.	if err := db.Where(&cfg).FirstOrCreate(&cfg).Error; err != nil {		return err	}	// perform the update	return db.Model(&cfg).Updates(map[string]any{		"allow_anonymous_issues": allowAnonymousIssues,		"allow_new_issues":       allowNewIssues,	}).Error}