| 65 | } |
| 66 | |
| 67 | func parseAndVerifyExamples() (examples []codersdk.TemplateExample, err error) { |
| 68 | f, err := files.Open(examplesJSON) |
| 69 | if err != nil { |
| 70 | return nil, xerrors.Errorf("open %s: %w", examplesJSON, err) |
| 71 | } |
| 72 | defer f.Close() |
| 73 | |
| 74 | b := bufio.NewReader(f) |
| 75 | |
| 76 | // Discard the first line (code generated by-comment). |
| 77 | _, _, err = b.ReadLine() |
| 78 | if err != nil { |
| 79 | return nil, xerrors.Errorf("read %s: %w", examplesJSON, err) |
| 80 | } |
| 81 | |
| 82 | err = json.NewDecoder(b).Decode(&examples) |
| 83 | if err != nil { |
| 84 | return nil, xerrors.Errorf("decode %s: %w", examplesJSON, err) |
| 85 | } |
| 86 | |
| 87 | // Sanity-check: Verify that the examples in the JSON file match the |
| 88 | // embedded files. |
| 89 | var wantEmbedFiles []string |
| 90 | for i, example := range examples { |
| 91 | examples[i].URL = exampleBasePath + example.ID |
| 92 | wantEmbedFiles = append(wantEmbedFiles, example.ID) |
| 93 | } |
| 94 | |
| 95 | files, err := fs.Sub(files, rootDir) |
| 96 | if err != nil { |
| 97 | return nil, xerrors.Errorf("get templates fs: %w", err) |
| 98 | } |
| 99 | dirs, err := fs.ReadDir(files, ".") |
| 100 | if err != nil { |
| 101 | return nil, xerrors.Errorf("read templates dir: %w", err) |
| 102 | } |
| 103 | var gotEmbedFiles []string |
| 104 | for _, dir := range dirs { |
| 105 | if dir.IsDir() { |
| 106 | gotEmbedFiles = append(gotEmbedFiles, dir.Name()) |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | slices.Sort(wantEmbedFiles) |
| 111 | slices.Sort(gotEmbedFiles) |
| 112 | want := strings.Join(wantEmbedFiles, ", ") |
| 113 | got := strings.Join(gotEmbedFiles, ", ") |
| 114 | if want != got { |
| 115 | return nil, xerrors.Errorf("mismatch between %s and embedded files: want %q, got %q", examplesJSON, want, got) |
| 116 | } |
| 117 | |
| 118 | return examples, nil |
| 119 | } |
| 120 | |
| 121 | // Archive returns a tar by example ID. |
| 122 | func Archive(exampleID string) ([]byte, error) { |