Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / mvdan.cc / xurls / v2@v2.2.0 / generate / tldsgen / main.go
1 // Copyright (c) 2015, Daniel Martí <mvdan@mvdan.cc>
2 // See LICENSE for licensing information
3
4 package main
5
6 import (
7         "bufio"
8         "errors"
9         "log"
10         "net/http"
11         "os"
12         "regexp"
13         "sort"
14         "strings"
15         "sync"
16         "text/template"
17 )
18
19 const path = "tlds.go"
20
21 var tldsTmpl = template.Must(template.New("tlds").Parse(`// Generated by tldsgen
22
23 package xurls
24
25 // TLDs is a sorted list of all public top-level domains.
26 //
27 // Sources:{{range $_, $url := .URLs}}
28 //  * {{$url}}{{end}}
29 var TLDs = []string{
30 {{range $_, $tld := .TLDs}}` + "\t`" + `{{$tld}}` + "`" + `,
31 {{end}}}
32 `))
33
34 func cleanTld(tld string) string {
35         tld = strings.ToLower(tld)
36         if strings.HasPrefix(tld, "xn--") {
37                 return ""
38         }
39         return tld
40 }
41
42 func fetchFromURL(url, pat string) {
43         defer wg.Done()
44         log.Printf("Fetching %s", url)
45         resp, err := http.Get(url)
46         if err == nil && resp.StatusCode >= 400 {
47                 err = errors.New(resp.Status)
48         }
49         if err != nil {
50                 errChan <- err
51                 return
52         }
53         defer resp.Body.Close()
54         scanner := bufio.NewScanner(resp.Body)
55         re := regexp.MustCompile(pat)
56         for scanner.Scan() {
57                 line := scanner.Text()
58                 tld := re.FindString(line)
59                 tld = cleanTld(tld)
60                 if tld == "" {
61                         continue
62                 }
63                 tldChan <- tld
64         }
65         if err := scanner.Err(); err != nil {
66                 errChan <- err
67         }
68 }
69
70 var (
71         wg      sync.WaitGroup
72         tldChan = make(chan string)
73         errChan = make(chan error)
74 )
75
76 func tldList() ([]string, []string, error) {
77         var urls []string
78         fromURL := func(url, pat string) {
79                 urls = append(urls, url)
80                 wg.Add(1)
81                 go fetchFromURL(url, pat)
82         }
83         fromURL("https://data.iana.org/TLD/tlds-alpha-by-domain.txt",
84                 `^[^#]+$`)
85         fromURL("https://publicsuffix.org/list/effective_tld_names.dat",
86                 `^[^/.]+$`)
87
88         tldSet := make(map[string]struct{})
89         anyError := false
90         go func() {
91                 for {
92                         select {
93                         case tld := <-tldChan:
94                                 tldSet[tld] = struct{}{}
95                         case err := <-errChan:
96                                 log.Printf("%v", err)
97                                 anyError = true
98                         }
99                 }
100         }()
101         wg.Wait()
102
103         if anyError {
104                 return nil, nil, errors.New("there were some errors while fetching the TLDs")
105         }
106
107         tlds := make([]string, 0, len(tldSet))
108         for tld := range tldSet {
109                 tlds = append(tlds, tld)
110         }
111
112         sort.Strings(tlds)
113         return tlds, urls, nil
114 }
115
116 func writeTlds(tlds, urls []string) error {
117         f, err := os.Create(path)
118         if err != nil {
119                 return err
120         }
121         defer f.Close()
122         return tldsTmpl.Execute(f, struct {
123                 TLDs []string
124                 URLs []string
125         }{
126                 TLDs: tlds,
127                 URLs: urls,
128         })
129 }
130
131 func main() {
132         tlds, urls, err := tldList()
133         if err != nil {
134                 log.Fatalf("Could not get TLD list: %v", err)
135         }
136         log.Printf("Generating %s...", path)
137         if err := writeTlds(tlds, urls); err != nil {
138                 log.Fatalf("Could not write path: %v", err)
139         }
140 }