diff --git a/modules/compiler_V2/compiler2.go b/modules/compiler_V2/compiler2.go deleted file mode 100644 index bf28ce0dc1bb0916c7afd380c2f98e7da6e8f9a1..0000000000000000000000000000000000000000 --- a/modules/compiler_V2/compiler2.go +++ /dev/null @@ -1,83 +0,0 @@ -package compiler_V2 - -import ( - "os" - "os/exec" -) - -type LanguageData struct { - Name Language - FileSuffix string // Like .go or .rs -} - -type Language string - -const ( - Go Language = "go" - Rust Language = "rust" -) - -type OS string - -const ( - Windows OS = "windows" - Linux OS = "linux" - MacOS OS = "darwin" -) - -type SourceCode string -type Dependencies []string - -type Compiler struct { - OS OS - Language Language - Dependencies Dependencies -} - -type GoCompilerCmd struct { - cmd string -} - -type ICompiler interface { - CheckCompileErrors(srcCode []byte) ([]byte, error) -} - -//func NewCompiler(os OS, language Language) ICompiler { -// switch language { -// case Go: -// return NewGoCompiler(os) -// case Rust: -// //return RustCompiler{}.New(os) -// panic("Rust compiler not implemented") -// default: -// return nil -// } -//} - -func MakeCommand(OS OS, cmd string) *exec.Cmd { - switch OS { - case Windows: - return exec.Command("cmd", "/c", cmd) - case Linux, MacOS: - return exec.Command("bash", "-c", cmd) - default: - panic("Unsupported OS") - } -} - -// SetupTempFolders creates the temp output directory for compiled files, panics if it fails -func SetupTempFolders(tempOutputDir string) { - // 0777 are the permissions for the directory, everyone can read, write and execute - err := os.MkdirAll(tempOutputDir, os.ModePerm) - if err != nil { - panic("Error creating temp output directory:\n\n" + err.Error()) - } -} - -// RemoveTempFolders removes the temp output directory for compiled files, panics if it fails -func RemoveTempFolders(tempOutputDir string) { - err := os.RemoveAll(tempOutputDir) - if err != nil { - panic("Error removing temp output directory:\n\n" + err.Error()) - } -} diff --git a/modules/compiler_V2/compilers.go b/modules/compiler_V2/compilers.go new file mode 100644 index 0000000000000000000000000000000000000000..b42f93f7321a5ea3e2562c52bc1be5480289fb17 --- /dev/null +++ b/modules/compiler_V2/compilers.go @@ -0,0 +1 @@ +package compiler_V2 diff --git a/modules/compiler_V2/consts/consts.go b/modules/compiler_V2/consts/consts.go new file mode 100644 index 0000000000000000000000000000000000000000..6ad098a82f4014a73058d285aa93210cdc73dcc2 --- /dev/null +++ b/modules/compiler_V2/consts/consts.go @@ -0,0 +1,3 @@ +package consts + +const TempOutputDir = "tempOutput/" diff --git a/modules/compiler_V2/data/OS.go b/modules/compiler_V2/data/OS.go new file mode 100644 index 0000000000000000000000000000000000000000..b1f2338c5f9b4f3821bb76c14ad8bafca33259eb --- /dev/null +++ b/modules/compiler_V2/data/OS.go @@ -0,0 +1,9 @@ +package data + +type OS string + +const ( + Windows OS = "windows" + Linux OS = "linux" + MacOS OS = "darwin" +) diff --git a/modules/compiler_V2/data/language.go b/modules/compiler_V2/data/language.go new file mode 100644 index 0000000000000000000000000000000000000000..07fb9da03984f28a953ba1ef9af535483281759d --- /dev/null +++ b/modules/compiler_V2/data/language.go @@ -0,0 +1,8 @@ +package data + +type Language string + +const ( + Go Language = "go" + Rust Language = "rust" +) diff --git a/modules/compiler_V2/go-compiler2/go_compiler.go b/modules/compiler_V2/go-compiler2/go_compiler.go index 4494e22eb347ea865a383f73a12b100f555ec143..ead1ae18f53b4db9f9bac06e62503e81bb994078 100644 --- a/modules/compiler_V2/go-compiler2/go_compiler.go +++ b/modules/compiler_V2/go-compiler2/go_compiler.go @@ -1,35 +1,33 @@ package go_compiler2 import ( - c2 "compiler_V2" + "compiler_V2/consts" + "compiler_V2/data" + "compiler_V2/utils" "os" ) +const fileName = "main.go" + type GoCompiler struct { - c2.Compiler + OS data.OS + Language data.Language } -const TempOutputDir = "tempOutput/" -const fileName = "main.go" - -func NewGoCompiler(OS c2.OS) *GoCompiler { +func NewGoCompiler(OS data.OS) *GoCompiler { return &GoCompiler{ - Compiler: c2.Compiler{ - OS: OS, - Language: c2.Go, - Dependencies: nil, - }, + OS: OS, + Language: data.Go, } } func (gb *GoCompiler) CheckCompileErrors(srcCode []byte) ([]byte, error) { // Make temp folders - - c2.SetupTempFolders(TempOutputDir) - defer c2.RemoveTempFolders(TempOutputDir) + utils.SetupTempFolders(consts.TempOutputDir) + defer utils.RemoveTempFolders(consts.TempOutputDir) // Write code to file - err := os.WriteFile(TempOutputDir+fileName, srcCode, 0644) + err := os.WriteFile(consts.TempOutputDir+fileName, srcCode, 0644) if err != nil { return nil, err } @@ -40,7 +38,7 @@ func (gb *GoCompiler) CheckCompileErrors(srcCode []byte) ([]byte, error) { cmdString += " && go build -o main " + fileName //cmdSlice := strings.Fields(cmdString) - cmd := c2.MakeCommand(gb.OS, cmdString) - cmd.Dir = TempOutputDir + cmd := utils.MakeCommand(gb.OS, cmdString) + cmd.Dir = consts.TempOutputDir return cmd.CombinedOutput() } diff --git a/modules/compiler_V2/go-compiler2/go_compiler_test.go b/modules/compiler_V2/go-compiler2/go_compiler_test.go index 3d6c57ffac6fe027ef6ae821ca50517b09e1e89e..ab38ecc663ba2c6610ce9e66277fdf99380e2b25 100644 --- a/modules/compiler_V2/go-compiler2/go_compiler_test.go +++ b/modules/compiler_V2/go-compiler2/go_compiler_test.go @@ -1,7 +1,7 @@ package go_compiler2 import ( - c2 "compiler_V2" + "compiler_V2/data" "os" "testing" ) @@ -35,10 +35,10 @@ func TestCompileStringToGo(t *testing.T) { // Read the code from the file code, err := os.ReadFile(test.filename) - output, err := NewGoCompiler(c2.Windows).CheckCompileErrors(code) + output, err := NewGoCompiler(data.Windows).CheckCompileErrors(code) if err != nil && test.shouldCompile { - t.Errorf("Expected the code to compile, but got an error: %v", err) + t.Errorf("Expected the code to compile, but got an output: %v \n error: %v", string(output), err) } else if err == nil && !test.shouldCompile { t.Errorf("Expected the code to not compile, but got no error") } diff --git a/modules/compiler_V2/rust-compiler2/rust_compiler.go b/modules/compiler_V2/rust-compiler2/rust_compiler.go new file mode 100644 index 0000000000000000000000000000000000000000..52f18b4999ce26942d4d5279e9f18f2f313808a4 --- /dev/null +++ b/modules/compiler_V2/rust-compiler2/rust_compiler.go @@ -0,0 +1,60 @@ +package rust_compiler2 + +import ( + "compiler_V2/consts" + "compiler_V2/data" + "compiler_V2/utils" + "os" + "strings" +) + +const fileName = "main.rs" + +type RustCompiler struct { + OS data.OS + Language data.Language +} + +func NewRustCompiler(OS data.OS) *RustCompiler { + return &RustCompiler{ + OS: OS, + Language: data.Rust, + } +} + +func (gb *RustCompiler) CheckCompileErrors(srcCode []byte, dependencies ...string) ([]byte, error) { + // Make temp folders + utils.SetupTempFolders(consts.TempOutputDir) + defer utils.RemoveTempFolders(consts.TempOutputDir) + + // Init cargo + if err := initCargo(gb.OS); err != nil { + return nil, err + } + + // Write code to file + if err := os.WriteFile(consts.TempOutputDir+"src/"+fileName, srcCode, 0644); err != nil { + return nil, err + } + + cmdString := "" + // Add dependencies + if dependencies != nil { + cmdString = "cargo add " + strings.Join(dependencies, " ") + " &&" + } + + // Run go build + cmdString += " cargo check" + + //cmdSlice := strings.Fields(cmdString) + cmd := utils.MakeCommand(gb.OS, cmdString) + cmd.Dir = consts.TempOutputDir + return cmd.CombinedOutput() +} + +func initCargo(OS data.OS) error { + // Init cargo + cmd := utils.MakeCommand(OS, "cargo init --bin") + cmd.Dir = consts.TempOutputDir + return cmd.Run() +} diff --git a/modules/compiler_V2/rust-compiler2/rust_compiler_test.go b/modules/compiler_V2/rust-compiler2/rust_compiler_test.go new file mode 100644 index 0000000000000000000000000000000000000000..87533db8b1afc9b08692d11eadae8d244ede247a --- /dev/null +++ b/modules/compiler_V2/rust-compiler2/rust_compiler_test.go @@ -0,0 +1,51 @@ +package rust_compiler2 + +import ( + "compiler_V2/data" + "os" + "testing" +) + +func TestCompileStringToRust(t *testing.T) { + + tests := []struct { + filename string + shouldCompile bool + dependencies []string + }{ + { + filename: "should_compile", + shouldCompile: true, + dependencies: nil, + }, + { + filename: "should_not_compile", + shouldCompile: false, + dependencies: nil, + }, + { + filename: "should_compile_with_dependencies", + shouldCompile: true, + dependencies: []string{"rand", "colored"}, + }, + } + + for _, test := range tests { + t.Run(test.filename, func(t *testing.T) { + // Read the code from the file + code, err := os.ReadFile(test.filename) + + output, err := NewRustCompiler(data.Windows).CheckCompileErrors(code, test.dependencies...) + + if err != nil && test.shouldCompile { + t.Errorf("Expected the code to compile, but got an output: %v \n error: %v", string(output), err) + } else if err == nil && !test.shouldCompile { + t.Errorf("Expected the code to not compile, but got no error") + } + // Check if the output is empty when the code shouldn't compile + if output == nil && !test.shouldCompile { + t.Errorf("Expected compiler error output, but got none") + } + }) + } +} diff --git a/modules/compiler_V2/rust-compiler2/should_compile b/modules/compiler_V2/rust-compiler2/should_compile new file mode 100644 index 0000000000000000000000000000000000000000..19e7b9497a7a8e803bf82f823e5c81746a21a2a6 --- /dev/null +++ b/modules/compiler_V2/rust-compiler2/should_compile @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, Should Compile :)"); +} \ No newline at end of file diff --git a/modules/compiler_V2/rust-compiler2/should_compile_with_dependencies b/modules/compiler_V2/rust-compiler2/should_compile_with_dependencies new file mode 100644 index 0000000000000000000000000000000000000000..5a39cdaf505bdaedeb67a40cc5f2adab1af92233 --- /dev/null +++ b/modules/compiler_V2/rust-compiler2/should_compile_with_dependencies @@ -0,0 +1,13 @@ +use rand::Rng; // Import the Rng trait from the rand crate +use colored::*; // Import colored for terminal text coloring + +fn main() { + // Create a random number generator + let mut rng = rand::thread_rng(); + + // Generate a random number between 1 and 100 + let random_number = rng.gen_range(1..=100); // Inclusive range + + // Print the random number in green + println!("Random number between 1 and 100: {}", random_number.to_string().green()); +} \ No newline at end of file diff --git a/modules/compiler_V2/rust-compiler2/should_not_compile b/modules/compiler_V2/rust-compiler2/should_not_compile new file mode 100644 index 0000000000000000000000000000000000000000..70a13aaa3ebfc5a31dd8134f3c0411f171f35378 --- /dev/null +++ b/modules/compiler_V2/rust-compiler2/should_not_compile @@ -0,0 +1,3 @@ +fn main() + println!("Hello, Should Not Compile :(") +} \ No newline at end of file diff --git a/modules/compiler_V2/utils/make_command.go b/modules/compiler_V2/utils/make_command.go new file mode 100644 index 0000000000000000000000000000000000000000..cffa76c6501efc965d13d64e3ecb7b492080939f --- /dev/null +++ b/modules/compiler_V2/utils/make_command.go @@ -0,0 +1,17 @@ +package utils + +import ( + "compiler_V2/data" + "os/exec" +) + +func MakeCommand(OS data.OS, cmd string) *exec.Cmd { + switch OS { + case data.Windows: + return exec.Command("cmd", "/c", cmd) + case data.Linux, data.MacOS: + return exec.Command("bash", "-c", cmd) + default: + panic("Unsupported OS") + } +} diff --git a/modules/compiler_V2/utils/setup.go b/modules/compiler_V2/utils/setup.go new file mode 100644 index 0000000000000000000000000000000000000000..c7e44cddd67552a2e9374dd8547960c96ba05292 --- /dev/null +++ b/modules/compiler_V2/utils/setup.go @@ -0,0 +1,20 @@ +package utils + +import "os" + +// SetupTempFolders creates the temp output directory for compiled files, panics if it fails +func SetupTempFolders(tempOutputDir string) { + // 0777 are the permissions for the directory, everyone can read, write and execute + err := os.MkdirAll(tempOutputDir, os.ModePerm) + if err != nil { + panic("Error creating temp output directory:\n\n" + err.Error()) + } +} + +// RemoveTempFolders removes the temp output directory for compiled files, panics if it fails +func RemoveTempFolders(tempOutputDir string) { + err := os.RemoveAll(tempOutputDir) + if err != nil { + panic("Error removing temp output directory:\n\n" + err.Error()) + } +}