-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathapply.go
119 lines (108 loc) · 2.9 KB
/
apply.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package action
import (
"cmp"
"context"
"fmt"
"slices"
"strings"
"sync"
"github.com/pkg/errors"
"projectforge.dev/projectforge/app"
"projectforge.dev/projectforge/app/lib/telemetry"
"projectforge.dev/projectforge/app/project"
"projectforge.dev/projectforge/app/util"
)
func ApplyAll(ctx context.Context, prjs project.Projects, actT Type, cfg util.ValueMap, as *app.State, logger util.Logger) ResultContexts {
serial := cfg.GetBoolOpt("serial") || cfg.GetStringOpt("mode") == refreshMode
mu := sync.Mutex{}
mSvc, pSvc, eSvc, xSvc := as.Services.Modules, as.Services.Projects, as.Services.Export, as.Services.Exec
results, _ := util.AsyncCollect(prjs, func(prj *project.Project) (*ResultContext, error) {
if serial {
mu.Lock()
defer mu.Unlock()
}
c := cfg.Clone()
prms := &Params{ProjectKey: prj.Key, T: actT, Cfg: cfg, MSvc: mSvc, PSvc: pSvc, XSvc: xSvc, ESvc: eSvc, Logger: logger}
result := Apply(ctx, prms)
if result.Project == nil {
result.Project = prj
}
return &ResultContext{Prj: prj, Cfg: c, Res: result}, nil
})
slices.SortFunc(results, func(l *ResultContext, r *ResultContext) int {
return cmp.Compare(strings.ToLower(l.Prj.Title()), strings.ToLower(r.Prj.Title()))
})
return results
}
func Apply(ctx context.Context, p *Params) (ret *Result) {
ctx, span, logger := telemetry.StartSpan(ctx, "action:"+p.T.Key, p.Logger)
defer span.Complete()
span.Attribute("project", p.ProjectKey)
span.Attribute("action", p.T.String())
timer := util.TimerStart()
defer func() {
if ret == nil {
ret = &Result{}
}
ret.Duration = timer.End()
if rec := recover(); rec != nil {
if err, ok := rec.(error); ok {
ret = ret.WithError(err)
} else {
ret = ret.WithError(errors.New(fmt.Sprint(rec)))
}
}
}()
ret = applyBasic(ctx, p)
if ret != nil {
return ret
}
if len(p.PSvc.Projects()) == 0 {
_, err := p.PSvc.Refresh(p.Logger)
if err != nil {
return errorResult(err, p.T, p.Cfg, logger)
}
}
if p.ProjectKey == "" {
prj := p.PSvc.Default()
p.ProjectKey = prj.Key
}
var pm *PrjAndMods
var err error
ctx, pm, err = getPrjAndMods(ctx, p)
if err != nil {
return errorResult(err, p.T, p.Cfg, logger)
}
return applyPrj(ctx, pm, p.T)
}
func applyBasic(ctx context.Context, p *Params) *Result {
switch p.T {
case TypeCreate:
return onCreate(ctx, p)
case TypeTest:
return onTest(ctx, p)
case TypeDoctor:
return onDoctor(ctx, p.Cfg, p.PSvc, p.MSvc, p.Logger)
}
return nil
}
func applyPrj(ctx context.Context, pm *PrjAndMods, t Type) *Result {
switch t {
case TypeAudit:
return onAudit(ctx, pm)
case TypeBuild:
return onBuild(ctx, pm)
case TypeDebug:
return onDebug(pm)
case TypeGenerate:
return onGenerate(pm)
case TypePreview:
return onPreview(pm)
case TypeRules:
return onRules(pm)
case TypeSVG:
return onSVG(ctx, pm)
default:
return errorResult(errors.Errorf("invalid action type [%s]", t.String()), t, pm.Cfg, pm.Logger)
}
}