1//go:build ignore
2
3package main
4
5import (
6 "archive/tar"
7 "compress/gzip"
8 "flag"
9 "fmt"
10 "io"
11 "log"
12 "net/http"
13 "os"
14 "path"
15 "path/filepath"
16 "strings"
17
18 "forgejo.org/modules/util"
19)
20
21func main() {
22 var (
23 prefix = "gitea-gitignore"
24 url = "https://api.github.com/repos/github/gitignore/tarball"
25 githubApiToken = ""
26 githubUsername = ""
27 destination = ""
28 )
29
30 flag.StringVar(&destination, "dest", "options/gitignore/", "destination for the gitignores")
31 flag.StringVar(&githubUsername, "username", "", "github username")
32 flag.StringVar(&githubApiToken, "token", "", "github api token")
33 flag.Parse()
34
35 file, err := os.CreateTemp(os.TempDir(), prefix)
36 if err != nil {
37 log.Fatalf("Failed to create temp file. %s", err)
38 }
39
40 defer util.Remove(file.Name())
41
42 req, err := http.NewRequest("GET", url, nil)
43 if err != nil {
44 log.Fatalf("Failed to download archive. %s", err)
45 }
46
47 if len(githubApiToken) > 0 && len(githubUsername) > 0 {
48 req.SetBasicAuth(githubUsername, githubApiToken)
49 }
50
51 resp, err := http.DefaultClient.Do(req)
52 if err != nil {
53 log.Fatalf("Failed to download archive. %s", err)
54 }
55 defer resp.Body.Close()
56
57 if _, err := io.Copy(file, resp.Body); err != nil {
58 log.Fatalf("Failed to copy archive to file. %s", err)
59 }
60
61 if _, err := file.Seek(0, 0); err != nil {
62 log.Fatalf("Failed to reset seek on archive. %s", err)
63 }
64
65 gz, err := gzip.NewReader(file)
66 if err != nil {
67 log.Fatalf("Failed to gunzip the archive. %s", err)
68 }
69
70 tr := tar.NewReader(gz)
71
72 filesToCopy := make(map[string]string, 0)
73
74 for {
75 hdr, err := tr.Next()
76
77 if err == io.EOF {
78 break
79 }
80
81 if err != nil {
82 log.Fatalf("Failed to iterate archive. %s", err)
83 }
84
85 if filepath.Ext(hdr.Name) != ".gitignore" {
86 continue
87 }
88
89 if hdr.Typeflag == tar.TypeSymlink {
90 fmt.Printf("Found symlink %s -> %s\n", hdr.Name, hdr.Linkname)
91 filesToCopy[strings.TrimSuffix(filepath.Base(hdr.Name), ".gitignore")] = strings.TrimSuffix(filepath.Base(hdr.Linkname), ".gitignore")
92 continue
93 }
94
95 out, err := os.Create(path.Join(destination, strings.TrimSuffix(filepath.Base(hdr.Name), ".gitignore")))
96 if err != nil {
97 log.Fatalf("Failed to create new file. %s", err)
98 }
99
100 defer out.Close()
101
102 if _, err := io.Copy(out, tr); err != nil {
103 log.Fatalf("Failed to write new file. %s", err)
104 } else {
105 fmt.Printf("Written %s\n", out.Name())
106 }
107 }
108
109 for dst, src := range filesToCopy {
110 // Read all content of src to data
111 src = path.Join(destination, src)
112 data, err := os.ReadFile(src)
113 if err != nil {
114 log.Fatalf("Failed to read src file. %s", err)
115 }
116 // Write data to dst
117 dst = path.Join(destination, dst)
118 err = os.WriteFile(dst, data, 0o644)
119 if err != nil {
120 log.Fatalf("Failed to write new file. %s", err)
121 }
122 fmt.Printf("Written (copy of %s) %s\n", src, dst)
123 }
124
125 fmt.Println("Done")
126}