@@ -21,6 +21,7 @@ import (
2121 "errors"
2222 "fmt"
2323 "net/url"
24+ "path/filepath"
2425 "regexp"
2526 "slices"
2627 "strings"
@@ -349,23 +350,39 @@ func (p *ProfilePlatformReference) UnmarshalYAML(unmarshal func(interface{}) err
349350// ProfileLibraryReference is a reference to a library
350351type ProfileLibraryReference struct {
351352 Library string
352- InstallDir * paths.Path
353353 Version * semver.Version
354+ InstallDir * paths.Path
355+ GitURL * url.URL
354356}
355357
356358// UnmarshalYAML decodes a ProfileLibraryReference from YAML source.
357359func (l * ProfileLibraryReference ) UnmarshalYAML (unmarshal func (interface {}) error ) error {
358360 var dataMap map [string ]any
359361 if err := unmarshal (& dataMap ); err == nil {
360- if installDir , ok := dataMap ["dir" ]; ! ok {
361- return errors .New (i18n .Tr ("invalid library reference: %s" , dataMap ))
362- } else if installDir , ok := installDir .(string ); ! ok {
363- return fmt .Errorf ("%s: %s" , i18n .Tr ("invalid library reference: %s" ), dataMap )
364- } else {
365- l .InstallDir = paths .New (installDir )
366- l .Library = l .InstallDir .Base ()
367- return nil
362+ if installDir , ok := dataMap ["dir" ]; ok {
363+ if installDir , ok := installDir .(string ); ! ok {
364+ return fmt .Errorf ("%s: %s" , i18n .Tr ("invalid library reference: %s" ), dataMap )
365+ } else {
366+ l .InstallDir = paths .New (installDir )
367+ l .Library = l .InstallDir .Base ()
368+ return nil
369+ }
370+ }
371+ if gitUrl , ok := dataMap ["git" ]; ok {
372+ if gitUrlStr , ok := gitUrl .(string ); ! ok {
373+ return fmt .Errorf ("%s: %s" , i18n .Tr ("invalid git library reference: %s" ), dataMap )
374+ } else if parsedUrl , err := url .Parse (gitUrlStr ); err != nil {
375+ return fmt .Errorf ("%s: %w" , i18n .Tr ("invalid git library URL:" ), err )
376+ } else {
377+ l .GitURL = parsedUrl
378+ if l .Library = filepath .Base (parsedUrl .Path ); l .Library == "" {
379+ l .Library = "lib"
380+ }
381+ l .Library = strings .TrimSuffix (l .Library , ".git" )
382+ return nil
383+ }
368384 }
385+ return errors .New (i18n .Tr ("invalid library reference: %s" , dataMap ))
369386 }
370387
371388 var data string
@@ -388,12 +405,18 @@ func (l *ProfileLibraryReference) AsYaml() string {
388405 if l .InstallDir != nil {
389406 return fmt .Sprintf (" - dir: %s\n " , l .InstallDir )
390407 }
408+ if l .GitURL != nil {
409+ return fmt .Sprintf (" - git: %s\n " , l .GitURL )
410+ }
391411 return fmt .Sprintf (" - %s (%s)\n " , l .Library , l .Version )
392412}
393413
394414func (l * ProfileLibraryReference ) String () string {
395415 if l .InstallDir != nil {
396- return fmt .Sprintf ("%s@dir:%s" , l .Library , l .InstallDir )
416+ return "@dir:" + l .InstallDir .String ()
417+ }
418+ if l .GitURL != nil {
419+ return "@git:" + l .GitURL .String ()
397420 }
398421 if l .Version == nil {
399422 return l .Library
@@ -467,6 +490,16 @@ func FromRpcProfileLibraryReference(l *rpc.SketchProfileLibraryReference) (*Prof
467490func (l * ProfileLibraryReference ) InternalUniqueIdentifier () string {
468491 f .Assert (l .InstallDir == nil ,
469492 "InternalUniqueIdentifier should not be called for library references with an install directory" )
493+
494+ if l .GitURL != nil {
495+ id := "git-" + utils .SanitizeName (l .GitURL .Host + l .GitURL .Path + "#" + l .GitURL .Fragment )
496+ if len (id ) > 50 {
497+ id = id [:50 ]
498+ }
499+ h := sha256 .Sum256 ([]byte (l .GitURL .String ()))
500+ return id + "-" + hex .EncodeToString (h [:])[:8 ]
501+ }
502+
470503 id := l .String ()
471504 h := sha256 .Sum256 ([]byte (id ))
472505 res := fmt .Sprintf ("%s_%s" , id , hex .EncodeToString (h [:])[:16 ])
0 commit comments