private static async Task <Tuple <List <Plugin>, List <Plugin> > > StageDefinition(SDK.Core.Plugins.Plugin definition, IDictionary <Name, Tuple <SDK.Core.Plugins.VersionRange, Plugin> > loaded = null) { var top = new List <Plugin>(); var nested = new List <Plugin>(); foreach (var dependency in definition.Dependencies ?? new Dictionary <Name, SDK.Core.Plugins.VersionRange>()) { var repo = definition.Repositories?.FirstOrDefault(r => r.Name.ToString() == dependency.Key.ToString()); var adapter = new AdapterBuilder(dependency.Key, repo).Adapter(); var versions = await adapter.GetVersions(); var versionMatch = versions.LastOrDefault(version => dependency.Value.IsSatisfied(version)); if (versionMatch == null) { throw new Exception("No matching version found"); } if (loaded == null) { loaded = new Dictionary <Name, Tuple <SDK.Core.Plugins.VersionRange, Plugin> >(); } if (loaded.ContainsKey(dependency.Key)) { if (dependency.Value.Value != "*" && loaded[dependency.Key].Item1.Value != "*" && !dependency.Value.IsSatisfied(loaded[dependency.Key].Item2.Version)) { throw new Exception($"{dependency.Key} was found"); } } var localPath = await adapter.Cache(versionMatch); var plugin = Plugin.Load(Path.Combine(localPath, ConfigurationManager.DefinitionFile)); if (loaded.ContainsKey(dependency.Key)) { loaded.Add(dependency.Key, new Tuple <SDK.Core.Plugins.VersionRange, Plugin>(dependency.Value, plugin)); } top.Add(plugin); // TODO: What should be validated? //if (plugin.Name != dependency.Key) throw new Exception("Downloaded package does not match requested."); //if (plugin.Version != versionMatch) throw new Exception("Downloaded package does not match requested."); nested.AddRange((await StageDefinition(plugin, loaded)).Item1); } return(new Tuple <List <Plugin>, List <Plugin> >(top, nested)); }