Manager: match Windows paths in two-way variables also with slashes

When doing two-way variable replacement, if the variable has a Windows
path (i.e. backslashes) also do a match for the value with forward slashes.

In other words, if a path `Y:/shared/...` comes in, and the variable value
is (correctly) `Y:\shared\...`, it will be seen as a match.
This commit is contained in:
Sybren A. Stüvel 2022-09-01 15:27:31 +02:00
parent 8368feebac
commit 1ffd56939a
2 changed files with 48 additions and 2 deletions

@ -443,7 +443,7 @@ func (c *Conf) ExpandVariables(inputChannel <-chan string, outputChannel chan<-
if !ok {
continue
}
if !strings.HasPrefix(expanded, managerValue) {
if !isValueMatch(expanded, managerValue) {
continue
}
expanded = targetValue + expanded[len(managerValue):]
@ -484,7 +484,7 @@ func (c *Conf) ConvertTwoWayVariables(inputChannel <-chan string, outputChannel
doValueReplacement := func(valueToConvert string) string {
for varName, varValue := range twoWayVars {
if !strings.HasPrefix(valueToConvert, varValue) {
if !isValueMatch(valueToConvert, varValue) {
continue
}
valueToConvert = fmt.Sprintf("{%s}%s", varName, valueToConvert[len(varValue):])
@ -498,6 +498,25 @@ func (c *Conf) ConvertTwoWayVariables(inputChannel <-chan string, outputChannel
}
}
// isValueMatch returns whether `valueToMatch` starts with `variableValue`.
// When `variableValue` is a Windows path (with backslash separators), it is
// also tested with forward slashes against `valueToMatch`.
func isValueMatch(valueToMatch, variableValue string) bool {
if strings.HasPrefix(valueToMatch, variableValue) {
return true
}
// If the variable value has a backslash, assume it is a Windows path.
// Convert it to slash notation just to see if that would provide a
// match.
if strings.ContainsRune(variableValue, '\\') {
slashedValue := crosspath.ToSlash(variableValue)
return strings.HasPrefix(valueToMatch, slashedValue)
}
return false
}
// getVariables returns the variable values for this (audience, platform) combination.
// If no variables are found, just returns an empty map. If a value is defined
// for both the "all" platform and specifically the given platform, the specific

@ -18,3 +18,30 @@ func TestVariablesWithBackslashes(t *testing.T) {
assert.Equal(t, expectDouble, vars["double-backslash"]["blender"])
assert.Equal(t, expectSingle, vars["quoted-double-backslash"]["blender"])
}
func TestReplaceTwowayVariables(t *testing.T) {
c := DefaultConfig(func(c *Conf) {
c.Variables["shared"] = Variable{
IsTwoWay: true,
Values: []VariableValue{
{Value: "/shared/flamenco", Platform: VariablePlatformLinux},
{Value: `Y:\shared\flamenco`, Platform: VariablePlatformWindows},
},
}
})
feeder := make(chan string, 2)
receiver := make(chan string, 2)
feeder <- `Y:\shared\flamenco\shot\file.blend`
// This is the real reason for this test: forward slashes in the path should
// still be matched to the backslashes in the variable value.
feeder <- `Y:/shared/flamenco/shot/file.blend`
close(feeder)
c.ConvertTwoWayVariables(feeder, receiver, VariableAudienceUsers, VariablePlatformWindows)
assert.Equal(t, `{shared}\shot\file.blend`, <-receiver)
assert.Equal(t, `{shared}/shot/file.blend`, <-receiver)
}