Defer inside loop; deferred calls accumulate until the function returns, not until the loop iteration ends. This can cause resource leaks
defer func(file *os.File) {
1// SPDX-License-Identifier: MIT23package main45import (6 "bytes"7 _ "embed"8 "fmt"9 "go/format"10 "maps"11 "os"12 "strconv"13 "strings"14 "text/template"1516 "github.com/boyter/scc/v3/processor"17 jsoniter "github.com/json-iterator/go"18)1920const (21 constantsFile = "./processor/constants.go"22 languagesListFile = "./LANGUAGES.md"23)2425var json = jsoniter.ConfigCompatibleWithStandardLibrary2627//go:embed languages.tmpl28var langTemplate string2930// Reads all .json files in the current folder31// and encodes them as strings literals in constants.go32func generateConstants() error {33 files, _ := os.ReadDir(".")34 buf := &bytes.Buffer{}3536 langs := map[string]processor.Language{}3738 for _, f := range files {39 if strings.HasPrefix(f.Name(), "languages") && strings.HasSuffix(f.Name(), ".json") {40 f, err := os.Open(f.Name())41 if err != nil {42 return fmt.Errorf("failed to open file '%s': %v", f.Name(), err)43 }44 defer func(file *os.File) {45 _ = file.Close()46 }(f)4748 data := map[string]processor.Language{}4950 // validate the json by decoding into an empty struct51 if err := json.NewDecoder(f).Decode(&data); err != nil {52 return fmt.Errorf("failed to validate json in file '%s': %v", f.Name(), err)53 }5455 maps.Insert(langs, maps.All(data))56 }57 }5859 t, err := template.New("codeGenerator").Funcs(template.FuncMap{60 "quote": strconv.Quote,61 }).Parse(langTemplate)62 if err != nil {63 return fmt.Errorf("failed to parse template file: %v", err)64 }6566 if err := t.Execute(buf, langs); err != nil {67 return fmt.Errorf("failed to execute template file: %v", err)68 }6970 source, err := format.Source(buf.Bytes())71 if err != nil {72 return fmt.Errorf("failed to format code: %v", err)73 }7475 out, err := os.OpenFile(constantsFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)76 if err != nil {77 return fmt.Errorf("failed to open constants file: %v", err)78 }79 defer func(file *os.File) {80 _ = file.Close()81 }(out)8283 if _, err := out.Write(source); err != nil {84 return fmt.Errorf("failed to write constants file %v", err)85 }8687 return nil88}8990func generateLanguagesList() error {91 out, err := os.OpenFile(languagesListFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)92 if err != nil {93 return fmt.Errorf("failed to open languages list file: %v", err)94 }95 defer func(file *os.File) {96 _ = file.Close()97 }(out)9899 _, _ = out.WriteString("```\n")100 processor.PrintLanguages(out)101 _, _ = out.WriteString("```\n")102103 return nil104}105106func main() {107 if err := generateConstants(); err != nil {108 fmt.Fprintf(os.Stderr, "failed to generate constants: %v\n", err)109 os.Exit(1)110 }111 if err := generateLanguagesList(); err != nil {112 fmt.Fprintf(os.Stderr, "failed to generate languages list: %v\n", err)113 os.Exit(1)114 }115}
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.