示例#1
0
        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);
                }
            }
        }
示例#2
0
        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);
            }
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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);
            }
        }