@@ -21,6 +21,7 @@ import (
2121 "errors"
2222 "fmt"
2323 "net/url"
24+ "path/filepath"
2425 "regexp"
2526 "strings"
2627
@@ -325,23 +326,39 @@ func (p *ProfilePlatformReference) UnmarshalYAML(unmarshal func(interface{}) err
325326// ProfileLibraryReference is a reference to a library
326327type ProfileLibraryReference struct {
327328 Library string
328- InstallDir * paths.Path
329329 Version * semver.Version
330+ InstallDir * paths.Path
331+ GitURL * url.URL
330332}
331333
332334// UnmarshalYAML decodes a ProfileLibraryReference from YAML source.
333335func (l * ProfileLibraryReference ) UnmarshalYAML (unmarshal func (interface {}) error ) error {
334336 var dataMap map [string ]any
335337 if err := unmarshal (& dataMap ); err == nil {
336- if installDir , ok := dataMap ["dir" ]; ! ok {
337- return errors .New (i18n .Tr ("invalid library reference: %s" , dataMap ))
338- } else if installDir , ok := installDir .(string ); ! ok {
339- return fmt .Errorf ("%s: %s" , i18n .Tr ("invalid library reference: %s" ), dataMap )
340- } else {
341- l .InstallDir = paths .New (installDir )
342- l .Library = l .InstallDir .Base ()
343- return nil
338+ if installDir , ok := dataMap ["dir" ]; ok {
339+ if installDir , ok := installDir .(string ); ! ok {
340+ return fmt .Errorf ("%s: %s" , i18n .Tr ("invalid library reference: %s" ), dataMap )
341+ } else {
342+ l .InstallDir = paths .New (installDir )
343+ l .Library = l .InstallDir .Base ()
344+ return nil
345+ }
346+ }
347+ if gitUrl , ok := dataMap ["git" ]; ok {
348+ if gitUrlStr , ok := gitUrl .(string ); ! ok {
349+ return fmt .Errorf ("%s: %s" , i18n .Tr ("invalid git library reference: %s" ), dataMap )
350+ } else if parsedUrl , err := url .Parse (gitUrlStr ); err != nil {
351+ return fmt .Errorf ("%s: %w" , i18n .Tr ("invalid git library URL:" ), err )
352+ } else {
353+ l .GitURL = parsedUrl
354+ if l .Library = filepath .Base (parsedUrl .Path ); l .Library == "" {
355+ l .Library = "lib"
356+ }
357+ l .Library = strings .TrimSuffix (l .Library , ".git" )
358+ return nil
359+ }
344360 }
361+ return errors .New (i18n .Tr ("invalid library reference: %s" , dataMap ))
345362 }
346363
347364 var data string
@@ -364,12 +381,18 @@ func (l *ProfileLibraryReference) AsYaml() string {
364381 if l .InstallDir != nil {
365382 return fmt .Sprintf (" - dir: %s\n " , l .InstallDir )
366383 }
384+ if l .GitURL != nil {
385+ return fmt .Sprintf (" - git: %s\n " , l .GitURL )
386+ }
367387 return fmt .Sprintf (" - %s (%s)\n " , l .Library , l .Version )
368388}
369389
370390func (l * ProfileLibraryReference ) String () string {
371391 if l .InstallDir != nil {
372- return fmt .Sprintf ("%s@dir:%s" , l .Library , l .InstallDir )
392+ return "@dir:" + l .InstallDir .String ()
393+ }
394+ if l .GitURL != nil {
395+ return "@git:" + l .GitURL .String ()
373396 }
374397 return fmt .Sprintf ("%s@%s" , l .Library , l .Version )
375398}
@@ -378,6 +401,16 @@ func (l *ProfileLibraryReference) String() string {
378401func (l * ProfileLibraryReference ) InternalUniqueIdentifier () string {
379402 f .Assert (l .InstallDir == nil ,
380403 "InternalUniqueIdentifier should not be called for library references with an install directory" )
404+
405+ if l .GitURL != nil {
406+ id := "git-" + utils .SanitizeName (l .GitURL .Host + l .GitURL .Path + "#" + l .GitURL .Fragment )
407+ if len (id ) > 50 {
408+ id = id [:50 ]
409+ }
410+ h := sha256 .Sum256 ([]byte (l .GitURL .String ()))
411+ return id + "-" + hex .EncodeToString (h [:])[:8 ]
412+ }
413+
381414 id := l .String ()
382415 h := sha256 .Sum256 ([]byte (id ))
383416 res := fmt .Sprintf ("%s_%s" , id , hex .EncodeToString (h [:])[:16 ])
0 commit comments