-
Notifications
You must be signed in to change notification settings - Fork 7
Unified Architecture Refactor - Python and C++ Packages Use Same Version Management #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: llpyg
Are you sure you want to change the base?
Conversation
Comprehensive PR ReviewTodo List:
🎯 SummaryThis PR implements a major architectural refactor that successfully unifies Python and C++ package processing under a single version management system. The implementation demonstrates good design principles and achieves the stated goals of consolidation and consistency. ✅ Strengths1. Excellent Architecture Unification
2. Comprehensive Documentation
3. Smart Package Detection
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @PengPengPeng717, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces a significant architectural refactor to llpkgstore, unifying the version management system for both Python and C++ packages. The core change is to align Python package processing with the existing C++ package architecture, ensuring consistent version extraction, post-processing, and Git tag management across all supported languages.
Highlights
- Unified Version Management System: Python and C++ packages now use the same actions.DefaultClient interface for version extraction, post-processing (GitHub Release creation, Git tag management), and consistent version recording.
- Smart Version Extraction: Version information is now intelligently extracted from the latest commit messages, with optimizations for CI environments.
- Automatic Git Tag Management: The system automatically creates and pushes Git tags based on extracted version information, including duplicate detection to prevent errors.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request is a significant architectural refactor to unify Python and C++ package processing under a single version management system. The changes are extensive, introducing a new command structure for Python packages and refactoring the main entry point to dynamically select the appropriate implementation. While the overall direction is positive and improves modularity, there are several areas that need attention. I've identified issues related to error handling where errors are ignored, the presence of dead or misleading code, inconsistencies in implementation versus the stated goals in the description, and some maintainability concerns. Addressing these points will improve the robustness and clarity of the new unified architecture.
| var paths []string | ||
| pathEnv := os.Getenv("LLPKG_PATH") | ||
| if pathEnv != "" { | ||
| json.Unmarshal([]byte(pathEnv), &paths) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error returned by json.Unmarshal is being ignored. If pathEnv contains malformed JSON, this will fail silently, and paths will likely be empty. This could lead to the command appearing to succeed without actually running any tests. The error should be checked and handled.
| json.Unmarshal([]byte(pathEnv), &paths) | |
| if err := json.Unmarshal([]byte(pathEnv), &paths); err != nil { | |
| return fmt.Errorf("failed to unmarshal LLPKG_PATH: %w", err) | |
| } |
upstream/installer/pip/pip.go
Outdated
| } | ||
|
|
||
| // 添加一些常用的 pip 选项以提高稳定性 | ||
| args = append(args, "--no-deps") // 暂时不安装依赖,避免版本冲突 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pip install command is hardcoded with --no-deps. This will prevent the installation of any dependencies for the Python package, which could lead to runtime errors if the package relies on them. This behavior should be made configurable or at least be very clearly documented, as it's a significant limitation.
| if cfg.Type != "python" { | ||
| ver := versions.Read("llpkgstore.json") | ||
| ver.Write(clib, cfg.Upstream.Package.Version, mappedVersion) | ||
| fmt.Printf("Updated llpkgstore.json for C++ package: %s\n", clib) | ||
| } else { | ||
| fmt.Printf("Skipping llpkgstore.json update for Python package: %s\n", clib) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation skips updating llpkgstore.json for Python packages. This contradicts the PR description, which states a goal of "Unified Version Recording: Consistent version record format and update mechanism." If this is intentional, the reasoning should be documented. Otherwise, this seems like a bug that prevents Python package versions from being recorded in the unified system.
| } | ||
|
|
||
| for _, path := range paths { | ||
| absPath, _ := filepath.Abs(path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error returned from filepath.Abs(path) is ignored. If an error occurs, absPath will be an empty string, and runLLPygVerificationWithDir will be called with an empty path, likely causing it to fail in a confusing way. The error should be handled properly.
absPath, err := filepath.Abs(path)
if err != nil {
return fmt.Errorf("failed to get absolute path for %s: %w", path, err)
}| generator := llpyg.New(dir, cfg.Upstream.Package.Name, dir) | ||
|
|
||
| generated := filepath.Join(dir, ".generated") | ||
| os.Mkdir(generated, 0777) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h") { | ||
| // Show help for Python version by default | ||
| fmt.Println("llpkgstore - Package management tool for Python and C/C++ packages") | ||
| fmt.Println("") | ||
| fmt.Println("Usage:") | ||
| fmt.Println(" llpkgstore [command] [flags]") | ||
| fmt.Println("") | ||
| fmt.Println("Commands:") | ||
| fmt.Println(" generate Generate Go bindings for Python packages") | ||
| fmt.Println(" verification Verify generated packages") | ||
| fmt.Println(" postprocessing Process merged PR for Python packages") | ||
| fmt.Println(" release Build and upload Python binary packages") | ||
| fmt.Println(" install Install Python packages") | ||
| fmt.Println(" test Test Python verification functionality") | ||
| fmt.Println("") | ||
| fmt.Println("Flags:") | ||
| fmt.Println(" -h, --help Show this help message") | ||
| fmt.Println("") | ||
| fmt.Println("Examples:") | ||
| fmt.Println(" llpkgstore generate") | ||
| fmt.Println(" llpkgstore verification") | ||
| fmt.Println(" llpkgstore postprocessing") | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| for _, arg := range args { | ||
| if arg == "postprocessing" { | ||
| // For postprocessing, return a default type and let the command handle it | ||
| return "python", nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The special handling for the postprocessing command inside detectPackageType feels out of place and makes the logic harder to follow. This kind of command-specific logic should ideally reside within the command's implementation itself, rather than in a generic utility function. This would improve separation of concerns.
config/config.go
Outdated
| // GetDefaultModDepth returns the default module depth if not specified | ||
| func (l *LlpygConfig) GetDefaultModDepth() int { | ||
| if l.ModDepth == 0 { | ||
| return 1 // 默认深度为 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| log.Printf("Detected Python package: %s", cfg.Upstream.Package.Name) | ||
| } else { | ||
| // For C/C++ packages, detect conan profile | ||
| exec.Command("conan", "profile", "detect").Run() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error from exec.Command("conan", "profile", "detect").Run() is ignored. If conan is not installed or fails for any reason, the program will continue without any indication of failure, which could lead to subsequent, harder-to-debug errors. The error should be checked.
if err := exec.Command("conan", "profile", "detect").Run(); err != nil {
log.Printf("Warning: 'conan profile detect' failed: %v. This may cause issues for C/C++ packages.", err)
}| func currentDir() string { | ||
| dir, err := os.Getwd() | ||
| if err != nil { | ||
| panic(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's invalid directory internal_cpp
| func WithPipSerializer() Options { | ||
| return func(cb *CmdBuilder) { | ||
| cb.serializer = func(k, v string) string { | ||
| return fmt.Sprintf(`--%s=%s`, k, v) | ||
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unnecessary and repeated.
| "mod_name": "github.com/PengPengPeng717/llpkg/numpy", | ||
| "mod_depth": 2 | ||
| } | ||
| } No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use English instead of Chinese.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use English instead of Chinese.
docs/Summary.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use English instead of Chinese.
docs/architecture-improvements.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use English instead of Chinese.
docs/llpkgstore.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use English instead of Chinese.
config/config.go
Outdated
| return errors.New("module name should contain at least one slash") | ||
| } | ||
|
|
||
| // 检查是否以 github.com 或其他有效域名开头 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EN is better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid file extension name, should be llpkg.cfg
docs/Summary.md
Outdated
|
|
||
| ## 📚 **文档概览** | ||
|
|
||
| llpkgstore 项目经过优化整理后,现在包含 **7 个核心文档文件**,涵盖项目介绍、技术架构、功能特性、使用指南等各个方面。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why have "llpkgstore 项目经过优化整理后"?
docs/Summary.md
Outdated
| ### **整理前**:分散的文档结构 | ||
| - 架构信息分散在多个文件中 | ||
| - Python 相关内容分散 | ||
| - 用户查找信息困难 | ||
| - 缺乏统一的版本管理说明 | ||
|
|
||
| ### **整理后**:6 个核心文档文件 | ||
| - 架构信息统一在 `ARCHITECTURE.md` 中 | ||
| - Python 信息统一在 `python-support.md` 中 | ||
| - 项目信息统一在 `PROJECT.md` 中 | ||
| - 结构更清晰,查找更便捷 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not design doc need
docs/Summary.md
Outdated
| ### **整理后** | ||
| - **总文档数**:6 个 | ||
| - **核心文档**:5 个 | ||
| - **可视化文件**:2 个 | ||
| - **结构清晰**:信息集中,易于查找 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not need
| // contains checks if a slice contains a specific string | ||
| func contains(slice []string, item string) bool { | ||
| for _, s := range slice { | ||
| if s == item { | ||
| return true | ||
| } | ||
| } | ||
| return false | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unnecessary, there's slices.Contains in go standard library.
docs/PROJECT.md
Outdated
| ## 📝 更新日志 | ||
|
|
||
| ### v2.0.0 (最新) | ||
|
|
||
| #### 🎉 重大更新 | ||
| - **统一版本管理**: C/C++ 和 Python 包使用一致的版本管理机制 | ||
| - **智能版本提取**: 从提交消息自动提取版本信息 | ||
| - **双重版本记录**: 同时维护本地和集中式版本记录文件 | ||
| - **自动 Git 标签**: 基于版本信息自动创建和推送 Git 标签 | ||
|
|
||
| #### ✨ 新功能 | ||
| - **Python 包支持**: 完整的 Python 包 Go 绑定生成 | ||
| - **统一命令接口**: 自动包类型检测和智能路由 | ||
| - **增强错误处理**: 结构化的错误处理和恢复机制 | ||
| - **CI/CD 集成**: 优化的 GitHub Actions 工作流 | ||
|
|
||
| #### 🔧 改进 | ||
| - **架构统一**: 消除了 C++ 和 Python 部分的架构不一致 | ||
| - **代码复用**: 减少了重复代码,提高了维护性 | ||
| - **用户体验**: 一致的命令接口和错误消息格式 | ||
|
|
||
| ### v1.0.0 | ||
|
|
||
| #### 🎉 初始版本 | ||
| - **C/C++ 包支持**: 完整支持 C/C++ 库的 Go 绑定生成 | ||
| - **Conan 集成**: 支持 Conan 包管理器 | ||
| - **版本管理**: 复杂的语义化版本映射 | ||
| - **CI/CD 集成**: GitHub Actions 工作流支持 | ||
|
|
||
| #### ✨ 核心功能 | ||
| - **包管理**: 自动包安装和依赖管理 | ||
| - **绑定生成**: 使用 llcppg 生成 Go 绑定 | ||
| - **测试框架**: 自动生成演示代码和测试 | ||
| - **发布管理**: GitHub Releases 集成 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not need
test_config.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this file is put here?
docs/Summary.md
Outdated
| ## 📝 **文档特色** | ||
|
|
||
| ### **统一版本管理** | ||
| - 详细的版本提取流程说明 | ||
| - 双重版本记录机制 | ||
| - 自动 Git 标签功能 | ||
| - CI/CD 集成优化 | ||
|
|
||
| ### **架构统一** | ||
| - C/C++ 和 Python 包使用一致的架构 | ||
| - 统一的错误处理机制 | ||
| - 代码复用和维护性提升 | ||
| - 清晰的架构演进说明 | ||
|
|
||
| ### **用户友好** | ||
| - 完整的快速开始指南 | ||
| - 详细的配置说明 | ||
| - 丰富的示例和最佳实践 | ||
| - 全面的故障排除指南 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not design doc need
config/config.go
Outdated
| // GetDefaultOutputDir returns the default output directory if not specified | ||
| func (l *LlpygConfig) GetDefaultOutputDir() string { | ||
| if l.OutputDir == "" { | ||
| return "./test" // 默认输出目录 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's mock data? please use a global constant.
| if l.ModName == "" { | ||
| return "" // 默认使用包名 | ||
| } | ||
| return l.ModName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if l.ModName == "" { | |
| return "" // 默认使用包名 | |
| } | |
| return l.ModName | |
| return l.ModName |
| return nil, errors.New("actions: no artifact found") | ||
| // No artifacts found, return empty result instead of error | ||
| // This allows postprocessing to work even when artifacts are not available | ||
| return []*os.File{}, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a best practice in Go to return an empty result instead of error here.
If you don't need artifact, please skip it.
| ) | ||
|
|
||
| var ( | ||
| ErrLLPygGenerate = errors.New("llpyg: cannot generate: ") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLPyg or Llpyg? This name should be standardized.
…nly perform temporary installations when there are no corresponding packages in the system environment
Unified Architecture Refactor - Python and C++ Packages Use Same Version Management
🎯 Overview
This PR implements a major architectural refactor of
llpkgstore, unifying Python package processing logic with the same architecture system used by C++ packages, achieving true unified version management.�� Major Improvements
1. **Unified Version Management System **
actions.DefaultClientinterfaceclient.MappedVersion()method2. Smart Version Extraction
3. Automatic Git Tag Management
🔧 Technical Implementation
Unified Architecture Implementation
📈 Implementation Results
1. Maintainability Improvement
2. User Experience
📚 Documentation Updates
🔄 Backward Compatibility
📋 File Changes
New Files
docs/ARCHITECTURE.md- Unified architecture documentationdocs/PROJECT.md- Main project documentationModified Files
cmd/llpkgstore/internal_python/postprocessing.go- Unified to DefaultClient interfacedocs/python-support.md- Added unified version management descriptioninternal/actions/api.go- Enhanced version extraction logicDeleted Files
This PR implements major architectural improvements to llpkgstore. 🚀