467 lines
16 KiB
PowerShell
467 lines
16 KiB
PowerShell
# ============================================================
|
||
# setup-1c-repo.ps1 - Настройка Git-репозитория под выгрузку 1С (конфигуратор)
|
||
#
|
||
# Версия: 1.2.2
|
||
# Автор: Michael BAG <mk@p7net.ru>
|
||
# Репозиторий: https://git.p7net.ru/tools/git_man
|
||
#
|
||
# Платформа: Windows (PowerShell 5.1+ / PowerShell 7+)
|
||
# Для Linux/macOS используйте setup-1c-repo.sh
|
||
#
|
||
# Использование:
|
||
# .\setup-1c-repo.ps1 -Path DIR [-DryRun] [-Force] [-Init] [-Renormalize]
|
||
# [-NoGitignore] [-Verbose] [-Quiet] [-Help] [-Version]
|
||
#
|
||
# Описание:
|
||
# Включает локальные настройки Git в указанной папке (-Path / -Repo;
|
||
# обязательный параметр) для проектов с выгрузкой из конфигуратора 1С:
|
||
# - UTF-8 с BOM (как у конфигуратора; BOM хранится как часть содержимого)
|
||
# - CRLF в рабочей копии для *.bsl / *.xml и др. текстовых файлов выгрузки
|
||
# - корректное отображение кириллических путей (core.quotepath=false)
|
||
# - длинные пути (core.longpaths=true)
|
||
# - создаёт/обновляет .gitattributes и .gitignore
|
||
# ============================================================
|
||
|
||
[CmdletBinding()]
|
||
param(
|
||
[Parameter()]
|
||
[Alias('Repo', 'RepoPath')]
|
||
[string]$Path,
|
||
|
||
[switch]$DryRun,
|
||
[Alias('f')]
|
||
[switch]$Force,
|
||
[switch]$Init,
|
||
[switch]$Renormalize,
|
||
[switch]$NoGitignore,
|
||
[Alias('q')]
|
||
[switch]$Quiet,
|
||
[Alias('h')]
|
||
[switch]$Help,
|
||
[Alias('V')]
|
||
[switch]$Version
|
||
)
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
$ScriptVersion = '1.2.2'
|
||
|
||
function Show-Help {
|
||
@"
|
||
============================================================
|
||
📦 setup-1c-repo.ps1 v$ScriptVersion — настройка репозитория под 1С
|
||
============================================================
|
||
|
||
ОПИСАНИЕ:
|
||
Настраивает локальный Git-репозиторий под выгрузку из
|
||
конфигуратора 1С (UTF-8 BOM + CRLF).
|
||
Путь к репозиторию обязателен: -Path / -Repo.
|
||
|
||
ИСПОЛЬЗОВАНИЕ:
|
||
.\setup-1c-repo.ps1 -Path DIR [ОПЦИИ]
|
||
.\setup-1c-repo.cmd -Path DIR [ОПЦИИ]
|
||
|
||
ОПЦИИ:
|
||
-Help, -h Показать эту справку
|
||
-Version, -V Показать версию скрипта
|
||
-Path, -Repo DIR Папка репозитория для настройки (обязательно)
|
||
-DryRun Только показать, что будет сделано
|
||
-Force, -f Перезаписать существующие .gitattributes / .gitignore
|
||
-Init Выполнить git init, если папка ещё не репозиторий
|
||
(создаёт каталог, если его нет)
|
||
-Renormalize После настройки: git add --renormalize .
|
||
-NoGitignore Не создавать/не менять .gitignore
|
||
-Verbose, -v Подробный вывод
|
||
-Quiet, -q Минимальный вывод (только ошибки)
|
||
|
||
ПРИМЕРЫ:
|
||
.\setup-1c-repo.ps1 -Path D:\projects\uas_ep -Force
|
||
.\setup-1c-repo.ps1 -Repo ..\my-1c-dump -Init
|
||
.\setup-1c-repo.ps1 -Path . -Force -Renormalize
|
||
.\setup-1c-repo.ps1 -Path C:\tmp\new-1c -Init -DryRun
|
||
|
||
============================================================
|
||
"@ | Write-Host
|
||
exit 0
|
||
}
|
||
|
||
function Show-Version {
|
||
Write-Host "setup-1c-repo.ps1 $ScriptVersion"
|
||
exit 0
|
||
}
|
||
|
||
if ($Help) { Show-Help }
|
||
if ($Version) { Show-Version }
|
||
|
||
function Write-Info([string]$Message) {
|
||
if (-not $Quiet) { Write-Host "ℹ️ $Message" -ForegroundColor Cyan }
|
||
}
|
||
function Write-Success([string]$Message) {
|
||
if (-not $Quiet) { Write-Host "✅ $Message" -ForegroundColor Green }
|
||
}
|
||
function Write-WarnMsg([string]$Message) {
|
||
if (-not $Quiet) { Write-Host "⚠️ $Message" -ForegroundColor Yellow }
|
||
}
|
||
function Write-ErrMsg([string]$Message) {
|
||
Write-Host "❌ $Message" -ForegroundColor Red
|
||
}
|
||
function Write-DebugMsg([string]$Message) {
|
||
if ($VerbosePreference -ne 'SilentlyContinue' -and -not $Quiet) {
|
||
Write-Host "🔍 $Message" -ForegroundColor Blue
|
||
}
|
||
}
|
||
function Write-Step([string]$Message) {
|
||
if (-not $Quiet) { Write-Host "▶ $Message" -ForegroundColor Magenta }
|
||
}
|
||
|
||
$GitAttributesContent = @'
|
||
# .gitattributes — выгрузка конфигуратора 1С (UTF-8 BOM + CRLF)
|
||
# Создано setup-1c-repo.ps1 (git_man). Не удаляйте без необходимости.
|
||
#
|
||
# Правило: текстовые файлы выгрузки — text + eol=crlf (рабочая копия = CRLF,
|
||
# в объекте Git нормализуется к LF). Бинарники — binary (без конвертации EOL).
|
||
|
||
* text=auto
|
||
|
||
# --- Текстовые файлы выгрузки конфигуратора ---
|
||
*.bsl text eol=crlf
|
||
*.os text eol=crlf
|
||
*.xml text eol=crlf
|
||
*.txt text eol=crlf
|
||
*.html text eol=crlf
|
||
*.htm text eol=crlf
|
||
*.xsd text eol=crlf
|
||
*.xslt text eol=crlf
|
||
*.xsl text eol=crlf
|
||
*.Form text eol=crlf
|
||
*.Module text eol=crlf
|
||
*.max text eol=crlf
|
||
|
||
# --- Служебные / документация репозитория (LF) ---
|
||
*.md text eol=lf
|
||
*.json text eol=lf
|
||
*.yml text eol=lf
|
||
*.yaml text eol=lf
|
||
*.sh text eol=lf
|
||
*.gitignore text eol=lf
|
||
*.gitattributes text eol=lf
|
||
.editorconfig text eol=lf
|
||
|
||
# --- Скрипты Windows ---
|
||
*.bat text eol=crlf
|
||
*.cmd text eol=crlf
|
||
*.ps1 text eol=crlf
|
||
|
||
# --- Бинарные артефакты 1С и медиа ---
|
||
*.bin binary
|
||
*.cf binary
|
||
*.cfe binary
|
||
*.cfu binary
|
||
*.epf binary
|
||
*.erf binary
|
||
*.axdt binary
|
||
*.addin binary
|
||
|
||
*.png binary
|
||
*.jpg binary
|
||
*.jpeg binary
|
||
*.gif binary
|
||
*.bmp binary
|
||
*.ico binary
|
||
*.webp binary
|
||
*.tif binary
|
||
*.tiff binary
|
||
*.svg -text
|
||
|
||
*.zip binary
|
||
*.rar binary
|
||
*.7z binary
|
||
*.gz binary
|
||
|
||
*.xls binary
|
||
*.xlsx binary
|
||
*.xlsm binary
|
||
*.doc binary
|
||
*.docx binary
|
||
*.pdf binary
|
||
*.rtf binary
|
||
|
||
*.ttf binary
|
||
*.otf binary
|
||
*.woff binary
|
||
*.woff2 binary
|
||
*.eot binary
|
||
'@
|
||
|
||
$GitIgnoreContent = @'
|
||
# .gitignore — типовые исключения для проектов 1С (конфигуратор)
|
||
# Создано setup-1c-repo.ps1 (git_man)
|
||
|
||
# Бинарные выгрузки конфигурации / расширений / обработок
|
||
*.cf
|
||
*.cfe
|
||
*.cfu
|
||
*.epf
|
||
*.erf
|
||
|
||
# Временные и резервные
|
||
*.tmp
|
||
*.bak
|
||
*.~*
|
||
*~
|
||
*.old
|
||
*.orig
|
||
|
||
# Логи и дампы
|
||
*.log
|
||
*.lgp
|
||
*.lgf
|
||
|
||
# ОС
|
||
Thumbs.db
|
||
ehthumbs.db
|
||
Desktop.ini
|
||
desktop.ini
|
||
.DS_Store
|
||
.AppleDouble
|
||
.LSOverride
|
||
|
||
# IDE / редакторы
|
||
.vs/
|
||
.vscode/
|
||
.idea/
|
||
*.suo
|
||
*.user
|
||
*.userosscache
|
||
*.sln.docstates
|
||
|
||
# Отладка / кэш
|
||
Debug/
|
||
debug/
|
||
cache/
|
||
*.pfl
|
||
'@
|
||
|
||
function Test-GitAvailable {
|
||
try {
|
||
$null = Get-Command git -ErrorAction Stop
|
||
return $true
|
||
} catch {
|
||
return $false
|
||
}
|
||
}
|
||
|
||
function Write-Utf8File {
|
||
param(
|
||
[string]$FilePath,
|
||
[string]$Content,
|
||
[string]$BaseDir
|
||
)
|
||
# UTF-8 без BOM: для .gitattributes/.gitignore достаточно; BOM у *.bsl
|
||
# — содержимое выгрузки конфигуратора, не этих служебных файлов.
|
||
$normalized = $Content -replace "`r`n", "`n" -replace "`r", "`n"
|
||
$normalized = $normalized.TrimEnd("`n") + "`n"
|
||
$encoding = New-Object System.Text.UTF8Encoding($false)
|
||
$fullPath = Join-Path $BaseDir $FilePath
|
||
[System.IO.File]::WriteAllText($fullPath, $normalized, $encoding)
|
||
}
|
||
|
||
function Write-FileSafe {
|
||
param(
|
||
[string]$FilePath,
|
||
[string]$Content,
|
||
[string]$Label,
|
||
[string]$BaseDir
|
||
)
|
||
|
||
$fullPath = Join-Path $BaseDir $FilePath
|
||
|
||
if ((Test-Path -LiteralPath $fullPath) -and -not $Force) {
|
||
Write-WarnMsg "$Label уже существует — пропуск (используйте -Force)"
|
||
return
|
||
}
|
||
|
||
if ($DryRun) {
|
||
if (Test-Path -LiteralPath $fullPath) {
|
||
Write-Host " [DRY-RUN] перезаписать $fullPath (бэкап $FilePath.bak)"
|
||
} else {
|
||
Write-Host " [DRY-RUN] создать $fullPath"
|
||
}
|
||
return
|
||
}
|
||
|
||
if (Test-Path -LiteralPath $fullPath) {
|
||
Copy-Item -LiteralPath $fullPath -Destination "$fullPath.bak" -Force
|
||
Write-Info "Бэкап: $FilePath.bak"
|
||
}
|
||
|
||
Write-Utf8File -FilePath $FilePath -Content $Content -BaseDir $BaseDir
|
||
Write-Success "Записан $FilePath"
|
||
}
|
||
|
||
function Set-LocalGitConfig {
|
||
param(
|
||
[string]$Key,
|
||
[string]$Value,
|
||
[string]$WorkTree
|
||
)
|
||
if ($DryRun) {
|
||
Write-Host " [DRY-RUN] git -C `"$WorkTree`" config --local $Key $Value"
|
||
return
|
||
}
|
||
& git -C $WorkTree config --local $Key $Value
|
||
if ($LASTEXITCODE -ne 0) {
|
||
throw "Не удалось установить git config $Key=$Value"
|
||
}
|
||
Write-DebugMsg "config $Key=$Value"
|
||
}
|
||
|
||
# ============================================================
|
||
# Целевой каталог
|
||
# ============================================================
|
||
if ([string]::IsNullOrWhiteSpace($Path)) {
|
||
Write-ErrMsg "Не указан путь к репозиторию"
|
||
Write-Host " Обязательно: -Path DIR или -Repo DIR" -ForegroundColor Red
|
||
Write-Host " Справка: .\setup-1c-repo.ps1 -Help" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
|
||
$TargetDir = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
|
||
|
||
# ============================================================
|
||
# Основной ход
|
||
# ============================================================
|
||
Write-Step "Проверка окружения (ОС: Windows)..."
|
||
Write-Info "Целевой каталог: $TargetDir"
|
||
|
||
if (-not (Test-GitAvailable)) {
|
||
Write-ErrMsg "Git не установлен или недоступен в PATH"
|
||
exit 1
|
||
}
|
||
|
||
$repoReady = $false
|
||
|
||
if (-not (Test-Path -LiteralPath $TargetDir -PathType Container)) {
|
||
if ($Init) {
|
||
if ($DryRun) {
|
||
Write-Host " [DRY-RUN] New-Item -ItemType Directory `"$TargetDir`""
|
||
Write-Host " [DRY-RUN] git -C `"$TargetDir`" init"
|
||
} else {
|
||
New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null
|
||
Write-Success "Создан каталог: $TargetDir"
|
||
& git -C $TargetDir init
|
||
if ($LASTEXITCODE -ne 0) { throw "git init завершился с ошибкой" }
|
||
Write-Success "Выполнен git init"
|
||
$repoReady = $true
|
||
}
|
||
} else {
|
||
Write-ErrMsg "Папка не существует: $TargetDir"
|
||
Write-Host " Укажите существующий путь или добавьте -Init" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
} else {
|
||
$gitMarker = Join-Path $TargetDir '.git'
|
||
if (Test-Path -LiteralPath $gitMarker) {
|
||
$repoReady = $true
|
||
} elseif ($Init) {
|
||
if ($DryRun) {
|
||
Write-Host " [DRY-RUN] git -C `"$TargetDir`" init"
|
||
} else {
|
||
& git -C $TargetDir init
|
||
if ($LASTEXITCODE -ne 0) { throw "git init завершился с ошибкой" }
|
||
Write-Success "Выполнен git init"
|
||
$repoReady = $true
|
||
}
|
||
} else {
|
||
Write-ErrMsg "Папка не является Git-репозиторием: $TargetDir"
|
||
Write-Host " Укажите корень репозитория (-Path) или добавьте -Init" -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
# В dry-run без реального каталога дальше только показываем действия
|
||
if (-not $DryRun -and -not $repoReady -and -not (Test-Path -LiteralPath (Join-Path $TargetDir '.git'))) {
|
||
Write-ErrMsg "Репозиторий не готов: $TargetDir"
|
||
exit 1
|
||
}
|
||
|
||
Write-Success "Окружение проверено"
|
||
|
||
Write-Step "Локальные настройки Git..."
|
||
|
||
# Кириллические пути без \320\...
|
||
Set-LocalGitConfig -Key 'core.quotepath' -Value 'false' -WorkTree $TargetDir
|
||
# Длинные пути Windows / глубокие деревья метаданных 1С
|
||
Set-LocalGitConfig -Key 'core.longpaths' -Value 'true' -WorkTree $TargetDir
|
||
# Кодировки UI и коммитов
|
||
Set-LocalGitConfig -Key 'gui.encoding' -Value 'utf-8' -WorkTree $TargetDir
|
||
Set-LocalGitConfig -Key 'i18n.commitEncoding' -Value 'utf-8' -WorkTree $TargetDir
|
||
# EOL полностью через .gitattributes
|
||
Set-LocalGitConfig -Key 'core.autocrlf' -Value 'false' -WorkTree $TargetDir
|
||
Set-LocalGitConfig -Key 'core.safecrlf' -Value 'warn' -WorkTree $TargetDir
|
||
# Рекомендации 1С:ГитКонвертер для крупных деревьев метаданных
|
||
Set-LocalGitConfig -Key 'diff.renames' -Value 'false' -WorkTree $TargetDir
|
||
Set-LocalGitConfig -Key 'diff.renameLimit' -Value '1' -WorkTree $TargetDir
|
||
|
||
if ($DryRun) {
|
||
Write-Info "Локальный git config (dry-run)"
|
||
} else {
|
||
Write-Success "Локальный git config применён"
|
||
}
|
||
|
||
Write-Step "Файл .gitattributes..."
|
||
Write-FileSafe -FilePath '.gitattributes' -Content $GitAttributesContent -Label '.gitattributes' -BaseDir $TargetDir
|
||
|
||
if (-not $NoGitignore) {
|
||
Write-Step "Файл .gitignore..."
|
||
Write-FileSafe -FilePath '.gitignore' -Content $GitIgnoreContent -Label '.gitignore' -BaseDir $TargetDir
|
||
} else {
|
||
Write-Info "Пропуск .gitignore (-NoGitignore)"
|
||
}
|
||
|
||
if ($Renormalize) {
|
||
Write-Step "Нормализация индекса (git add --renormalize .)..."
|
||
if ($DryRun) {
|
||
Write-Host " [DRY-RUN] git -C `"$TargetDir`" add --renormalize ."
|
||
} else {
|
||
& git -C $TargetDir add --renormalize .
|
||
if ($LASTEXITCODE -ne 0) { throw "git add --renormalize завершился с ошибкой" }
|
||
Write-Success "Индекс перенормализован"
|
||
Write-WarnMsg "Проверьте git status — возможны массовые изменения EOL"
|
||
}
|
||
}
|
||
|
||
if (-not $Quiet) {
|
||
Write-Host ""
|
||
Write-Host "============================================================"
|
||
Write-Host "📊 Итог настройки под выгрузку конфигуратора 1С" -ForegroundColor Cyan
|
||
Write-Host "============================================================"
|
||
Write-Host " ОС: Windows"
|
||
Write-Host " Каталог: $TargetDir"
|
||
Write-Host " Encoding: UTF-8 (BOM сохраняется в содержимом файлов)"
|
||
Write-Host " EOL (выгрузка): CRLF в рабочей копии (*.bsl, *.xml, …)"
|
||
Write-Host " core.autocrlf: false (управляет .gitattributes)"
|
||
Write-Host " core.quotepath: false"
|
||
Write-Host " core.longpaths: true"
|
||
if ($DryRun) {
|
||
Write-Host ""
|
||
Write-Host "⚠️ Режим -DryRun: изменения НЕ применены" -ForegroundColor Yellow
|
||
} else {
|
||
Write-Host ""
|
||
Write-Host "✅ Готово" -ForegroundColor Green
|
||
Write-Host ""
|
||
Write-Host "Следующие шаги:" -ForegroundColor Cyan
|
||
Write-Host " 1. git -C `"$TargetDir`" status"
|
||
Write-Host " 2. git -C `"$TargetDir`" add .gitattributes .gitignore"
|
||
Write-Host ' 3. git commit -m "Настройки Git для выгрузки конфигуратора 1С"'
|
||
if (-not $Renormalize) {
|
||
Write-Host " 4. При необходимости нормализовать EOL:"
|
||
Write-Host " .\setup-1c-repo.ps1 -Path `"$TargetDir`" -Renormalize"
|
||
Write-Host " или: git -C `"$TargetDir`" add --renormalize ."
|
||
}
|
||
}
|
||
Write-Host "============================================================"
|
||
Write-Host ""
|
||
}
|
||
|
||
exit 0
|