Files
cliprepo/internal/bundle/bundle.go
T
2026-05-15 23:54:10 +08:00

92 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 =====
// <file content>
//
// ===== path/to/another =====
// <file content>
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)
}