【删除】移除 cfg --export_test_data 选项,如果想不导出测试数据,使用 --export_exclude_tags test

【特性】新增 cfg --export_exclude_tags选项,支持过滤指定tags列表的数据
main
walon 2021-10-11 15:43:51 +08:00
parent dd5bae123f
commit 68676cf8ab
19 changed files with 67 additions and 79 deletions

View File

@ -221,9 +221,9 @@ array与list类型都能表示列表它们区别在于array生成的代码为
- 表级别分组 - 表级别分组
- 字段级别分组(任意bean字段粒度而不仅限于顶层字段) - 字段级别分组(任意bean字段粒度而不仅限于顶层字段)
### 数据标签 ### 数据标签过滤
开发期有时候希望临时注释掉一些记录,另外开发期经常会制作一些仅供开发使用的配置,比如测试道具,比如自动化测试使用的配置,在正式上线时不导出这些数据。 luban支持数据标签及数据注释及测试数据过滤导出导出正式配置时不需要手动将测试数据删掉。 开发期经常会制作一些仅供开发使用的配置,比如测试道具,比如自动化测试使用的配置,希望在正式发布时不导出这些数据。
![pipeline](docs/images/examples/c_11.jpg) ![pipeline](docs/images/examples/c_11.jpg)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -15,6 +15,6 @@ namespace Luban.Job.Cfg.DataSources
public abstract List<Record> ReadMulti(TBean type); public abstract List<Record> ReadMulti(TBean type);
public abstract void Load(string rawUrl, string sheetName, Stream stream, bool exportDebugData); public abstract void Load(string rawUrl, string sheetName, Stream stream);
} }
} }

View File

@ -8,7 +8,7 @@ namespace Luban.Job.Cfg.DataSources.Binary
{ {
class BinaryDataSource : AbstractDataSource class BinaryDataSource : AbstractDataSource
{ {
public override void Load(string rawUrl, string sheetName, Stream stream, bool exportDebugData) public override void Load(string rawUrl, string sheetName, Stream stream)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -18,7 +18,7 @@ namespace Luban.Job.Cfg.DataSources
".bin", ".bin",
}; };
public static AbstractDataSource Create(string url, string sheetName, Stream stream, bool exportTestData) public static AbstractDataSource Create(string url, string sheetName, Stream stream)
{ {
try try
{ {
@ -36,7 +36,7 @@ namespace Luban.Job.Cfg.DataSources
case "yml": source = new Yaml.YamlDataSource(); break; case "yml": source = new Yaml.YamlDataSource(); break;
default: throw new Exception($"不支持的文件类型:{url}"); default: throw new Exception($"不支持的文件类型:{url}");
} }
source.Load(url, sheetName, stream, exportTestData); source.Load(url, sheetName, stream);
return source; return source;
} }
catch (DataCreateException) catch (DataCreateException)

View File

@ -33,7 +33,7 @@ namespace Luban.Job.Cfg.DataSources.Excel
} }
} }
public override void Load(string rawUrl, string sheetName, Stream stream, bool exportTestData) public override void Load(string rawUrl, string sheetName, Stream stream)
{ {
s_logger.Trace("{filename} {sheet}", rawUrl, sheetName); s_logger.Trace("{filename} {sheet}", rawUrl, sheetName);
RawUrl = rawUrl; RawUrl = rawUrl;

View File

@ -14,7 +14,7 @@ namespace Luban.Job.Cfg.DataSources.Json
{ {
JsonElement _data; JsonElement _data;
public override void Load(string rawUrl, string sheetName, Stream stream, bool exportDebugData) public override void Load(string rawUrl, string sheetName, Stream stream)
{ {
RawUrl = rawUrl; RawUrl = rawUrl;
this._data = JsonDocument.Parse(stream).RootElement; this._data = JsonDocument.Parse(stream).RootElement;

View File

@ -17,7 +17,7 @@ namespace Luban.Job.Cfg.DataSources.Lua
private LuaGlobal _env; private LuaGlobal _env;
private LuaTable _dataTable; private LuaTable _dataTable;
public override void Load(string rawUrl, string sheetName, Stream stream, bool exportDebugData) public override void Load(string rawUrl, string sheetName, Stream stream)
{ {
RawUrl = rawUrl; RawUrl = rawUrl;
_env = LuaManager.CreateEnvironment(); _env = LuaManager.CreateEnvironment();

View File

@ -14,7 +14,7 @@ namespace Luban.Job.Cfg.DataSources.Xml
{ {
private XElement _doc; private XElement _doc;
public override void Load(string rawUrl, string sheetName, Stream stream, bool exportDebugData) public override void Load(string rawUrl, string sheetName, Stream stream)
{ {
RawUrl = rawUrl; RawUrl = rawUrl;
_doc = XElement.Load(stream); _doc = XElement.Load(stream);

View File

@ -13,7 +13,7 @@ namespace Luban.Job.Cfg.DataSources.Yaml
class YamlDataSource : AbstractDataSource class YamlDataSource : AbstractDataSource
{ {
private YamlMappingNode _root; private YamlMappingNode _root;
public override void Load(string rawUrl, string sheetName, Stream stream, bool exportDebugData) public override void Load(string rawUrl, string sheetName, Stream stream)
{ {
var ys = new YamlStream(); var ys = new YamlStream();
ys.Load(new StreamReader(stream)); ys.Load(new StreamReader(stream));

View File

@ -13,7 +13,14 @@ namespace Luban.Job.Cfg.Datas
public int Index { get; set; } public int Index { get; set; }
public bool IsTest => Tags != null && DataUtil.IsTestTag(Tags); public bool IsNotFiltered(List<string> excludeTags)
{
if (Tags == null)
{
return true;
}
return Tags.TrueForAll(t => !excludeTags.Contains(t));
}
public Record(DBean data, string source, List<string> tags) public Record(DBean data, string source, List<string> tags)
{ {

View File

@ -478,7 +478,7 @@ namespace Luban.Job.Cfg.Defs
} }
}) })
{ {
AssemblyBase = new DefAssembly("", null, true, Agent), AssemblyBase = new DefAssembly("", null, new List<string>(), Agent),
}; };
defTableRecordType.PreCompile(); defTableRecordType.PreCompile();
defTableRecordType.Compile(); defTableRecordType.Compile();
@ -489,7 +489,7 @@ namespace Luban.Job.Cfg.Defs
{ {
var source = new ExcelDataSource(); var source = new ExcelDataSource();
var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5); var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5);
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, null, bytes, true, false); var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, null, bytes, true);
foreach (var r in records) foreach (var r in records)
{ {
DBean data = r.Data; DBean data = r.Data;
@ -544,7 +544,7 @@ namespace Luban.Job.Cfg.Defs
} }
}) })
{ {
AssemblyBase = new DefAssembly("", null, true, Agent), AssemblyBase = new DefAssembly("", null, new List<string>(), Agent),
}; };
defTableRecordType.PreCompile(); defTableRecordType.PreCompile();
defTableRecordType.Compile(); defTableRecordType.Compile();
@ -555,7 +555,7 @@ namespace Luban.Job.Cfg.Defs
{ {
var source = new ExcelDataSource(); var source = new ExcelDataSource();
var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5); var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5);
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, null, bytes, true, false); var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, null, bytes, true);
PEnum curEnum = null; PEnum curEnum = null;
foreach (var r in records) foreach (var r in records)
@ -599,7 +599,7 @@ namespace Luban.Job.Cfg.Defs
var inputFileInfos = await DataLoaderUtil.CollectInputFilesAsync(this.Agent, this._importExcelBeanFiles, dataDir); var inputFileInfos = await DataLoaderUtil.CollectInputFilesAsync(this.Agent, this._importExcelBeanFiles, dataDir);
var ass = new DefAssembly("", null, true, Agent); var ass = new DefAssembly("", null, new List<string>(), Agent);
var defBeanFieldType = new DefBean(new CfgBean() var defBeanFieldType = new DefBean(new CfgBean()
{ {
@ -669,7 +669,7 @@ namespace Luban.Job.Cfg.Defs
{ {
var source = new ExcelDataSource(); var source = new ExcelDataSource();
var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5); var bytes = await this.Agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5);
var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, null, bytes, true, false); var records = DataLoaderUtil.LoadCfgRecords(tableRecordType, file.OriginFile, null, bytes, true);
foreach (var r in records) foreach (var r in records)
{ {

View File

@ -19,19 +19,6 @@ namespace Luban.Job.Cfg.Defs
public List<Record> FinalRecords { get; set; } public List<Record> FinalRecords { get; set; }
private List<Record> _notTestRecords;
public List<Record> NotTestRecords
{
get
{
if (_notTestRecords == null)
{
_notTestRecords = FinalRecords.Where(r => !r.IsTest).ToList();
}
return _notTestRecords;
}
}
public Dictionary<DType, Record> FinalRecordMap { get; set; } public Dictionary<DType, Record> FinalRecordMap { get; set; }
public TableDataInfo(List<Record> mainRecords, List<Record> patchRecords) public TableDataInfo(List<Record> mainRecords, List<Record> patchRecords)
@ -50,17 +37,17 @@ namespace Luban.Job.Cfg.Defs
public Service CfgTargetService { get; private set; } public Service CfgTargetService { get; private set; }
private readonly string _patchName; private readonly string _patchName;
private readonly bool _exportTestData; private readonly List<string> _excludeTags;
public Patch TargetPatch { get; private set; } public Patch TargetPatch { get; private set; }
public TimeZoneInfo TimeZone { get; } public TimeZoneInfo TimeZone { get; }
public DefAssembly(string patchName, TimeZoneInfo timezone, bool exportTestData, RemoteAgent agent) public DefAssembly(string patchName, TimeZoneInfo timezone, List<string> excludeTags, RemoteAgent agent)
{ {
this._patchName = patchName; this._patchName = patchName;
this.TimeZone = timezone; this.TimeZone = timezone;
this._exportTestData = exportTestData; this._excludeTags = excludeTags;
this.Agent = agent; this.Agent = agent;
} }
@ -126,7 +113,19 @@ namespace Luban.Job.Cfg.Defs
public List<Record> GetTableExportDataList(DefTable table) public List<Record> GetTableExportDataList(DefTable table)
{ {
var tableDataInfo = _recordsByTables[table.FullName]; var tableDataInfo = _recordsByTables[table.FullName];
return _exportTestData ? tableDataInfo.FinalRecords : tableDataInfo.NotTestRecords; if (_excludeTags.Count == 0)
{
return tableDataInfo.FinalRecords;
}
else
{
var finalRecords = tableDataInfo.FinalRecords.Where(r => r.IsNotFiltered(_excludeTags)).ToList();
if (table.IsOneValueTable && finalRecords.Count != 1)
{
throw new Exception($"配置表 {table.FullName} 是单值表 mode=one,但数据个数:{finalRecords.Count} != 1");
}
return finalRecords;
}
} }
public TableDataInfo GetTableDataInfo(DefTable table) public TableDataInfo GetTableDataInfo(DefTable table)

View File

@ -32,11 +32,8 @@ namespace Luban.Job.Cfg
[Option('s', "service", Required = true, HelpText = "service")] [Option('s', "service", Required = true, HelpText = "service")]
public string Service { get; set; } public string Service { get; set; }
[Option("export_test_data", Required = false, HelpText = "export test data")] [Option("export_exclude_tags", Required = false, HelpText = "export exclude tags. default export all tags")]
public bool ExportTestData { get; set; } = false; public string ExportExcludeTags { get; set; } = "";
[Option("export_tag_filter", Required = false, HelpText = "export tag filter")]
public string ExportTagFilter { get; set; } = "";
[Option('t', "l10n_timezone", Required = false, HelpText = "timezone")] [Option('t', "l10n_timezone", Required = false, HelpText = "timezone")]
public string TimeZone { get; set; } public string TimeZone { get; set; }

View File

@ -140,7 +140,8 @@ namespace Luban.Job.Cfg
TimeZoneInfo timeZoneInfo = string.IsNullOrEmpty(args.TimeZone) ? null : TimeZoneInfo.FindSystemTimeZoneById(args.TimeZone); TimeZoneInfo timeZoneInfo = string.IsNullOrEmpty(args.TimeZone) ? null : TimeZoneInfo.FindSystemTimeZoneById(args.TimeZone);
var ass = new DefAssembly(args.PatchName, timeZoneInfo, args.ExportTestData, agent) var excludeTags = args.ExportExcludeTags.Split(',').Select(t => t.Trim().ToLowerInvariant()).Where(t => !string.IsNullOrEmpty(t)).ToList();
var ass = new DefAssembly(args.PatchName, timeZoneInfo, excludeTags, agent)
{ {
UseUnityVectors = args.UseUnityVectors UseUnityVectors = args.UseUnityVectors
}; };
@ -166,7 +167,7 @@ namespace Luban.Job.Cfg
hasLoadCfgData = true; hasLoadCfgData = true;
var timer = new ProfileTimer(); var timer = new ProfileTimer();
timer.StartPhase("load config data"); timer.StartPhase("load config data");
await DataLoaderUtil.LoadCfgDataAsync(agent, ass, args.InputDataDir, args.PatchName, args.PatchInputDataDir, args.ExportTestData); await DataLoaderUtil.LoadCfgDataAsync(agent, ass, args.InputDataDir, args.PatchName, args.PatchInputDataDir);
timer.EndPhaseAndLog(); timer.EndPhaseAndLog();
if (needL10NTextConvert) if (needL10NTextConvert)

View File

@ -71,7 +71,7 @@ namespace Luban.Job.Cfg.Utils
// return CollectInputFilesAsync(agent, table.InputFiles, dataDir) // return CollectInputFilesAsync(agent, table.InputFiles, dataDir)
//} //}
public static async Task GenerateLoadRecordFromFileTasksAsync(RemoteAgent agent, DefTable table, string dataDir, List<string> inputFiles2, bool exportTestData, List<Task<List<Record>>> tasks) public static async Task GenerateLoadRecordFromFileTasksAsync(RemoteAgent agent, DefTable table, string dataDir, List<string> inputFiles2, List<Task<List<Record>>> tasks)
{ {
var inputFileInfos = await CollectInputFilesAsync(agent, inputFiles2, dataDir); var inputFileInfos = await CollectInputFilesAsync(agent, inputFiles2, dataDir);
@ -93,8 +93,7 @@ namespace Luban.Job.Cfg.Utils
file.OriginFile, file.OriginFile,
file.SheetName, file.SheetName,
await agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5), await agent.GetFromCacheOrReadAllBytesAsync(file.ActualFile, file.MD5),
RenderFileUtil.IsExcelFile(file.ActualFile), RenderFileUtil.IsExcelFile(file.ActualFile));
exportTestData);
FileRecordCacheManager.Ins.AddCacheLoadedRecords(table, file.MD5, file.SheetName, res); FileRecordCacheManager.Ins.AddCacheLoadedRecords(table, file.MD5, file.SheetName, res);
@ -103,10 +102,10 @@ namespace Luban.Job.Cfg.Utils
} }
} }
public static async Task LoadTableAsync(RemoteAgent agent, DefTable table, string dataDir, string patchName, string patchDataDir, bool exportTestData) public static async Task LoadTableAsync(RemoteAgent agent, DefTable table, string dataDir, string patchName, string patchDataDir)
{ {
var mainLoadTasks = new List<Task<List<Record>>>(); var mainLoadTasks = new List<Task<List<Record>>>();
var mainGenerateTask = GenerateLoadRecordFromFileTasksAsync(agent, table, dataDir, table.InputFiles, exportTestData, mainLoadTasks); var mainGenerateTask = GenerateLoadRecordFromFileTasksAsync(agent, table, dataDir, table.InputFiles, mainLoadTasks);
var patchLoadTasks = new List<Task<List<Record>>>(); var patchLoadTasks = new List<Task<List<Record>>>();
@ -116,7 +115,7 @@ namespace Luban.Job.Cfg.Utils
var patchInputFiles = table.GetPatchInputFiles(patchName); var patchInputFiles = table.GetPatchInputFiles(patchName);
if (patchInputFiles != null) if (patchInputFiles != null)
{ {
patchGenerateTask = GenerateLoadRecordFromFileTasksAsync(agent, table, patchDataDir, patchInputFiles, exportTestData, patchLoadTasks); patchGenerateTask = GenerateLoadRecordFromFileTasksAsync(agent, table, patchDataDir, patchInputFiles, patchLoadTasks);
} }
} }
@ -146,7 +145,7 @@ namespace Luban.Job.Cfg.Utils
s_logger.Trace("table:{name} record num:{num}", table.FullName, mainRecords.Count); s_logger.Trace("table:{name} record num:{num}", table.FullName, mainRecords.Count);
} }
public static async Task LoadCfgDataAsync(RemoteAgent agent, DefAssembly ass, string dataDir, string patchName, string patchDataDir, bool exportTestData) public static async Task LoadCfgDataAsync(RemoteAgent agent, DefAssembly ass, string dataDir, string patchName, string patchDataDir)
{ {
var ctx = agent; var ctx = agent;
List<DefTable> exportTables = ass.Types.Values.Where(t => t is DefTable ct && ct.NeedExport).Select(t => (DefTable)t).ToList(); List<DefTable> exportTables = ass.Types.Values.Where(t => t is DefTable ct && ct.NeedExport).Select(t => (DefTable)t).ToList();
@ -160,7 +159,7 @@ namespace Luban.Job.Cfg.Utils
genDataTasks.Add(Task.Run(async () => genDataTasks.Add(Task.Run(async () =>
{ {
long beginTime = TimeUtil.NowMillis; long beginTime = TimeUtil.NowMillis;
await LoadTableAsync(agent, table, dataDir, patchName, patchDataDir, exportTestData); await LoadTableAsync(agent, table, dataDir, patchName, patchDataDir);
long endTime = TimeUtil.NowMillis; long endTime = TimeUtil.NowMillis;
if (endTime - beginTime > 100) if (endTime - beginTime > 100)
{ {
@ -171,10 +170,10 @@ namespace Luban.Job.Cfg.Utils
await Task.WhenAll(genDataTasks.ToArray()); await Task.WhenAll(genDataTasks.ToArray());
} }
public static List<Record> LoadCfgRecords(TBean recordType, string originFile, string sheetName, byte[] content, bool multiRecord, bool exportTestData) public static List<Record> LoadCfgRecords(TBean recordType, string originFile, string sheetName, byte[] content, bool multiRecord)
{ {
// (md5,sheet,multiRecord,exportTestData) -> (valuetype, List<(datas)>) // (md5,sheet,multiRecord,exportTestData) -> (valuetype, List<(datas)>)
var dataSource = DataSourceFactory.Create(originFile, sheetName, new MemoryStream(content), exportTestData); var dataSource = DataSourceFactory.Create(originFile, sheetName, new MemoryStream(content));
try try
{ {
if (multiRecord) if (multiRecord)

View File

@ -117,33 +117,18 @@ namespace Luban.Job.Cfg.Utils
{ {
return !string.IsNullOrEmpty(tagName) && return !string.IsNullOrEmpty(tagName) &&
( (
tagName.Equals("false", System.StringComparison.OrdinalIgnoreCase) tagName.Equals("no", System.StringComparison.OrdinalIgnoreCase)
|| tagName.Equals("no", System.StringComparison.OrdinalIgnoreCase)
|| tagName.Equals("##", System.StringComparison.Ordinal) || tagName.Equals("##", System.StringComparison.Ordinal)
//|| tagName.Equals("·ñ", System.StringComparison.Ordinal)
); );
} }
private static bool IsTestTag(string tagName)
{
return !string.IsNullOrEmpty(tagName) &&
(tagName.Equals("test", System.StringComparison.OrdinalIgnoreCase)
|| tagName.Equals("²âÊÔ", System.StringComparison.Ordinal)
);
}
public static bool IsTestTag(List<string> tagNames)
{
return tagNames.Any(IsTestTag);
}
public static List<string> ParseTags(string rawTagStr) public static List<string> ParseTags(string rawTagStr)
{ {
if (string.IsNullOrWhiteSpace(rawTagStr)) if (string.IsNullOrWhiteSpace(rawTagStr))
{ {
return null; return null;
} }
var tags = new List<string>(rawTagStr.Split(',').Select(t => t.Trim()).Where(t => !string.IsNullOrEmpty(t))); var tags = new List<string>(rawTagStr.Split(',').Select(t => t.Trim().ToLower()).Where(t => !string.IsNullOrEmpty(t)));
return tags.Count > 0 ? tags : null; return tags.Count > 0 ? tags : null;
} }

View File

@ -201,17 +201,17 @@ namespace Luban.Job.Cfg
{ {
case ETableMode.ONE: case ETableMode.ONE:
{ {
if (mainRecords.Count != 1) //if (mainRecords.Count != 1)
{ //{
throw new Exception($"配置表 {table.FullName} 是单值表 mode=one,但主文件数据个数:{mainRecords.Count} != 1"); // throw new Exception($"配置表 {table.FullName} 是单值表 mode=one,但主文件数据个数:{mainRecords.Count} != 1");
} //}
if (patchRecords != null && patchRecords.Count != 1) //if (patchRecords != null && patchRecords.Count != 1)
{ //{
throw new Exception($"配置表 {table.FullName} 是单值表 mode=one,但分支文件数据个数:{patchRecords.Count} != 1"); // throw new Exception($"配置表 {table.FullName} 是单值表 mode=one,但分支文件数据个数:{patchRecords.Count} != 1");
} //}
if (patchRecords != null) if (patchRecords != null)
{ {
mainRecords[0] = patchRecords[0]; mainRecords = patchRecords;
} }
break; break;
} }

View File

@ -66,7 +66,7 @@ namespace Luban.Job.Cfg.l10n
public void LoadFromFile(string fileName, byte[] bytes) public void LoadFromFile(string fileName, byte[] bytes)
{ {
var records = DataLoaderUtil.LoadCfgRecords(_textRowType, fileName, null, bytes, true, false); var records = DataLoaderUtil.LoadCfgRecords(_textRowType, fileName, null, bytes, true);
foreach (var r in records) foreach (var r in records)
{ {
//s_logger.Info("== read text:{}", r.Data); //s_logger.Info("== read text:{}", r.Data);