You've already forked git-hook-1c
mirror of
https://github.com/tishchenkovv/git-hook-1c.git
synced 2026-04-26 20:42:50 +02:00
387 lines
12 KiB
PowerShell
387 lines
12 KiB
PowerShell
<#
|
|
Git Hook Pre-commit
|
|
Автор: Тищенко В.В.
|
|
Версия: 1.0
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param (
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$files
|
|
)
|
|
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
|
|
function Show-Message {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$text,
|
|
|
|
[string]$caption = "Information",
|
|
[string]$icon = "Information"
|
|
)
|
|
|
|
$iconEnum = [System.Windows.Forms.MessageBoxIcon]::$icon
|
|
$buttonEnum = [System.Windows.Forms.MessageBoxButtons]::OK
|
|
|
|
[System.Windows.Forms.MessageBox]::Show($text, $caption, $buttonEnum, $iconEnum)
|
|
}
|
|
|
|
function Test-Settings {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[hashtable]$settings
|
|
)
|
|
|
|
$skipKeys = @("user", "password", "path_bsl", "files")
|
|
$errors = @()
|
|
|
|
foreach ($item in $settings.GetEnumerator()) {
|
|
$key = $item.Key
|
|
$value = $item.Value
|
|
|
|
if ($skipKeys -contains $key) {
|
|
continue
|
|
}
|
|
|
|
if ($null -eq $value -or [string]::IsNullOrWhiteSpace($value)) {
|
|
$errors += "$($key): empty"
|
|
}
|
|
}
|
|
|
|
if ($errors.Count -gt 0) {
|
|
$msg = "Пропущен параметр в settings:`n" + ($errors -join "`n")
|
|
Show-Message -text $msg -caption "Settings validation error" -icon "Error"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
function Stop-1c {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$base
|
|
)
|
|
|
|
$matchingProcesses = Get-CimInstance Win32_Process |
|
|
Where-Object {
|
|
$_.Name -eq "1cv8.exe" -and $_.CommandLine -match [regex]::Escape($base)
|
|
}
|
|
|
|
foreach ($proc in $matchingProcesses) {
|
|
try {
|
|
Stop-Process -Id $proc.ProcessId -Force
|
|
} catch {
|
|
Write-Warning "Не удалось завершить процесс с PID $($proc.ProcessId): $_"
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
|
|
function Test-Syntax {
|
|
param(
|
|
[hashtable]$settings
|
|
)
|
|
|
|
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
|
|
$logPath = Join-Path $settings["root"] "syntax_check_$timestamp.log"
|
|
|
|
$authByUser = $settings["AuthOS"]
|
|
$userSpecified = -not ($settings["user"] -eq "")
|
|
$infobase = ($settings["base"] -split "\\")[1]
|
|
Stop-1c -base $infobase
|
|
|
|
$args = if (-not $authByUser -and $userSpecified) {
|
|
@(
|
|
"DESIGNER",
|
|
"/DisableStartupDialogs",
|
|
"/S", $settings["base"],
|
|
"/N", $settings["user"],
|
|
"/P", $settings["password"],
|
|
"/CheckConfig", "-ConfigLogIntegrity", "-Server", "-ExternalConnectionServer",
|
|
"-UnreferenceProcedures", "-HandlersExistence", "-EmptyHandlers",
|
|
"/Out", "`"$logPath`""
|
|
)
|
|
} else {
|
|
@(
|
|
"DESIGNER",
|
|
"/DisableStartupDialogs",
|
|
"/S", $settings["base"],
|
|
"/CheckConfig", "-ConfigLogIntegrity", "-Server", "-ExternalConnectionServer",
|
|
"-UnreferenceProcedures", "-HandlersExistence", "-EmptyHandlers",
|
|
"/Out", "`"$logPath`""
|
|
)
|
|
}
|
|
|
|
Write-Host "Запущен синтакис чек 1с..."
|
|
Write-Host "$($settings["platform"]) $($args -join ' ')"
|
|
|
|
$proc = Start-Process -FilePath $settings["platform"] -ArgumentList $args -PassThru
|
|
$timeout = 2700
|
|
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
|
|
|
while (-not $proc.HasExited) {
|
|
Start-Sleep -Seconds 2
|
|
if ($sw.Elapsed.TotalSeconds -ge $timeout) {
|
|
Write-Warning "1C процесс завис. Попытка завершения процесса..."
|
|
try {
|
|
$proc.Kill()
|
|
Write-Error "Процесс уничтожен 1с $timeout сек."
|
|
} catch {
|
|
Write-Error "Не удалось завершить процесс 1с: $_"
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
|
|
$sw.Stop()
|
|
|
|
$msg = "Заершен процесс синтаксис проверки $([math]::Round($sw.Elapsed.TotalSeconds, 1)) сек."
|
|
Write-Host $msg
|
|
|
|
if (Test-Path $logPath -PathType Leaf) {
|
|
$lines = Get-Content $logPath -Encoding UTF8
|
|
$filtered = $lines | Where-Object { $_ -notmatch 'Не обнаружено ссылок на процедуру: "Подключаемый_' -and $_ -notmatch 'Не обнаружено ссылок на функцию: "Подключаемый_' }
|
|
Set-Content -Path $logPath $filtered -Encoding UTF8
|
|
if (@(Get-Content -Path $logPath).Count -gt 0) {
|
|
Show-Message -text "Найдены ошибки в конфигурации" -caption "Syntax-check 1c"
|
|
Invoke-Item $logPath
|
|
} else {
|
|
Show-Message -text "Ошибок не найдено. OK" -caption "Syntax-check 1c"
|
|
}
|
|
} else {
|
|
Show-Message -text "Не найден файл" -caption "Syntax-check 1c" -icon "Error"
|
|
}
|
|
}
|
|
|
|
function Test-BSL {
|
|
param(
|
|
[hashtable]$operation,
|
|
[hashtable]$settings_1c
|
|
)
|
|
|
|
$bslFile = Join-Path $settings_1c.root "bsl-json.json"
|
|
|
|
if (Test-Path $bslFile) {
|
|
Remove-Item $bslFile -Force
|
|
}
|
|
|
|
$files = $operation.files
|
|
|
|
if ($files.Count -eq 0) {
|
|
Write-Host "Нет файлов для проверки"
|
|
exit 0
|
|
}
|
|
|
|
$pathBSL = $operation.path_bsl
|
|
|
|
if (!(Test-Path $pathBSL)) {
|
|
$msg = "Не найден BSL 1c"
|
|
Write-Host $msg
|
|
Show-Message -text $msg -caption "BSL" -icon "Error"
|
|
exit 1
|
|
}
|
|
|
|
$folder = New-Item -Name "input" -Path $settings_1c.root -ItemType Directory
|
|
$filesRepo = @{}
|
|
$count = 1
|
|
|
|
foreach ($file in $files) {
|
|
$nameFile = @($count, "bsl") -join "."
|
|
$tempPath = Join-Path $folder $nameFile
|
|
Copy-Item -Path $file -Destination $tempPath
|
|
$filesRepo[$nameFile] = $file
|
|
$count++
|
|
}
|
|
|
|
$args = @(
|
|
"-jar",
|
|
$pathBSL,
|
|
"-a",
|
|
"-s", $folder,
|
|
"-o", $settings_1c.root,
|
|
"-r", "json"
|
|
)
|
|
|
|
Start-Process java -ArgumentList $args -Wait -NoNewWindow
|
|
|
|
$pathDiag = Join-Path $settings_1c.root "bsl-json.json"
|
|
|
|
$errorList = @()
|
|
if (Test-Path $pathDiag) {
|
|
$diag = Get-Content $pathDiag -Raw -Encoding UTF8 | ConvertFrom-Json
|
|
foreach ($fileinfo in $diag.fileinfos) {
|
|
$cleanPath = $fileinfo.path -replace "^file:///", ""
|
|
$nameFile = (Get-Item -Path $cleanPath).Name
|
|
$originalFile = $filesRepo[$nameFile]
|
|
|
|
foreach ($result in $fileinfo.diagnostics) {
|
|
$errorList += New-Object psobject -Property @{
|
|
File = $originalFile
|
|
Type_Error = $result.severity
|
|
LineNumber = $result.range.start.line + 1
|
|
Message = $result.message
|
|
}
|
|
}
|
|
}
|
|
|
|
$tempCsvPath = Join-Path $env:TEMP "bsl_diag_temp.csv"
|
|
$errorList | Export-Csv -Path $tempCsvPath -Encoding UTF8 -NoTypeInformation
|
|
$vbsPath = Join-Path $env:TEMP "launch_gridview.vbs"
|
|
|
|
$vbsContent = @'
|
|
Dim shell
|
|
Set shell = CreateObject("WScript.Shell")
|
|
shell.Run "powershell -WindowStyle Hidden -NoProfile -Command ""Import-Csv -Path '" & WScript.Arguments(0) & "' | Out-GridView -Title 'Diagnostic code with BSL Server 1c'; Remove-Item -Path '" & WScript.Arguments(0) & "' -Force; Start-Sleep -Seconds 3600""", 0, False
|
|
'@
|
|
|
|
Set-Content -Path $vbsPath -Value $vbsContent -Encoding ASCII
|
|
Start-Process "wscript.exe" -ArgumentList @("`"$vbsPath`"", "`"$tempCsvPath`"") -WindowStyle Hidden
|
|
Start-Sleep -Milliseconds 500
|
|
Remove-Item -Path $vbsPath -Force
|
|
|
|
Remove-Item -Path $pathDiag -Force
|
|
Write-Host "Удаление файла: " $pathDiag
|
|
}
|
|
|
|
if (Test-Path $folder) {
|
|
Remove-Item $folder -Recurse -Force
|
|
}
|
|
}
|
|
|
|
|
|
function Test-Configuration {
|
|
param(
|
|
[hashtable]$settings_1c,
|
|
[hashtable]$operation
|
|
)
|
|
|
|
$logFiles = Get-ChildItem -Path $settings_1c["root"] | Where-Object { $_.Extension -eq ".log" }
|
|
|
|
foreach ($file in $logFiles) {
|
|
try {
|
|
Remove-Item -Path $file.FullName -Force
|
|
Write-Host "Удалено: $($file.FullName)"
|
|
} catch {
|
|
Write-Warning "Не удалось удалить: $($file.FullName)"
|
|
}
|
|
}
|
|
|
|
$testSyntax = $operation.check_syntax
|
|
$testBSL = $operation.check_bsl
|
|
$pathBSL = $operation.path_bsl
|
|
|
|
if ($testSyntax) {
|
|
$result = $true
|
|
if (-not $operation.check_syntax_auto) {
|
|
$dialogResult = [System.Windows.Forms.MessageBox]::Show(
|
|
"Запустить проврерку syntax check 1c?",
|
|
"Check Syntax",
|
|
[System.Windows.Forms.MessageBoxButtons]::YesNo,
|
|
[System.Windows.Forms.MessageBoxIcon]::Question
|
|
)
|
|
$result = ($dialogResult -eq [System.Windows.Forms.DialogResult]::Yes)
|
|
}
|
|
|
|
if ($result) {
|
|
Test-Syntax -settings $settings_1c
|
|
}
|
|
}
|
|
|
|
if ($testBSL -and -not [string]::IsNullOrWhiteSpace($pathBSL)) {
|
|
$result = $true
|
|
if (-not $operation.check_bsl_auto) {
|
|
$dialogResult = [System.Windows.Forms.MessageBox]::Show(
|
|
"Сделать проверку c помощью BSL Server 1c?",
|
|
"Check BSL",
|
|
[System.Windows.Forms.MessageBoxButtons]::YesNo,
|
|
[System.Windows.Forms.MessageBoxIcon]::Question
|
|
)
|
|
$result = ($dialogResult -eq [System.Windows.Forms.DialogResult]::Yes)
|
|
}
|
|
|
|
if ($result) {
|
|
Test-BSL -operation $operation -settings_1c $settings_1c
|
|
}
|
|
}
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($files)) {
|
|
Write-Host "❗ Получена пустая строка. Прерывание."
|
|
exit 0
|
|
}
|
|
|
|
$filesArray = $files -split '\s+'
|
|
$filesArray = $filesArray | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
|
|
|
|
Write-Host "Список полученных файлов:"
|
|
$filesArray | ForEach-Object { Write-Host " → $_" }
|
|
|
|
$filesList = @()
|
|
foreach ($file in $filesArray) {
|
|
$item = Get-Item $file -ErrorAction SilentlyContinue
|
|
if ($item -and $item.Extension -eq ".bsl") {
|
|
$filesList += $file
|
|
}
|
|
}
|
|
|
|
Write-Host "Файлы с расширением .bsl:"
|
|
$filesList | ForEach-Object { Write-Host " + $_" }
|
|
|
|
$root = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
|
|
$jsonPath = Join-Path $root "config_hooks.json"
|
|
|
|
if (!(Test-Path $jsonPath)) {
|
|
$msg = "Settings file not found: config_hooks.json"
|
|
Write-Host $msg -ForegroundColor Red
|
|
Show-Message $msg "Settings" "Warning"
|
|
exit 1
|
|
}
|
|
|
|
$hook = Get-Content $jsonPath -Raw | ConvertFrom-Json
|
|
|
|
if (-not $hook.settings.pre_commit.use_precommit) {
|
|
Write-Host "Pre-commit hook отключен"
|
|
exit 0
|
|
}
|
|
|
|
$pathBSL = ""
|
|
|
|
if (-not [string]::IsNullOrWhiteSpace($hook.settings.pre_commit.path_bsl)) {
|
|
$pathBSL = $hook.settings.pre_commit.path_bsl
|
|
} else {
|
|
$bsl = Get-ChildItem -Path $root -Filter *.jar -File | Select-Object -First 1
|
|
if ($null -ne $bsl -and (Test-Path $bsl.FullName)) {
|
|
$pathBSL = $bsl.FullName
|
|
}
|
|
}
|
|
|
|
$operation = @{
|
|
use_precommit = $hook.settings.pre_commit.use_precommit
|
|
check_syntax = $hook.settings.pre_commit.check_syntax
|
|
check_syntax_auto = $hook.settings.pre_commit.check_syntax_auto
|
|
check_bsl = $hook.settings.pre_commit.check_bsl
|
|
path_bsl = $pathBSL
|
|
files = $filesList
|
|
}
|
|
|
|
Test-Settings -settings $operation
|
|
|
|
$src = if ([string]::IsNullOrWhiteSpace($hook.settings_1c.src)) {
|
|
Join-Path $root "src"
|
|
} else {
|
|
$hook.settings_1c.src
|
|
}
|
|
|
|
$settings_1c = @{
|
|
base = $hook.settings_1c.base
|
|
AuthOS = $hook.settings_1c.AuthOS
|
|
user = $hook.settings_1c.user
|
|
password = $hook.settings_1c.password
|
|
platform = $hook.settings_1c.platform
|
|
root = $root
|
|
src = $src
|
|
}
|
|
|
|
Test-Settings -settings $settings_1c
|
|
Test-Configuration -settings $settings_1c -operation $operation
|