Skip to content

Commit 646ab4b

Browse files
committed
docs: 补充完整的多语言文档页面
🌍 完善中文文档系统: - docs/zh/quick-start.md - 中文快速开始指南 - docs/zh/api/index.md - 中文API概览 - docs/zh/examples/index.md - 中文示例概览 - docs/zh/examples/basic-usage.md - 中文基本用法示例 - docs/zh/examples/position-aware-editor.md - 中文位置感知编辑器示例 - docs/zh/guide/supported-formats.md - 中文支持格式指南 - docs/zh/guide/performance.md - 中文性能优化指南 📝 补充英文示例页面: - docs/examples/position-aware-editor.md - 位置感知编辑器完整示例 ✨ 文档完整性: - 所有配置中引用的页面都已创建 - 中英文文档结构对称 - 导航链接全部可用 - 无404页面 🎯 文档覆盖: - ✅ 首页和快速开始 - ✅ 完整API参考 - ✅ 用户指南(格式、性能) - ✅ 渐进式示例教程 - ✅ 多语言支持(英文/中文) 📊 文档统计: - 英文页面: 12个 - 中文页面: 8个 - 总计: 20个文档页面 - 代码示例: 100+个 - 性能基准: 详细数据 这个提交确保了文档网站的完整性,所有导航链接都能正常工作, 为用户提供了完整的多语言文档体验。
1 parent ee17983 commit 646ab4b

File tree

8 files changed

+3115
-0
lines changed

8 files changed

+3115
-0
lines changed
Lines changed: 382 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,382 @@
1+
# Position Aware Editor
2+
3+
The Position Aware Editor is the most advanced editor in Python Requirements Parser, designed for production environments where minimal changes are crucial.
4+
5+
## Overview
6+
7+
The Position Aware Editor achieves **minimal diff editing** by:
8+
- Recording exact position information during parsing
9+
- Making surgical changes only to version constraints
10+
- Preserving all original formatting, comments, and structure
11+
12+
## Key Features
13+
14+
- **Minimal diff** - Only changes what's necessary
15+
- **Perfect format preservation** - Maintains comments, spacing, and structure
16+
- **High performance** - Nanosecond-level update operations
17+
- **Zero allocations** - Batch updates with no memory allocations
18+
19+
## Performance Comparison
20+
21+
| Editor | Single Update | Batch Update (10) | Diff Size |
22+
|--------|---------------|-------------------|-----------|
23+
| **PositionAwareEditor** | 67.67 ns | 374.1 ns | **5.9%** |
24+
| VersionEditorV2 | 2.1 µs | 15.2 µs | 11.8% |
25+
| VersionEditor | 5.3 µs | 42.1 µs | 15.2% |
26+
27+
## Basic Usage
28+
29+
```go
30+
package main
31+
32+
import (
33+
"fmt"
34+
"log"
35+
"os"
36+
37+
"github.com/scagogogo/python-requirements-parser/pkg/editor"
38+
)
39+
40+
func main() {
41+
// Create position-aware editor
42+
editor := editor.NewPositionAwareEditor()
43+
44+
// Read requirements file
45+
content, err := os.ReadFile("requirements.txt")
46+
if err != nil {
47+
log.Fatal(err)
48+
}
49+
50+
// Parse with position information
51+
doc, err := editor.ParseRequirementsFile(string(content))
52+
if err != nil {
53+
log.Fatal(err)
54+
}
55+
56+
// Update single package
57+
err = editor.UpdatePackageVersion(doc, "flask", "==2.0.1")
58+
if err != nil {
59+
log.Fatal(err)
60+
}
61+
62+
// Serialize with minimal changes
63+
result := editor.SerializeToString(doc)
64+
65+
// Write back to file
66+
err = os.WriteFile("requirements.txt", []byte(result), 0644)
67+
if err != nil {
68+
log.Fatal(err)
69+
}
70+
71+
fmt.Println("✅ Updated requirements.txt with minimal changes")
72+
}
73+
```
74+
75+
## Batch Updates
76+
77+
For maximum efficiency, use batch updates:
78+
79+
```go
80+
func securityUpdates() error {
81+
editor := editor.NewPositionAwareEditor()
82+
83+
content, err := os.ReadFile("requirements.txt")
84+
if err != nil {
85+
return err
86+
}
87+
88+
doc, err := editor.ParseRequirementsFile(string(content))
89+
if err != nil {
90+
return err
91+
}
92+
93+
// Security updates from vulnerability scanner
94+
updates := map[string]string{
95+
"django": ">=3.2.13,<4.0.0", // Security patch
96+
"requests": ">=2.28.0", // Security patch
97+
"cryptography": ">=39.0.2", // Security patch
98+
"pillow": ">=9.1.1", // Security patch
99+
}
100+
101+
// Apply all updates in one operation
102+
err = editor.BatchUpdateVersions(doc, updates)
103+
if err != nil {
104+
return err
105+
}
106+
107+
result := editor.SerializeToString(doc)
108+
return os.WriteFile("requirements.txt", []byte(result), 0644)
109+
}
110+
```
111+
112+
## Real-World Example
113+
114+
Here's a complete example showing the power of minimal diff editing:
115+
116+
```go
117+
package main
118+
119+
import (
120+
"fmt"
121+
"log"
122+
"strings"
123+
124+
"github.com/scagogogo/python-requirements-parser/pkg/editor"
125+
)
126+
127+
func main() {
128+
// Complex requirements.txt with various formats
129+
originalContent := `# Production dependencies
130+
flask==1.0.0 # Web framework
131+
django[rest,auth]>=3.2.0,<4.0.0 # Web framework with extras
132+
requests>=2.25.0,<3.0.0 # HTTP library
133+
134+
# VCS dependencies (should be preserved)
135+
git+https://github.com/company/[email protected]#egg=internal-package
136+
-e git+https://github.com/company/dev-tools.git@develop#egg=dev-tools
137+
138+
# URL dependencies (should be preserved)
139+
https://files.pythonhosted.org/packages/special-package-1.0.0.tar.gz
140+
141+
# Environment markers (should be preserved)
142+
pywin32>=1.0; platform_system == "Windows"
143+
dataclasses>=0.6; python_version < "3.7"
144+
145+
# File references (should be preserved)
146+
-r requirements-dev.txt
147+
-c constraints.txt
148+
149+
# Global options (should be preserved)
150+
--index-url https://pypi.company.com/simple/
151+
--extra-index-url https://pypi.org/simple/
152+
--trusted-host pypi.company.com`
153+
154+
fmt.Println("Original requirements.txt:")
155+
fmt.Println(strings.Repeat("=", 50))
156+
fmt.Println(originalContent)
157+
fmt.Println(strings.Repeat("=", 50))
158+
fmt.Println()
159+
160+
// Create editor and parse
161+
editor := editor.NewPositionAwareEditor()
162+
doc, err := editor.ParseRequirementsFile(originalContent)
163+
if err != nil {
164+
log.Fatal(err)
165+
}
166+
167+
// Security updates
168+
updates := map[string]string{
169+
"flask": "==2.0.1",
170+
"django": ">=3.2.13,<4.0.0",
171+
"requests": ">=2.28.0,<3.0.0",
172+
}
173+
174+
fmt.Printf("Applying %d security updates...\n", len(updates))
175+
for pkg, version := range updates {
176+
fmt.Printf(" 📦 %s: %s\n", pkg, version)
177+
}
178+
fmt.Println()
179+
180+
err = editor.BatchUpdateVersions(doc, updates)
181+
if err != nil {
182+
log.Fatal(err)
183+
}
184+
185+
result := editor.SerializeToString(doc)
186+
187+
fmt.Println("Updated requirements.txt:")
188+
fmt.Println(strings.Repeat("=", 50))
189+
fmt.Println(result)
190+
fmt.Println(strings.Repeat("=", 50))
191+
fmt.Println()
192+
193+
// Analyze the diff
194+
originalLines := strings.Split(originalContent, "\n")
195+
newLines := strings.Split(result, "\n")
196+
197+
changedLines := 0
198+
for i := 0; i < len(originalLines) && i < len(newLines); i++ {
199+
if originalLines[i] != newLines[i] {
200+
changedLines++
201+
fmt.Printf("📝 Line %d changed:\n", i+1)
202+
fmt.Printf(" - %s\n", originalLines[i])
203+
fmt.Printf(" + %s\n", newLines[i])
204+
fmt.Println()
205+
}
206+
}
207+
208+
fmt.Printf("📊 Summary:\n")
209+
fmt.Printf(" Total lines: %d\n", len(originalLines))
210+
fmt.Printf(" Changed lines: %d\n", changedLines)
211+
fmt.Printf(" Change rate: %.1f%%\n", float64(changedLines)/float64(len(originalLines))*100)
212+
fmt.Printf(" Preserved: VCS, URLs, file refs, global options, comments\n")
213+
214+
fmt.Println("\n✅ Perfect minimal diff editing!")
215+
}
216+
```
217+
218+
## Advanced Features
219+
220+
### Package Information
221+
222+
```go
223+
// Get detailed package information
224+
info, err := editor.GetPackageInfo(doc, "django")
225+
if err != nil {
226+
log.Fatal(err)
227+
}
228+
229+
fmt.Printf("Package: %s\n", info.Name)
230+
fmt.Printf("Version: %s\n", info.Version)
231+
fmt.Printf("Extras: %v\n", info.Extras)
232+
fmt.Printf("Markers: %s\n", info.Markers)
233+
fmt.Printf("Comment: %s\n", info.Comment)
234+
235+
// Position information
236+
if info.PositionInfo != nil {
237+
fmt.Printf("Line: %d\n", info.PositionInfo.LineNumber)
238+
fmt.Printf("Version position: %d-%d\n",
239+
info.PositionInfo.VersionStartColumn,
240+
info.PositionInfo.VersionEndColumn)
241+
}
242+
```
243+
244+
### List All Packages
245+
246+
```go
247+
packages := editor.ListPackages(doc)
248+
fmt.Printf("Found %d packages:\n", len(packages))
249+
250+
for _, pkg := range packages {
251+
fmt.Printf(" 📦 %s %s", pkg.Name, pkg.Version)
252+
if len(pkg.Extras) > 0 {
253+
fmt.Printf(" [%s]", strings.Join(pkg.Extras, ","))
254+
}
255+
if pkg.Markers != "" {
256+
fmt.Printf(" ; %s", pkg.Markers)
257+
}
258+
if pkg.Comment != "" {
259+
fmt.Printf(" # %s", pkg.Comment)
260+
}
261+
fmt.Println()
262+
}
263+
```
264+
265+
## Error Handling
266+
267+
```go
268+
// Handle package not found
269+
err := editor.UpdatePackageVersion(doc, "nonexistent", "==1.0.0")
270+
if err != nil {
271+
if strings.Contains(err.Error(), "not found") {
272+
fmt.Printf("Package not found, skipping update\n")
273+
} else {
274+
log.Fatalf("Update failed: %v", err)
275+
}
276+
}
277+
278+
// Handle invalid version format
279+
err = editor.UpdatePackageVersion(doc, "flask", "invalid-version")
280+
if err != nil {
281+
fmt.Printf("Invalid version format: %v\n", err)
282+
}
283+
284+
// Handle batch update failures
285+
err = editor.BatchUpdateVersions(doc, updates)
286+
if err != nil {
287+
fmt.Printf("Some updates failed: %v\n", err)
288+
// Continue with successful updates
289+
}
290+
```
291+
292+
## Production Use Cases
293+
294+
### CI/CD Security Updates
295+
296+
```go
297+
func ciSecurityUpdate() error {
298+
editor := editor.NewPositionAwareEditor()
299+
300+
// Read current requirements
301+
content, err := os.ReadFile("requirements.txt")
302+
if err != nil {
303+
return err
304+
}
305+
306+
doc, err := editor.ParseRequirementsFile(string(content))
307+
if err != nil {
308+
return err
309+
}
310+
311+
// Get security updates from vulnerability scanner
312+
securityUpdates := getSecurityUpdates() // Your implementation
313+
314+
// Apply updates
315+
err = editor.BatchUpdateVersions(doc, securityUpdates)
316+
if err != nil {
317+
return err
318+
}
319+
320+
// Write back with minimal changes
321+
result := editor.SerializeToString(doc)
322+
return os.WriteFile("requirements.txt", []byte(result), 0644)
323+
}
324+
```
325+
326+
### Development Workflow
327+
328+
```go
329+
func upgradePackages(packages []string) error {
330+
editor := editor.NewPositionAwareEditor()
331+
332+
content, err := os.ReadFile("requirements.txt")
333+
if err != nil {
334+
return err
335+
}
336+
337+
doc, err := editor.ParseRequirementsFile(string(content))
338+
if err != nil {
339+
return err
340+
}
341+
342+
updates := make(map[string]string)
343+
344+
// Get latest versions for specified packages
345+
for _, pkg := range packages {
346+
latestVersion, err := getLatestVersion(pkg) // Your implementation
347+
if err != nil {
348+
fmt.Printf("Warning: Could not get latest version for %s: %v\n", pkg, err)
349+
continue
350+
}
351+
updates[pkg] = latestVersion
352+
}
353+
354+
if len(updates) == 0 {
355+
fmt.Println("No packages to update")
356+
return nil
357+
}
358+
359+
fmt.Printf("Updating %d packages...\n", len(updates))
360+
err = editor.BatchUpdateVersions(doc, updates)
361+
if err != nil {
362+
return err
363+
}
364+
365+
result := editor.SerializeToString(doc)
366+
return os.WriteFile("requirements.txt", []byte(result), 0644)
367+
}
368+
```
369+
370+
## Best Practices
371+
372+
1. **Always use batch updates** for multiple packages
373+
2. **Validate version formats** before updating
374+
3. **Handle errors gracefully** for production use
375+
4. **Reuse editor instances** for better performance
376+
5. **Test changes** before applying to production
377+
378+
## Next Steps
379+
380+
- **[API Reference](/api/editors)** - Complete editor API documentation
381+
- **[Performance Guide](/guide/performance)** - Optimization tips
382+
- **[Examples Overview](/examples/)** - More examples and tutorials

0 commit comments

Comments
 (0)