package main import ( "context" "database/sql" "fmt" "os" "os/signal" "path" "runtime" "syscall" "time" "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 }