mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in NOTICE, alongside LICENSE. The header lint accepts any copyright line above the SPDX line, so it no longer demands an upstream one. Co-authored-by: Hanzo Dev <[email protected]>
166 lines
3.7 KiB
Go
166 lines
3.7 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/hanzoai/git/models/db"
|
|
repo_model "github.com/hanzoai/git/models/repo"
|
|
"github.com/hanzoai/git/modules/git"
|
|
"github.com/hanzoai/git/modules/gitrepo"
|
|
"github.com/hanzoai/git/modules/log"
|
|
repo_module "github.com/hanzoai/git/modules/repository"
|
|
|
|
"github.com/urfave/cli/v3"
|
|
)
|
|
|
|
func newAdminCommand() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "admin",
|
|
Usage: "Perform common administrative operations",
|
|
Commands: []*cli.Command{
|
|
newUserCommand(),
|
|
newRepoSyncReleasesCommand(),
|
|
newRegenerateCommand(),
|
|
newAuthCommand(),
|
|
newSendMailCommand(),
|
|
},
|
|
}
|
|
}
|
|
|
|
func newRepoSyncReleasesCommand() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "repo-sync-releases",
|
|
Usage: "Synchronize repository releases with tags",
|
|
Action: runRepoSyncReleases,
|
|
}
|
|
}
|
|
|
|
func newRegenerateCommand() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "regenerate",
|
|
Usage: "Regenerate specific files",
|
|
Commands: []*cli.Command{
|
|
newRegenerateHooksCommand(),
|
|
newRegenerateKeysCommand(),
|
|
},
|
|
}
|
|
}
|
|
|
|
func newAuthCommand() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "auth",
|
|
Usage: "Modify external auth providers",
|
|
Commands: []*cli.Command{
|
|
newAuthListCommand(),
|
|
newAuthDeleteCommand(),
|
|
},
|
|
}
|
|
}
|
|
|
|
func newSendMailCommand() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "sendmail",
|
|
Usage: "Send a message to all users",
|
|
Action: runSendMail,
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "title",
|
|
Usage: "a title of a message",
|
|
Required: true,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "content",
|
|
Usage: "a content of a message",
|
|
Value: "",
|
|
},
|
|
&cli.BoolFlag{
|
|
Name: "force",
|
|
Aliases: []string{"f"},
|
|
Usage: "A flag to bypass a confirmation step",
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func idFlag() *cli.Int64Flag {
|
|
return &cli.Int64Flag{
|
|
Name: "id",
|
|
Usage: "ID of authentication source",
|
|
}
|
|
}
|
|
|
|
func runRepoSyncReleases(ctx context.Context, _ *cli.Command) error {
|
|
if err := initDB(ctx); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := git.InitSimple(); err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Trace("Synchronizing repository releases (this may take a while)")
|
|
for page := 1; ; page++ {
|
|
repos, count, err := repo_model.SearchRepositoryByName(ctx, repo_model.SearchRepoOptions{
|
|
ListOptions: db.ListOptions{
|
|
PageSize: repo_model.RepositoryListDefaultPageSize,
|
|
Page: page,
|
|
},
|
|
Private: true,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("SearchRepositoryByName: %w", err)
|
|
}
|
|
if len(repos) == 0 {
|
|
break
|
|
}
|
|
log.Trace("Processing next %d repos of %d", len(repos), count)
|
|
for _, repo := range repos {
|
|
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RelativePath())
|
|
gitRepo, err := gitrepo.OpenRepository(ctx, repo)
|
|
if err != nil {
|
|
log.Warn("OpenRepository: %v", err)
|
|
continue
|
|
}
|
|
|
|
oldnum, err := getReleaseCount(ctx, repo.ID)
|
|
if err != nil {
|
|
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
|
}
|
|
log.Trace(" currentNumReleases is %d, running SyncReleasesWithTags", oldnum)
|
|
|
|
if _, err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
|
|
log.Warn(" SyncReleasesWithTags: %v", err)
|
|
gitRepo.Close()
|
|
continue
|
|
}
|
|
|
|
count, err = getReleaseCount(ctx, repo.ID)
|
|
if err != nil {
|
|
log.Warn(" GetReleaseCountByRepoID: %v", err)
|
|
gitRepo.Close()
|
|
continue
|
|
}
|
|
|
|
log.Trace("repo %s releases synchronized to tags: from %d to %d",
|
|
repo.FullName(), oldnum, count)
|
|
gitRepo.Close()
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getReleaseCount(ctx context.Context, id int64) (int64, error) {
|
|
return db.Count[repo_model.Release](
|
|
ctx,
|
|
repo_model.FindReleasesOptions{
|
|
RepoID: id,
|
|
IncludeTags: true,
|
|
},
|
|
)
|
|
}
|