add html and server interpreters

these are basic and lack most features.
the server seems to work the best.
the html on the other hand is really rough and doesn't seem to work yet.
but it does build the pages and they have all the shapes and sections we
wanted. More work to come. :)
This commit is contained in:
2025-08-25 00:50:55 -06:00
parent cf3ad736b7
commit d36e1bfd86
5 changed files with 681 additions and 6 deletions

View File

@ -464,3 +464,111 @@ func generateHTML(inputFile, outputDir string) error {
fmt.Printf("Successfully generated %d HTML file(s)\n", len(htmlFiles))
return nil
}
func serveCmd() *cli.Command {
return &cli.Command{
Name: "serve",
Usage: "Generate and run a simple HTTP server from a Masonry file",
Description: "This command parses a Masonry file and generates a simple Go HTTP server with in-memory database.",
Category: "development",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "file",
Usage: "Path to the Masonry file to interpret",
Required: true,
Aliases: []string{"f"},
},
&cli.StringFlag{
Name: "output",
Usage: "Output file for the generated server code",
Value: "server.go",
Aliases: []string{"o"},
},
&cli.BoolFlag{
Name: "run",
Usage: "Run the server after generating it",
Value: false,
Aliases: []string{"r"},
},
},
Action: func(c *cli.Context) error {
masonryFile := c.String("file")
outputFile := c.String("output")
shouldRun := c.Bool("run")
fmt.Printf("Parsing Masonry file: %s\n", masonryFile)
// Read the Masonry file
content, err := os.ReadFile(masonryFile)
if err != nil {
return fmt.Errorf("error reading Masonry file: %w", err)
}
// Parse the Masonry file
parser, err := participle.Build[lang.AST](
participle.Unquote("String"),
)
if err != nil {
return fmt.Errorf("error building parser: %w", err)
}
ast, err := parser.ParseString("", string(content))
if err != nil {
return fmt.Errorf("error parsing Masonry file: %w", err)
}
// Generate server code using the server interpreter
serverInterpreter := interpreter.NewServerInterpreter()
serverCode, err := serverInterpreter.Interpret(*ast)
if err != nil {
return fmt.Errorf("error interpreting Masonry file: %w", err)
}
// Write the generated server code to the output file
err = os.WriteFile(outputFile, []byte(serverCode), 0644)
if err != nil {
return fmt.Errorf("error writing server code to file: %w", err)
}
fmt.Printf("Server code generated successfully: %s\n", outputFile)
if shouldRun {
fmt.Println("Installing dependencies...")
// Initialize go module if it doesn't exist
if _, err := os.Stat("go.mod"); os.IsNotExist(err) {
cmd := exec.Command("go", "mod", "init", "masonry-server")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("error initializing go module: %w", err)
}
}
// Install required dependencies
dependencies := []string{
"github.com/google/uuid",
"github.com/gorilla/mux",
}
for _, dep := range dependencies {
fmt.Printf("Installing %s...\n", dep)
cmd := exec.Command("go", "get", dep)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("error installing dependency %s: %w", dep, err)
}
}
fmt.Printf("Running server from %s...\n", outputFile)
cmd := exec.Command("go", "run", outputFile)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
return nil
},
}
}