diff options
author | Toon Claes <toon@gitlab.com> | 2023-01-31 12:21:37 +0300 |
---|---|---|
committer | Toon Claes <toon@gitlab.com> | 2023-01-31 12:21:37 +0300 |
commit | 87034c09d5ef18ede2a776e8f4106db5c82e267b (patch) | |
tree | fadfbe801ce44cc013240e05a0b5c926ad7d8ccd | |
parent | 9e9717d60e83bc08e6bcb3ca0e636edf1668a9b3 (diff) |
cmd: Add stand-alone command gitaly-license-detecttoon-bench-go-license
This change extracts all the code related to go-license-detect so we can
use it without spawning a gitaly process.
-rw-r--r-- | cmd/gitaly-license-detect/main.go | 89 | ||||
-rw-r--r-- | internal/gitaly/service/repository/license.go | 24 | ||||
-rw-r--r-- | internal/gitaly/service/repository/license_test.go | 28 |
3 files changed, 122 insertions, 19 deletions
diff --git a/cmd/gitaly-license-detect/main.go b/cmd/gitaly-license-detect/main.go new file mode 100644 index 000000000..c02fff419 --- /dev/null +++ b/cmd/gitaly-license-detect/main.go @@ -0,0 +1,89 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + _ "net/http/pprof" + "os" + "runtime" + "runtime/pprof" + + "github.com/go-enry/go-license-detector/v4/licensedb" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile" + "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" + "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/service/repository" + "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb" +) + +func main() { + cpuprofile := flag.String("cpuprofile", "", "write cpu profile to `file`") + memprofile := flag.String("memprofile", "", "write memory profile to `file`") + + flag.Parse() + + licensedb.Preload() + + if *cpuprofile != "" { + f, err := os.Create(*cpuprofile) + if err != nil { + log.Fatal("could not create CPU profile: ", err) + } + defer f.Close() // error handling omitted for example + if err := pprof.StartCPUProfile(f); err != nil { + log.Fatal("could not start CPU profile: ", err) + } + defer pprof.StopCPUProfile() + } + + // ... rest of the program ... + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + cfg := config.Cfg{ + BinDir: "/usr/bin", + Storages: []config.Storage{ + { + Name: "default", + Path: "/home", + }, + }, + } + cmdFactory, cleanup, err := git.NewExecCommandFactory(cfg) + if err != nil { + panic(err) + } + defer cleanup() + + catfileCache := catfile.NewCache(cfg) + locator := config.NewLocator(cfg) + repoProto := &gitalypb.Repository{ + StorageName: "default", + RelativePath: flag.Args()[0], + } + repo := localrepo.New(locator, cmdFactory, catfileCache, repoProto) + headOID, err := repo.ResolveRevision(ctx, "HEAD") + repoFiler := &repository.GitFiler{Ctx: ctx, Repo: repo, TreeishID: headOID} + detectedLicenses, err := licensedb.Detect(repoFiler) + if err != nil { + panic(err) + } + + fmt.Println(detectedLicenses) + + if *memprofile != "" { + f, err := os.Create(*memprofile) + if err != nil { + log.Fatal("could not create memory profile: ", err) + } + defer f.Close() // error handling omitted for example + runtime.GC() // get up-to-date statistics + if err := pprof.WriteHeapProfile(f); err != nil { + log.Fatal("could not write memory profile: ", err) + } + } +} diff --git a/internal/gitaly/service/repository/license.go b/internal/gitaly/service/repository/license.go index c0b12833a..a63a08bfd 100644 --- a/internal/gitaly/service/repository/license.go +++ b/internal/gitaly/service/repository/license.go @@ -85,7 +85,7 @@ func (s *server) FindLicense(ctx context.Context, req *gitalypb.FindLicenseReque } func findLicense(ctx context.Context, repo *localrepo.Repo, commitID git.ObjectID) (*gitalypb.FindLicenseResponse, error) { - repoFiler := &gitFiler{ctx: ctx, repo: repo, treeishID: commitID} + repoFiler := &GitFiler{Ctx: ctx, Repo: repo, TreeishID: commitID} detectedLicenses, err := licensedb.Detect(repoFiler) if err != nil { if errors.Is(err, licensedb.ErrNoLicenseFound) { @@ -175,16 +175,16 @@ func trimDeprecatedPrefix(name string) string { var readmeRegexp = regexp.MustCompile(`(readme|guidelines)(\.md|\.rst|\.html|\.txt)?$`) -type gitFiler struct { - ctx context.Context - repo *localrepo.Repo +type GitFiler struct { + Ctx context.Context + Repo *localrepo.Repo foundLicense bool path string - treeishID git.ObjectID + TreeishID git.ObjectID } -func (f *gitFiler) ReadFile(path string) ([]byte, error) { - data, err := f.repo.ReadObject(f.ctx, git.ObjectID(fmt.Sprintf("%s:%s", f.treeishID, path))) +func (f *GitFiler) ReadFile(path string) ([]byte, error) { + data, err := f.Repo.ReadObject(f.Ctx, git.ObjectID(fmt.Sprintf("%s:%s", f.TreeishID, path))) if err != nil { return nil, fmt.Errorf("read file: %w", err) } @@ -207,14 +207,14 @@ func (f *gitFiler) ReadFile(path string) ([]byte, error) { return data, nil } -func (f *gitFiler) ReadDir(string) ([]filer.File, error) { +func (f *GitFiler) ReadDir(string) ([]filer.File, error) { var stderr bytes.Buffer - cmd, err := f.repo.Exec(f.ctx, git.Command{ + cmd, err := f.Repo.Exec(f.Ctx, git.Command{ Name: "ls-tree", Flags: []git.Option{ git.Flag{Name: "-z"}, }, - Args: []string{f.treeishID.String()}, + Args: []string{f.TreeishID.String()}, }, git.WithStderr(&stderr)) if err != nil { return nil, err @@ -249,9 +249,9 @@ func (f *gitFiler) ReadDir(string) ([]filer.File, error) { return files, nil } -func (f *gitFiler) Close() {} +func (f *GitFiler) Close() {} -func (f *gitFiler) PathsAreAlwaysSlash() bool { +func (f *GitFiler) PathsAreAlwaysSlash() bool { // git ls-files uses unix slash `/` return true } diff --git a/internal/gitaly/service/repository/license_test.go b/internal/gitaly/service/repository/license_test.go index 3384d0cad..d518ec7a3 100644 --- a/internal/gitaly/service/repository/license_test.go +++ b/internal/gitaly/service/repository/license_test.go @@ -4,6 +4,7 @@ package repository import ( "context" + _ "net/http/pprof" "os" "testing" @@ -339,6 +340,11 @@ func BenchmarkFindLicense(b *testing.B) { SkipCreationViaService: true, }) + repoKicad, _ := gittest.CreateRepository(b, ctx, cfg, gittest.CreateRepositoryConfig{ + SkipCreationViaService: true, + Seed: "kicad.git", + }) + // Based on https://github.com/go-enry/go-license-detector/blob/18a439e5437cd46905b074ac24c27cbb6cac4347/licensedb/internal/investigation.go#L28-L38 fileNames := []string{ "licence", @@ -397,16 +403,24 @@ func BenchmarkFindLicense(b *testing.B) { ) for _, tc := range []struct { - desc string - repo *gitalypb.Repository + desc string + repo *gitalypb.Repository + shortname string }{ { - desc: "gitlab-org/gitlab.git", - repo: repoGitLab, + desc: "gitlab-org/gitlab.git", + repo: repoGitLab, + shortname: "mit", + }, + { + desc: "stress.git", + repo: repoStress, + shortname: "mit", }, { - desc: "stress.git", - repo: repoStress, + desc: "kicad.git", + repo: repoKicad, + shortname: "bsl-1.0", }, } { b.Run(tc.desc, func(b *testing.B) { @@ -415,7 +429,7 @@ func BenchmarkFindLicense(b *testing.B) { for i := 0; i < b.N; i++ { resp, err := client.FindLicense(ctx, &gitalypb.FindLicenseRequest{Repository: tc.repo}) require.NoError(b, err) - require.Equal(b, "mit", resp.GetLicenseShortName()) + require.Equal(b, tc.shortname, resp.GetLicenseShortName()) } if featureflag.LocalrepoReadObjectCached.IsEnabled(ctx) { |