Skip to content

Conversation

@reddevillg
Copy link
Collaborator

No description provided.

@deepin-ci-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: reddevillg

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @reddevillg, 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 significantly refactors the builder configuration loading mechanism to enhance its robustness, centralization, and ease of use. It streamlines the process of locating and initializing the BuilderConfig by encapsulating complex path resolution and default creation logic within the linglong::builder library. This change improves maintainability, leverages modern C++ features like std::filesystem, and is thoroughly validated by a new suite of unit tests.

Highlights

  • Centralized Configuration Loading: The logic for discovering and loading builder configuration has been moved from the application's main entry point (main.cpp) into the linglong::builder library, promoting better modularity and reusability.
  • Simplified API for Configuration: The main application now interacts with a simplified, parameterless loadConfig() function, which internally handles the complexities of path resolution, default configuration initialization, and loading.
  • Modern C++ Filesystem Integration: Replaced QString and QDir based path manipulation with std::filesystem::path for improved type safety, consistency, and adherence to modern C++ standards.
  • Robust Default Configuration Initialization: A new initDefaultBuildConfig function has been introduced within the library to handle the creation of default configuration files and directories, leveraging XDG Base Directory Specification for standard locations.
  • Comprehensive Unit Testing: A new test file (config_test.cpp) has been added, providing extensive unit tests for the configuration saving, loading, and default initialization logic under various scenarios.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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

  1. 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.

@deepin-ci-robot
Copy link
Collaborator

deepin pr auto review

Git Diff 代码审查报告

总体评价

这次改动主要重构了配置加载逻辑,将配置管理从 main.cpp 移至专门的 config.cpp 模块,并添加了完整的单元测试。整体方向是正确的,提高了代码的模块化和可维护性,同时从 Qt 类型向标准 C++ 类型迁移。

具体问题与建议

1. 语法与逻辑问题

1.1 日志函数不一致性

位置: main.cpp 第 1003 行

qCritical() << builderCfg.error();

改为:

LogE("failed to load build config {}", builderCfg.error());

问题: 日志系统从 Qt 的 qCritical() 改为自定义的 LogE(),但需要确保整个项目日志系统已统一。
建议: 确认项目中所有日志调用是否已统一迁移到新的日志系统,避免混用导致日志格式不一致。

1.2 文件路径处理不一致

位置: config.cpp 第 22-27 行

auto cacheLocation = common::xdg::getXDGCacheHomeDir();
if (cacheLocation.empty()) {
    return LINGLONG_ERR("failed to get cache dir, neither XDG_CACHE_HOME nor HOME is set");
}

问题: 使用 std::filesystem::path 处理路径,但在某些地方仍使用字符串连接。
建议: 统一使用 std::filesystem::path 进行路径操作,避免手动拼接路径字符串。

2. 代码质量问题

2.1 错误处理不够详细

位置: config.cpp 第 70-73 行

if (!config) {
    return LINGLONG_ERR(config);
}

问题: 错误信息不够详细,没有指出具体是哪个配置文件加载失败。
建议: 添加更详细的错误信息,包括尝试加载的配置文件路径。

2.2 路径硬编码

位置: config.cpp 第 62 行

std::filesystem::path builderConfigPath = "builder/config.yaml";

问题: 配置文件路径硬编码,缺乏灵活性。
建议: 将配置文件路径定义为常量或通过配置选项提供,便于未来修改。

2.3 缺少配置文件验证

位置: config.cpp 第 43-45 行

if (config->version != 1) {
    return LINGLONG_ERR(
      fmt::format("wrong configuration file version {}", config->version));
}

问题: 仅验证版本号,未验证其他配置字段的合法性。
建议: 添加对其他关键配置字段的验证,如 repo 路径是否存在、arch 是否为支持的架构等。

3. 代码性能问题

3.1 文件系统操作可能频繁

位置: config.cpp 第 68-69 行

auto path = configDir / builderConfigPath;
if (!std::filesystem::exists(path, ec)) {

问题: 每次加载配置都会检查文件是否存在,可能造成不必要的文件系统访问。
建议: 考虑缓存配置文件路径或状态,减少文件系统操作频率。

3.2 YAML 加载效率

位置: config.cpp 第 35 行

auto config = utils::serialize::LoadYAMLFile<api::types::v1::BuilderConfig>(path);

问题: 每次加载配置都会完整解析 YAML 文件。
建议: 对于频繁访问的配置,考虑在内存中缓存解析后的配置对象。

4. 代码安全问题

4.1 路径遍历风险

位置: config.cpp 第 62-65 行

std::filesystem::path builderConfigPath = "builder/config.yaml";
auto configDir = common::dir::getUserRuntimeConfigDir();
if (configDir.empty()) {
    return LINGLONG_ERR("failed to get config dir");
}

问题: 如果 getUserRuntimeConfigDir() 返回的路径不可信,可能导致路径遍历攻击。
建议: 验证返回的配置目录路径是否合法,确保不会访问预期之外的文件。

4.2 权限问题

位置: config.cpp 第 28-31 行

std::error_code ec;
std::filesystem::create_directories(path.parent_path(), ec);
if (ec) {
    return LINGLONG_ERR("failed to create config dir", ec);
}

问题: 创建目录时没有设置适当的权限,可能导致配置文件被其他用户读取或修改。
建议: 在创建目录时设置适当的权限(如 0700),确保配置文件的安全性。

4.3 敏感信息泄露风险

位置: config.cpp 第 100-101 行

LogD("Load build config from {}", path);

问题: 日志中记录完整路径可能泄露系统信息。
建议: 在日志中只记录配置文件名或相对路径,避免记录完整绝对路径。

5. 测试覆盖问题

5.1 测试用例不完整

位置: config_test.cpp
问题: 测试用例覆盖了基本功能,但缺少一些边界情况和异常情况的测试。
建议: 添加以下测试用例:

  1. 配置文件损坏的情况
  2. 配置文件权限不足的情况
  3. 配置目录不可写的情况
  4. 并发访问配置文件的情况

5.2 测试环境隔离

位置: config_test.cpp 第 30-31 行

EnvironmentVariableGuard homeGuard("HOME", testDir().string());
EnvironmentVariableGuard xdgCacheGuard("XDG_CACHE_HOME", (testDir() / "cache").string());

问题: 测试中修改环境变量,但可能影响其他测试。
建议: 确保测试用例之间完全隔离,每个测试用例结束后恢复环境变量到初始状态。

总结

这次重构在整体方向上是正确的,提高了代码的模块化和可维护性。但在错误处理、路径安全、权限设置等方面还有改进空间。建议在合并前解决上述安全和健壮性问题,并完善测试用例覆盖。

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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 refactors the builder configuration loading logic, centralizing it and removing Qt dependencies in favor of the standard C++ filesystem library. This is a great improvement. I've added a few comments:

  • A high-severity concern about the removal of project-specific configuration file loading, which appears to be a significant breaking change.
  • A suggestion to improve consistency by adding noexcept to a new function declaration.
  • A fix for a test case that seems to have flawed logic.

Overall, the changes are good, but the potential breaking change needs to be addressed or at least documented.

I am having trouble creating individual review comments. Click here to see my feedback.

apps/ll-builder/src/main.cpp (41-54)

high

This refactoring removes the functionality to search for project-specific configuration files (.ll-builder/config.yaml) by traversing up from the current directory. The new implementation in linglong::builder::loadConfig() only loads a single global user configuration.

This is a significant behavioral change that could break workflows for users who depend on per-project builder configurations.

If this change is intentional, it should be clearly documented as a breaking change for users. If it's unintentional, the project-specific config loading logic should be restored within the new loadConfig implementation.

libs/linglong/tests/ll-tests/src/linglong/builder/config_test.cpp (140-150)

high

This test case for directory creation failure appears to be flawed. Passing "config.yaml" to initDefaultBuildConfig results in its parent path being empty. std::filesystem::create_directories on an empty path is a no-op and doesn't set an error. Subsequently, saveConfig will likely succeed by creating config.yaml in the test's working directory, causing the ASSERT_FALSE to fail.

To correctly test this failure scenario, you should create a file where a directory is expected, which will cause create_directories to fail. Here is a suggested implementation:

TEST_F(BuilderConfigTest, InitDefaultBuildConfigCreateDirFailure)
{
    EnvironmentVariableGuard homeGuard("HOME", testDir().string());
    EnvironmentVariableGuard xdgCacheGuard("XDG_CACHE_HOME", (testDir() / "cache").string());

    // Create a file where a directory is expected, to cause create_directories to fail.
    const auto builderDirAsFile = testDir() / "builder";
    std::ofstream(builderDirAsFile);

    const auto configPath = builderDirAsFile / "config.yaml";
    auto result = initDefaultBuildConfig(configPath);

    ASSERT_FALSE(result.has_value());
    EXPECT_TRUE(result.error().message().find("failed to create config dir") != std::string::npos);
}

libs/linglong/src/linglong/builder/config.h (16-17)

medium

For consistency with other function declarations in this header, initDefaultBuildConfig should be marked as noexcept. The implementation does not throw exceptions but returns errors via the Result type, which matches the noexcept pattern used for other functions like loadConfig and saveConfig.

Don't forget to add noexcept to the function definition in config.cpp as well.

utils::error::Result<api::types::v1::BuilderConfig>
initDefaultBuildConfig(const std::filesystem::path &path) noexcept;

@codecov
Copy link

codecov bot commented Jan 16, 2026

Codecov Report

❌ Patch coverage is 53.65854% with 19 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
libs/linglong/src/linglong/builder/config.cpp 56.41% 7 Missing and 10 partials ⚠️
apps/ll-builder/src/main.cpp 0.00% 2 Missing ⚠️
Files with missing lines Coverage Δ
apps/ll-builder/src/main.cpp 0.00% <0.00%> (ø)
libs/linglong/src/linglong/builder/config.cpp 47.16% <56.41%> (+47.16%) ⬆️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request refactors the builder configuration loading logic to simplify the implementation and improve maintainability. The changes migrate from Qt-based types (QString, QStringList) to standard C++ types (std::filesystem::path, std::string) and remove complex multi-path configuration resolution in favor of a simpler, single-path approach.

Changes:

  • Replaced Qt-based file path handling with std::filesystem::path throughout the configuration module
  • Simplified configuration loading by removing multi-path search logic and consolidating to XDG config directory
  • Added comprehensive test coverage for all configuration loading scenarios including error cases

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
libs/linglong/tests/ll-tests/src/linglong/builder/config_test.cpp New comprehensive test suite covering all configuration functions including edge cases and error scenarios
libs/linglong/tests/ll-tests/CMakeLists.txt Added new test file to the build configuration
libs/linglong/src/linglong/builder/config.h Updated API signatures to use std::filesystem::path instead of QString and simplified to three main functions
libs/linglong/src/linglong/builder/config.cpp Refactored implementation to use std::filesystem and removed complex multi-path resolution logic
apps/ll-builder/src/main.cpp Simplified configuration loading by removing project-specific config paths and initialization logic

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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