mirror of
https://github.com/johndoe6345789/WizardMerge.git
synced 2026-04-24 13:44:55 +00:00
Add API client examples and comprehensive documentation
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
221
backend/examples/README.md
Normal file
221
backend/examples/README.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# WizardMerge API Examples
|
||||
|
||||
This directory contains example clients for the WizardMerge HTTP API.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Make sure the WizardMerge HTTP server is running:
|
||||
|
||||
```sh
|
||||
cd ..
|
||||
./build.sh
|
||||
cd build
|
||||
./wizardmerge-cli
|
||||
```
|
||||
|
||||
The server should be running on http://localhost:8080
|
||||
|
||||
## Examples
|
||||
|
||||
### Python Client (`api_client.py`)
|
||||
|
||||
Demonstrates API usage with the requests library.
|
||||
|
||||
**Requirements:**
|
||||
```sh
|
||||
pip install requests
|
||||
```
|
||||
|
||||
**Run:**
|
||||
```sh
|
||||
./api_client.py
|
||||
```
|
||||
|
||||
### Curl Examples (`test_api.sh`)
|
||||
|
||||
Shell script with curl commands for testing the API.
|
||||
|
||||
**Requirements:**
|
||||
- curl
|
||||
- jq (optional, for pretty JSON output)
|
||||
|
||||
**Run:**
|
||||
```sh
|
||||
./test_api.sh
|
||||
```
|
||||
|
||||
## API Endpoint
|
||||
|
||||
### POST /api/merge
|
||||
|
||||
Performs a three-way merge operation.
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"base": ["line1", "line2", "line3"],
|
||||
"ours": ["line1", "line2_modified", "line3"],
|
||||
"theirs": ["line1", "line2", "line3_modified"]
|
||||
}
|
||||
```
|
||||
|
||||
**Response (Success):**
|
||||
```json
|
||||
{
|
||||
"merged": ["line1", "line2_modified", "line3_modified"],
|
||||
"conflicts": [],
|
||||
"has_conflicts": false
|
||||
}
|
||||
```
|
||||
|
||||
**Response (With Conflicts):**
|
||||
```json
|
||||
{
|
||||
"merged": [
|
||||
"line1",
|
||||
"<<<<<<< OURS",
|
||||
"line2_ours",
|
||||
"=======",
|
||||
"line2_theirs",
|
||||
">>>>>>> THEIRS",
|
||||
"line3"
|
||||
],
|
||||
"conflicts": [
|
||||
{
|
||||
"start_line": 1,
|
||||
"end_line": 1,
|
||||
"base_lines": ["line2"],
|
||||
"our_lines": ["line2_ours"],
|
||||
"their_lines": ["line2_theirs"]
|
||||
}
|
||||
],
|
||||
"has_conflicts": true
|
||||
}
|
||||
```
|
||||
|
||||
**Error Response (400 Bad Request):**
|
||||
```json
|
||||
{
|
||||
"error": "Missing required fields: base, ours, theirs"
|
||||
}
|
||||
```
|
||||
|
||||
## Manual Testing with curl
|
||||
|
||||
Basic example:
|
||||
```sh
|
||||
curl -X POST http://localhost:8080/api/merge \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"base": ["hello", "world"],
|
||||
"ours": ["hello", "beautiful world"],
|
||||
"theirs": ["goodbye", "world"]
|
||||
}'
|
||||
```
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### JavaScript/Node.js
|
||||
|
||||
```javascript
|
||||
const axios = require('axios');
|
||||
|
||||
async function merge(base, ours, theirs) {
|
||||
const response = await axios.post('http://localhost:8080/api/merge', {
|
||||
base, ours, theirs
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
// Usage
|
||||
merge(
|
||||
['line1', 'line2'],
|
||||
['line1', 'line2_modified'],
|
||||
['line1', 'line2']
|
||||
).then(result => {
|
||||
console.log('Merged:', result.merged);
|
||||
console.log('Has conflicts:', result.has_conflicts);
|
||||
});
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
def merge(base, ours, theirs, server_url="http://localhost:8080"):
|
||||
response = requests.post(
|
||||
f"{server_url}/api/merge",
|
||||
json={"base": base, "ours": ours, "theirs": theirs}
|
||||
)
|
||||
return response.json()
|
||||
|
||||
# Usage
|
||||
result = merge(
|
||||
base=["line1", "line2"],
|
||||
ours=["line1", "line2_modified"],
|
||||
theirs=["line1", "line2"]
|
||||
)
|
||||
print(f"Merged: {result['merged']}")
|
||||
print(f"Has conflicts: {result['has_conflicts']}")
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type MergeRequest struct {
|
||||
Base []string `json:"base"`
|
||||
Ours []string `json:"ours"`
|
||||
Theirs []string `json:"theirs"`
|
||||
}
|
||||
|
||||
type MergeResponse struct {
|
||||
Merged []string `json:"merged"`
|
||||
Conflicts []Conflict `json:"conflicts"`
|
||||
HasConflicts bool `json:"has_conflicts"`
|
||||
}
|
||||
|
||||
func merge(base, ours, theirs []string) (*MergeResponse, error) {
|
||||
req := MergeRequest{Base: base, Ours: ours, Theirs: theirs}
|
||||
jsonData, _ := json.Marshal(req)
|
||||
|
||||
resp, err := http.Post(
|
||||
"http://localhost:8080/api/merge",
|
||||
"application/json",
|
||||
bytes.NewBuffer(jsonData),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result MergeResponse
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
return &result, nil
|
||||
}
|
||||
```
|
||||
|
||||
## Docker Usage
|
||||
|
||||
If running the server in Docker:
|
||||
|
||||
```sh
|
||||
# Start server
|
||||
docker-compose up -d
|
||||
|
||||
# Test API (from host)
|
||||
curl -X POST http://localhost:8080/api/merge \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"base":["a"],"ours":["b"],"theirs":["c"]}'
|
||||
|
||||
# Check logs
|
||||
docker-compose logs -f
|
||||
```
|
||||
98
backend/examples/api_client.py
Executable file
98
backend/examples/api_client.py
Executable file
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example client for WizardMerge HTTP API
|
||||
Demonstrates how to use the POST /api/merge endpoint
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import sys
|
||||
|
||||
def test_merge(base_lines, ours_lines, theirs_lines, server_url="http://localhost:8080"):
|
||||
"""
|
||||
Test the merge API with given inputs
|
||||
"""
|
||||
endpoint = f"{server_url}/api/merge"
|
||||
|
||||
payload = {
|
||||
"base": base_lines,
|
||||
"ours": ours_lines,
|
||||
"theirs": theirs_lines
|
||||
}
|
||||
|
||||
print(f"Sending merge request to {endpoint}")
|
||||
print(f"Base: {base_lines}")
|
||||
print(f"Ours: {ours_lines}")
|
||||
print(f"Theirs: {theirs_lines}")
|
||||
print()
|
||||
|
||||
try:
|
||||
response = requests.post(endpoint, json=payload)
|
||||
response.raise_for_status()
|
||||
|
||||
result = response.json()
|
||||
|
||||
print("=== Merge Result ===")
|
||||
print(f"Merged lines: {result['merged']}")
|
||||
print(f"Has conflicts: {result['has_conflicts']}")
|
||||
|
||||
if result['conflicts']:
|
||||
print(f"Number of conflicts: {len(result['conflicts'])}")
|
||||
for i, conflict in enumerate(result['conflicts']):
|
||||
print(f"\nConflict {i+1}:")
|
||||
print(f" Lines: {conflict['start_line']}-{conflict['end_line']}")
|
||||
print(f" Base: {conflict['base_lines']}")
|
||||
print(f" Ours: {conflict['our_lines']}")
|
||||
print(f" Theirs: {conflict['their_lines']}")
|
||||
|
||||
return result
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
print(f"ERROR: Could not connect to server at {server_url}")
|
||||
print("Make sure the server is running with: ./wizardmerge-cli")
|
||||
sys.exit(1)
|
||||
except requests.exceptions.HTTPError as e:
|
||||
print(f"ERROR: HTTP {e.response.status_code}")
|
||||
print(e.response.text)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"ERROR: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
print("WizardMerge API Client - Example Usage")
|
||||
print("=" * 50)
|
||||
print()
|
||||
|
||||
# Test 1: No conflicts
|
||||
print("Test 1: No conflicts (non-overlapping changes)")
|
||||
print("-" * 50)
|
||||
test_merge(
|
||||
base_lines=["line1", "line2", "line3"],
|
||||
ours_lines=["line1", "line2_modified", "line3"],
|
||||
theirs_lines=["line1", "line2", "line3_modified"]
|
||||
)
|
||||
print()
|
||||
|
||||
# Test 2: With conflicts
|
||||
print("\nTest 2: With conflicts (overlapping changes)")
|
||||
print("-" * 50)
|
||||
test_merge(
|
||||
base_lines=["line1", "line2", "line3"],
|
||||
ours_lines=["line1", "line2_ours", "line3"],
|
||||
theirs_lines=["line1", "line2_theirs", "line3"]
|
||||
)
|
||||
print()
|
||||
|
||||
# Test 3: Identical changes
|
||||
print("\nTest 3: Identical changes (auto-resolved)")
|
||||
print("-" * 50)
|
||||
test_merge(
|
||||
base_lines=["line1", "line2", "line3"],
|
||||
ours_lines=["line1", "line2_same", "line3"],
|
||||
theirs_lines=["line1", "line2_same", "line3"]
|
||||
)
|
||||
print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
70
backend/examples/test_api.sh
Executable file
70
backend/examples/test_api.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
# Example API calls using curl
|
||||
|
||||
SERVER_URL="http://localhost:8080"
|
||||
|
||||
echo "WizardMerge API - Example curl Commands"
|
||||
echo "========================================"
|
||||
echo
|
||||
|
||||
# Test 1: No conflicts
|
||||
echo "Test 1: No conflicts (non-overlapping changes)"
|
||||
echo "-----------------------------------------------"
|
||||
curl -X POST "${SERVER_URL}/api/merge" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"base": ["line1", "line2", "line3"],
|
||||
"ours": ["line1", "line2_modified", "line3"],
|
||||
"theirs": ["line1", "line2", "line3_modified"]
|
||||
}' | jq '.'
|
||||
echo
|
||||
echo
|
||||
|
||||
# Test 2: With conflicts
|
||||
echo "Test 2: With conflicts (overlapping changes)"
|
||||
echo "---------------------------------------------"
|
||||
curl -X POST "${SERVER_URL}/api/merge" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"base": ["line1", "line2", "line3"],
|
||||
"ours": ["line1", "line2_ours", "line3"],
|
||||
"theirs": ["line1", "line2_theirs", "line3"]
|
||||
}' | jq '.'
|
||||
echo
|
||||
echo
|
||||
|
||||
# Test 3: Identical changes
|
||||
echo "Test 3: Identical changes (auto-resolved)"
|
||||
echo "------------------------------------------"
|
||||
curl -X POST "${SERVER_URL}/api/merge" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"base": ["line1", "line2", "line3"],
|
||||
"ours": ["line1", "line2_same", "line3"],
|
||||
"theirs": ["line1", "line2_same", "line3"]
|
||||
}' | jq '.'
|
||||
echo
|
||||
echo
|
||||
|
||||
# Test 4: Error handling - Missing field
|
||||
echo "Test 4: Error handling - Missing required field"
|
||||
echo "------------------------------------------------"
|
||||
curl -X POST "${SERVER_URL}/api/merge" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"base": ["line1", "line2"],
|
||||
"ours": ["line1", "line2_modified"]
|
||||
}' | jq '.'
|
||||
echo
|
||||
echo
|
||||
|
||||
# Test 5: Error handling - Invalid JSON
|
||||
echo "Test 5: Error handling - Invalid JSON"
|
||||
echo "--------------------------------------"
|
||||
curl -X POST "${SERVER_URL}/api/merge" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d 'not json'
|
||||
echo
|
||||
echo
|
||||
|
||||
echo "Done!"
|
||||
Reference in New Issue
Block a user