未验证 提交 ff9ab35b 编写于 作者: R Ryland 提交者: GitHub

Add one-time installation of a pre-commit git hook to protect generated WPF files (#1075)

* Add pre-commit Git hook to WPF repo to protect WPF's generated files (installed on first build)
上级 e4a212b4
......@@ -81,4 +81,60 @@
</Code>
</Task>
</UsingTask>
<!-- Installs WPF pre-commit git hook to protect generated files -->
<Target Name="InstallWPFPreCommitGitHook">
<Message Text="InstallWPFPreCommitGitHook: WPF repo root: $(RepoRoot)" />
<Message Text="InstallWPFPreCommitGitHook: WPF Arcade SDK tools root: $(WpfArcadeSdkToolsDir)" />
<InstallWPFPreCommitGitHook RepoRoot="$(RepoRoot)" WpfArcadeSdkToolsDir="$(WpfArcadeSdkToolsDir)" />
</Target>
<UsingTask TaskName="InstallWPFPreCommitGitHook"
TaskFactory="$(TaskFactoryToUse)"
AssemblyFile="$(TaskFactoryAssemblyToUse)">
<ParameterGroup>
<RepoRoot ParameterType="System.String" Required="true" />
<WpfArcadeSdkToolsDir ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
string WPFPreCommitGitHookSource = Path.Combine(WpfArcadeSdkToolsDir, @"pre-commit.githook");
string WPFPreCommitGitHookDest = Path.Combine(RepoRoot, @".git\hooks\pre-commit");
Log.LogMessage($"InstallWPFPreCommitGitHook: WPFPreCommitGitHookSource: {WPFPreCommitGitHookSource}");
Log.LogMessage($"InstallWPFPreCommitGitHook: WPFPreCommitGitHookDest: {WPFPreCommitGitHookDest}");
try
{
Log.LogMessage("InstallWPFPreCommitGitHook: Detecting pre-comit git hook...");
// Verify the payload file exists
if (!File.Exists(WPFPreCommitGitHookSource))
{
throw new Exception($"InstallWPFPreCommitGitHook: {WPFPreCommitGitHookSource} file does not exit.");
}
// Install pre-commit hook if it has not been installed
if (!File.Exists(WPFPreCommitGitHookDest))
{
Log.LogMessage("InstallWPFPreCommitGitHook: Installing pre-comit git hook...");
File.Copy(WPFPreCommitGitHookSource, WPFPreCommitGitHookDest);
}
else
{
Log.LogMessage("InstallWPFPreCommitGitHook: pre-comit git hook already installed.");
}
}
catch (Exception e)
{
Log.LogErrorFromException(e);
throw e;
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
此差异已折叠。
#!/bin/sh
# WPF generated files should only be modified by the file generation scripts.
# This hook prevents users from committing generated files locally. Generated
# files should only be modified by the file generation scripts. The hook
# references a list of generated files that are not allowed to be committed.
# If any generated files are staged, the hook will exit with a non-zero
# status and stop the commit.
# To disable the pre-commit check, use 'git commit --no-verify'.
# Please try to keep this script as basic and easy to read as possible.
# Note that the generated file list must use Unix line endings and remain sorted.
GENERATED_FILE_LIST="eng/WpfArcadeSdk/tools/WPF_Generated_Files.txt"
TEMP_FILE_NAME="WPF_Staged_Files.tmp"
# Redirect output to stderr.
exec 1>&2
# Git staged files
STAGED_FILES=$(git diff --cached --name-only)
# Git repo root
REPO_ROOT=$(git rev-parse --show-toplevel | sort)
# Path of temporary file containing a list of staged files
TEMP_FILE_FULL_PATH=$REPO_ROOT/$TEMP_FILE_NAME
# Create the temporary file containing a list of staged files(always overwrite)
echo "$STAGED_FILES" > "$TEMP_FILE_FULL_PATH"
# Find any staged files that intersect with the generated file list
STAGED_GENERATED_FILES=$(comm -12 $TEMP_FILE_FULL_PATH $GENERATED_FILE_LIST)
# Remove temporary file
[ -f $TEMP_FILE_FULL_PATH ] && $(rm $TEMP_FILE_FULL_PATH)
# If any generated files have been staged, issue an error message and prevent
# the user from committing their change locally.
if test -n "$STAGED_GENERATED_FILES"
then
echo "Error: WPF generated staged files detected. These files must not be modified."
echo "$STAGED_GENERATED_FILES"
exit 1
fi
......@@ -2,35 +2,117 @@
# This file should be kept in sync across https://www.github.com/dotnet/wpf and dotnet-wpf-int repos.
#
# One-time setup for Wpf's custom toolset
function InitializeWpfCustomToolset() {
if (Test-Path variable:global:_WpfToolsetBuildProj) {
return $global:_WpfToolsetBuildProj
}
$nugetCache = GetNuGetPackageCachePath
# Get all sdks listed in repo's 'global.json' file
$msbuild_sdks = $GlobalJson.'msbuild-sdks'
# Determine if WpfArcadeSdk is present in this repo's 'global.json' file.
#
# The Arcade.Wpf.Sdk will only be present in 'global.json' if it is not available in the
# local repo (under repo_root/eng/wpfarcadesdk). The WpfArcadeSdk will be available
# in the internal WPF repo's 'global.json' only (dotnet-wpf-int), as it needs to resolve
# the location during build time from the NuGet cache. The public WPF GitHub repo has
# a local copy of the WPF Arcade SDK and a 'global.json' entry for the sdk is not required.
if ('Microsoft.DotNet.Arcade.Wpf.Sdk' -in $msbuild_sdks.PSobject.Properties.Name) {
# Get the version of the Wpf Arcade SDK for the toolset location file name
$wpfToolsetVersion = $GlobalJson.'msbuild-sdks'.'Microsoft.DotNet.Arcade.Wpf.Sdk'
$wpfToolsetLocationFile = Join-Path $ToolsetDir "$wpfToolsetVersion.txt"
# If toolset file already exists, one-time setup has already run
if (Test-Path $wpfToolsetLocationFile) {
$path = Get-Content $wpfToolsetLocationFile -TotalCount 1
if (Test-Path $path) {
return $global:_WpfToolsetBuildProj = $path
}
}
if (-not $restore) {
Write-Host "Wpf Toolset version $toolsetVersion has not been restored." -ForegroundColor Red
ExitWithExitCode 1
}
# Install WPF git hooks when WpfArcadeSdk is located in the NuGet cache (dotnet-wpf-int)
if (!$ci)
{
$installGitHooksProject = Join-Path $ToolsetDir "wpfInstallWPFPreCommitGitHook.proj"
'<Project Sdk="Microsoft.DotNet.Arcade.Wpf.Sdk"/>' | Set-Content $installGitHooksProject
$installGitHooksBinLog = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "InstallGitHooks.binlog") } else { "" }
MSBuild $installGitHooksProject $installGitHooksBinlog /t:InstallWPFPreCommitGitHook /clp:ErrorsOnly`;NoSummary
}
# Write toolset location (e.g., dotnet-wpf-int\artifacts\toolset\4.8.0-preview7.19322.1.txt)
$proj = Join-Path $ToolsetDir "wpfRestore.proj"
$bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "WpfToolsetRestore.binlog") } else { "" }
'<Project Sdk="Microsoft.DotNet.Arcade.Wpf.Sdk"/>' | Set-Content $proj
MSBuild $proj $bl /t:__WriteToolsetLocation /clp:ErrorsOnly`;NoSummary /p:__ToolsetLocationOutputFile=$wpfToolsetLocationFile
# Verify toolset file was successfully written
$path = Get-Content $wpfToolsetLocationFile -TotalCount 1
if (!(Test-Path $path)) {
throw "Invalid toolset path: $path"
}
return $global:_WpfToolsetBuildProj = $path
}
}
# Installs custom WPF git hook to prevent modification of generated files
function InstallCustomWPFGitHooksFromLocalToolsPath {
# Install the githook using the inline task if WpfArcadeSdk is located in
# engineering root. This should only be the case for the public GitHub repo
# (e.g., dotnet-wpf/eng/wpfarcadesdk.)
$WPFArcadeSDKPath = Join-Path $EngRoot "wpfarcadesdk";
if (Test-Path $WPFArcadeSDKPath) {
# Install the githook using the script
$WPFPreCommitGitHookSource = Join-Path $EngRoot "wpfarcadesdk\tools\pre-commit.githook"
$WPFPreCommitGitHookDest = Join-Path $RepoRoot ".git\hooks\pre-commit"
if (-not (Test-Path $WPFPreCommitGitHookSource)) {
Write-Host "WPF PreCommit GitHook file is missing: $WPFPreCommitGitHookSource"
ExitWithExitCode 1
}
Write-Host "Detecting WPF Git hooks..."
if (-not (Test-Path $WPFPreCommitGitHookDest)) {
Write-Host "Installing WPF Git pre-commit hook..."
try {
Copy-Item -Path $WPFPreCommitGitHookSource -Destination $WPFPreCommitGitHookDest
}
catch {
Write-Host "Error: WPF Git pre-commit hook installation failed!"
Write-Host $_
Write-Host $_.Exception
Write-Host $_.ScriptStackTrace
ExitWithExitCode 1
}
}
else {
Write-Host "Detected existing WPF Git pre-commit hook."
}
}
else
{
Write-Host "InstallCustomWPFGitHooks: WpfArcadeSdk was not available in repo's engineering root.";
}
}
InitializeWpfCustomToolset
. $PsScriptRoot\common\init-tools-native.ps1 -InstallDirectory $PSScriptRoot\..\.tools\native -GlobalJsonFile $PSScriptRoot\..\global.json
\ No newline at end of file
if (!$ci)
{
InstallCustomWPFGitHooksFromLocalToolsPath
}
. $PsScriptRoot\common\init-tools-native.ps1 -InstallDirectory $PSScriptRoot\..\.tools\native -GlobalJsonFile $PSScriptRoot\..\global.json
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册