diff options
author | Adam Hegyi <ahegyi@gitlab.com> | 2019-09-24 15:26:19 +0300 |
---|---|---|
committer | Zeger-Jan van de Weg <git@zjvandeweg.nl> | 2019-09-24 15:26:19 +0300 |
commit | be6d4c122dd158a72291b043623b41a60bf28964 (patch) | |
tree | b9c64be1317e9391d97c82bff7b183cd2e9e747d /internal/linguist | |
parent | 94ab4e3d76d08721d7a2d9f82835bb651b130a9a (diff) |
File count and bytes in CommitLanguage response
This change extends the CommitLanguage response to include FileCount and
Bytes. Getting the FileCount per language requires an additional
git-linguist call which might increase the GRPC call execution time.
To have control over the FileCount call, a new feature flag
('linguist_file_count_stats') has been introduced that can be turned off
when performance issues occur.
Diffstat (limited to 'internal/linguist')
-rw-r--r-- | internal/linguist/linguist.go | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/internal/linguist/linguist.go b/internal/linguist/linguist.go index 3b215fd9a..419f22993 100644 --- a/internal/linguist/linguist.go +++ b/internal/linguist/linguist.go @@ -19,6 +19,8 @@ func init() { config.RegisterHook(LoadColors) } +var exportedEnvVars = []string{"HOME", "PATH", "GEM_HOME", "BUNDLE_PATH", "BUNDLE_APP_CONFIG"} + var ( colorMap = make(map[string]Language) ) @@ -28,11 +30,19 @@ type Language struct { Color string `json:"color"` } +// CountPerLanguage represents a counter value (int) per language. +type CountPerLanguage map[string]int + +// ByteCountPerLanguage represents a counter value (bytes) per language. +type ByteCountPerLanguage map[string]uint64 + +// FileListPerLanguage is used to parse Linguist's breakdown output to represent the list of files per language. +type FileListPerLanguage map[string][]string + // Stats returns the repository's language stats as reported by 'git-linguist'. -func Stats(ctx context.Context, repoPath string, commitID string) (map[string]int, error) { - cmd := exec.Command("bundle", "exec", "bin/ruby-cd", repoPath, "git-linguist", "--commit="+commitID, "stats") - cmd.Dir = config.Config.Ruby.Dir - reader, err := command.New(ctx, cmd, nil, nil, nil, os.Environ()...) +func Stats(ctx context.Context, repoPath string, commitID string) (ByteCountPerLanguage, error) { + reader, err := startGitLinguist(ctx, repoPath, commitID, "stats") + if err != nil { return nil, err } @@ -42,10 +52,35 @@ func Stats(ctx context.Context, repoPath string, commitID string) (map[string]in return nil, err } - stats := make(map[string]int) + stats := make(ByteCountPerLanguage) return stats, json.Unmarshal(data, &stats) } +// FileCountStats returns the file counts per language +func FileCountStats(ctx context.Context, repoPath string, commitID string) (CountPerLanguage, error) { + reader, err := startGitLinguist(ctx, repoPath, commitID, "breakdown") + if err != nil { + return nil, err + } + + data, err := ioutil.ReadAll(reader) + if err != nil { + return nil, err + } + + languageFiles := make(FileListPerLanguage) + if err := json.Unmarshal(data, &languageFiles); err != nil { + return nil, err + } + + stats := make(CountPerLanguage) + for lang, files := range languageFiles { + stats[lang] = len(files) + } + + return stats, nil +} + // Color returns the color Linguist has assigned to language. func Color(language string) string { if color := colorMap[language].Color; color != "" { @@ -67,6 +102,19 @@ func LoadColors(cfg config.Cfg) error { return json.NewDecoder(jsonReader).Decode(&colorMap) } +func startGitLinguist(ctx context.Context, repoPath string, commitID string, linguistCommand string) (io.Reader, error) { + cmd := exec.Command("bundle", "exec", "bin/ruby-cd", repoPath, "git-linguist", "--commit="+commitID, linguistCommand) + cmd.Dir = config.Config.Ruby.Dir + + var env []string + reader, err := command.New(ctx, cmd, nil, nil, nil, exportEnvironment(env)...) + if err != nil { + return nil, err + } + + return reader, nil +} + func openLanguagesJSON(cfg config.Cfg) (io.ReadCloser, error) { if jsonPath := cfg.Ruby.LinguistLanguagesPath; jsonPath != "" { // This is a fallback for environments where dynamic discovery of the @@ -106,3 +154,13 @@ func openLanguagesJSON(cfg config.Cfg) (io.ReadCloser, error) { return os.Open(path.Join(linguistPathSymlink.Name(), "lib/linguist/languages.json")) } + +func exportEnvironment(env []string) []string { + for _, envVarName := range exportedEnvVars { + if val, ok := os.LookupEnv(envVarName); ok { + env = append(env, fmt.Sprintf("%s=%s", envVarName, val)) + } + } + + return env +} |