gitee.com/h79/goutils@v1.22.10/build/config.go (about) 1 package build 2 3 import ( 4 "regexp" 5 "strconv" 6 "strings" 7 ) 8 9 // Build contains the build configuration section. 10 type Build struct { 11 ID string `yaml:"id,omitempty" json:"id,omitempty"` 12 Goos []string `yaml:"goos,omitempty" json:"goos,omitempty"` 13 GoArch []string `yaml:"goarch,omitempty" json:"goarch,omitempty"` 14 GoArm []string `yaml:"goarm,omitempty" json:"goarm,omitempty"` 15 GoMips []string `yaml:"gomips,omitempty" json:"gomips,omitempty"` 16 GoAmd64 []string `yaml:"goamd64,omitempty" json:"goamd64,omitempty"` 17 Executor map[string]string `yaml:"executor" json:"executor"` //生成的执行文件名,不同的操作系统对应不同的执行文件,"drawin":"projectName-mac",“linux":"projectName-linux","windows":"projectName-win.exe" 18 ModulePath string `yaml:"module_path" json:"module_path"` 19 ProductId string `yaml:"product_id" json:"product_id"` 20 ProjectName string `yaml:"project_name" json:"project_name"` 21 Target string `yaml:"target,omitempty" json:"target,omitempty"` //生成目标目录 22 Dir string `yaml:"dir,omitempty" json:"dir,omitempty"` 23 Main string `yaml:"main,omitempty" json:"main,omitempty"` 24 GoBinary string `yaml:"go_binary,omitempty" json:"go_binary,omitempty"` 25 Command string `yaml:"command,omitempty" json:"command,omitempty"` 26 Package Package `yaml:"package" json:"package"` 27 Details `yaml:",inline" json:",inline"` // nolint: tagliatelle 28 } 29 30 type Details struct { 31 Buildmode string `yaml:"buildmode,omitempty" json:"buildmode,omitempty"` 32 Ldflags StringArray `yaml:"ldflags,omitempty" json:"ldflags,omitempty"` 33 Tags FlagArray `yaml:"tags,omitempty" json:"tags,omitempty"` 34 Flags FlagArray `yaml:"flags,omitempty" json:"flags,omitempty"` 35 AsmFlags StringArray `yaml:"asm_flags,omitempty" json:"asm_flags,omitempty"` 36 GcFlags StringArray `yaml:"gc_flags,omitempty" json:"gc_flags,omitempty"` 37 Env []string `yaml:"env,omitempty" json:"env,omitempty"` 38 } 39 40 type PackCheck func(path, name string, isDir bool) bool 41 type PackCompleted func(out *PackOut, pf *PackFile, completed bool) 42 43 type PackOut struct { 44 Version string `json:"version"` 45 Path string `json:"path"` // ./build 46 PackagePath string `json:"packagePath"` 47 PublishPath string `json:"publishPath"` 48 Name string `json:"name"` // file name 49 Ext string `json:"ext"` // file ext 50 Target string `json:"target"` 51 Url string `json:"url"` 52 Hash string `json:"hash"` // updates.json 文件名(包括路径) 53 Data interface{} `json:"-"` //自定义 54 } 55 56 const ( 57 OutHashFile = 0x00001 // 输出updates.json(hash文件) 58 HashNeedProject = 0x00002 // hash文件需要用程序名 59 HashNeedVersion = 0x00004 // hash文件需要带版本号 60 HashNeedModel = 0x00008 // hash输出带model 61 HashNeedOs = 0x00010 // hash输出带os 62 TargetNeedVersion = 0x00020 63 TargetNeedModel = 0x00040 64 TargetNeedOs = 0x00080 65 TargetNeedDate = 0x00100 66 NeedArchiveHash = 0x02000 // hashFile需要添加到压缩文件中 67 OnlyPackOut = 0x04000 68 NotArchive = 0x08000 //不需要压缩 69 ArchiveVersion = 0x10000 //压缩目录带版本 70 ArchiveProject = 0x20000 //压缩目录带产品名(ProjectName) 71 NotCheckTpl = 0x40000 //不需要检测模板 *.tpl 72 NotCheckPackFile = 0x80000 //不对 exclude, include 检测 73 ) 74 75 var flagMap = map[string]int{ 76 "OutHashFile": OutHashFile, 77 "HashNeedProject": HashNeedProject, // hash文件需要用程序名 78 "HashNeedVersion": HashNeedVersion, // hash文件需要带版本号 79 "HashNeedModel": HashNeedModel, // hash输出带model 80 "HashNeedOs": HashNeedOs, // hash输出带os 81 "TargetNeedVersion": TargetNeedVersion, 82 "TargetNeedModel": TargetNeedModel, 83 "TargetNeedOs": TargetNeedOs, 84 "TargetNeedDate": TargetNeedDate, 85 "NeedArchiveHash": NeedArchiveHash, // hashFile需要添加到压缩文件中 86 "OnlyPackOut": OnlyPackOut, 87 "NotArchive": NotArchive, //不需要压缩 88 "ArchiveVersion": ArchiveVersion, //压缩目录带版本 89 "ArchiveProject": ArchiveProject, //压缩目录带产品名(ProjectName) 90 "NotCheckTpl": NotCheckTpl, //不需要检测模板 *.tpl 91 "NotCheckPackFile": NotCheckPackFile, 92 } 93 94 func AddFlag(f string, bit int) { 95 flagMap[f] = bit 96 } 97 98 func GetFlag(f string) int { 99 ret, ok := flagMap[f] 100 if ok { 101 return ret 102 } 103 return 0 104 } 105 106 type Package struct { 107 ProductCode string `yaml:"productCode" json:"productCode"` //产品编号 108 Model string `yaml:"model" json:"model"` //prod, test, dev 109 Os string `yaml:"os" json:"os"` //操作系统 windows,linux,darwin 110 Format string `yaml:"format" json:"format"` //zip, tar.gz, tgz, tar, cab(windows), setup 111 Dist string `yaml:"dist" json:"dist"` //输出目录 112 PackagePath string `yaml:"packagePath" json:"packagePath"` // 包目录 dist/package_path, 默认 dist/packages 113 PublishPath string `yaml:"publishPath" json:"publishPath"` // 发布目录 dist/publish_path 默认 dist/publishes 114 Target string `yaml:"target" json:"target"` //输出文件名,可以为空 115 Hash string `yaml:"hash" json:"hash"` //输出pack 总的包描述文件,如: updates.json 116 BaseUrl string `yaml:"baseUrl" json:"baseUrl"` //文件存储基本地址(oss,如阿里云) 117 MgrHost string `yaml:"mgrHost" json:"mgrHost"` //版本管理后台host,需要把打包的信息保存到后台进行管理,比如: http://xxx.com:port 118 Flag string `yaml:"flag" json:"flag"` //标识 @see OutHashFile 119 Exclude []string `yaml:"exclude" json:"exclude"` //打包不包括的选项 120 Include []string `yaml:"include" json:"include"` //打包包括的选项 121 flag Bit 122 excludeR []Regex 123 includeR []Regex 124 excludeCheck PackCheck 125 includeCheck PackCheck 126 packCompleted PackCompleted 127 } 128 129 type Bit int32 130 131 func ToBit(b string) Bit { 132 var ret int 133 bits := strings.Split(b, "|") 134 for i := range bits { 135 bit, err := strconv.Atoi(bits[i]) 136 if err != nil { 137 bit = GetFlag(bits[i]) 138 } 139 ret |= bit 140 } 141 return Bit(ret) 142 } 143 144 func (a Bit) Bit(bit int32) bool { 145 return int32(a)&bit == bit 146 } 147 148 type Regex struct { 149 Path bool 150 Exp *regexp.Regexp 151 } 152 153 func (p *Package) Parse() { 154 p.flag = ToBit(p.Flag) 155 } 156 157 func (p *Package) IsFlag(o int32) bool { 158 return p.flag.Bit(o) 159 } 160 161 func (p *Package) WithExcludeCheck(check PackCheck) { 162 p.excludeCheck = check 163 } 164 165 func (p *Package) WithIncludeCheck(check PackCheck) { 166 p.includeCheck = check 167 } 168 169 func (p *Package) WithCompleted(check PackCompleted) { 170 p.packCompleted = check 171 } 172 173 func (p *Package) buildCheck() { 174 if len(p.Exclude) > 0 && len(p.excludeR) == 0 { 175 p.excludeR = make([]Regex, len(p.Exclude)) 176 } 177 if len(p.Include) > 0 && len(p.includeR) == 0 { 178 p.includeR = make([]Regex, len(p.Include)) 179 } 180 } 181 182 const ( 183 RegexPrefix = "regex|" 184 PathPrefix = "path|" 185 ) 186 187 func (p *Package) IncludeCheck(path, name string, isDir bool) bool { 188 p.buildCheck() 189 if p.includeCheck != nil { 190 if p.includeCheck(path, name, isDir) { 191 return true 192 } 193 } 194 for i := range p.Include { 195 if strings.EqualFold(p.Include[i], name) { 196 return true 197 } 198 if p.includeR[i].Exp == nil { 199 if strings.HasPrefix(p.Include[i], RegexPrefix) { 200 p.includeR[i].Exp, _ = regexp.Compile(strings.TrimPrefix(p.Include[i], RegexPrefix)) 201 } else if strings.HasPrefix(p.Include[i], PathPrefix) { 202 p.includeR[i].Exp, _ = regexp.Compile(strings.TrimPrefix(p.Include[i], PathPrefix)) 203 p.includeR[i].Path = true 204 } 205 if p.includeR[i].Exp == nil { 206 continue 207 } 208 } 209 if p.includeR[i].Path && isDir { 210 if path != "" && p.includeR[i].Exp.MatchString(path) { 211 return true 212 } 213 } else if p.includeR[i].Exp.MatchString(name) { 214 return true 215 } 216 } 217 return false 218 } 219 220 func (p *Package) ExcludeCheck(path, name string, isDir bool) bool { 221 p.buildCheck() 222 if p.excludeCheck != nil { 223 if p.excludeCheck(path, name, isDir) { 224 return true 225 } 226 } 227 for i := range p.Exclude { 228 if strings.EqualFold(p.Exclude[i], name) { 229 return true 230 } 231 if p.excludeR[i].Exp == nil { 232 if strings.HasPrefix(p.Exclude[i], RegexPrefix) { 233 p.excludeR[i].Exp, _ = regexp.Compile(strings.TrimPrefix(p.Exclude[i], RegexPrefix)) 234 } else if strings.HasPrefix(p.Exclude[i], PathPrefix) { 235 p.excludeR[i].Exp, _ = regexp.Compile(strings.TrimPrefix(p.Exclude[i], PathPrefix)) 236 p.excludeR[i].Path = true 237 } 238 if p.excludeR[i].Exp == nil { 239 continue 240 } 241 } 242 if p.excludeR[i].Path { 243 if isDir && path != "" && p.excludeR[i].Exp.MatchString(path) { 244 return true 245 } 246 } else if p.excludeR[i].Exp.MatchString(name) { 247 return true 248 } 249 } 250 return false 251 } 252 253 func (p *Package) Ignore(path, name string, isDir bool) bool { 254 if p.IsFlag(NotCheckPackFile) { 255 return false 256 } 257 ss := strings.ToLower(name) 258 if p.CheckOs(ss) { 259 return true 260 } 261 if p.IncludeCheck(path, ss, isDir) { 262 return false 263 } 264 if p.ExcludeCheck(path, ss, isDir) { 265 return true 266 } 267 return false 268 } 269 270 func (p *Package) CheckOs(name string) bool { 271 if p.Model != "" { 272 if strings.HasPrefix(name, "dev") && p.Model != "dev" { 273 return true 274 } 275 if strings.HasPrefix(name, "prod") && p.Model != "prod" { 276 return true 277 } 278 if strings.HasPrefix(name, "test") && p.Model != "test" { 279 return true 280 } 281 } 282 if p.Os != "" { 283 if p.Os == "windows" { 284 if strings.HasSuffix(name, ".sh") || 285 strings.HasSuffix(name, "-mac") || 286 strings.HasSuffix(name, "-linux") || 287 strings.HasSuffix(name, ".so") { 288 return true 289 } 290 } else { 291 if p.Os == "darwin" { 292 if strings.HasSuffix(name, "-linux") { 293 return true 294 } 295 } else if p.Os == "linux" { 296 if strings.HasSuffix(name, "-mac") { 297 return true 298 } 299 } 300 if strings.HasSuffix(name, ".bat") || 301 strings.HasSuffix(name, ".exe") || 302 strings.HasSuffix(name, ".dll") { 303 return true 304 } 305 } 306 } 307 return strings.HasSuffix(name, ".lib") || 308 strings.HasSuffix(name, ".go") || 309 strings.HasSuffix(name, ".c") || 310 strings.HasSuffix(name, ".h") 311 } 312 313 type PackFile struct { 314 Name string `json:"name"` 315 MD5 string `json:"md5"` 316 Size int64 `json:"size"` 317 Url string `json:"url,omitempty"` 318 } 319 320 type HashFile struct { 321 Os string `json:"os"` 322 Version string `json:"version"` 323 Model string `json:"model"` 324 ProductId string `json:"product_id"` 325 ProductCode string `json:"product_code"` 326 ProjectName string `json:"project_name"` 327 Packs []PackFile `json:"files"` 328 } 329 330 // StringArray is a wrapper for an array of strings. 331 type StringArray []string 332 333 type FlagArray []string