@@ -139,24 +139,10 @@ func Create(req *rpc.CreateRequest, extraUserAgent ...string) (*rpc.CreateRespon
139139 dataDir .Join ("tmp" ),
140140 userAgent ,
141141 )
142-
143- // Create library manager and add libraries directories
144- lm := librariesmanager .NewLibraryManager (
142+ instance .lm = librariesmanager .NewLibraryManager (
145143 dataDir ,
146144 downloadsDir ,
147145 )
148- instance .lm = lm
149-
150- // Add directories of libraries bundled with IDE
151- if bundledLibsDir := configuration .IDEBundledLibrariesDir (configuration .Settings ); bundledLibsDir != nil {
152- lm .AddLibrariesDir (bundledLibsDir , libraries .IDEBuiltIn )
153- }
154-
155- // Add libraries directory from config file
156- lm .AddLibrariesDir (
157- configuration .LibrariesDir (configuration .Settings ),
158- libraries .User ,
159- )
160146
161147 // Save instance
162148 instanceID := instancesCount
@@ -217,9 +203,30 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
217203 pm := instance .PackageManager
218204 pm .Clear ()
219205
220- // Load Platforms
206+ // Try to extract profile if specified
207+ var profile * sketch.Profile
208+ if req .GetProfile () != "" {
209+ sk , err := sketch .New (paths .New (req .GetSketchPath ()))
210+ if err != nil {
211+ return & arduino.InvalidArgumentError {Cause : err }
212+ }
213+ profile = sk .GetProfile (req .GetProfile ())
214+ responseCallback (& rpc.InitResponse {
215+ Message : & rpc.InitResponse_ProfileSelectedFqbn {
216+ ProfileSelectedFqbn : profile .FQBN ,
217+ },
218+ })
219+ }
220+
221+ loadBuiltinTools := func () []error {
222+ builtinPackage := pm .Packages .GetOrCreatePackage ("builtin" )
223+ return pm .LoadToolsFromPackageDir (builtinPackage , pm .PackagesDir .Join ("builtin" , "tools" ))
224+ }
225+
221226 urls := []string {globals .DefaultIndexURL }
222- urls = append (urls , configuration .Settings .GetStringSlice ("board_manager.additional_urls" )... )
227+ if profile == nil {
228+ urls = append (urls , configuration .Settings .GetStringSlice ("board_manager.additional_urls" )... )
229+ }
223230 for _ , u := range urls {
224231 URL , err := utils .URLParse (u )
225232 if err != nil {
@@ -229,9 +236,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
229236 }
230237
231238 if URL .Scheme == "file" {
232- indexFile := paths .New (URL .Path )
233-
234- _ , err := pm .LoadPackageIndexFromFile (indexFile )
239+ _ , err := pm .LoadPackageIndexFromFile (paths .New (URL .Path ))
235240 if err != nil {
236241 s := status .Newf (codes .FailedPrecondition , tr ("Loading index file: %v" ), err )
237242 responseError (s )
@@ -245,15 +250,30 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
245250 }
246251 }
247252
253+ // Load Platforms
254+ if profile == nil {
255+ for _ , err := range pm .LoadHardware () {
256+ s := & arduino.PlatformLoadingError {Cause : err }
257+ responseError (s .ToRPCStatus ())
258+ }
259+ } else {
260+ // Load platforms from profile
261+ errs := pm .LoadHardwareForProfile (
262+ profile , true , downloadCallback , taskCallback ,
263+ )
264+ for _ , err := range errs {
265+ s := & arduino.PlatformLoadingError {Cause : err }
266+ responseError (s .ToRPCStatus ())
267+ }
268+
269+ // Load "builtin" tools
270+ _ = loadBuiltinTools ()
271+ }
272+
248273 // We load hardware before verifying builtin tools are installed
249274 // otherwise we wouldn't find them and reinstall them each time
250275 // and they would never get reloaded.
251- for _ , err := range pm .LoadHardware () {
252- s := & arduino.PlatformLoadingError {Cause : err }
253- responseError (s .ToRPCStatus ())
254- }
255276
256- // Get builtin tools
257277 builtinToolReleases := []* cores.ToolRelease {}
258278 for name , tool := range pm .Packages .GetOrCreatePackage ("builtin" ).Tools {
259279 latestRelease := tool .LatestRelease ()
@@ -280,7 +300,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
280300 if toolsHaveBeenInstalled {
281301 // We installed at least one new tool after loading hardware
282302 // so we must reload again otherwise we would never found them.
283- for _ , err := range pm . LoadHardware () {
303+ for _ , err := range loadBuiltinTools () {
284304 s := & arduino.PlatformLoadingError {Cause : err }
285305 responseError (s .ToRPCStatus ())
286306 }
@@ -291,7 +311,12 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
291311 responseError (s .ToRPCStatus ())
292312 }
293313
294- lm := instance .lm
314+ // Create library manager and add libraries directories
315+ lm := librariesmanager .NewLibraryManager (
316+ pm .IndexDir ,
317+ pm .DownloadDir ,
318+ )
319+ instance .lm = lm
295320
296321 // Load libraries
297322 for _ , pack := range pm .Packages {
@@ -307,6 +332,57 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
307332 responseError (s )
308333 }
309334
335+ if profile == nil {
336+ // Add directories of libraries bundled with IDE
337+ if bundledLibsDir := configuration .IDEBundledLibrariesDir (configuration .Settings ); bundledLibsDir != nil {
338+ lm .AddLibrariesDir (bundledLibsDir , libraries .IDEBuiltIn )
339+ }
340+
341+ // Add libraries directory from config file
342+ lm .AddLibrariesDir (configuration .LibrariesDir (configuration .Settings ), libraries .User )
343+ } else {
344+ // Load libraries required for profile
345+ for _ , libraryRef := range profile .Libraries {
346+ uid := libraryRef .InternalUniqueIdentifier ()
347+ libRoot := configuration .ProfilesCacheDir (configuration .Settings ).Join (uid )
348+ libDir := libRoot .Join (libraryRef .Library )
349+
350+ if ! libDir .IsDir () {
351+ // Download library
352+ taskCallback (& rpc.TaskProgress {Name : tr ("Downloading library %s" , libraryRef )})
353+ libRelease := lm .Index .FindRelease (& librariesindex.Reference {
354+ Name : libraryRef .Library ,
355+ Version : libraryRef .Version ,
356+ })
357+ if libRelease == nil {
358+ taskCallback (& rpc.TaskProgress {Name : tr ("Library %s not found" , libraryRef )})
359+ err := & arduino.LibraryNotFoundError {Library : libraryRef .Library }
360+ responseError (err .ToRPCStatus ())
361+ continue
362+ }
363+ if err := libRelease .Resource .Download (lm .DownloadsDir , nil , libRelease .String (), downloadCallback ); err != nil {
364+ taskCallback (& rpc.TaskProgress {Name : tr ("Error downloading library %s" , libraryRef )})
365+ e := & arduino.FailedLibraryInstallError {Cause : err }
366+ responseError (e .ToRPCStatus ())
367+ continue
368+ }
369+ taskCallback (& rpc.TaskProgress {Completed : true })
370+
371+ // Install library
372+ taskCallback (& rpc.TaskProgress {Name : tr ("Installing library %s" , libraryRef )})
373+ if err := libRelease .Resource .Install (lm .DownloadsDir , libRoot , libDir ); err != nil {
374+ taskCallback (& rpc.TaskProgress {Name : tr ("Error installing library %s" , libraryRef )})
375+ e := & arduino.FailedLibraryInstallError {Cause : err }
376+ responseError (e .ToRPCStatus ())
377+ continue
378+ }
379+ taskCallback (& rpc.TaskProgress {Completed : true })
380+ }
381+
382+ lm .AddLibrariesDir (libRoot , libraries .User )
383+ }
384+ }
385+
310386 for _ , err := range lm .RescanLibraries () {
311387 s := status .Newf (codes .FailedPrecondition , tr ("Loading libraries: %v" ), err )
312388 responseError (s )
0 commit comments