From 3fb73c6c9ac4164e588d7491ff1841e63246dc28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 14 Feb 2025 18:44:50 +0100 Subject: [PATCH] Make two-way variable replacement case-insensitive The conversion from a known path prefix to a variable is now done in a case-insensitive way. This means that if the variable `{storage}` has value `S:\Flamenco`, a path `s:\flamenco\project\file.blend` will be recognised and replaced with `{storage}\project\file.blend`. This happens uniformly, regardless of the platform. So also on Linux, which has a case-sensitive filesystem, this matching is done in a case-insensitive way. It is very unlikely that a Flamenco configuration has two separate variables, for paths that only differ in their case. Fixes: #104336 Drive letter case mismatch causes two way variables not to work correctly --- internal/manager/config/variables.go | 6 +++++- internal/manager/config/variables_test.go | 26 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/internal/manager/config/variables.go b/internal/manager/config/variables.go index 6d866c56..7c71bf16 100644 --- a/internal/manager/config/variables.go +++ b/internal/manager/config/variables.go @@ -50,11 +50,15 @@ func (c *Conf) NewVariableExpander(audience VariableAudience, platform VariableP // ValueToVariableReplacer replaces any variable values it recognises in // valueToConvert to the actual variable. For example, `/path/to/file.blend` can // be changed to `{my_storage}/file.blend`. +// +// Matching is done in a case-insensitive way on all platforms, because some +// filesystems are case-insensitive. It is very unlikely that there will be two +// variables for two paths, only differing in their case. func (vvc *ValueToVariableReplacer) Replace(valueToConvert string) string { result := valueToConvert for varName, varValue := range vvc.twoWayVars { - if !isValueMatch(result, varValue) { + if !isValueMatch(strings.ToLower(result), strings.ToLower(varValue)) { continue } result = vvc.join(varName, result[len(varValue):]) diff --git a/internal/manager/config/variables_test.go b/internal/manager/config/variables_test.go index f073d17b..a5d826f9 100644 --- a/internal/manager/config/variables_test.go +++ b/internal/manager/config/variables_test.go @@ -50,3 +50,29 @@ func TestExpandTwowayVariablesMixedSlashes(t *testing.T) { assert.Equal(t, `/shared/flamenco/shot/file.blend`, expanderLnx.Expand(`{shared}\shot\file.blend`)) assert.Equal(t, `/shared/flamenco/shot/file.blend`, expanderLnx.Expand(`{shared}/shot/file.blend`)) } + +func TestReplaceTwowayVariablesMixedCase(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}, + }, + } + }) + + replacerWin := c.NewVariableToValueConverter(VariableAudienceWorkers, VariablePlatformWindows) + + // Both uppercase and lowercase drive letter should match. + assert.Equal(t, `{shared}\shot\file.blend`, replacerWin.Replace(`y:\shared\flamenco\shot\file.blend`), + "Lower-case drive letter should match") + assert.Equal(t, `{shared}\shot\file.blend`, replacerWin.Replace(`Y:\shared\flamenco\shot\file.blend`), + "Same-case drive letter should match") + + // Both uppercase and lowercase path should match. + assert.Equal(t, `{shared}\shot\file.blend`, replacerWin.Replace(`Y:\SHARED\flamenco\shot\file.blend`), + "Upper case 1st directory component should match") + assert.Equal(t, `{shared}\SHOT\file.blend`, replacerWin.Replace(`Y:\shared\FLAMENCO\SHOT\file.blend`), + "Upper case 2nd directory component should match") +}