using NLog; using System; using System.Collections.Specialized; using System.IO; using System.Text; using System.Text.RegularExpressions; namespace YLPublishTool { class Runner { string _actionName; IPublishAction _action; NameValueCollection _actionProperties; ILogger _logger; PublishContext _context; /// /// 空指令运行 /// public bool EmptyRun { get; set; } public void Run(string filePath, NameValueCollection predefines = null) { _context = new PublishContext(predefines); _logger = LogManager.GetLogger(Path.GetFileName(filePath)); _logger.Info("开始分析执行...."); var lines = File.ReadAllLines(filePath); var lineIterator = new LineIterator(lines); _action = null; _actionName = null; _actionProperties = new NameValueCollection(); while (lineIterator.MoveNext()) { var lineText = lineIterator.Current?.Trim(); if (string.IsNullOrEmpty(lineText) || lineText[0] == '#') { continue; } if (lineText[0] == '[') { ParseAction(lineText, lineIterator.LineNum); _actionProperties.Clear(); } else if (_action == null) { throw new Exception($"[行 {lineIterator.LineNum}]缺少指令定义"); } else { ParseProperties(lineText, lineIterator); } } if (_action != null) { _context.Logger = LogManager.GetLogger(_actionName); _action.Execute(_context); _logger.Info($"^^^结束指令[{_actionName}]"); } } private void ParseAction(string lineText, int lineNum) { if (_action != null) { _context.Logger = LogManager.GetLogger(_actionName); _action.Execute(_context); _logger.Info($"[行 {lineNum}]结束指令[{_actionName}]"); Console.WriteLine(); } _actionName = lineText.Trim(new[] { '[', ']' }); Console.WriteLine(); _logger.Info($"[行 {lineNum}]开始指令[{_actionName}]"); if (_actionName == "全局变量") { _action = _context; } else { _action = EmptyRun || _actionName.StartsWith("#") ? new EmptyAction() : Helper.GetAction(_actionName); if (_action == null) { throw new Exception($"[行 {lineNum}]没有找到对应的指令处理器:{lineText}"); } } } private void ParseProperties(string lineText, LineIterator lineIterator) { var lineNum = lineIterator.LineNum; var index = lineText.IndexOf('='); if (index < 0) { throw new Exception($"[行 {lineNum}]无效:{lineText}"); } var left = lineText.Substring(0, index).TrimEnd(); if (left.Length < 1) { throw new Exception($"[行 {lineNum}]无效:{lineText}"); } var right = lineText.Substring(index + 1).TrimStart(); if (right.StartsWith("#")) { return; } if (right.StartsWith("'''")) { var sb = new StringBuilder().Append(right); while (lineIterator.MoveNext()) { lineText = lineIterator.Current.TrimEnd(); sb.AppendLine(lineText); if (lineText.EndsWith("'''")) { break; } } right = sb.ToString().Trim(new[] { '\'', '\r', '\n' }); } right = ConvertTemplateString(right); if (right.Length > 0) { _action.SetProperty(left, right); _actionProperties[left] = right; _logger.Info($"[行 {lineNum}]变量赋值:{left} = {right}"); } } private string ConvertTemplateString(string str) { if (string.IsNullOrEmpty(str) || str.IndexOf("${") < 0) { return str; } return Regex.Replace(str, @"\$\{(.+?)\}", m => { var name = m.Groups[1].Value; return _actionProperties[name] ?? _context.GetProperty(name); }); } class LineIterator { readonly string[] _lines; public LineIterator(string[] lines) { _lines = lines; } public int LineNum { get; private set; } public string Current { get; private set; } public void Reset() { LineNum = 0; Current = null; } public bool MoveNext() { if (++LineNum <= _lines.Length) { Current = _lines[LineNum - 1]; return true; } Current = null; return false; } } class EmptyAction : IPublishAction { public void Execute(IPublishContext context) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("[EmptyAction]Execute"); Console.ForegroundColor = ConsoleColor.White; } public void SetProperty(string name, string value) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"[EmptyAction]SetProperty"); Console.ForegroundColor = ConsoleColor.White; } } } }