// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "../zen.h" #include "../authutils.h" namespace zen { class ProjectStoreCommand : public ZenCmdBase { virtual ZenCmdCategory& CommandCategory() const override { return g_ProjectStoreCategory; } }; // Base for `project` subcommands. Registers the shared --hosturl option; // host resolution is handled by ZenServiceClient at construction. class ProjectSubCmdBase : public ZenSubCmdBase { public: ProjectSubCmdBase(std::string_view Name, std::string_view Description); protected: std::string m_HostName; }; class ProjectCreateSubCmd : public ProjectSubCmdBase { public: ProjectCreateSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectId; std::string m_RootDir; std::string m_EngineRootDir; std::string m_ProjectRootDir; std::string m_ProjectFile; bool m_ForceUpdate = false; }; class ProjectDropSubCmd : public ProjectSubCmdBase { public: ProjectDropSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectName; std::string m_OplogName; bool m_DryRun = true; }; class ProjectInfoSubCmd : public ProjectSubCmdBase { public: ProjectInfoSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectName; std::string m_OplogName; }; class ProjectStatsSubCmd : public ProjectSubCmdBase { public: ProjectStatsSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; }; class ProjectOpDetailsSubCmd : public ProjectSubCmdBase { public: ProjectOpDetailsSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: bool m_Details = false; bool m_OpDetails = false; bool m_AttachmentDetails = false; bool m_CSV = false; std::string m_ProjectName; std::string m_OplogName; std::string m_OpId; }; class ProjectCommand : public ProjectStoreCmdWithSubCommands { public: static constexpr char Name[] = "project"; static constexpr char Description[] = "Manage projects - create, drop, info, stats, op-details"; ProjectCommand(); ~ProjectCommand(); cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; ProjectCreateSubCmd m_CreateSubCmd; ProjectDropSubCmd m_DropSubCmd; ProjectInfoSubCmd m_InfoSubCmd; ProjectStatsSubCmd m_StatsSubCmd; ProjectOpDetailsSubCmd m_OpDetailsSubCmd; }; // --------------------------------------------------------------------------- // Deprecated legacy top-level commands. These forward to the corresponding // 'project ' subcommand so existing scripts keep working. They are // hidden from the top-level `zen --help` listing; `zen project --help` is the // canonical discovery surface now. namespace project_legacy_shim { void RunAs(const char* SubCommandName, const ZenCliOptions& GlobalOptions, int argc, char** argv); } class DeprecatedProjectStoreCommand : public ProjectStoreCommand { public: bool IsHidden() const override { return true; } }; class DropProjectCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "project-drop"; static constexpr char Description[] = "(deprecated, use 'project drop') Drop project or project oplog"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { project_legacy_shim::RunAs("drop", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class ProjectInfoCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "project-info"; static constexpr char Description[] = "(deprecated, use 'project info') Info on project or project oplog"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { project_legacy_shim::RunAs("info", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class CreateProjectCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "project-create"; static constexpr char Description[] = "(deprecated, use 'project create') Create a project"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { project_legacy_shim::RunAs("create", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class ProjectStatsCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "project-stats"; static constexpr char Description[] = "(deprecated, use 'project stats') Stats on project store"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { project_legacy_shim::RunAs("stats", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class ProjectOpDetailsCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "project-op-details"; static constexpr char Description[] = "(deprecated, use 'project op-details') Detail info on ops inside a project store oplog"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { project_legacy_shim::RunAs("op-details", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; // --------------------------------------------------------------------------- // `oplog ` command tree. // Base for `oplog` subcommands. Owns the shared --hosturl option that resolves // against the local zenserver instance. class OplogSubCmdBase : public ZenSubCmdBase { public: OplogSubCmdBase(std::string_view Name, std::string_view Description); protected: std::string m_HostName; }; class OplogCreateSubCmd : public OplogSubCmdBase { public: OplogCreateSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectId; std::string m_OplogId; std::string m_GcPath; bool m_ForceUpdate = false; }; class OplogExportSubCmd : public OplogSubCmdBase { public: OplogExportSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectName; std::string m_OplogName; uint64_t m_MaxBlockSize = 0; uint64_t m_MaxChunksPerBlock = 0; uint64_t m_MaxChunkEmbedSize = 0; bool m_EmbedLooseFiles = false; bool m_Force = false; bool m_DisableBlocks = false; bool m_Async = false; bool m_IgnoreMissingAttachments = false; std::string m_JupiterNamespace; std::string m_JupiterBucket; std::string m_JupiterOpenIdProvider; std::string m_JupiterAccessToken; std::string m_JupiterAccessTokenEnv; std::string m_JupiterAccessTokenPath; std::string m_OidcTokenAuthExecutablePath; bool m_JupiterAssumeHttp2 = false; bool m_JupiterDisableTempBlocks = false; std::string m_CloudUrl; std::string m_CloudKey; std::string m_BaseCloudKey; std::string m_BuildsUrl; std::string m_BuildsId; std::string m_BuildsMetadataPath; std::string m_BuildsMetadata; bool m_BoostWorkerCount = false; bool m_BoostWorkerMemory = false; bool m_BoostWorkers = false; std::string m_ZenUrl; std::string m_ZenProjectName; std::string m_ZenOplogName; bool m_ZenClean = false; std::string m_FileDirectoryPath; std::string m_FileName; std::string m_BaseFileName; bool m_FileForceEnableTempBlocks = false; bool m_PlainProgress = false; }; class OplogImportSubCmd : public OplogSubCmdBase { public: OplogImportSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectName; std::string m_OplogName; std::string m_GcPath; bool m_Force = false; bool m_Async = false; bool m_IgnoreMissingAttachments = false; bool m_Clean = false; bool m_PlainProgress = false; std::string m_JupiterNamespace; std::string m_JupiterBucket; std::string m_JupiterOpenIdProvider; std::string m_JupiterAccessToken; std::string m_JupiterAccessTokenEnv; std::string m_JupiterAccessTokenPath; std::string m_OidcTokenAuthExecutablePath; bool m_JupiterAssumeHttp2 = false; std::string m_CloudUrl; std::string m_ZenCacheHost; bool m_UploadToZenCache = false; std::string m_CloudKey; std::string m_BuildsHost; std::string m_BuildsOverrideHost; std::string m_BuildsId; std::string m_ZenUrl; std::string m_ZenProjectName; std::string m_ZenOplogName; std::string m_FileDirectoryPath; std::string m_FileName; bool m_BoostWorkerCount = false; bool m_BoostWorkerMemory = false; bool m_BoostWorkers = false; std::string m_AllowPartialBlockRequests = "true"; }; class OplogSnapshotSubCmd : public OplogSubCmdBase { public: OplogSnapshotSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectName; std::string m_OplogName; }; class OplogMirrorSubCmd : public OplogSubCmdBase { public: OplogMirrorSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectName; std::string m_OplogName; std::string m_MirrorRootPath; std::string m_KeyFilter; std::string m_FilenameFilter; std::string m_ChunkIdFilter; bool m_Decompress = false; bool m_TrimToReferencedSet = true; }; class OplogValidateSubCmd : public OplogSubCmdBase { public: OplogValidateSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::string m_ProjectName; std::string m_OplogName; }; // `oplog download` does not target a local zenserver; it has its own host / // URL options for Cloud Builds and therefore does not inherit from // OplogSubCmdBase (which would force a --hosturl that goes unused). class OplogDownloadSubCmd : public ZenSubCmdBase { public: OplogDownloadSubCmd(); void Run(const ZenCliOptions& GlobalOptions) override; private: std::filesystem::path m_SystemRootDir; bool m_Quiet = false; bool m_Verbose = false; bool m_Yes = false; bool m_PlainProgress = false; bool m_LogProgress = false; AuthCommandLineOptions m_AuthOptions; // cloud builds std::string m_OverrideHost; std::string m_Host; std::string m_Url; bool m_AssumeHttp2 = false; bool m_AllowRedirect = false; std::string m_ZenCacheHost; std::string m_Namespace; std::string m_Bucket; std::string m_BuildId; bool m_ForceDownload = false; bool m_BoostWorkerCount = false; bool m_BoostWorkerMemory = false; bool m_BoostWorkers = false; bool m_UploadToZenCache = true; std::filesystem::path m_OplogOutputPath; bool m_DecompressAttachments = true; std::vector m_Attachments; std::filesystem::path m_AttachmentsPath; }; class OplogCommand : public ProjectStoreCmdWithSubCommands { public: static constexpr char Name[] = "oplog"; static constexpr char Description[] = "Manage oplogs - create, export, import, snapshot, mirror, validate, download"; OplogCommand(); ~OplogCommand(); cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; OplogCreateSubCmd m_CreateSubCmd; OplogDownloadSubCmd m_DownloadSubCmd; OplogExportSubCmd m_ExportSubCmd; OplogImportSubCmd m_ImportSubCmd; OplogMirrorSubCmd m_MirrorSubCmd; OplogSnapshotSubCmd m_SnapshotSubCmd; OplogValidateSubCmd m_ValidateSubCmd; }; // --------------------------------------------------------------------------- // Deprecated legacy top-level commands. These forward to the corresponding // 'oplog ' subcommand so existing scripts keep working. They are hidden // from the top-level `zen --help` listing; `zen oplog --help` is the canonical // discovery surface. namespace oplog_legacy_shim { void RunAs(const char* SubCommandName, const ZenCliOptions& GlobalOptions, int argc, char** argv); } class CreateOplogCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "oplog-create"; static constexpr char Description[] = "(deprecated, use 'oplog create') Create a project oplog"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { oplog_legacy_shim::RunAs("create", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class ExportOplogCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "oplog-export"; static constexpr char Description[] = "(deprecated, use 'oplog export') Export project store oplog"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { oplog_legacy_shim::RunAs("export", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class ImportOplogCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "oplog-import"; static constexpr char Description[] = "(deprecated, use 'oplog import') Import project store oplog"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { oplog_legacy_shim::RunAs("import", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class SnapshotOplogCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "oplog-snapshot"; static constexpr char Description[] = "(deprecated, use 'oplog snapshot') Copy oplog's loose files on disk into zenserver"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { oplog_legacy_shim::RunAs("snapshot", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class OplogMirrorCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "oplog-mirror"; static constexpr char Description[] = "(deprecated, use 'oplog mirror') Mirror project store oplog to file system"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { oplog_legacy_shim::RunAs("mirror", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class OplogValidateCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "oplog-validate"; static constexpr char Description[] = "(deprecated, use 'oplog validate') Validate oplog for missing references"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { oplog_legacy_shim::RunAs("validate", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; class OplogDownloadCommand : public DeprecatedProjectStoreCommand { public: static constexpr char Name[] = "oplog-download"; static constexpr char Description[] = "(deprecated, use 'oplog download') Download an cloud storage oplog"; void Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override { oplog_legacy_shim::RunAs("download", GlobalOptions, argc, argv); } cxxopts::Options& Options() override { return m_Options; } private: cxxopts::Options m_Options{Name, Description}; }; } // namespace zen