@@ -21,6 +21,7 @@ import (
21
21
"net/url"
22
22
"path/filepath"
23
23
"strings"
24
+ "time"
24
25
25
26
"github.com/arduino/arduino-cli/commands/cmderrors"
26
27
"github.com/arduino/arduino-cli/commands/internal/instances"
@@ -406,30 +407,59 @@ func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse
406
407
}
407
408
408
409
// UpdateLibrariesIndex updates the library_index.json
409
- func UpdateLibrariesIndex (ctx context.Context , req * rpc.UpdateLibrariesIndexRequest , downloadCB rpc.DownloadProgressCB ) error {
410
+ func UpdateLibrariesIndex (ctx context.Context , req * rpc.UpdateLibrariesIndexRequest , downloadCB rpc.DownloadProgressCB ) ( * rpc. UpdateLibrariesIndexResponse_Result , error ) {
410
411
logrus .Info ("Updating libraries index" )
412
+
411
413
pme , release , err := instances .GetPackageManagerExplorer (req .GetInstance ())
412
414
if err != nil {
413
- return err
415
+ return nil , err
414
416
}
415
417
indexDir := pme .IndexDir
416
418
release ()
417
419
420
+ index := globals .LibrariesIndexResource
421
+ result := func (status rpc.IndexUpdateReport_Status ) * rpc.UpdateLibrariesIndexResponse_Result {
422
+ return & rpc.UpdateLibrariesIndexResponse_Result {
423
+ LibrariesIndex : & rpc.IndexUpdateReport {
424
+ IndexUrl : globals .LibrariesIndexResource .URL .String (),
425
+ Status : status ,
426
+ },
427
+ }
428
+ }
429
+
430
+ // Create the index directory if it doesn't exist
418
431
if err := indexDir .MkdirAll (); err != nil {
419
- return & cmderrors.PermissionDeniedError {Message : tr ("Could not create index directory" ), Cause : err }
432
+ return result ( rpc . IndexUpdateReport_STATUS_FAILED ), & cmderrors.PermissionDeniedError {Message : tr ("Could not create index directory" ), Cause : err }
420
433
}
421
434
435
+ // Check if the index file is already up-to-date
436
+ indexFileName , _ := index .IndexFileName ()
437
+ if info , err := indexDir .Join (indexFileName ).Stat (); err == nil {
438
+ ageSecs := int64 (time .Since (info .ModTime ()).Seconds ())
439
+ if ageSecs < req .GetUpdateIfOlderThanSecs () {
440
+ return result (rpc .IndexUpdateReport_STATUS_ALREADY_UP_TO_DATE ), nil
441
+ }
442
+ }
443
+
444
+ // Perform index update
422
445
if err := globals .LibrariesIndexResource .Download (indexDir , downloadCB ); err != nil {
423
- return err
446
+ return nil , err
424
447
}
425
448
426
- return nil
449
+ return result ( rpc . IndexUpdateReport_STATUS_UPDATED ), nil
427
450
}
428
451
429
452
// UpdateIndex FIXMEDOC
430
- func UpdateIndex (ctx context.Context , req * rpc.UpdateIndexRequest , downloadCB rpc.DownloadProgressCB ) error {
453
+ func UpdateIndex (ctx context.Context , req * rpc.UpdateIndexRequest , downloadCB rpc.DownloadProgressCB ) ( * rpc. UpdateIndexResponse_Result , error ) {
431
454
if ! instances .IsValid (req .GetInstance ()) {
432
- return & cmderrors.InvalidInstanceError {}
455
+ return nil , & cmderrors.InvalidInstanceError {}
456
+ }
457
+
458
+ report := func (indexURL * url.URL , status rpc.IndexUpdateReport_Status ) * rpc.IndexUpdateReport {
459
+ return & rpc.IndexUpdateReport {
460
+ IndexUrl : indexURL .String (),
461
+ Status : status ,
462
+ }
433
463
}
434
464
435
465
indexpath := configuration .DataDir (configuration .Settings )
@@ -440,6 +470,7 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rp
440
470
}
441
471
442
472
failed := false
473
+ result := & rpc.UpdateIndexResponse_Result {}
443
474
for _ , u := range urls {
444
475
URL , err := utils .URLParse (u )
445
476
if err != nil {
@@ -448,6 +479,7 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rp
448
479
downloadCB .Start (u , tr ("Downloading index: %s" , u ))
449
480
downloadCB .End (false , msg )
450
481
failed = true
482
+ result .UpdatedIndexes = append (result .UpdatedIndexes , report (URL , rpc .IndexUpdateReport_STATUS_FAILED ))
451
483
continue
452
484
}
453
485
@@ -460,26 +492,51 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rp
460
492
msg := fmt .Sprintf ("%s: %v" , tr ("Invalid package index in %s" , path ), err )
461
493
downloadCB .End (false , msg )
462
494
failed = true
495
+ result .UpdatedIndexes = append (result .UpdatedIndexes , report (URL , rpc .IndexUpdateReport_STATUS_FAILED ))
463
496
} else {
464
497
downloadCB .End (true , "" )
498
+ result .UpdatedIndexes = append (result .UpdatedIndexes , report (URL , rpc .IndexUpdateReport_STATUS_SKIPPED ))
465
499
}
466
500
continue
467
501
}
468
502
503
+ // Check if the index is up-to-date
469
504
indexResource := resources.IndexResource {URL : URL }
505
+ indexFileName , err := indexResource .IndexFileName ()
506
+ if err != nil {
507
+ downloadCB .Start (u , tr ("Downloading index: %s" , filepath .Base (URL .Path )))
508
+ downloadCB .End (false , tr ("Invalid index URL: %s" , err ))
509
+ failed = true
510
+ result .UpdatedIndexes = append (result .UpdatedIndexes , report (URL , rpc .IndexUpdateReport_STATUS_FAILED ))
511
+ continue
512
+ }
513
+ indexFile := indexpath .Join (indexFileName )
514
+ if info , err := indexFile .Stat (); err == nil {
515
+ ageSecs := int64 (time .Since (info .ModTime ()).Seconds ())
516
+ if ageSecs < req .GetUpdateIfOlderThanSecs () {
517
+ downloadCB .Start (u , tr ("Downloading index: %s" , filepath .Base (URL .Path )))
518
+ downloadCB .End (true , tr ("Index is already up-to-date" ))
519
+ result .UpdatedIndexes = append (result .UpdatedIndexes , report (URL , rpc .IndexUpdateReport_STATUS_ALREADY_UP_TO_DATE ))
520
+ continue
521
+ }
522
+ }
523
+
470
524
if strings .HasSuffix (URL .Host , "arduino.cc" ) && strings .HasSuffix (URL .Path , ".json" ) {
471
525
indexResource .SignatureURL , _ = url .Parse (u ) // should not fail because we already parsed it
472
526
indexResource .SignatureURL .Path += ".sig"
473
527
}
474
528
if err := indexResource .Download (indexpath , downloadCB ); err != nil {
475
529
failed = true
530
+ result .UpdatedIndexes = append (result .UpdatedIndexes , report (URL , rpc .IndexUpdateReport_STATUS_FAILED ))
531
+ } else {
532
+ result .UpdatedIndexes = append (result .UpdatedIndexes , report (URL , rpc .IndexUpdateReport_STATUS_UPDATED ))
476
533
}
477
534
}
478
535
479
536
if failed {
480
- return & cmderrors.FailedDownloadError {Message : tr ("Some indexes could not be updated." )}
537
+ return result , & cmderrors.FailedDownloadError {Message : tr ("Some indexes could not be updated." )}
481
538
}
482
- return nil
539
+ return result , nil
483
540
}
484
541
485
542
// firstUpdate downloads libraries and packages indexes if they don't exist.
@@ -493,7 +550,7 @@ func firstUpdate(ctx context.Context, instance *rpc.Instance, downloadCb func(ms
493
550
// The library_index.json file doesn't exists, that means the CLI is run for the first time
494
551
// so we proceed with the first update that downloads the file
495
552
req := & rpc.UpdateLibrariesIndexRequest {Instance : instance }
496
- if err := UpdateLibrariesIndex (ctx , req , downloadCb ); err != nil {
553
+ if _ , err := UpdateLibrariesIndex (ctx , req , downloadCb ); err != nil {
497
554
return err
498
555
}
499
556
}
@@ -515,7 +572,7 @@ func firstUpdate(ctx context.Context, instance *rpc.Instance, downloadCb func(ms
515
572
// library update we download that file and all the other package indexes from
516
573
// additional_urls
517
574
req := & rpc.UpdateIndexRequest {Instance : instance }
518
- if err := UpdateIndex (ctx , req , downloadCb ); err != nil {
575
+ if _ , err := UpdateIndex (ctx , req , downloadCb ); err != nil {
519
576
return err
520
577
}
521
578
break
0 commit comments