Skip to content

Commit 37374a1

Browse files
committed
refactor: collapse resolveSource into a single org->space->app cascade
Replace the three separate --source-app/--source-space/--source-org branches with one linear cascade: each level (org, then space, then app) refines the GUID the next level resolves against, and the most specific flag provided becomes the scope. The result is built once as cf:<scope>:<guid>. This removes the resolveOrgGUID/resolveSpaceGUID helpers, since GUID resolution now happens exactly once per level inline. Source strings, verbose scope output, warning ordering, and the app-not-found TIP error are all unchanged; the existing black-box command specs cover them.
1 parent 4ba1b4f commit 37374a1

1 file changed

Lines changed: 48 additions & 77 deletions

File tree

command/v7/route_policy_source_flags.go

Lines changed: 48 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ func (f RoutePolicySourceFlags) validateSourceFlags() error {
6464

6565
// resolveSource resolves source flags to a raw source string and a human-readable
6666
// scope description. Returns (source, scopeDisplay, warnings, error).
67+
//
68+
// Resolution cascades org -> space -> app: each level refines the GUID that the
69+
// next level resolves against, and the most specific flag provided becomes the
70+
// scope. The result is always of the form cf:<scope>:<guid>.
6771
func resolveSource(f RoutePolicySourceFlags, actor Actor, config command.Config) (string, string, v7action.Warnings, error) {
6872
var allWarnings v7action.Warnings
6973

@@ -77,29 +81,38 @@ func resolveSource(f RoutePolicySourceFlags, actor Actor, config command.Config)
7781
return "cf:any", "scope: any, source: any authenticated app", allWarnings, nil
7882
}
7983

80-
// --source-app (with optional --source-space / --source-org for cross-space/org lookup)
81-
if f.SourceApp != "" {
82-
spaceGUID := config.TargetedSpace().GUID
83-
spaceName := config.TargetedSpace().Name
84-
orgName := config.TargetedOrganization().Name
84+
scope := ""
85+
var sourceGUID string
8586

86-
if f.SourceSpace != "" {
87-
resolvedOrgGUID, resolvedOrgName, orgWarnings, err := resolveOrgGUID(f, actor, config)
88-
allWarnings = append(allWarnings, orgWarnings...)
89-
if err != nil {
90-
return "", "", allWarnings, err
91-
}
92-
orgName = resolvedOrgName
87+
// Org level: default to the targeted org; --source-org overrides it and, when it
88+
// is the most specific flag provided, becomes the scope.
89+
orgGUID := config.TargetedOrganization().GUID
90+
orgName := config.TargetedOrganization().Name
91+
if f.SourceOrg != "" {
92+
org, warnings, err := actor.GetOrganizationByName(f.SourceOrg)
93+
allWarnings = append(allWarnings, warnings...)
94+
if err != nil {
95+
return "", "", allWarnings, err
96+
}
97+
orgGUID, orgName = org.GUID, f.SourceOrg
98+
scope, sourceGUID = "org", orgGUID
99+
}
93100

94-
resolvedSpaceGUID, spaceWarnings, err := resolveSpaceGUID(f.SourceSpace, resolvedOrgGUID, actor)
95-
allWarnings = append(allWarnings, spaceWarnings...)
96-
if err != nil {
97-
return "", "", allWarnings, err
98-
}
99-
spaceGUID = resolvedSpaceGUID
100-
spaceName = f.SourceSpace
101+
// Space level: resolved within orgGUID (targeted or --source-org).
102+
spaceGUID := config.TargetedSpace().GUID
103+
spaceName := config.TargetedSpace().Name
104+
if f.SourceSpace != "" {
105+
space, warnings, err := actor.GetSpaceByNameAndOrganization(f.SourceSpace, orgGUID)
106+
allWarnings = append(allWarnings, warnings...)
107+
if err != nil {
108+
return "", "", allWarnings, err
101109
}
110+
spaceGUID, spaceName = space.GUID, f.SourceSpace
111+
scope, sourceGUID = "space", spaceGUID
112+
}
102113

114+
// App level: resolved within spaceGUID (targeted, --source-space, or both).
115+
if f.SourceApp != "" {
103116
app, warnings, err := actor.GetApplicationByNameAndSpace(f.SourceApp, spaceGUID)
104117
allWarnings = append(allWarnings, warnings...)
105118
if err != nil {
@@ -113,75 +126,33 @@ func resolveSource(f RoutePolicySourceFlags, actor Actor, config command.Config)
113126
}
114127
return "", "", allWarnings, err
115128
}
129+
scope, sourceGUID = "app", app.GUID
130+
}
131+
132+
if scope == "" {
133+
return "", "", allWarnings, fmt.Errorf("no source specified")
134+
}
116135

117-
scopeDisplay := fmt.Sprintf("scope: app, source: %s", f.SourceApp)
136+
// Human-readable scope description; annotate cross-space/cross-org modifiers when present.
137+
var scopeDisplay string
138+
switch scope {
139+
case "app":
140+
scopeDisplay = fmt.Sprintf("scope: app, source: %s", f.SourceApp)
118141
if f.SourceSpace != "" {
119142
scopeDisplay += fmt.Sprintf(" (space: %s", spaceName)
120143
if f.SourceOrg != "" {
121144
scopeDisplay += fmt.Sprintf(", org: %s", orgName)
122145
}
123146
scopeDisplay += ")"
124147
}
125-
126-
return fmt.Sprintf("cf:app:%s", app.GUID), scopeDisplay, allWarnings, nil
127-
}
128-
129-
// --source-space (primary: space-level policy)
130-
if f.SourceSpace != "" {
131-
orgGUID, orgName, orgWarnings, err := resolveOrgGUID(f, actor, config)
132-
allWarnings = append(allWarnings, orgWarnings...)
133-
if err != nil {
134-
return "", "", allWarnings, err
135-
}
136-
137-
spaceGUID, spaceWarnings, err := resolveSpaceGUID(f.SourceSpace, orgGUID, actor)
138-
allWarnings = append(allWarnings, spaceWarnings...)
139-
if err != nil {
140-
return "", "", allWarnings, err
141-
}
142-
143-
scopeDisplay := fmt.Sprintf("scope: space, source: %s", f.SourceSpace)
148+
case "space":
149+
scopeDisplay = fmt.Sprintf("scope: space, source: %s", f.SourceSpace)
144150
if f.SourceOrg != "" {
145151
scopeDisplay += fmt.Sprintf(" (org: %s)", orgName)
146152
}
147-
148-
return fmt.Sprintf("cf:space:%s", spaceGUID), scopeDisplay, allWarnings, nil
149-
}
150-
151-
// --source-org (primary: org-level policy)
152-
if f.SourceOrg != "" {
153-
org, warnings, err := actor.GetOrganizationByName(f.SourceOrg)
154-
allWarnings = append(allWarnings, warnings...)
155-
if err != nil {
156-
return "", "", allWarnings, err
157-
}
158-
159-
return fmt.Sprintf("cf:org:%s", org.GUID),
160-
fmt.Sprintf("scope: org, source: %s", f.SourceOrg),
161-
allWarnings, nil
162-
}
163-
164-
return "", "", allWarnings, fmt.Errorf("no source specified")
165-
}
166-
167-
// resolveOrgGUID returns the GUID and name of the org identified by --source-org,
168-
// falling back to the targeted org if --source-org is not set.
169-
func resolveOrgGUID(f RoutePolicySourceFlags, actor Actor, config command.Config) (string, string, v7action.Warnings, error) {
170-
if f.SourceOrg == "" {
171-
return config.TargetedOrganization().GUID, config.TargetedOrganization().Name, nil, nil
153+
default: // "org"
154+
scopeDisplay = fmt.Sprintf("scope: org, source: %s", f.SourceOrg)
172155
}
173-
org, warnings, err := actor.GetOrganizationByName(f.SourceOrg)
174-
if err != nil {
175-
return "", "", v7action.Warnings(warnings), err
176-
}
177-
return org.GUID, f.SourceOrg, v7action.Warnings(warnings), nil
178-
}
179156

180-
// resolveSpaceGUID returns the GUID of the named space within the given org.
181-
func resolveSpaceGUID(spaceName, orgGUID string, actor Actor) (string, v7action.Warnings, error) {
182-
space, warnings, err := actor.GetSpaceByNameAndOrganization(spaceName, orgGUID)
183-
if err != nil {
184-
return "", v7action.Warnings(warnings), err
185-
}
186-
return space.GUID, v7action.Warnings(warnings), nil
157+
return fmt.Sprintf("cf:%s:%s", scope, sourceGUID), scopeDisplay, allWarnings, nil
187158
}

0 commit comments

Comments
 (0)