Skip to content

Commit

Permalink
Setup lazy expanderfunc to avoid projectfile set callback
Browse files Browse the repository at this point in the history
  • Loading branch information
daved committed Jun 6, 2023
1 parent 09269dd commit 0c8f91c
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 122 deletions.
16 changes: 16 additions & 0 deletions pkg/project/expander.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,22 @@ func makeEntryMapMap(structure reflect.Value) map[string]map[string]entry {
return m
}

func makeLazyExpanderFuncFromPtrToStruct(val reflect.Value) ExpanderFunc {
return func(v, name, meta string, isFunc bool, ctx *Expansion) (string, error) {
iface := val.Interface()
if u, ok := iface.(interface{ Update(*Project) }); ok {
u.Update(ctx.Project)
}

if val.Kind() == reflect.Ptr {
val = val.Elem()
}
fn := makeExpanderFuncFromMap(makeEntryMapMap(val))

return fn(v, name, meta, isFunc, ctx)
}
}

func makeExpanderFuncFromMap(m map[string]map[string]entry) ExpanderFunc {
return func(v, name, meta string, isFunc bool, ctx *Expansion) (string, error) {
if isFunc && meta == "()" {
Expand Down
7 changes: 0 additions & 7 deletions pkg/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,6 @@ func (p *Project) SetCommit(commitID string) error {
return p.Source().SetCommit(commitID, p.IsHeadless())
}

func (p *Project) SetUpdateCallback(fn func()) {
if p.projectfile == nil {
return
}
p.projectfile.SetUpdateCallback(fn)
}

// Constants returns a reference to projectfile.Constants
func (p *Project) Constants() []*Constant {
constrained, err := constraints.FilterUnconstrained(pConditional, p.projectfile.Constants.AsConstrainedEntities())
Expand Down
56 changes: 4 additions & 52 deletions pkg/project/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,55 +31,7 @@ func init() {
}
}

func RegisterTopLevelStruct(name string, val interface{}) error {
v := reflect.ValueOf(val)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}

m := makeEntryMapMap(v)
name = strings.ToLower(name)
err := RegisterExpander(name, makeExpanderFuncFromMap(m))
if err != nil {
return locale.WrapError(
err, "project_expand_register_expander_map",
"Cannot register expander (map)",
)
}

return nil
}

func RegisterTopLevelFunc(name string, val interface{}) error {
v := reflect.ValueOf(val)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}

name = strings.ToLower(name)
err := RegisterExpander(name, makeExpanderFuncFromFunc(v))
if err != nil {
return locale.WrapError(
err, "project_expand_register_expander_func",
"Cannot register expander (func)",
)
}

return nil
}

func RegisterTopLevelStringer(name string, val interface{}) error {
v := reflect.ValueOf(val)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}

topLevelLookup[strings.ToLower(name)] = fmt.Sprintf("%v", v.Interface())

return nil
}

/*func RegisterStruct(val interface{}) error {
func RegisterStruct(val interface{}) error {
v := reflect.ValueOf(val)
// deref if needed
if v.Kind() == reflect.Ptr {
Expand All @@ -95,6 +47,7 @@ func RegisterTopLevelStringer(name string, val interface{}) error {
}

d1Val := v.FieldByIndex(f.Index)
d1ValOrig := d1Val
if d1Val.Kind() == reflect.Ptr {
d1Val = d1Val.Elem()
}
Expand All @@ -105,9 +58,8 @@ func RegisterTopLevelStringer(name string, val interface{}) error {
switch d1Val.Type().Kind() {
// Convert type (to map-map) to express advanced control like tag handling.
case reflect.Struct:
m := makeEntryMapMap(d1Val)
name := strings.ToLower(f.Name)
err := RegisterExpander(name, makeExpanderFuncFromMap(m))
err := RegisterExpander(name, makeLazyExpanderFuncFromPtrToStruct(d1ValOrig))
if err != nil {
return locale.WrapError(
err, "project_expand_register_expander_map",
Expand All @@ -133,7 +85,7 @@ func RegisterTopLevelStringer(name string, val interface{}) error {
}

return nil
}*/
}

// RegisterExpander registers an Expander Func for some given handler value. The handler value
// must not effectively be a blank string and the Func must be defined. It is definitely possible
Expand Down
21 changes: 0 additions & 21 deletions pkg/projectfile/projectfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ type Project struct {
parsedURL projectURL // parsed url data
parsedBranch string
parsedVersion string

updateCallback func()
}

// Build covers the build map, which can go under languages or packages
Expand Down Expand Up @@ -684,21 +682,8 @@ func (p *Project) save(cfg ConfigGetter, path string) error {
return nil
}

func (p *Project) runUpdateCallback() {
if p.updateCallback == nil {
return
}
p.updateCallback()
}

func (p *Project) SetUpdateCallback(fn func()) {
p.updateCallback = fn
}

// SetNamespace updates the namespace in the project file
func (p *Project) SetNamespace(owner, project string) error {
defer p.runUpdateCallback()

pf := NewProjectField()
if err := pf.LoadProject(p.Project); err != nil {
return errs.Wrap(err, "Could not load activestate.yaml")
Expand All @@ -720,8 +705,6 @@ func (p *Project) SetNamespace(owner, project string) error {
// in-place so that line order is preserved.
// If headless is true, the project is defined by a commit-id only
func (p *Project) SetCommit(commitID string, headless bool) error {
defer p.runUpdateCallback()

pf := NewProjectField()
if err := pf.LoadProject(p.Project); err != nil {
return errs.Wrap(err, "Could not load activestate.yaml")
Expand All @@ -739,8 +722,6 @@ func (p *Project) SetCommit(commitID string, headless bool) error {
// SetBranch sets the branch within the current project file. This is done
// in-place so that line order is preserved.
func (p *Project) SetBranch(branch string) error {
defer p.runUpdateCallback()

pf := NewProjectField()

if err := pf.LoadProject(p.Project); err != nil {
Expand All @@ -762,8 +743,6 @@ func (p *Project) SetBranch(branch string) error {

// SetPath sets the path of the project file and should generally only be used by tests
func (p *Project) SetPath(path string) {
defer p.runUpdateCallback()

p.path = path
}

Expand Down
50 changes: 19 additions & 31 deletions pkg/projectfile/vars/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,11 @@ import (
"path/filepath"

"github.com/ActiveState/cli/internal/multilog"
"github.com/ActiveState/cli/internal/rtutils/p"
"github.com/ActiveState/cli/pkg/platform/authentication"
"github.com/ActiveState/cli/pkg/project"
"github.com/ActiveState/cli/pkg/sysinfo"
)

type projectDataProvider interface {
Owner() string
Name() string
NamespaceString() string
CommitID() string
BranchName() string
Path() string
URL() string
}

type Project struct {
Namespace string `expand:",asFunc"`
Name string `expand:",asFunc"`
Expand All @@ -49,26 +39,24 @@ type Project struct {
NamespacePrefix string
}

func NewProject(pj projectDataProvider) *Project {
var (
project = &Project{}
)
if !p.IsNil(pj) {
project.Namespace = pj.NamespaceString()
project.Name = pj.Name()
project.Owner = pj.Owner()
project.Url = pj.URL()
project.Commit = pj.CommitID()
project.Branch = pj.BranchName()
project.Path = pj.Path()
if project.Path != "" {
project.Path = filepath.Dir(project.Path)
}
func NewProject(pj *project.Project) *Project {
p := &Project{}
p.Update(pj)
return p
}

project.NamespacePrefix = pj.NamespaceString()
func (p *Project) Update(pj *project.Project) {
p.Namespace = pj.NamespaceString()
p.Name = pj.Name()
p.Owner = pj.Owner()
p.Url = pj.URL()
p.Commit = pj.CommitID()
p.Branch = pj.BranchName()
p.Path = pj.Path()
if p.Path != "" {
p.Path = filepath.Dir(p.Path)
}

return project
p.NamespacePrefix = pj.NamespaceString()
}

type OSVersion struct {
Expand Down Expand Up @@ -128,14 +116,14 @@ type Vars struct {
Mixin func() *Mixin
}

func New(auth *authentication.Auth, project *Project, subshellName string) *Vars {
func New(auth *authentication.Auth, pj *project.Project, subshellName string) *Vars {
osVersion, err := sysinfo.OSVersion()
if err != nil {
multilog.Error("Could not detect OSVersion: %v", err)
}

return &Vars{
Project: project,
Project: NewProject(pj),
OS: NewOS(osVersion),
Shell: subshellName,
Mixin: func() *Mixin { return NewMixin(auth) },
Expand Down
15 changes: 4 additions & 11 deletions pkg/projget/projget.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,10 @@ func newProject(out output.Outputer, auth *authentication.Auth, shell string, pj
return nil, err
}

registerProjectVars := func() {
projVars := vars.New(auth, vars.NewProject(pj), shell)
conditional := constraints.NewPrimeConditional(projVars)
project.RegisterConditional(conditional)
_ = project.RegisterTopLevelStruct("project", projVars.Project)
_ = project.RegisterTopLevelFunc("mixin", projVars.Mixin)
_ = project.RegisterTopLevelStringer("shell", projVars.Shell)
}

pj.SetUpdateCallback(registerProjectVars)
registerProjectVars()
projVars := vars.New(auth, pj, shell)
conditional := constraints.NewPrimeConditional(projVars)
project.RegisterConditional(conditional)
_ = project.RegisterStruct(projVars)

return pj, nil
}
Expand Down

0 comments on commit 0c8f91c

Please sign in to comment.