@@ -618,25 +618,50 @@ func (pme *Explorer) GetTool(toolID string) *cores.Tool {
618
618
func (pme * Explorer ) FindToolsRequiredForBoard (board * cores.Board ) ([]* cores.ToolRelease , error ) {
619
619
pme .log .Infof ("Searching tools required for board %s" , board )
620
620
621
- // core := board.Properties["build.core"]
622
621
platform := board .PlatformRelease
623
622
624
- // maps "PACKAGER:TOOL" => ToolRelease
625
- foundTools := map [string ]* cores.ToolRelease {}
626
-
627
- // a Platform may not specify required tools (because it's a platform that comes from a
628
- // user/hardware dir without a package_index.json) then add all available tools
629
- for _ , targetPackage := range pme .packages {
630
- for _ , tool := range targetPackage .Tools {
631
- rel := tool .GetLatestInstalled ()
632
- if rel != nil {
633
- foundTools [rel .Tool .Name ] = rel
623
+ // maps tool name => all available ToolRelease
624
+ allToolsAlternatives := map [string ][]* cores.ToolRelease {}
625
+ for _ , tool := range pme .GetAllInstalledToolsReleases () {
626
+ alternatives := allToolsAlternatives [tool .Tool .Name ]
627
+ alternatives = append (alternatives , tool )
628
+ allToolsAlternatives [tool .Tool .Name ] = alternatives
629
+ }
630
+
631
+ // selectBest select the tool with best matching, applying the following rules
632
+ // in order of priority:
633
+ // - the tool comes from the requested packager
634
+ // - the tool has the greatest version
635
+ // - the tool packager comes first in alphabetic order
636
+ selectBest := func (tools []* cores.ToolRelease , packager string ) * cores.ToolRelease {
637
+ selected := tools [0 ]
638
+ for _ , tool := range tools [1 :] {
639
+ if tool .Tool .Package .Name != selected .Tool .Package .Name {
640
+ if tool .Tool .Package .Name == packager {
641
+ selected = tool
642
+ }
643
+ continue
644
+ }
645
+ if ! tool .Version .Equal (selected .Version ) {
646
+ if tool .Version .GreaterThan (selected .Version ) {
647
+ selected = tool
648
+ }
649
+ continue
650
+ }
651
+ if tool .Tool .Package .Name < selected .Tool .Package .Name {
652
+ selected = tool
634
653
}
635
654
}
655
+ return selected
636
656
}
637
657
638
- // replace the default tools above with the specific required by the current platform
658
+ // First select the specific tools required by the current platform
639
659
requiredTools := []* cores.ToolRelease {}
660
+ // The Sorting of the tool dependencies is required because some platforms may depends
661
+ // on more than one version of the same tool. For example adafruit:samd has both
662
+ // [email protected] and [email protected] . To allow the runtime property
663
+ // {runtime.tools.bossac.path} to be correctly set to the 1.8.0 version we must ensure
664
+ // taht the returned array is sorted by version.
640
665
platform .ToolDependencies .Sort ()
641
666
for _ , toolDep := range platform .ToolDependencies {
642
667
pme .log .WithField ("tool" , toolDep ).Infof ("Required tool" )
@@ -645,11 +670,15 @@ func (pme *Explorer) FindToolsRequiredForBoard(board *cores.Board) ([]*cores.Too
645
670
return nil , fmt .Errorf (tr ("tool release not found: %s" ), toolDep )
646
671
}
647
672
requiredTools = append (requiredTools , tool )
648
- delete (foundTools , tool .Tool .Name )
673
+ delete (allToolsAlternatives , tool .Tool .Name )
649
674
}
650
675
651
- for _ , toolRel := range foundTools {
652
- requiredTools = append (requiredTools , toolRel )
676
+ // Since a Platform may not specify the required tools (because it's a platform that comes
677
+ // from a user/hardware dir without a package_index.json) then add all available tools giving
678
+ // priority to tools coming from the same packager
679
+ for _ , tools := range allToolsAlternatives {
680
+ tool := selectBest (tools , platform .Platform .Package .Name )
681
+ requiredTools = append (requiredTools , tool )
653
682
}
654
683
return requiredTools , nil
655
684
}
0 commit comments