From 3e613b21b7b3f93daa55d7a0cbfd9a20da3cd868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Insaurralde?= Date: Tue, 7 Jul 2026 08:34:25 -0300 Subject: [PATCH] perf(scanner): hoist parser regexps to package level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compile the five parser path patterns once at package init instead of recompiling them in each parser constructor on every repo scan. BenchmarkNewMemParsers: 9673ns→57ns (169x), 30424B→120B, 255→6 allocs. Signed-off-by: Matías Insaurralde --- scanner/parsers.go | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/scanner/parsers.go b/scanner/parsers.go index 6156555..13dd8e7 100644 --- a/scanner/parsers.go +++ b/scanner/parsers.go @@ -11,13 +11,24 @@ import ( "gopkg.in/yaml.v3" ) +// Parser path patterns are stateless and safe for concurrent use, so they are +// compiled once at package init rather than per-parser-construction (which used +// to recompile all five on every repo scan). +var ( + githubActionsMetadataPattern = regexp.MustCompile(`(^|/)action\.ya?ml$`) + githubWorkflowPattern = regexp.MustCompile(`^\.github/workflows/[^/]+\.ya?ml$`) + azurePipelinesPattern = regexp.MustCompile(`\.?azure-pipelines(-.+)?\.ya?ml$`) + gitlabCiPattern = regexp.MustCompile(`\.?gitlab-ci(-.+)?\.ya?ml$`) + tektonPattern = regexp.MustCompile(`^\.tekton/[^/]+\.ya?ml$`) +) + type GithubActionsMetadataParser struct { pattern *regexp.Regexp } func NewGithubActionsMetadataParser() *GithubActionsMetadataParser { return &GithubActionsMetadataParser{ - pattern: regexp.MustCompile(`(^|/)action\.ya?ml$`), + pattern: githubActionsMetadataPattern, } } @@ -63,7 +74,7 @@ type GithubActionWorkflowParser struct { func NewGithubActionWorkflowParser() *GithubActionWorkflowParser { return &GithubActionWorkflowParser{ - pattern: regexp.MustCompile(`^\.github/workflows/[^/]+\.ya?ml$`), + pattern: githubWorkflowPattern, } } @@ -108,7 +119,7 @@ type AzurePipelinesParser struct { func NewAzurePipelinesParser() *AzurePipelinesParser { return &AzurePipelinesParser{ - pattern: regexp.MustCompile(`\.?azure-pipelines(-.+)?\.ya?ml$`), + pattern: azurePipelinesPattern, } } @@ -154,7 +165,7 @@ type GitlabCiParser struct { func NewGitlabCiParser() *GitlabCiParser { return &GitlabCiParser{ - pattern: regexp.MustCompile(`\.?gitlab-ci(-.+)?\.ya?ml$`), + pattern: gitlabCiPattern, } } @@ -228,7 +239,7 @@ type PipelineAsCodeTektonParser struct { func NewPipelineAsCodeTektonParser() *PipelineAsCodeTektonParser { return &PipelineAsCodeTektonParser{ - pattern: regexp.MustCompile(`^\.tekton/[^/]+\.ya?ml$`), + pattern: tektonPattern, } }