diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59c239b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.opencode diff --git a/README.md b/README.md index ba5e5e8..4fde502 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,12 @@ The project is cleanly separated into three packages: go build ./cmd/poiesis ``` +## CLI Options + +- `[file]` - Path to TypeScript file to execute (optional) +- `--print-types` - Print TypeScript type declarations for all registered functions +- `--help` - Show help information + ## Testing ```bash @@ -58,8 +64,9 @@ golangci-lint run ## Usage ```bash -poiesis -poiesis -print-types +poiesis execute [file] # Run TypeScript file +poiesis types # Print TypeScript type declarations +poiesis --help # Show help ``` ## Function System diff --git a/cmd/poiesis/main.go b/cmd/poiesis/main.go index a4adca0..af71dd6 100644 --- a/cmd/poiesis/main.go +++ b/cmd/poiesis/main.go @@ -5,36 +5,64 @@ import ( "fmt" "os" + "github.com/spf13/cobra" "reichard.io/poiesis/internal/runtime" ) -func main() { - // Validate Arguments - if len(os.Args) < 2 { - fmt.Fprintln(os.Stderr, "Usage: poiesis ") - fmt.Fprintln(os.Stderr, " poiesis -print-types") - os.Exit(1) - } - - // Print Types - if os.Args[1] == "-print-types" { - rt, err := runtime.New(context.Background()) +var runCmd = &cobra.Command{ + Use: "execute [file]", + Short: "Transpile and execute TypeScript code", + Long: `Poiesis transpiles TypeScript to JavaScript using esbuild and executes it with QuickJS. +It also provides a builtin system for exposing Go functions to TypeScript.`, + Args: cobra.MaximumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + ctx := context.Background() + rt, err := runtime.New(ctx) if err != nil { - panic(err) + fmt.Fprintf(os.Stderr, "Failed to create runtime: %v\n", err) + os.Exit(1) + } + + if len(args) == 0 { + fmt.Fprintln(os.Stderr, "Usage: poiesis execute [file]") + cmd.Help() + os.Exit(1) + } + + if err := rt.RunFile(args[0]); err != nil { + fmt.Fprintf(os.Stderr, "Failed to run file: %v\n", err) + os.Exit(1) + } + }, +} + +var typesCmd = &cobra.Command{ + Use: "types", + Short: "Print TypeScript type declarations", + Run: func(cmd *cobra.Command, args []string) { + ctx := context.Background() + rt, err := runtime.New(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to create runtime: %v\n", err) + os.Exit(1) } fmt.Println(rt.GetTypeDeclarations()) - return - } + }, +} - // Create Runtime - rt, err := runtime.New(context.Background()) - if err != nil { - panic(err) - } +var rootCmd = &cobra.Command{ + Use: "poiesis", + Short: "TypeScript transpiler and executor", +} - // Run File - filePath := os.Args[1] - if err := rt.RunFile(filePath); err != nil { - panic(err) +func init() { + rootCmd.AddCommand(runCmd) + rootCmd.AddCommand(typesCmd) +} + +func main() { + if err := rootCmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) } } diff --git a/go.mod b/go.mod index 4b96c3e..6117202 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,10 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/cobra v1.10.2 // indirect + github.com/spf13/pflag v1.0.9 // indirect github.com/tetratelabs/wazero v1.9.0 // indirect golang.org/x/sys v0.37.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index f1e663f..9ff65dd 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,24 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/evanw/esbuild v0.27.2 h1:3xBEws9y/JosfewXMM2qIyHAi+xRo8hVx475hVkJfNg= github.com/evanw/esbuild v0.27.2/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= github.com/fastschema/qjs v0.0.6 h1:C45KMmQMd21UwsUAmQHxUxiWOfzwTg1GJW0DA0AbFEE= github.com/fastschema/qjs v0.0.6/go.mod h1:bbg36wxXnx8g0FdKIe5+nCubrQvHa7XEVWqUptjHt/A= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=