-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split a wildcard implementation to xmvExpander
- Loading branch information
1 parent
eac5268
commit 39c4b1e
Showing
5 changed files
with
261 additions
and
232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package tfmigrate | ||
|
||
import ( | ||
"fmt" | ||
"regexp" | ||
"strings" | ||
) | ||
|
||
// xmvExpander is a helper method for implementing wildcard expansion for xmv actions. | ||
type xmvExpander struct { | ||
// xmv action to be expanded | ||
action *StateXMvAction | ||
} | ||
|
||
// newXMvExpander returns a new XMvExpander instance. | ||
func newXMvExpander(action *StateXMvAction) *xmvExpander { | ||
return &xmvExpander{ | ||
action: action, | ||
} | ||
} | ||
|
||
// A wildcardChar will greedy match with any character in the resource path. | ||
const matchWildcardRegex = "(.*)" | ||
const wildcardChar = "*" | ||
|
||
// makeSourceMatchPattern returns regex pattern that matches the wildcard | ||
// source and make sure characters are not treated as special meta characters. | ||
func makeSourceMatchPattern(s string) string { | ||
safeString := regexp.QuoteMeta(s) | ||
quotedWildCardChar := regexp.QuoteMeta(wildcardChar) | ||
return strings.ReplaceAll(safeString, quotedWildCardChar, matchWildcardRegex) | ||
} | ||
|
||
// makeSrcRegex returns a regex that will do matching based on the wildcard | ||
// source that was given. | ||
func makeSrcRegex(source string) (*regexp.Regexp, error) { | ||
regPattern := makeSourceMatchPattern(source) | ||
regExpression, err := regexp.Compile(regPattern) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not make pattern out of %s (%s) due to %s", source, regPattern, err) | ||
} | ||
return regExpression, nil | ||
} | ||
|
||
// expand returns actions matching wildcard move actions based on the list of resources. | ||
func (e *xmvExpander) expand(stateList []string) ([]*StateMvAction, error) { | ||
if e.nrOfWildcards() == 0 { | ||
staticActionAsList := make([]*StateMvAction, 1) | ||
staticActionAsList[0] = NewStateMvAction(e.action.source, e.action.destination) | ||
return staticActionAsList, nil | ||
} | ||
matchingSources, err := e.getMatchingSourcesFromState(stateList) | ||
if err != nil { | ||
return nil, err | ||
} | ||
matchingActions := make([]*StateMvAction, len(matchingSources)) | ||
for i, matchingSource := range matchingSources { | ||
destination, e2 := e.getDestinationForStateSrc(matchingSource) | ||
if e2 != nil { | ||
return nil, e2 | ||
} | ||
matchingActions[i] = NewStateMvAction(matchingSource, destination) | ||
} | ||
return matchingActions, nil | ||
} | ||
|
||
func (e *xmvExpander) nrOfWildcards() int { | ||
return strings.Count(e.action.source, wildcardChar) | ||
} | ||
|
||
// getMatchingSourcesFromState looks into the state and find sources that match | ||
// pattern with wild cards. | ||
func (e *xmvExpander) getMatchingSourcesFromState(stateList []string) ([]string, error) { | ||
re, err := makeSrcRegex(e.action.source) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var matchingStateSources []string | ||
|
||
for _, s := range stateList { | ||
match := re.FindString(s) | ||
if match != "" { | ||
matchingStateSources = append(matchingStateSources, match) | ||
} | ||
} | ||
return matchingStateSources, err | ||
} | ||
|
||
// getDestinationForStateSrc returns the destination for a source. | ||
func (e *xmvExpander) getDestinationForStateSrc(stateSource string) (string, error) { | ||
re, err := makeSrcRegex(e.action.source) | ||
if err != nil { | ||
return "", err | ||
} | ||
destination := re.ReplaceAllString(stateSource, e.action.destination) | ||
return destination, err | ||
} |
Oops, something went wrong.