scripts/include.go GO 116 lines View on github.com → Search inside
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}

Code quality findings 1

Defer inside loop; deferred calls accumulate until the function returns, not until the loop iteration ends. This can cause resource leaks
warning correctness defer-in-loop
defer func(file *os.File) {

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.