-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathupdate.ps1
More file actions
303 lines (257 loc) · 11.6 KB
/
update.ps1
File metadata and controls
303 lines (257 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<#
.SYNOPSIS
Updates the Google Ads API Developer Assistant and its dependencies on Windows.
.DESCRIPTION
This script performs the following steps:
1. Updates the 'google-ads-api-developer-assistant' repository (git pull).
2. Reads '.gemini/settings.json' to locate configured client library repositories.
3. Updates each found client library repository (git pull).
.EXAMPLE
.\update.ps1
#>
param(
[switch]$Python,
[switch]$Php,
[switch]$Ruby,
[switch]$Java,
[switch]$Dotnet
)
function Get-RepoUrl {
param($Lang)
switch ($Lang) {
"python" { return "https://github.com/googleads/google-ads-python.git" }
"php" { return "https://github.com/googleads/google-ads-php.git" }
"ruby" { return "https://github.com/googleads/google-ads-ruby.git" }
"java" { return "https://github.com/googleads/google-ads-java.git" }
"dotnet" { return "https://github.com/googleads/google-ads-dotnet.git" }
}
}
function Get-RepoName {
param($Lang)
switch ($Lang) {
"python" { return "google-ads-python" }
"php" { return "google-ads-php" }
"ruby" { return "google-ads-ruby" }
"java" { return "google-ads-java" }
"dotnet" { return "google-ads-dotnet" }
}
}
$ErrorActionPreference = "Stop"
# --- Dependency Check ---
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Error "ERROR: git is not installed. Please install it to continue."
exit 1
}
# --- Project Directory Resolution ---
try {
$ProjectDirAbs = git rev-parse --show-toplevel 2>$null
if (-not $ProjectDirAbs) { throw "Not in a git repo" }
$ProjectDirAbs = (Get-Item -LiteralPath $ProjectDirAbs).FullName
}
catch {
Write-Error "ERROR: This script must be run from within the google-ads-api-developer-assistant git repository."
exit 1
}
Write-Host "Detected project root: $ProjectDirAbs"
# --- Update Assistant Repo ---
Write-Host "Updating google-ads-api-developer-assistant..."
$SettingsFile = Join-Path $ProjectDirAbs ".gemini\settings.json"
$TempSettingsFile = [System.IO.Path]::GetTempFileName()
$CustomerIdFile = Join-Path $ProjectDirAbs "customer_id.txt"
$TempCustomerIdFile = [System.IO.Path]::GetTempFileName()
try {
# 1. Backup existing settings if they exist
if (Test-Path -LiteralPath $SettingsFile) {
Write-Host "Backing up $SettingsFile..."
Copy-Item -LiteralPath $SettingsFile -Destination $TempSettingsFile -Force
# 2. Reset local changes to settings.json to allow git pull
# Check if file is tracked by git
$GitStatus = git ls-files --error-unmatch $SettingsFile 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "Resetting $SettingsFile to avoid merge conflicts..."
git checkout $SettingsFile
}
}
# 1b. Backup customer_id.txt if it exists
if (Test-Path -LiteralPath $CustomerIdFile) {
Write-Host "Backing up $CustomerIdFile..."
Copy-Item -LiteralPath $CustomerIdFile -Destination $TempCustomerIdFile -Force
# Reset local changes
$GitStatus = git ls-files --error-unmatch $CustomerIdFile 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "Resetting $CustomerIdFile to avoid merge conflicts..."
git checkout $CustomerIdFile
}
}
# 3. Update Repo
git pull
if ($LASTEXITCODE -ne 0) {
throw "Failed to update google-ads-api-developer-assistant."
}
Write-Host "Successfully updated google-ads-api-developer-assistant."
# 4. Restore/Merge settings
if ((Test-Path -LiteralPath $TempSettingsFile) -and (Get-Item $TempSettingsFile).Length -gt 0) {
Write-Host "Merging preserved settings with new defaults..."
# Read contents
$UserContent = Get-Content -LiteralPath $TempSettingsFile -Raw | ConvertFrom-Json
$RepoContent = Get-Content -LiteralPath $SettingsFile -Raw | ConvertFrom-Json
# Merge Logic: User overrides Repo
# Helper function for recursive merge could go here, but for now we do specific top-level merge
# replicating jq * behavior for simple objects.
# Actually, let's just use strict property copy from User to Repo for top-level keys
# If deeply nested merge is needed, valid for context.includeDirectories?
# Usually settings.json is flat or 1-level deep.
# Simple Merge: Add/Overwrite properties from User to Repo object
foreach ($Prop in $UserContent.PSObject.Properties) {
if ($Prop.Name -eq "context") {
# Special handling for context if needed, or just overwrite?
# jq * merges recursively.
# Let's try to merge context if both have it.
if ($RepoContent.PSObject.Properties["context"]) {
foreach ($CtxProp in $Prop.Value.PSObject.Properties) {
# e.g. includeDirectories
if (-not $RepoContent.context.PSObject.Properties[$CtxProp.Name]) {
$RepoContent.context | Add-Member -MemberType NoteProperty -Name $CtxProp.Name -Value $CtxProp.Value
} else {
$RepoContent.context.$($CtxProp.Name) = $CtxProp.Value
}
}
} else {
$RepoContent | Add-Member -MemberType NoteProperty -Name "context" -Value $Prop.Value
}
} else {
if (-not $RepoContent.PSObject.Properties[$Prop.Name]) {
$RepoContent | Add-Member -MemberType NoteProperty -Name $Prop.Name -Value $Prop.Value
} else {
$RepoContent.$($Prop.Name) = $Prop.Value
}
}
}
# Save merged
$RepoContent | ConvertTo-Json -Depth 10 | Set-Content -LiteralPath $SettingsFile -Encoding UTF8
Write-Host "Settings restored and merged successfully."
Write-Host "Settings restored and merged successfully."
}
# 4b. Restore customer_id.txt
if ((Test-Path -LiteralPath $TempCustomerIdFile) -and (Get-Item $TempCustomerIdFile).Length -gt 0) {
Write-Host "Restoring preserved $CustomerIdFile..."
# Always overwrite with user's backup
Move-Item -LiteralPath $TempCustomerIdFile -Destination $CustomerIdFile -Force
Write-Host "Restored $CustomerIdFile successfully."
}
}
catch {
Write-Error "ERROR: $_"
# Restore backup if pull failed or something went wrong involving the file
if ((Test-Path -LiteralPath $TempSettingsFile) -and (Get-Item $TempSettingsFile).Length -gt 0) {
if (-not (Test-Path -LiteralPath $SettingsFile) -or (Get-Item $SettingsFile).Length -eq 0) {
Write-Host "Restoring original settings after failure..."
Copy-Item -LiteralPath $TempSettingsFile -Destination $SettingsFile -Force
}
}
if ((Test-Path -LiteralPath $TempCustomerIdFile) -and (Get-Item $TempCustomerIdFile).Length -gt 0) {
if (-not (Test-Path -LiteralPath $CustomerIdFile) -or (Get-Item $CustomerIdFile).Length -eq 0) {
Write-Host "Restoring original customer_id.txt after failure..."
Copy-Item -LiteralPath $TempCustomerIdFile -Destination $CustomerIdFile -Force
}
}
exit 1
}
finally {
if (Test-Path -LiteralPath $TempSettingsFile) {
Remove-Item -LiteralPath $TempSettingsFile -Force -ErrorAction SilentlyContinue
}
if (Test-Path -LiteralPath $TempCustomerIdFile) {
Remove-Item -LiteralPath $TempCustomerIdFile -Force -ErrorAction SilentlyContinue
}
}
# --- Handle Specific Library Additions ---
$SpecifiedLangs = @()
if ($Python) { $SpecifiedLangs += "python" }
if ($Php) { $SpecifiedLangs += "php" }
if ($Ruby) { $SpecifiedLangs += "ruby" }
if ($Java) { $SpecifiedLangs += "java" }
if ($Dotnet) { $SpecifiedLangs += "dotnet" }
if ($SpecifiedLangs.Count -gt 0) {
$DefaultParentDir = Join-Path $ProjectDirAbs "client_libs"
foreach ($Lang in $SpecifiedLangs) {
$RepoUrl = Get-RepoUrl $Lang
$RepoName = Get-RepoName $Lang
$LibPath = Join-Path $DefaultParentDir $RepoName
if (-not (Test-Path -LiteralPath $LibPath)) {
Write-Host "Library $RepoName not found. Cloning into $LibPath..."
New-Item -ItemType Directory -Force -Path $DefaultParentDir | Out-Null
git clone $RepoUrl $LibPath
if ($LASTEXITCODE -ne 0) { throw "Failed to clone $RepoUrl" }
# Add to settings.json if not present
if (Test-Path -LiteralPath $SettingsFile) {
# Ensure we have the most up to date settings after possible git pull
$SettingsJson = Get-Content -LiteralPath $SettingsFile -Raw | ConvertFrom-Json
$AbsPath = (Get-Item -LiteralPath $LibPath).FullName
if ($null -eq $SettingsJson.context) {
$SettingsJson | Add-Member -MemberType NoteProperty -Name "context" -Value @{ includeDirectories = @() }
}
if ($null -eq $SettingsJson.context.includeDirectories) {
$SettingsJson.context | Add-Member -MemberType NoteProperty -Name "includeDirectories" -Value @()
}
if (-not ($SettingsJson.context.includeDirectories -contains $AbsPath)) {
Write-Host "Registering $AbsPath in $SettingsFile..."
$SettingsJson.context.includeDirectories += $AbsPath
$SettingsJson | ConvertTo-Json -Depth 10 | Set-Content -LiteralPath $SettingsFile -Encoding UTF8
}
}
}
}
}
# --- Locate and Update Client Libraries ---
$SettingsFile = Join-Path $ProjectDirAbs ".gemini\settings.json"
if (-not (Test-Path -LiteralPath $SettingsFile)) {
Write-Error "ERROR: Settings file not found: $SettingsFile"
Write-Error "Please run install.ps1 first."
exit 1
}
Write-Host "Reading $SettingsFile to find client libraries..."
try {
$SettingsJson = Get-Content -LiteralPath $SettingsFile -Raw | ConvertFrom-Json
if (-not $SettingsJson.context -or -not $SettingsJson.context.includeDirectories) {
Write-Warning "No directories found in settings."
exit 0
}
$IncludeDirs = $SettingsJson.context.includeDirectories
Write-Host "Found $($IncludeDirs.Count) directories in settings."
foreach ($LibPath in $IncludeDirs) {
if ([string]::IsNullOrWhiteSpace($LibPath)) { continue }
# Check if path exists
if (-not (Test-Path -LiteralPath $LibPath)) {
Write-Warning "Directory not found: $LibPath. Skipping."
continue
}
$AbsLibPath = (Get-Item -LiteralPath $LibPath).FullName
# Check if it is a git repository
if (-not (Test-Path -LiteralPath (Join-Path $AbsLibPath ".git"))) {
Write-Warning "Skipping non-git directory: $AbsLibPath"
continue
}
Write-Host "Updating repository at: $AbsLibPath..."
Push-Location $AbsLibPath
try {
git pull
if ($LASTEXITCODE -eq 0) {
Write-Host "Successfully updated $AbsLibPath."
} else {
Write-Error "ERROR: Failed to update $AbsLibPath"
# We exit on error to match update.sh behavior of failing fast-ish?
# Actually update.sh likely fails fast due to set -e.
exit 1
}
}
finally {
Pop-Location
}
}
}
catch {
Write-Error "ERROR: An error occurred while processing settings or updating libraries: $_"
exit 1
}
Write-Host "Update complete."