forked from coder/coder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexamples.go
More file actions
173 lines (147 loc) · 3.89 KB
/
Copy pathexamples.go
File metadata and controls
173 lines (147 loc) · 3.89 KB
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
173
package examples
import (
"archive/tar"
"bytes"
"embed"
"path"
"sync"
"github.com/gohugoio/hugo/parser/pageparser"
"golang.org/x/sync/singleflight"
"golang.org/x/xerrors"
)
var (
//go:embed */*.md
//go:embed */*.tf
files embed.FS
examples = make([]Example, 0)
parseExamples sync.Once
archives = singleflight.Group{}
)
type Example struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Markdown string `json:"markdown"`
}
// List returns all embedded examples.
func List() ([]Example, error) {
var returnError error
parseExamples.Do(func() {
dirs, err := files.ReadDir(".")
if err != nil {
returnError = xerrors.Errorf("read dir: %w", err)
return
}
for _, dir := range dirs {
exampleID := dir.Name()
// Each one of these is a example!
readme, err := files.ReadFile(path.Join(dir.Name(), "README.md"))
if err != nil {
returnError = xerrors.Errorf("example %q does not contain README.md", exampleID)
return
}
frontMatter, err := pageparser.ParseFrontMatterAndContent(bytes.NewReader(readme))
if err != nil {
returnError = xerrors.Errorf("parse example %q front matter: %w", exampleID, err)
return
}
nameRaw, exists := frontMatter.FrontMatter["name"]
if !exists {
returnError = xerrors.Errorf("example %q front matter does not contain name", exampleID)
return
}
name, valid := nameRaw.(string)
if !valid {
returnError = xerrors.Errorf("example %q name isn't a string", exampleID)
return
}
descriptionRaw, exists := frontMatter.FrontMatter["description"]
if !exists {
returnError = xerrors.Errorf("example %q front matter does not contain name", exampleID)
return
}
description, valid := descriptionRaw.(string)
if !valid {
returnError = xerrors.Errorf("example %q description isn't a string", exampleID)
return
}
examples = append(examples, Example{
ID: exampleID,
Name: name,
Description: description,
Markdown: string(frontMatter.Content),
})
}
})
return examples, returnError
}
// Archive returns a tar by example ID.
func Archive(exampleID string) ([]byte, error) {
rawData, err, _ := archives.Do(exampleID, func() (interface{}, error) {
examples, err := List()
if err != nil {
return nil, xerrors.Errorf("list: %w", err)
}
var selected Example
for _, example := range examples {
if example.ID != exampleID {
continue
}
selected = example
break
}
if selected.ID == "" {
return nil, xerrors.Errorf("example with id %q not found", exampleID)
}
entries, err := files.ReadDir(exampleID)
if err != nil {
return nil, xerrors.Errorf("read dir: %w", err)
}
var buffer bytes.Buffer
tarWriter := tar.NewWriter(&buffer)
for _, entry := range entries {
file, err := files.Open(path.Join(exampleID, entry.Name()))
if err != nil {
return nil, xerrors.Errorf("open file: %w", err)
}
info, err := file.Stat()
if err != nil {
return nil, xerrors.Errorf("stat file: %w", err)
}
if info.IsDir() {
continue
}
data := make([]byte, info.Size())
_, err = file.Read(data)
if err != nil {
return nil, xerrors.Errorf("read data: %w", err)
}
header, err := tar.FileInfoHeader(info, entry.Name())
if err != nil {
return nil, xerrors.Errorf("get file header: %w", err)
}
header.Mode = 0644
err = tarWriter.WriteHeader(header)
if err != nil {
return nil, xerrors.Errorf("write file: %w", err)
}
_, err = tarWriter.Write(data)
if err != nil {
return nil, xerrors.Errorf("write: %w", err)
}
}
err = tarWriter.Flush()
if err != nil {
return nil, xerrors.Errorf("flush archive: %w", err)
}
return buffer.Bytes(), nil
})
if err != nil {
return nil, err
}
data, valid := rawData.([]byte)
if !valid {
panic("dev error: data must be a byte slice")
}
return data, nil
}