Skip to content

Commit 2c2baa7

Browse files
committed
Added support for git-libraries in profiles
1 parent 5a6331b commit 2c2baa7

File tree

4 files changed

+79
-1
lines changed

4 files changed

+79
-1
lines changed

commands/instances.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,40 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor
388388
continue
389389
}
390390

391+
if libraryRef.GitURL != nil {
392+
uid := libraryRef.InternalUniqueIdentifier()
393+
libRoot := s.settings.ProfilesCacheDir().Join(uid)
394+
libDir := libRoot.Join(libraryRef.Library)
395+
396+
if !libDir.IsDir() {
397+
// Clone repo and install
398+
tmpDir, err := librariesmanager.CloneLibraryGitRepository(ctx, libraryRef.GitURL.String())
399+
if err != nil {
400+
taskCallback(&rpc.TaskProgress{Name: i18n.Tr("Error downloading library %s", libraryRef)})
401+
e := &cmderrors.FailedLibraryInstallError{Cause: err}
402+
responseError(e.GRPCStatus())
403+
continue
404+
}
405+
406+
// Install library into profile cache
407+
copyErr := tmpDir.CopyDirTo(libDir)
408+
_ = tmpDir.RemoveAll()
409+
if copyErr != nil {
410+
taskCallback(&rpc.TaskProgress{Name: i18n.Tr("Error installing library %s", libraryRef)})
411+
e := &cmderrors.FailedLibraryInstallError{Cause: fmt.Errorf("copying library to profile cache: %w", err)}
412+
responseError(e.GRPCStatus())
413+
continue
414+
}
415+
}
416+
417+
lmb.AddLibrariesDir(librariesmanager.LibrariesDir{
418+
Path: libDir,
419+
Location: libraries.Profile,
420+
IsSingleLibrary: true,
421+
})
422+
continue
423+
}
424+
391425
uid := libraryRef.InternalUniqueIdentifier()
392426
libRoot := s.settings.ProfilesCacheDir().Join(uid)
393427
libDir := libRoot.Join(libraryRef.Library)

internal/arduino/sketch/profiles.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"net/url"
24+
"path/filepath"
2425
"regexp"
2526
"slices"
2627
"strings"
@@ -354,6 +355,7 @@ type ProfileLibraryReference struct {
354355
Version *semver.Version
355356
IsDependency bool
356357
InstallDir *paths.Path
358+
GitURL *url.URL
357359
}
358360

359361
// UnmarshalYAML decodes a ProfileLibraryReference from YAML source.
@@ -375,6 +377,19 @@ func (l *ProfileLibraryReference) UnmarshalYAML(unmarshal func(interface{}) erro
375377
}
376378
l.IsDependency = true
377379
// Fallback
380+
} else if gitUrl, ok := dataMap["git"]; ok {
381+
if gitUrlStr, ok := gitUrl.(string); !ok {
382+
return fmt.Errorf("%s: %s", i18n.Tr("invalid library reference"), dataMap)
383+
} else if parsedUrl, err := url.Parse(gitUrlStr); err != nil {
384+
return fmt.Errorf("%s: %w", i18n.Tr("invalid git URL"), err)
385+
} else {
386+
l.GitURL = parsedUrl
387+
if l.Library = filepath.Base(parsedUrl.Path); l.Library == "" {
388+
l.Library = "lib"
389+
}
390+
l.Library = strings.TrimSuffix(l.Library, ".git")
391+
return nil
392+
}
378393
} else {
379394
return fmt.Errorf("%s: %s", i18n.Tr("invalid library reference"), dataMap)
380395
}
@@ -401,6 +416,9 @@ func (l *ProfileLibraryReference) AsYaml() string {
401416
if l.InstallDir != nil {
402417
return fmt.Sprintf(" - dir: %s\n", l.InstallDir)
403418
}
419+
if l.GitURL != nil {
420+
return fmt.Sprintf(" - git: %s\n", l.GitURL)
421+
}
404422
dep := ""
405423
if l.IsDependency {
406424
dep = "dependency: "
@@ -412,6 +430,9 @@ func (l *ProfileLibraryReference) String() string {
412430
if l.InstallDir != nil {
413431
return "@dir:" + l.InstallDir.String()
414432
}
433+
if l.GitURL != nil {
434+
return "@git:" + l.GitURL.String()
435+
}
415436
dep := ""
416437
if l.IsDependency {
417438
dep = " (dep)"
@@ -431,6 +452,14 @@ func (l *ProfileLibraryReference) Match(other *ProfileLibraryReference) bool {
431452
if other.InstallDir != nil {
432453
return false
433454
}
455+
456+
if l.GitURL != nil {
457+
return other.GitURL != nil && l.GitURL.String() == other.GitURL.String()
458+
}
459+
if other.GitURL != nil {
460+
return false
461+
}
462+
434463
if l.Library != other.Library {
435464
return false
436465
}
@@ -494,6 +523,15 @@ func (l *ProfileLibraryReference) InternalUniqueIdentifier() string {
494523
f.Assert(l.InstallDir == nil,
495524
"InternalUniqueIdentifier should not be called for library references with an install directory")
496525

526+
if l.GitURL != nil {
527+
id := "git-" + utils.SanitizeName(l.GitURL.Host+l.GitURL.Path+"#"+l.GitURL.Fragment)
528+
if len(id) > 50 {
529+
id = id[:50]
530+
}
531+
h := sha256.Sum256([]byte(l.GitURL.String()))
532+
return id + "-" + hex.EncodeToString(h[:])[:8]
533+
}
534+
497535
id := l.Library + "@" + l.Version.String()
498536
h := sha256.Sum256([]byte(id))
499537
res := fmt.Sprintf("%s_%s", id, hex.EncodeToString(h[:])[:16])

internal/arduino/sketch/profiles_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,19 @@ func TestProjectFileLibraries(t *testing.T) {
6060
require.NoError(t, err)
6161
require.Len(t, proj.Profiles, 1)
6262
prof := proj.Profiles[0]
63-
require.Len(t, prof.Libraries, 4)
63+
require.Len(t, prof.Libraries, 6)
6464
require.Equal(t, "[email protected]", prof.Libraries[0].String())
6565
require.Equal(t, "@dir:/path/to/system/lib", prof.Libraries[1].String())
6666
require.Equal(t, "@dir:path/to/sketch/lib", prof.Libraries[2].String())
6767
require.Equal(t, "[email protected] (dep)", prof.Libraries[3].String())
68+
require.Equal(t, "@git:https://github.com/username/HelloWorld.git#v2.13", prof.Libraries[4].String())
69+
require.Equal(t, "@git:https://github.com/username/HelloWorld.git#v2.14", prof.Libraries[5].String())
6870
require.Equal(t, "FlashStorage_1.2.3_e525d7c96b27788f", prof.Libraries[0].InternalUniqueIdentifier())
6971
require.Panics(t, func() { prof.Libraries[1].InternalUniqueIdentifier() })
7072
require.Panics(t, func() { prof.Libraries[2].InternalUniqueIdentifier() })
7173
require.Equal(t, "DependencyLib_2.3.4_ecde631facb47ae5", prof.Libraries[3].InternalUniqueIdentifier())
74+
require.Equal(t, "git-github.com_username_HelloWorld.git_v2.13-0c146203", prof.Libraries[4].InternalUniqueIdentifier())
75+
require.Equal(t, "git-github.com_username_HelloWorld.git_v2.14-49f5df7f", prof.Libraries[5].InternalUniqueIdentifier())
7276

7377
orig, err := sketchProj.ReadFile()
7478
require.NoError(t, err)

internal/arduino/sketch/testdata/profiles/profile_with_libraries.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ profiles:
88
- dir: /path/to/system/lib
99
- dir: path/to/sketch/lib
1010
- dependency: DependencyLib (2.3.4)
11+
- git: https://github.com/username/HelloWorld.git#v2.13
12+
- git: https://github.com/username/HelloWorld.git#v2.14
1113

1214
default_profile: giga_any

0 commit comments

Comments
 (0)