diff --git a/cmd/rbxcompiler/rbxcompiler.go b/cmd/rbxcompiler/rbxcompiler.go index b2c301a..793966d 100644 --- a/cmd/rbxcompiler/rbxcompiler.go +++ b/cmd/rbxcompiler/rbxcompiler.go @@ -9,7 +9,7 @@ import ( "os" ) -var isModel = flag.Bool("model", false, "If the target is a model.") +var script = flag.Bool("script", false, "If the target is a script.") var doUpload = flag.Bool("upload", false, "If the model should be uploaded.") var output = flag.String("output", "d", "Output path.") var input = flag.String("input", "", "Input path.") @@ -27,10 +27,18 @@ func build() { settings.Writer = buffer } - if err := rbxbuilder.BuildPlace(settings); err != nil { - fmt.Println("Failed to start build place.") - os.Exit(1) - return + if *script { + if err := rbxbuilder.BuildScript(settings); err != nil { + fmt.Println("Failed to build script.") + os.Exit(1) + return + } + } else { + if err := rbxbuilder.BuildPlace(settings); err != nil { + fmt.Println("Failed to build place.") + os.Exit(1) + return + } } if *doUpload { @@ -61,7 +69,7 @@ func build() { } func generate() { - if *isModel { + if *script { fmt.Println("Model not supported for generation.") os.Exit(2) } diff --git a/internal/rbxbuilder/build_script.lua.go b/internal/rbxbuilder/build_script.lua.go new file mode 100644 index 0000000..c29710c --- /dev/null +++ b/internal/rbxbuilder/build_script.lua.go @@ -0,0 +1,133 @@ +package rbxbuilder + +import ( + "ci.itzana.me/itzaname/rbxfile" + "ci.itzana.me/itzaname/rbxfile/xml" + "fmt" + "os" + "path/filepath" + "sort" + "strings" +) + +type ScriptBuilder struct { + Options *BuildSettings + root *rbxfile.Root +} + +func (b *ScriptBuilder) loadScript(path string) error { + scriptName := strings.TrimSuffix(filepath.Base(path), ".lua") + scriptFilePath := strings.TrimPrefix(path, "/MainModule") + parentPath := filepath.Dir(path) + parentName := filepath.Base(parentPath) + basePath := strings.TrimSuffix(strings.TrimSuffix(path, parentName+string(os.PathSeparator)+filepath.Base(path)), seperator) + if basePath == "" { + basePath = parentPath + } + + if scriptFilePath == "/main.lua" { + script := loadScript("MainModule", "ModuleScript", b.Options.Source+scriptFilePath) + if script != nil { + b.root.Instances = append(b.root.Instances, script) + } else { + return fmt.Errorf("failed to load script: %s", scriptFilePath) + } + return nil + } + + parentInstance := instanceFromScriptPath(b.root, parentPath) + parentBaseInstance := instanceFromScriptPath(b.root, basePath) + if parentBaseInstance == nil { + return fmt.Errorf("parent and base instance doesn't exist: %s %s", parentPath, basePath) + } + if parentInstance == nil { + path := strings.TrimPrefix(parentPath+seperator+parentName+".lua", "/MainModule") + script := loadScript(parentName, "ModuleScript", b.Options.Source+path) + if script != nil { + if err := parentBaseInstance.AddChild(script); err != nil { + return err + } + parentInstance = script + } else { + folder := generateFolder(parentName) + if err := parentBaseInstance.AddChild(folder); err != nil { + return err + } + parentInstance = folder + } + } + + if scriptName == parentName { + return nil + } + + // Load normal scripts + script := loadScript(scriptName, "ModuleScript", b.Options.Source+scriptFilePath) + if script != nil { + if err := parentInstance.AddChild(script); err != nil { + return err + } + } else { + return fmt.Errorf("failed to load script: %s", scriptFilePath) + } + + return nil +} + +func (b *ScriptBuilder) scriptTree() ([]string, error) { + var filelist []string + err := filepath.Walk(b.Options.Source, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + if filepath.Ext(path) == ".lua" { + filelist = append(filelist, "/MainModule"+strings.TrimPrefix(path, b.Options.Source)) + } + } + return nil + }) + + sort.Slice(filelist, func(i, j int) bool { + return strings.Count(filelist[i], string(os.PathSeparator)) < strings.Count(filelist[j], string(os.PathSeparator)) + }) + + return filelist, err + +} + +func (b *ScriptBuilder) createScripts() error { + tree, err := b.scriptTree() + if err != nil { + return err + } + + for i := 0; i < len(tree); i++ { + if err := b.loadScript(tree[i]); err != nil { + return err + } + } + + return nil +} + +func (b ScriptBuilder) Build() error { + b.root = rbxfile.NewRoot() + + if err := b.createScripts(); err != nil { + fmt.Println(err) + return err + } + + if b.Options.Writer != nil { + return xml.Serialize(b.Options.Writer, nil, b.root) + } + + file, err := os.OpenFile(b.Options.Output, os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return fmt.Errorf("failed to open output file") + } + defer file.Close() + + return xml.Serialize(file, nil, b.root) +} diff --git a/internal/rbxbuilder/rbxbuilder.go b/internal/rbxbuilder/rbxbuilder.go index bd62911..d7e025a 100644 --- a/internal/rbxbuilder/rbxbuilder.go +++ b/internal/rbxbuilder/rbxbuilder.go @@ -39,3 +39,9 @@ func BuildPlace(options *BuildSettings) error { Options: options, }.Build() } + +func BuildScript(options *BuildSettings) error { + return ScriptBuilder{ + Options: options, + }.Build() +}