Skip to content

<fix>[rest]: port Go SDK generator bug fixes from ZSV-11399#3616

Open
MatheMatrix wants to merge 2 commits into5.5.12from
sync/ye.zou/fix/gosdk-bugfix-from-zsv11399
Open

<fix>[rest]: port Go SDK generator bug fixes from ZSV-11399#3616
MatheMatrix wants to merge 2 commits into5.5.12from
sync/ye.zou/fix/gosdk-bugfix-from-zsv11399

Conversation

@MatheMatrix
Copy link
Copy Markdown
Owner

Summary

从 MR !9249 (ZSV-11399) 平移 Go SDK 生成器的 bug fix 到 5.5.12 分支。

GoApiTemplate.groovy

  • 所有生成的 Go 方法签名添加 ctx context.Context 参数(关键修复,符合 Go 惯例)
  • 添加 allTo 响应键提取,支持 PostWithRespKey 正确解包响应
  • 添加 valid 标志 + isValid() 方法,安全校验模板初始化
  • 添加 reset() 静态方法,防止重复 SDK 生成时状态污染
  • 添加 getApiOptPath() 处理可选路径
  • 修复复数化 bug:仅在辅音后的 y 才替换为 ies
  • GetWithSpec 传入 allTo 参数用于正确响应解包

GoInventory.groovy

  • 添加 reset() 方法 + 在 generate() 开始时调用 GoApiTemplate.reset()
  • 使用 template.isValid() 替代 template.at != null
  • 修复 time.Nowtime.Now()(4 处缺少括号)
  • 删除废弃的 generateClientFile() 方法(~400 行死代码)

base_param_types.go.template

  • 修复 time.Nowtime.Now()(缺少括号导致编译警告)

Origin

Ported from: http://gitlab.zstack.io/zstackio/zstack/-/merge_requests/9249

sync from gitlab !9477

Port critical Go SDK generation fixes from MR !9249 (ZSV-11399):

GoApiTemplate.groovy:
- Add context.Context parameter to all generated Go method signatures
- Add allTo response key extraction for PostWithRespKey
- Add valid flag + isValid() for safe template initialization
- Add reset() to prevent stale state across repeated SDK generation
- Add getApiOptPath() for optional path handling
- Fix pluralization: only replace y→ies after consonants
- Pass allTo to GetWithSpec for correct response unwrapping

GoInventory.groovy:
- Add reset() + call GoApiTemplate.reset() at start of generation
- Use template.isValid() instead of template.at != null
- Fix time.Now → time.Now() in generated Go code (4 occurrences)
- Remove deprecated generateClientFile() (~400 lines of dead code)

base_param_types.go.template:
- Fix time.Now → time.Now() (missing parentheses)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)

Review profile: CHILL

Plan: Pro

Run ID: c08ed3e5-5ea5-4d9d-add0-d123b62ae9c0

📥 Commits

Reviewing files that changed from the base of the PR and between 37326b7 and 326ca6b.

📒 Files selected for processing (1)
  • rest/src/main/resources/scripts/GoInventory.groovy
🚧 Files skipped from review as they are similar to previous changes (1)
  • rest/src/main/resources/scripts/GoInventory.groovy

Walkthrough

更新增强了 Go API 模板生成器的状态管理与重置能力,在生成的 Go 客户端方法中统一加入 context.Context 参数,修正了 time.Now() 调用,并调整了模板有效性与分页复数化判断逻辑。

Changes

Cohort / File(s) Summary
API 模板生成器
rest/src/main/resources/scripts/GoApiTemplate.groovy
新增私有字段 allTo、私有布尔 validisValid() 方法与公共静态 reset();引入 getApiOptPath(String);模板初始化仅在成功时标记为有效;生成器在输出的所有 Go 客户端方法中将 context.Context 作为首个参数并在调用处传递;调整分页变量复数化的特殊 ...y 规则。
生成器库存与重置
rest/src/main/resources/scripts/GoInventory.groovy
新增实例 reset() 方法以清理静态与实例生成缓存;在生成前调用 GoApiTemplate.reset() 与自身 reset();API 预解析改为基于 template.isValid();将 time.Now 参照更新为 time.Now();移除已弃用的私有 generateClientFile()
Go 模板导入占位修复
rest/src/main/resources/scripts/templates/base_param_types.go.template
将未使用导入的占位从 var _ = time.Now 改为 var _ = time.Now(),确保导入使用被视为已调用。

Sequence Diagram(s)

(无序列图:更改以生成器/模板内部为主,未引入新的多组件运行时控制流)

Estimated code review effort

🎯 4 (复杂) | ⏱️ ~45 分钟

🐰✨ 我在模板地里嗅新风,
重置足迹把旧云吹走,
上下文随行步步稳,
time.Now() 跳进时间溜,
小耳一抖,生成新芽生。

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed 标题遵循 [scope]: 格式且长度为 59 字符,符合 72 字符的限制要求。
Description check ✅ Passed 描述详细说明了 Go SDK 生成器的 bug 修复,包括对 GoApiTemplate.groovy、GoInventory.groovy 和 base_param_types.go.template 的更改,与代码变更高度相关。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/ye.zou/fix/gosdk-bugfix-from-zsv11399

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
rest/src/main/resources/scripts/GoApiTemplate.groovy (2)

555-588: ⚠️ Potential issue | 🔴 Critical

先把生成的 context import 补上。

这里开始给所有 client 方法生成 ctx context.Context,但 rest/src/main/resources/scripts/GoInventory.groovygenerateOtherActionsFile()generateActionFiles() 生成的 import block 还没有 context。这样产出的 other_actions.go / *_actions.go 会直接报 undefined: context

#!/bin/bash
set -e
echo "== Methods now using context.Context =="
sed -n '549,623p' rest/src/main/resources/scripts/GoApiTemplate.groovy | rg -n 'context\.Context|func \(cli \*ZSClient\)'
echo
echo "== other_actions.go import template =="
sed -n '1343,1353p' rest/src/main/resources/scripts/GoInventory.groovy
echo
echo "== grouped *_actions.go import template =="
sed -n '1663,1674p' rest/src/main/resources/scripts/GoInventory.groovy

Also applies to: 598-623

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rest/src/main/resources/scripts/GoApiTemplate.groovy` around lines 555 - 588,
The generated client methods in GoApiTemplate.groovy now add a ctx parameter of
type context.Context, but the import blocks produced by
generateOtherActionsFile() and generateActionFiles() in GoInventory.groovy don’t
include the context import, causing undefined: context errors; update the import
templates inside generateOtherActionsFile() and generateActionFiles() to include
"context" (add it alongside existing imports) so that other_actions.go and
grouped *_actions.go include import "context" whenever generated methods accept
ctx context.Context.

1337-1344: ⚠️ Potential issue | 🟠 Major

异步方法没有向 PostWithAsync 传递 ctx 参数。

函数签名已包含 ctx context.Context 参数,但在调用 cli.PostWithAsync(resource, responseKey, params, retVal, true) 时并未传递它。同步方法生成模板正确地将 ctx 传递给 cli.Post(ctx, ...)cli.Delete(ctx, ...) 等调用。需要修正模板,将 ctx 作为参数传递给 PostWithAsync 调用,以确保正确的上下文传播和超时/取消语义。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rest/src/main/resources/scripts/GoApiTemplate.groovy` around lines 1337 -
1344, The async method template in GoApiTemplate.groovy builds a ZSClient method
(function name ${asyncMethodName}) that accepts ctx context.Context but calls
cli.PostWithAsync without passing ctx; update the template so the PostWithAsync
invocation on cli includes ctx as the first argument (matching how sync methods
call cli.Post/cli.Delete) to propagate the context and preserve
cancellation/timeouts when calling PostWithAsync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@rest/src/main/resources/scripts/GoApiTemplate.groovy`:
- Around line 685-698: generateGetMethod currently ignores the parsed allTo
value and hardcodes response keys (e.g. "inventory" or "") in the unwrap=true
branches; update generateGetMethod to accept an allTo parameter (the value
parsed from `@RestResponse`) and replace the hardcoded responseKey arguments in
the GetWithRespKey and GetWithSpec calls inside the unwrap branches (references:
generateGetMethod, GetWithRespKey, GetWithSpec, variables clzName, cleanPath,
responseStructName, fieldName) so the generated methods use "${allTo}" instead
of "inventory" or "" across all branches.

In `@rest/src/main/resources/scripts/GoInventory.groovy`:
- Around line 109-115: The reset() method only clears longJobMappings but leaves
instance caches that leak between generate() runs; update reset() to also clear
allApiTemplates, generatedViewStructs, generatedParamStructs,
generatedClientMethods, additionalClasses (and any similar instance collections
used by generate()) so the GoInventory instance is fully reinitialized before a
new generation; locate the static void reset() method and add clear() calls for
each of those collections (and verify any other fields referenced by generate()
are reset as well) and keep the existing logger.warn call.

---

Outside diff comments:
In `@rest/src/main/resources/scripts/GoApiTemplate.groovy`:
- Around line 555-588: The generated client methods in GoApiTemplate.groovy now
add a ctx parameter of type context.Context, but the import blocks produced by
generateOtherActionsFile() and generateActionFiles() in GoInventory.groovy don’t
include the context import, causing undefined: context errors; update the import
templates inside generateOtherActionsFile() and generateActionFiles() to include
"context" (add it alongside existing imports) so that other_actions.go and
grouped *_actions.go include import "context" whenever generated methods accept
ctx context.Context.
- Around line 1337-1344: The async method template in GoApiTemplate.groovy
builds a ZSClient method (function name ${asyncMethodName}) that accepts ctx
context.Context but calls cli.PostWithAsync without passing ctx; update the
template so the PostWithAsync invocation on cli includes ctx as the first
argument (matching how sync methods call cli.Post/cli.Delete) to propagate the
context and preserve cancellation/timeouts when calling PostWithAsync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml (via .coderabbit.yaml)

Review profile: CHILL

Plan: Pro

Run ID: 132f1f34-cafb-40da-9dd2-f10ccb8aeb3d

📥 Commits

Reviewing files that changed from the base of the PR and between c4c23a6 and 37326b7.

📒 Files selected for processing (3)
  • rest/src/main/resources/scripts/GoApiTemplate.groovy
  • rest/src/main/resources/scripts/GoInventory.groovy
  • rest/src/main/resources/scripts/templates/base_param_types.go.template

Comment on lines +685 to 698
return """func (cli *ZSClient) ${clzName}(ctx context.Context) (*view.${viewStructName}, error) {
\tvar resp view.${responseStructName}
\tif err := cli.GetWithRespKey("${cleanPath}", "", "inventory", nil, &resp); err != nil {
\tif err := cli.GetWithRespKey(ctx, "${cleanPath}", "", "inventory", nil, &resp); err != nil {
\t\treturn nil, err
\t}
\treturn &resp.${fieldName}, nil
}
"""
} else {
// Single placeholder: use GetWithRespKey with uuid to extract inventory
return """func (cli *ZSClient) ${clzName}(uuid string) (*view.${viewStructName}, error) {
return """func (cli *ZSClient) ${clzName}(ctx context.Context, uuid string) (*view.${viewStructName}, error) {
\tvar resp view.${responseStructName}
\tif err := cli.GetWithRespKey("${cleanPath}", uuid, "inventory", nil, &resp); err != nil {
\tif err := cli.GetWithRespKey(ctx, "${cleanPath}", uuid, "inventory", nil, &resp); err != nil {
\t\treturn nil, err
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
echo "== Current GET branches =="
sed -n '671,720p' rest/src/main/resources/scripts/GoApiTemplate.groovy
echo
echo "== RestResponse(allTo=...) usages =="
rg -nP '@RestResponse\s*\(\s*allTo\s*=\s*"[^"]+"' --glob '*.java'

Repository: MatheMatrix/zstack

Length of output: 50374


🏁 Script executed:

# First, let's see the full generateGetMethod function and its context
sed -n '665,750p' rest/src/main/resources/scripts/GoApiTemplate.groovy

Repository: MatheMatrix/zstack

Length of output: 3625


🏁 Script executed:

# Find where generateGetMethod is called and check for allTo availability
grep -n "generateGetMethod" rest/src/main/resources/scripts/GoApiTemplate.groovy

# Also check if allTo is parsed somewhere
grep -n "allTo" rest/src/main/resources/scripts/GoApiTemplate.groovy | head -20

Repository: MatheMatrix/zstack

Length of output: 844


🏁 Script executed:

# Check lines 712-715 mentioned in "Also applies to"
sed -n '710,720p' rest/src/main/resources/scripts/GoApiTemplate.groovy

Repository: MatheMatrix/zstack

Length of output: 459


GET 方法的 unwrap 分支没有使用解析出的 allTo 值。

generateGetMethod 虽然可以访问类成员变量 allTo(在第 97 行从 @RestResponse 注解解析),但该方法的 unwrap=true 分支中:

  • 第 685-687 行:hardcode "inventory" 作为 responseKey
  • 第 698-700 行:hardcode "inventory" 作为 responseKey
  • 第 713 行:hardcode "" 传给 GetWithSpec

这与代码中其他地方的做法不一致(如第 650、1084 行正确使用 "${allTo}")。当 GET API 标注了 @RestResponse(allTo = "inventories") 或其他自定义值时,生成的 Go 代码仍会按错误的 key(或空字符串)解包响应,导致数据提取失败。

应该将 allTo 作为参数传入 generateGetMethod,并在所有分支中使用该参数而非 hardcode 值。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rest/src/main/resources/scripts/GoApiTemplate.groovy` around lines 685 - 698,
generateGetMethod currently ignores the parsed allTo value and hardcodes
response keys (e.g. "inventory" or "") in the unwrap=true branches; update
generateGetMethod to accept an allTo parameter (the value parsed from
`@RestResponse`) and replace the hardcoded responseKey arguments in the
GetWithRespKey and GetWithSpec calls inside the unwrap branches (references:
generateGetMethod, GetWithRespKey, GetWithSpec, variables clzName, cleanPath,
responseStructName, fieldName) so the generated methods use "${allTo}" instead
of "inventory" or "" across all branches.

The previous reset() only cleared longJobMappings (static), leaving
instance-level caches (allApiTemplates, generatedViewStructs,
generatedParamStructs, generatedClientMethods, additionalClasses,
etc.) intact across repeated generate() calls on the same instance.

This caused skipped or duplicate output when TestGenerateGoSDK ran
more than once in the same JVM.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants