IdentifyAllPackages( bool allowDuplicates = false, bool enforceBamAssemblyVersions = true) { var packageRepos = new System.Collections.Generic.Queue<string>(); foreach (var repo in Graph.Instance.PackageRepositories) { if (packageRepos.Contains(repo)) { continue; } packageRepos.Enqueue(repo); } var masterDefinitionFile = GetMasterPackage(enforceBamAssemblyVersions: enforceBamAssemblyVersions); foreach (var repo in masterDefinitionFile.PackageRepositories) { if (packageRepos.Contains(repo)) { continue; } packageRepos.Enqueue(repo); } // read the definition files of any package found in the package roots var candidatePackageDefinitions = new Array<PackageDefinition>(); candidatePackageDefinitions.Add(masterDefinitionFile); while (packageRepos.Count > 0) { var repo = packageRepos.Dequeue(); if (!System.IO.Directory.Exists(repo)) { throw new Exception("Package repository directory {0} does not exist", repo); } var candidatePackageDirs = System.IO.Directory.GetDirectories(repo, BamSubFolder, System.IO.SearchOption.AllDirectories); Graph.Instance.PackageRepositories.Add(repo); foreach (var bamDir in candidatePackageDirs) { var packageDir = System.IO.Path.GetDirectoryName(bamDir); var packageDefinitionPath = GetPackageDefinitionPathname(packageDir); // ignore any duplicates (can be found due to nested repositories) if (null != candidatePackageDefinitions.Where(item => item.XMLFilename == packageDefinitionPath).FirstOrDefault()) { continue; } var definitionFile = new PackageDefinition(packageDefinitionPath, !Graph.Instance.ForceDefinitionFileUpdate); definitionFile.Read(true, enforceBamAssemblyVersions); candidatePackageDefinitions.Add(definitionFile); foreach (var newRepo in definitionFile.PackageRepositories) { if (Graph.Instance.PackageRepositories.Contains(newRepo)) { continue; } packageRepos.Enqueue(newRepo); } } } // defaults come from // - the master definition file // - command line args (these trump the mdf) // and only requires resolving when referenced var packageDefinitions = new Array<PackageDefinition>(); PackageDefinition.ResolveDependencies(masterDefinitionFile, packageDefinitions, candidatePackageDefinitions); // now resolve any duplicate names using defaults // unless duplicates are allowed var duplicatePackageNames = packageDefinitions.GroupBy(item => item.Name).Where(item => item.Count() > 1).Select(item => item.Key); if ((duplicatePackageNames.Count() > 0) && !allowDuplicates) { var versionSpeciferArgs = new Options.PackageDefaultVersion(); var packageVersionSpecifiers = CommandLineProcessor.Evaluate(versionSpeciferArgs); var toRemove = new Array<PackageDefinition>(); foreach (var dupName in duplicatePackageNames) { var duplicates = packageDefinitions.Where(item => item.Name == dupName); PackageDefinition resolvedDuplicate = null; // command line specifications take precedence to resolve a duplicate foreach (var specifier in packageVersionSpecifiers) { if (!specifier.Contains(dupName)) { continue; } foreach (var dupPackage in duplicates) { if (specifier[1] == dupPackage.Version) { resolvedDuplicate = dupPackage; break; } } if (resolvedDuplicate != null) { break; } var noMatchMessage = new System.Text.StringBuilder(); noMatchMessage.AppendFormat("Command line version specified, {0}, could not resolve to one of the available versions of package {1}:", specifier[1], duplicates.First().Name); noMatchMessage.AppendLine(); foreach (var dup in duplicates) { noMatchMessage.AppendFormat("\t{0}", dup.Version); noMatchMessage.AppendLine(); } throw new Exception(noMatchMessage.ToString()); } if (resolvedDuplicate != null) { toRemove.AddRange(packageDefinitions.Where(item => (item.Name == dupName) && (item != resolvedDuplicate))); continue; } // now look at the master dependency file, for any 'default' specifications var masterDependency = masterDefinitionFile.Dependents.Where(item => item.Item1 == dupName && item.Item3.HasValue && item.Item3.Value).FirstOrDefault(); if (null != masterDependency) { toRemove.AddRange(packageDefinitions.Where(item => (item.Name == dupName) && (item.Version != masterDependency.Item2))); continue; } var resolveErrorMessage = new System.Text.StringBuilder(); resolveErrorMessage.AppendFormat("Unable to resolve to a single version of package {0}. Use --{0}.version=<version> to resolve. Available versions of the package are:", duplicates.First().Name); resolveErrorMessage.AppendLine(); foreach (var dup in duplicates) { resolveErrorMessage.AppendFormat("\t{0}", dup.Version); resolveErrorMessage.AppendLine(); } throw new Exception(resolveErrorMessage.ToString()); } packageDefinitions.RemoveAll(toRemove); } Graph.Instance.SetPackageDefinitions(packageDefinitions); }
GetMasterPackage( bool enforceBamAssemblyVersions = true) { var workingDir = Graph.Instance.ProcessState.WorkingDirectory; var isWorkingPackageWellDefined = IsPackageDirectory(workingDir); if (!isWorkingPackageWellDefined) { throw new Exception("Working directory package is not well defined"); } var masterDefinitionFile = new PackageDefinition(GetPackageDefinitionPathname(workingDir), !Graph.Instance.ForceDefinitionFileUpdate); masterDefinitionFile.Read(true, enforceBamAssemblyVersions); return masterDefinitionFile; }