diff --git a/bin/.lefthook-1.6.16.pkg b/bin/.lefthook-1.6.14.pkg similarity index 100% rename from bin/.lefthook-1.6.16.pkg rename to bin/.lefthook-1.6.14.pkg diff --git a/bin/lefthook b/bin/lefthook index c7675538bd..ec088d329a 120000 --- a/bin/lefthook +++ b/bin/lefthook @@ -1 +1 @@ -.lefthook-1.6.16.pkg \ No newline at end of file +.lefthook-1.6.14.pkg \ No newline at end of file diff --git a/go-runtime/schema/common/common.go b/go-runtime/schema/common/common.go index 6c6d264579..e0dd7b53f9 100644 --- a/go-runtime/schema/common/common.go +++ b/go-runtime/schema/common/common.go @@ -8,13 +8,14 @@ import ( "reflect" "strings" + "github.com/alecthomas/types/optional" + "github.com/puzpuzpuz/xsync/v3" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/backend/schema/strcase" "github.com/TBD54566975/golang-tools/go/analysis" "github.com/TBD54566975/golang-tools/go/analysis/passes/inspect" "github.com/TBD54566975/golang-tools/go/ast/inspector" - "github.com/alecthomas/types/optional" - "github.com/puzpuzpuz/xsync/v3" ) var ( @@ -41,7 +42,8 @@ func NewExtractor(name string, factType analysis.Fact, run func(*analysis.Pass) type ExtractDeclFunc[T schema.Decl, N ast.Node] func(pass *analysis.Pass, node N, object types.Object) optional.Option[T] -func NewDeclExtractor[T schema.Decl, N ast.Node](name string, factType analysis.Fact, extractFunc ExtractDeclFunc[T, N]) *analysis.Analyzer { +func NewDeclExtractor[T schema.Decl, N ast.Node](name string, extractFunc ExtractDeclFunc[T, N]) *analysis.Analyzer { + type Tag struct{} // Tag uniquely identifies the fact type for this extractor. dType := reflect.TypeFor[T]() if _, ok := extractorRegistery.Load(dType); ok { panic(fmt.Sprintf("multiple extractors registered for %s", dType.String())) @@ -54,7 +56,7 @@ func NewDeclExtractor[T schema.Decl, N ast.Node](name string, factType analysis. return optional.None[schema.Decl]() } extractorRegistery.Store(dType, wrapped) - return NewExtractor(name, factType, runExtractDeclsFunc[T, N](extractFunc)) + return NewExtractor(name, (*DefaultFact[Tag])(nil), runExtractDeclsFunc[T, N](extractFunc)) } type ExtractorResult struct { diff --git a/go-runtime/schema/common/fact.go b/go-runtime/schema/common/fact.go index 701c720f99..f9b3ba98fb 100644 --- a/go-runtime/schema/common/fact.go +++ b/go-runtime/schema/common/fact.go @@ -4,10 +4,11 @@ import ( "go/types" "reflect" - "github.com/TBD54566975/ftl/backend/schema" - "github.com/TBD54566975/golang-tools/go/analysis" "github.com/alecthomas/types/optional" sets "github.com/deckarep/golang-set/v2" + + "github.com/TBD54566975/ftl/backend/schema" + "github.com/TBD54566975/golang-tools/go/analysis" ) // SchemaFact is a fact that associates a schema node with a Go object. @@ -17,6 +18,21 @@ type SchemaFact interface { Get() SchemaFactValue } +// DefaultFact should be used as the base type for all schema facts. Each +// Analyzer needs a uniuqe Fact type that is otherwise identical, and this type +// simply reduces that boilerplate. +// +// Usage: +// +// type Fact = common.DefaultFact[struct{}] +type DefaultFact[T any] struct { + value SchemaFactValue +} + +func (*DefaultFact[T]) AFact() {} +func (t *DefaultFact[T]) Set(v SchemaFactValue) { t.value = v } +func (t *DefaultFact[T]) Get() SchemaFactValue { return t.value } + // SchemaFactValue is the value of a SchemaFact. type SchemaFactValue interface { schemaFactValue() diff --git a/go-runtime/schema/data/analyzer.go b/go-runtime/schema/data/analyzer.go index f77f62727e..fff96949f3 100644 --- a/go-runtime/schema/data/analyzer.go +++ b/go-runtime/schema/data/analyzer.go @@ -8,28 +8,21 @@ import ( "strings" "unicode" + "github.com/alecthomas/types/optional" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/backend/schema/strcase" "github.com/TBD54566975/ftl/go-runtime/schema/common" "github.com/TBD54566975/golang-tools/go/analysis" - "github.com/alecthomas/types/optional" ) var ( // Extractor extracts schema.Data to the module schema. - Extractor = common.NewDeclExtractor[*schema.Data, *ast.TypeSpec]("data", (*Fact)(nil), Extract) + Extractor = common.NewDeclExtractor[*schema.Data, *ast.TypeSpec]("data", Extract) aliasFieldTag = "json" ) -type Fact struct { - value common.SchemaFactValue -} - -func (t *Fact) AFact() {} -func (t *Fact) Set(v common.SchemaFactValue) { t.value = v } -func (t *Fact) Get() common.SchemaFactValue { return t.value } - func Extract(pass *analysis.Pass, node *ast.TypeSpec, obj types.Object) optional.Option[*schema.Data] { named, ok := obj.Type().(*types.Named) if !ok { diff --git a/go-runtime/schema/extract.go b/go-runtime/schema/extract.go index 7dd8df7072..172a5c626e 100644 --- a/go-runtime/schema/extract.go +++ b/go-runtime/schema/extract.go @@ -3,6 +3,8 @@ package schema import ( "fmt" + "golang.org/x/exp/maps" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/go-runtime/schema/common" "github.com/TBD54566975/ftl/go-runtime/schema/data" @@ -16,7 +18,6 @@ import ( "github.com/TBD54566975/golang-tools/go/analysis/passes/inspect" checker "github.com/TBD54566975/golang-tools/go/analysis/programmaticchecker" "github.com/TBD54566975/golang-tools/go/packages" - "golang.org/x/exp/maps" ) // Extractors contains all schema extractors that will run. diff --git a/go-runtime/schema/metadata/analyzer.go b/go-runtime/schema/metadata/analyzer.go index eb32288fcc..f7f78e12c4 100644 --- a/go-runtime/schema/metadata/analyzer.go +++ b/go-runtime/schema/metadata/analyzer.go @@ -5,25 +5,21 @@ import ( "go/token" "reflect" + "github.com/alecthomas/types/optional" + sets "github.com/deckarep/golang-set/v2" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/go-runtime/schema/common" "github.com/TBD54566975/golang-tools/go/analysis" "github.com/TBD54566975/golang-tools/go/analysis/passes/inspect" "github.com/TBD54566975/golang-tools/go/ast/inspector" - "github.com/alecthomas/types/optional" - sets "github.com/deckarep/golang-set/v2" ) // Extractor extracts metadata to the module schema. var Extractor = common.NewExtractor("metadata", (*Fact)(nil), Extract) -type Fact struct { - value common.SchemaFactValue -} - -func (t *Fact) AFact() {} -func (t *Fact) Set(v common.SchemaFactValue) { t.value = v } -func (t *Fact) Get() common.SchemaFactValue { return t.value } +type Tag struct{} // Tag uniquely identifies the fact type for this extractor. +type Fact = common.DefaultFact[Tag] func Extract(pass *analysis.Pass) (interface{}, error) { in := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) //nolint:forcetypeassert diff --git a/go-runtime/schema/transitive/analyzer.go b/go-runtime/schema/transitive/analyzer.go index da6eac8a94..bb2c2dbcee 100644 --- a/go-runtime/schema/transitive/analyzer.go +++ b/go-runtime/schema/transitive/analyzer.go @@ -4,12 +4,13 @@ import ( "go/ast" "go/types" + sets "github.com/deckarep/golang-set/v2" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/go-runtime/schema/common" "github.com/TBD54566975/golang-tools/go/analysis" "github.com/TBD54566975/golang-tools/go/analysis/passes/inspect" "github.com/TBD54566975/golang-tools/go/ast/inspector" - sets "github.com/deckarep/golang-set/v2" ) // Extractor extracts transitive schema.Decls to the module schema. @@ -18,13 +19,8 @@ import ( // but not themselves explicitly annotated. var Extractor = common.NewExtractor("transitive", (*Fact)(nil), Extract) -type Fact struct { - value common.SchemaFactValue -} - -func (t *Fact) AFact() {} -func (t *Fact) Set(v common.SchemaFactValue) { t.value = v } -func (t *Fact) Get() common.SchemaFactValue { return t.value } +type Tag struct{} // Tag uniquely identifies the fact type for this extractor. +type Fact = common.DefaultFact[Tag] // Extract traverses all schema type root AST nodes and determines if a node has been marked for extraction. // diff --git a/go-runtime/schema/typealias/analyzer.go b/go-runtime/schema/typealias/analyzer.go index 7c475ff579..4e7608ec43 100644 --- a/go-runtime/schema/typealias/analyzer.go +++ b/go-runtime/schema/typealias/analyzer.go @@ -4,23 +4,16 @@ import ( "go/ast" "go/types" + "github.com/alecthomas/types/optional" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/backend/schema/strcase" "github.com/TBD54566975/ftl/go-runtime/schema/common" "github.com/TBD54566975/golang-tools/go/analysis" - "github.com/alecthomas/types/optional" ) // Extractor extracts type aliases to the module schema. -var Extractor = common.NewDeclExtractor[*schema.TypeAlias, *ast.TypeSpec]("typealias", (*Fact)(nil), Extract) - -type Fact struct { - value common.SchemaFactValue -} - -func (t *Fact) AFact() {} -func (t *Fact) Set(v common.SchemaFactValue) { t.value = v } -func (t *Fact) Get() common.SchemaFactValue { return t.value } +var Extractor = common.NewDeclExtractor[*schema.TypeAlias, *ast.TypeSpec]("typealias", Extract) func Extract(pass *analysis.Pass, node *ast.TypeSpec, obj types.Object) optional.Option[*schema.TypeAlias] { schType, ok := common.ExtractTypeForNode(pass, obj, node, nil).Get() diff --git a/go-runtime/schema/verb/analyzer.go b/go-runtime/schema/verb/analyzer.go index a2cc05ade4..f4086464c7 100644 --- a/go-runtime/schema/verb/analyzer.go +++ b/go-runtime/schema/verb/analyzer.go @@ -4,24 +4,17 @@ import ( "go/ast" "go/types" + "github.com/alecthomas/types/optional" + "github.com/TBD54566975/ftl/backend/schema" "github.com/TBD54566975/ftl/backend/schema/strcase" "github.com/TBD54566975/ftl/go-runtime/schema/common" "github.com/TBD54566975/ftl/go-runtime/schema/initialize" "github.com/TBD54566975/golang-tools/go/analysis" - "github.com/alecthomas/types/optional" ) // Extractor extracts verbs to the module schema. -var Extractor = common.NewDeclExtractor[*schema.Verb, *ast.FuncDecl]("verb", (*Fact)(nil), Extract) - -type Fact struct { - value common.SchemaFactValue -} - -func (t *Fact) AFact() {} -func (t *Fact) Set(v common.SchemaFactValue) { t.value = v } -func (t *Fact) Get() common.SchemaFactValue { return t.value } +var Extractor = common.NewDeclExtractor[*schema.Verb, *ast.FuncDecl]("verb", Extract) func Extract(pass *analysis.Pass, root *ast.FuncDecl, obj types.Object) optional.Option[*schema.Verb] { md, ok := common.GetFactForObject[*common.ExtractedMetadata](pass, obj).Get() diff --git a/renovate.json b/renovate.json deleted file mode 100644 index fefe324ddb..0000000000 --- a/renovate.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended", - ":semanticCommits", - ":semanticCommitTypeAll(chore)", - ":semanticCommitScope(deps)", - "group:allNonMajor", - "schedule:earlyMondays" - ], - "packageRules": [ - { - "matchUpdateTypes": [ - "minor", - "patch" - ], - "automerge": true - }, - { - "matchPackageNames": [ - "jbr", - "ktfmt", - "golangci-lint", - "svu" - ], - "matchManagers": [ - "hermit" - ], - "enabled": false - }, - { - "matchFileNames": [ - "**/testdata/**/go.mod" - ], - "enabled": false - }, - { - "matchPackageNames": [ - "eslint", - "codemirror" - ], - "enabled": false, - "paths": [ - "frontend/**", - "extensions/**" - ] - }, - { - "matchPackageNames": [ - "connectrpc.com/connect" - ], - "enabled": false - } - ] -} \ No newline at end of file diff --git a/renovate.json5 b/renovate.json5 new file mode 100644 index 0000000000..d46a1fdf5c --- /dev/null +++ b/renovate.json5 @@ -0,0 +1,41 @@ +{ + $schema: "https://docs.renovatebot.com/renovate-schema.json", + extends: [ + "config:recommended", + ":semanticCommits", + ":semanticCommitTypeAll(chore)", + ":semanticCommitScope(deps)", + "group:allNonMajor", + "schedule:earlyMondays", + ], + packageRules: [ + { + matchUpdateTypes: ["minor", "patch"], + automerge: true, + }, + { + matchPackageNames: [ + "jbr", + "ktfmt", + "golangci-lint", + "svu", + "lefthook", // Everything after 1.6.14 is broken + ], + matchManagers: ["hermit"], + enabled: false, + }, + { + matchFileNames: ["**/testdata/**/go.mod"], + enabled: false, + }, + { + matchPackageNames: ["eslint", "codemirror"], + enabled: false, + paths: ["frontend/**", "extensions/**"], + }, + { + matchPackageNames: ["connectrpc.com/connect"], + enabled: false, + }, + ], +}