@@ -63,6 +63,13 @@ func (pm *Builder) LoadHardwareFromDirectory(path *paths.Path) []error {
63
63
return append (merr , errors .New (i18n .Tr ("%s is not a directory" , path )))
64
64
}
65
65
66
+ // If the hardware directory is inside, or equals, the sketchbook/hardware directory
67
+ // it's not a managed package, otherwise it is.
68
+ managed := true
69
+ if userInstalled , err := path .IsInsideDir (pm .userPackagesDir .Parent ()); err == nil && userInstalled {
70
+ managed = false
71
+ }
72
+
66
73
// Scan subdirs
67
74
packagersPaths , err := path .ReadDir ()
68
75
if err != nil {
@@ -85,43 +92,39 @@ func (pm *Builder) LoadHardwareFromDirectory(path *paths.Path) []error {
85
92
86
93
for _ , packagerPath := range packagersPaths {
87
94
packager := packagerPath .Base ()
88
-
89
95
// Skip tools, they're not packages and don't contain Platforms
90
96
if packager == "tools" {
91
97
pm .log .Infof ("Excluding directory: %s" , packagerPath )
92
98
continue
93
99
}
100
+ targetPackage := pm .packages .GetOrCreatePackage (packager )
94
101
95
102
// Follow symlinks
96
- err := packagerPath . FollowSymLink () // ex : .arduino15/packages/arduino/
97
- if err != nil {
103
+ // (for example : .arduino15/packages/arduino/ could point to a dev directory)
104
+ if err := packagerPath . FollowSymLink (); err != nil {
98
105
merr = append (merr , fmt .Errorf ("%s: %w" , i18n .Tr ("following symlink %s" , path ), err ))
99
106
continue
100
107
}
101
108
102
109
// There are two possible package directory structures:
103
- // - PACKAGER/ARCHITECTURE-1/boards.txt... (ex: arduino/avr/...)
104
- // PACKAGER/ARCHITECTURE-2/boards.txt... (ex: arduino/sam/...)
105
- // PACKAGER/ARCHITECTURE-3/boards.txt... (ex: arduino/samd/...)
106
- // or
107
- // - PACKAGER/hardware/ARCHITECTURE-1/VERSION/boards.txt... (ex: arduino/hardware/avr/1.6.15/...)
108
- // PACKAGER/hardware/ARCHITECTURE-2/VERSION/boards.txt... (ex: arduino/hardware/sam/1.6.6/...)
109
- // PACKAGER/hardware/ARCHITECTURE-3/VERSION/boards.txt... (ex: arduino/hardware/samd/1.6.12/...)
110
- // PACKAGER/tools/... (ex: arduino/tools/...)
111
- // in the latter case we just move into "hardware" directory and continue
112
- var architectureParentPath * paths.Path
113
- hardwareSubdirPath := packagerPath .Join ("hardware" ) // ex: .arduino15/packages/arduino/hardware
114
- if hardwareSubdirPath .IsDir () {
115
- // we found the "hardware" directory move down into that
116
- architectureParentPath = hardwareSubdirPath // ex: .arduino15/packages/arduino/
110
+ if managed {
111
+ // 1. Inside the Boards Manager .arduino15/packages directory:
112
+ // PACKAGER/hardware/ARCHITECTURE-1/VERSION/boards.txt... (ex: arduino/hardware/avr/1.6.15/...)
113
+ // PACKAGER/hardware/ARCHITECTURE-2/VERSION/boards.txt... (ex: arduino/hardware/sam/1.6.6/...)
114
+ // PACKAGER/hardware/ARCHITECTURE-3/VERSION/boards.txt... (ex: arduino/hardware/samd/1.6.12/...)
115
+ // PACKAGER/tools/... (ex: arduino/tools/...)
116
+ if p := packagerPath .Join ("hardware" ); p .IsDir () {
117
+ merr = append (merr , pm .loadPlatforms (targetPackage , p , managed )... )
118
+ }
117
119
} else {
118
- // we are already at the correct level
119
- architectureParentPath = packagerPath
120
+ // 2. Inside the sketchbook/hardware directory:
121
+ // PACKAGER/ARCHITECTURE-1/boards.txt... (ex: arduino/avr/...)
122
+ // PACKAGER/ARCHITECTURE-2/boards.txt... (ex: arduino/sam/...)
123
+ // PACKAGER/ARCHITECTURE-3/boards.txt... (ex: arduino/samd/...)
124
+ // ex: .arduino15/packages/arduino/hardware/...
125
+ merr = append (merr , pm .loadPlatforms (targetPackage , packagerPath , managed )... )
120
126
}
121
127
122
- targetPackage := pm .packages .GetOrCreatePackage (packager )
123
- merr = append (merr , pm .loadPlatforms (targetPackage , architectureParentPath )... )
124
-
125
128
// Check if we have tools to load, the directory structure is as follows:
126
129
// - PACKAGER/tools/TOOL-NAME/TOOL-VERSION/... (ex: arduino/tools/bossac/1.7.0/...)
127
130
toolsSubdirPath := packagerPath .Join ("tools" )
@@ -141,8 +144,8 @@ func (pm *Builder) LoadHardwareFromDirectory(path *paths.Path) []error {
141
144
// loadPlatforms load plaftorms from the specified directory assuming that they belongs
142
145
// to the targetPackage object passed as parameter.
143
146
// A list of gRPC Status error is returned for each Platform failed to load.
144
- func (pm * Builder ) loadPlatforms (targetPackage * cores.Package , packageDir * paths.Path ) []error {
145
- pm .log .Infof ("Loading package %s from: %s" , targetPackage .Name , packageDir )
147
+ func (pm * Builder ) loadPlatforms (targetPackage * cores.Package , packageDir * paths.Path , managed bool ) []error {
148
+ pm .log .Infof ("Loading package %s from: %s (managed=%v) " , targetPackage .Name , packageDir , managed )
146
149
147
150
var merr []error
148
151
@@ -162,7 +165,7 @@ func (pm *Builder) loadPlatforms(targetPackage *cores.Package, packageDir *paths
162
165
if targetArchitecture == "tools" {
163
166
continue
164
167
}
165
- if err := pm .loadPlatform (targetPackage , targetArchitecture , platformPath ); err != nil {
168
+ if err := pm .loadPlatform (targetPackage , targetArchitecture , platformPath , managed ); err != nil {
166
169
merr = append (merr , err )
167
170
}
168
171
}
@@ -173,46 +176,18 @@ func (pm *Builder) loadPlatforms(targetPackage *cores.Package, packageDir *paths
173
176
// loadPlatform loads a single platform and all its installed releases given a platformPath.
174
177
// platformPath must be a directory.
175
178
// Returns a gRPC Status error in case of failures.
176
- func (pm * Builder ) loadPlatform (targetPackage * cores.Package , architecture string , platformPath * paths.Path ) error {
179
+ func (pm * Builder ) loadPlatform (targetPackage * cores.Package , architecture string , platformPath * paths.Path , managed bool ) error {
177
180
// This is not a platform
178
181
if platformPath .IsNotDir () {
179
182
return errors .New (i18n .Tr ("path is not a platform directory: %s" , platformPath ))
180
183
}
181
184
182
185
// There are two possible platform directory structures:
183
- // - ARCHITECTURE/boards.txt
184
- // - ARCHITECTURE/VERSION/boards.txt
185
- // We identify them by checking where is the bords.txt file
186
- possibleBoardTxtPath := platformPath .Join ("boards.txt" )
187
- if exist , err := possibleBoardTxtPath .ExistCheck (); err != nil {
188
- return fmt .Errorf ("%s: %w" , i18n .Tr ("looking for boards.txt in %s" , possibleBoardTxtPath ), err )
189
- } else if exist {
190
- // case: ARCHITECTURE/boards.txt
186
+ if managed {
187
+ // 1. Inside the Boards Manager .arduino15/packages/PACKAGER/hardware/ARCHITECTURE directory:
188
+ // - ARCHITECTURE/VERSION/boards.txt
191
189
192
- platformTxtPath := platformPath .Join ("platform.txt" )
193
- platformProperties , err := properties .SafeLoad (platformTxtPath .String ())
194
- if err != nil {
195
- return fmt .Errorf ("%s: %w" , i18n .Tr ("loading platform.txt" ), err )
196
- }
197
-
198
- versionString := platformProperties .ExpandPropsInString (platformProperties .Get ("version" ))
199
- version , err := semver .Parse (versionString )
200
- if err != nil {
201
- return & cmderrors.InvalidVersionError {Cause : fmt .Errorf ("%s: %s" , platformTxtPath , err )}
202
- }
203
-
204
- platform := targetPackage .GetOrCreatePlatform (architecture )
205
- platform .ManuallyInstalled = true
206
- release := platform .GetOrCreateRelease (version )
207
- if err := pm .loadPlatformRelease (release , platformPath ); err != nil {
208
- return fmt .Errorf ("%s: %w" , i18n .Tr ("loading platform release %s" , release ), err )
209
- }
210
- pm .log .WithField ("platform" , release ).Infof ("Loaded platform" )
211
-
212
- } else {
213
- // case: ARCHITECTURE/VERSION/boards.txt
214
190
// let's dive into VERSION directories
215
-
216
191
versionDirs , err := platformPath .ReadDir ()
217
192
if err != nil {
218
193
return fmt .Errorf ("%s: %w" , i18n .Tr ("reading directory %s" , platformPath ), err )
@@ -237,6 +212,29 @@ func (pm *Builder) loadPlatform(targetPackage *cores.Package, architecture strin
237
212
}
238
213
pm .log .WithField ("platform" , release ).Infof ("Loaded platform" )
239
214
}
215
+ } else {
216
+ // 2. Inside the sketchbook/hardware/PACKAGER/ARCHITECTURE directory:
217
+ // - ARCHITECTURE/boards.txt
218
+
219
+ // Determine platform version from the platform.txt metadata
220
+ platformTxtPath := platformPath .Join ("platform.txt" )
221
+ platformProperties , err := properties .SafeLoad (platformTxtPath .String ())
222
+ if err != nil {
223
+ return fmt .Errorf ("%s: %w" , i18n .Tr ("loading platform.txt" ), err )
224
+ }
225
+
226
+ versionString := platformProperties .ExpandPropsInString (platformProperties .Get ("version" ))
227
+ version , err := semver .Parse (versionString )
228
+ if err != nil {
229
+ return & cmderrors.InvalidVersionError {Cause : fmt .Errorf ("%s: %s" , platformTxtPath , err )}
230
+ }
231
+
232
+ platform := targetPackage .GetOrCreatePlatform (architecture )
233
+ release := platform .GetOrCreateRelease (version )
234
+ if err := pm .loadPlatformRelease (release , platformPath ); err != nil {
235
+ return fmt .Errorf ("%s: %w" , i18n .Tr ("loading platform release %s" , release ), err )
236
+ }
237
+ pm .log .WithField ("platform" , release ).Infof ("Loaded platform" )
240
238
}
241
239
242
240
return nil
0 commit comments