Compare commits

..

2 Commits

Author SHA1 Message Date
b6e180f466 Update go.mod, go.sum 2025-10-13 13:15:06 -04:00
8f5f25780e cmd/hopp-generate: Improve command line interface 2025-10-13 13:14:44 -04:00
3 changed files with 69 additions and 19 deletions

View File

@ -1,48 +1,66 @@
package main package main
import "os" import "os"
import "fmt"
import "strings" import "strings"
import "path/filepath" import "path/filepath"
import "git.tebibyte.media/sashakoshka/go-cli"
import "git.tebibyte.media/sashakoshka/goparse" import "git.tebibyte.media/sashakoshka/goparse"
import "git.tebibyte.media/sashakoshka/hopp/generate" import "git.tebibyte.media/sashakoshka/hopp/generate"
func main() { func main() {
name := os.Args[0] flagOutput := cli.NewInputFlag('o', "output", "The output file", "", cli.ValString)
if len(os.Args) != 3 { flagPackageName := cli.NewInputFlag('p', "package-name", "The package name of the file", "", cli.ValString)
fmt.Fprintf(os.Stderr, "Usage: %s SOURCE DESTINATION\n", name) command := cli.New("Compile PDL files to program source code",
flagOutput,
flagPackageName)
command.Syntax = "FILE [OPTIONS]..."
command.ParseOrExit(os.Args)
if len(command.Args) != 1 {
command.Usage()
os.Exit(2) os.Exit(2)
} }
source := os.Args[1] source := command.Args[0]
destination := os.Args[2] destination := flagOutput.Value
if destination == "" {
destination = "protocol.go"
}
input, err := os.Open(source) input, err := os.Open(source)
handleErr(1, err) handleErr(command, 1, err)
defer input.Close() defer input.Close()
protocol, err := generate.ParseReader(source, input) protocol, err := generate.ParseReader(source, input)
handleErr(1, err) handleErr(command, 1, err)
packageName := flagPackageName.Value
if packageName == "" {
absDestination, err := filepath.Abs(destination) absDestination, err := filepath.Abs(destination)
handleErr(1, err) handleErr(command, 1, err)
packageName := cleanPackageName(strings.ReplaceAll( base := filepath.Base(absDestination)
strings.ToLower(filepath.Base(absDestination)), if scrounged, ok := scroungeForPackageName(base); ok {
" ", "_")) packageName = scrounged
destination = filepath.Join(os.Args[2], "generated.go") } else {
packageName = strings.ReplaceAll(
strings.ToLower(base),
" ", "_")
}
}
packageName = cleanPackageName(packageName)
output, err := os.Create(destination) output, err := os.Create(destination)
handleErr(1, err) handleErr(command, 1, err)
generator := generate.Generator { generator := generate.Generator {
Output: output, Output: output,
PackageName: packageName, PackageName: packageName,
} }
_, err = generator.Generate(protocol) _, err = generator.Generate(protocol)
handleErr(1, err) handleErr(command, 1, err)
fmt.Fprintf(os.Stderr, "%s: OK\n", name) command.Println(output, "OK")
} }
func handleErr(code int, err error) { func handleErr(command *cli.Cli, code int, err error) {
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], parse.Format(err)) command.Errorln(parse.Format(err))
os.Exit(code) os.Exit(code)
} }
} }
@ -61,3 +79,32 @@ func cleanPackageName(str string) string {
} }
return string(buffer[:j]) return string(buffer[:j])
} }
func scroungeForPackageName(dir string) (string, bool) {
entries, err := os.ReadDir(dir)
if err != nil { return "", false}
for _, entry := range entries {
if !entry.Type().IsRegular() { continue }
file, err := os.Open(filepath.Join(dir, entry.Name()))
if err != nil { continue }
defer file.Close()
// FIXME: it is entirely possible that the only file will have
// a shitload of doc comments preceeding the package name, and
// those comments are usually huge so this is bad
buffer := [512]byte { }
n, _ := file.Read(buffer[:])
text := string(buffer[:n])
packageIndex := strings.Index(text, "package")
if packageIndex < 0 { continue }
text = text[packageIndex:]
newlineIndex := strings.Index(text, "\n")
if packageIndex > 0 { text = text[:newlineIndex] }
fields := strings.Fields(text)
if len(fields) < 2 { continue }
return fields[1], true
}
return "", false
}

1
go.mod
View File

@ -3,6 +3,7 @@ module git.tebibyte.media/sashakoshka/hopp
go 1.23.0 go 1.23.0
require ( require (
git.tebibyte.media/sashakoshka/go-cli v0.1.3
git.tebibyte.media/sashakoshka/go-util v0.9.1 git.tebibyte.media/sashakoshka/go-util v0.9.1
git.tebibyte.media/sashakoshka/goparse v0.2.0 git.tebibyte.media/sashakoshka/goparse v0.2.0
) )

2
go.sum
View File

@ -1,3 +1,5 @@
git.tebibyte.media/sashakoshka/go-cli v0.1.3 h1:tSkWjyx2JrGu6KotbXWSTKSYGGS1D4O3qwCrRoZuwbs=
git.tebibyte.media/sashakoshka/go-cli v0.1.3/go.mod h1:JFA3wSdRkXxa4iQJWHfe3DokiG7Dh2XUJBzPmuVlbuY=
git.tebibyte.media/sashakoshka/go-util v0.9.1 h1:eGAbLwYhOlh4aq/0w+YnJcxT83yPhXtxnYMzz6K7xGo= git.tebibyte.media/sashakoshka/go-util v0.9.1 h1:eGAbLwYhOlh4aq/0w+YnJcxT83yPhXtxnYMzz6K7xGo=
git.tebibyte.media/sashakoshka/go-util v0.9.1/go.mod h1:0Q1t+PePdx6tFYkRuJNcpM1Mru7wE6X+it1kwuOH+6Y= git.tebibyte.media/sashakoshka/go-util v0.9.1/go.mod h1:0Q1t+PePdx6tFYkRuJNcpM1Mru7wE6X+it1kwuOH+6Y=
git.tebibyte.media/sashakoshka/goparse v0.2.0 h1:uQmKvOCV2AOlCHEDjg9uclZCXQZzq2PxaXfZ1aIMiQI= git.tebibyte.media/sashakoshka/goparse v0.2.0 h1:uQmKvOCV2AOlCHEDjg9uclZCXQZzq2PxaXfZ1aIMiQI=