diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88a0aa56..17399d15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,10 @@ jobs: with: fetch-depth: 0 fetch-tags: true + - name: Setup deno + uses: denoland/setup-deno@v1 + with: + deno-version: v1.x - name: Setup go uses: actions/setup-go@v5 with: diff --git a/internal/command/command_file.go b/internal/command/command_file.go index 88b22a01..c345e2b4 100644 --- a/internal/command/command_file.go +++ b/internal/command/command_file.go @@ -13,10 +13,10 @@ import ( type fileCommand struct { internalCommand + logger *zap.Logger + scriptFile *os.File tempDir string - - logger *zap.Logger } func (c *fileCommand) Start(ctx context.Context) error { @@ -71,11 +71,23 @@ func (c *fileCommand) createTempDir() (err error) { } func (c *fileCommand) createScriptFile() (err error) { - c.scriptFile, err = os.CreateTemp(c.tempDir, "runme-script-*") + pattern := "runme-script-*" + if ext := c.scriptFileExt(); ext != "" { + pattern += "." + ext + } + c.scriptFile, err = os.CreateTemp(c.tempDir, pattern) err = errors.WithMessage(err, "failed to create a temporary file for script execution") return } +func (c *fileCommand) scriptFileExt() string { + cfg := c.ProgramConfig() + if ext := cfg.GetFileExtension(); ext != "" { + return ext + } + return inferFileExtension(cfg.GetLanguageId()) +} + func (c *fileCommand) removeTempDir() error { if c.tempDir == "" { return nil @@ -90,3 +102,30 @@ func (c *fileCommand) writeScript(script string) error { } return errors.WithMessage(c.scriptFile.Close(), "failed to close the temporary file") } + +var fileExtensionByLanguageID = map[string]string{ + "js": "js", + "javascript": "js", + "jsx": "jsx", + "javascriptreact": "jsx", + "tsx": "tsx", + "typescriptreact": "tsx", + "typescript": "ts", + "ts": "ts", + "sh": "sh", + "bash": "sh", + "ksh": "sh", + "zsh": "sh", + "fish": "sh", + "powershell": "ps1", + "cmd": "bat", + "dos": "bat", + "py": "py", + "python": "py", + "ruby": "rb", + "rb": "rb", +} + +func inferFileExtension(languageID string) string { + return fileExtensionByLanguageID[languageID] +} diff --git a/internal/command/command_file_test.go b/internal/command/command_file_test.go index a63d2100..f051b9a2 100644 --- a/internal/command/command_file_test.go +++ b/internal/command/command_file_test.go @@ -40,4 +40,23 @@ func TestFileCommand(t *testing.T) { testExecuteCommand(t, cfg, nil, "test\n", "") }) + + // TypeScript runner requires the file extension to be .ts. + t.Run("TypeScript", func(t *testing.T) { + t.Parallel() + + cfg := &ProgramConfig{ + LanguageId: "ts", + Source: &runnerv2alpha1.ProgramConfig_Script{ + Script: `function print(message: string): void { + console.log(message) +} +print("important message") +`, + }, + Mode: runnerv2alpha1.CommandMode_COMMAND_MODE_FILE, + } + + testExecuteCommand(t, cfg, nil, "important message\n", "") + }) }