// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include namespace cpr { class Response; } namespace zen { struct ZenCliOptions { bool IsDebug = false; bool IsVerbose = false; // Arguments after " -- " on command line are passed through and not parsed std::string PassthroughCommandLine; std::string PassthroughArgs; std::vector PassthroughArgV; }; struct ZenCmdCategory { std::string Name; std::map SortedCmds; }; extern ZenCmdCategory g_UtilitiesCategory; extern ZenCmdCategory g_ProjectStoreCategory; extern ZenCmdCategory g_CacheStoreCategory; extern ZenCmdCategory g_StorageCategory; /** Base class for command implementations */ class ZenCmdBase { public: virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) = 0; virtual cxxopts::Options& Options() = 0; virtual ZenCmdCategory& CommandCategory() const; bool ParseOptions(int argc, char** argv); static bool ParseOptions(cxxopts::Options& Options, int argc, char** argv); static int GetSubCommand(cxxopts::Options& Options, int argc, char** argv, std::span SubOptions, cxxopts::Options*& OutSubOption, std::vector& OutSubCommandArguments); static std::string FormatHttpResponse(const cpr::Response& Response); static int MapHttpToCommandReturnCode(const cpr::Response& Response); static std::string ResolveTargetHostSpec(const std::string& InHostSpec); static std::string ResolveTargetHostSpec(const std::string& InHostSpec, uint16_t& OutEffectivePort); }; class StorageCommand : public ZenCmdBase { virtual ZenCmdCategory& CommandCategory() const override { return g_StorageCategory; } }; class CacheStoreCommand : public ZenCmdBase { virtual ZenCmdCategory& CommandCategory() const override { return g_CacheStoreCategory; } }; class ProgressBar { public: struct State { bool operator==(const State&) const = default; std::string Task; std::string Details; uint64_t TotalCount = 0; uint64_t RemainingCount = 0; enum class EStatus { Running, Aborted, Paused }; EStatus Status = EStatus::Running; static EStatus CalculateStatus(bool IsAborted, bool IsPaused) { if (IsAborted) { return EStatus::Aborted; } if (IsPaused) { return EStatus::Paused; } return EStatus::Running; } }; enum class Mode { Plain, Pretty, Log, Quiet }; static void SetLogOperationName(Mode InMode, std::string_view Name); static void SetLogOperationProgress(Mode InMode, uint32_t StepIndex, uint32_t StepCount); explicit ProgressBar(Mode InMode, std::string_view InSubTask); ~ProgressBar(); void UpdateState(const State& NewState, bool DoLinebreak); void ForceLinebreak(); void Finish(); bool IsSameTask(std::string_view Task) const; bool HasActiveTask() const; private: const Mode m_Mode; Stopwatch m_SW; uint64_t m_LastUpdateMS; uint64_t m_PausedMS; State m_State; const std::string m_SubTask; size_t m_LastOutputLength = 0; }; } // namespace zen