diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c671fe2..2937e10 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '1.20' + go-version: '1.21' - run: go build -o bin/${{ github.event.repository.name }}_linux_x64 . - run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o bin/${{ github.event.repository.name }}_win_x64.exe diff --git a/README.md b/README.md index 5e92067..9b19d98 100644 --- a/README.md +++ b/README.md @@ -121,11 +121,15 @@ table_export -g csv_test,csv_test.csv # TODO -在1.0版本中会加入数据检测,自定义复合类型,自定义枚举,特殊后处理等功能。 - +目前1.0版本中已经支持,后续会更新使用文档 + - 数据检测 + - 自定义复合类型(使用go或者js脚本扩展) + - 自定义枚举 +TODO :添加特殊后处理等功能。 ## Credits - [LuaTableOptimizer](https://github.com/lujian101/LuaTableOptimizer) 使用了lua表优化工具,在此基础上做了更进一步的优化 -- [luban](https://github.com/focus-creative-games/luban) 使用了二进制序列化的代码和一些思路 \ No newline at end of file +- [luban](https://github.com/focus-creative-games/luban) 使用了二进制序列化的代码和一些思路 +- [goja](https://github.com/dop251/goja) js的脚本引擎,使用js来扩展自定义类型和表后处理 \ No newline at end of file diff --git a/component/goja/table_engine/module.go b/component/goja/table_engine/module.go new file mode 100644 index 0000000..df95b0f --- /dev/null +++ b/component/goja/table_engine/module.go @@ -0,0 +1,90 @@ +package table_engine + +import ( + "github.com/821869798/table-export/config" + "github.com/821869798/table-export/field_type" + "github.com/dop251/goja" + "github.com/dop251/goja_nodejs/require" + _ "github.com/dop251/goja_nodejs/util" +) + +type TableEngine struct { + runtime *goja.Runtime + //util *goja.Object +} + +func (c *TableEngine) NewTableFieldClass(name string) *field_type.TableFieldClass { + return field_type.NewTableFieldClass(name) +} + +func (c *TableEngine) NewTableFieldType(fieldType int) *field_type.TableFieldType { + return field_type.NewTableFieldType(field_type.EFieldType(fieldType)) +} + +func (c *TableEngine) NewTableFieldEnumType(name string) *field_type.TableFieldType { + return field_type.NewTableFieldEnumType(name) +} + +func (c *TableEngine) NewTableFieldArrayType(value *field_type.TableFieldType) *field_type.TableFieldType { + return field_type.NewTableFieldArrayType(value) +} + +func (c *TableEngine) NewTableFieldMapType(key *field_type.TableFieldType, value *field_type.TableFieldType) *field_type.TableFieldType { + return field_type.NewTableFieldMapType(key, value) +} + +func (c *TableEngine) NewTableFieldClassType(class *field_type.TableFieldClass) *field_type.TableFieldType { + return field_type.NewTableFieldClassType(class) +} + +//func (c *TableEngine) log(p func(string)) func(goja.FunctionCall) goja.Value { +// return func(call goja.FunctionCall) goja.Value { +// if format, ok := goja.AssertFunction(c.util.Get("format")); ok { +// ret, err := format(c.util, call.Arguments...) +// if err != nil { +// panic(err) +// } +// +// p(ret.String()) +// } else { +// panic(c.runtime.NewTypeError("util.format is not a function")) +// } +// +// return nil +// } +//} + +func Require(runtime *goja.Runtime, module *goja.Object) { + requireWithPrinter()(runtime, module) +} + +func RequireWithPrinter() require.ModuleLoader { + return requireWithPrinter() +} + +func requireWithPrinter() require.ModuleLoader { + return func(runtime *goja.Runtime, module *goja.Object) { + c := &TableEngine{ + runtime: runtime, + } + + //c.util = require.Require(runtime, "util").(*goja.Object) + + o := module.Get("exports").(*goja.Object) + o.Set("NewTableFieldClass", c.NewTableFieldClass) + o.Set("NewTableFieldType", c.NewTableFieldType) + o.Set("NewTableFieldEnumType", c.NewTableFieldEnumType) + o.Set("NewTableFieldArrayType", c.NewTableFieldArrayType) + o.Set("NewTableFieldMapType", c.NewTableFieldMapType) + o.Set("NewTableFieldClassType", c.NewTableFieldClassType) + o.Set("TableConfig", config.GlobalConfig.Table) + } +} + +func Enable(runtime *goja.Runtime) { + runtime.Set("tableEngine", require.Require(runtime, "tableEngine")) +} + +func init() { + require.RegisterNativeModule("tableEngine", Require) +} diff --git a/config/config_rule.go b/config/config_rule.go index 2f0e4ef..fc04181 100644 --- a/config/config_rule.go +++ b/config/config_rule.go @@ -42,42 +42,3 @@ type RawMetaRuleUnitLua struct { func (r *RawMetaRuleUnitLua) RuleExportType() ExportType { return ExportType_Lua } - -type RawMetaRuleUnitCSBin struct { - CodeTempDir string `toml:"code_temp_dir"` - DataTempDir string `toml:"data_temp_dir"` - GenCodeDir string `toml:"gen_code_dir"` - DataBinDir string `toml:"data_bin_dir"` - GenCodeNamespace string `toml:"code_namespace"` - GenCodeHead string `toml:"gen_code_head"` - CodeNotFoundKey string `toml:"code_not_found_key"` - GenOptimizeData bool `toml:"gen_optimize"` - EnumFiles []string `toml:"enum_files"` - EnumDefinePrefix string `toml:"enum_define_prefix"` - ClassDefinePrefix string `toml:"class_define_prefix"` - BuiltinFieldTypes []string `toml:"builtin_field_types"` -} - -func (r *RawMetaRuleUnitCSBin) RuleExportType() ExportType { - return ExportType_CS_Bin -} - -func (r *RawMetaRuleUnitCSBin) ActiveOptimizeData() bool { - return r.GenOptimizeData -} - -func (r *RawMetaRuleUnitCSBin) GetEnumFiles() []string { - return r.EnumFiles -} - -func (r *RawMetaRuleUnitCSBin) GetEnumDefinePrefix() string { - return r.EnumDefinePrefix -} - -func (r *RawMetaRuleUnitCSBin) GetClassDefinePrefix() string { - return r.ClassDefinePrefix -} - -func (r *RawMetaRuleUnitCSBin) GetBuiltinFieldTypes() []string { - return r.BuiltinFieldTypes -} diff --git a/config/config_rule_csbin.go b/config/config_rule_csbin.go new file mode 100644 index 0000000..ee2095e --- /dev/null +++ b/config/config_rule_csbin.go @@ -0,0 +1,45 @@ +package config + +type RawMetaRuleUnitCSBin struct { + CodeTempDir string `toml:"code_temp_dir"` + DataTempDir string `toml:"data_temp_dir"` + GenCodeDir string `toml:"gen_code_dir"` + DataBinDir string `toml:"data_bin_dir"` + GenCodeNamespace string `toml:"code_namespace"` + GenCodeHead string `toml:"gen_code_head"` + CodeNotFoundKey string `toml:"code_not_found_key"` + GenOptimizeData bool `toml:"gen_optimize"` + EnumFiles []string `toml:"enum_files"` + EnumDefinePrefix string `toml:"enum_define_prefix"` + ClassDefinePrefix string `toml:"class_define_prefix"` + BuiltinFieldTypes []string `toml:"builtin_field_types"` + ScriptFieldTypes []string `toml:"script_field_types"` +} + +func (r *RawMetaRuleUnitCSBin) RuleExportType() ExportType { + return ExportType_CS_Bin +} + +func (r *RawMetaRuleUnitCSBin) ActiveOptimizeData() bool { + return r.GenOptimizeData +} + +func (r *RawMetaRuleUnitCSBin) GetEnumFiles() []string { + return r.EnumFiles +} + +func (r *RawMetaRuleUnitCSBin) GetEnumDefinePrefix() string { + return r.EnumDefinePrefix +} + +func (r *RawMetaRuleUnitCSBin) GetClassDefinePrefix() string { + return r.ClassDefinePrefix +} + +func (r *RawMetaRuleUnitCSBin) GetBuiltinFieldTypes() []string { + return r.BuiltinFieldTypes +} + +func (r *RawMetaRuleUnitCSBin) GetExtFieldTypeScriptPath() []string { + return r.ScriptFieldTypes +} diff --git a/config/define.go b/config/define.go index 3093bd2..7beda7a 100644 --- a/config/define.go +++ b/config/define.go @@ -22,4 +22,5 @@ type MetaRuleUnitPlus interface { GetEnumDefinePrefix() string GetClassDefinePrefix() string GetBuiltinFieldTypes() []string + GetExtFieldTypeScriptPath() []string } diff --git a/convert/apiconvert/idatavisitor.go b/convert/apiconvert/idatavisitor.go index 7cc26a6..50dc371 100644 --- a/convert/apiconvert/idatavisitor.go +++ b/convert/apiconvert/idatavisitor.go @@ -23,4 +23,5 @@ type IDataVisitor interface { AcceptCommonMap(r map[interface{}]interface{}, KeyType *field_type.TableFieldType, ValueType *field_type.TableFieldType) AcceptClass(r map[string]interface{}, class *field_type.TableFieldClass) AcceptClassString(r map[string]string, class *field_type.TableFieldClass) + AcceptClassNull(class *field_type.TableFieldClass) } diff --git a/convert/visitor/binary.go b/convert/visitor/binary.go index eafa41f..16bcf77 100644 --- a/convert/visitor/binary.go +++ b/convert/visitor/binary.go @@ -202,3 +202,13 @@ func (b *BinaryVisitor) AcceptClassString(r map[string]string, class *field_type } } } + +func (b *BinaryVisitor) AcceptClassNull(class *field_type.TableFieldClass) { + for _, field := range class.AllFields() { + // 使用默认值解析 + err := wrap.RunDataVisitorString(b, field.Type, "") + if err != nil { + slog.Fatalf("export binary AcceptClass failed: %v", err) + } + } +} diff --git a/convert/wrap/wrap_class.go b/convert/wrap/wrap_class.go index 9bd0b93..ef8f202 100644 --- a/convert/wrap/wrap_class.go +++ b/convert/wrap/wrap_class.go @@ -34,6 +34,10 @@ func (c *classWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType } func (c *classWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error { + if origin == nil { + visitor.AcceptClassNull(fieldType.Class) + return nil + } switch value := origin.(type) { case map[string]interface{}: visitor.AcceptClass(value, fieldType.Class) @@ -44,7 +48,7 @@ func (c *classWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType case string: return RunDataVisitorString(visitor, fieldType, value) default: - return errors.New(fmt.Sprintf("[DataVisitorValue|map] no support type[%T]", origin)) + return errors.New(fmt.Sprintf("[DataVisitorValue|class] no support type[%T]", origin)) } } diff --git a/convert/wrap/wrap_double.go b/convert/wrap/wrap_double.go index 48b26d0..12bebaa 100644 --- a/convert/wrap/wrap_double.go +++ b/convert/wrap/wrap_double.go @@ -59,16 +59,21 @@ func (b *doubleWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldTyp } func (b *doubleWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error { - value, ok := origin.(float64) - if ok { + switch value := origin.(type) { + case float64: visitor.AcceptDouble(value) return nil + case float32: + visitor.AcceptDouble(float64(value)) + return nil + case int64: + visitor.AcceptDouble(float64(value)) + return nil + case string: + return b.DataVisitorString(visitor, fieldType, value) + default: + return errors.New(fmt.Sprintf("[DataVisitorValue|double] no support type[%T]", origin)) } - stringValue, ok := origin.(string) - if ok { - return b.DataVisitorString(visitor, fieldType, stringValue) - } - return errors.New(fmt.Sprintf("[DataVisitorValue|double] no support type[%T]", origin)) } func (b *doubleWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string { diff --git a/convert/wrap/wrap_enum.go b/convert/wrap/wrap_enum.go index 4bbdc69..af2bd3e 100644 --- a/convert/wrap/wrap_enum.go +++ b/convert/wrap/wrap_enum.go @@ -84,6 +84,9 @@ func (e *enumWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType * case int: visitor.AcceptInt(int32(value)) return nil + case float64: + visitor.AcceptInt(int32(value)) + return nil case string: return e.DataVisitorString(visitor, fieldType, value) default: diff --git a/convert/wrap/wrap_float.go b/convert/wrap/wrap_float.go index a8a8c97..50e3f18 100644 --- a/convert/wrap/wrap_float.go +++ b/convert/wrap/wrap_float.go @@ -70,6 +70,9 @@ func (b *floatWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType case float64: visitor.AcceptFloat(float32(value)) return nil + case int64: + visitor.AcceptFloat(float32(value)) + return nil case string: return b.DataVisitorString(visitor, fieldType, value) default: diff --git a/convert/wrap/wrap_int.go b/convert/wrap/wrap_int.go index 0b6a658..2ea4ece 100644 --- a/convert/wrap/wrap_int.go +++ b/convert/wrap/wrap_int.go @@ -69,6 +69,9 @@ func (b *intWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *f case int: visitor.AcceptInt(int32(value)) return nil + case float64: + visitor.AcceptInt(int32(value)) + return nil case string: return b.DataVisitorString(visitor, fieldType, value) default: diff --git a/convert/wrap/wrap_long.go b/convert/wrap/wrap_long.go index a124195..342fd5e 100644 --- a/convert/wrap/wrap_long.go +++ b/convert/wrap/wrap_long.go @@ -59,16 +59,24 @@ func (b *longWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType } func (b *longWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error { - value, ok := origin.(int64) - if ok { + switch value := origin.(type) { + case int64: visitor.AcceptLong(value) return nil + case int32: + visitor.AcceptLong(int64(value)) + return nil + case int: + visitor.AcceptLong(int64(value)) + return nil + case float64: + visitor.AcceptLong(int64(value)) + return nil + case string: + return b.DataVisitorString(visitor, fieldType, value) + default: + return errors.New(fmt.Sprintf("[DataVisitorValue|long] no support type[%T]", origin)) } - stringValue, ok := origin.(string) - if ok { - return b.DataVisitorString(visitor, fieldType, stringValue) - } - return errors.New(fmt.Sprintf("[DataVisitorValue|long] no support type[%T]", origin)) } func (b *longWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string { diff --git a/convert/wrap/wrap_uint.go b/convert/wrap/wrap_uint.go index b43e8a6..76d823a 100644 --- a/convert/wrap/wrap_uint.go +++ b/convert/wrap/wrap_uint.go @@ -70,6 +70,18 @@ func (b *uintWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType * case uint64: visitor.AcceptUInt(uint32(value)) return nil + case int: + visitor.AcceptUInt(uint32(value)) + return nil + case float64: + visitor.AcceptUInt(uint32(value)) + return nil + case int64: + visitor.AcceptUInt(uint32(value)) + return nil + case int32: + visitor.AcceptUInt(uint32(value)) + return nil case string: return b.DataVisitorString(visitor, fieldType, value) default: diff --git a/convert/wrap/wrap_ulong.go b/convert/wrap/wrap_ulong.go index ab8f1a8..cf40c3a 100644 --- a/convert/wrap/wrap_ulong.go +++ b/convert/wrap/wrap_ulong.go @@ -59,16 +59,30 @@ func (b *ulongWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType } func (b *ulongWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error { - value, ok := origin.(uint64) - if ok { + switch value := origin.(type) { + case uint64: visitor.AcceptULong(value) return nil + case uint32: + visitor.AcceptULong(uint64(value)) + return nil + case int: + visitor.AcceptULong(uint64(value)) + return nil + case float64: + visitor.AcceptULong(uint64(value)) + return nil + case int64: + visitor.AcceptULong(uint64(value)) + return nil + case int32: + visitor.AcceptULong(uint64(value)) + return nil + case string: + return b.DataVisitorString(visitor, fieldType, value) + default: + return errors.New(fmt.Sprintf("[DataVisitorValue|ulong] no support type[%T]", origin)) } - stringValue, ok := origin.(string) - if ok { - return b.DataVisitorString(visitor, fieldType, stringValue) - } - return errors.New(fmt.Sprintf("[DataVisitorValue|ulong] no support type[%T]", origin)) } func (b *ulongWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string { diff --git a/examples/conf/config.toml b/examples/conf/config.toml index 9ee11c9..3efc381 100644 --- a/examples/conf/config.toml +++ b/examples/conf/config.toml @@ -69,7 +69,7 @@ Debug.LogError($"[%s] config id not found,id:{%s}"); gen_optimize = true # 枚举文件路径集,可以支持多个,以及*或**匹配 enum_files = [ - "./cs_bin_config/enum_define/*.toml", + "./cs_bin_config/enum_define/**/*.toml", ] # 枚举,统一添加一个的前缀名,可为空 enum_define_prefix = "" @@ -81,5 +81,8 @@ Debug.LogError($"[%s] config id not found,id:{%s}"); "KVList_IntInt", "KVList_IntFloat", ] - + # 用脚本实现的扩展类型 + script_field_types = [ + "./cs_bin_config/scripts/ext_field/**/*.js", + ] diff --git a/examples/cs_bin_config/scripts/common/table-lib.js b/examples/cs_bin_config/scripts/common/table-lib.js new file mode 100644 index 0000000..e71ddd4 --- /dev/null +++ b/examples/cs_bin_config/scripts/common/table-lib.js @@ -0,0 +1,19 @@ +const eFieldType = { + None: 0, + Int: 1, + UInt: 2, + Long: 3, + ULong: 4, + Bool: 5, + Float: 6, + Double: 7, + String: 8, + Enum: 9, + Slice: 10, + Map: 11, + Class: 12 +} + +module.exports = { + eFieldType +} \ No newline at end of file diff --git a/examples/cs_bin_config/scripts/ext_field/field-vector3.js b/examples/cs_bin_config/scripts/ext_field/field-vector3.js new file mode 100644 index 0000000..5e4bea4 --- /dev/null +++ b/examples/cs_bin_config/scripts/ext_field/field-vector3.js @@ -0,0 +1,45 @@ +const {eFieldType} = require('../common/table-lib'); + +const TypeName = "TestVector3"; + +var ftc = tableEngine.NewTableFieldClass(TypeName); +ftc.AddField("x", tableEngine.NewTableFieldType(eFieldType.Float)); +ftc.AddField("y", tableEngine.NewTableFieldType(eFieldType.Float)); +ftc.AddField("z", tableEngine.NewTableFieldType(eFieldType.Float)); + +const fieldType = tableEngine.NewTableFieldClassType(ftc); + +const ArraySplit = tableEngine.TableConfig.ArraySplit; + +const extFieldVector3 = { + Name() { + return TypeName; + }, + DefineFile() { + return "CfgMath"; + }, + TableFieldType() { + return fieldType; + }, + ParseOriginData(origin, context) { + origin = origin.trim(); + if (origin.length === 0) { + return { x : 0, y: 0, z: 0}; + } + const stringArray = origin.split(ArraySplit); + if (stringArray.length === 0) { + return { x : 0, y: 0, z: 0}; + } + if (stringArray.length !== 3) { + context.Error = "Vector3 Parse Error,param count must be 3 or 0: " + origin; + //console.error("js error:" + origin); + return null + } + const x = parseFloat(stringArray[0]); + const y = parseFloat(stringArray[1]); + const z = parseFloat(stringArray[2]); + return { x : x, y: y, z: z}; + } +} + +module.exports = extFieldVector3; \ No newline at end of file diff --git a/examples/cs_bin_config/table_meta/base_test.toml b/examples/cs_bin_config/table_meta/base_test.toml index 88dce5e..c26f548 100644 --- a/examples/cs_bin_config/table_meta/base_test.toml +++ b/examples/cs_bin_config/table_meta/base_test.toml @@ -19,6 +19,7 @@ fields = [ { active = true, sname = "condition_type" , tname = "conditionType" , type = "ConditionType" , key = 0, desc = "条件类型,测试枚举2"}, { active = true, sname = "position", tname = "position", type = "PointInt", key = 0, desc = "位置"}, { active = true, sname = "rewards", tname = "rewards", type = "KVList_IntInt", key = 0, desc = "奖励"}, + { active = true, sname = "vector3", tname = "vector3", type = "TestVector3", key = 0, desc = "测试使用脚本自定义字段类型" } ] # 数据检测示例,$代表一行数据,table代表当前表,global代表全局,global[name]可以取到其他表的数据 diff --git a/examples/excels/base_test.xlsx b/examples/excels/base_test.xlsx index 1ccd565..e307525 100644 Binary files a/examples/excels/base_test.xlsx and b/examples/excels/base_test.xlsx differ diff --git a/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs b/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs index cbda6c4..8f51b92 100644 --- a/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs +++ b/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs @@ -12,7 +12,6 @@ public partial class KVList_IntInt public KVList_IntInt(ByteBuf _buf) { - {int __n0 = _buf.ReadSize(); keys = new int[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int __v0; __v0 = _buf.ReadInt(); keys[__i0] = __v0; } } {int __n0 = _buf.ReadSize(); values = new int[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int __v0; __v0 = _buf.ReadInt(); values[__i0] = __v0; } } PostInit(); @@ -31,7 +30,6 @@ public partial class KVList_IntFloat public KVList_IntFloat(ByteBuf _buf) { - {int __n0 = _buf.ReadSize(); keys = new int[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int __v0; __v0 = _buf.ReadInt(); keys[__i0] = __v0; } } {int __n0 = _buf.ReadSize(); values = new float[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ float __v0; __v0 = _buf.ReadFloat(); values[__i0] = __v0; } } PostInit(); diff --git a/examples/projects/proj_cs_bin/src/gen/CfgMath.cs b/examples/projects/proj_cs_bin/src/gen/CfgMath.cs index e2c7940..7d185b2 100644 --- a/examples/projects/proj_cs_bin/src/gen/CfgMath.cs +++ b/examples/projects/proj_cs_bin/src/gen/CfgMath.cs @@ -12,7 +12,6 @@ public partial class PointInt public PointInt(ByteBuf _buf) { - x = _buf.ReadInt(); y = _buf.ReadInt(); PostInit(); @@ -24,4 +23,24 @@ public PointInt(ByteBuf _buf) partial void PostInit(); } + public partial class TestVector3 + { + public float x { get; private set; } + public float y { get; private set; } + public float z { get; private set; } + + public TestVector3(ByteBuf _buf) + { + x = _buf.ReadFloat(); + y = _buf.ReadFloat(); + z = _buf.ReadFloat(); + PostInit(); + } + + /// + /// post process ext class + /// + partial void PostInit(); + } + } diff --git a/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs b/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs index dd2483e..7482cd9 100644 --- a/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs +++ b/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs @@ -77,6 +77,7 @@ private Cfgbase_test(ByteBuf _buf, _TbCommonbase_test _commonData) conditionType = (ConditionType)_buf.ReadInt(); { int dataIndex = _buf.ReadInt() - 1; position = _commonData._field2[dataIndex]; } { int dataIndex = _buf.ReadInt() - 1; rewards = _commonData._field3[dataIndex]; } + { int dataIndex = _buf.ReadInt() - 1; vector3 = _commonData._field4[dataIndex]; } PostInit(); } @@ -130,6 +131,11 @@ internal static Cfgbase_test DeserializeCfgbase_test(ByteBuf _buf, _TbCommonbase /// public KVList_IntInt rewards { get; private set; } + /// + /// 测试使用脚本自定义字段类型 + /// + public TestVector3 vector3 { get; private set; } + /// /// post process table @@ -147,6 +153,7 @@ internal class _TbCommonbase_test internal int[][] _field1 { get; private set; } internal PointInt[] _field2 { get; private set; } internal KVList_IntInt[] _field3 { get; private set; } + internal TestVector3[] _field4 { get; private set; } internal _TbCommonbase_test(ByteBuf _buf) { @@ -154,6 +161,7 @@ internal _TbCommonbase_test(ByteBuf _buf) {int __n0 = _buf.ReadSize(); _field1 = new int[__n0][]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int[] __v0; {int __n1 = _buf.ReadSize(); __v0 = new int[__n1]; for(var __i1 = 0 ; __i1 < __n1 ; __i1++ ){ int __v1; __v1 = _buf.ReadInt(); __v0[__i1] = __v1; } } _field1[__i0] = __v0; } } {int __n0 = _buf.ReadSize(); _field2 = new PointInt[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ PointInt __v0; __v0 = new PointInt(_buf); _field2[__i0] = __v0; } } {int __n0 = _buf.ReadSize(); _field3 = new KVList_IntInt[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ KVList_IntInt __v0; __v0 = new KVList_IntInt(_buf); _field3[__i0] = __v0; } } + {int __n0 = _buf.ReadSize(); _field4 = new TestVector3[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ TestVector3 __v0; __v0 = new TestVector3(_buf); _field4[__i0] = __v0; } } } } diff --git a/examples/projects/proj_cs_bin/table_bytes/base_test.bytes b/examples/projects/proj_cs_bin/table_bytes/base_test.bytes index a538ba2..df4c060 100644 Binary files a/examples/projects/proj_cs_bin/table_bytes/base_test.bytes and b/examples/projects/proj_cs_bin/table_bytes/base_test.bytes differ diff --git a/export/common/export_util.go b/export/common/export_util.go index a91ea6e..ae8d7fe 100644 --- a/export/common/export_util.go +++ b/export/common/export_util.go @@ -7,11 +7,12 @@ import ( "github.com/821869798/table-export/data/env" "github.com/821869798/table-export/data/model" "github.com/821869798/table-export/ext" + "github.com/821869798/table-export/ext/ext_scripts" "github.com/821869798/table-export/meta" "github.com/BurntSushi/toml" + "github.com/bmatcuk/doublestar/v4" "github.com/gookit/slog" "os" - "path/filepath" "sync" ) @@ -21,9 +22,9 @@ func ExportPlusCommon(tableMetas []*meta.RawTableMeta, rulePlus config.MetaRuleU var enumFiles = rulePlus.GetEnumFiles() rawEnumConfigs := make([]*config.RawMetaEnumConfig, 0, len(enumFiles)) for _, p := range enumFiles { - matches, err := filepath.Glob(p) + matches, err := doublestar.FilepathGlob(p) if err != nil { - slog.Fatalf("Enum Files laod error filePath:%s err:%v", p, err) + slog.Fatalf("Enum Files load error filePath:%s err:%v", p, err) } for _, m := range matches { fullPath := fanpath.AbsOrRelExecutePath(m) @@ -52,7 +53,26 @@ func ExportPlusCommon(tableMetas []*meta.RawTableMeta, rulePlus config.MetaRuleU } } - // TODO 加载自定义解析脚本 + // 添加脚本实现的扩展类型 + for _, extFieldScriptPath := range rulePlus.GetExtFieldTypeScriptPath() { + matches, err := doublestar.FilepathGlob(extFieldScriptPath) + if err != nil { + slog.Fatalf("Ext Script path glob error filePath:%s err:%v", extFieldScriptPath, err) + os.Exit(1) + } + for _, m := range matches { + extFieldType, err := ext_scripts.NewExtFieldJS(m) + if err != nil { + slog.Fatalf("Ext Script Files laod error filePath:%s err:%v", m, err) + os.Exit(1) + } + err = env.AddExtFieldType(extFieldType) + if err != nil { + slog.Fatalf("add ext field type error:%v", err) + os.Exit(1) + } + } + } //实际开始转换 allDataModel := LoadTableModelPlusParallel(tableMetas, rulePlus, nil) diff --git a/export/cs_bin/template_cs_bin.go b/export/cs_bin/template_cs_bin.go index 80b5b6a..e5f72e0 100644 --- a/export/cs_bin/template_cs_bin.go +++ b/export/cs_bin/template_cs_bin.go @@ -131,7 +131,7 @@ namespace {{.NameSpace}} public {{$.ClassDefinePrefix}}{{$classType.Name}}(ByteBuf _buf) { -{{ range $v := $classType.Fields }} +{{- range $v := $classType.Fields }} {{CSbinFieldReader $v.FieldType $v.Name "_buf" }} {{- end }} PostInit(); diff --git a/ext/ext_scripts/ext_field_goja.go b/ext/ext_scripts/ext_field_goja.go new file mode 100644 index 0000000..d6beb4f --- /dev/null +++ b/ext/ext_scripts/ext_field_goja.go @@ -0,0 +1,85 @@ +package ext_scripts + +import ( + "errors" + "fmt" + "github.com/821869798/fankit/fanpath" + "github.com/821869798/table-export/component/goja/table_engine" + "github.com/821869798/table-export/field_type" + "github.com/dop251/goja" + "github.com/dop251/goja_nodejs/console" + "github.com/dop251/goja_nodejs/require" + "sync" +) + +// ExtFieldJS 通过js脚本扩展字段类型 +type ExtFieldJS struct { + FieldType *field_type.TableFieldType + ScriptPath string + jsResult *jsScriptResult + Error string + mutex sync.Mutex +} + +type jsScriptResult struct { + Name string + DefineFile string + ParseFunc func(string, *ExtFieldJS) interface{} + TableFieldType func() *field_type.TableFieldType +} + +func NewExtFieldJS(scripPath string) (field_type.IExtFieldType, error) { + + e := &ExtFieldJS{ + ScriptPath: scripPath, + jsResult: &jsScriptResult{}, + } + registry := require.NewRegistry(require.WithGlobalFolders(fanpath.ExecuteParentPath())) + + vm := goja.New() + _ = registry.Enable(vm) + console.Enable(vm) + table_engine.Enable(vm) + + var script = fmt.Sprintf("const extField = require(\"%s\");\n", e.ScriptPath) + + `const result = { Name: extField.Name(),DefineFile: extField.DefineFile(),TableFieldType: extField.TableFieldType, ParseFunc: extField.ParseOriginData}; +result;` + res, err := vm.RunString(script) + if err != nil { + return nil, err + } + + if err := vm.ExportTo(res, e.jsResult); err != nil { + return nil, err + } + + e.FieldType = e.jsResult.TableFieldType() + e.FieldType.SetExtFieldType(e) + + return e, nil +} + +func (e *ExtFieldJS) Name() string { + return e.jsResult.Name +} + +func (e *ExtFieldJS) DefineFile() string { + return e.jsResult.DefineFile +} + +func (e *ExtFieldJS) TableFieldType() *field_type.TableFieldType { + return e.FieldType +} + +func (e *ExtFieldJS) ParseOriginData(origin string) (interface{}, error) { + // goja 不支持线程安全 + e.mutex.Lock() + defer e.mutex.Unlock() + + e.Error = "" + result := e.jsResult.ParseFunc(origin, e) + if e.Error != "" { + return nil, errors.New(e.Error) + } + return result, nil +} diff --git a/go.mod b/go.mod index 202997f..1851cde 100644 --- a/go.mod +++ b/go.mod @@ -5,12 +5,18 @@ go 1.21 require ( github.com/821869798/fankit v0.0.6 github.com/BurntSushi/toml v1.3.2 + github.com/bmatcuk/doublestar/v4 v4.6.1 + github.com/dop251/goja v0.0.0-20231014103939-873a1496dc8e + github.com/dop251/goja_nodejs v0.0.0-20231122114759-e84d9a924c5c github.com/expr-lang/expr v1.15.8 github.com/gookit/slog v0.5.4 github.com/xuri/excelize/v2 v2.8.0 ) require ( + github.com/dlclark/regexp2 v1.10.0 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect github.com/gookit/color v1.5.4 // indirect github.com/gookit/goutil v0.6.12 // indirect github.com/gookit/gsr v0.1.0 // indirect @@ -21,9 +27,9 @@ require ( github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca // indirect github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/net v0.14.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect ) diff --git a/go.sum b/go.sum index 8c91382..ed78dcc 100644 --- a/go.sum +++ b/go.sum @@ -2,11 +2,33 @@ github.com/821869798/fankit v0.0.6 h1:WnBBUMwIB+zyqtpJSxx8JD8j+CprDE0KrJZGrO9U5Q github.com/821869798/fankit v0.0.6/go.mod h1:73w1EUt6i92eswVBeuUVVmHtjidOqcVsmwL3beokqQA= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= +github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20231014103939-873a1496dc8e h1:lCjFpJwrCCaDOyQ4RKYNOIexG+yrjxai//OlcMQEGqg= +github.com/dop251/goja v0.0.0-20231014103939-873a1496dc8e/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/dop251/goja_nodejs v0.0.0-20231122114759-e84d9a924c5c h1:hLoodLRD4KLWIH8eyAQCLcH8EqIrjac7fCkp/fHnvuQ= +github.com/dop251/goja_nodejs v0.0.0-20231122114759-e84d9a924c5c/go.mod h1:bhGPmCgCCTSRfiMYWjpS46IDo9EUZXlsuUaPXSWGbv0= github.com/expr-lang/expr v1.15.8 h1:FL8+d3rSSP4tmK9o+vKfSMqqpGL8n15pEPiHcnBpxoI= github.com/expr-lang/expr v1.15.8/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= +github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/gookit/goutil v0.6.12 h1:73vPUcTtVGXbhSzBOFcnSB1aJl7Jq9np3RAE50yIDZc= @@ -15,6 +37,13 @@ github.com/gookit/gsr v0.1.0 h1:0gadWaYGU4phMs0bma38t+Do5OZowRMEVlHv31p0Zig= github.com/gookit/gsr v0.1.0/go.mod h1:7wv4Y4WCnil8+DlDYHBjidzrEzfHhXEoFjEA0pPPWpI= github.com/gookit/slog v0.5.4 h1:EMctf/kap/SR8cnhkUucL0D3YZwUAJJ+WKQ/DN6kS5s= github.com/gookit/slog v0.5.4/go.mod h1:awroa12zroMvjFpS7tdpTX12AqIzVewUlC10tsj4TYY= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -24,6 +53,7 @@ github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7 github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -44,8 +74,9 @@ github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo= @@ -57,8 +88,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -67,12 +99,14 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -80,17 +114,25 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=