diff --git a/gen/generate.go b/gen/generate.go index 8b8d9c31..b0734491 100644 --- a/gen/generate.go +++ b/gen/generate.go @@ -41,15 +41,19 @@ func main() { return } - out := filepath.Join(".", *outputDir) - err := os.MkdirAll(out, os.ModePerm) + imp, err := goGithubImportPath("go.mod") if err != nil { + panic(err) + } + params.GoGithubImport = imp + + out := filepath.Join(".", *outputDir) + if err := os.MkdirAll(out, os.ModePerm); err != nil { panic("failed to create output directory") } // create events.go - err = ExecuteWebhookEventTemplate(filepath.Join(out, "events"), params) - if err != nil { + if err := ExecuteWebhookEventTemplate(filepath.Join(out, "events"), params); err != nil { panic(err) } @@ -59,7 +63,8 @@ func main() { fileName := "events_" + param.Name outFile := filepath.Join(out, fileName) err := ExecuteWebhookEventTypesTemplate(outFile, TemplateParameters{ - Webhooks: []GithubWebhooks{param}, + GoGithubImport: imp, + Webhooks: []GithubWebhooks{param}, }) if err != nil { panic(err) diff --git a/gen/gomod.go b/gen/gomod.go new file mode 100644 index 00000000..fb833786 --- /dev/null +++ b/gen/gomod.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "os" + "regexp" + "sort" +) + +var goGithubModuleRE = regexp.MustCompile(`github\.com/google/go-github/v\d+`) + +// goGithubImportPath reads gomodPath and returns the go-github package import +// path (module path + "/github") derived from the module's require directive. +// This keeps the go-github major version defined in exactly one place. +func goGithubImportPath(gomodPath string) (string, error) { + data, err := os.ReadFile(gomodPath) + if err != nil { + return "", fmt.Errorf("read %s: %w", gomodPath, err) + } + matches := goGithubModuleRE.FindAllString(string(data), -1) + uniq := map[string]struct{}{} + for _, m := range matches { + uniq[m] = struct{}{} + } + switch len(uniq) { + case 0: + return "", fmt.Errorf("no github.com/google/go-github require found in %s", gomodPath) + case 1: + return matches[0] + "/github", nil + default: + uniqueVersions := make([]string, 0, len(uniq)) + for v := range uniq { + uniqueVersions = append(uniqueVersions, v) + } + sort.Strings(uniqueVersions) + return "", fmt.Errorf("multiple go-github module versions found in %s: %v", gomodPath, uniqueVersions) + } +} diff --git a/gen/gomod_test.go b/gen/gomod_test.go new file mode 100644 index 00000000..3a5b3d71 --- /dev/null +++ b/gen/gomod_test.go @@ -0,0 +1,58 @@ +package main + +import ( + "os" + "path/filepath" + "testing" +) + +func writeGoMod(t *testing.T, content string) string { + t.Helper() + dir := t.TempDir() + p := filepath.Join(dir, "go.mod") + if err := os.WriteFile(p, []byte(content), 0o644); err != nil { + t.Fatal(err) + } + return p +} + +func TestGoGithubImportPath(t *testing.T) { + p := writeGoMod(t, `module github.com/cbrgm/githubevents/v2 + +go 1.25.0 + +require ( + github.com/google/go-github/v89 v89.0.0 + golang.org/x/sync v0.22.0 +) +`) + got, err := goGithubImportPath(p) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if want := "github.com/google/go-github/v89/github"; got != want { + t.Fatalf("got %q, want %q", got, want) + } +} + +func TestGoGithubImportPathMissing(t *testing.T) { + p := writeGoMod(t, "module x\n\ngo 1.25.0\n") + if _, err := goGithubImportPath(p); err == nil { + t.Fatal("expected error when no go-github require present") + } +} + +func TestGoGithubImportPathMultiple(t *testing.T) { + p := writeGoMod(t, `module github.com/cbrgm/githubevents/v2 + +go 1.25.0 + +require ( + github.com/google/go-github/v89 v89.0.0 + github.com/google/go-github/v90 v90.0.0 +) +`) + if _, err := goGithubImportPath(p); err == nil { + t.Fatal("expected error when multiple distinct go-github versions present") + } +} diff --git a/gen/template_params.go b/gen/template_params.go index 87a505e0..bd873ed3 100644 --- a/gen/template_params.go +++ b/gen/template_params.go @@ -2,7 +2,9 @@ package main // TemplateParameters represents template parameters. type TemplateParameters struct { - Webhooks []GithubWebhooks + // GoGithubImport is the go-github package import path, derived from go.mod. + GoGithubImport string + Webhooks []GithubWebhooks } // GithubWebhooks represents a Github webhook event type parameters. diff --git a/gen/template_webhook_event.go.tmpl b/gen/template_webhook_event.go.tmpl index b41d16a6..72362875 100644 --- a/gen/template_webhook_event.go.tmpl +++ b/gen/template_webhook_event.go.tmpl @@ -10,7 +10,7 @@ package githubevents import ( "context" "fmt" - "github.com/google/go-github/v89/github" + "{{ .GoGithubImport }}" "golang.org/x/sync/errgroup" "net/http" "sync" diff --git a/gen/template_webhook_event_tests.go.tmpl b/gen/template_webhook_event_tests.go.tmpl index 17531cd1..56d702eb 100644 --- a/gen/template_webhook_event_tests.go.tmpl +++ b/gen/template_webhook_event_tests.go.tmpl @@ -10,7 +10,7 @@ package githubevents import ( "context" "errors" - "github.com/google/go-github/v89/github" + "{{ .GoGithubImport }}" "testing" "sync" ) diff --git a/gen/template_webhook_event_types.go.tmpl b/gen/template_webhook_event_types.go.tmpl index e360ce39..11992675 100644 --- a/gen/template_webhook_event_types.go.tmpl +++ b/gen/template_webhook_event_types.go.tmpl @@ -10,7 +10,7 @@ package githubevents import ( "context" "fmt" - "github.com/google/go-github/v89/github" + "{{ .GoGithubImport }}" "golang.org/x/sync/errgroup" )