Compare commits
	
		
			6 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 77dd8e708a | |||
| af2a0b9786 | |||
| e386078eb6 | |||
| 7e1597531d | |||
| f091ff3254 | |||
| 6f769757f3 | 
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,6 @@ | ||||
| [submodule "src/BuildData"] | ||||
| 	path = src/BuildData | ||||
| 	url = https://git.p-epsilon.com/Deukhoofd/BuildData.git | ||||
| [submodule "extern/gitversion"] | ||||
| 	path = extern/gitversion | ||||
| 	url = https://github.com/smessmer/gitversion.git | ||||
|   | ||||
| @@ -38,4 +38,9 @@ if (WINDOWS) | ||||
|     if (SHARED) | ||||
|         set_target_properties(PokemonScriptTester PROPERTIES SUFFIX ".exe") | ||||
|     endif(SHARED) | ||||
| endif (WINDOWS) | ||||
| endif (WINDOWS) | ||||
|  | ||||
| set(PRE_CONFIGURE_FILE "git.h.in") | ||||
| set(POST_CONFIGURE_FILE "src/git.h") | ||||
| include(git_watcher.cmake) | ||||
| add_dependencies(PokemonScriptTester check_git) | ||||
							
								
								
									
										5
									
								
								git.h.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								git.h.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| // automatically generated | ||||
| #pragma once | ||||
|  | ||||
| // The output from git --describe (e.g. the most recent tag) | ||||
| #define GIT_DESCRIBE "@GIT_DESCRIBE@" | ||||
							
								
								
									
										335
									
								
								git_watcher.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								git_watcher.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,335 @@ | ||||
| # git_watcher.cmake | ||||
| # https://raw.githubusercontent.com/andrew-hardin/cmake-git-version-tracking/master/git_watcher.cmake | ||||
| # | ||||
| # Released under the MIT License. | ||||
| # https://raw.githubusercontent.com/andrew-hardin/cmake-git-version-tracking/master/LICENSE | ||||
|  | ||||
|  | ||||
| # This file defines a target that monitors the state of a git repo. | ||||
| # If the state changes (e.g. a commit is made), then a file gets reconfigured. | ||||
| # Here are the primary variables that control script behavior: | ||||
| # | ||||
| #   PRE_CONFIGURE_FILE (REQUIRED) | ||||
| #   -- The path to the file that'll be configured. | ||||
| # | ||||
| #   POST_CONFIGURE_FILE (REQUIRED) | ||||
| #   -- The path to the configured PRE_CONFIGURE_FILE. | ||||
| # | ||||
| #   GIT_STATE_FILE (OPTIONAL) | ||||
| #   -- The path to the file used to store the previous build's git state. | ||||
| #      Defaults to the current binary directory. | ||||
| # | ||||
| #   GIT_WORKING_DIR (OPTIONAL) | ||||
| #   -- The directory from which git commands will be run. | ||||
| #      Defaults to the directory with the top level CMakeLists.txt. | ||||
| # | ||||
| #   GIT_EXECUTABLE (OPTIONAL) | ||||
| #   -- The path to the git executable. It'll automatically be set if the | ||||
| #      user doesn't supply a path. | ||||
| # | ||||
| #   GIT_FAIL_IF_NONZERO_EXIT (optional) | ||||
| #   -- Raise a FATAL_ERROR if any of the git commands return a non-zero | ||||
| #      exit code. This is set to TRUE by default. You can set this to FALSE | ||||
| #      if you'd like the build to continue even if a git command fails. | ||||
| # | ||||
| # DESIGN | ||||
| #   - This script was designed similar to a Python application | ||||
| #     with a Main() function. I wanted to keep it compact to | ||||
| #     simplify "copy + paste" usage. | ||||
| # | ||||
| #   - This script is invoked under two CMake contexts: | ||||
| #       1. Configure time (when build files are created). | ||||
| #       2. Build time (called via CMake -P). | ||||
| #     The first invocation is what registers the script to | ||||
| #     be executed at build time. | ||||
| # | ||||
| # MODIFICATIONS | ||||
| #   You may wish to track other git properties like when the last | ||||
| #   commit was made. There are two sections you need to modify, | ||||
| #   and they're tagged with a ">>>" header. | ||||
|  | ||||
| # Short hand for converting paths to absolute. | ||||
| macro(PATH_TO_ABSOLUTE var_name) | ||||
|     get_filename_component(${var_name} "${${var_name}}" ABSOLUTE) | ||||
| endmacro() | ||||
|  | ||||
| # Check that a required variable is set. | ||||
| macro(CHECK_REQUIRED_VARIABLE var_name) | ||||
|     if(NOT DEFINED ${var_name}) | ||||
|         message(FATAL_ERROR "The \"${var_name}\" variable must be defined.") | ||||
|     endif() | ||||
|     PATH_TO_ABSOLUTE(${var_name}) | ||||
| endmacro() | ||||
|  | ||||
| # Check that an optional variable is set, or, set it to a default value. | ||||
| macro(CHECK_OPTIONAL_VARIABLE_NOPATH var_name default_value) | ||||
|     if(NOT DEFINED ${var_name}) | ||||
|         set(${var_name} ${default_value}) | ||||
|     endif() | ||||
| endmacro() | ||||
|  | ||||
| # Check that an optional variable is set, or, set it to a default value. | ||||
| # Also converts that path to an abspath. | ||||
| macro(CHECK_OPTIONAL_VARIABLE var_name default_value) | ||||
|     CHECK_OPTIONAL_VARIABLE_NOPATH(${var_name} ${default_value}) | ||||
|     PATH_TO_ABSOLUTE(${var_name}) | ||||
| endmacro() | ||||
|  | ||||
| CHECK_REQUIRED_VARIABLE(PRE_CONFIGURE_FILE) | ||||
| CHECK_REQUIRED_VARIABLE(POST_CONFIGURE_FILE) | ||||
| CHECK_OPTIONAL_VARIABLE(GIT_STATE_FILE "${CMAKE_BINARY_DIR}/git-state-hash") | ||||
| CHECK_OPTIONAL_VARIABLE(GIT_WORKING_DIR "${CMAKE_SOURCE_DIR}") | ||||
| CHECK_OPTIONAL_VARIABLE_NOPATH(GIT_FAIL_IF_NONZERO_EXIT TRUE) | ||||
|  | ||||
| # Check the optional git variable. | ||||
| # If it's not set, we'll try to find it using the CMake packaging system. | ||||
| if(NOT DEFINED GIT_EXECUTABLE) | ||||
|     find_package(Git QUIET REQUIRED) | ||||
| endif() | ||||
| CHECK_REQUIRED_VARIABLE(GIT_EXECUTABLE) | ||||
|  | ||||
|  | ||||
| set(_state_variable_names | ||||
|         GIT_RETRIEVED_STATE | ||||
|         GIT_HEAD_SHA1 | ||||
|         GIT_IS_DIRTY | ||||
|         GIT_AUTHOR_NAME | ||||
|         GIT_AUTHOR_EMAIL | ||||
|         GIT_COMMIT_DATE_ISO8601 | ||||
|         GIT_COMMIT_SUBJECT | ||||
|         GIT_COMMIT_BODY | ||||
|         GIT_DESCRIBE | ||||
|         # >>> | ||||
|         # 1. Add the name of the additional git variable you're interested in monitoring | ||||
|         #    to this list. | ||||
|         ) | ||||
|  | ||||
|  | ||||
|  | ||||
| # Macro: RunGitCommand | ||||
| # Description: short-hand macro for calling a git function. Outputs are the | ||||
| #              "exit_code" and "output" variables. | ||||
| macro(RunGitCommand) | ||||
|     execute_process(COMMAND | ||||
|             "${GIT_EXECUTABLE}" ${ARGV} | ||||
|             WORKING_DIRECTORY "${_working_dir}" | ||||
|             RESULT_VARIABLE exit_code | ||||
|             OUTPUT_VARIABLE output | ||||
|             ERROR_VARIABLE stderr | ||||
|             OUTPUT_STRIP_TRAILING_WHITESPACE) | ||||
|     if(NOT exit_code EQUAL 0) | ||||
|         set(ENV{GIT_RETRIEVED_STATE} "false") | ||||
|  | ||||
|         # Issue 26: git info not properly set | ||||
|         # | ||||
|         # Check if we should fail if any of the exit codes are non-zero. | ||||
|         if(GIT_FAIL_IF_NONZERO_EXIT) | ||||
|             string(REPLACE ";" " " args_with_spaces "${ARGV}") | ||||
|             message(FATAL_ERROR "${stderr} (${GIT_EXECUTABLE} ${args_with_spaces})") | ||||
|         endif() | ||||
|     endif() | ||||
| endmacro() | ||||
|  | ||||
|  | ||||
|  | ||||
| # Function: GetGitState | ||||
| # Description: gets the current state of the git repo. | ||||
| # Args: | ||||
| #   _working_dir (in)  string; the directory from which git commands will be executed. | ||||
| function(GetGitState _working_dir) | ||||
|  | ||||
|     # This is an error code that'll be set to FALSE if the | ||||
|     # RunGitCommand ever returns a non-zero exit code. | ||||
|     set(ENV{GIT_RETRIEVED_STATE} "true") | ||||
|  | ||||
|     # Get whether or not the working tree is dirty. | ||||
|     RunGitCommand(status --porcelain) | ||||
|     if(NOT exit_code EQUAL 0) | ||||
|         set(ENV{GIT_IS_DIRTY} "false") | ||||
|     else() | ||||
|         if(NOT "${output}" STREQUAL "") | ||||
|             set(ENV{GIT_IS_DIRTY} "true") | ||||
|         else() | ||||
|             set(ENV{GIT_IS_DIRTY} "false") | ||||
|         endif() | ||||
|     endif() | ||||
|  | ||||
|     # There's a long list of attributes grabbed from git show. | ||||
|     set(object HEAD) | ||||
|     RunGitCommand(show -s "--format=%H" ${object}) | ||||
|     if(exit_code EQUAL 0) | ||||
|         set(ENV{GIT_HEAD_SHA1} ${output}) | ||||
|     endif() | ||||
|  | ||||
|     RunGitCommand(show -s "--format=%an" ${object}) | ||||
|     if(exit_code EQUAL 0) | ||||
|         set(ENV{GIT_AUTHOR_NAME} "${output}") | ||||
|     endif() | ||||
|  | ||||
|     RunGitCommand(show -s "--format=%ae" ${object}) | ||||
|     if(exit_code EQUAL 0) | ||||
|         set(ENV{GIT_AUTHOR_EMAIL} "${output}") | ||||
|     endif() | ||||
|  | ||||
|     RunGitCommand(show -s "--format=%ci" ${object}) | ||||
|     if(exit_code EQUAL 0) | ||||
|         set(ENV{GIT_COMMIT_DATE_ISO8601} "${output}") | ||||
|     endif() | ||||
|  | ||||
|     RunGitCommand(show -s "--format=%s" ${object}) | ||||
|     if(exit_code EQUAL 0) | ||||
|         # Escape quotes | ||||
|         string(REPLACE "\"" "\\\"" output "${output}") | ||||
|         set(ENV{GIT_COMMIT_SUBJECT} "${output}") | ||||
|     endif() | ||||
|  | ||||
|     RunGitCommand(show -s "--format=%b" ${object}) | ||||
|     if(exit_code EQUAL 0) | ||||
|         if(output) | ||||
|             # Escape quotes | ||||
|             string(REPLACE "\"" "\\\"" output "${output}") | ||||
|             # Escape line breaks in the commit message. | ||||
|             string(REPLACE "\r\n" "\\r\\n\\\r\n" safe "${output}") | ||||
|             if(safe STREQUAL output) | ||||
|                 # Didn't have windows lines - try unix lines. | ||||
|                 string(REPLACE "\n" "\\n\\\n" safe "${output}") | ||||
|             endif() | ||||
|         else() | ||||
|             # There was no commit body - set the safe string to empty. | ||||
|             set(safe "") | ||||
|         endif() | ||||
|         set(ENV{GIT_COMMIT_BODY} "\"${safe}\"") | ||||
|     else() | ||||
|         set(ENV{GIT_COMMIT_BODY} "\"\"") # empty string. | ||||
|     endif() | ||||
|  | ||||
|     # Get output of git describe | ||||
|     RunGitCommand(describe --always --tags ${object}) | ||||
|     if(NOT exit_code EQUAL 0) | ||||
|         set(ENV{GIT_DESCRIBE} "unknown") | ||||
|     else() | ||||
|         set(ENV{GIT_DESCRIBE} "${output}") | ||||
|     endif() | ||||
|  | ||||
|     # >>> | ||||
|     # 2. Additional git properties can be added here via the | ||||
|     #    "execute_process()" command. Be sure to set them in | ||||
|     #    the environment using the same variable name you added | ||||
|     #    to the "_state_variable_names" list. | ||||
|  | ||||
| endfunction() | ||||
|  | ||||
|  | ||||
|  | ||||
| # Function: GitStateChangedAction | ||||
| # Description: this function is executed when the state of the git | ||||
| #              repository changes (e.g. a commit is made). | ||||
| function(GitStateChangedAction) | ||||
|     foreach(var_name ${_state_variable_names}) | ||||
|         set(${var_name} $ENV{${var_name}}) | ||||
|     endforeach() | ||||
|     configure_file("${PRE_CONFIGURE_FILE}" "${POST_CONFIGURE_FILE}" @ONLY) | ||||
| endfunction() | ||||
|  | ||||
|  | ||||
|  | ||||
| # Function: HashGitState | ||||
| # Description: loop through the git state variables and compute a unique hash. | ||||
| # Args: | ||||
| #   _state (out)  string; a hash computed from the current git state. | ||||
| function(HashGitState _state) | ||||
|     set(ans "") | ||||
|     foreach(var_name ${_state_variable_names}) | ||||
|         string(SHA256 ans "${ans}$ENV{${var_name}}") | ||||
|     endforeach() | ||||
|     set(${_state} ${ans} PARENT_SCOPE) | ||||
| endfunction() | ||||
|  | ||||
|  | ||||
|  | ||||
| # Function: CheckGit | ||||
| # Description: check if the git repo has changed. If so, update the state file. | ||||
| # Args: | ||||
| #   _working_dir    (in)  string; the directory from which git commands will be ran. | ||||
| #   _state_changed (out)    bool; whether or no the state of the repo has changed. | ||||
| function(CheckGit _working_dir _state_changed) | ||||
|  | ||||
|     # Get the current state of the repo. | ||||
|     GetGitState("${_working_dir}") | ||||
|  | ||||
|     # Convert that state into a hash that we can compare against | ||||
|     # the hash stored on-disk. | ||||
|     HashGitState(state) | ||||
|  | ||||
|     # Issue 14: post-configure file isn't being regenerated. | ||||
|     # | ||||
|     # Update the state to include the SHA256 for the pre-configure file. | ||||
|     # This forces the post-configure file to be regenerated if the | ||||
|     # pre-configure file has changed. | ||||
|     file(SHA256 ${PRE_CONFIGURE_FILE} preconfig_hash) | ||||
|     string(SHA256 state "${preconfig_hash}${state}") | ||||
|  | ||||
|     # Check if the state has changed compared to the backup on disk. | ||||
|     if(EXISTS "${GIT_STATE_FILE}") | ||||
|         file(READ "${GIT_STATE_FILE}" OLD_HEAD_CONTENTS) | ||||
|         if(OLD_HEAD_CONTENTS STREQUAL "${state}") | ||||
|             # State didn't change. | ||||
|             set(${_state_changed} "false" PARENT_SCOPE) | ||||
|             return() | ||||
|         endif() | ||||
|     endif() | ||||
|  | ||||
|     # The state has changed. | ||||
|     # We need to update the state file on disk. | ||||
|     # Future builds will compare their state to this file. | ||||
|     file(WRITE "${GIT_STATE_FILE}" "${state}") | ||||
|     set(${_state_changed} "true" PARENT_SCOPE) | ||||
| endfunction() | ||||
|  | ||||
|  | ||||
|  | ||||
| # Function: SetupGitMonitoring | ||||
| # Description: this function sets up custom commands that make the build system | ||||
| #              check the state of git before every build. If the state has | ||||
| #              changed, then a file is configured. | ||||
| function(SetupGitMonitoring) | ||||
|     add_custom_target(check_git | ||||
|             ALL | ||||
|             DEPENDS ${PRE_CONFIGURE_FILE} | ||||
|             BYPRODUCTS | ||||
|             ${POST_CONFIGURE_FILE} | ||||
|             ${GIT_STATE_FILE} | ||||
|             COMMENT "Checking the git repository for changes..." | ||||
|             COMMAND | ||||
|             ${CMAKE_COMMAND} | ||||
|             -D_BUILD_TIME_CHECK_GIT=TRUE | ||||
|             -DGIT_WORKING_DIR=${GIT_WORKING_DIR} | ||||
|             -DGIT_EXECUTABLE=${GIT_EXECUTABLE} | ||||
|             -DGIT_STATE_FILE=${GIT_STATE_FILE} | ||||
|             -DPRE_CONFIGURE_FILE=${PRE_CONFIGURE_FILE} | ||||
|             -DPOST_CONFIGURE_FILE=${POST_CONFIGURE_FILE} | ||||
|             -DGIT_FAIL_IF_NONZERO_EXIT=${GIT_FAIL_IF_NONZERO_EXIT} | ||||
|             -P "${CMAKE_CURRENT_LIST_FILE}") | ||||
| endfunction() | ||||
|  | ||||
|  | ||||
|  | ||||
| # Function: Main | ||||
| # Description: primary entry-point to the script. Functions are selected based | ||||
| #              on whether it's configure or build time. | ||||
| function(Main) | ||||
|     if(_BUILD_TIME_CHECK_GIT) | ||||
|         # Check if the repo has changed. | ||||
|         # If so, run the change action. | ||||
|         CheckGit("${GIT_WORKING_DIR}" changed) | ||||
|         if(changed OR NOT EXISTS "${POST_CONFIGURE_FILE}") | ||||
|             GitStateChangedAction() | ||||
|         endif() | ||||
|     else() | ||||
|         # >> Executes at configure time. | ||||
|         SetupGitMonitoring() | ||||
|     endif() | ||||
| endfunction() | ||||
|  | ||||
| # And off we go... | ||||
| Main() | ||||
 Submodule src/BuildData updated: 85b80f4be7...d3e95dad61
									
								
							| @@ -5,6 +5,7 @@ | ||||
| #include <CreatureLib/Battling/TurnChoices/PassTurnChoice.hpp> | ||||
| #include <PkmnLib/Battling/Battle/Battle.hpp> | ||||
| #include <PkmnLib/Battling/Pokemon/CreatePokemon.hpp> | ||||
| #include <PkmnLib/Battling/Pokemon/PokemonParty.hpp> | ||||
| #include <angelscript.h> | ||||
| #include "../TestEnvironment.hpp" | ||||
|  | ||||
| @@ -14,7 +15,7 @@ class BattleFunctions { | ||||
|         TestEnvironment* env = static_cast<TestEnvironment*>(ctx->GetUserData()); | ||||
|  | ||||
|         auto lib = Globals::Library.GetValue(); | ||||
|         auto p1 = new CreatureLib::Battling::CreatureParty(species->GetSize()); | ||||
|         auto p1 = new PkmnLib::Battling::PokemonParty(species->GetSize()); | ||||
|         for (u32 i = 0; i < species->GetSize(); ++i) { | ||||
|             auto s = reinterpret_cast<const ArbUt::StringView*>(species->At(i)); | ||||
|             auto mon1 = PkmnLib::Battling::CreatePokemon(lib, *s, level) | ||||
| @@ -43,7 +44,7 @@ class BattleFunctions { | ||||
|                         .WithGender(CreatureLib::Library::Gender::Male) | ||||
|                         .IsAllowedExperienceGain(false) | ||||
|                         .Build(); | ||||
|         auto p1 = new CreatureLib::Battling::CreatureParty(1); | ||||
|         auto p1 = new PkmnLib::Battling::PokemonParty(1); | ||||
|         p1->SwapInto(0, mon1); | ||||
|  | ||||
|         auto mon2 = PkmnLib::Battling::CreatePokemon(lib, species2, level) | ||||
| @@ -53,7 +54,7 @@ class BattleFunctions { | ||||
|                         .WithGender(CreatureLib::Library::Gender::Male) | ||||
|                         .IsAllowedExperienceGain(false) | ||||
|                         .Build(); | ||||
|         auto p2 = new CreatureLib::Battling::CreatureParty(1); | ||||
|         auto p2 = new PkmnLib::Battling::PokemonParty(1); | ||||
|         p2->SwapInto(0, mon2); | ||||
|  | ||||
|         auto battle = new PkmnLib::Battling::Battle( | ||||
| @@ -75,8 +76,8 @@ class BattleFunctions { | ||||
|         return battle; | ||||
|     } | ||||
|  | ||||
|     static PkmnLib::Battling::Battle* CreateSimpleBattleFromParties(u32 seed, CreatureLib::Battling::CreatureParty* p1, | ||||
|                                                                     CreatureLib::Battling::CreatureParty* p2) { | ||||
|     static PkmnLib::Battling::Battle* CreateSimpleBattleFromParties(u32 seed, PkmnLib::Battling::PokemonParty* p1, | ||||
|                                                                     PkmnLib::Battling::PokemonParty* p2) { | ||||
|         auto* ctx = asGetActiveContext(); | ||||
|         TestEnvironment* env = static_cast<TestEnvironment*>(ctx->GetUserData()); | ||||
|         auto lib = Globals::Library.GetValue(); | ||||
| @@ -91,7 +92,7 @@ class BattleFunctions { | ||||
|             seed  // with seed | ||||
|         ); | ||||
|         battle->SwitchCreature(0, 0, p1->GetAtIndex(0)); | ||||
|         battle->SwitchCreature(1, 0, p2->GetAtIndex(1)); | ||||
|         battle->SwitchCreature(1, 0, p2->GetAtIndex(0)); | ||||
|  | ||||
|         env->AddGarbage(battle); | ||||
|         return battle; | ||||
|   | ||||
| @@ -9,8 +9,10 @@ | ||||
| #include "Tester/AngelScript/MiscMockFunctions.hpp" | ||||
| #include "Tester/AngelScript/TestFunctions.hpp" | ||||
| #include "Tester/TestRunner.hpp" | ||||
| #include "git.h" | ||||
|  | ||||
| int main(int argc, char** argv) { | ||||
|     std::cout << "PokemonScript Tester version: " << GIT_DESCRIBE << std::endl; | ||||
|     args::ArgumentParser parser("PkmnLib Script Tester.", ""); | ||||
|     args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); | ||||
|  | ||||
| @@ -20,6 +22,7 @@ int main(int argc, char** argv) { | ||||
|     args::ValueFlag<std::string> workingDirFlag(parser, "Working Directory", "Which work directory to use.", | ||||
|                                                 {"workdir"}); | ||||
|     args::Flag logTimeFlag(parser, "time-log", "Whether to show time logging.", {'t', "time-log"}); | ||||
|     args::Flag forceColorFlag(parser, "force-color", "Whether to force color text output.", {'c', "force-color"}); | ||||
|     try { | ||||
|         parser.ParseCLI(argc, argv); | ||||
|     } catch (args::Help&) { | ||||
| @@ -40,6 +43,9 @@ int main(int argc, char** argv) { | ||||
|     if (!workingDirectory.empty()) { | ||||
|         chdir((const char*)std::filesystem::path(workingDirectory).c_str()); | ||||
|     } | ||||
|     if (forceColorFlag.Get()){ | ||||
|         termcolor::colorize(std::cout); | ||||
|     } | ||||
|  | ||||
|     std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); | ||||
|     std::function<void(PkmnLib::Battling::ScriptResolver*)> initialize = | ||||
|   | ||||
		Reference in New Issue
	
	Block a user