fix(test): convert dos crlf to lf

Ayman Bagabas created

Change summary

server/hooks/hooks.go                     |  1 
server/server.go                          |  7 +++++
server/utils/utils.go                     |  8 ++--
testscript/script_test.go                 | 35 +++++++++++++++---------
testscript/testdata/mirror.txtar          |  4 +-
testscript/testdata/repo-create.txtar     |  4 +-
testscript/testdata/repo-import.txt       |  4 +-
testscript/testdata/set-username.txtar    |  4 +-
testscript/testdata/user_management.txtar |  4 +-
9 files changed, 44 insertions(+), 27 deletions(-)

Detailed changes

server/hooks/hooks.go 🔗

@@ -31,6 +31,7 @@ const (
 // This function should be called by the backend when a repository is created.
 // TODO: support context.
 func GenerateHooks(_ context.Context, cfg *config.Config, repo string) error {
+	// TODO: support git hook tests.
 	if flag.Lookup("test.v") != nil {
 		log.WithPrefix("backend.hooks").Warn("refusing to set up hooks when in test")
 		return nil

server/server.go 🔗

@@ -4,6 +4,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"io"
 	"net/http"
 
 	"github.com/charmbracelet/log"
@@ -158,6 +159,9 @@ func (s *Server) Shutdown(ctx context.Context) error {
 		s.Cron.Stop()
 		return nil
 	})
+	if closer, ok := s.Backend.(io.Closer); ok {
+		defer closer.Close() // nolint: errcheck
+	}
 	return errg.Wait()
 }
 
@@ -172,5 +176,8 @@ func (s *Server) Close() error {
 		s.Cron.Stop()
 		return nil
 	})
+	if closer, ok := s.Backend.(io.Closer); ok {
+		defer closer.Close() // nolint: errcheck
+	}
 	return errg.Wait()
 }

server/utils/utils.go 🔗

@@ -2,7 +2,7 @@ package utils
 
 import (
 	"fmt"
-	"path/filepath"
+	"path"
 	"strings"
 	"unicode"
 )
@@ -10,7 +10,9 @@ import (
 // SanitizeRepo returns a sanitized version of the given repository name.
 func SanitizeRepo(repo string) string {
 	repo = strings.TrimPrefix(repo, "/")
-	repo = filepath.Clean(repo)
+	// We're using path instead of filepath here because this is not OS dependent
+	// looking at you Windows
+	repo = path.Clean(repo)
 	repo = strings.TrimSuffix(repo, ".git")
 	return repo
 }
@@ -40,8 +42,6 @@ func ValidateRepo(repo string) error {
 		return fmt.Errorf("repo cannot be empty")
 	}
 
-	fmt.Println("ACTUAL REPO NAME IS", repo)
-
 	for _, r := range repo {
 		if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '-' && r != '_' && r != '.' && r != '/' {
 			fmt.Println("INVALID CHAR", r, string(r))

testscript/script_test.go 🔗

@@ -8,6 +8,7 @@ import (
 	"net"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"sync"
 	"testing"
@@ -47,7 +48,7 @@ func TestScript(t *testing.T) {
 			"soft":     cmdSoft(admin1.Signer()),
 			"git":      cmdGit(key),
 			"mkreadme": cmdMkReadme,
-			"unix2dos": cmdUnix2Dos,
+			"dos2unix": cmdDos2Unix,
 		},
 		Setup: func(e *testscript.Env) error {
 			sshPort := test.RandomPort()
@@ -153,14 +154,13 @@ func cmdSoft(key ssh.Signer) func(ts *testscript.TestScript, neg bool, args []st
 	}
 }
 
-func cmdUnix2Dos(ts *testscript.TestScript, neg bool, args []string) {
-	// now this should not be needed indeed
-	return
+// P.S. Windows sucks!
+func cmdDos2Unix(ts *testscript.TestScript, neg bool, args []string) {
 	if neg {
-		ts.Fatalf("unsupported: ! unix2dos")
+		ts.Fatalf("unsupported: ! dos2unix")
 	}
 	if len(args) < 1 {
-		ts.Fatalf("usage: unix2dos paths...")
+		ts.Fatalf("usage: dos2unix paths...")
 	}
 	for _, arg := range args {
 		filename := ts.MkAbs(arg)
@@ -169,11 +169,8 @@ func cmdUnix2Dos(ts *testscript.TestScript, neg bool, args []string) {
 			ts.Fatalf("%s: %v", filename, err)
 		}
 
-		// First ensure we don't have any `\r\n` there already then replace all
-		// `\n` with `\r\n`.
-		// This should prevent creating `\r\r\n`.
+		// Replace all '\r\n' with '\n'.
 		data = bytes.ReplaceAll(data, []byte{'\r', '\n'}, []byte{'\n'})
-		data = bytes.ReplaceAll(data, []byte{'\n'}, []byte{'\r', '\n'})
 
 		if err := os.WriteFile(filename, data, 0o644); err != nil {
 			ts.Fatalf("%s: %v", filename, err)
@@ -184,13 +181,25 @@ func cmdUnix2Dos(ts *testscript.TestScript, neg bool, args []string) {
 func cmdGit(key string) func(ts *testscript.TestScript, neg bool, args []string) {
 	return func(ts *testscript.TestScript, neg bool, args []string) {
 		sshArgs := []string{
-			"-F", "/dev/null",
 			"-o", "StrictHostKeyChecking=no",
-			"-o", "UserKnownHostsFile=/dev/null",
 			"-o", "IdentityAgent=none",
 			"-o", "IdentitiesOnly=yes",
 			"-o", "ServerAliveInterval=60",
-			"-i", key,
+			// Escape the key path for Windows.
+			"-i", strings.ReplaceAll(key, `\`, `\\`),
+		}
+		// Windows null device
+		// https://stackoverflow.com/a/36746090/10913628
+		if runtime.GOOS == "windows" {
+			sshArgs = append(sshArgs, []string{
+				"-F", `$nul`,
+				"-o", `UserKnownHostsFile=$nul`,
+			}...)
+		} else {
+			sshArgs = append(sshArgs, []string{
+				"-F", "/dev/null",
+				"-o", "UserKnownHostsFile=/dev/null",
+			}...)
 		}
 		ts.Setenv(
 			"GIT_SSH_COMMAND",

testscript/testdata/mirror.txtar 🔗

@@ -1,7 +1,7 @@
 # vi: set ft=conf
 
-# convert crlf on windows
-[windows] unix2dos info1.txt info2.txt tree.txt
+# convert crlf to lf on windows
+[windows] dos2unix info1.txt info2.txt tree.txt
 
 # import a repo
 soft repo import --mirror charmbracelet/catwalk https://github.com/charmbracelet/catwalk.git

testscript/testdata/repo-create.txtar 🔗

@@ -1,7 +1,7 @@
 # vi: set ft=conf
 
-# convert crlf on windows
-[windows] unix2dos tree.txt readme.md branch_list.1.txt
+# convert crlf to lf on windows
+[windows] dos2unix tree.txt readme.md branch_list.1.txt
 
 # create a repo
 soft repo create repo1 -d 'description' -H -p -n 'repo11'

testscript/testdata/repo-import.txt 🔗

@@ -1,7 +1,7 @@
 # vi: set ft=conf
 
-# convert crlf on windows
-[windows] unix2dos repo3.txt
+# convert crlf to lf on windows
+[windows] dos2unix repo3.txt
 
 # import private
 soft repo import --private repo1 https://github.com/charmbracelet/catwalk.git

testscript/testdata/set-username.txtar 🔗

@@ -1,7 +1,7 @@
 # vi: set ft=conf
 
-# convert crlf on windows
-[windows] unix2dos info1.txt info2.txt
+# convert crlf to lf on windows
+[windows] dos2unix info1.txt info2.txt
 
 # get original username
 soft info

testscript/testdata/user_management.txtar 🔗

@@ -1,7 +1,7 @@
 # vi: set ft=conf
 
-# convert crlf on windows
-[windows] unix2dos info.txt admin_key_list1.txt admin_key_list2.txt list1.txt list2.txt foo_info1.txt foo_info2.txt foo_info3.txt foo_info4.txt foo_info5.txt
+# convert crlf to lf on windows
+[windows] dos2unix info.txt admin_key_list1.txt admin_key_list2.txt list1.txt list2.txt foo_info1.txt foo_info2.txt foo_info3.txt foo_info4.txt foo_info5.txt
 
 # add key to admin
 soft user add-pubkey admin "$ADMIN2_AUTHORIZED_KEY"