-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit introduces a new internal package 'autodetect' that automatically detects the language of the project and applies the appropriate cache patterns. This removes the need for manual pattern specification in most cases. Signed-off-by: Chmouel Boudjnah <[email protected]>
- Loading branch information
1 parent
df60fad
commit e7ffbb0
Showing
6 changed files
with
182 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package autodetect | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
) | ||
|
||
type ( | ||
Pattern []string | ||
LanguePattern struct { | ||
Language string | ||
Patterns []Pattern | ||
} | ||
) | ||
|
||
var languagePatterns = []LanguePattern{ | ||
{ | ||
Language: "go", | ||
Patterns: []Pattern{ | ||
{"go.mod", "go.sum"}, | ||
}, | ||
}, | ||
{ | ||
Language: "nodejs", | ||
Patterns: []Pattern{ | ||
{"package.json", "package-lock.json"}, | ||
{"yarn.lock"}, | ||
}, | ||
}, | ||
{ | ||
Language: "java", | ||
Patterns: []Pattern{ | ||
{"pom.xml"}, | ||
{"build.gradle"}, | ||
}, | ||
}, | ||
{ | ||
Language: "python", | ||
Patterns: []Pattern{ | ||
{"setup.py", "requirements.txt"}, | ||
{"Pipfile"}, | ||
{"poetry.lock"}, | ||
}, | ||
}, | ||
{ | ||
Language: "ruby", | ||
Patterns: []Pattern{ | ||
{"Gemfile", "Gemfile.lock"}, | ||
}, | ||
}, | ||
{ | ||
Language: "php", | ||
Patterns: []Pattern{ | ||
{"composer.json", "composer.lock"}, | ||
}, | ||
}, | ||
{ | ||
Language: "rust", | ||
Patterns: []Pattern{ | ||
{"Cargo.toml", "Cargo.lock"}, | ||
}, | ||
}, | ||
} | ||
|
||
func PatternsByLanguage(workingdir string) map[string][]string { | ||
detectedPatterns := make(map[string][]string) | ||
|
||
for _, languagePattern := range languagePatterns { | ||
for _, pattern := range languagePattern.Patterns { | ||
allFilesExist := true | ||
for _, file := range pattern { | ||
if _, err := os.Stat(filepath.Join(workingdir, file)); os.IsNotExist(err) { | ||
allFilesExist = false | ||
break | ||
} | ||
} | ||
if allFilesExist { | ||
detectedPatterns[languagePattern.Language] = pattern | ||
break | ||
} | ||
} | ||
} | ||
|
||
return detectedPatterns | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package autodetect | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"gotest.tools/v3/assert" | ||
"gotest.tools/v3/env" | ||
"gotest.tools/v3/fs" | ||
) | ||
|
||
func TestWriteFile(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
language string | ||
files []string | ||
}{ | ||
{name: "golang", language: "go", files: []string{"go.mod", "go.sum"}}, | ||
{name: "nodejs-npm", language: "nodejs", files: []string{"package.json", "package-lock.json"}}, | ||
{name: "nodejs-yarn", language: "nodejs", files: []string{"yarn.lock"}}, | ||
{name: "java-maven", language: "java", files: []string{"pom.xml"}}, | ||
{name: "java-gradle", language: "java", files: []string{"build.gradle"}}, | ||
{name: "python-setup", language: "python", files: []string{"setup.py", "requirements.txt"}}, | ||
{name: "python-pipfile", language: "python", files: []string{"Pipfile"}}, | ||
{name: "python-poetry", language: "python", files: []string{"poetry.lock"}}, | ||
{name: "ruby", language: "ruby", files: []string{"Gemfile", "Gemfile.lock"}}, | ||
{name: "php", language: "php", files: []string{"composer.json", "composer.lock"}}, | ||
{name: "rust", language: "rust", files: []string{"Cargo.toml", "Cargo.lock"}}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
tmpdir := fs.NewDir(t, t.Name()) | ||
defer tmpdir.Remove() | ||
|
||
defer env.ChangeWorkingDir(t, tmpdir.Path())() | ||
|
||
for _, file := range tt.files { | ||
err := os.WriteFile(filepath.Join(tmpdir.Path(), file), []byte("random content"), 0o644) | ||
assert.NilError(t, err) | ||
} | ||
|
||
patterns := PatternsByLanguage(tmpdir.Path()) | ||
assert.DeepEqual(t, patterns, map[string][]string{ | ||
tt.language: tt.files, | ||
}) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package flags | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/openshift-pipelines/tekton-caches/internal/autodetect" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var PatternsFlag = "pattern" | ||
|
||
func Patterns(cmd *cobra.Command, workingdir string) ([]string, error) { | ||
patterns, err := cmd.Flags().GetStringArray(PatternsFlag) | ||
if err != nil { | ||
return []string{}, err | ||
} | ||
if len(patterns) == 0 { | ||
// NOTE(chmouel): on multiples languages we use a single cache target, it | ||
// ust make things simpler | ||
// on very large monorepo this might be a problem | ||
languages := autodetect.PatternsByLanguage(workingdir) | ||
if len(languages) == 0 { | ||
return []string{}, fmt.Errorf("didn't detect any language, please specify the patterns with --%s flag", PatternsFlag) | ||
} | ||
for language, files := range languages { | ||
fmt.Fprintf(os.Stderr, "Detected project language %s\n", language) | ||
for _, file := range files { | ||
// NOTE(chmouel): we are using a glob pattern to match the top dir not the subdirs | ||
// but that's fine since most of the time most people don't use | ||
// composed dependencies workspaces (except the rustaceans) | ||
patterns = append(patterns, fmt.Sprintf("*%s", file)) | ||
} | ||
} | ||
} | ||
return patterns, nil | ||
} |