Skip to content

Commit d7fdfeb

Browse files
committed
Implement external package stub mode with persistent stubs
- Changed stub generation directory from vendor/ to external_stubs/ to avoid Go vendor conflicts - Modified stub generator to not overwrite existing stub implementations - Added test configuration support via .go2rust.toml files - Updated test script to read config and pass --external-packages flag - Implemented working decimal stub for external_simple test - Test auto-promoted from XFAIL to passing The stub mode now properly: 1. Generates stub files in external_stubs/ directory on first run 2. Preserves manual stub implementations on subsequent runs 3. Allows tests to specify their external package strategy via config file Signed-off-by: Tyler Laprade <[email protected]>
1 parent 045b0c5 commit d7fdfeb

File tree

18 files changed

+116
-2369
lines changed

18 files changed

+116
-2369
lines changed

go/external_packages.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@ func (h *ExternalPackageHandler) updateCargoWorkspace() error {
108108
// Add external packages as workspace members
109109
for pkg := range h.packageMapping {
110110
crateName := h.packageMapping[pkg]
111-
workspaceSection += fmt.Sprintf(" \"vendor/%s\",\n", crateName)
111+
workspaceSection += fmt.Sprintf(" \"external_stubs/%s\",\n", crateName)
112112
}
113113
workspaceSection += "]\n\n"
114114

115115
// Add dependencies section for external packages
116116
depsSection := "[dependencies]\n"
117117
for pkg := range h.packageMapping {
118118
crateName := h.packageMapping[pkg]
119-
depsSection += fmt.Sprintf("%s = { path = \"vendor/%s\" }\n", crateName, crateName)
119+
depsSection += fmt.Sprintf("%s = { path = \"external_stubs/%s\" }\n", crateName, crateName)
120120
}
121121

122122
// Combine workspace section with existing package configuration

go/project.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (pg *ProjectGenerator) generateInternal(skipExternalHandling bool) error {
179179
if err != nil {
180180
// This is expected with stubs - external types won't be available
181181
fmt.Fprintf(os.Stderr, "Note: Type checking incomplete (external packages are stubs): %v\n", err)
182-
fmt.Fprintf(os.Stderr, "You will need to implement the stub packages in vendor/\n")
182+
fmt.Fprintf(os.Stderr, "You will need to implement the stub packages in external_stubs/\n")
183183
}
184184
pg.typeInfo = typeInfo
185185
SetTypeInfo(typeInfo)
@@ -440,7 +440,7 @@ path = "main.rs"
440440
if len(pg.packageMapping) > 0 {
441441
workspaceSection := "\n[workspace]\nmembers = [\n \".\",\n"
442442
for _, crateName := range pg.packageMapping {
443-
workspaceSection += fmt.Sprintf(" \"vendor/%s\",\n", crateName)
443+
workspaceSection += fmt.Sprintf(" \"external_stubs/%s\",\n", crateName)
444444
}
445445
workspaceSection += "]\n"
446446
cargoContent = workspaceSection + "\n" + cargoContent
@@ -454,7 +454,7 @@ path = "main.rs"
454454
}
455455
// Add external package dependencies
456456
for _, crateName := range pg.packageMapping {
457-
cargoContent += fmt.Sprintf("%s = { path = \"vendor/%s\" }\n", crateName, crateName)
457+
cargoContent += fmt.Sprintf("%s = { path = \"external_stubs/%s\" }\n", crateName, crateName)
458458
}
459459
}
460460

go/stub_generator.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ func (sg *StubGenerator) generateStub(importPath, pkgName string) error {
7171
crateName := sg.goPathToRustCrate(importPath)
7272
sg.packageMapping[importPath] = crateName
7373

74-
// Create vendor directory
75-
vendorDir := filepath.Join(sg.projectPath, "vendor")
74+
// Create external_stubs directory
75+
vendorDir := filepath.Join(sg.projectPath, "external_stubs")
7676
if err := os.MkdirAll(vendorDir, 0755); err != nil {
77-
return fmt.Errorf("failed to create vendor directory: %v", err)
77+
return fmt.Errorf("failed to create external_stubs directory: %v", err)
7878
}
7979

8080
// Create package directory
@@ -83,11 +83,16 @@ func (sg *StubGenerator) generateStub(importPath, pkgName string) error {
8383
return fmt.Errorf("failed to create package directory: %v", err)
8484
}
8585

86-
// Generate lib.rs with TODO comments
86+
// Generate lib.rs with TODO comments (only if it doesn't exist)
8787
libRsPath := filepath.Join(pkgDir, "lib.rs")
88-
libRsContent := sg.generateLibRsContent(importPath, pkgName)
89-
if err := os.WriteFile(libRsPath, []byte(libRsContent), 0644); err != nil {
90-
return fmt.Errorf("failed to write lib.rs: %v", err)
88+
if _, err := os.Stat(libRsPath); os.IsNotExist(err) {
89+
libRsContent := sg.generateLibRsContent(importPath, pkgName)
90+
if err := os.WriteFile(libRsPath, []byte(libRsContent), 0644); err != nil {
91+
return fmt.Errorf("failed to write lib.rs: %v", err)
92+
}
93+
fmt.Fprintf(os.Stderr, "Generated NEW stub for %s at external_stubs/%s/\n", importPath, crateName)
94+
} else {
95+
fmt.Fprintf(os.Stderr, "Using existing stub for %s at external_stubs/%s/\n", importPath, crateName)
9196
}
9297

9398
// Generate Cargo.toml
@@ -110,7 +115,6 @@ path = "lib.rs"
110115
}
111116

112117
sg.generatedStubs[importPath] = true
113-
fmt.Fprintf(os.Stderr, "Generated stub for %s at vendor/%s/\n", importPath, crateName)
114118
return nil
115119
}
116120

tests.bats

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,22 @@ run_transpile_and_compare() {
7878
local test_dir="$1"
7979
local go_output="$2"
8080

81+
# Check for test-specific configuration
82+
local external_mode=""
83+
if [ -f "$test_dir/.go2rust.toml" ]; then
84+
# Simple parsing - just look for external_packages line
85+
external_mode=$(grep "^external_packages" "$test_dir/.go2rust.toml" | cut -d'"' -f2)
86+
fi
87+
88+
# Build transpile command with appropriate flags
89+
local transpile_cmd="./go2rust"
90+
if [ -n "$external_mode" ]; then
91+
transpile_cmd="$transpile_cmd --external-packages=$external_mode"
92+
fi
93+
transpile_cmd="$transpile_cmd \"$test_dir\""
94+
8195
# Transpile to Rust
82-
transpile_output=$(./go2rust "$test_dir" 2>&1)
96+
transpile_output=$(eval $transpile_cmd 2>&1)
8397
if [ $? -ne 0 ]; then
8498
echo "Transpilation failed:"
8599
echo "$transpile_output" | sed "s/^/ /"
@@ -307,6 +321,10 @@ run_xfail_test() {
307321
run_test "tests/error_simple"
308322
}
309323

324+
@test "external_simple" {
325+
run_test "tests/external_simple"
326+
}
327+
310328
@test "fmt_println" {
311329
run_test "tests/fmt_println"
312330
}
@@ -567,10 +585,6 @@ run_xfail_test() {
567585
run_xfail_test "tests/XFAIL/external_packages"
568586
}
569587

570-
@test "XFAIL: external_simple" {
571-
run_xfail_test "tests/XFAIL/external_simple"
572-
}
573-
574588
@test "XFAIL: fallthrough_switch" {
575589
run_xfail_test "tests/XFAIL/fallthrough_switch"
576590
}

tests/XFAIL/external_simple/main.rs

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)