diff --git a/arduino/cores/packagemanager/package_manager.go b/arduino/cores/packagemanager/package_manager.go index 175a783025b..7561e38707e 100644 --- a/arduino/cores/packagemanager/package_manager.go +++ b/arduino/cores/packagemanager/package_manager.go @@ -380,13 +380,13 @@ func (pme *Explorer) ResolveFQBN(fqbn *cores.FQBN) ( } func (pme *Explorer) determineReferencedPlatformRelease(boardBuildProperties *properties.Map, boardPlatformRelease *cores.PlatformRelease, fqbn *cores.FQBN) (string, *cores.PlatformRelease, string, *cores.PlatformRelease, error) { - core := boardBuildProperties.Get("build.core") + core := boardBuildProperties.ExpandPropsInString(boardBuildProperties.Get("build.core")) referredCore := "" if split := strings.Split(core, ":"); len(split) > 1 { referredCore, core = split[0], split[1] } - variant := boardBuildProperties.Get("build.variant") + variant := boardBuildProperties.ExpandPropsInString(boardBuildProperties.Get("build.variant")) referredVariant := "" if split := strings.Split(variant, ":"); len(split) > 1 { referredVariant, variant = split[0], split[1] diff --git a/arduino/cores/packagemanager/package_manager_test.go b/arduino/cores/packagemanager/package_manager_test.go index 5cab6878485..42053c9fa30 100644 --- a/arduino/cores/packagemanager/package_manager_test.go +++ b/arduino/cores/packagemanager/package_manager_test.go @@ -807,6 +807,102 @@ func TestLegacyPackageConversionToPluggableDiscovery(t *testing.T) { } } +func TestVariantAndCoreSelection(t *testing.T) { + // Pass nil, since these paths are only used for installing + pmb := NewBuilder(nil, nil, nil, nil, "test") + // Hardware from main packages directory + pmb.LoadHardwareFromDirectory(dataDir1.Join("packages")) + pm := pmb.Build() + pme, release := pm.NewExplorer() + defer release() + + requireSameFile := func(f1, f2 *paths.Path) { + require.True(t, f1.EquivalentTo(f2), "%s must be equivalent to %s", f1, f2) + } + + // build.core test suite + t.Run("CoreWithoutSubstitutions", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "arduino", buildProps.Get("build.core")) + requireSameFile(buildProps.GetPath("build.core.path"), dataDir1.Join("packages", "test2", "hardware", "avr", "1.0.0", "cores", "arduino")) + }) + t.Run("CoreWithSubstitutions", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test2") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "{my_core}", buildProps.Get("build.core")) + require.Equal(t, "arduino", buildProps.Get("my_core")) + requireSameFile(buildProps.GetPath("build.core.path"), dataDir1.Join("packages", "test2", "hardware", "avr", "1.0.0", "cores", "arduino")) + }) + t.Run("CoreWithSubstitutionsAndDefaultOption", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test3") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "{my_core}", buildProps.Get("build.core")) + require.Equal(t, "arduino", buildProps.Get("my_core")) + requireSameFile(buildProps.GetPath("build.core.path"), dataDir1.Join("packages", "test2", "hardware", "avr", "1.0.0", "cores", "arduino")) + }) + t.Run("CoreWithSubstitutionsAndNonDefaultOption", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test3:core=referenced") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "{my_core}", buildProps.Get("build.core")) + require.Equal(t, "arduino:arduino", buildProps.Get("my_core")) + requireSameFile(buildProps.GetPath("build.core.path"), dataDir1.Join("packages", "arduino", "hardware", "avr", "1.8.3", "cores", "arduino")) + }) + + // build.variant test suite + t.Run("VariantWithoutSubstitutions", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test4") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "standard", buildProps.Get("build.variant")) + requireSameFile(buildProps.GetPath("build.variant.path"), dataDir1.Join("packages", "test2", "hardware", "avr", "1.0.0", "variants", "standard")) + }) + t.Run("VariantWithSubstitutions", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test5") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "{my_variant}", buildProps.Get("build.variant")) + require.Equal(t, "standard", buildProps.Get("my_variant")) + requireSameFile(buildProps.GetPath("build.variant.path"), dataDir1.Join("packages", "test2", "hardware", "avr", "1.0.0", "variants", "standard")) + }) + t.Run("VariantWithSubstitutionsAndDefaultOption", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test6") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "{my_variant}", buildProps.Get("build.variant")) + require.Equal(t, "standard", buildProps.Get("my_variant")) + requireSameFile(buildProps.GetPath("build.variant.path"), dataDir1.Join("packages", "test2", "hardware", "avr", "1.0.0", "variants", "standard")) + }) + t.Run("VariantWithSubstitutionsAndNonDefaultOption", func(t *testing.T) { + fqbn, err := cores.ParseFQBN("test2:avr:test6:variant=referenced") + require.NoError(t, err) + require.NotNil(t, fqbn) + _, _, _, buildProps, _, err := pme.ResolveFQBN(fqbn) + require.NoError(t, err) + require.Equal(t, "{my_variant}", buildProps.Get("build.variant")) + require.Equal(t, "arduino:standard", buildProps.Get("my_variant")) + requireSameFile(buildProps.GetPath("build.variant.path"), dataDir1.Join("packages", "arduino", "hardware", "avr", "1.8.3", "variants", "standard")) + }) +} + func TestRunPostInstall(t *testing.T) { pmb := NewBuilder(nil, nil, nil, nil, "test") pm := pmb.Build() diff --git a/arduino/cores/packagemanager/testdata/data_dir_1/packages/test2/hardware/avr/1.0.0/boards.txt b/arduino/cores/packagemanager/testdata/data_dir_1/packages/test2/hardware/avr/1.0.0/boards.txt new file mode 100644 index 00000000000..7829201e7e9 --- /dev/null +++ b/arduino/cores/packagemanager/testdata/data_dir_1/packages/test2/hardware/avr/1.0.0/boards.txt @@ -0,0 +1,47 @@ +menu.core=Core +menu.variant=Variant + +## Test cases for core selection + +test.name=Test Board +test.build.board=AVR_TEST +test.build.core=arduino +test.build.variant=standard + +test2.name=Test Board 2 +test2.build.board=AVR_TEST_2 +test2.build.core={my_core} +test2.my_core=arduino +test2.build.variant=standard + +test3.name=Test Board 2 +test3.build.board=AVR_TEST_2 +test3.build.core={my_core} +test3.my_core=arduino +test3.build.variant=standard +test3.menu.core.default=Default +test3.menu.core.referenced=Referenced +test3.menu.core.referenced.my_core=arduino:arduino + +## Test cases for variant selection + +test4.name=Test Board +test4.build.board=AVR_TEST +test4.build.core=arduino +test4.build.variant=standard + +test5.name=Test Board 2 +test5.build.board=AVR_TEST_2 +test5.build.core=arduino +test5.my_variant=standard +test5.build.variant={my_variant} + +test6.name=Test Board 2 +test6.build.board=AVR_TEST_2 +test5.build.core=arduino +test6.my_variant=standard +test6.build.variant={my_variant} +test6.menu.variant.default=Default +test6.menu.variant.referenced=Referenced +test6.menu.variant.referenced.my_variant=arduino:standard +