diff --git a/internal/manager/config/config.go b/internal/manager/config/config.go index d8f1cf07..ba917785 100644 --- a/internal/manager/config/config.go +++ b/internal/manager/config/config.go @@ -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 diff --git a/internal/manager/config/config_test.go b/internal/manager/config/config_test.go index 9e38d320..95cb033d 100644 --- a/internal/manager/config/config_test.go +++ b/internal/manager/config/config_test.go @@ -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) +}