Exemple #1
0
        public ProductBuild(LibraryManifest currManifest, string buildPath)
        {
            buildLogfile     = "";
            buildLogfileLock = new Object();
            buildTimes       = new StringCollection();
            libraryManifest  = currManifest;

            string buildDefinitionFile = ProductBuildDataSet.GetBuildConfigurationFilename(buildPath);

            pbDataSet = ProductBuildDataSet.ReadBuildConfigurationFile(buildDefinitionFile);
        }
Exemple #2
0
        public static bool CanBuildOnPath(string sourcePath, string buildPath, ref string errorMsg)
        {
            bool returnValue = true;

            if (LibraryManifest.IsNetworkPath(buildPath))
            {
                returnValue = false;
                errorMsg    = "Builds are not allowed on VMS product paths; ";
                errorMsg   += "please select a different path and try again.";
            }
            else
            {
                if (sourcePath.ToLower() != buildPath.ToLower())
                {
                    LibraryManifest libManifest  = new LibraryManifest(sourcePath);
                    string          buildLibName = (LibraryManifest.IsNetworkPath(sourcePath))? "NETWORK_" : "LOCAL_";
                    buildLibName += libManifest.GetBranchOrTrunkName() + "_BUILD";
                    //Abort if the path is a registered path of a non-build lib
                    VmsLibrary[] libList = LibraryBuilderConfig.GetLibrariesWithElementValue(LibraryElementNames.libraryPath, buildPath);
                    if (libList != null)
                    {
                        bool canUsePath = false;
                        foreach (VmsLibrary currLib in libList)
                        {
                            if (currLib.Name.ToLower() == buildLibName.ToLower())
                            {
                                canUsePath = true;
                            }
                        }
                        if (false == canUsePath)
                        {
                            returnValue = false;
                            errorMsg    = "A local library already exists on the selected build path; ";
                            errorMsg   += "please select a different path and try again.";
                        }
                    }
                }
            }
            return(returnValue);
        }
Exemple #3
0
        private void ValidateLibrary(NewMessage userMsg, bool isQuietMode)
        {
            string buildTimeEntry = DateTime.Now + " - Starting Validate.";

            buildTimes.Add(buildTimeEntry);
            Console.WriteLine(buildTimeEntry);

            string buildPath  = pbDataSet.GetBuildProperty("BuildPath");
            string sourcePath = pbDataSet.GetBuildProperty("SourcePath");

            // save build configuration file
            string buildDefinitionFile = ProductBuildDataSet.GetBuildConfigurationFilename(buildPath);
            string tempFile            = ProductBuildDataSet.GetBuildConfigurationFilename(Path.GetTempPath());

            if (File.Exists(tempFile))
            {
                File.SetAttributes(tempFile, FileAttributes.Normal);
                File.Delete(tempFile);
            }
            string tempBuildDefinitionDirectory = Path.Combine(Path.GetPathRoot(tempFile), Path.GetDirectoryName(tempFile));

            if (!Directory.Exists(tempBuildDefinitionDirectory))
            {
                Directory.CreateDirectory(tempBuildDefinitionDirectory);
            }
            File.Move(buildDefinitionFile, tempFile);


            // copy build definition file into buildpath
            string buildDefinitionDirectory = Path.Combine(Path.GetPathRoot(buildDefinitionFile), Path.GetDirectoryName(buildDefinitionFile));

            if (Directory.Exists(buildDefinitionDirectory))
            {
                Directory.Delete(buildDefinitionDirectory, true);
            }
            Directory.CreateDirectory(buildDefinitionDirectory);
            File.Move(tempFile, buildDefinitionFile);

            string errorMsg = null;

            if (false == CanBuildOnPath(sourcePath, buildPath, ref errorMsg))
            {
                throw new Exception(errorMsg);
            }

            string buildLibName;
            string createDate;

            if (LibraryManifest.IsNetworkPath(sourcePath))
            {
                buildLibName = "NETWORK_" + libraryManifest.GetBranchOrTrunkName() + "_BUILD";
                createDate   = new DateTime(DatabaseInterface.GetCurrentServerTime()).ToString();
            }
            else
            {
                buildLibName = "LOCAL_" + libraryManifest.GetBranchOrTrunkName() + "_BUILD";
                createDate   = libraryManifest.GetDate();
            }


            // Attempt to run LB three times. Try the first time in quiet mode.
            // Disable "quiet mode" on a retry, hoping to get information
            // useful to determine the source of problem.
            string quietModeArg          = "/q";
            int    lbExitCode            = 0;
            int    attemptCount          = 0;
            string validateBatchFilePath = buildPath + "\\validate.bat";

            while (true)
            {
                string validateCmd = LibraryBuilderConfig.GetLbCommandLinePath() + " /c " + quietModeArg + " /nocopy /src:" + sourcePath + " /path:" + buildPath;
                validateCmd += " /name:" + buildLibName + " /date:\"" + createDate + "\"";

                //create bat file in buildPath and save
                StreamWriter cmdWriter = new StreamWriter(validateBatchFilePath, false);
                cmdWriter.WriteLine(validateCmd);
                cmdWriter.WriteLine("@set LB__EXIT__CODE=%ERRORLEVEL%");
                cmdWriter.WriteLine("@echo Library validation: LB exited with code: %LB__EXIT__CODE%");
                cmdWriter.WriteLine("@exit %LB__EXIT__CODE%");
                cmdWriter.Close();

                lbExitCode = RunBatchWithInternalOutputHandling(validateBatchFilePath, null, buildPath, isQuietMode, (1 * 60 * 60 * 1000), userMsg);
                Console.WriteLine("LB exited with code: " + lbExitCode);

                if (lbExitCode != 0 && ++attemptCount < 3)
                {
                    Console.WriteLine("LB failed - retrying...");
                    quietModeArg = "";
                    continue;
                }

                break;
            }

            File.Delete(validateBatchFilePath);

            if (lbExitCode != 0)
            {
                Console.WriteLine("Unable to validate library, terminating build...");
                throw new Exception("Unable to validate library. Please see build log for details.");
            }

            // refresh LibraryInfo file with current datetime
            LibraryManifest lif = new LibraryManifest(
                pbDataSet.GetBuildProperty("ProductName"),
                pbDataSet.GetBuildProperty("ProductVersion"),
                pbDataSet.GetBuildProperty("ProductPlatform"),
                pbDataSet.GetBuildProperty("BranchOrTrunkName"),
                pbDataSet.GetBuildProperty("ProductDirectory"),
                pbDataSet.GetBuildProperty("LibraryDate"));

            lif.SaveToPath(pbDataSet.GetBuildProperty("BuildPath"));

            buildTimeEntry = DateTime.Now + " - Validate Complete.";
            if (pbDataSet.IsPartialBuild())
            {
                string binCopyCmd = Path.Combine(pbDataSet.GetBuildProperty("PBToolsPath"),
                                                 "CopyBinaries.bat");
                string copyArgs = " " + sourcePath + " " + buildPath;
                RunBatch(binCopyCmd, copyArgs, buildPath, isQuietMode, (1 * 60 * 60 * 1000), userMsg);
            }
            buildTimes.Add(buildTimeEntry);
            Console.WriteLine(buildTimeEntry);
        }
Exemple #4
0
        public int Run(NewMessage userMsg, bool isQuietMode)
        {
            int buildErrorLevel = BUILDSTATUS_INCOMPLETE;

            isValidationSuccessful = true;

            try {
                startTime = DateTime.Now;
                //must not build on net path
                if (LibraryManifest.IsNetworkPath(pbDataSet.GetBuildProperty("BuildPath")))
                {
                    string errorMsg = "Builds are not allowed on VMS product directories; ";
                    errorMsg += "please select a different build path and try again.";
                    throw new Exception(errorMsg);
                }

                // register build start in BUILD_STATUS
                RegisterBuildStart();

                // allow log to be overwritten
                SetBuildLogfile(pbDataSet.GetBuildProperty("BuildLogFileName"));
                if (File.Exists(GetBuildLogfile()))
                {
                    File.SetAttributes(GetBuildLogfile(), FileAttributes.Normal);
                    File.Delete(GetBuildLogfile());
                    FileStream logFile = File.Create(GetBuildLogfile());
                    logFile.Close();
                }

                if (!pbDataSet.SourcePathEqualsBuildPath() && !userMsg.IsCancelled())
                {
                    try {
                        ValidateLibrary(userMsg, isQuietMode);
                    }
                    catch (Exception e) {
                        isValidationSuccessful = false;
                        throw e;
                    }
                }

                if (!userMsg.IsCancelled())
                {
                    buildErrorLevel = PerformBuild(userMsg, isQuietMode);
                }
            }
            catch (Exception e) {
                buildErrorLevel = BUILDSTATUS_FAILED;
                throw e;
            }
            finally {
                completeTime = DateTime.Now;

                // register build finish in BUILD_STATUS
                RegisterBuildFinish(buildErrorLevel);

                SaveReport(buildErrorLevel, userMsg, isQuietMode);

                SendEmail(buildErrorLevel);
            }

            return(buildErrorLevel);
        }
Exemple #5
0
        static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                errorLevel = 3;
                Usage();
                return(errorLevel);
            }

            try {
                string    path = null;
                Hashtable commandLineProperties = new Hashtable();

                ProcessCommandLineArguments(args, ref path, commandLineProperties);

                LibraryManifest libraryInfo = new LibraryManifest(path);

                // default to Development profile
                string profileName            = "Development (Public)";
                string commandLineProfileName = (string)commandLineProperties["BuildProfileName"];
                profileName = (commandLineProfileName != null) ? commandLineProfileName : profileName;

                ProductBuildDataSet pbDataSet = ProductBuildDataSet.GetProductBuildDataSetWithoutComplist(
                    profileName,
                    libraryInfo.GetName(),
                    libraryInfo.GetVersion(),
                    libraryInfo.GetPlatform(),
                    libraryInfo.GetBranchOrTrunkName(),
                    libraryInfo.GetDirectory(),
                    path,
                    libraryInfo.GetDate());

                pbDataSet.ApplyCommandLineProperties(commandLineProperties);
                pbDataSet.LoadComplist();
                pbDataSet.FinalizeProperties();
                pbDataSet.WriteBuildConfigurationFile(pbDataSet.GetBuildConfigurationFilename());

                string           buildPath        = pbDataSet.GetBuildProperty("BuildPath");
                VmsProduct       currProduct      = new VmsProduct(libraryInfo.GetName(), libraryInfo.GetVersion(), libraryInfo.GetPlatform());
                VmsLibrary       currLibrary      = new VmsLibrary(currProduct, libraryInfo.GetBranchOrTrunkName());
                ControllerObject controllerObject = new ControllerObject();
                string           currentKey       = Util.GetServiceKey();
                bool             actionSucceeded  = false;
                string           errorMessage     = null;
                if (controllerObject.BuildLibrary(currLibrary, currentKey, buildPath, out errorMessage, false))
                {
                    NewMessage.ProcessMessages(currentKey, ref errorMessage, ref actionSucceeded, false, ref errorLevel);
                    if (actionSucceeded)
                    {
                        Console.WriteLine("    Successfully built " + currLibrary.ShortLibraryName);
                    }
                    else
                    {
                        Console.WriteLine("    Error building " + currLibrary.ShortLibraryName + ":" + errorMessage);
                    }
                }
                else
                {
                    Console.WriteLine("    Error building " + currLibrary.ShortLibraryName + ":" + errorMessage);
                }
            }
            catch (Exception e) {
                errorLevel = 3;
                Console.Error.WriteLine("An error occurred in ProductBuilder:");
                Console.Error.WriteLine(e.ToString());
                Usage();
            }
            return(errorLevel);
        }
Exemple #6
0
        static int Main(string[] commandArgs)
        {
            int returnValue = 0;

            try {
                if (commandArgs.Length < 1)   //error, no arg. supplied
                {
                    string errMsg = "No argument supplied.\n";
                    errMsg += "\tUsage: " + Process.GetCurrentProcess().ProcessName + " <Build Import Manifest>\n";
                    errMsg += "\tFor example, " + Process.GetCurrentProcess().ProcessName + " BuildImports.xml";
                    throw new Exception(errMsg);
                }
                if (!File.Exists(commandArgs[0]))
                {
                    throw new Exception("File not found: " + commandArgs[0]);
                }
                //Get build attributes. Note: This module always expects q:\ to be mapped to the build path by
                //LibraryBuilder prior to invocation.
                LibraryManifest     currManifest        = new LibraryManifest(LBEnvironment.BuildMapDrive);
                string              buildDefinitionFile = ProductBuildDataSet.GetBuildConfigurationFilename(LBEnvironment.BuildMapDrive);
                ProductBuildDataSet pbDataSet           = ProductBuildDataSet.ReadBuildConfigurationFile(buildDefinitionFile);
                string              buildProfile        = pbDataSet.GetBuildProperty("BuildProfileName");

                //Parse the xml file.
                XmlDocument xmlManifestDoc = new XmlDocument();
                xmlManifestDoc.Load(commandArgs[0]);
                //file may or may not contain version info
                XmlNode versionNode = xmlManifestDoc.DocumentElement.Attributes.GetNamedItem("version");
                int     fileVersion = (versionNode == null)? 1 : int.Parse(versionNode.InnerText);
                //version 3 or higher is implemented in LB and uses zip file implementation
                if (fileVersion >= 3)
                {
                    FileSystemInterface.ValidateComponentImportStep(LBEnvironment.BuildMapDrive,
                                                                    currManifest.GetBranchOrTrunkName(),
                                                                    commandArgs[0], false, true, false);
                }
                else
                {
                    foreach (XmlNode importNode in xmlManifestDoc.DocumentElement.ChildNodes)
                    {
                        if (importNode.NodeType != XmlNodeType.Comment)
                        {
                            string prodName           = importNode.Attributes["sourceProduct"].InnerText;
                            string prodVer            = importNode.Attributes["sourceVersion"].InnerText;
                            string platCode           = importNode.Attributes["sourcePlatform"].InnerText;
                            string branchOrTrunkName  = importNode.Attributes["sourceBranchOrTrunkName"].InnerText;
                            string itemToCopy         = importNode.SelectSingleNode("source").Attributes["path"].InnerText;
                            string destPath           = importNode.SelectSingleNode("destination").Attributes["path"].InnerText;;
                            bool   copySubdirectories = false;
                            bool   cleanAtDestination = false;
                            if (fileVersion > 1)
                            {
                                copySubdirectories = bool.Parse(importNode.SelectSingleNode("source").Attributes["copySubDirectories"].InnerText.ToLower());
                                cleanAtDestination = bool.Parse(importNode.SelectSingleNode("source").Attributes["cleanDestination"].InnerText.ToLower());
                            }

                            //Trim spaces and path characters
                            itemToCopy = itemToCopy.Trim(new char[] { ' ', '\\', '/' });
                            destPath   = destPath.Trim(new char[] { ' ', '\\', '/' });

                            string productPath = LBEnvironment.NetworkProductRootDir + "\\" + prodName + "\\V" + prodVer.Replace(".", "_") + "." + platCode;
                            if (!Directory.Exists(productPath))
                            {
                                throw new Exception("Product directory not found: " + productPath);
                            }

                            //Compute and identify - directory, file or wildcard - what to copy. Compute the destination as well.
                            // Also indicate whether listed path exists.
                            string       sourceFullPath          = productPath + "\\" + branchOrTrunkName + "\\" + itemToCopy;;
                            string       destFullpath            = Path.Combine(LBEnvironment.BuildMapDrive, destPath);
                            string       alternateSourceFullPath = productPath + "\\" + "DEVELOP" + "\\" + itemToCopy;;
                            bool         usingAlternateCopyPath  = false;
                            CopyItemType copyItemType            = CopyItemType.UNIDENTIFIED;
                            if (itemToCopy.IndexOf("*") > 1)
                            {
                                copyItemType = CopyItemType.WILDCARD;
                                if (!Directory.Exists(Path.GetDirectoryName(sourceFullPath)))
                                {
                                    usingAlternateCopyPath  = true;
                                    alternateSourceFullPath = productPath + "\\" + "DEVELOP" + "\\" + itemToCopy;
                                }
                            }
                            else if (Directory.Exists(sourceFullPath))
                            {
                                copyItemType = CopyItemType.DIRECTORY;
                            }
                            else if (Directory.Exists(alternateSourceFullPath))
                            {
                                copyItemType           = CopyItemType.DIRECTORY;
                                usingAlternateCopyPath = true;
                            }
                            else if (File.Exists(sourceFullPath))
                            {
                                copyItemType = CopyItemType.FILE;
                            }
                            else if (File.Exists(alternateSourceFullPath))
                            {
                                copyItemType           = CopyItemType.FILE;
                                usingAlternateCopyPath = true;
                            }
                            else   //Listed path not valid
                            {
                                throw new Exception("Unable to find import source: " + sourceFullPath);
                            }
                            //Create the destination directory
                            Directory.CreateDirectory(destFullpath);

                            //For QA profiles or non-DEVELOP builds, a build must fail if a listed path cannot be found. Accept no substitutes:
                            //A listed path must not be from DEVELOP, PREPROD, PROD or CANDIDATE and it must exist
                            if (buildProfile.ToUpper().StartsWith("QA") || (currManifest.GetBranchOrTrunkName().ToUpper() != "DEVELOP"))
                            {
                                if ((branchOrTrunkName.ToUpper() == "DEVELOP") || (branchOrTrunkName.ToUpper() == "CANDIDATE") ||
                                    (branchOrTrunkName.ToUpper() == "PREPROD") || (branchOrTrunkName.ToUpper() == "PROD") ||
                                    (branchOrTrunkName.ToUpper() == "STABLE"))
                                {
                                    string errMsg = "Cannot build QA level library or profile without a branch library import source. ";
                                    errMsg += "Please check your entry in " + commandArgs[0] + " for ";
                                    errMsg += prodName + " " + prodVer + " " + platCode + " " + branchOrTrunkName;
                                    throw new Exception(errMsg);
                                }
                                if (usingAlternateCopyPath)
                                {
                                    throw new Exception("Unable to find import source: " + sourceFullPath);
                                }
                            }

                            string sourceItem = (usingAlternateCopyPath)? alternateSourceFullPath : sourceFullPath;
                            //If copying a directory add a wildcard
                            if (copyItemType == CopyItemType.DIRECTORY)
                            {
                                sourceItem = Path.Combine(sourceItem, "*.*");
                            }
                            //if clean copy was requested, delete source files' paths at destination
                            if (cleanAtDestination && Directory.Exists(destFullpath))
                            {
                                ImportComponents.DeleteFiles(Path.Combine(destFullpath, Path.GetFileName(sourceItem)), copySubdirectories);
                            }

                            returnValue = ImportComponents.XCopyDirToQDrive(sourceItem, destFullpath, copySubdirectories);
                            if (returnValue != 0)
                            {
                                throw new Exception("xcopy returned an error(" + returnValue.ToString() + ") while copying " + sourceItem + " to " + destFullpath);
                            }
                        }
                    }//foreach
                }
            }
            catch (Exception currExcept) {
                Console.WriteLine("Error occurred during build import: " + currExcept.Message);
                if (returnValue == 0)
                {
                    returnValue = 1;
                }
            }
            return(returnValue);
        }
Exemple #7
0
        static int Main(string[] args)
        {
            int errlvl = 0;

            try {
                // Process Command-line Arguments
                string buildPath        = null;
                string buildUserProfile = null;
                string maxFileAge       = null;
                string exclusionFile    = null;
                string buildCfgFile     = null;

                if (args.Length < 1)
                {
                    Console.WriteLine();
                    Console.Error.WriteLine("Missing or Invalid Parameter.");
                    Usage();
                    errlvl = 2;
                    return(errlvl);
                }

                buildPath = args[0];
                foreach (string arg in args)
                {
                    if (arg.ToLower().StartsWith("/p:"))
                    {
                        buildUserProfile = arg.Substring(3).Trim();
                    }
                    if (arg.ToLower().StartsWith("/a:"))
                    {
                        maxFileAge = arg.Substring(3).Trim();
                    }
                    if (arg.ToLower().StartsWith("/e:"))
                    {
                        exclusionFile = arg.Substring(3).Trim();
                    }
                    if (arg.ToLower().StartsWith("/f:"))
                    {
                        buildCfgFile = arg.Substring(3).Trim();
                    }
                }

                Console.WriteLine();
                Console.WriteLine("buildPath:        " + buildPath);
                Console.WriteLine("buildUserProfile: " + buildUserProfile);
                Console.WriteLine("maxFileAge:       " + maxFileAge);
                Console.WriteLine("exclusionFile:    " + exclusionFile);
                Console.WriteLine("buildCfgFile:     " + buildCfgFile);
                Console.WriteLine();

                //build dataset
                ProductBuildDataSet pbDataSet = null;
                if (buildCfgFile != null)
                {
                    pbDataSet = ProductBuildDataSet.ReadBuildConfigurationFile(buildCfgFile);
                }
                else
                {
                    LibraryManifest li = new LibraryManifest(buildPath);
                    if (buildUserProfile == null)
                    {
                        buildUserProfile = "Development";
                    }
                    pbDataSet = ProductBuildDataSet.GetProductBuildDataSetWithoutComplist(buildUserProfile,
                                                                                          li.GetName(),
                                                                                          li.GetVersion(),
                                                                                          li.GetPlatform(),
                                                                                          li.GetBranchOrTrunkName(),
                                                                                          li.GetDirectory(),
                                                                                          buildPath,
                                                                                          li.GetDate());
                    pbDataSet.LoadComplist();
                    pbDataSet.FinalizeProperties();
                }

                if (maxFileAge == null)
                {
                    maxFileAge = pbDataSet.GetBuildProperty("MaximumTargetAge");
                }
                //hack for backwards compatibility
                int colonIndex  = maxFileAge.IndexOf(':');
                int periodIndex = maxFileAge.IndexOf('.');
                if (periodIndex == -1 || colonIndex < periodIndex)
                {
                    maxFileAge = maxFileAge.Substring(0, colonIndex) + "." + maxFileAge.Substring(colonIndex + 1);
                }

                ArrayList checkedTargets   = pbDataSet.GetTargets(true);
                ArrayList uncheckedTargets = pbDataSet.GetTargets(false);

                if (exclusionFile != null)
                {
                    StringCollection excludedFiles = CollectionUtil.ReadValueFile(exclusionFile);
                    foreach (string excludedFile in excludedFiles)
                    {
                        foreach (string checkedTarget in checkedTargets)
                        {
                            if (excludedFile.ToLower() == checkedTarget.ToLower())
                            {
                                checkedTargets.Remove(checkedTarget);
                                uncheckedTargets.Add(checkedTarget);
                            }
                        }
                    }
                    uncheckedTargets.Sort();
                }

                //check the build
                Console.WriteLine();
                Console.WriteLine("Checking product , {0}, {1}, {2}, {3}",
                                  new object[] { pbDataSet.GetBuildProperty("ProductName"),
                                                 pbDataSet.GetBuildProperty("ProductVersion"),
                                                 pbDataSet.GetBuildProperty("ProductPlatform"),
                                                 pbDataSet.GetBuildProperty("BranchOrTrunkName"),
                                                 buildPath });
                Console.WriteLine("  in {0}", buildPath);
                Console.WriteLine();

                int  totalTargets     = checkedTargets.Count + uncheckedTargets.Count;
                int  foundTargets     = 0;
                int  duplicateTargets = 0;
                int  excludedTargets  = uncheckedTargets.Count;
                int  missingTargets   = 0;
                int  overAgeTargets   = 0;
                bool buildSucceeded   = true;

                string binPath = Path.Combine(buildPath, "bin");

                DateTime currentTime = DateTime.Now;
                DateTime checkTime   = currentTime - TimeSpan.Parse(maxFileAge);
                for (int targetIndex = 0; targetIndex < checkedTargets.Count; targetIndex++)
                {
                    string target = (string)checkedTargets[targetIndex];
                    if (targetIndex > 0 && target.ToLower() == ((string)checkedTargets[targetIndex - 1]).ToLower())
                    {
                        duplicateTargets++;
                        continue;
                    }
                    string targetFilename = Path.Combine(binPath, target);
                    if (!File.Exists(targetFilename))
                    {
                        buildSucceeded = false;
                        missingTargets++;
                        Console.WriteLine("{0,-32} Missing", target);
                        continue;
                    }
                    foundTargets++;
                    DateTime creationTime = File.GetLastWriteTime(targetFilename);
                    if (creationTime < checkTime)
                    {
                        buildSucceeded = false;
                        overAgeTargets++;
                        TimeSpan overAgeTime   = currentTime - creationTime;
                        string   overAgeString = "";
                        if (overAgeTime.Days > 0)
                        {
                            overAgeString += String.Format("{0,4}d", overAgeTime.Days);
                        }
                        if (overAgeTime.Hours > 0)
                        {
                            overAgeString += String.Format("{0:D2}h", overAgeTime.Hours);
                        }
                        overAgeString += String.Format("{0:D2}m", overAgeTime.Minutes);
                        Console.WriteLine("{0,-32} OverAge:{1}", target, overAgeString);
                    }
                }

                //results summary
                Console.WriteLine();
                Console.WriteLine("CheckBuild Statistics:");
                Console.WriteLine("Product           : {0}", pbDataSet.GetBuildProperty("ProductName"));
                Console.WriteLine("Version           : {0}", pbDataSet.GetBuildProperty("ProductVersion"));
                Console.WriteLine("Platform          : {0}", pbDataSet.GetBuildProperty("ProductPlatform"));
                Console.WriteLine("BranchOrTrunkName : {0}", pbDataSet.GetBuildProperty("BranchOrTrunkName"));
                Console.WriteLine("Target Dir        : {0}", buildPath);
                Console.WriteLine("Max File Age      : {0} (DD.HH:MM:SS)", maxFileAge);
                Console.WriteLine("Targets           : {0}", totalTargets);
                Console.WriteLine("Found             : {0}", foundTargets);
                Console.WriteLine("Duplicates        : {0}", duplicateTargets);
                Console.WriteLine("Excluded          : {0}", excludedTargets);
                Console.WriteLine("Missing           : {0}", missingTargets);
                Console.WriteLine("OverAge           : {0}", overAgeTargets);
                string successString = (buildSucceeded) ? "Successful Build." : "Build Failed!!!";
                Console.WriteLine("Results           : {0}", successString);

                errlvl = (buildSucceeded) ? 0 : 1;
            }
            catch (Exception e) {
                errlvl = 2;
                Console.Error.WriteLine("An error occurred in CheckBuild:");
                Console.Error.WriteLine(e.ToString());
                Usage();
            }

            return(errlvl);
        }