-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgen.go
172 lines (140 loc) · 3.56 KB
/
gen.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package main
import (
"errors"
"flag"
"fmt"
"io"
"io/fs"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/PuerkitoBio/goquery"
)
const (
aocURL = "https://adventofcode.com/%d/day/%d"
template = `package main
import (
"flag"
"fmt"
"log"
"github.com/naisuuuu/aoc2021/input"
)
func main() {
runInput := flag.Bool("i", false, "run on real input (instead of example)")
flag.Parse()
in, err := input.Read("example")
if *runInput {
in, err = input.Read("input")
}
if err != nil {
log.Fatal(err)
}
solve(in)
}
func solve(in []string) {
fmt.Println("Part 1:", in)
}
`
)
func main() {
day := flag.Int("d", 1, "day of AOC")
year := flag.Int("y", 2021, "year of AOC")
flag.Parse()
if err := gen(*day, *year); err != nil {
log.Fatalln("Error", err)
}
}
func gen(day, year int) error {
dir := fmt.Sprintf("day%02d", day)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return fmt.Errorf("creating dir: %w", err)
}
if err := writeTemplate(filepath.Join(dir, "main.go")); err != nil {
return fmt.Errorf("writing template: %w", err)
}
if err := downloadExample(filepath.Join(dir, "example"), year, day); err != nil {
log.Printf("Error downloading example: %v", err)
}
cookie, err := os.ReadFile(".cookie")
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
log.Println(".cookie not found. Input will not be downloaded.")
return nil
}
return fmt.Errorf("reading .cookie: %v", err)
}
if err := downloadInput(
strings.Trim(string(cookie), " \n"),
filepath.Join(dir, "input"),
year, day); err != nil {
return fmt.Errorf("downloading input: %v", err)
}
return nil
}
func downloadInput(cookie, fpath string, year, day int) error {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(aocURL, year, day)+"/input", nil)
if err != nil {
return fmt.Errorf("preparing request: %w", err)
}
req.AddCookie(&http.Cookie{Name: "session", Value: cookie})
res, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("executing request: %w", err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
log.Printf("input download non-200 status code: %d", res.StatusCode)
}
f, err := os.Create(fpath)
if err != nil {
return fmt.Errorf("creating file: %w", err)
}
defer f.Close()
if _, err := io.Copy(f, res.Body); err != nil {
return fmt.Errorf("copying body: %w", err)
}
return nil
}
func downloadExample(fpath string, year, day int) error {
res, err := http.Get(fmt.Sprintf(aocURL, year, day))
if err != nil {
return fmt.Errorf("getting puzzle body: %w", err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
return fmt.Errorf("non-200 status code: %d", res.StatusCode)
}
doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
return fmt.Errorf("parsing puzzle body: %w", err)
}
example := doc.FindMatcher(goquery.Single(".day-desc pre code")).Text()
if len(strings.Trim(example, " \n")) == 0 {
return fmt.Errorf("zero length example: '%s'", example)
}
f, err := os.Create(fpath)
if err != nil {
return fmt.Errorf("creating file: %w", err)
}
defer f.Close()
if _, err := f.WriteString(example); err != nil {
return fmt.Errorf("writing example: %w", err)
}
return nil
}
func writeTemplate(fpath string) error {
_, err := os.Stat(fpath)
if err == nil {
log.Printf("%s already exists. Template will not be written", fpath)
return nil
}
if !errors.Is(err, fs.ErrNotExist) {
return fmt.Errorf("stat %s: %w", fpath, err)
}
if err := os.WriteFile(fpath, []byte(template), 0644); err != nil {
return fmt.Errorf("creating main.go: %w", err)
}
return nil
}