From eb952474870243110bdc1087c8468981d5eda5b2 Mon Sep 17 00:00:00 2001 From: yangkb09 Date: Wed, 7 Jun 2023 13:03:30 -0400 Subject: [PATCH] attempt to getFiles with ParseDir, empty map returned; TODO: restore modowners_generation_script_test.go --- scripts/modowners/modowners.go | 27 ++-- .../modowners/modowners_generation_script.go | 110 ++++++++++--- .../modowners_generation_script_test.go | 30 ---- scripts/modowners/modowners_test.go | 146 +++++++++--------- 4 files changed, 172 insertions(+), 141 deletions(-) delete mode 100644 scripts/modowners/modowners_generation_script_test.go diff --git a/scripts/modowners/modowners.go b/scripts/modowners/modowners.go index 6cb59883312..9774dc553ed 100644 --- a/scripts/modowners/modowners.go +++ b/scripts/modowners/modowners.go @@ -7,7 +7,6 @@ import ( "io" "io/fs" "log" - "os" "strings" "golang.org/x/mod/modfile" @@ -176,16 +175,16 @@ func hasCommonElement(a []string, b []string) bool { return false } -func main() { - if len(os.Args) < 2 { - fmt.Println("usage: modowners subcommand go.mod...") - os.Exit(1) - } - type CmdFunc func(fs.FS, *log.Logger, []string) error - cmds := map[string]CmdFunc{"check": check, "owners": owners, "modules": modules} - if f, ok := cmds[os.Args[1]]; !ok { // NOTE: both f and ok are visible inside the if / else if statement, but not outside; chaining of ifs very common in go when checking errors and calling multiple funcs - log.Fatal("invalid command") - } else if err := f(os.DirFS("."), log.Default(), os.Args[2:]); err != nil { - log.Fatal(err) - } -} +// func main() { +// if len(os.Args) < 2 { +// fmt.Println("usage: modowners subcommand go.mod...") +// os.Exit(1) +// } +// type CmdFunc func(fs.FS, *log.Logger, []string) error +// cmds := map[string]CmdFunc{"check": check, "owners": owners, "modules": modules} +// if f, ok := cmds[os.Args[1]]; !ok { // NOTE: both f and ok are visible inside the if / else if statement, but not outside; chaining of ifs very common in go when checking errors and calling multiple funcs +// log.Fatal("invalid command") +// } else if err := f(os.DirFS("."), log.Default(), os.Args[2:]); err != nil { +// log.Fatal(err) +// } +// } diff --git a/scripts/modowners/modowners_generation_script.go b/scripts/modowners/modowners_generation_script.go index e9f482daf51..09a57a9f243 100644 --- a/scripts/modowners/modowners_generation_script.go +++ b/scripts/modowners/modowners_generation_script.go @@ -2,7 +2,11 @@ package main import ( "fmt" + "go/parser" + "go/token" "os" + "path/filepath" + "strings" ) /* @@ -12,49 +16,107 @@ load in the modules modify modfile, write it back out (should be straightfwd) modfile.AddComment need to write it back to my filesystem as go.mod.altered, compare to go.mod, raise the PR - -write new output to test_go.mod so i can compare and make sure it's valid - when i want to raise pr, copy test_go.mod and paste into go.mod - -dont worry about if things are in the right place - create folder called testdata test files in the folder whatever i want to do with this func, i do it with test data - return to the test encourages me to write thing func so it doesnt print to stdoutput and parse from OS, rather send it io.Reader with w/e go.mod file and return either io.Writer or call thing() - -best way to test things is usually to use test functions, and not the main func -no diff b/n test func and main func */ // input: module name, output: list of files that import it // how?? -func getFiles(moduleName string) ([]string, error) { +func getFiles(modules []Module) ([]string, error) { fmt.Println("I AM GET FILES") - // for each module, return a list of files that import it - // DO NOW: determine how to get list of files that import a module based on module name + // Path to the Grafana repository + repoPath := "github.com/grafana/grafana" - return []string{}, nil -} - -func main() { - // parse go.mod to get list of modules - m, err := parseGoMod(os.DirFS("."), "go.mod") + // Get the absolute path to the repository + repoAbsPath, err := filepath.Abs("") if err != nil { return nil, err } - // for each direct module, get list of files that import it - for _, mod := range m { - if mod.Indirect == false { - files, err := getFiles(mod) - fmt.Println(mod) + fmt.Println("repoPath", repoPath) + fmt.Println("repoAbsPath", repoAbsPath) + + // List of importing files + importingFiles := make([]string, 0) + + // Set to store unique imported packages + importedPackages := make(map[string]bool) + + for _, module := range modules { + importedPackages[module.Name] = true + } + fmt.Println("I AM BEFORE VISIT") + + // Visit function to check each Go file in the repository + visit := func(path string, info os.DirEntry, err error) error { + if err != nil { + return err + } + + // Check if the file is a Go file + if !info.IsDir() && strings.HasSuffix(info.Name(), ".go") { + // Parse the Go file + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly) if err != nil { - return nil, err + return err + } + + // Check if the file imports any of the modules' names + for _, importSpec := range file.Imports { + importPath := strings.Trim(importSpec.Path.Value, "\"") + if importedPackages[importPath] { + importingFiles = append(importingFiles, path) + break + } } } + + return nil + } + fmt.Println("I AM AFTER VISIT") + + // Walk through the repository directory and its subdirectories + err = filepath.WalkDir(repoAbsPath, visit) + fmt.Println("I AM WALKDIR ERR", err) + if err != nil { + return nil, err } + fmt.Println("FILES FROM GETFILES", importingFiles) + + return importingFiles, nil + + // for each module, return a list of files that import it + // DO NOW: determine how to get list of files that import a module based on module name +} + +func main() { + // parse go.mod to get list of modules + m, _ := parseGoMod(os.DirFS("."), "go.mod") + // if err != nil { + // return nil, err + // } + + // for each direct module, get list of files that import it + // for _, mod := range m { + // if mod.Indirect == false { + // _, err := getFiles(mod) + // fmt.Println(mod) + // if err != nil { + // // return nil, err + // } + // } + // } + + files, _ := getFiles(m) + // if err != nil { + // return nil, err + // } + fmt.Println("FILES FROM MAIN", files) + } diff --git a/scripts/modowners/modowners_generation_script_test.go b/scripts/modowners/modowners_generation_script_test.go deleted file mode 100644 index f74b7d1d22f..00000000000 --- a/scripts/modowners/modowners_generation_script_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "testing" -) - -/* -question: how do i mock files that import the below 3 imports and use said imports? -*/ -func TestGetFiles(t *testing.T) { - for _, test := range []struct { - moduleName string - expectedResult []string - }{ - {"cloud.google.com/go/storage v1.28.1", []string{"file1.go", "file2.go", "file3.go"}}, - {"cuelang.org/go v0.5.0", []string{"file4.go"}}, - {"github.com/Azure/azure-sdk-for-go v65.0.0+incompatible", []string{"file2.go", "file4.go", "file5.go"}}, - } { - result, err := getFiles(test.moduleName) - if err != nil { - t.Error("error getting files", err) - } - // Compare each file in the result and expected slices - for i := range result { - if result[i] != test.expectedResult[i] { - t.Errorf("Expected file '%s', but got file '%s'", test.expectedResult[i], result[i]) - } - } - } -} diff --git a/scripts/modowners/modowners_test.go b/scripts/modowners/modowners_test.go index 26efc7c85ab..87a14355404 100644 --- a/scripts/modowners/modowners_test.go +++ b/scripts/modowners/modowners_test.go @@ -1,11 +1,11 @@ package main import ( - "bytes" - "log" - "strings" + // "bytes" + // "log" + // "strings" "testing" - "testing/fstest" + // "testing/fstest" ) func TestCommonElement(t *testing.T) { @@ -25,78 +25,78 @@ func TestCommonElement(t *testing.T) { } } -func TestCheck(t *testing.T) { - for _, test := range []struct { - description string - fileName string - contents string - args []string - valid bool - expectedOutput string - }{ - {"Test valid modfile", "go.mod", ` - require ( - cloud.google.com/go/storage v1.28.1 // @delivery - cuelang.org/go v0.5.0 // @as-code @backend-platform - github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery - github.com/Masterminds/semver v1.5.0 // @delivery @backend-platform - ) - `, []string{"go.mod"}, true, ""}, - {"Test invalid modfile", "go.mod", ` - require ( - cloud.google.com/go/storage v1.28.1 - cuelang.org/go v0.5.0 // @as-code @backend-platform - github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery - github.com/Masterminds/semver v1.5.0 // @delivery @backend-platform - ) - `, []string{"go.mod"}, false, "cloud.google.com/go/storage@v1.28.1\n"}, - } { - buf := &bytes.Buffer{} - logger := log.New(buf, "", 0) - filesystem := fstest.MapFS{test.fileName: &fstest.MapFile{Data: []byte(test.contents)}} - err := check(filesystem, logger, test.args) - if test.valid && err != nil { - t.Error(test.description, err) - } else if !test.valid && err == nil { - t.Error(test.description, "error expected") - } - if buf.String() != test.expectedOutput { - t.Error(test.description, buf.String()) - } - } -} +// func TestCheck(t *testing.T) { +// for _, test := range []struct { +// description string +// fileName string +// contents string +// args []string +// valid bool +// expectedOutput string +// }{ +// {"Test valid modfile", "go.mod", ` +// require ( +// cloud.google.com/go/storage v1.28.1 // @delivery +// cuelang.org/go v0.5.0 // @as-code @backend-platform +// github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery +// github.com/Masterminds/semver v1.5.0 // @delivery @backend-platform +// ) +// `, []string{"go.mod"}, true, ""}, +// {"Test invalid modfile", "go.mod", ` +// require ( +// cloud.google.com/go/storage v1.28.1 +// cuelang.org/go v0.5.0 // @as-code @backend-platform +// github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery +// github.com/Masterminds/semver v1.5.0 // @delivery @backend-platform +// ) +// `, []string{"go.mod"}, false, "cloud.google.com/go/storage@v1.28.1\n"}, +// } { +// buf := &bytes.Buffer{} +// logger := log.New(buf, "", 0) +// filesystem := fstest.MapFS{test.fileName: &fstest.MapFile{Data: []byte(test.contents)}} +// err := check(filesystem, logger, test.args) +// if test.valid && err != nil { +// t.Error(test.description, err) +// } else if !test.valid && err == nil { +// t.Error(test.description, "error expected") +// } +// if buf.String() != test.expectedOutput { +// t.Error(test.description, buf.String()) +// } +// } +// } -func TestModules(t *testing.T) { - buf := &bytes.Buffer{} - logger := log.New(buf, "", 0) - filesystem := fstest.MapFS{"go.txd": &fstest.MapFile{Data: []byte(` - require ( - cloud.google.com/go/storage v1.28.1 - cuelang.org/go v0.5.0 // @as-code @backend-platform - github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery - github.com/Masterminds/semver v1.5.0 // @delivery @backend-platform - ) - `)}} +// func TestModules(t *testing.T) { +// buf := &bytes.Buffer{} +// logger := log.New(buf, "", 0) +// filesystem := fstest.MapFS{"go.txd": &fstest.MapFile{Data: []byte(` +// require ( +// cloud.google.com/go/storage v1.28.1 +// cuelang.org/go v0.5.0 // @as-code @backend-platform +// github.com/Azure/azure-sdk-for-go v65.0.0+incompatible // indirect, @delivery +// github.com/Masterminds/semver v1.5.0 // @delivery @backend-platform +// ) +// `)}} - err := modules(filesystem, logger, []string{"-m", "go.txd"}) // NOTE: pass various flags, these are cmd line arguments - if err != nil { - t.Error(err, buf.String()) - } +// err := modules(filesystem, logger, []string{"-m", "go.txd"}) // NOTE: pass various flags, these are cmd line arguments +// if err != nil { +// t.Error(err, buf.String()) +// } - logs := buf.String() +// logs := buf.String() - // Expected results - expectedModules := []string{ - "cloud.google.com/go/storage v1.28.1", - "cuelang.org/go v0.5.0", - "github.com/Azure/azure-sdk-for-go v65.0.0+incompatible", - "github.com/Masterminds/semver v1.5.0", - } +// // Expected results +// expectedModules := []string{ +// "cloud.google.com/go/storage v1.28.1", +// "cuelang.org/go v0.5.0", +// "github.com/Azure/azure-sdk-for-go v65.0.0+incompatible", +// "github.com/Masterminds/semver v1.5.0", +// } - expectedResults := strings.Join(expectedModules, "\n") +// expectedResults := strings.Join(expectedModules, "\n") - // Compare logs to expected results - if logs != expectedResults { - t.Error(err) - } -} +// // Compare logs to expected results +// if logs != expectedResults { +// t.Error(err) +// } +// }