/// <summary> /// Syntax $$Run-Plugin::PluginName['arg1', 'arg2', 'argN'] /// </summary> public static JObject ResolvePluginExpressions(this JObject json, ref int warnings) { var expressionRegex = new Regex(@"(?<expression>\$\$Run-Plugin::(?<name>[^\[]*)\[(?<arguments>[^\]]*)\])", RegexOptions.Compiled); var pluginExpressions = expressionRegex.Matches(json.ToString()).Cast<Match>() .Select((m) => new { Expression = m.Groups["expression"].Value, Name = m.Groups["name"].Value, //Arguments = m.Groups["arguments"].Value Arguments = Regex.Unescape(m.Groups["arguments"].Value) .Split(',') // do not use StringSplitOptions.RemoveEmptyEntries .Select((a) => a.Trim(new[] { ' ', '\'' })) .ToArray() }) .Distinct() .ToList(); #region Print debug expressions _logger.Debug("Plugin expressions found '{0}'", pluginExpressions.Count); foreach (var plugin in pluginExpressions) { _logger.Debug("\tExpression '{0}'", plugin.Expression); _logger.Debug("\t\tPlugin '{0}'", plugin.Name); foreach (var argument in plugin.Arguments) _logger.Debug("\t\tArgument '{0}'", argument); } #endregion _logger.Info("Collecting plugins"); using (var collector = new PluginCollector()) { _logger.Info("Plugins found '{0}'", collector.Plugins.Count); foreach (var plugin in collector.Plugins) _logger.Debug($"\tPlugin '{ plugin.Name }' - '{ plugin.Version }' - '{ plugin.Description }'"); string resolvedJson = json.ToString(); foreach (var expression in pluginExpressions) { var plugin = collector.Plugins.SingleOrDefault((p) => p.Name.Equals(expression.Name, StringComparison.InvariantCultureIgnoreCase)); if (plugin == null) { _logger.Warn("Plugin not found for expression '{0}'", expression.Expression); warnings++; continue; } dynamic pluginResult; #region Execute plugin _logger.Info("Executing plugin '{0}' - '{1}' - '{2}'", plugin.Name, plugin.Version, plugin.Description); plugin.Initialize(_logger.Factory); try { if (plugin is IMetadataCompilerPlugin) { pluginResult = (plugin as IMetadataCompilerPlugin).Compile(expression.Arguments); } else { throw new ApplicationException(string.Format("Plugin interface unidentified for expression '{0}'", expression.Expression)); } } finally { plugin.Shutdown(); } #endregion _logger.Debug("Resolved plugin expression type is '{0}' => '{1}'", pluginResult.GetType(), pluginResult); var replaceExpression = expression.Expression; // Add beginning and trailing quotes, since we're replacing a json value fragment with raw string json object. if (!(pluginResult is JValue)) replaceExpression = "\"" + expression.Expression + "\""; //resolvedJson = resolvedJson.Replace(replaceExpression, pluginResult.ToString().Replace("\\\\", "\\")); resolvedJson = resolvedJson.Replace(replaceExpression, pluginResult.ToString()); } _logger.Info("Parsing resolved plugin metadata"); _logger.Debug(resolvedJson); return JObject.Parse(resolvedJson); } }
private static int Plugins(PluginsOptions pluginsOptions) { if (pluginsOptions.Action.ToLower() == "list") { PluginCollector collector = new PluginCollector(); _logger.Info("Plugins found: {0}", collector.Plugins.Count); foreach (var plugin in collector.Plugins) { _logger.Info("- {0} v.{1}: {2}", plugin.Name, plugin.Version, plugin.Description); } } if (pluginsOptions.Action.ToLower() == "help") { PluginCollector collector = new PluginCollector(); var plugin = collector.Plugins.SingleOrDefault((p) => p.Name.Equals(pluginsOptions.PluginName, StringComparison.InvariantCultureIgnoreCase)); if (plugin != null) { plugin.Initialize(_logger.Factory); _logger.Info("{0} v.{1}", plugin.Name, plugin.Version); _logger.Info("by {0}", plugin.Author); _logger.Info(plugin.Description); _logger.Info(plugin.Help); plugin.Shutdown(); } _logger.Warn(ErrorArgumentVerbNotImplemented); } return 0; }