package bundle import ( "fmt" "os" "strings" "cliprepo/internal/config" "github.com/atotto/clipboard" ) const maxFileSize = 1 * 1024 * 1024 // 1MB // Build 根据 config 中定义的 bundle key,将多个文件内容聚合成一个字符串 // // 设计用途: // 用于 CLI 工具中快速“打包”一组文件内容,例如: // cliprepo bundle api // => 输出 api 相关的一组代码文件内容,方便复制/分享/提交 prompt // // 行为特点: // 1. 从 cliprepo.yaml 中读取 bundles 配置 // 2. 根据 key 找到对应文件列表 // 3. 逐个读取文件内容并拼接 // 4. 自动跳过异常文件(不存在 / 读取失败) // 5. 自动过滤过大的文件(> 1MB) // // 输出格式: // // ===== path/to/file ===== // // // ===== path/to/another ===== // func Build(key string) (string, error) { // 读取配置文件(cliprepo.yaml) cfg, err := config.Load() if err != nil { return "", err } // 获取对应 bundle 的文件列表 files, ok := cfg.Bundles[key] if !ok { return "", fmt.Errorf("bundle not found: %s", key) } var builder strings.Builder // 遍历 bundle 中的所有文件路径 for _, file := range files { // 获取文件信息(用于判断大小 / 是否存在) info, err := os.Stat(file) if err != nil { // 文件不存在或无法访问时跳过 continue } // 跳过过大的文件,避免 CLI 输出过载或内存占用过高 if info.Size() > maxFileSize { continue } // 读取文件内容 data, err := os.ReadFile(file) if err != nil { // 读取失败直接跳过,不中断整个 bundle 构建 continue } // 写入文件分隔标记,便于阅读结构 builder.WriteString(fmt.Sprintf("===== %s =====\n", file)) // 写入文件内容 builder.Write(data) builder.WriteString("\n\n") } return builder.String(), nil } // Copy 将 bundle 内容写入系统剪贴板 // // 常见使用场景: // CLI 一键复制 bundle 输出,用于: // - prompt 输入 // - 代码审查 // - 远程分享 // - AI 上下文输入 func Copy(content string) error { return clipboard.WriteAll(content) }