Skip to content

Commit 6f90002

Browse files
committed
Merge branch 'master' into daemon
2 parents f11373b + fdfe999 commit 6f90002

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1688
-580
lines changed

Gopkg.lock

+27-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

arduino/libraries/librariesresolver/cpp.go

+51-9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/arduino/arduino-cli/arduino/libraries"
2626
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
2727
"github.com/arduino/arduino-cli/arduino/utils"
28+
"github.com/schollz/closestmatch"
2829
"github.com/sirupsen/logrus"
2930
)
3031

@@ -76,31 +77,48 @@ func (resolver *Cpp) AlternativesFor(header string) libraries.List {
7677
// header and architecture. If no libraries provides the requested header, nil is returned
7778
func (resolver *Cpp) ResolveFor(header, architecture string) *libraries.Library {
7879
logrus.Infof("Resolving include %s for arch %s", header, architecture)
79-
var found *libraries.Library
80+
var found libraries.List
8081
var foundPriority int
8182
for _, lib := range resolver.headers[header] {
8283
libPriority := computePriority(lib, header, architecture)
8384
msg := " discarded"
8485
if found == nil || foundPriority < libPriority {
85-
found = lib
86+
found = libraries.List{}
87+
found.Add(lib)
8688
foundPriority = libPriority
8789
msg = " found better lib"
90+
} else if foundPriority == libPriority {
91+
found.Add(lib)
92+
msg = " found another lib with same priority"
8893
}
8994
logrus.
9095
WithField("lib", lib.Name).
9196
WithField("prio", fmt.Sprintf("%03X", libPriority)).
9297
Infof(msg)
9398
}
94-
return found
95-
}
99+
if found == nil {
100+
return nil
101+
}
102+
if len(found) == 1 {
103+
return found[0]
104+
}
96105

97-
func computePriority(lib *libraries.Library, header, arch string) int {
98-
simplify := func(name string) string {
99-
name = utils.SanitizeName(name)
100-
name = strings.ToLower(name)
101-
return name
106+
// If more than one library qualifies use the "closestmatch" algorithm to
107+
// find the best matching one (instead of choosing it randomly)
108+
winner := findLibraryWithNameBestDistance(header, found)
109+
if winner != nil {
110+
logrus.WithField("lib", winner.Name).Info(" library with the best mathing name")
102111
}
112+
return winner
113+
}
114+
115+
func simplify(name string) string {
116+
name = utils.SanitizeName(name)
117+
name = strings.ToLower(name)
118+
return name
119+
}
103120

121+
func computePriority(lib *libraries.Library, header, arch string) int {
104122
header = strings.TrimSuffix(header, filepath.Ext(header))
105123
header = simplify(header)
106124
name := simplify(lib.Name)
@@ -119,3 +137,27 @@ func computePriority(lib *libraries.Library, header, arch string) int {
119137
}
120138
return priority
121139
}
140+
141+
func findLibraryWithNameBestDistance(name string, libs libraries.List) *libraries.Library {
142+
// Create closestmatch DB
143+
wordsToTest := []string{}
144+
for _, lib := range libs {
145+
wordsToTest = append(wordsToTest, simplify(lib.Name))
146+
}
147+
// Choose a set of bag sizes, more is more accurate but slower
148+
bagSizes := []int{2}
149+
150+
// Create a closestmatch object and find the best matching name
151+
cm := closestmatch.New(wordsToTest, bagSizes)
152+
closestName := cm.Closest(name)
153+
154+
// Return the closest-matching lib
155+
var winner *libraries.Library
156+
for _, lib := range libs {
157+
if closestName == simplify(lib.Name) {
158+
winner = lib
159+
break
160+
}
161+
}
162+
return winner
163+
}

arduino/libraries/librariesresolver/cpp_test.go

+37-7
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,53 @@ import (
2424
"github.com/stretchr/testify/require"
2525
)
2626

27-
func TestCppHeaderPriority(t *testing.T) {
28-
l1 := &libraries.Library{Name: "Calculus Lib", Location: libraries.Sketchbook}
29-
l2 := &libraries.Library{Name: "Calculus Lib-master", Location: libraries.Sketchbook}
30-
l3 := &libraries.Library{Name: "Calculus Lib Improved", Location: libraries.Sketchbook}
31-
l4 := &libraries.Library{Name: "Another Calculus Lib", Location: libraries.Sketchbook}
32-
l5 := &libraries.Library{Name: "Yet Another Calculus Lib Improved", Location: libraries.Sketchbook}
33-
l6 := &libraries.Library{Name: "AnotherLib", Location: libraries.Sketchbook}
27+
var l1 = &libraries.Library{Name: "Calculus Lib", Location: libraries.Sketchbook}
28+
var l2 = &libraries.Library{Name: "Calculus Lib-master", Location: libraries.Sketchbook}
29+
var l3 = &libraries.Library{Name: "Calculus Lib Improved", Location: libraries.Sketchbook}
30+
var l4 = &libraries.Library{Name: "Another Calculus Lib", Location: libraries.Sketchbook}
31+
var l5 = &libraries.Library{Name: "Yet Another Calculus Lib Improved", Location: libraries.Sketchbook}
32+
var l6 = &libraries.Library{Name: "Calculus Unified Lib", Location: libraries.Sketchbook}
33+
var l7 = &libraries.Library{Name: "AnotherLib", Location: libraries.Sketchbook}
3434

35+
func TestCppHeaderPriority(t *testing.T) {
3536
r1 := computePriority(l1, "calculus_lib.h", "avr")
3637
r2 := computePriority(l2, "calculus_lib.h", "avr")
3738
r3 := computePriority(l3, "calculus_lib.h", "avr")
3839
r4 := computePriority(l4, "calculus_lib.h", "avr")
3940
r5 := computePriority(l5, "calculus_lib.h", "avr")
4041
r6 := computePriority(l6, "calculus_lib.h", "avr")
42+
r7 := computePriority(l7, "calculus_lib.h", "avr")
4143
require.True(t, r1 > r2)
4244
require.True(t, r2 > r3)
4345
require.True(t, r3 > r4)
4446
require.True(t, r4 > r5)
4547
require.True(t, r5 > r6)
48+
require.True(t, r6 == r7)
49+
}
50+
51+
func TestCppHeaderResolverWithNilResult(t *testing.T) {
52+
resolver := NewCppResolver()
53+
libraryList := libraries.List{}
54+
libraryList.Add(l1)
55+
resolver.headers["aaa.h"] = libraryList
56+
require.Nil(t, resolver.ResolveFor("bbb.h", "avr"))
57+
}
58+
59+
func TestCppHeaderResolver(t *testing.T) {
60+
resolve := func(header string, libs ...*libraries.Library) string {
61+
resolver := NewCppResolver()
62+
librarylist := libraries.List{}
63+
for _, lib := range libs {
64+
librarylist.Add(lib)
65+
}
66+
resolver.headers[header] = librarylist
67+
return resolver.ResolveFor(header, "avr").Name
68+
}
69+
require.Equal(t, "Calculus Lib", resolve("calculus_lib.h", l1, l2, l3, l4, l5, l6, l7))
70+
require.Equal(t, "Calculus Lib-master", resolve("calculus_lib.h", l2, l3, l4, l5, l6, l7))
71+
require.Equal(t, "Calculus Lib Improved", resolve("calculus_lib.h", l3, l4, l5, l6, l7))
72+
require.Equal(t, "Another Calculus Lib", resolve("calculus_lib.h", l4, l5, l6, l7))
73+
require.Equal(t, "Yet Another Calculus Lib Improved", resolve("calculus_lib.h", l5, l6, l7))
74+
require.Equal(t, "Calculus Unified Lib", resolve("calculus_lib.h", l6, l7))
75+
require.Equal(t, "Calculus Unified Lib", resolve("calculus_lib.h", l7, l6))
4676
}

arduino/resources/install.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func findPackageRoot(parent *paths.Path) (*paths.Path, error) {
124124
}
125125
}
126126
if root == nil {
127-
return nil, fmt.Errorf("package does not contains any subfolder")
127+
return nil, fmt.Errorf("files in archive must be placed in a subdirectory")
128128
}
129129
return root, nil
130130
}

0 commit comments

Comments
 (0)