@@ -4,10 +4,11 @@ import (
4
4
"archive/tar"
5
5
"bytes"
6
6
"embed"
7
+ "fmt"
7
8
"io"
8
9
"io/fs"
9
- "path"
10
10
"path/filepath"
11
+ "strings"
11
12
"sync"
12
13
13
14
"github.com/gohugoio/hugo/parser/pageparser"
@@ -26,92 +27,115 @@ var (
26
27
)
27
28
28
29
type Example struct {
29
- ID string `json:"id"`
30
- URL string `json:"url"`
31
- Name string `json:"name"`
32
- Description string `json:"description"`
33
- Markdown string `json:"markdown"`
30
+ ID string `json:"id"`
31
+ URL string `json:"url"`
32
+ Name string `json:"name"`
33
+ Description string `json:"description"`
34
+ Markdown string `json:"markdown"`
35
+ DirectoryPath string `json:"directory_path"`
34
36
}
35
37
36
38
const rootDir = "quickstart"
37
39
38
- // List returns all embedded examples.
39
- func List () ([]Example , error ) {
40
- var returnError error
41
- parseExamples .Do (func () {
42
- files , err := fs .Sub (files , rootDir )
43
- if err != nil {
44
- returnError = xerrors .Errorf ("get example fs: %w" , err )
45
- }
40
+ // WalkForExamples will walk recursively through the examples directory and call
41
+ // exampleDirectory() on each directory that contains a main.tf file.
42
+ func WalkForExamples (files fs.FS , rootDir string , exampleDirectory func (path string )) error {
43
+ return walkDir (exampleDirectory , files , rootDir )
44
+ }
46
45
47
- groups , err := fs .ReadDir (files , "." )
48
- if err != nil {
49
- returnError = xerrors .Errorf ("read dir: %w" , err )
50
- return
51
- }
46
+ func walkDir (exampleDirectory func (path string ), fileFS fs.FS , path string ) error {
47
+ file , err := fileFS .Open (path )
48
+ if err != nil {
49
+ return xerrors .Errorf ("open file %q: %w" , path , err )
50
+ }
51
+ info , err := file .Stat ()
52
+ if err != nil {
53
+ return xerrors .Errorf ("stat file %q: %w" , path , err )
54
+ }
52
55
53
- var dirs []Example
54
- for _ , group := range groups {
55
- if group .IsDir () {
56
- groupDirs , err := fs .Sub (files , filepath .Join (rootDir , group .Name ()))
57
- }
56
+ if info .IsDir () {
57
+ files , err := fs .ReadDir (files , path )
58
+ if err != nil {
59
+ return xerrors .Errorf ("read dir %q: %w" , path , err )
58
60
}
59
61
60
- for true {
61
- for _ , dir := range dirs {
62
- if ! dir . IsDir ( ) {
63
- continue
64
- }
65
- exampleID := dir . Name ()
66
- exampleURL := exampleBasePath + exampleID
67
- // Each one of these is a example!
68
- readme , err := fs . ReadFile ( files , path .Join (dir .Name (), "README.md" ))
62
+ for _ , file := range files {
63
+ n := file . Name ()
64
+ if strings . EqualFold ( file . Name (), "main.tf" ) {
65
+ // This is an example dir
66
+ exampleDirectory ( path )
67
+ return nil
68
+ } else if file . IsDir () {
69
+ fmt . Println ( "walk" , filepath . Join ( path , file . Name ()), n )
70
+ err := walkDir ( exampleDirectory , fileFS , filepath .Join (path , file .Name ()))
69
71
if err != nil {
70
- returnError = xerrors .Errorf ("example %q does not contain README.md" , exampleID )
71
- return
72
+ return err
72
73
}
74
+ }
75
+ }
76
+ }
77
+ return nil
78
+ }
73
79
74
- frontMatter , err := pageparser .ParseFrontMatterAndContent (bytes .NewReader (readme ))
75
- if err != nil {
76
- returnError = xerrors .Errorf ("parse example %q front matter: %w" , exampleID , err )
77
- return
78
- }
80
+ // List returns all embedded examples.
81
+ func List () ([]Example , error ) {
82
+ var returnError error
83
+ parseExamples .Do (func () {
84
+ err := WalkForExamples (files , rootDir , func (path string ) {
85
+ exampleID := filepath .Base (path )
86
+ exampleURL := exampleBasePath + exampleID
87
+ // Each one of these is a example!
88
+ readme , err := fs .ReadFile (files , filepath .Join (path , "README.md" ))
89
+ if err != nil {
90
+ returnError = xerrors .Errorf ("example %q does not contain README.md" , exampleID )
91
+ return
92
+ }
79
93
80
- nameRaw , exists := frontMatter . FrontMatter [ "name" ]
81
- if ! exists {
82
- returnError = xerrors .Errorf ("example %q front matter does not contain name " , exampleID )
83
- return
84
- }
94
+ frontMatter , err := pageparser . ParseFrontMatterAndContent ( bytes . NewReader ( readme ))
95
+ if err != nil {
96
+ returnError = xerrors .Errorf ("parse example %q front matter: %w " , exampleID , err )
97
+ return
98
+ }
85
99
86
- name , valid := nameRaw .( string )
87
- if ! valid {
88
- returnError = xerrors .Errorf ("example %q name isn't a string " , exampleID )
89
- return
90
- }
100
+ nameRaw , exists := frontMatter . FrontMatter [ "name" ]
101
+ if ! exists {
102
+ returnError = xerrors .Errorf ("example %q front matter does not contain name " , exampleID )
103
+ return
104
+ }
91
105
92
- descriptionRaw , exists := frontMatter . FrontMatter [ "description" ]
93
- if ! exists {
94
- returnError = xerrors .Errorf ("example %q front matter does not contain name " , exampleID )
95
- return
96
- }
106
+ name , valid := nameRaw .( string )
107
+ if ! valid {
108
+ returnError = xerrors .Errorf ("example %q name isn't a string " , exampleID )
109
+ return
110
+ }
97
111
98
- description , valid := descriptionRaw .( string )
99
- if ! valid {
100
- returnError = xerrors .Errorf ("example %q description isn't a string " , exampleID )
101
- return
102
- }
112
+ descriptionRaw , exists := frontMatter . FrontMatter [ "description" ]
113
+ if ! exists {
114
+ returnError = xerrors .Errorf ("example %q front matter does not contain name " , exampleID )
115
+ return
116
+ }
103
117
104
- examples = append (examples , Example {
105
- ID : exampleID ,
106
- URL : exampleURL ,
107
- Name : name ,
108
- Description : description ,
109
- Markdown : string (frontMatter .Content ),
110
- })
118
+ description , valid := descriptionRaw .(string )
119
+ if ! valid {
120
+ returnError = xerrors .Errorf ("example %q description isn't a string" , exampleID )
121
+ return
111
122
}
112
- }
113
123
124
+ examples = append (examples , Example {
125
+ ID : exampleID ,
126
+ URL : exampleURL ,
127
+ Name : name ,
128
+ Description : description ,
129
+ Markdown : string (frontMatter .Content ),
130
+ DirectoryPath : path ,
131
+ })
132
+ })
133
+ if err != nil {
134
+ returnError = xerrors .Errorf ("walking embedded files: %w" , err )
135
+ return
136
+ }
114
137
})
138
+
115
139
return examples , returnError
116
140
}
117
141
@@ -125,18 +149,17 @@ func Archive(exampleID string) ([]byte, error) {
125
149
126
150
var selected Example
127
151
for _ , example := range examples {
128
- if example .ID != exampleID {
129
- continue
152
+ if example .ID == exampleID {
153
+ selected = example
154
+ break
130
155
}
131
- selected = example
132
- break
133
156
}
134
157
135
158
if selected .ID == "" {
136
159
return nil , xerrors .Errorf ("example with id %q not found" , exampleID )
137
160
}
138
161
139
- exampleFiles , err := fs .Sub (files , path . Join ( rootDir , exampleID ) )
162
+ exampleFiles , err := fs .Sub (files , selected . DirectoryPath )
140
163
if err != nil {
141
164
return nil , xerrors .Errorf ("get example fs: %w" , err )
142
165
}
0 commit comments