Runner.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Console/IConsole.h>
  9. #include <AzCore/Debug/Trace.h>
  10. #include <AzCore/IO/SystemFile.h>
  11. #include <AzCore/StringFunc/StringFunc.h>
  12. #include <AzCore/Settings/CommandLine.h>
  13. #include <Application.h>
  14. #include <Converter.h>
  15. #include <Dumper.h>
  16. #include <SliceConverter.h>
  17. namespace SerializeContextTools
  18. {
  19. void PrintHelp()
  20. {
  21. AZ_Printf("Help", "Serialize Context Tool\n");
  22. AZ_Printf("Help", " <action> [-config] [misc options] <action arguments>*\n");
  23. AZ_Printf("Help", " [opt] -config=<path>: optional path to application's config file. Default is 'config/editor.xml'.\n");
  24. AZ_Printf("Help", " [opt] -specializations=<prefix>: <comma or semicolon>-separated list of optional Registry project\n");
  25. AZ_Printf("Help", " specializations, such as 'editor' or 'game' or 'editor;test'. Default is none. \n");
  26. AZ_Printf("Help", "\n");
  27. AZ_Printf("Help", " 'help': Print this help\n");
  28. AZ_Printf("Help", " example: 'help'\n");
  29. AZ_Printf("Help", "\n");
  30. AZ_Printf("Help", " 'dumpfiles': Dump the content to a .dump.txt file next to the original file.\n");
  31. AZ_Printf("Help", " [arg] -files=<path>: ;-separated list of files to verify. Supports wildcards.\n");
  32. AZ_Printf("Help", " [opt] -output=<path>: Path to the folder to write to instead of next to the original file.\n");
  33. AZ_Printf("Help", " example: 'dumpfiles -files=folder/*.ext;a.ext;folder/another/z.ext'\n");
  34. AZ_Printf("Help", "\n");
  35. AZ_Printf("Help", " 'dumpsc': Dump the content of the Serialize and Edit Context to a JSON file.\n");
  36. AZ_Printf("Help", " [opt] -output=<path>: Path to the folder to write to instead of next to the original file.\n");
  37. AZ_Printf("Help", " example: 'dumpsc -output=../TargetFolder/SerializeContext.json'\n");
  38. AZ_Printf("Help", "\n");
  39. AZ_Printf("Help", " 'dumptypes': Dump the list of reflected types to stdout or a file.\n");
  40. AZ_Printf("Help", " [opt] --sort=<WORD> : Sorts the reflected type by <WORD> where word can be one of the following values.\n");
  41. AZ_Printf("Help", R"( "name", "typeid", "none")" "\n")
  42. AZ_Printf("Help", " sorts by name if not specified .\n");
  43. AZ_Printf("Help", " [opt] --output-file=<filepath>: Path to the file to output reflected types.\n");
  44. AZ_Printf("Help", " If not specfied, output is written to stdout.\n");
  45. AZ_Printf("Help", R"( example: 'dumptypes')" "\n");
  46. AZ_Printf("Help", R"( example: 'dumptypes --sort=typeid)" "\n");
  47. AZ_Printf("Help", R"( example: 'dumptypes --output-file=reflectedtypes.txt)" "\n");
  48. AZ_Printf("Help", "\n");
  49. AZ_Printf("Help", " 'convert': Converts a file with an ObjectStream to the new JSON formats.\n");
  50. AZ_Printf("Help", " [arg] -files=<path>: <comma or semicolon>-separated list of files to verify. Supports wildcards.\n");
  51. AZ_Printf("Help", " [arg] -ext=<string>: Extension to use for the new file.\n");
  52. AZ_Printf("Help", " [opt] -dryrun: Processes as normal, but doesn't write files.\n");
  53. AZ_Printf("Help", " [opt] -skipverify: After conversion the result will not be compared to the original.\n");
  54. AZ_Printf("Help", " [opt] -keepdefaults: Fields are written if a default value was found.\n");
  55. AZ_Printf("Help", " [opt] -json-prefix=<prefix>: JSON pointer path prefix to anchor the JSON output underneath.\n");
  56. AZ_Printf("Help", " On Windows the <prefix> should be in quotes, as \"/\" is treated as command option prefix\n");
  57. AZ_Printf("Help", " [opt] -json-prefix=prefix: Json pointer path prefix to use as a \"root\" for settings.\n");
  58. AZ_Printf("Help", " [opt] -verbose: Report additional details during the conversion process.\n");
  59. AZ_Printf("Help", " example: 'convert -file=*.slice;*.uislice -ext=slice2'\n");
  60. AZ_Printf("Help", "\n");
  61. AZ_Printf("Help", R"( 'convert-ini': Converts windows-style INI file to a json format file.)" "\n");
  62. AZ_Printf("Help", R"( The converted file is suitable for being loaded into the Settings Registry.)" "\n");
  63. AZ_Printf("Help", R"( Can be used to convert .cfg/.ini files.)" "\n");
  64. AZ_Printf("Help", R"( [arg] -files=<path...>: <comma or semicolon>-separated list of files to verify. Supports wildcards.)" "\n");
  65. AZ_Printf("Help", R"( [opt] -ext=<string>: Extension to use for the new files. default=setreg)" "\n");
  66. AZ_Printf("Help", R"( [opt] -dryrun: Processes as normal, but doesn't write files.)" "\n");
  67. AZ_Printf("Help", R"( [opt] -json-prefix=<prefix>: JSON pointer path prefix to anchor the JSON output underneath.)" "\n");
  68. AZ_Printf("Help", R"( On Windows the <prefix> should be in quotes, as \"/\" is treated as command option prefix)" "\n");
  69. AZ_Printf("Help", R"( [opt] -verbose: Report additional details during the conversion process.)" "\n");
  70. AZ_Printf("Help", R"( example: 'convert-ini --files=AssetProcessorPlatformConfig.ini;bootstrap.cfg --ext=setreg)" "\n");
  71. AZ_Printf("Help", " 'convert-slice': Converts ObjectStream-based slice files or legacy levels to a JSON-based prefab.\n");
  72. AZ_Printf("Help", " [arg] -files=<path>: <comma or semicolon>-separated list of files to convert. Supports wildcards.\n");
  73. AZ_Printf("Help", " [opt] -slices=<path>: <comma or semicolon>-separated list of .slice files that you converted files depends on. Supports wildcards. Use this if you cannot use the asset processor on the target project (like o3de converting lumberyard)\n");
  74. AZ_Printf("Help", " [opt] -dryrun: Processes as normal, but doesn't write files.\n");
  75. AZ_Printf("Help", " [opt] -keepdefaults: Fields are written if a default value was found.\n");
  76. AZ_Printf("Help", " [opt] -verbose: Report additional details during the conversion process.\n");
  77. AZ_Printf("Help", " example: 'convert-slice -files=*.slice -specializations=editor\n");
  78. AZ_Printf("Help", " example: 'convert-slice -files=Levels/TestLevel/TestLevel.ly -project-path=F:/lmbr-fork/dev/StarterGame -slices=Gems/*.slice -specializations=editor\n");
  79. AZ_Printf("Help", "\n");
  80. AZ_Printf("Help", " 'createtype': Create a default constructed object using Json Serialization and output the contents.\n");
  81. AZ_Printf("Help", " [arg] --type-name=<string>: Name of type to construct and output.\n");
  82. AZ_Printf("Help", " The type must be registered with the Json Registration or Serialize Context.\n");
  83. AZ_Printf("Help", " Cannot be specified with the -type-id parameter.\n");
  84. AZ_Printf("Help", " [arg] --type-id=<uuid>: Uuid of type to construct and output.\n");
  85. AZ_Printf("Help", " The type must be registered with the Json Registration or Serialize Context.\n");
  86. AZ_Printf("Help", " Cannot be specified with the -type-name parameter.\n");
  87. AZ_Printf("Help", " [opt] --output-file=<filepath>: Path to the file to output constructed object.\n");
  88. AZ_Printf("Help", " If not supplied, output is written to stdout.\n");
  89. AZ_Printf("Help", R"( [opt] --json-prefix=<prefix>: JSON pointer path prefix to anchor the JSON output underneath.)" "\n");
  90. AZ_Printf("Help", R"( example: 'createtype --type-name="AZ::Entity"')" "\n");
  91. AZ_Printf("Help", R"( example: 'createtype --type-id="{75651658-8663-478D-9090-2432DFCAFA44}"')" "\n");
  92. AZ_Printf("Help", R"( example: 'createtype --type-name="AZ::Entity" --json-prefix="/My/Anchor"')" "\n");
  93. AZ_Printf("Help", R"( example: 'createtype --type-name="AZ::Entity" --output-file=object.json)" "\n");
  94. AZ_Printf("Help", "\n");
  95. AZ_Printf("Help", " 'createuuid': Create a UUID using a SHA1 hash from a string and output the contents to stdout or a file.\n");
  96. AZ_Printf("Help", " [arg] --values=<string...>: One or more strings to convert to UUID.\n");
  97. AZ_Printf("Help", " Multiple strings can be specified by either using multiple `--values` option or with a single `--values` option by separating them by a comma without any quotes.\n");
  98. AZ_Printf("Help", R"( Ex. --values "engine.json" --values "project.json")" "\n");
  99. AZ_Printf("Help", R"( Ex. --values engine.json,project.json)" "\n");
  100. AZ_Printf("Help", R"( Ex. --values engine.json,project.json --values gem.json)" "\n");
  101. AZ_Printf("Help", " [opt] --values-file=<filepath>: Path to file containing linefeed delimited strings to convert to UUD.\n");
  102. AZ_Printf("Help", " specifying an argument of dash '-' reads input from stdin\n");
  103. AZ_Printf("Help", " [opt] --output-file=<filepath>: Path to the file to output constructed uuids.\n");
  104. AZ_Printf("Help", " If not supplied, output is written to stdout.\n");
  105. AZ_Printf("Help", " specifying an argument of dash '-' writes output to stdout\n");
  106. AZ_Printf("Help", " [opt] --with-curly-braces=<true|false> Outputs the Uuid with curly braces. Defaults to true\n");
  107. AZ_Printf("Help", " Ex. when true = {0123456789abcdef0123456789abcdef}\n");
  108. AZ_Printf("Help", " Ex. when false = 0123456789abcdef0123456789abcdef\n");
  109. AZ_Printf("Help", " [opt] --with-dashes=<true|false> Outputs the Uuid with dashes. Defaults to true\n");
  110. AZ_Printf("Help", " Ex. when true = 01234567-89ab-cdef-0123-456789abcdef\n");
  111. AZ_Printf("Help", " Ex. when false = 0123456789abcdef0123456789abcdef\n");
  112. AZ_Printf("Help", " [opt] -q --quiet suppress output of string used to generate the Uuid\n");
  113. AZ_Printf("Help", " Ex. when set = 01234567-89ab-cdef-0123-456789abcdef\n");
  114. AZ_Printf("Help", " Ex. when not set = 01234567-89ab-cdef-0123-456789abcdef <uuid-string>\n");
  115. AZ_Printf("Help", R"( example: 'createuuid --values="engine.json"')" "\n");
  116. AZ_Printf("Help", R"( output: {3B28A661-E723-5EBE-AB52-EC5829D88C31} engine.json)" "\n");
  117. AZ_Printf("Help", R"( example: 'createuuid --values="engine.json" --values="project.json"')" "\n");
  118. AZ_Printf("Help", R"( output: {3B28A661-E723-5EBE-AB52-EC5829D88C31} engine.json)" "\n");
  119. AZ_Printf("Help", R"( output: {B076CDDC-14DF-50F4-A5E9-7518ABB3E851} project.json)" "\n");
  120. AZ_Printf("Help", R"( example: 'createtype --values=engine.json,project.json --output-file=uuids.txt')" "\n");
  121. AZ_Printf("Help", "\n");
  122. AZ_Printf("Help", " Miscellaneous Options:\n");
  123. AZ_Printf("Help", " This options can be used with any of the above actions:\n");
  124. AZ_Printf("Help", " [opt] --regset <setreg_key>=<setreg_value>: Set setreg_value at key setreg_key within the settings registry.\n");
  125. AZ_Printf("Help", " [opt] --project-path <project_path>: Sets the path to the active project. Used to load gems associated with project\n");
  126. }
  127. int LaunchSerializeContextTools(int argc, char** argv)
  128. {
  129. using namespace AZ::SerializeContextTools;
  130. const AZ::Debug::Trace tracer;
  131. constexpr int StdoutDescriptor = 1;
  132. AZ::IO::FileDescriptorCapturer stdoutCapturer(StdoutDescriptor);
  133. // Capture command output of command that executed
  134. // If a failure occured write the output to stderr, otherwise write the output to stdout
  135. AZStd::string commandOutput;
  136. auto CaptureStdout = [&commandOutput](AZStd::span<AZStd::byte const> outputBytes)
  137. {
  138. commandOutput += AZStd::string_view(reinterpret_cast<const char*>(outputBytes.data()), outputBytes.size());
  139. };
  140. stdoutCapturer.Start(CaptureStdout);
  141. Application application(argc, argv, &stdoutCapturer);
  142. AZ::ComponentApplication::StartupParameters startupParameters;
  143. application.Start({}, startupParameters);
  144. bool result = false;
  145. const AZ::CommandLine* commandLine = application.GetAzCommandLine();
  146. bool commandExecuted = false;
  147. if (commandLine->GetNumMiscValues() >= 1)
  148. {
  149. // Set the command executed boolean to true
  150. commandExecuted = true;
  151. AZStd::string_view action = commandLine->GetMiscValue(0);
  152. if (AZ::StringFunc::Equal("dumpfiles", action))
  153. {
  154. result = Dumper::DumpFiles(application);
  155. }
  156. else if (AZ::StringFunc::Equal("dumpsc", action))
  157. {
  158. result = Dumper::DumpSerializeContext(application);
  159. }
  160. else if (AZ::StringFunc::Equal("dumptypes", action))
  161. {
  162. result = Dumper::DumpTypes(application);
  163. }
  164. else if (AZ::StringFunc::Equal("convert", action))
  165. {
  166. result = Converter::ConvertObjectStreamFiles(application);
  167. }
  168. else if (AZ::StringFunc::Equal("convert-ini", action))
  169. {
  170. result = Converter::ConvertConfigFile(application);
  171. }
  172. else if (AZ::StringFunc::Equal("convert-slice", action))
  173. {
  174. SliceConverter sliceConverter;
  175. result = sliceConverter.ConvertSliceFiles(application);
  176. }
  177. else if (AZ::StringFunc::Equal("createtype", action))
  178. {
  179. result = Dumper::CreateType(application);
  180. }
  181. else if (AZ::StringFunc::Equal("createuuid", action))
  182. {
  183. result = Dumper::CreateUuid(application);
  184. }
  185. else
  186. {
  187. commandExecuted = false;
  188. }
  189. }
  190. // If a command was not executed, display the help options
  191. if (!commandExecuted)
  192. {
  193. // Stop capture of stdout to allow the help command to output to stdout
  194. fflush(stdout);
  195. stdoutCapturer.Stop();
  196. PrintHelp();
  197. result = true;
  198. // Flush stdout stream before restarting the capture to make sure
  199. // all the help text is output
  200. fflush(stdout);
  201. stdoutCapturer.Start(AZStd::move(CaptureStdout));
  202. }
  203. if (!result)
  204. {
  205. AZ_Printf("SerializeContextTools", "Processing didn't complete fully as problems were encountered.\n");
  206. }
  207. application.Stop();
  208. // Because the FILE* stream is buffered, make sure to flush
  209. // it before stopping the capture of stdout.
  210. fflush(stdout);
  211. stdoutCapturer.Stop();
  212. // Write out any error output if the command result is non-zero
  213. if (!result)
  214. {
  215. fwrite(commandOutput.data(), 1, commandOutput.size(), stderr);
  216. return -1;
  217. }
  218. return 0;
  219. }
  220. }