z_mirror/fmm
git clone https://git.raiguard.me/z_mirror/fmm
4041dcd
updating
1package fmm 2 3import ( 4"encoding/json" 5"fmt" 6"strings" 7) 8 9type Dependency struct { 10Name string 11Version * Version 12Kind DependencyKind 13Req VersionCmpRes 14} 15 16type DependencyKind uint8 17 18const ( 19DependencyRequired DependencyKind = iota 20DependencyOptional 21DependencyHiddenOptional 22DependencyIncompatible 23DependencyNoLoadOrder 24) 25 26var dependencyKindString = map [DependencyKind ]string { 27DependencyOptional :"? " , 28DependencyHiddenOptional :"(?) " , 29DependencyIncompatible :"! " , 30DependencyNoLoadOrder :"~ " , 31} 32 33func NewDependency (input string ) (* Dependency ,error ) { 34input = strings .TrimSpace (input ) 35 36kind := DependencyRequired 37if strings .HasPrefix (input ,"!" ) { 38kind = DependencyIncompatible 39input = strings .TrimPrefix (input ,"!" ) 40 }else if strings .HasPrefix (input ,"?" ) { 41kind = DependencyOptional 42input = strings .TrimPrefix (input ,"?" ) 43 }else if strings .HasPrefix (input ,"(?)" ) { 44kind = DependencyHiddenOptional 45input = strings .TrimPrefix (input ,"(?)" ) 46 }else if strings .HasPrefix (input ,"~" ) { 47kind = DependencyNoLoadOrder 48input = strings .TrimPrefix (input ,"~" ) 49 } 50 51// Iterate in reverse and find the first non-digit and non-dot 52var ver * Version 53for i := len (input )- 1 ;i >= 0 ;i -- { 54if i > 0 && ! (input [i ]== '.' || (input [i ]>= '0' && input [i ]<= '9' )) { 55parsed ,err := NewVersion (input [i :]) 56if err == nil { 57ver = parsed 58input = strings .TrimSpace (input [:i ]) 59 } 60break 61 } 62 } 63 64req := VersionAny 65if strings .HasSuffix (input ,"<=" ) { 66req = VersionLtEq 67input = strings .TrimSuffix (input ,"<=" ) 68 }else if strings .Contains (input ,"<" ) { 69req = VersionLt 70input = strings .TrimSuffix (input ,"<" ) 71 }else if strings .Contains (input ,">=" ) { 72req = VersionGtEq 73input = strings .TrimSuffix (input ,">=" ) 74 }else if strings .Contains (input ,">" ) { 75req = VersionGt 76input = strings .TrimSuffix (input ,">" ) 77 }else if strings .Contains (input ,"=" ) { 78req = VersionEq 79input = strings .TrimSuffix (input ,"=" ) 80 } 81 82name := strings .TrimSpace (input ) 83 84return & Dependency {name ,ver ,kind ,req },nil 85} 86 87func (d * Dependency )Test (ver * Version )bool { 88if ver == nil { 89return true 90 } 91 92if d .Kind == DependencyIncompatible { 93return false 94 } 95 96if d .Req == VersionAny { 97return true 98 } 99 100return d .Req & ver .Cmp (d .Version )> 0 101} 102 103func (d * Dependency )ToString ()string { 104versionStr := "" 105if d .Version != nil { 106versionStr = d .Version .ToString (false ) 107 } 108return fmt .Sprintf ("%s%s %s %s" ,dependencyKindString [d .Kind ],d .Name ,versionCmpResString [d .Req ],versionStr ) 109} 110 111func (d * Dependency )UnmarshalJSON (data []byte )error { 112var s string 113if err := json .Unmarshal (data ,& s );err != nil { 114return err 115 } 116 117dep ,err := NewDependency (s ) 118if err != nil { 119return err 120 } 121 122d .Name = dep .Name 123d .Version = dep .Version 124d .Kind = dep .Kind 125d .Req = dep .Req 126 127return nil 128}