/* =========================================================================================== */ public void ExecuteRelevantPatches(IEnumerable <ISnPatch> candidates, PatchExecutionContext context) { var patchesToExec = candidates.ToList(); while (true) { var installedComponents = LoadInstalledComponents(); var executables = GetExecutablePatches(patchesToExec, installedComponents, context, out _); if (executables.Length == 0) { break; } var faulty = ExecutePatches(executables, context); if (faulty == null) { break; } RemoveNotExecutables(context, patchesToExec); if (patchesToExec.Count == 0) { break; } } }
private void RemoveNotExecutables(PatchExecutionContext context, List <ISnPatch> patchesToExec) { var patches = context.Errors.SelectMany(x => x.FaultyPatches); foreach (var patch in patches) { patchesToExec.Remove(patch); } }
internal PatchManager(PatchExecutionContext context) { _context = context; }
public PatchManager(RepositoryStartSettings settings, Action <PatchExecutionLogRecord> logCallback) { _context = new PatchExecutionContext(settings, logCallback); }
public ISnPatch[] GetExecutablePatches(IEnumerable <ISnPatch> candidates, SnComponentDescriptor[] installedComponents, PatchExecutionContext context, out SnComponentDescriptor[] componentsAfter) { var patches = candidates.ToArray(); var installedIds = installedComponents .Where(x => x.Version != null && x.Version > NullVersion) .Select(x => x.ComponentId) .ToArray(); var installers = patches .Where(x => x.Type == PackageType.Install && !installedIds.Contains(x.ComponentId)) .OrderBy(x => x.ComponentId) .ToArray(); var installerGroups = installers.GroupBy(x => x.ComponentId); var duplicates = installerGroups.Where(x => x.Count() > 1).Select(x => x.Key).ToArray(); if (duplicates.Length > 0) { // Duplicates are not allowed foreach (var id in duplicates) { var message = "There is a duplicated installer for the component " + id; var faultyPatches = installers.Where(inst => inst.ComponentId == id).ToArray(); var error = new PatchExecutionError(PatchExecutionErrorType.DuplicatedInstaller, faultyPatches, message); var logRecord = new PatchExecutionLogRecord(PatchExecutionEventType.DuplicatedInstaller, faultyPatches.First(), message); context.Errors.Add(error); context.LogCallback(logRecord); } // Set unchanged list as output componentsAfter = installedComponents.ToArray(); return(new ISnPatch[0]); } // Order patches by componentId and versions var orderedSnPatches = patches .Where(x => x.Type == PackageType.Patch) .OrderBy(x => x.ComponentId).ThenBy(x => x.Version) .ToArray(); // ------------------------------------------------------------ sorting by dependencies var inputList = installers.Union(orderedSnPatches).ToList(); var outputList = new List <ISnPatch>(); // patches in right order to execute var installed = new List <SnComponentDescriptor>(installedComponents); // all simulated components. var currentlyManaged = new List <ISnPatch>(); // temporary list in one iteration. while (true) { foreach (var item in inputList) { if (CheckPrerequisites(item, installed, out var skipExecution, out var error)) { currentlyManaged.Add(item); outputList.Add(item); if (item is SnPatch snPatch) { // Modify version and dependencies of the installed components. var patchedComponent = installed.Single(x => x.ComponentId == snPatch.ComponentId); patchedComponent.Version = (Version)snPatch.Version.Clone(); patchedComponent.Dependencies = snPatch.Dependencies?.ToArray(); } else if (item is ComponentInstaller installer) { // Add to installed components. installed.Add(new SnComponentDescriptor(installer.ComponentId, installer.Version, installer.Description, installer.Dependencies?.ToArray())); } else { throw new SnNotSupportedException(); } }
public IEnumerable <ISnPatch> GetExecutablePatches(IEnumerable <ISnPatch> candidates, PatchExecutionContext context) { return(GetExecutablePatches(candidates, LoadInstalledComponents(), context, out _)); }
internal ISnPatch ExecuteRelevantPatches(IEnumerable <ISnPatch> candidates, SnComponentDescriptor[] installedComponents, PatchExecutionContext context) { return(ExecutePatches( GetExecutablePatches(candidates, installedComponents, context, out _), context)); }