-
Notifications
You must be signed in to change notification settings - Fork 232
/
validate.go
85 lines (76 loc) · 2.52 KB
/
validate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package app
import (
"encr.dev/pkg/errors"
"encr.dev/pkg/paths"
"encr.dev/v2/internals/parsectx"
"encr.dev/v2/parser"
"encr.dev/v2/parser/apis/authhandler"
"encr.dev/v2/parser/apis/middleware"
"encr.dev/v2/parser/infra/pubsub"
"encr.dev/v2/parser/infra/secrets"
)
// validate checks that the application is in a valid state across all services and compilation units.
func (d *Desc) validate(pc *parsectx.Context, result *parser.Result) {
defer pc.Trace("app.validate").Done()
// Validate the framework
if fw, ok := d.Framework.Get(); ok {
d.validateAuthHandlers(pc, fw)
d.validateAPIs(pc, fw, result)
d.validateMiddleware(pc, fw)
d.validateServiceStructs(pc, result)
}
// Validate infrastructure
d.validateCaches(pc, result)
d.validateConfigs(pc, result)
d.validateCrons(pc, result)
d.validateDatabases(pc, result)
d.validatePubSub(pc, result)
// Validate all resources are defined within a service
for _, b := range result.AllBinds() {
r := result.ResourceForBind(b)
switch r.(type) {
case *pubsub.Topic:
// We allow pubsub topics to be declared outside of service code
continue
case *middleware.Middleware:
// Middleware is also allowed to be declared outside of service code if it's global (validateMiddleware checks this already)
continue
case *authhandler.AuthHandler:
// AuthHandlers are also allowed to be declared outside of service code as it's shared code between all services
continue
case *secrets.Secrets:
// Secrets are allowed anywhere
continue
default:
_, ok := d.ServiceForPath(b.Package().FSPath)
// It's permitted to declare resources in test files
// or in the main pkg in the case of 'encore alpha exec'.
mainPkgPath := d.BuildInfo.MainPkg.GetOrElse("")
inTestFile, inMainPkg := false, false
if file, ok := b.DeclaredIn().Get(); ok {
if file.TestFile {
inTestFile = true
}
if mainPkgPath != "" && mainPkgPath.LexicallyContains(file.Pkg.ImportPath) {
inMainPkg = true
}
}
if !ok && !inTestFile && !inMainPkg {
pc.Errs.Add(errResourceDefinedOutsideOfService.AtGoNode(r))
}
}
}
// Validate nothing is accessing an et package if it isn't a test file
etPkg := paths.Pkg("encore.dev/et")
for _, pkg := range result.AppPackages() {
for _, file := range pkg.Files {
if !file.TestFile {
for importPath, importSpec := range file.Imports {
if etPkg.LexicallyContains(importPath) {
pc.Errs.Add(errETPackageUsedOutsideOfTestFile.AtGoNode(importSpec, errors.AsError("imported here")))
}
}
}
}
}
}