|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "log" |
| 6 | + "strings" |
| 7 | + |
| 8 | + "github.com/scagogogo/python-requirements-parser/pkg/editor" |
| 9 | +) |
| 10 | + |
| 11 | +func main() { |
| 12 | + fmt.Println("=== 位置感知编辑器示例 ===") |
| 13 | + fmt.Println("演示最小化diff的编辑功能") |
| 14 | + fmt.Println() |
| 15 | + |
| 16 | + // 创建位置感知编辑器 |
| 17 | + posEditor := editor.NewPositionAwareEditor() |
| 18 | + |
| 19 | + // 示例requirements.txt内容(保持复杂的格式) |
| 20 | + originalContent := `# Production dependencies |
| 21 | +flask==1.0.0 # Web framework |
| 22 | +django>=3.2.0,<4.0.0 # Another web framework |
| 23 | +requests>=2.25.0,<3.0.0 # HTTP library |
| 24 | +
|
| 25 | +# Development dependencies |
| 26 | +pytest>=6.0.0 # Testing framework |
| 27 | +black==21.9b0 # Code formatter |
| 28 | +
|
| 29 | +# Complex dependencies with extras and markers |
| 30 | +uvicorn[standard]>=0.15.0 # ASGI server |
| 31 | +pywin32>=1.0; platform_system == "Windows" # Windows specific |
| 32 | +django[rest,auth]>=3.2.0 # Web framework with extras |
| 33 | +
|
| 34 | +# URL and VCS dependencies (will be preserved as-is) |
| 35 | +git+https://github.com/user/project.git#egg=project |
| 36 | +https://example.com/package.whl |
| 37 | +
|
| 38 | +# File references (will be preserved) |
| 39 | +-r dev-requirements.txt |
| 40 | +-c constraints.txt` |
| 41 | + |
| 42 | + fmt.Println("原始 requirements.txt 内容:") |
| 43 | + fmt.Println(strings.Repeat("=", 50)) |
| 44 | + fmt.Println(originalContent) |
| 45 | + fmt.Println(strings.Repeat("=", 50)) |
| 46 | + fmt.Println() |
| 47 | + |
| 48 | + // 解析文档 |
| 49 | + doc, err := posEditor.ParseRequirementsFile(originalContent) |
| 50 | + if err != nil { |
| 51 | + log.Fatalf("解析失败: %v", err) |
| 52 | + } |
| 53 | + |
| 54 | + // 显示解析出的包和位置信息 |
| 55 | + fmt.Println("=== 解析结果和位置信息 ===") |
| 56 | + packages := posEditor.ListPackages(doc) |
| 57 | + fmt.Printf("发现 %d 个包依赖:\n", len(packages)) |
| 58 | + for _, pkg := range packages { |
| 59 | + fmt.Printf("📦 %s %s", pkg.Name, pkg.Version) |
| 60 | + if len(pkg.Extras) > 0 { |
| 61 | + fmt.Printf(" [%s]", strings.Join(pkg.Extras, ",")) |
| 62 | + } |
| 63 | + if pkg.Markers != "" { |
| 64 | + fmt.Printf(" ; %s", pkg.Markers) |
| 65 | + } |
| 66 | + if pkg.Comment != "" { |
| 67 | + fmt.Printf(" # %s", pkg.Comment) |
| 68 | + } |
| 69 | + fmt.Println() |
| 70 | + |
| 71 | + if pkg.PositionInfo != nil { |
| 72 | + fmt.Printf(" 📍 位置: 行%d, 版本位置: %d-%d\n", |
| 73 | + pkg.PositionInfo.LineNumber, |
| 74 | + pkg.PositionInfo.VersionStartColumn, |
| 75 | + pkg.PositionInfo.VersionEndColumn) |
| 76 | + } |
| 77 | + fmt.Println() |
| 78 | + } |
| 79 | + |
| 80 | + // 演示单个包版本更新 |
| 81 | + fmt.Println("=== 单个包版本更新 ===") |
| 82 | + fmt.Println("更新 flask 版本: 1.0.0 -> 2.0.1") |
| 83 | + err = posEditor.UpdatePackageVersion(doc, "flask", "==2.0.1") |
| 84 | + if err != nil { |
| 85 | + log.Fatalf("更新flask版本失败: %v", err) |
| 86 | + } |
| 87 | + |
| 88 | + // 序列化并显示diff |
| 89 | + newContent := posEditor.SerializeToString(doc) |
| 90 | + fmt.Println("✅ 更新完成") |
| 91 | + fmt.Println() |
| 92 | + |
| 93 | + // 显示diff分析 |
| 94 | + fmt.Println("=== Diff 分析 ===") |
| 95 | + originalLines := strings.Split(originalContent, "\n") |
| 96 | + newLines := strings.Split(newContent, "\n") |
| 97 | + |
| 98 | + changedLines := 0 |
| 99 | + for i := 0; i < len(originalLines) && i < len(newLines); i++ { |
| 100 | + if originalLines[i] != newLines[i] { |
| 101 | + changedLines++ |
| 102 | + fmt.Printf("📝 行 %d 变化:\n", i+1) |
| 103 | + fmt.Printf(" - %s\n", originalLines[i]) |
| 104 | + fmt.Printf(" + %s\n", newLines[i]) |
| 105 | + fmt.Println() |
| 106 | + } |
| 107 | + } |
| 108 | + |
| 109 | + fmt.Printf("📊 总结: 只有 %d 行发生变化(最小化diff)\n", changedLines) |
| 110 | + fmt.Println() |
| 111 | + |
| 112 | + // 演示批量更新 |
| 113 | + fmt.Println("=== 批量版本更新 ===") |
| 114 | + updates := map[string]string{ |
| 115 | + "django": ">=3.2.13,<4.0.0", // 安全更新 |
| 116 | + "pytest": ">=7.0.0", // 主要版本升级 |
| 117 | + "uvicorn": ">=0.18.0", // 新版本 |
| 118 | + } |
| 119 | + |
| 120 | + fmt.Println("批量更新以下包:") |
| 121 | + for pkg, version := range updates { |
| 122 | + fmt.Printf(" 📦 %s: %s\n", pkg, version) |
| 123 | + } |
| 124 | + |
| 125 | + err = posEditor.BatchUpdateVersions(doc, updates) |
| 126 | + if err != nil { |
| 127 | + log.Printf("批量更新警告: %v", err) |
| 128 | + } else { |
| 129 | + fmt.Println("✅ 批量更新完成") |
| 130 | + } |
| 131 | + fmt.Println() |
| 132 | + |
| 133 | + // 最终结果 |
| 134 | + finalContent := posEditor.SerializeToString(doc) |
| 135 | + |
| 136 | + fmt.Println("=== 最终结果 ===") |
| 137 | + fmt.Println(strings.Repeat("=", 50)) |
| 138 | + fmt.Println(finalContent) |
| 139 | + fmt.Println(strings.Repeat("=", 50)) |
| 140 | + fmt.Println() |
| 141 | + |
| 142 | + // 最终diff分析 |
| 143 | + fmt.Println("=== 最终 Diff 分析 ===") |
| 144 | + finalLines := strings.Split(finalContent, "\n") |
| 145 | + totalChangedLines := 0 |
| 146 | + |
| 147 | + for i := 0; i < len(originalLines) && i < len(finalLines); i++ { |
| 148 | + if originalLines[i] != finalLines[i] { |
| 149 | + totalChangedLines++ |
| 150 | + fmt.Printf("📝 行 %d 最终变化:\n", i+1) |
| 151 | + fmt.Printf(" 原始: %s\n", originalLines[i]) |
| 152 | + fmt.Printf(" 最终: %s\n", finalLines[i]) |
| 153 | + fmt.Println() |
| 154 | + } |
| 155 | + } |
| 156 | + |
| 157 | + fmt.Printf("📊 最终总结: 总共 %d 行发生变化\n", totalChangedLines) |
| 158 | + fmt.Printf("📈 变化率: %.1f%% (%d/%d 行)\n", |
| 159 | + float64(totalChangedLines)/float64(len(originalLines))*100, |
| 160 | + totalChangedLines, len(originalLines)) |
| 161 | + |
| 162 | + // 演示位置感知编辑器的优势 |
| 163 | + fmt.Println() |
| 164 | + fmt.Println("=== 位置感知编辑器的优势 ===") |
| 165 | + fmt.Println("✅ 最小化diff - 只修改需要变更的部分") |
| 166 | + fmt.Println("✅ 保持格式 - 完美保留注释、空行、缩进") |
| 167 | + fmt.Println("✅ 精确编辑 - 基于位置信息的精确替换") |
| 168 | + fmt.Println("✅ 复杂格式支持 - extras、markers、注释都完美保持") |
| 169 | + fmt.Println("✅ 非包行保持 - URL、VCS、文件引用等保持不变") |
| 170 | + fmt.Println("✅ 高性能 - 基于位置信息,无需重新解析") |
| 171 | + |
| 172 | + fmt.Println() |
| 173 | + fmt.Println("🎉 位置感知编辑器演示完成!") |
| 174 | +} |
0 commit comments