public async Task Run(Context context, Log log = null) { Log = log; foreach (Step step in Steps) { context.Banner(step.Description ?? step.GetType().FullName); bool success; Exception stepEx = null; try { success = await step.Run(context); } catch (Exception ex) { stepEx = ex; success = false; } if (success) { continue; } string message = $"Step {step.FailedStep ?? step} failed"; if (stepEx != null) { throw new InvalidOperationException($"{message}: {stepEx.Message}", stepEx); } else { throw new InvalidOperationException(message); } } }
public async Task <bool> Run(Context context) { FailedStep = null; bool success = await Execute(context); if (success) { return(true); } if (!HasFailureSteps) { return(false); } foreach (Step step in failureSteps !) { ExecutedFailureSteps = true; context.Banner(step.Description); try { if (!await step.Run(context)) { FailedStep = step; return(false); } } catch { FailedStep = step; throw; } } return(true); }
static void DumpProperties(Context context) { if (context.Properties.Count == 0) { Log.Instance.InfoLine("No properties defined"); return; } context.Banner("Defined properties"); foreach (var kvp in context.Properties) { Log.Instance.InfoLine($"{kvp.Key} = ", kvp.Value ?? "<null>", ConsoleColor.White, ConsoleColor.White); } }
/// <summary> /// <para> /// Initialize OS support. Initializes basic OS properties (by calling <see cref="InitOS"/>), dependencies (by /// calling <see cref="InitializeDependencies"/>) as well as makes sure that all the dependencies are /// installed and initializes the environment. /// </para> /// <para> /// Missing dependencies are installed only if <see cref="KnownConditions.AllowProgramInstallation"/> /// condition is set and and <see cref="Context.AutoProvision"/> is <c>true</c>. If the two conditions aren't /// met and missing programs are found, the initialization fails unless the <see /// cref="KnownConditions.IgnoreMissingPrograms"/> is set to <c>true</c> in which case only a warning is /// printed regarding the missing dependencies. /// </para> /// </summary> public async Task <bool> Init() { if (!InitOS()) { throw new InvalidOperationException("Failed to initialize operating system support"); } InitializeDependencies(); Context.Banner("Ensuring all required programs are installed"); if (!await EnsureDependencies()) { return(false); } Context.Banner("Configuring environment"); ConfigureEnvironment(); return(true); }
async Task <bool> EnsureDependencies() { if (Dependencies == null) { throw new InvalidOperationException("Dependencies not set"); } Log.Todo("Implement 'package refresh' mode where we reinstall packages/programs forcibly"); int maxNameLength = GetMaxNameLength(Dependencies); var missing = new List <Program> (); foreach (Program p in Dependencies) { if (p == null) { continue; } Log.Status($"Checking ", $"{p.Name}".PadRight(maxNameLength), tailColor: ConsoleColor.White); bool installed = await p.IsInstalled(); if (installed) { if (!p.InstalledButWrongVersion) { Log.StatusLine($" [FOUND {p.CurrentVersion}]", Context.SuccessColor); } else { Log.StatusLine($" [WRONG VERSION {p.CurrentVersion}]", Context.WarningColor); missing.Add(p); } } else { Log.StatusLine(" [MISSING]", Context.FailureColor); missing.Add(p); } } if (missing.Count == 0) { return(true); } bool ignoreMissing = Context.Instance.CheckCondition(KnownConditions.IgnoreMissingPrograms); if (!Context.Instance.AutoProvision) { string message = "Some programs are missing or have invalid versions, but automatic provisioning is disabled"; if (ignoreMissing) { Log.WarningLine($"{message}. Ignoring missing programs."); return(true); } Log.ErrorLine(message); return(false); } maxNameLength = GetMaxNameLength(missing); Context.Banner("Installing programs"); if (missing.Any(p => p.NeedsSudoToInstall)) { Log.StatusLine("You might be prompted for your sudo password"); } bool someFailed = false; foreach (Program p in missing) { if (p.NeedsSudoToInstall && !Context.AutoProvisionUsesSudo) { Log.ErrorLine($"Program '{p.Name}' requires sudo to install but sudo is disabled"); someFailed = true; continue; } if (!p.CanInstall()) { if (!ignoreMissing) { someFailed = true; } Log.Status("Installation disabled for "); Log.StatusLine(p.Name.PadRight(maxNameLength), ConsoleColor.Cyan); continue; } Log.Status("Installing "); Log.StatusLine(p.Name.PadRight(maxNameLength), ConsoleColor.White); bool success = await p.Install(); Log.StatusLine(); if (success) { continue; } someFailed = true; Log.ErrorLine($"Installation of {p.Name} failed"); } if (someFailed) { throw new InvalidOperationException("Failed to install some required programs."); } return(true); int GetMaxNameLength(List <Program> list) { int ret = 0; list.ForEach(p => { int len = p.Name.Length; if (len < ret) { return; } ret = len; } ); ret++; return(ret); } }