Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavlo Strokov <pstrokov@gitlab.com>2021-03-15 15:10:38 +0300
committerPavlo Strokov <pstrokov@gitlab.com>2021-03-18 12:49:31 +0300
commit63c55949d54543fce205c0f750f8fc502ed9566a (patch)
treea26b220fde2aea0495789d584b35432bc6212751 /internal/gitaly/linguist/linguist.go
parent2093a05fa4214e69abc75eacea26e926266264b1 (diff)
Linguist converted into an instantiation dependency
Implementation of the linguist package relies on the package-private state: the use of the colorMap variable. It is filled with a hook mechanism after validation of the gitaly configuration. The problem is that this operation invokes ruby code to get it done and this call is pretty expensive. It also doesn't allow us to convert tests to parallel as it causes race conditions in attempt to fill the global variable. The solution to this problem is creation of the struct instance that encapsulates the state and can be instantiated only when needed. The change also includes minification in generating test configuration that does not require to make a ruby call and uses a stub file for initialisation. The behaviour could be returned back to the normal with usage of the WithActualLinguist option for configuration creation. The change also includes renames of the test functions for the linguist package. The change speeds up execution of the tests: before 0m43.907s and after 0m21.659s on my local. Part of: https://gitlab.com/gitlab-org/gitaly/-/issues/2699
Diffstat (limited to 'internal/gitaly/linguist/linguist.go')
-rw-r--r--internal/gitaly/linguist/linguist.go47
1 files changed, 27 insertions, 20 deletions
diff --git a/internal/gitaly/linguist/linguist.go b/internal/gitaly/linguist/linguist.go
index 9356a8af1..8cb187569 100644
--- a/internal/gitaly/linguist/linguist.go
+++ b/internal/gitaly/linguist/linguist.go
@@ -15,13 +15,8 @@ import (
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config"
)
-func init() {
- config.RegisterHook(LoadColors)
-}
-
var (
exportedEnvVars = []string{"HOME", "PATH", "GEM_HOME", "BUNDLE_PATH", "BUNDLE_APP_CONFIG"}
- colorMap = make(map[string]Language)
)
// Language is used to parse Linguist's language.json file.
@@ -32,8 +27,31 @@ type Language struct {
// ByteCountPerLanguage represents a counter value (bytes) per language.
type ByteCountPerLanguage map[string]uint64
+// Instance is a holder of the defined in the system language settings.
+type Instance struct {
+ colorMap map[string]Language
+}
+
+// New loads the name->color map from the Linguist gem and returns initialised instance
+// to use back to the caller or an error.
+func New(cfg config.Cfg) (*Instance, error) {
+ jsonReader, err := openLanguagesJSON(cfg)
+ if err != nil {
+ return nil, err
+ }
+ defer jsonReader.Close()
+
+ var inst Instance
+
+ if err := json.NewDecoder(jsonReader).Decode(&inst.colorMap); err != nil {
+ return nil, err
+ }
+
+ return &inst, nil
+}
+
// Stats returns the repository's language stats as reported by 'git-linguist'.
-func Stats(ctx context.Context, cfg config.Cfg, repoPath string, commitID string) (ByteCountPerLanguage, error) {
+func (inst *Instance) Stats(ctx context.Context, cfg config.Cfg, repoPath string, commitID string) (ByteCountPerLanguage, error) {
cmd, err := startGitLinguist(ctx, cfg, repoPath, commitID, "stats")
if err != nil {
return nil, err
@@ -53,8 +71,8 @@ func Stats(ctx context.Context, cfg config.Cfg, repoPath string, commitID string
}
// Color returns the color Linguist has assigned to language.
-func Color(language string) string {
- if color := colorMap[language].Color; color != "" {
+func (inst *Instance) Color(language string) string {
+ if color := inst.colorMap[language].Color; color != "" {
return color
}
@@ -62,17 +80,6 @@ func Color(language string) string {
return fmt.Sprintf("#%x", colorSha[0:3])
}
-// LoadColors loads the name->color map from the Linguist gem.
-func LoadColors(cfg *config.Cfg) error {
- jsonReader, err := openLanguagesJSON(cfg)
- if err != nil {
- return err
- }
- defer jsonReader.Close()
-
- return json.NewDecoder(jsonReader).Decode(&colorMap)
-}
-
func startGitLinguist(ctx context.Context, cfg config.Cfg, repoPath string, commitID string, linguistCommand string) (*command.Command, error) {
bundle, err := exec.LookPath("bundle")
if err != nil {
@@ -115,7 +122,7 @@ func startGitLinguist(ctx context.Context, cfg config.Cfg, repoPath string, comm
return internalCmd, nil
}
-func openLanguagesJSON(cfg *config.Cfg) (io.ReadCloser, error) {
+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
// linguist path via Bundler is not working for some reason, for example