gogstea/cmd/gogscsv/main.go

193 lines
3.8 KiB
Go
Raw Permalink Normal View History

package main
import (
"context"
"database/sql"
"fmt"
"os"
"os/signal"
"path"
"runtime"
"syscall"
"time"
2025-02-19 18:47:11 +01:00
"gitea.urkob.com/mcr-swiss/gogstea/config"
_ "github.com/go-sql-driver/mysql"
)
func main() {
ctx, cancel := context.WithCancel(signalContext(context.Background()))
defer cancel()
cfgFile := os.Getenv("CONFIG_FILE")
if cfgFile == "" {
// Get root path
_, filename, _, _ := runtime.Caller(0)
cfgFile = path.Join(path.Dir(filename), "configs", "app.yml")
}
cfg, err := config.LoadConfig(cfgFile)
if err != nil {
panic(err)
}
// Connection to db
db, err := sql.Open("mysql", cfg.Gogs.DSN)
if err != nil {
panic(err)
}
// See "Important settings" section.
db.SetConnMaxLifetime(time.Minute * 3)
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)
// Users
if err := func() error {
// create csv file
f, err := os.Create(cfg.Users.CSVPath)
if err != nil {
return err
}
defer f.Close()
rows, err := db.QueryContext(ctx, "SELECT * FROM user WHERE email !=''")
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var (
name string
orgID string
ownerName string
ownerEmail string
)
if err := rows.Scan(&name, &orgID, &ownerName, &ownerEmail); err != nil {
return err
}
// append to csv
if _, err := f.WriteString(fmt.Sprintf("%s,%s,%s,%s\n", name, orgID, ownerName, ownerEmail)); err != nil {
return err
}
}
return nil
}(); err != nil {
panic(err)
}
// Organizations
if err := func() error {
// create csv file
f, err := os.Create(cfg.Organizations.CSVPath)
if err != nil {
return err
}
defer f.Close()
rows, err := db.QueryContext(
ctx,
`SELECT
u.name,
ou.org_id,
uo.name AS owner_name,
uo.email AS owner_email
FROM org_user ou
INNER JOIN user u ON ou.org_id = u.id
INNER JOIN user uo ON uo.id = ou.is_owner`)
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var (
name string
orgID string
ownerName string
ownerEmail string
)
if err := rows.Scan(&name, &orgID, &ownerName, &ownerEmail); err != nil {
return err
}
// append to csv
if _, err := f.WriteString(fmt.Sprintf("%s,%s,%s,%s\n", name, orgID, ownerName, ownerEmail)); err != nil {
return err
}
}
return nil
}(); err != nil {
panic(err)
}
// Collaborators
if err := func() error {
// create csv file
f, err := os.Create(cfg.Collaborators.CSVPath)
if err != nil {
return err
}
defer f.Close()
rows, err := db.QueryContext(
ctx,
`SELECT
r.name AS repo_name,
uo.name AS repo_owner,
u.name AS collaborator_user,
co.mode,
CASE
WHEN co.mode = 1 THEN 'read'
WHEN co.mode = 2 THEN 'write'
WHEN co.mode = 3 THEN 'admin'
WHEN co.mode = 4 THEN 'owner'
ELSE 'failed'
END AS permission
FROM collaboration co
INNER JOIN repository r ON r.id = co.repo_id
INNER JOIN user uo ON uo.id = r.owner_id
INNER JOIN user u ON u.id = co.user_id`)
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var (
repoName string
repoOwner string
collaboratorUser string
mode string
permission string
)
if err := rows.Scan(
&repoName, &repoOwner, &collaboratorUser, &mode, &permission,
); err != nil {
return err
}
// append to csv
if _, err := f.WriteString(fmt.Sprintf("%s,%s,%s,%s,%s\n", repoName, repoOwner, collaboratorUser, mode, permission)); err != nil {
return err
}
}
return nil
}(); err != nil {
panic(err)
}
}
func signalContext(ctx context.Context) context.Context {
ctx, cancel := context.WithCancel(ctx)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigs
signal.Stop(sigs)
close(sigs)
cancel()
}()
return ctx
}