package main
import (
"context"
"flag"
"fmt"
"log"
"os"
"code.gitea.io/sdk/gitea"
)
func main() {
baseURL := flag.String("base-url", os.Getenv("GITEA_BASE_URL"), "Gitea base URL, e.g. https://gitea.example.com")
token := flag.String("token", os.Getenv("GITEA_TOKEN"), "Gitea API token")
doDelete := flag.Bool("delete", false, "Actually delete empty repos (default is dry-run)")
pageSize := flag.Int("page-size", 50, "Number of repos to fetch per page")
flag.Parse()
if *baseURL == "" {
log.Fatal("base URL must be provided via -base-url or GITEA_BASE_URL")
}
if *token == "" {
log.Fatal("token must be provided via -token or GITEA_TOKEN")
}
client, err := gitea.NewClient(*baseURL, gitea.SetToken(*token))
if err != nil {
log.Fatalf("failed to create Gitea client: %v", err)
}
// Optional: set a context (useful if you want timeouts/cancellation)
client.SetContext(context.Background())
var emptyRepos []*gitea.Repository
page := 1
for {
repos, resp, err := client.ListMyRepos(gitea.ListReposOptions{
ListOptions: gitea.ListOptions{
Page: page,
PageSize: *pageSize,
},
})
if err != nil {
log.Fatalf("failed to list repos (page %d): %v", page, err)
}
if len(repos) == 0 {
break
}
for _, r := range repos {
if r.Empty {
emptyRepos = append(emptyRepos, r)
}
}
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
}
if len(emptyRepos) == 0 {
fmt.Println("No empty repositories found.")
return
}
fmt.Printf("Found %d empty repositories:\n", len(emptyRepos))
for _, r := range emptyRepos {
owner := ""
if r.Owner != nil {
owner = r.Owner.UserName
}
fmt.Printf("- %s/%s (ID=%d)\n", owner, r.Name, r.ID)
}
if !*doDelete {
fmt.Println("\nDry run only. Re-run with -delete to actually delete these repos.")
return
}
fmt.Println("\nDeleting empty repositories...")
for _, r := range emptyRepos {
if r.Owner == nil {
fmt.Printf("Skipping repo ID=%d (%s): missing owner info\n", r.ID, r.Name)
continue
}
owner := r.Owner.UserName
fmt.Printf("Deleting %s/%s... ", owner, r.Name)
if _, err := client.DeleteRepo(owner, r.Name); err != nil {
fmt.Printf("ERROR: %v\n", err)
continue
}
fmt.Println("OK")
}
fmt.Println("Done.")
}