IdentifyAllPackages( bool allowDuplicates = false, bool enforceBamAssemblyVersions = true) { var packageRepos = new System.Collections.Generic.LinkedList <System.Tuple <string, PackageDefinition> >(); int reposHWM = 0; foreach (var repo in Graph.Instance.PackageRepositories) { EnqueuePackageRepositoryToVisit(packageRepos, ref reposHWM, repo, null); } var masterDefinitionFile = GetMasterPackage(); foreach (var repo in masterDefinitionFile.PackageRepositories) { EnqueuePackageRepositoryToVisit(packageRepos, ref reposHWM, repo, masterDefinitionFile); } // read the definition files of any package found in the package roots var candidatePackageDefinitions = new Array <PackageDefinition>(); candidatePackageDefinitions.Add(masterDefinitionFile); var packageReposVisited = 0; Log.Detail("Querying package repositories..."); while (packageRepos.Count > 0) { var repoTuple = packageRepos.First(); packageRepos.RemoveFirst(); var repo = repoTuple.Item1; if (!System.IO.Directory.Exists(repo)) { var message = new System.Text.StringBuilder(); message.AppendFormat("Package repository directory {0} does not exist.", repo); message.AppendLine(); message.AppendFormat("Repository requested from {0}", repoTuple.Item2.XMLFilename); message.AppendLine(); throw new Exception(message.ToString()); } // faster than System.IO.Directory.GetDirectories(repo, BamSubFolder, System.IO.SearchOption.AllDirectories); // when there are deep directories StringArray candidatePackageDirs = new StringArray(); var possiblePackages = System.IO.Directory.GetDirectories(repo, "*", System.IO.SearchOption.TopDirectoryOnly); foreach (var packageDir in possiblePackages) { var possibleBamFolder = System.IO.Path.Combine(packageDir, BamSubFolder); if (System.IO.Directory.Exists(possibleBamFolder)) { candidatePackageDirs.Add(packageDir); } } Graph.Instance.PackageRepositories.Add(repo); foreach (var packageDir in candidatePackageDirs) { var packageDefinitionPath = GetPackageDefinitionPathname(packageDir); // ignore any duplicates (can be found due to nested repositories) if (null != candidatePackageDefinitions.FirstOrDefault(item => item.XMLFilename == packageDefinitionPath)) { continue; } var definitionFile = new PackageDefinition(packageDefinitionPath); definitionFile.Read(); candidatePackageDefinitions.Add(definitionFile); foreach (var newRepo in definitionFile.PackageRepositories) { EnqueuePackageRepositoryToVisit(packageRepos, ref reposHWM, newRepo, definitionFile); } } ++packageReposVisited; Log.DetailProgress("{0,3}%", (int)(100 * ((float)packageReposVisited / reposHWM))); } #if DEBUG if (packageReposVisited != reposHWM) { throw new Exception("Inconsistent package repository count: {0} added, {1} visited", reposHWM, packageReposVisited); } #endif // 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); var uniquePackageNames = packageDefinitions.GroupBy(item => item.Name).Where(item => item.Count() == 1).Select(item => item.Key); var versionSpeciferArgs = new Options.PackageDefaultVersion(); var packageVersionSpecifiers = CommandLineProcessor.Evaluate(versionSpeciferArgs); if ((duplicatePackageNames.Count() > 0) && !allowDuplicates) { var toRemove = new Array <PackageDefinition>(); foreach (var dupName in duplicatePackageNames) { var duplicates = packageDefinitions.Where(item => item.Name == dupName); var resolvedDuplicate = TryToResolveDuplicate(masterDefinitionFile, dupName, duplicates, packageDefinitions, packageVersionSpecifiers, toRemove); if (null != resolvedDuplicate) { continue; } // try removing any packages that have already been resolved // which can remove additional packages (recursive check) because they had been added solely by those we are just about to remove packageDefinitions.RemoveAll(PackagesToRemove(toRemove, packageDefinitions, masterDefinitionFile)); packageDefinitions.RemoveAll(toRemove); // and if that has reduced the duplicates for this package down to a single version, we're good to carry on var numDuplicates = duplicates.Count(); if (1 == numDuplicates) { toRemove.Clear(); continue; } // otherwise, error var resolveErrorMessage = new System.Text.StringBuilder(); if (numDuplicates > 0) { resolveErrorMessage.AppendFormat("Unable to resolve to a single version of package {0}. Use --{0}.version=<version> to resolve.", dupName); resolveErrorMessage.AppendLine(); resolveErrorMessage.AppendLine("Available versions of the package are:"); foreach (var dup in duplicates) { resolveErrorMessage.AppendFormat("\t{0}", dup.Version); resolveErrorMessage.AppendLine(); } } else { resolveErrorMessage.AppendFormat("No version of package {0} has been determined to be available.", dupName); resolveErrorMessage.AppendLine(); if (toRemove.Count() > 0) { resolveErrorMessage.AppendFormat("If there were any references to {0}, they may have been removed from consideration by the following packages being discarded:", dupName); resolveErrorMessage.AppendLine(); foreach (var removed in toRemove) { resolveErrorMessage.AppendFormat("\t{0}", removed.FullName); resolveErrorMessage.AppendLine(); } } resolveErrorMessage.AppendFormat("Please add an explicit dependency to (a version of) the {0} package either in your master package or one of its dependencies.", dupName); resolveErrorMessage.AppendLine(); } throw new Exception(resolveErrorMessage.ToString()); } // finally, clean up the package definition list to use, with all those that need to be deleted packageDefinitions.RemoveAll(toRemove); } // ensure that all packages with a single version in the definition files, does not have a command line override // that refers to a completely different version foreach (var uniquePkgName in uniquePackageNames) { foreach (var versionSpecifier in packageVersionSpecifiers) { if (!versionSpecifier.Contains(uniquePkgName)) { continue; } var versionFromDefinition = packageDefinitions.First(item => item.Name == uniquePkgName).Version; if (versionSpecifier[1] != versionFromDefinition) { 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}:", versionSpecifier[1], uniquePkgName); noMatchMessage.AppendLine(); noMatchMessage.AppendFormat("\t{0}", versionFromDefinition); noMatchMessage.AppendLine(); throw new Exception(noMatchMessage.ToString()); } } } if (enforceBamAssemblyVersions) { // for all packages that make up this assembly, ensure that their requirements on the version of the Bam // assemblies are upheld, prior to compiling the code foreach (var pkgDefn in packageDefinitions) { pkgDefn.ValidateBamAssemblyRequirements(); } } Graph.Instance.SetPackageDefinitions(packageDefinitions); }
DumpProfiles() { var additionalDetails = false; var profileHeader = "Profile"; var minutesHeader = "Minutes"; var secondsHeader = "Seconds"; var millisecondsHeader = "Milliseconds"; var startTimeHeader = "Start"; var stopTimeHeader = "Stop"; int maxNameLength = profileHeader.Length; int maxMinuteLength = minutesHeader.Length; int maxSecondLength = secondsHeader.Length; int maxMillisecondLength = millisecondsHeader.Length; int maxTimeLength = 9; foreach (var profile in Profiles) { int nameLength = profile.Profile.ToString().Length; if (nameLength > maxNameLength) { maxNameLength = nameLength; } int minuteLength = profile.Elapsed.Minutes.ToString().Length; if (minuteLength > maxMinuteLength) { maxMinuteLength = minuteLength; } int secondLength = profile.Elapsed.Seconds.ToString().Length; if (secondLength > maxSecondLength) { maxSecondLength = secondLength; } int millisecondLength = profile.Elapsed.Milliseconds.ToString().Length; if (millisecondLength > maxMillisecondLength) { maxMillisecondLength = millisecondLength; } } var header = System.String.Format("{0}{1} | {2}{3} | {4}{5} | {6}{7} | {8}{9} | {10}{11}", profileHeader, new string(' ', maxNameLength - profileHeader.Length), minutesHeader, new string(' ', maxMinuteLength - minutesHeader.Length), secondsHeader, new string(' ', maxSecondLength - secondsHeader.Length), millisecondsHeader, new string(' ', maxMillisecondLength - millisecondsHeader.Length), new string(' ', maxTimeLength - startTimeHeader.Length), startTimeHeader, new string(' ', maxTimeLength - stopTimeHeader.Length), stopTimeHeader); var horizontalRule = new string('-', header.Length); Log.Info("\nTask timing"); Log.Info(horizontalRule); Log.Info(header); Log.Info(horizontalRule); var cumulativeTime = new System.TimeSpan(); foreach (var profile in Profiles) { var elapsedTime = (null != profile) ? profile.Elapsed : new System.TimeSpan(0); if (ETimingProfiles.TimedTotal != profile.Profile) { cumulativeTime = cumulativeTime.Add(elapsedTime); } string diffString = null; if (additionalDetails && (ETimingProfiles.TimedTotal != profile.Profile)) { var diff = profile.Start - Profiles.First().Stop; diffString = diff.Milliseconds.ToString(); } var minuteString = elapsedTime.Minutes.ToString(); var secondString = elapsedTime.Seconds.ToString(); var millisecondString = elapsedTime.Milliseconds.ToString(); var startTimeString = (null != profile) ? profile.Start.ToString(TimeProfile.DateTimeFormat) : "0"; var stopTimeString = (null != profile) ? profile.Stop.ToString(TimeProfile.DateTimeFormat) : "0"; if (ETimingProfiles.TimedTotal == profile.Profile) { Log.Info(horizontalRule); var cumulativeString = "CumulativeTotal"; var cumulativeMinutesString = cumulativeTime.Minutes.ToString(); var cumulativeSecondsString = cumulativeTime.Seconds.ToString(); var cumulativeMillisecondsString = cumulativeTime.Milliseconds.ToString(); Log.Info("{0}{1} | {2}{3} | {4}{5} | {6}{7}", cumulativeString, new string(' ', maxNameLength - cumulativeString.Length), new string(' ', maxMinuteLength - cumulativeMinutesString.Length), cumulativeMinutesString, new string(' ', maxSecondLength - cumulativeSecondsString.Length), cumulativeSecondsString, new string(' ', maxMillisecondLength - cumulativeMillisecondsString.Length), cumulativeMillisecondsString); Log.Info(horizontalRule); } Log.Info("{0}{1} | {2}{3} | {4}{5} | {6}{7} | {8}{9} | {10}{11} {12}", profile.Profile.ToString(), new string(' ', maxNameLength - profile.Profile.ToString().Length), new string(' ', maxMinuteLength - minuteString.Length), minuteString, new string(' ', maxSecondLength - secondString.Length), secondString, new string(' ', maxMillisecondLength - millisecondString.Length), millisecondString, new string(' ', maxTimeLength - startTimeString.Length), startTimeString, new string(' ', maxTimeLength - stopTimeString.Length), stopTimeString, diffString); } Log.Info(horizontalRule); }