internal bool CreateAggregatePackage(AggregatePackage package) { // The assumption is that in order for the source of an aggregate to change the package source folder must of changed for a new version. // And therefor it is assumed this never needs to be regenerated (assumed corruption would be cleaned up manually). if (Directory.Exists(package.OutPropertyValue)) { Log.LogMessage(MessageImportance.Low, $"{package.OutPropertyValue} already created. Skipping"); return(true); } using (var mutex = new Mutex(false, package.OutPropertyValue.GetHash(prefix: @"Global\"))) { bool owner = false; try { var outTmpDir = package.OutPropertyValue + ".tmp"; FileUtilities.AcquireMutex(mutex); owner = true; // check again to see if aggregate package is already created while waiting. if (Directory.Exists(package.OutPropertyValue)) { Log.LogMessage(MessageImportance.Low, $"{package.OutPropertyValue} already created. Skipping"); return(true); } if (Directory.Exists(outTmpDir)) { Log.LogMessage(MessageImportance.Low, $"{outTmpDir} not cleaned up from previous build cleaning now."); Directory.Delete(outTmpDir, true); } foreach (var srcPkg in package.PackagesToAggregate) { if (srcPkg.Operation.Equals(AggregatePackage.AggregateOperation.Add)) { Log.LogMessage(MessageImportance.Low, $"Adding {srcPkg.Folder} to aggregate of {package.OutPropertyValue}"); FileUtilities.DirectoryCopy(srcPkg.Folder, outTmpDir, true, true); } if (srcPkg.Operation.Equals(AggregatePackage.AggregateOperation.Remove)) { Log.LogMessage(MessageImportance.Low, $"Removing {srcPkg.Folder} from aggregate of {package.OutPropertyValue}"); FileUtilities.DirectoryRemove(srcPkg.Folder, outTmpDir, true); } } Directory.Move(outTmpDir, package.OutPropertyValue); } finally { if (owner) { mutex.ReleaseMutex(); } } } return(Directory.Exists(package.OutPropertyValue)); }