GitInfo.targets 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Project ToolsVersion="4.0" InitialTargets="SetGitExe" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  3. <!--
  4. ==============================================================
  5. Retrieves and exposes Git information
  6. If the importing project has a C# or VB Language property,
  7. by default a ThisAssembly file/class will be generated
  8. containing assembly-level metadata for the git information,
  9. as well as a ThisAssembly static class with constants for
  10. all the available values.
  11. Customization:
  12. $(GitThisAssembly): set to 'false' to prevent assembly
  13. metadata and constants generation.
  14. $(GitThisAssemblyMetadata): set to 'false' to prevent assembly
  15. metadata generation only. Defaults
  16. to 'false'.
  17. $(ThisAssemblyNamespace): allows overriding the namespace
  18. for the ThisAssembly class.
  19. Defaults to the global namespace.
  20. $(GitDefaultBranch): determines the base branch used to
  21. calculate commits on top of current branch.
  22. Defaults to 'master'.
  23. $(GitVersionFile): determines the name of a file in the Git
  24. repository root used to provide the base
  25. version info.
  26. Defaults to 'GitInfo.txt'.
  27. $(GitCommitsRelativeTo): optionally specifies an alternative directory
  28. for counting commits on top of the base version.
  29. Defaults to the $(GitVersionFile) directory.
  30. $(GitInfoReportImportance): allows rendering all the retrieved
  31. git information with the specified
  32. message importance ('high', 'normal' or 'low').
  33. Defaults to 'low'.
  34. $(GitIgnoreBranchVersion) and $(GitIgnoreTagVersion): determines
  35. whether the branch and tags (if any)
  36. will be used to find a base version.
  37. Defaults to empty value (no ignoring).
  38. $(GitSkipCache): whether to cache the Git information determined
  39. in a previous build in a GitInfo.cache for
  40. performance reasons.
  41. Defaults to empty value (no ignoring).
  42. ==============================================================
  43. -->
  44. <PropertyGroup>
  45. <!-- GitVersionFile allows overriding tags/branch names as a source for base version information -->
  46. <GitVersionFile Condition="'$(GitVersionFile)' == ''">GitInfo.txt</GitVersionFile>
  47. <!-- Default the lookup directory to the project directory unless overridden -->
  48. <GitInfoBaseDir Condition="'$(GitInfoBaseDir)' == ''">$(MSBuildProjectDirectory)</GitInfoBaseDir>
  49. <!-- Look it upwards and grab the first one we find. -->
  50. <GitVersionFile Condition="'$([MSBuild]::GetDirectoryNameOfFileAbove($(GitInfoBaseDir), $(GitVersionFile)))' != ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(GitInfoBaseDir), $(GitVersionFile)))\$(GitVersionFile)</GitVersionFile>
  51. <GitDefaultBranch Condition="'$(GitDefaultBranch)' == ''">master</GitDefaultBranch>
  52. <GitDefaultCommit Condition="'$(GitDefaultCommit)' == ''">0000000</GitDefaultCommit>
  53. <GitDefaultVersion Condition="'$(GitDefaultVersion)' == ''">0.1.0</GitDefaultVersion>
  54. <GitInfoThisAssemblyFile Condition="'$(GitInfoThisAssemblyFile)' == '' And '$(DefaultLanguageSourceExtension)' != ''">$(IntermediateOutputPath)ThisAssembly.GitInfo.g$(DefaultLanguageSourceExtension)</GitInfoThisAssemblyFile>
  55. <GitThisAssembly Condition="'$(Language)' != 'C#' And '$(Language)' != 'VB'">false</GitThisAssembly>
  56. <GitThisAssembly Condition="'$(GitThisAssembly)' == '' And '$(GitInfoThisAssemblyFile)' != ''">true</GitThisAssembly>
  57. <GitInfoReportImportance Condition="'$(GitInfoReportImportance)' == ''">low</GitInfoReportImportance>
  58. <GitThisAssemblyMetadataDefine Condition="'$(GitThisAssemblyMetadata)' == 'true'">ADDMETADATA</GitThisAssemblyMetadataDefine>
  59. <GitThisAssemblyMetadataDefine Condition="'$(GitThisAssemblyMetadata)' != 'true'">NOMETADATA</GitThisAssemblyMetadataDefine>
  60. <!-- Defaults if overrides are specified when building -->
  61. <GitCommits Condition="'$(GitCommits)' == ''">0</GitCommits>
  62. <GitSemVerSource Condition="'$(GitBaseVersion)' != ''">MSBuild</GitSemVerSource>
  63. <GitSkipCache Condition="'$(GitSkipCache)' == ''">false</GitSkipCache>
  64. <SkipReadGitCache Condition="'$(SkipReadGitCache)' == ''">$(GitSkipCache)</SkipReadGitCache>
  65. <SkipWriteGitCache Condition="'$(SkipWriteGitCache)' == ''">$(GitSkipCache)</SkipWriteGitCache>
  66. <GitMinVersion>2.5.0</GitMinVersion>
  67. </PropertyGroup>
  68. <!-- Private properties -->
  69. <PropertyGroup>
  70. <CoreCompileDependsOn>
  71. GitInfo;
  72. GitVersion;
  73. GitThisAssembly;
  74. GitInfoReport;
  75. $(CoreCompileDependsOn)
  76. </CoreCompileDependsOn>
  77. <_GitBaseVersionExpr Condition="'$(_GitBaseVersionExpr)' == ''">^v?(?&lt;MAJOR&gt;\d+)\.(?&lt;MINOR&gt;\d+)\.(?&lt;PATCH&gt;\d+)(?:\-(?&lt;LABEL&gt;[\dA-Za-z\-\.]+))?$|^(?&lt;LABEL&gt;[\dA-Za-z\-\.]+)\-v?(?&lt;MAJOR&gt;\d+)\.(?&lt;MINOR&gt;\d+)\.(?&lt;PATCH&gt;\d+)$</_GitBaseVersionExpr>
  78. <!-- Cache file used to avoid running all git commands. Only GitRoot will be retrieved to determine the path of this cache file. -->
  79. <_GitInfoFile>$(IntermediateOutputPath)GitInfo.cache</_GitInfoFile>
  80. </PropertyGroup>
  81. <Target Name="GitInfoReport" DependsOnTargets="GitInfo;GitVersion">
  82. <Message Importance="$(GitInfoReportImportance)" Text="Git Info:
  83. GitInfoBaseDir: $(GitInfoBaseDir)
  84. GitRoot: $(GitRoot)
  85. GitBranch: $(GitBranch)
  86. GitCommit: $(GitCommit)
  87. GitSha: $(GitSha)
  88. GitBaseVersion: $(GitBaseVersion)
  89. GitBaseVersionSource: $(GitBaseVersionSource)
  90. GitBaseVersionMajor: $(GitBaseVersionMajor)
  91. GitBaseVersionMinor: $(GitBaseVersionMinor)
  92. GitBaseVersionPatch: $(GitBaseVersionPatch)
  93. GitCommits: $(GitCommits)
  94. GitTag: $(GitTag)
  95. GitBaseTag: $(GitBaseTag)
  96. GitSemVerMajor: $(GitSemVerMajor)
  97. GitSemVerMinor: $(GitSemVerMinor)
  98. GitSemVerPatch: $(GitSemVerPatch)
  99. GitSemVerLabel: $(GitSemVerLabel)
  100. GitSemVerDashLabel: $(GitSemVerDashLabel)
  101. GitSemVerSource: $(GitSemVerSource)
  102. "/>
  103. </Target>
  104. <PropertyGroup>
  105. <GitInfoDependsOn>
  106. SetGitExe;
  107. _EnsureGit;
  108. _GitRoot;
  109. _GitInputs;
  110. _GitClearCache;
  111. _GitReadCache;
  112. _GitBranch;
  113. _GitCommit;
  114. _GitPopulateInfo;
  115. </GitInfoDependsOn>
  116. </PropertyGroup>
  117. <!-- Under Unix, we don't double %% the format. That only works on Windows. -->
  118. <PropertyGroup Condition="'$(OS)' == 'Windows_NT'">
  119. <_ShortShaFormat>%%h</_ShortShaFormat>
  120. <_LongShaFormat>%%H</_LongShaFormat>
  121. </PropertyGroup>
  122. <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
  123. <_ShortShaFormat>%h</_ShortShaFormat>
  124. <_LongShaFormat>%H</_LongShaFormat>
  125. </PropertyGroup>
  126. <Target Name="GitInfo" DependsOnTargets="$(GitInfoDependsOn)" Returns="@(GitInfo)" />
  127. <Target Name="_EnsureGit">
  128. <Exec Command='$(GitExe) --version'
  129. EchoOff='true'
  130. ContinueOnError='true'
  131. ConsoleToMSBuild='true'
  132. StandardErrorImportance='high'
  133. StandardOutputImportance='low'>
  134. <Output TaskParameter="ConsoleOutput" PropertyName="_GitOutput"/>
  135. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  136. </Exec>
  137. <Error Condition="'$(MSBuildLastExitCode)' != '0'" Text="Failed to run `git --version`. Git may not be properly installed: %0A $(_GitOutput)" />
  138. <PropertyGroup>
  139. <_GitCurrentVersion>$([System.Text.RegularExpressions.Regex]::Match("$(_GitOutput)", "\d+\.\d+\.\d+").Value)</_GitCurrentVersion>
  140. </PropertyGroup>
  141. <Error Condition="$([System.Version]::Parse('$(_GitCurrentVersion)').CompareTo($([System.Version]::Parse('$(GitMinVersion)')))) &lt; 0"
  142. Text="Required minimum git version is $(GitMinVersion) but found $(_GitCurrentVersion)." />
  143. </Target>
  144. <Target Name="_GitRoot" Returns="$(GitRoot)" Condition="'$(GitRoot)' == ''">
  145. <Exec Command='$(GitExe) rev-parse --show-toplevel'
  146. EchoOff='true'
  147. StandardErrorImportance='high'
  148. StandardOutputImportance='low'
  149. ConsoleToMSBuild='true'
  150. WorkingDirectory='$(GitInfoBaseDir)'
  151. ContinueOnError='true'>
  152. <Output TaskParameter="ConsoleOutput" PropertyName="_GitOutput"/>
  153. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  154. </Exec>
  155. <PropertyGroup Condition="'$(MSBuildLastExitCode)' == '0'">
  156. <GitRoot>$(_GitOutput.Trim())</GitRoot>
  157. </PropertyGroup>
  158. <!-- Account for cygwin/WSL separately -->
  159. <Exec Command='"$(CygPathExe)" -w "$(_GitOutput)"'
  160. EchoOff='true'
  161. WorkingDirectory="$(GitInfoBaseDir)"
  162. StandardErrorImportance='high'
  163. StandardOutputImportance='low'
  164. ConsoleToMSBuild='true'
  165. Condition="'$(MSBuildLastExitCode)' == '0' And '$(CygPathExe)' != ''">
  166. <Output TaskParameter="ConsoleOutput" PropertyName="_GitOutput" />
  167. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  168. </Exec>
  169. <PropertyGroup Condition="'$(MSBuildLastExitCode)' == '0'">
  170. <GitRoot>$(_GitOutput.Trim())</GitRoot>
  171. </PropertyGroup>
  172. <!-- Determine the .git dir. In the simple case, this is just $(GitRoot)\.git.
  173. But in the case of submodules, a .git *file* rather than a directory
  174. will be present at that path, with a value like:
  175. gitdir: ../../.git/modules/external/toq
  176. Which points to the actual folder where the git info exists in the containing
  177. repository. -->
  178. <PropertyGroup>
  179. <GitDir>$([System.IO.Path]::Combine('$(GitRoot)', '.git'))</GitDir>
  180. <_IsGitFile>$([System.IO.File]::Exists('$(GitDir)'))</_IsGitFile>
  181. </PropertyGroup>
  182. <Exec Condition="'$(_IsGitFile)' == 'true'"
  183. Command='$(GitExe) rev-parse --is-inside-work-tree'
  184. EchoOff='true'
  185. StandardErrorImportance='high'
  186. StandardOutputImportance='low'
  187. ConsoleToMSBuild='true'
  188. WorkingDirectory='$(GitInfoBaseDir)'
  189. ContinueOnError='true'>
  190. <Output TaskParameter="ConsoleOutput" PropertyName="_GitIsWorkTree"/>
  191. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  192. </Exec>
  193. <PropertyGroup Condition="'$(MSBuildLastExitCode)' == '0'">
  194. <_IsGitWorkTree>$(_GitIsWorkTree.Trim())</_IsGitWorkTree>
  195. </PropertyGroup>
  196. <Exec Condition="'$(_IsGitFile)' == 'true' and '$(_IsGitWorkTree)' == 'true'"
  197. Command='$(GitExe) rev-parse --git-common-dir'
  198. EchoOff='true'
  199. StandardErrorImportance='high'
  200. StandardOutputImportance='low'
  201. ConsoleToMSBuild='true'
  202. WorkingDirectory='$(GitInfoBaseDir)'
  203. ContinueOnError='true'>
  204. <Output TaskParameter="ConsoleOutput" PropertyName="_GitCommonDir"/>
  205. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  206. </Exec>
  207. <!-- Account for cygwin/WSL separately -->
  208. <Exec Command='"$(CygPathExe)" -w "$(_GitCommonDir)"'
  209. EchoOff='true'
  210. WorkingDirectory="$(GitInfoBaseDir)"
  211. StandardErrorImportance='high'
  212. StandardOutputImportance='low'
  213. ConsoleToMSBuild='true'
  214. Condition="'$(_IsGitFile)' == 'true' and '$(_IsGitWorkTree)' == 'true' And '$(MSBuildLastExitCode)' == '0' And '$(CygPathExe)' != ''">
  215. <Output TaskParameter="ConsoleOutput" PropertyName="_GitCommonDir" />
  216. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  217. </Exec>
  218. <PropertyGroup Condition="'$(_IsGitFile)' == 'true' and '$(_IsGitWorkTree)' == 'true'">
  219. <GitDir>$(_GitCommonDir.Trim())</GitDir>
  220. </PropertyGroup>
  221. <PropertyGroup Condition="'$(_IsGitFile)' == 'true' and '$(_IsGitWorkTree)' != 'true'">
  222. <_GitFileContents>$([System.IO.File]::ReadAllText('$(GitDir)'))</_GitFileContents>
  223. <GitDir>$([System.String]::new('$(_GitFileContents)').Substring(7).Trim())</GitDir>
  224. <GitDir>$([System.IO.Path]::Combine('$(GitRoot)', '$(GitDir)'))</GitDir>
  225. <GitDir>$([System.IO.Path]::GetFullPath('$(GitDir)'))</GitDir>
  226. </PropertyGroup>
  227. <PropertyGroup>
  228. <GitDir Condition="!HasTrailingSlash('$(GitDir)')">$(GitDir)$([System.IO.Path]::DirectorySeparatorChar)</GitDir>
  229. </PropertyGroup>
  230. <Message Text="Determined Git repository root as '$(GitRoot)'" Importance="$(GitInfoReportImportance)" Condition="'$(GitRoot)' != ''" />
  231. <Message Text="Determined Git dir as '$(GitDir)'" Importance="$(GitInfoReportImportance)" Condition="'$(GitRoot)' != ''" />
  232. <Warning Text="Directory $(GitInfoBaseDir) is not in a Git repository. Cannot determine Git repository root." Condition="'$(GitRoot)' == ''" />
  233. <Exec Command='$(GitExe) diff-index --quiet HEAD'
  234. Condition="'$(GitRoot)' != ''"
  235. EchoOff='true'
  236. StandardErrorImportance="low"
  237. StandardOutputImportance="low"
  238. WorkingDirectory="$(GitRoot)"
  239. IgnoreExitCode="true">
  240. <Output TaskParameter="ExitCode" PropertyName="GitIsDirty" />
  241. </Exec>
  242. </Target>
  243. <Target Name="_GitInputs" DependsOnTargets="_GitRoot" Returns="@(_GitInput)">
  244. <ItemGroup>
  245. <_GitInput Include="$(GitDir)HEAD" />
  246. <_GitInput Include="$(GitVersionFile)" Condition="Exists('$(GitVersionFile)')" />
  247. </ItemGroup>
  248. <CreateItem Include="$([System.IO.Path]::Combine('$(GitDir)', 'packed-refs'))">
  249. <Output ItemName="_GitInput" TaskParameter="Include" />
  250. </CreateItem>
  251. <CreateItem Include="$([System.IO.Path]::Combine('$(GitDir)', 'refs', 'heads', '**', '*.*'))">
  252. <Output ItemName="_GitInput" TaskParameter="Include" />
  253. </CreateItem>
  254. <CreateItem Include="$([System.IO.Path]::Combine('$(GitDir)', 'refs', 'tags', '*.*'))">
  255. <Output ItemName="_GitInput" TaskParameter="Include" />
  256. </CreateItem>
  257. <Delete Files="$(_GitInfoFile)" Condition="Exists('$(_GitInfoFile)') And '$(SkipReadGitCache)' == 'true'" />
  258. </Target>
  259. <!-- If the inputs/outputs are outdated, clear the cache -->
  260. <Target Name="_GitClearCache" Inputs="@(_GitInput)" Outputs="$(_GitInfoFile)" Condition="Exists('$(_GitInfoFile)')">
  261. <Delete Files="$(_GitInfoFile)" />
  262. </Target>
  263. <Target Name="_GitReadCache" Condition="Exists('$(_GitInfoFile)') And '$(SkipReadGitCache)' != 'true' ">
  264. <PropertyGroup>
  265. <_GitCachedInfo>$([System.IO.File]::ReadAllText('$(_GitInfoFile)'))</_GitCachedInfo>
  266. </PropertyGroup>
  267. <CreateItem Include="GitInfo" AdditionalMetadata="$(_GitCachedInfo.Split(';'))">
  268. <Output TaskParameter="Include" ItemName="GitInfo" />
  269. </CreateItem>
  270. <PropertyGroup>
  271. <GitBranch Condition="'$(GitBranch)' == ''">%(GitInfo.GitBranch)</GitBranch>
  272. <GitCommit Condition="'$(GitCommit)' == ''">%(GitInfo.GitCommit)</GitCommit>
  273. <GitSha Condition="'$(GitSha)' == ''">%(GitInfo.GitSha)</GitSha>
  274. <GitBaseVersion Condition="'$(GitBaseVersion)' == ''">%(GitInfo.GitBaseVersion)</GitBaseVersion>
  275. <GitBaseVersionSource Condition="'$(GitBaseVersionSource)' == ''">%(GitInfo.GitBaseVersionSource)</GitBaseVersionSource>
  276. <GitBaseVersionMajor Condition="'$(GitBaseVersionMajor)' == ''">%(GitInfo.GitBaseVersionMajor)</GitBaseVersionMajor>
  277. <GitBaseVersionMinor Condition="'$(GitBaseVersionMinor)' == ''">%(GitInfo.GitBaseVersionMinor)</GitBaseVersionMinor>
  278. <GitBaseVersionPatch Condition="'$(GitBaseVersionPatch)' == ''">%(GitInfo.GitBaseVersionPatch)</GitBaseVersionPatch>
  279. <GitCommits Condition="'$(GitCommits)' == '' Or '$(GitCommits)' == '0'">%(GitInfo.GitCommits)</GitCommits>
  280. <GitTag Condition="'$(GitTag)' == ''">%(GitInfo.GitTag)</GitTag>
  281. <GitBaseTag Condition="'$(GitBaseTag)' == ''">%(GitInfo.GitBaseTag)</GitBaseTag>
  282. <GitSemVerMajor Condition="'$(GitSemVerMajor)' == ''">%(GitInfo.GitSemVerMajor)</GitSemVerMajor>
  283. <GitSemVerMinor Condition="'$(GitSemVerMinor)' == ''">%(GitInfo.GitSemVerMinor)</GitSemVerMinor>
  284. <GitSemVerPatch Condition="'$(GitSemVerPatch)' == ''">%(GitInfo.GitSemVerPatch)</GitSemVerPatch>
  285. <GitSemVerLabel Condition="'$(GitSemVerLabel)' == ''">%(GitInfo.GitSemVerLabel)</GitSemVerLabel>
  286. <GitSemVerDashLabel Condition="'$(GitSemVerDashLabel)' == ''">%(GitInfo.GitSemVerDashLabel)</GitSemVerDashLabel>
  287. <GitSemVerSource Condition="'$(GitSemVerSource)' == ''">%(GitInfo.GitSemVerSource)</GitSemVerSource>
  288. </PropertyGroup>
  289. </Target>
  290. <Target Name="_GitBranch" Returns="$(GitBranch)"
  291. DependsOnTargets="_GitInputs"
  292. Condition="'$(GitBranch)' == ''"
  293. Inputs="@(_GitInput)"
  294. Outputs="$(_GitInfoFile)">
  295. <PropertyGroup Condition="'$(GitRoot)' != ''">
  296. <_GitHead>$([System.IO.Path]::Combine($(GitDir), 'HEAD'))</_GitHead>
  297. <_GitHead>$([System.IO.Path]::GetFullPath($(_GitHead)))</_GitHead>
  298. <_GitHead>$([System.IO.File]::ReadAllText('$(_GitHead)'))</_GitHead>
  299. <GitBranch>$([System.Text.RegularExpressions.Regex]::Match($(_GitHead), '(?&lt;=refs/heads/).+$'))</GitBranch>
  300. <GitBranch>$(GitBranch.Trim())</GitBranch>
  301. </PropertyGroup>
  302. <!-- CI systems may checkout the specific commit, rather than the branch, so we need to fallback -->
  303. <Exec Command='$(GitExe) name-rev --name-only HEAD'
  304. Condition=" '$(GitBranch)' == '' "
  305. EchoOff='true'
  306. StandardErrorImportance="low"
  307. StandardOutputImportance="low"
  308. ConsoleToMSBuild="true"
  309. WorkingDirectory="$(GitRoot)"
  310. ContinueOnError="true">
  311. <Output TaskParameter="ConsoleOutput" PropertyName="GitBranch"/>
  312. </Exec>
  313. <PropertyGroup Condition="'$(GitRoot)' == ''">
  314. <GitBranch>$(GitDefaultBranch)</GitBranch>
  315. </PropertyGroup>
  316. </Target>
  317. <Target Name="_GitCommit" Returns="$(GitCommit)"
  318. DependsOnTargets="_GitRoot"
  319. Inputs="@(_GitInput)"
  320. Outputs="$(_GitInfoFile)"
  321. Condition="'$(GitRoot)' != '' And '$(GitCommit)' == ''">
  322. <Exec Command='$(GitExe) log --format=format:$(_ShortShaFormat) -n 1'
  323. EchoOff='true'
  324. StandardErrorImportance="low"
  325. StandardOutputImportance="low"
  326. ConsoleToMSBuild="true"
  327. WorkingDirectory="$(GitRoot)"
  328. ContinueOnError="true">
  329. <Output TaskParameter="ConsoleOutput" PropertyName="GitCommit"/>
  330. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  331. </Exec>
  332. <PropertyGroup Condition="'$(MSBuildLastExitCode)' != '0'">
  333. <GitCommit>$(GitDefaultCommit)</GitCommit>
  334. </PropertyGroup>
  335. <Exec Command='$(GitExe) log --format=format:$(_LongShaFormat) -n 1'
  336. EchoOff='true'
  337. StandardErrorImportance="low"
  338. StandardOutputImportance="low"
  339. ConsoleToMSBuild="true"
  340. WorkingDirectory="$(GitRoot)"
  341. ContinueOnError="true">
  342. <Output TaskParameter="ConsoleOutput" PropertyName="GitSha"/>
  343. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  344. </Exec>
  345. <PropertyGroup Condition="'$(MSBuildLastExitCode)' != '0'">
  346. <GitSha>$(GitDefaultCommit)</GitSha>
  347. </PropertyGroup>
  348. </Target>
  349. <Target Name="_GitPopulateInfo">
  350. <ItemGroup>
  351. <GitInfo Include="GitInfo">
  352. <GitRoot>$(GitRoot)</GitRoot>
  353. <GitBranch>$(GitBranch)</GitBranch>
  354. <GitCommit>$(GitCommit)</GitCommit>
  355. <GitSha>$(GitSha)</GitSha>
  356. </GitInfo>
  357. </ItemGroup>
  358. </Target>
  359. <PropertyGroup>
  360. <GitVersionDependsOn>
  361. GitInfo;
  362. _GitBaseVersionBranch;
  363. _GitBaseVersionTagExists;
  364. _GitBaseVersionTag;
  365. _GitBaseVersionFile;
  366. _GitBaseVersionFallback;
  367. _GitValidateBaseVersion;
  368. _GitPopulateVersionInfo;
  369. _GitWriteCache
  370. </GitVersionDependsOn>
  371. </PropertyGroup>
  372. <Target Name="GitVersion" DependsOnTargets="$(GitVersionDependsOn)" Returns="@(GitInfo)" />
  373. <Target Name="_GitBaseVersionFile" Returns="$(GitBaseVersion)"
  374. Inputs="@(_GitInput)"
  375. Outputs="$(_GitInfoFile)"
  376. Condition="'$(GitBaseVersion)' == '' And Exists('$(GitVersionFile)')">
  377. <PropertyGroup>
  378. <GitBaseVersion>$([System.IO.File]::ReadAllText('$(GitVersionFile)'))</GitBaseVersion>
  379. <GitBaseVersion>$(GitBaseVersion.Trim())</GitBaseVersion>
  380. <IsValidGitBaseVersion>
  381. $([System.Text.RegularExpressions.Regex]::IsMatch($(GitBaseVersion), $(_GitBaseVersionExpr)))
  382. </IsValidGitBaseVersion>
  383. <IsValidGitBaseVersion>$(IsValidGitBaseVersion.Trim())</IsValidGitBaseVersion>
  384. </PropertyGroup>
  385. <Error Text="$(GitVersionFile) does not contain a valid base version (found '$(GitBaseVersion)', regex: $(_GitBaseVersionExpr))."
  386. Condition="'$(IsValidGitBaseVersion)' == 'False'" />
  387. <PropertyGroup>
  388. <_GitVersionFile>$(GitVersionFile)</_GitVersionFile>
  389. <GitBaseVersionSource>$(GitVersionFile)</GitBaseVersionSource>
  390. <GitSemVerSource>File</GitSemVerSource>
  391. </PropertyGroup>
  392. <Message Text="Using base version from version file $(GitVersionFile)'" Importance="normal" />
  393. <!-- Account for cygwin/WSL separately -->
  394. <Exec Command='"$(CygPathExe)" -u "$(_GitVersionFile)"'
  395. EchoOff='true'
  396. WorkingDirectory="$(GitRoot)"
  397. StandardErrorImportance='high'
  398. StandardOutputImportance='low'
  399. ConsoleToMSBuild='true'
  400. Condition="'$(MSBuildLastExitCode)' == '0' And '$(CygPathExe)' != ''">
  401. <Output TaskParameter="ConsoleOutput" PropertyName="_GitVersionFile" />
  402. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  403. </Exec>
  404. <Exec Command='$(GitExe) log -n 1 --format=format:$(_ShortShaFormat) "$(_GitVersionFile)"'
  405. EchoOff='true'
  406. StandardErrorImportance="low"
  407. StandardOutputImportance="low"
  408. ConsoleToMSBuild="true"
  409. WorkingDirectory="$(GitRoot)"
  410. ContinueOnError="true">
  411. <Output TaskParameter="ConsoleOutput" PropertyName="_GitLastBump"/>
  412. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  413. </Exec>
  414. <Warning Text="Could not retrieve last commit for $(GitVersionFile). Defaulting to its declared version '$(GitBaseVersion)' and no additional commits."
  415. Condition="'$(MSBuildLastExitCode)' != '0' Or '$(_GitLastBump)' == ''" />
  416. <PropertyGroup>
  417. <GitCommits Condition="'$(MSBuildLastExitCode)' != '0' Or '$(_GitLastBump)' == ''">0</GitCommits>
  418. <_GitLastBump>$(_GitLastBump.Trim())</_GitLastBump>
  419. <_GitCommitsRelativeTo>$(GitCommitsRelativeTo)</_GitCommitsRelativeTo>
  420. <!-- If the GitVersionFile is at the GitRoot dir, there won't be a directory to specify to base the rev-list count, so no need to quote anything -->
  421. <_GitCommitsRelativeTo Condition="'$(_GitCommitsRelativeTo)' == '' And '$([System.IO.Path]::GetDirectoryName($(GitVersionFile)))' != ''">"$([System.IO.Path]::GetDirectoryName("$(GitVersionFile)"))"</_GitCommitsRelativeTo>
  422. <!-- If the GitVersionFile is at the GitRoot dir, we use the current directory '.' for the count. This allows us to exclude submodule commits -->
  423. <_GitCommitsRelativeTo Condition="'$(_GitCommitsRelativeTo)' == ''">.</_GitCommitsRelativeTo>
  424. </PropertyGroup>
  425. <!-- Account for cygwin/WSL separately -->
  426. <Exec Command='"$(CygPathExe)" -u $(_GitCommitsRelativeTo)'
  427. EchoOff='true'
  428. WorkingDirectory="$(GitRoot)"
  429. StandardErrorImportance='high'
  430. StandardOutputImportance='low'
  431. ConsoleToMSBuild='true'
  432. Condition="'$(MSBuildLastExitCode)' == '0' And '$(CygPathExe)' != '' And '$(_GitCommitsRelativeTo)' != ''">
  433. <Output TaskParameter="ConsoleOutput" PropertyName="_GitCommitsRelativeTo" />
  434. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  435. </Exec>
  436. <Exec Command='$(GitExe) rev-list --count --full-history "$(_GitLastBump)"..HEAD $(_GitCommitsRelativeTo)'
  437. Condition="$(MSBuildLastExitCode) == '0' And '$(_GitLastBump)' != ''"
  438. EchoOff='true'
  439. StandardErrorImportance="low"
  440. StandardOutputImportance="low"
  441. ConsoleToMSBuild="true"
  442. WorkingDirectory="$(GitRoot)"
  443. ContinueOnError="true">
  444. <Output TaskParameter="ConsoleOutput" PropertyName="GitCommits"/>
  445. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  446. </Exec>
  447. </Target>
  448. <Target Name="_GitBaseVersionBranch" Returns="$(GitBaseVersion)"
  449. Inputs="@(_GitInput)"
  450. Outputs="$(_GitInfoFile)"
  451. DependsOnTargets="_GitBranch"
  452. Condition="'$(GitBaseVersion)' == '' And '$(GitIgnoreBranchVersion)' != 'true' ">
  453. <PropertyGroup>
  454. <IsValidGitBaseVersion>
  455. $([System.Text.RegularExpressions.Regex]::IsMatch($(GitBranch), $(_GitBaseVersionExpr)))
  456. </IsValidGitBaseVersion>
  457. <IsValidGitBaseVersion>$(IsValidGitBaseVersion.Trim())</IsValidGitBaseVersion>
  458. </PropertyGroup>
  459. <Message Text="Git branch '$(GitBranch)' cannot be used as a version specifier. Skipping branch-based version processing."
  460. Importance="low" Condition="'$(IsValidGitBaseVersion)' == 'false'" />
  461. <PropertyGroup Condition="'$(IsValidGitBaseVersion)' == 'true'">
  462. <GitBaseVersion>$(GitBranch)</GitBaseVersion>
  463. <GitBaseVersionSource>GitBranch</GitBaseVersionSource>
  464. <GitSemVerSource>Branch</GitSemVerSource>
  465. </PropertyGroup>
  466. <!-- Get the initial commit when the current branch departed from the default branch -->
  467. <Exec Command='$(GitExe) merge-base --fork-point "$(GitDefaultBranch)"'
  468. Condition="'$(IsValidGitBaseVersion)' == 'true'"
  469. EchoOff='true'
  470. StandardErrorImportance="low"
  471. StandardOutputImportance="low"
  472. ConsoleToMSBuild="true"
  473. WorkingDirectory="$(GitRoot)"
  474. ContinueOnError="true">
  475. <Output TaskParameter="ConsoleOutput" PropertyName="_GitForkPoint"/>
  476. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  477. </Exec>
  478. <Warning Text="Could not retrieve first commit where branch $(GitBranch) forked from $(GitDefaultBranch). Defaulting to zero commits."
  479. Condition="'$(IsValidGitBaseVersion)' == 'true' And '$(MSBuildLastExitCode)' != '0'" />
  480. <PropertyGroup Condition="'$(IsValidGitBaseVersion)' == 'true' And '$(MSBuildLastExitCode)' != '0'">
  481. <GitCommits>0</GitCommits>
  482. </PropertyGroup>
  483. <!-- Get the commit count from the fork point to the current branch head -->
  484. <Exec Command='$(GitExe) rev-list --count "$(_GitForkPoint)"..HEAD'
  485. Condition="'$(IsValidGitBaseVersion)' == 'true' and '$(MSBuildLastExitCode)' == '0'"
  486. EchoOff='true'
  487. StandardErrorImportance="low"
  488. StandardOutputImportance="low"
  489. ConsoleToMSBuild="true"
  490. WorkingDirectory="$(GitRoot)"
  491. ContinueOnError="true">
  492. <Output TaskParameter="ConsoleOutput" PropertyName="GitCommits"/>
  493. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  494. </Exec>
  495. </Target>
  496. <Target Name="_GitBaseVersionTagExists" Returns="$(GitBaseTag)"
  497. Inputs="@(_GitInput)"
  498. Outputs="$(_GitInfoFile)"
  499. DependsOnTargets="_GitBranch;_GitCommit"
  500. Condition="'$(GitBaseVersion)' == '' And '$(GitIgnoreTagVersion)' != 'true' ">
  501. <Exec Command='$(GitExe) describe --tags --abbrev=0'
  502. EchoOff='true'
  503. StandardErrorImportance="low"
  504. StandardOutputImportance="low"
  505. ConsoleToMSBuild="true"
  506. WorkingDirectory="$(GitRoot)"
  507. ContinueOnError="true"
  508. IgnoreExitCode="true">
  509. <Output TaskParameter="ConsoleOutput" PropertyName="GitBaseTag"/>
  510. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  511. </Exec>
  512. <PropertyGroup Condition="'$(MSBuildLastExitCode)' != '0'">
  513. <GitCommits>0</GitCommits>
  514. <GitBaseTag></GitBaseTag>
  515. </PropertyGroup>
  516. <Message Text="No git tags exist. Skipping tag processing."
  517. Importance="low" Condition="'$(GitBaseTag)' == ''" />
  518. </Target>
  519. <Target Name="_GitBaseVersionTag" Returns="$(GitBaseVersion)"
  520. Inputs="@(_GitInput)"
  521. Outputs="$(_GitInfoFile)"
  522. DependsOnTargets="_GitBaseVersionTagExists"
  523. Condition="'$(GitBaseVersion)' == '' And '$(GitIgnoreTagVersion)' != 'true' And '$(GitBaseTag)' != ''">
  524. <!-- At this point, we now there is a base tag already we can leverage -->
  525. <Exec Command='$(GitExe) describe --tags'
  526. EchoOff='true'
  527. StandardErrorImportance="low"
  528. StandardOutputImportance="low"
  529. ConsoleToMSBuild="true"
  530. WorkingDirectory="$(GitRoot)"
  531. ContinueOnError="true">
  532. <Output TaskParameter="ConsoleOutput" PropertyName="GitTag"/>
  533. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  534. </Exec>
  535. <PropertyGroup>
  536. <IsValidGitBaseVersion>
  537. $([System.Text.RegularExpressions.Regex]::IsMatch($(GitBaseTag), $(_GitBaseVersionExpr)))
  538. </IsValidGitBaseVersion>
  539. <IsValidGitBaseVersion>$(IsValidGitBaseVersion.Trim())</IsValidGitBaseVersion>
  540. <GitBaseVersion Condition="'$(IsValidGitBaseVersion)' == 'true'">$(GitBaseTag)</GitBaseVersion>
  541. </PropertyGroup>
  542. <Message Text="Current tag '$(GitBaseTag)' cannot be used as a version specifier. Skipping tag-based version processing."
  543. Importance="low" Condition="'$(IsValidGitBaseVersion)' == 'false'" />
  544. <PropertyGroup Condition="'$(IsValidGitBaseVersion)' == 'true'" >
  545. <GitBaseVersionSource>GitBaseTag</GitBaseVersionSource>
  546. <GitSemVerSource>Tag</GitSemVerSource>
  547. <GitCommits>0</GitCommits>
  548. </PropertyGroup>
  549. <Exec Command='$(GitExe) rev-list "$(GitBaseTag)" -n 1'
  550. Condition="'$(IsValidGitBaseVersion)' == 'true'"
  551. EchoOff='true'
  552. StandardErrorImportance="low"
  553. StandardOutputImportance="low"
  554. ConsoleToMSBuild="true"
  555. WorkingDirectory="$(GitRoot)"
  556. ContinueOnError="true">
  557. <Output TaskParameter="ConsoleOutput" PropertyName="_GitBaseTagCommit"/>
  558. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  559. </Exec>
  560. <Exec Command='$(GitExe) rev-list --count "$(_GitBaseTagCommit)".."$(GitCommit)"'
  561. Condition="'$(IsValidGitBaseVersion)' == 'true' And '$(_GitBaseTagCommit)' != '' And '$(GitCommit)' != '' And '$(GitCommit)' != '$(GitDefaultCommit)'"
  562. EchoOff='true'
  563. StandardErrorImportance="low"
  564. StandardOutputImportance="low"
  565. ConsoleToMSBuild="true"
  566. WorkingDirectory="$(GitRoot)"
  567. ContinueOnError="true">
  568. <Output TaskParameter="ConsoleOutput" PropertyName="GitCommits"/>
  569. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  570. </Exec>
  571. <Warning Text="Failed to retrieve commit count from tag '$(GitBaseTag)' to tip $(GitCommit). Defaulting to zero commits."
  572. Condition="'$(IsValidGitBaseVersion)' == 'true' And '$(MSBuildLastExitCode)' != '0'" />
  573. <PropertyGroup>
  574. <GitCommits Condition="'$(MSBuildLastExitCode)' != '0'">0</GitCommits>
  575. </PropertyGroup>
  576. </Target>
  577. <Target Name="_GitBaseVersionFallback" Returns="$(GitBaseVersion)"
  578. Inputs="@(_GitInput)"
  579. Outputs="$(_GitInfoFile)"
  580. Condition="'$(GitBaseVersion)' == '' And '$(GitDefaultVersion)' != ''">
  581. <PropertyGroup>
  582. <IsValidGitDefaultVersion>
  583. $([System.Text.RegularExpressions.Regex]::IsMatch($(GitDefaultVersion), $(_GitBaseVersionExpr)))
  584. </IsValidGitDefaultVersion>
  585. <IsValidGitDefaultVersion>$(IsValidGitDefaultVersion.Trim())</IsValidGitDefaultVersion>
  586. <GitCommits>0</GitCommits>
  587. </PropertyGroup>
  588. <!-- If $(GitBaseVersion) == '' And $(IsValidGitBaseVersion) == '' -->
  589. <Error Text="Fallback version %24(GitDefaultVersion) value of '$(GitDefaultVersion)' is not a valid SemVer 2.0 string."
  590. Condition="'$(IsValidGitDefaultVersion)' == 'false'" />
  591. <Exec Command='$(GitExe) rev-list --count $(GitCommit)'
  592. Condition="'$(IsValidGitDefaultVersion)' == 'true' And '$(GitCommit)' != '' And '$(GitCommit)' != '$(GitDefaultCommit)'"
  593. EchoOff='true'
  594. StandardErrorImportance="low"
  595. StandardOutputImportance="low"
  596. ConsoleToMSBuild="true"
  597. WorkingDirectory="$(GitRoot)"
  598. ContinueOnError="true">
  599. <Output TaskParameter="ConsoleOutput" PropertyName="GitCommits"/>
  600. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  601. </Exec>
  602. <PropertyGroup>
  603. <GitBaseVersion>$(GitDefaultVersion)</GitBaseVersion>
  604. <GitSemVerSource>Default</GitSemVerSource>
  605. </PropertyGroup>
  606. </Target>
  607. <Target Name="_GitValidateBaseVersion"
  608. Inputs="@(_GitInput)"
  609. Outputs="$(_GitInfoFile)">
  610. <!-- If $(GitBaseVersion) == '', it means we couldn't determine a base version by any probing mechanism -->
  611. <Error Text="Failed to find a valid base version to use. Please make sure you have a %24(GitVersionFile) file (defaults to '$(GitVersionFile)'), branch, tag or %24(GitDefaultVersion) property with a valid SemVer 2.0 string."
  612. Condition="'$(GitBaseVersion)' == ''" />
  613. <PropertyGroup>
  614. <IsValidGitBaseVersion>
  615. $([System.Text.RegularExpressions.Regex]::IsMatch($(GitBaseVersion), $(_GitBaseVersionExpr)))
  616. </IsValidGitBaseVersion>
  617. <IsValidGitBaseVersion>$(IsValidGitBaseVersion.Trim())</IsValidGitBaseVersion>
  618. </PropertyGroup>
  619. <Error Text="Current %24(GitBaseVersion) value of '$(GitBaseVersion)' is not a valid SemVer 2.0 string."
  620. Condition="'$(IsValidGitBaseVersion)' == 'false'" />
  621. </Target>
  622. <Target Name="_GitPopulateVersionInfo">
  623. <PropertyGroup>
  624. <!-- Remove the initial optional 'v' or 'V' from the base version. -->
  625. <GitBaseVersion Condition="$(GitBaseVersion.StartsWith('v'))">$(GitBaseVersion.TrimStart('v'))</GitBaseVersion>
  626. <GitBaseVersion Condition="$(GitBaseVersion.StartsWith('V'))">$(GitBaseVersion.TrimStart('V'))</GitBaseVersion>
  627. <GitBaseVersionMajor>$([System.Text.RegularExpressions.Regex]::Match($(GitBaseVersion), $(_GitBaseVersionExpr)).Groups['MAJOR'].Value)</GitBaseVersionMajor>
  628. <GitBaseVersionMinor>$([System.Text.RegularExpressions.Regex]::Match($(GitBaseVersion), $(_GitBaseVersionExpr)).Groups['MINOR'].Value)</GitBaseVersionMinor>
  629. <GitBaseVersionPatch>$([System.Text.RegularExpressions.Regex]::Match($(GitBaseVersion), $(_GitBaseVersionExpr)).Groups['PATCH'].Value)</GitBaseVersionPatch>
  630. <GitSemVerMajor>$(GitBaseVersionMajor)</GitSemVerMajor>
  631. <GitSemVerMinor>$(GitBaseVersionMinor)</GitSemVerMinor>
  632. <GitSemVerPatch>$([MSBuild]::Add('$(GitBaseVersionPatch)', '$(GitCommits)'))</GitSemVerPatch>
  633. <GitSemVerLabel>$([System.Text.RegularExpressions.Regex]::Match($(GitBaseVersion), $(_GitBaseVersionExpr)).Groups['LABEL'].Value)</GitSemVerLabel>
  634. <GitSemVerDashLabel Condition="'$(GitSemVerLabel)' != ''" >-$(GitSemVerLabel)</GitSemVerDashLabel>
  635. </PropertyGroup>
  636. <ItemGroup>
  637. <_GitInfo Include="@(GitInfo -> Distinct())">
  638. <GitBaseVersion>$(GitBaseVersion)</GitBaseVersion>
  639. <GitBaseVersionSource>$(GitBaseVersionSource)</GitBaseVersionSource>
  640. <GitBaseVersionMajor>$(GitBaseVersionMajor)</GitBaseVersionMajor>
  641. <GitBaseVersionMinor>$(GitBaseVersionMinor)</GitBaseVersionMinor>
  642. <GitBaseVersionPatch>$(GitBaseVersionPatch)</GitBaseVersionPatch>
  643. <GitCommits>$(GitCommits)</GitCommits>
  644. <GitTag>$(GitTag)</GitTag>
  645. <GitBaseTag>$(GitBaseTag)</GitBaseTag>
  646. <GitSemVerMajor>$(GitSemVerMajor)</GitSemVerMajor>
  647. <GitSemVerMinor>$(GitSemVerMinor)</GitSemVerMinor>
  648. <GitSemVerPatch>$(GitSemVerPatch)</GitSemVerPatch>
  649. <GitSemVerLabel>$(GitSemVerLabel)</GitSemVerLabel>
  650. <GitSemVerDashLabel>$(GitSemVerDashLabel)</GitSemVerDashLabel>
  651. <GitSemVerSource>$(GitSemVerSource)</GitSemVerSource>
  652. </_GitInfo>
  653. <GitInfo Remove="@(GitInfo)" />
  654. <GitInfo Include="@(_GitInfo)" />
  655. </ItemGroup>
  656. </Target>
  657. <Target Name="_GitWriteCache" Inputs="@(_GitInput)" Outputs="$(_GitInfoFile)" Condition="'$(SkipWriteGitCache)' != 'true'">
  658. <PropertyGroup>
  659. <_GitInfoContent>$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)GitInfo.cache.pp'))</_GitInfoContent>
  660. <_GitInfoContent>$(_GitInfoContent.Replace('$GitBranch$', '$(GitBranch)'))</_GitInfoContent>
  661. <_GitInfoContent>$(_GitInfoContent.Replace('$GitCommits$', '$(GitCommits)'))</_GitInfoContent>
  662. <_GitInfoContent>$(_GitInfoContent.Replace('$GitCommit$', '$(GitCommit)'))</_GitInfoContent>
  663. <_GitInfoContent>$(_GitInfoContent.Replace('$GitSha$', '$(GitSha)'))</_GitInfoContent>
  664. <_GitInfoContent>$(_GitInfoContent.Replace('$GitBaseVersion$', '$(GitBaseVersion)'))</_GitInfoContent>
  665. <_GitInfoContent>$(_GitInfoContent.Replace('$GitBaseVersionSource$', '$(GitBaseVersionSource)'))</_GitInfoContent>
  666. <_GitInfoContent>$(_GitInfoContent.Replace('$GitBaseVersionMajor$', '$(GitBaseVersionMajor)'))</_GitInfoContent>
  667. <_GitInfoContent>$(_GitInfoContent.Replace('$GitBaseVersionMinor$', '$(GitBaseVersionMinor)'))</_GitInfoContent>
  668. <_GitInfoContent>$(_GitInfoContent.Replace('$GitBaseVersionPatch$', '$(GitBaseVersionPatch)'))</_GitInfoContent>
  669. <_GitInfoContent>$(_GitInfoContent.Replace('$GitTag$', '$(GitTag)'))</_GitInfoContent>
  670. <_GitInfoContent>$(_GitInfoContent.Replace('$GitBaseTag$', '$(GitBaseTag)'))</_GitInfoContent>
  671. <_GitInfoContent>$(_GitInfoContent.Replace('$GitSemVerMajor$', '$(GitSemVerMajor)'))</_GitInfoContent>
  672. <_GitInfoContent>$(_GitInfoContent.Replace('$GitSemVerMinor$', '$(GitSemVerMinor)'))</_GitInfoContent>
  673. <_GitInfoContent>$(_GitInfoContent.Replace('$GitSemVerPatch$', '$(GitSemVerPatch)'))</_GitInfoContent>
  674. <_GitInfoContent>$(_GitInfoContent.Replace('$GitSemVerLabel$', '$(GitSemVerLabel)'))</_GitInfoContent>
  675. <_GitInfoContent>$(_GitInfoContent.Replace('$GitSemVerDashLabel$', '$(GitSemVerDashLabel)'))</_GitInfoContent>
  676. <_GitInfoContent>$(_GitInfoContent.Replace('$GitSemVerSource$', '$(GitSemVerSource)'))</_GitInfoContent>
  677. </PropertyGroup>
  678. <PropertyGroup>
  679. <_GitInfoFileDir>$([System.IO.Path]::GetDirectoryName('$(_GitInfoFile)'))</_GitInfoFileDir>
  680. </PropertyGroup>
  681. <MakeDir Directories="$(_GitInfoFileDir)" Condition="!Exists('$(_GitInfoFileDir)')" />
  682. <WriteLinesToFile File="$(_GitInfoFile)" Lines="$(_GitInfoContent)" Overwrite="true" />
  683. <ItemGroup>
  684. <FileWrites Include="$(_GitInfoFile)" />
  685. </ItemGroup>
  686. </Target>
  687. <PropertyGroup>
  688. <GitThisAssemblyDependsOn>
  689. GitInfo;
  690. GitVersion;
  691. _GitInputs;
  692. _GitGenerateThisAssembly
  693. </GitThisAssemblyDependsOn>
  694. </PropertyGroup>
  695. <Target Name="GitThisAssembly" DependsOnTargets="$(GitThisAssemblyDependsOn)"
  696. BeforeTargets="BuildOnlySettings" Condition="'$(GitThisAssembly)' == 'true'">
  697. <ItemGroup>
  698. <Compile Remove="$(GitInfoThisAssemblyFile)" />
  699. <Compile Include="$(GitInfoThisAssemblyFile)" />
  700. <!-- For the double compilation happening with XAML projects. -->
  701. <_GeneratedCodeFiles Include="$(GitInfoThisAssemblyFile)" />
  702. </ItemGroup>
  703. </Target>
  704. <Target Name="_GitGenerateThisAssembly" Condition="'$(GitThisAssembly)' == 'true'"
  705. Inputs="@(_GitInput)" Outputs="$(GitInfoThisAssemblyFile)">
  706. <PropertyGroup>
  707. <_ThisAssemblyContent>$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)GitInfo$(DefaultLanguageSourceExtension).pp'))</_ThisAssemblyContent>
  708. <!-- The $NamespaceDefine$ replacement is turned into the GLOBALNAMESPACE define if the ThisAssemblyNamespace isn't empty. -->
  709. <_ThisAssemblyContent Condition="'$(ThisAssemblyNamespace)' != ''">$(_ThisAssemblyContent.Replace('$NamespaceDefine$', 'LOCALNAMESPACE'))</_ThisAssemblyContent>
  710. <_ThisAssemblyContent Condition="'$(ThisAssemblyNamespace)' == ''">$(_ThisAssemblyContent.Replace('$NamespaceDefine$', 'GLOBALNAMESPACE'))</_ThisAssemblyContent>
  711. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$MetadataDefine$', '$(GitThisAssemblyMetadataDefine)'))</_ThisAssemblyContent>
  712. <_ThisAssemblyContent Condition="'$(ThisAssemblyNamespace)' != ''">$(_ThisAssemblyContent.Replace('RootNamespace.', '$(ThisAssemblyNamespace).'))</_ThisAssemblyContent>
  713. <_ThisAssemblyContent Condition="'$(ThisAssemblyNamespace)' == ''">$(_ThisAssemblyContent.Replace('RootNamespace.', ''))</_ThisAssemblyContent>
  714. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('_RootNamespace_', '$(ThisAssemblyNamespace)'))</_ThisAssemblyContent>
  715. <!-- no git repository -->
  716. <_ThisAssemblyContent Condition="'$(Language)' == 'C#' And '$(GitRoot)' == ''">$(_ThisAssemblyContent.Replace('$GitIsDirty$', 'false'))</_ThisAssemblyContent>
  717. <_ThisAssemblyContent Condition="'$(Language)' == 'C#' And '$(GitIsDirty)' == '1'">$(_ThisAssemblyContent.Replace('$GitIsDirty$', 'true'))</_ThisAssemblyContent>
  718. <_ThisAssemblyContent Condition="'$(Language)' == 'C#' And '$(GitIsDirty)' == '0'">$(_ThisAssemblyContent.Replace('$GitIsDirty$', 'false'))</_ThisAssemblyContent>
  719. <!-- no git repository -->
  720. <_ThisAssemblyContent Condition="'$(Language)' == 'VB' And '$(GitRoot)' == ''">$(_ThisAssemblyContent.Replace('$GitIsDirty$', 'False'))</_ThisAssemblyContent>
  721. <_ThisAssemblyContent Condition="'$(Language)' == 'VB' And '$(GitIsDirty)' == '1'">$(_ThisAssemblyContent.Replace('$GitIsDirty$', 'True'))</_ThisAssemblyContent>
  722. <_ThisAssemblyContent Condition="'$(Language)' == 'VB' And '$(GitIsDirty)' == '0'">$(_ThisAssemblyContent.Replace('$GitIsDirty$', 'False'))</_ThisAssemblyContent>
  723. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitBranch$', '$(GitBranch)'))</_ThisAssemblyContent>
  724. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitCommits$', '$(GitCommits)'))</_ThisAssemblyContent>
  725. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitCommit$', '$(GitCommit)'))</_ThisAssemblyContent>
  726. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitSha$', '$(GitSha)'))</_ThisAssemblyContent>
  727. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitBaseVersion$', '$(GitBaseVersion)'))</_ThisAssemblyContent>
  728. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitBaseVersionSource$', '$(GitBaseVersionSource)'))</_ThisAssemblyContent>
  729. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitBaseVersionMajor$', '$(GitBaseVersionMajor)'))</_ThisAssemblyContent>
  730. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitBaseVersionMinor$', '$(GitBaseVersionMinor)'))</_ThisAssemblyContent>
  731. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitBaseVersionPatch$', '$(GitBaseVersionPatch)'))</_ThisAssemblyContent>
  732. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitTag$', '$(GitTag)'))</_ThisAssemblyContent>
  733. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitBaseTag$', '$(GitBaseTag)'))</_ThisAssemblyContent>
  734. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitSemVerMajor$', '$(GitSemVerMajor)'))</_ThisAssemblyContent>
  735. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitSemVerMinor$', '$(GitSemVerMinor)'))</_ThisAssemblyContent>
  736. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitSemVerPatch$', '$(GitSemVerPatch)'))</_ThisAssemblyContent>
  737. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitSemVerLabel$', '$(GitSemVerLabel)'))</_ThisAssemblyContent>
  738. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitSemVerDashLabel$', '$(GitSemVerDashLabel)'))</_ThisAssemblyContent>
  739. <_ThisAssemblyContent>$(_ThisAssemblyContent.Replace('$GitSemVerSource$', '$(GitSemVerSource)'))</_ThisAssemblyContent>
  740. </PropertyGroup>
  741. <PropertyGroup>
  742. <GitInfoThisAssemblyDir>$([System.IO.Path]::GetDirectoryName('$(GitInfoThisAssemblyFile)'))</GitInfoThisAssemblyDir>
  743. </PropertyGroup>
  744. <MakeDir Directories="$(GitInfoThisAssemblyDir)" Condition="!Exists('$(GitInfoThisAssemblyDir)')" />
  745. <WriteLinesToFile File='$(GitInfoThisAssemblyFile)' Lines='$(_ThisAssemblyContent)' Overwrite='true' />
  746. </Target>
  747. <!--
  748. ============================================================
  749. GitExe Property
  750. Cascading probing mechanism will try to locate an installed
  751. version of git, msysgit, WSL git or cygwin git.
  752. ============================================================
  753. -->
  754. <PropertyGroup Condition="'$(GitExe)' == '' And '$(OS)' != 'Windows_NT'">
  755. <GitExe>git</GitExe>
  756. </PropertyGroup>
  757. <Target Name="SetGitExe" Condition="'$(GitExe)' == '' And '$(OS)' == 'Windows_NT'">
  758. <!-- If git from %PATH% works, just use that -->
  759. <Exec Command='git --version'
  760. EchoOff='true'
  761. ContinueOnError='true'
  762. StandardErrorImportance='high'
  763. StandardOutputImportance='low'>
  764. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  765. </Exec>
  766. <PropertyGroup Condition="'$(MSBuildLastExitCode)' == '0'">
  767. <GitExe>git</GitExe>
  768. </PropertyGroup>
  769. <PropertyGroup Condition="'$(GitExe)' == ''">
  770. <!-- We probe multiple places, with the first matching one winning -->
  771. <GitExe Condition="'$(GitExe)' == '' And Exists('C:\Program Files\Git\bin\git.exe')">"C:\Program Files\Git\bin\git.exe"</GitExe>
  772. <GitExe Condition="'$(GitExe)' == '' And Exists('C:\Program Files (x86)\Git\bin\git.exe')">"C:\Program Files (x86)\Git\bin\git.exe"</GitExe>
  773. <GitExe Condition="'$(GitExe)' == '' And Exists('C:\msysgit\bin\git.exe')">C:\msysgit\bin\git.exe</GitExe>
  774. </PropertyGroup>
  775. <!-- If we didn't find it in the PATH nor the above locations, check for git installed in WSL -->
  776. <Exec Condition="'$(GitExe)' == ''"
  777. Command="$(MSBuildThisFileDirectory)wslrun.cmd git --version"
  778. EchoOff='true'
  779. ContinueOnError='true'
  780. StandardErrorImportance='high'
  781. StandardOutputImportance='low'>
  782. <Output TaskParameter="ExitCode" PropertyName="MSBuildLastExitCode" />
  783. </Exec>
  784. <PropertyGroup Condition="'$(GitExe)' == '' And '$(MSBuildLastExitCode)' == '0'">
  785. <GitExe>$(MSBuildThisFileDirectory)wslrun.cmd git</GitExe>
  786. <CygPathExe>$(MSBuildThisFileDirectory)wslpath.cmd</CygPathExe>
  787. </PropertyGroup>
  788. <PropertyGroup Condition="'$(GitExe)' == ''">
  789. <!-- Only consider cygwin as a last resort, as it tends to be slower -->
  790. <GitExe Condition="'$(GitExe)' == '' And Exists('C:\cygwin\bin\git.exe')">C:\cygwin\bin\git.exe</GitExe>
  791. <GitExe Condition="'$(GitExe)' == '' And Exists('C:\cygwin64\bin\git.exe')">C:\cygwin64\bin\git.exe</GitExe>
  792. </PropertyGroup>
  793. <!--
  794. ============================================================
  795. CygPathExe Property
  796. If we are using cygwin git, we need to pipe the path to
  797. cygpath to convert it into a Windows path. If the path is
  798. already a Windows path, it will be returned unchanged.
  799. ============================================================
  800. -->
  801. <PropertyGroup>
  802. <CygPathExe Condition="'$(CygPathExe)' == '' And Exists('C:\cygwin\bin\cygpath.exe') And $(GitExe.Contains('cygwin'))">C:\cygwin\bin\cygpath.exe</CygPathExe>
  803. <CygPathExe Condition="'$(CygPathExe)' == '' And Exists('C:\cygwin64\bin\cygpath.exe') And $(GitExe.Contains('cygwin64'))">C:\cygwin64\bin\cygpath.exe</CygPathExe>
  804. </PropertyGroup>
  805. </Target>
  806. <PropertyGroup>
  807. <GitInfoImported>true</GitInfoImported>
  808. </PropertyGroup>
  809. </Project>