同步最新

This commit is contained in:
Zane
2026-05-07 11:14:29 +08:00
parent ff654b91f2
commit 8f3aa6fd3a
12 changed files with 319 additions and 381 deletions

252
git_sync_daily.ps1 Normal file
View File

@@ -0,0 +1,252 @@
#!/usr/bin/env pwsh
# Git Sync Script with Gantt Integration
# Runs daily at 10:30 AM
param(
[string]$RepoPath = "D:/fork_project/obsidian-notes"
)
$InBoxPath = Join-Path $RepoPath "InBox"
$GanttTag = "obsidian"
$GitArgs = @("-c", "safe.directory=$RepoPath")
function Resolve-GanttApp {
$candidates = @(
"C:/Users/Administrator/Desktop/我的/app_gant2/src-tauri/target/release/gantt-app.exe",
"C:/Users/Administrator/Desktop/我的/app_gant2/src-tauri/target/debug/gantt-app.exe"
)
foreach ($candidate in $candidates) {
if (Test-Path $candidate) {
return $candidate
}
}
$searchRoot = "C:/Users/Administrator/Desktop"
if (Test-Path $searchRoot) {
$found = Get-ChildItem -Path $searchRoot -Filter "gantt-app.exe" -Recurse -ErrorAction SilentlyContinue |
Sort-Object FullName -Descending |
Select-Object -First 1 -ExpandProperty FullName
if ($found) {
return $found
}
}
return $null
}
$GanttApp = Resolve-GanttApp
# Change to repo directory
Set-Location $RepoPath
function Invoke-GitCommand {
param(
[Parameter(Mandatory)]
[string[]]$Arguments
)
$output = & git @GitArgs @Arguments 2>&1
return [PSCustomObject]@{
Output = @($output)
ExitCode = $LASTEXITCODE
}
}
function Get-InBoxFileNames {
if (Test-Path $InBoxPath) {
return Get-ChildItem -Path $InBoxPath -File | Select-Object -ExpandProperty Name
}
return @()
}
# Function to get all Gantt tasks
function Get-GanttTasks {
if ($GanttApp -and (Test-Path $GanttApp)) {
try {
$result = & $GanttApp --cli list-tasks 2>$null | ConvertFrom-Json
if ($result.ok -and $result.data.tasks) {
return $result.data.tasks
}
} catch {
Write-Host "Failed to get Gantt tasks: $_"
}
}
return @()
}
# Function to show Windows notification
function Show-Notification {
param([string]$Title, [string]$Message)
Add-Type -AssemblyName System.Windows.Forms
$global:balloon = New-Object System.Windows.Forms.NotifyIcon
$path = (Get-Process -Id $pid).Path
$balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
$balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Warning
$balloon.BalloonTipText = $Message
$balloon.BalloonTipTitle = $Title
$balloon.Visible = $true
$balloon.ShowBalloonTip(5000)
}
function Fail-AndExit {
param(
[string]$Title,
[string]$Message
)
Write-Host $Message
Show-Notification -Title $Title -Message $Message
exit 1
}
function Test-RepoReady {
if (-not (Test-Path $RepoPath)) {
Fail-AndExit -Title "Git Sync Error" -Message "Repository path not found: $RepoPath"
}
$statusResult = Invoke-GitCommand -Arguments @("status", "--short", "--branch")
if ($statusResult.ExitCode -ne 0) {
$message = ($statusResult.Output -join [Environment]::NewLine).Trim()
if ([string]::IsNullOrWhiteSpace($message)) {
$message = "Failed to read git status."
}
Fail-AndExit -Title "Git Sync Error" -Message $message
}
$dirtyEntries = $statusResult.Output | Where-Object {
$_ -and $_ -notmatch "^## "
}
if ($dirtyEntries.Count -gt 0) {
$preview = ($dirtyEntries | Select-Object -First 5) -join "; "
$message = "Working tree is not clean. Resolve or commit local changes before auto sync. $preview"
Fail-AndExit -Title "Git Sync Blocked" -Message $message
}
}
function Add-GanttTask {
param([string]$TaskName)
$today = Get-Date -Format "yyyy-MM-dd"
$taskId = [Guid]::NewGuid().ToString()
if ($GanttApp -and (Test-Path $GanttApp)) {
try {
& $GanttApp --cli add-task --id $taskId --name $TaskName --start $today --description "Auto-created from InBox sync" --tag $GanttTag 2>$null
Write-Host "Created Gantt task: $TaskName"
} catch {
Write-Host "Failed to create Gantt task: $_"
}
} else {
Write-Host "Gantt app not found"
}
}
function Update-GanttTaskTag {
param(
[string]$TaskId,
[string]$TaskName
)
if ($GanttApp -and (Test-Path $GanttApp)) {
try {
& $GanttApp --cli update-task --id $TaskId --tag $GanttTag 2>$null
Write-Host "Updated Gantt task tag: $TaskName"
} catch {
Write-Host "Failed to update Gantt task tag: $_"
}
}
}
function Remove-GanttTask {
param([string]$TaskId)
if ($GanttApp -and (Test-Path $GanttApp)) {
try {
& $GanttApp --cli delete-task --id $TaskId 2>$null
Write-Host "Deleted Gantt task: $TaskId"
} catch {
Write-Host "Failed to delete Gantt task: $_"
}
}
}
function Sync-InBoxTasks {
if (-not ($GanttApp -and (Test-Path $GanttApp))) {
Write-Host "Skipping Gantt sync because gantt-app.exe was not found"
return
}
$inboxFiles = Get-InBoxFileNames
$ganttTasks = Get-GanttTasks
$existingInboxTasks = $ganttTasks | Where-Object { $_.name -match "^Process InBox: " }
foreach ($task in $existingInboxTasks) {
$taskFileName = $task.name -replace "^Process InBox: ", ""
if ($taskFileName -notin $inboxFiles) {
Write-Host "File no longer exists, deleting task: $($task.name)"
Remove-GanttTask -TaskId $task.id
}
}
foreach ($file in $inboxFiles) {
$taskName = "Process InBox: $file"
$matchingTasks = @($existingInboxTasks | Where-Object { $_.name -eq $taskName })
if ($matchingTasks.Count -eq 0) {
Add-GanttTask -TaskName $taskName
continue
}
foreach ($task in $matchingTasks) {
if ($task.tag -ne $GanttTag) {
Update-GanttTaskTag -TaskId $task.id -TaskName $task.name
} else {
Write-Host "Task already exists for: $file"
}
}
}
}
# Perform git pull
Test-RepoReady
Write-Host "Starting git pull at $(Get-Date)..."
$pullResult = Invoke-GitCommand -Arguments @("pull")
$pullOutput = $pullResult.Output
$pullExitCode = $pullResult.ExitCode
if ($pullExitCode -ne 0) {
$message = "Git pull failed: " + (($pullOutput -join [Environment]::NewLine).Trim())
Fail-AndExit -Title "Git Sync Error" -Message $message
}
Write-Host "Git pull completed: $($pullOutput -join [Environment]::NewLine)"
# Check for merge conflicts
if ($pullOutput -match "CONFLICT|conflict|Automatic merge failed") {
Show-Notification -Title "Git Sync Conflict" -Message "Merge conflicts detected during git pull. Please resolve manually."
exit 1
}
# Sync Gantt tasks against the full current InBox state
Start-Sleep -Seconds 2
Sync-InBoxTasks
# Perform git push
Write-Host "Starting git push..."
$pushResult = Invoke-GitCommand -Arguments @("push")
$pushOutput = $pushResult.Output
$pushExitCode = $pushResult.ExitCode
if ($pushExitCode -ne 0) {
$pushText = ($pushOutput -join [Environment]::NewLine).Trim()
if ($pushText -match "rejected|failed|conflict|non-fast-forward") {
Show-Notification -Title "Git Push Conflict" -Message "Push rejected. Please pull and resolve conflicts manually."
} else {
Show-Notification -Title "Git Push Error" -Message "Git push failed: $pushText"
}
exit 1
}
Write-Host "Git push completed successfully at $(Get-Date)"