{
if projectName == "" {
return fmt.Errorf("project name cannot be empty")
}
moduleName := projectName
projectName = path.Base(moduleName)
projectPath := projectName
if _, err := os.Stat(projectPath); !os.IsNotExist(err) {
return fmt.Errorf("project directory already exists")
}
if err := os.Mkdir(projectPath, 0755); err != nil {
return fmt.Errorf("failed to create project directory: %w", err)
}
err := fs.WalkDir(TemplatesFS, "template", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if path == "template" {
return nil
}
relPath := strings.TrimPrefix(path, "template/")
targetPath := filepath.Join(projectPath, relPath)
if strings.HasSuffix(targetPath, ".tmpl") {
targetPath = strings.TrimSuffix(targetPath, ".tmpl")
}
if d.IsDir() {
return os.MkdirAll(targetPath, 0755)
}
content, err := TemplatesFS.ReadFile(path)
if err != nil {
return err
}
contentStr := string(content)
contentStr = strings.ReplaceAll(contentStr, "{{moduleName}}", moduleName)
contentStr = strings.ReplaceAll(contentStr, "{{projectName}}", projectName)
return os.WriteFile(targetPath, []byte(contentStr), 0644)
})
if err != nil {
return fmt.Errorf("failed to copy template files: %w", err)
}
if err := copyWasmExec(projectPath); err != nil {
return fmt.Errorf("failed to copy wasm_exec.js: %w", err)
}
if err := initGoModule(projectPath, moduleName, skipTidy); err != nil {
return fmt.Errorf("failed to initialize go module: %w", err)
}
fmt.Printf("Project '%s' initialized successfully.\n", projectName)
return nil
}
{
cmd := exec.Command("go", "env", "GOROOT")
output, err := cmd.Output()
if err != nil {
return fmt.Errorf("failed to get GOROOT: %w", err)
}
goRoot := strings.TrimSpace(string(output))
srcPath := filepath.Join(goRoot, "lib", "wasm", "wasm_exec.js")
destPath := filepath.Join(projectDir, "wasm_exec.js")
input, err := os.ReadFile(srcPath)
if err != nil {
return fmt.Errorf("failed to read wasm_exec.js: %w", err)
}
if err := os.WriteFile(destPath, input, 0644); err != nil {
return fmt.Errorf("failed to write wasm_exec.js: %w", err)
}
return nil
}
{
cmd := exec.Command("go", "mod", "init", moduleName)
cmd.Dir = projectPath
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("go mod init failed: %w: %s", err, strings.TrimSpace(string(out)))
}
if !skipTidy {
cmd = exec.Command("go", "mod", "tidy")
cmd.Dir = projectPath
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("go mod tidy failed: %w: %s", err, strings.TrimSpace(string(out)))
}
}
return nil
}
TestInitProjectSuccess verifies project scaffolding.
{
dir := t.TempDir()
oldwd, err := os.Getwd()
if err != nil {
t.Fatalf("Getwd failed: %v", err)
}
defer os.Chdir(oldwd)
if err := os.Chdir(dir); err != nil {
t.Fatalf("Chdir failed: %v", err)
}
if err := InitProject("example.com/testproj", true); err != nil {
t.Fatalf("InitProject failed: %v", err)
}
projDir := filepath.Join(dir, "testproj")
if _, err := os.Stat(filepath.Join(projDir, "go.mod")); err != nil {
t.Fatalf("go.mod not created: %v", err)
}
if _, err := os.Stat(filepath.Join(projDir, "wasm_exec.js")); err != nil {
t.Fatalf("wasm_exec.js not created: %v", err)
}
if _, err := os.Stat(filepath.Join(projDir, "wasm_loader.js")); err != nil {
t.Fatalf("wasm_loader.js not created: %v", err)
}
}
TestInitProjectErrors checks basic error paths.
{
if err := InitProject("", true); err == nil {
t.Fatalf("expected error for empty project name")
}
dir := t.TempDir()
oldwd, _ := os.Getwd()
defer os.Chdir(oldwd)
os.Chdir(dir)
os.Mkdir("exists", 0755)
if err := InitProject("exists", true); err == nil {
t.Fatalf("expected error for existing directory")
}
}
import "embed"
import "fmt"
import "io/fs"
import "os"
import "os/exec"
import "path"
import "path/filepath"
import "strings"
import "os"
import "path/filepath"
import "testing"