public void Simple() { var config = new Config() { Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); config.Dependencies.Add(dep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.1")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig } }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should not throw var deps = restorer.CollectDependencies(); // Ensure we still only have one dependency and nothing has changed Assert.Collection(deps, kvp => { Assert.True(kvp.Key.Dependency.Id == dep.Id); Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange); }); }
public void DoNotMatchConfig() { // Collect nested dependencies that are not collapsible, should cause a DependencyException // Collect nested dependencies that are collapsible, should result in 1 var config = new Config() { Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4")); config.Dependencies.Add(dep); config.Dependencies.Add(otherDep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0")) } }; var innerDep = new Dependency("needed", new SemVer.Range("0.1.0")); depConfig.Config.Dependencies.Add(innerDep); var innerDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig }, { otherDep, innerDepConfig }, { innerDep, innerDepConfig } }); var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object); // Should throw Assert.Throws <DependencyException>(() => innerRestorer.CollectDependencies()); // Assume it DID NOT restore var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // This should NOT throw, since the version we test here actually exists and is satisfiable. // and our dependency config DOES NOT contain a restored dependency that causes any problems. // TODO: We could add a test here to test for when one matches but they other doesn't too. var deps = restorer.CollectDependencies(); Assert.Collection(deps, kvp => { Assert.True(kvp.Key.Dependency.Id == dep.Id); Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version); }, kvp => { Assert.True(kvp.Key.Dependency.Id == otherDep.Id); Assert.True(kvp.Key.Dependency.VersionRange == otherDep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); }); }
public void Recursive() { var config = new Config() { Info = new PackageInfo("MyMod", "id", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); config.Dependencies.Add(dep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig } }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should throw a recursive exception (id cannot include id) Assert.Throws <DependencyException>(() => restorer.CollectDependencies()); // Should never have made any GetConfig calls uriHandler.Verify(mocks => mocks.GetSharedConfig(It.IsAny <RestoredDependencyPair>()), Times.Never); }
public void SimpleCollapse() { // Collect a dependency, collapse it, and nothing should change var config = new Config() { Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); config.Dependencies.Add(dep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.1")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig } }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should not throw var deps = restorer.CollectDependencies(); var result = RestoreHandler.CollapseDependencies(deps); Assert.All(deps, kvp => { Assert.True(result.TryGetValue(kvp.Key, out var conf)); Assert.True(kvp.Value == conf); }); }
public void NestedRecursive() { var config = new Config() { Info = new PackageInfo("MyMod", "id", new SemVer.Version("0.1.0")) }; var dep = new Dependency("asdf", new SemVer.Range("^0.1.0")); config.Dependencies.Add(dep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "asdf", new SemVer.Version("0.1.0")) } }; // It's undefined behavior to attempt to load a config that allows its dependencies to ask for itself // Therefore, we will test ourselves, and all other configs must follow this same principle var innerDep = new Dependency("id", new SemVer.Range("^0.1.0")); depConfig.Config.Dependencies.Add(innerDep); var innerDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("inner", "id", new SemVer.Version("0.1.0")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig }, { innerDep, innerDepConfig } }); var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object); // Should not throw var innerDeps = innerRestorer.CollectDependencies(); Assert.Collection(innerDeps, kvp => { Assert.True(kvp.Key.Dependency.Id == innerDep.Id); Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); } ); uriHandler.Verify(mocks => mocks.GetSharedConfig(It.Is <RestoredDependencyPair>(p => p.Dependency == innerDep)), Times.Once); // Assume it restored depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = innerDepConfig.Config.Info.Version }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should throw a recursive exception (id cannot include id) Assert.Throws <DependencyException>(() => restorer.CollectDependencies()); // Should have tried to get asdf's config uriHandler.Verify(mocks => mocks.GetSharedConfig(It.Is <RestoredDependencyPair>(p => p.Dependency == dep)), Times.Once); // The inner dependency should have been attempted to have been gotten exactly once, from the innerRestorer collection // It should not have been collected again in our collection of dependencies uriHandler.Verify(mocks => mocks.GetSharedConfig(It.Is <RestoredDependencyPair>(p => p.Dependency == innerDep)), Times.Once); }
private void OnExecute() { var outp = Program.RestoreHandler.CollectDependencies(); var collapsed = RestoreHandler.CollapseDependencies(outp); foreach (var pair in collapsed) { Console.WriteLine($"{PrintRestoredDependency(pair.Key)} (config: {pair.Value.Config.Info.Version}, {pair.Value.RestoredDependencies.Count} restored dependencies)"); PrintDependencies("- ", pair.Value); } Utils.WriteSuccess(); }
public static int Main(string[] args) { // Create config provider configProvider = new LocalConfigProvider(Environment.CurrentDirectory, PackageFileName, LocalFileName); api = new QPMApi(configProvider); androidMkProvider = new AndroidMkProvider(Path.Combine(Environment.CurrentDirectory, "Android.mk")); resolver = new RemoteQPMDependencyResolver(api, androidMkProvider); propertiesProvider = new CppPropertiesProvider(Path.Combine(Environment.CurrentDirectory, ".vscode", "c_cpp_properties.json")); bmbfmodProvider = new BmbfModProvider(Path.Combine(Environment.CurrentDirectory, "bmbfmod.json")); // Create handlers PackageHandler = new PackageHandler(configProvider); DependencyHandler = new DependencyHandler(configProvider); RestoreHandler = new RestoreHandler(configProvider, resolver); PublishHandler = new PublishHandler(configProvider, api); // Register callbacks PackageHandler.OnPackageCreated += PackageHandler_OnPackageCreated; PackageHandler.OnIdChanged += PackageHandler_OnIdChanged; PackageHandler.OnVersionChanged += PackageHandler_OnVersionChanged; PackageHandler.OnNameChanged += PackageHandler_OnNameChanged; DependencyHandler.OnDependencyRemoved += DependencyHandler_OnDependencyRemoved; // TODO: AKLJSHFJKGHDKJ RestoreHandler.OnRestore += (resolver as RemoteQPMDependencyResolver).OnRestore; try { return(CommandLineApplication.Execute <Program>(args)); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(); Console.WriteLine(e); Utils.WriteFail(); } return(-1); }
public void NestedNew() { var config = new Config() { Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); config.Dependencies.Add(dep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.1")) } }; var innerDep = new Dependency("id2", new SemVer.Range("^0.1.0")); depConfig.Config.Dependencies.Add(innerDep); var innerDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("Cool Name", "id2", new SemVer.Version("0.1.1")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig }, { innerDep, innerDepConfig } }); var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object); // Should not throw var innerDeps = innerRestorer.CollectDependencies(); Assert.Collection(innerDeps, kvp => { Assert.True(kvp.Key.Dependency.Id == innerDep.Id); Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); } ); // Assume it restored depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = innerDepConfig.Config.Info.Version }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should not throw var deps = restorer.CollectDependencies(); // We should now have TWO dependencies, one for id and one for id2 // Order of these dependencies should not matter. They just both need to be in there. Assert.Collection(deps, kvp => { Assert.True(kvp.Key.Dependency.Id == dep.Id); Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version); }, kvp => { Assert.True(kvp.Key.Dependency.Id == innerDep.Id); Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); }); }
public void NestedExistingDuplicate() { var config = new Config() { Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4")); config.Dependencies.Add(dep); config.Dependencies.Add(otherDep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0")) } }; var innerDep = new Dependency("needed", new SemVer.Range("^0.1.0")); depConfig.Config.Dependencies.Add(innerDep); //depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = new SemVer.Version("0.1.4") }); var innerDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig }, { otherDep, innerDepConfig }, { innerDep, innerDepConfig } }); var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object); // Should not throw var innerDeps = innerRestorer.CollectDependencies(); Assert.Collection(innerDeps, kvp => { Assert.True(kvp.Key.Dependency.Id == innerDep.Id); Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); } ); // Assume it restored depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = innerDepConfig.Config.Info.Version }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should not throw var deps = restorer.CollectDependencies(); // We should now ONLY HAVE TWO dependencies! // The two dependencies for "needed" should be auto-collapsed into one, because the Versions match Assert.Collection(deps, kvp => { // Dependency must match, so should the version range (the first dependency should be from ourselves, so it should match perfectly) Assert.True(kvp.Key.Dependency.Id == dep.Id); Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version); }, kvp => { // Dependency ID must match, version range doesn't matter, but theoretically should intersect Assert.True(kvp.Key.Dependency.Id == otherDep.Id); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); } ); }
public void NestedExistingUnique() { var config = new Config() { Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4")); config.Dependencies.Add(dep); config.Dependencies.Add(otherDep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0")) } }; var innerDep = new Dependency("needed", new SemVer.Range("^0.1.0")); depConfig.Config.Dependencies.Add(innerDep); //depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = new SemVer.Version("0.1.4") }); var otherDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4")) } }; var innerDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.3")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig }, { otherDep, otherDepConfig }, { innerDep, innerDepConfig } }); var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object); // Should not throw var innerDeps = innerRestorer.CollectDependencies(); Assert.Collection(innerDeps, kvp => { Assert.True(kvp.Key.Dependency.Id == innerDep.Id); Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); } ); // Assume it restored depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = innerDepConfig.Config.Info.Version }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should not throw var deps = restorer.CollectDependencies(); // We should now HAVE THREE dependencies! // The two dependencies for "needed" (because they are unique versions) and the dependency for "id" Assert.Collection(deps, kvp => { // Dependency ID and VersionRange must match // This is because the first dependency must be the one from our config Assert.True(kvp.Key.Dependency.Id == dep.Id); Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version); }, kvp => { // Dependency ID must match Assert.True(kvp.Key.Dependency.Id == innerDep.Id); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); }, kvp => { // Dependency ID must match Assert.True(kvp.Key.Dependency.Id == otherDep.Id); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == otherDepConfig.Config.Info.Version); } ); }
internal void OnRestore(RestoreHandler self, Dictionary <RestoredDependencyPair, SharedConfig> deps, Dictionary <RestoredDependencyPair, SharedConfig> uniques) => Complete();
public void CollapseMatching() { // Collect nested dependencies that are collapsible, should result in 1 var config = new Config() { Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0")) }; var dep = new Dependency("id", new SemVer.Range("^0.1.0")); var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4")); config.Dependencies.Add(dep); config.Dependencies.Add(otherDep); var depConfig = new SharedConfig { Config = new Config() { Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0")) } }; var innerDep = new Dependency("needed", new SemVer.Range("^0.1.0")); depConfig.Config.Dependencies.Add(innerDep); var otherDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4")) } }; var innerDepConfig = new SharedConfig { Config = new Config { Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.2")) } }; var configProvider = Utils.GetConfigProvider(config); var uriHandler = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> { { dep, depConfig }, { otherDep, otherDepConfig }, { innerDep, innerDepConfig } }); var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object); // Should not throw var innerDeps = innerRestorer.CollectDependencies(); Assert.Collection(innerDeps, kvp => { Assert.True(kvp.Key.Dependency.Id == innerDep.Id); Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange); Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); } ); // Assume it restored depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = innerDepConfig.Config.Info.Version }); var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object); // Should not throw var deps = restorer.CollectDependencies(); // We should now HAVE THREE dependencies! // The two dependencies for "needed" (because they are unique versions) and the dependency for "id" Assert.Collection(deps, kvp => { // Dependency ID and VersionRange must match // This is because the first dependency must be the one from our config Assert.True(kvp.Key.Dependency.Id == dep.Id); Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version); }, kvp => { // Dependency ID must match Assert.True(kvp.Key.Dependency.Id == innerDep.Id); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version); }, kvp => { // Dependency ID must match Assert.True(kvp.Key.Dependency.Id == otherDep.Id); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == otherDepConfig.Config.Info.Version); } ); var result = RestoreHandler.CollapseDependencies(deps); // After collapsing, we should have the exact same version. // This is an easy case, since their config objects are literally identical. Assert.Collection(result, kvp => { // Dependency ID and VersionRange must match // This is because the first dependency must be the one from our config Assert.True(kvp.Key.Dependency.Id == dep.Id); Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange); // Config version must be the correctly resolved version Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version); }, kvp => { // Dependency ID must match Assert.True(kvp.Key.Dependency.Id == innerDep.Id); // Config version should be the HIGHEST version. In this case, otherDepConfig Assert.True(kvp.Value.Config.Info.Version == otherDepConfig.Config.Info.Version); } ); }