diff --git a/SETUP_DEV_OSX.md b/SETUP_DEV_OSX.md index d6d36f68..c06809b0 100644 --- a/SETUP_DEV_OSX.md +++ b/SETUP_DEV_OSX.md @@ -1,90 +1,88 @@ # How to setup Browsh's build system for Mac -If you just want to try Browsh, you can use [Homebrew](https://brew.sh/) (check out the [installation page](https://www.brow.sh/docs/installation/) at the [official site](https://www.brow.sh/)). + +If you want to try Browsh, you can use [Homebrew](https://brew.sh/). +Check out the [installation page](https://www.brow.sh/docs/installation/) at the +[official site](https://www.brow.sh/)). ## Installations + You need Go, Firefox and Node.js to run Browsh. ### Install Go -Follow the [installation guide](https://golang.org/doc/install) (you can use an installer). - -#### Ensure your GOPATH is set - -```sh -$ echo $GOPATH -/Users/uesr_name/go -$ # anywhere is ok, but make sure it's not none -``` - -#### Ensure you have `$GOPATH/src` and `$GOPATH/bin` folders -If you're not sure if you have these folders, run: -```sh -$ mkdir "$GOPATH/src" -$ mkdir "$GOPATH/bin" -``` +Follow the [installation guide](https://golang.org/doc/install) (you can use an installer). ### Install Firefox -Follow the official [guide](https://support.mozilla.org/en-US/kb/how-download-and-install-firefox-mac) to install Firefox. + +Follow the official [guide](https://support.mozilla.org/en-US/kb/how-download-and-install-firefox-mac) +to install Firefox. #### Include Firefox to your PATH -The `firefox` executable is probably at `/Applications/Firefox.app/Contents/MacOS`. You need to add it to your `PATH` so that Browsh can create new instances of Firefox. + +The `firefox` executable is probably at `/Applications/Firefox.app/Contents/MacOS`. +You need to add it to your `PATH` so that Browsh can create new instances of Firefox. ### Install Node.js + Follow the [official downloading page](https://nodejs.org/en/download/). -> v8.11.4. is currently recommended for working with Browsh (?) +Use Nodejs > v8.11.4 with Browsh. #### Install web-ext globally -It's a Mozilla's handy tool for working with Firefox web extensions: -```sh -$ npm install -g web-ext +It's a Mozilla tool for working with Firefox web extensions: + +```shell +npm install -g web-ext ``` ## Setting up your Browsh ### Clone Browsh -Fork Browsh to your Github account. Clone it to `$GOPATH/src`. + +Fork Browsh to your Github account. +Clone it to a directory of your choice. +We will refer to this directory as `$browsh` for the rest of the guide. ### Install NPM packages ```shell -$ cd "$GOPATH/src/browsh/webext" -$ npm install +cd "$browsh/webext" +npm install ``` ### Run the build script ```sh -$ cd "$GOPATH/src/browsh" -$ # install several required package" -$ ./interfacer/contrib/build_browsh.sh +cd "$browsh" +# install required package" +./interfacer/contrib/build_browsh.sh ``` ## Running Browsh from source -Now that you have all of the required dependencies installed, we can run Browsh. Open three terminals and do the follows: + +Now that you have the required dependencies installed, we can run Browsh. +Open three terminals and do the following: ### Terminal 1 (builds JavaScript) ```sh -$ cd "$GOPATH/src/browsh/webext" -$ # create a dist folder inside the webext folder. -$ npx webpack --watch +cd "$browsh/webext +# create a dist folder inside the webext folder. +npx webpack --watch ``` ### Terminal 2 (handles Firefox web extension) ```sh -$ # the dist folder is created in the first terminal -$ cd "$GOPATH/src/browsh/webext/dist" -$ # create a dist folder inside the webext folder. -$ npx webpack --watch +mkdir "$browsh/webext/dist" +cd "$browsh/webext/dist" +npx webpack --watch ``` ### Terminal 3 (Displays Browsh) ```sh -$ cd "$GOPATH/src/browsh/interfacer" -$ go run ./cmd/browsh/main.go --firefox.use-existing --debug +cd "$browsh/interfacer" +go run ./cmd/browsh/main.go --firefox.use-existing --debug ``` - diff --git a/interfacer/go.mod b/interfacer/go.mod index 6c563a9e..d1408a78 100644 --- a/interfacer/go.mod +++ b/interfacer/go.mod @@ -1,6 +1,6 @@ module github.com/browsh-org/browsh/interfacer -go 1.18 +go 1.21 require ( github.com/NYTimes/gziphandler v1.1.1 diff --git a/interfacer/go.sum b/interfacer/go.sum index a4f60633..32065889 100644 --- a/interfacer/go.sum +++ b/interfacer/go.sum @@ -58,6 +58,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= @@ -98,6 +99,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -110,6 +112,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -143,9 +146,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= @@ -164,6 +169,7 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= @@ -182,6 +188,7 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= github.com/spf13/afero v1.9.0 h1:sFSLUHgxdnN32Qy38hK3QkYBFXZj9DKjVjCUCtD7juY= @@ -506,6 +513,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/interfacer/src/browsh/browsh.go b/interfacer/src/browsh/browsh.go index fde4ca5a..4e035fba 100644 --- a/interfacer/src/browsh/browsh.go +++ b/interfacer/src/browsh/browsh.go @@ -3,7 +3,7 @@ package browsh import ( "encoding/base64" "fmt" - "io/ioutil" + "log/slog" "net/url" "os" "os/exec" @@ -44,40 +44,18 @@ var ( ) func setupLogging() { - dir, err := os.Getwd() - if err != nil { - Shutdown(err) - } - logfile = fmt.Sprintf(filepath.Join(dir, "debug.log")) - fmt.Println("Logging to: " + logfile) - if _, err := os.Stat(logfile); err == nil { - os.Truncate(logfile, 0) - } - if err != nil { - Shutdown(err) - } -} - -// Log for general purpose logging -// TODO: accept generic types -func Log(msg string) { - if !*isDebug { - return - } - if viper.GetBool("http-server-mode") && !IsTesting { - fmt.Println(msg) - } else { - f, oErr := os.OpenFile(logfile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) - if oErr != nil { - Shutdown(oErr) + out := os.Stderr + if *isDebug { + dir, err := os.Getwd() + if err != nil { + Shutdown(err) } - defer f.Close() - - msg = msg + "\n" - if _, wErr := f.WriteString(msg); wErr != nil { - Shutdown(wErr) + logfile = fmt.Sprintf(filepath.Join(dir, "debug.log")) + if out, err = os.OpenFile(logfile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644); err != nil { + Shutdown(err) } } + slog.SetDefault(slog.New(slog.NewTextHandler(out, nil))) } // Initialise browsh @@ -85,9 +63,7 @@ func Initialise() { if IsTesting { *isDebug = true } - if *isDebug { - setupLogging() - } + setupLogging() loadConfig() } @@ -95,9 +71,9 @@ func Initialise() { func Shutdown(err error) { if *isDebug { if e, ok := err.(*errors.Error); ok { - Log(fmt.Sprintf(e.ErrorStack())) + slog.Error(e.ErrorStack()) } else { - Log(err.Error()) + slog.Error(err.Error()) } } exitCode := 0 @@ -111,12 +87,15 @@ func Shutdown(err error) { os.Exit(exitCode) } +func Log(message string) { +} + func saveScreenshot(base64String string) { dec, err := base64.StdEncoding.DecodeString(base64String) if err != nil { Shutdown(err) } - file, err := ioutil.TempFile(os.TempDir(), "browsh-screenshot") + file, err := os.CreateTemp("", "browsh-screenshot") if err != nil { Shutdown(err) } @@ -154,9 +133,14 @@ func TTYStart(injectedScreen tcell.Screen) { screen = injectedScreen setupTcell() writeString(1, 0, logo, tcell.StyleDefault) - writeString(0, 15, "Starting Browsh v"+browshVersion+", the modern text-based web browser.", tcell.StyleDefault) + writeString( + 0, + 15, + "Starting Browsh v"+browshVersion+", the modern text-based web browser.", + tcell.StyleDefault, + ) StartFirefox() - Log("Starting Browsh CLI client") + slog.Info("Starting Browsh CLI client") go readStdin() startWebSocketServer() } diff --git a/interfacer/src/browsh/comms.go b/interfacer/src/browsh/comms.go index b9ca96d9..02dc49c2 100644 --- a/interfacer/src/browsh/comms.go +++ b/interfacer/src/browsh/comms.go @@ -3,6 +3,7 @@ package browsh import ( "encoding/json" "fmt" + "log/slog" "net/http" "strings" @@ -30,7 +31,7 @@ func startWebSocketServer() { serverMux := http.NewServeMux() serverMux.HandleFunc("/", webSocketServer) port := viper.GetString("browsh.websocket-port") - Log("Starting websocket server...") + slog.Info("Starting websocket server...") if netErr := http.ListenAndServe(":"+port, serverMux); netErr != nil { Shutdown(errors.New(fmt.Errorf("Error starting websocket server: %v", netErr))) } @@ -38,7 +39,7 @@ func startWebSocketServer() { func sendMessageToWebExtension(message string) { if !IsConnectedToWebExtension { - Log("Webextension not connected. Message not sent: " + message) + slog.Info("Webextension not connected. Message not sent: " + message) return } stdinChannel <- message @@ -53,12 +54,12 @@ func webSocketReader(ws *websocket.Conn) { handleWebextensionCommand(message) if err != nil { if websocket.IsCloseError(err, websocket.CloseGoingAway) { - Log("Socket reader detected that the browser closed the websocket") + slog.Info("Socket reader detected that the browser closed the websocket") triggerSocketWriterClose() return } if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) { - Log("Socket reader detected that the connection unexpectedly dissapeared") + slog.Info("Socket reader detected that the connection unexpectedly dissapeared") triggerSocketWriterClose() return } @@ -89,7 +90,7 @@ func handleWebextensionCommand(message []byte) { case "/screenshot": saveScreenshot(parts[1]) default: - Log("WEBEXT: " + string(message)) + slog.Info("WEBEXT: " + string(message)) } } @@ -102,13 +103,13 @@ func handleRawFrameTextCommands(parts []string) { Shutdown(err) } if incoming.RequestID != "" { - Log("Raw text for " + incoming.RequestID) + slog.Info("Raw text for " + incoming.RequestID) rawTextRequests.store(incoming.RequestID, incoming.RawJSON) } else { - Log("Raw text but no associated request ID") + slog.Info("Raw text but no associated request ID") } } else { - Log("WEBEXT: " + strings.Join(parts[0:], ",")) + slog.Info("WEBEXT: " + strings.Join(parts[0:], ",")) } } @@ -117,7 +118,8 @@ func handleRawFrameTextCommands(parts []string) { // automatically notice until it actually needs to send something. So we force that // by sending this NOOP text. // TODO: There's a potential race condition because new connections share the same -// Go channel. So we need to setup a new channel for every connection. +// +// Go channel. So we need to setup a new channel for every connection. func triggerSocketWriterClose() { stdinChannel <- "BROWSH CLIENT FORCING CLOSE OF WEBSOCKET WRITER" } @@ -128,12 +130,12 @@ func webSocketWriter(ws *websocket.Conn) { defer ws.Close() for { message = <-stdinChannel - Log(fmt.Sprintf("TTY sending: %s", message)) + slog.Info(fmt.Sprintf("TTY sending: %s", message)) if err := ws.WriteMessage(websocket.TextMessage, []byte(message)); err != nil { if err == websocket.ErrCloseSent { - Log("Socket writer detected that the browser closed the websocket") + slog.Info("Socket writer detected that the browser closed the websocket") } else { - Log("Socket writer detected unexpected closure of websocket") + slog.Info("Socket writer detected unexpected closure of websocket") } return } @@ -141,7 +143,7 @@ func webSocketWriter(ws *websocket.Conn) { } func webSocketServer(w http.ResponseWriter, r *http.Request) { - Log("Incoming web request from browser") + slog.Info("Incoming web request from browser") ws, err := upgrader.Upgrade(w, r, nil) if err != nil { Shutdown(err) diff --git a/interfacer/src/browsh/config.go b/interfacer/src/browsh/config.go index 7a108bdc..0ed45839 100644 --- a/interfacer/src/browsh/config.go +++ b/interfacer/src/browsh/config.go @@ -3,6 +3,7 @@ package browsh import ( "bytes" "fmt" + "log/slog" "os" "path/filepath" "strings" @@ -15,7 +16,7 @@ import ( var ( configFilename = "config.toml" - isDebug = pflag.Bool("debug", false, "Log to ./debug.log") + isDebug = pflag.Bool("debug", false, "slog.Info to ./debug.log") timeLimit = pflag.Int("time-limit", 0, "Kill Browsh after the specified number of seconds") _ = pflag.Bool("http-server-mode", false, "Run as an HTTP service") @@ -79,20 +80,18 @@ func setDefaults() { func loadConfig() { dir := getConfigDir() fullPath := filepath.Join(dir, configFilename) - Log("Looking in " + fullPath + " for config.") + slog.Info("Looking in " + fullPath + " for config.") viper.SetConfigType("toml") viper.SetConfigName(strings.Trim(configFilename, ".toml")) viper.AddConfigPath(dir) viper.AddConfigPath(".") setDefaults() // First load the sample config in case the user hasn't updated any new fields - err := viper.ReadConfig(bytes.NewBuffer([]byte(configSample))) - if err != nil { + if err := viper.ReadConfig(bytes.NewBuffer([]byte(configSample))); err != nil { panic(fmt.Errorf("Config file error: %s \n", err)) } // Then load the users own config file, overwriting the sample config - err = viper.MergeInConfig() - if err != nil { + if err := viper.MergeInConfig(); err != nil { panic(fmt.Errorf("Config file error: %s \n", err)) } viper.BindPFlags(pflag.CommandLine) diff --git a/interfacer/src/browsh/firefox.go b/interfacer/src/browsh/firefox.go index 06614e63..c754c536 100644 --- a/interfacer/src/browsh/firefox.go +++ b/interfacer/src/browsh/firefox.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "log/slog" "net" "os" "os/exec" @@ -59,7 +60,7 @@ var ( ) func startHeadlessFirefox() { - Log("Starting Firefox in headless mode") + slog.Info("Starting Firefox in headless mode") checkIfFirefoxIsAlreadyRunning() firefoxPath := ensureFirefoxBinary() ensureFirefoxVersion(firefoxPath) @@ -69,11 +70,11 @@ func startHeadlessFirefox() { } profile := viper.GetString("firefox.profile") if profile != "browsh-default" { - Log("Using profile: " + profile) + slog.Info("Using profile: " + profile) args = append(args, "-P", profile) } else { profilePath := getFirefoxProfilePath() - Log("Using default profile at: " + profilePath) + slog.Info("Using default profile at: " + profilePath) args = append(args, "--profile", profilePath) } firefoxProcess := exec.Command(firefoxPath, args...) @@ -87,7 +88,7 @@ func startHeadlessFirefox() { } in := bufio.NewScanner(stdout) for in.Scan() { - Log("FF-CONSOLE: " + in.Text()) + slog.Info("FF-CONSOLE: " + in.Text()) } } @@ -114,7 +115,7 @@ func ensureFirefoxBinary() string { path = getFirefoxPath() } } - Log("Using Firefox at: " + path) + slog.Info("Using Firefox at: " + path) if _, err := os.Stat(path); os.IsNotExist(err) { Shutdown(errors.New("Firefox binary not found: " + path)) } @@ -155,12 +156,12 @@ func versionOrdinal(version string) string { // because I haven't been able to recreate the way `web-ext` injects an unsigned // extension. func startWERFirefox() { - Log("Attempting to start headless Firefox with `web-ext`") + slog.Info("Attempting to start headless Firefox with `web-ext`") if IsConnectedToWebExtension { Shutdown(errors.New("There appears to already be an existing Web Extension connection")) } checkIfFirefoxIsAlreadyRunning() - var rootDir = Shell("git rev-parse --show-toplevel") + rootDir := Shell("git rev-parse --show-toplevel") args := []string{ "run", "--firefox=" + rootDir + "/webext/contrib/firefoxheadless.sh", @@ -185,9 +186,9 @@ func startWERFirefox() { strings.Contains(in.Text(), "dbus") { continue } - Log("FF-CONSOLE: " + in.Text()) + slog.Info("FF-CONSOLE: " + in.Text()) } - Log("WER Firefox unexpectedly closed") + slog.Info("WER Firefox unexpectedly closed") } // Connect to Firefox's Marionette service. @@ -206,7 +207,7 @@ func firefoxMarionette() { conn net.Conn ) connected := false - Log("Attempting to connect to Firefox Marionette") + slog.Info("Attempting to connect to Firefox Marionette") start := time.Now() for time.Since(start) < 30*time.Second { conn, err = net.Dial("tcp", "127.0.0.1:2828") @@ -262,14 +263,14 @@ func readMarionette() { buffer := make([]byte, 4096) count, err := marionette.Read(buffer) if err != nil { - Log("Error reading from Marionette connection") + slog.Info("Error reading from Marionette connection") return } - Log("FF-MRNT: " + string(buffer[:count])) + slog.Info("FF-MRNT: " + string(buffer[:count])) } func sendFirefoxCommand(command string, args map[string]interface{}) { - Log("Sending `" + command + "` to Firefox Marionette") + slog.Info("Sending `" + command + "` to Firefox Marionette") fullCommand := []interface{}{0, ffCommandCount, command, args} marshalled, _ := json.Marshal(fullCommand) message := fmt.Sprintf("%d:%s", len(marshalled), marshalled) diff --git a/interfacer/src/browsh/firefox_windows.go b/interfacer/src/browsh/firefox_windows.go index 17394f79..e3c925aa 100644 --- a/interfacer/src/browsh/firefox_windows.go +++ b/interfacer/src/browsh/firefox_windows.go @@ -4,6 +4,7 @@ package browsh import ( "fmt" + "log/slog" "strings" "github.com/go-errors/errors" @@ -46,13 +47,13 @@ func getWindowsFirefoxVersionString() string { Shutdown(errors.New("Error reading Windows registry: " + fmt.Sprintf("%s", err))) } - Log("Windows registry Firefox version: " + versionString) + slog.Info("Windows registry Firefox version: " + versionString) return versionString } func getFirefoxFlavor() string { - var flavor = "null" + flavor := "null" k, err := registry.OpenKey( registry.LOCAL_MACHINE, `Software\Mozilla\Mozilla Firefox`, diff --git a/interfacer/src/browsh/frame_builder.go b/interfacer/src/browsh/frame_builder.go index afb53c38..a11bb655 100644 --- a/interfacer/src/browsh/frame_builder.go +++ b/interfacer/src/browsh/frame_builder.go @@ -3,6 +3,7 @@ package browsh import ( "encoding/json" "fmt" + "log/slog" "unicode" "github.com/gdamore/tcell" @@ -78,7 +79,9 @@ func parseJSONFrameText(jsonString string) { Shutdown(err) } if !isTabPresent(incoming.Meta.TabID) { - Log(fmt.Sprintf("Not building frame for non-existent tab ID: %d", incoming.Meta.TabID)) + slog.Info( + fmt.Sprintf("Not building frame for non-existent tab ID: %d", incoming.Meta.TabID), + ) return } Tabs[incoming.Meta.TabID].frame.buildFrameText(incoming) @@ -100,7 +103,9 @@ func parseJSONFramePixels(jsonString string) { Shutdown(err) } if !isTabPresent(incoming.Meta.TabID) { - Log(fmt.Sprintf("Not building frame for non-existent tab ID: %d", incoming.Meta.TabID)) + slog.Info( + fmt.Sprintf("Not building frame for non-existent tab ID: %d", incoming.Meta.TabID), + ) return } if len(Tabs[incoming.Meta.TabID].frame.text) == 0 { @@ -139,7 +144,7 @@ func (f *frame) resetCells() { func (f *frame) isIncomingFrameTextValid(incoming incomingFrameText) bool { if len(incoming.Text) == 0 { - Log("Not parsing zero-size text frame") + slog.Info("Not parsing zero-size text frame") return false } return true @@ -224,7 +229,7 @@ func (f *frame) populateFramePixels(incoming incomingFramePixels) { func (f *frame) isIncomingFramePixelsValid(incoming incomingFramePixels) bool { if len(incoming.Colours) == 0 { - Log("Not parsing zero-size text frame") + slog.Info("Not parsing zero-size text frame") return false } return true diff --git a/interfacer/src/browsh/raw_text_server.go b/interfacer/src/browsh/raw_text_server.go index 479f3338..a547993c 100644 --- a/interfacer/src/browsh/raw_text_server.go +++ b/interfacer/src/browsh/raw_text_server.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "net/http" "net/url" "regexp" @@ -69,7 +70,7 @@ func HTTPServerStart() { IsHTTPServerMode = true StartFirefox() go startWebSocketServer() - Log("Starting Browsh HTTP server") + slog.Info("Starting Browsh HTTP server") bind := viper.GetString("http-server.bind") port := viper.GetString("http-server.port") serverMux := http.NewServeMux() @@ -120,7 +121,7 @@ func (h *slashFix) ServeHTTP(w http.ResponseWriter, r *http.Request) { func handleHTTPServerRequest(w http.ResponseWriter, r *http.Request) { var message string var isErrored bool - var start = time.Now().Format(time.RFC3339) + start := time.Now().Format(time.RFC3339) urlForBrowsh, _ := url.PathUnescape(strings.TrimPrefix(r.URL.Path, "/")) urlForBrowsh, isErrored = deRecurseURL(urlForBrowsh) if isErrored { @@ -147,7 +148,7 @@ func handleHTTPServerRequest(w http.ResponseWriter, r *http.Request) { return } } - Log(r.Header.Get("User-Agent")) + slog.Info(r.Header.Get("User-Agent")) if isKubeReadinessProbe(r.Header.Get("User-Agent")) { io.WriteString(w, "healthy") return @@ -228,7 +229,7 @@ func isProductionHTTP(r *http.Request) bool { // 'HTML' mode returns some basic HTML tags for things like anchor links. // 'DOM' mode returns a simple dump of the DOM. func getRawTextMode(r *http.Request) string { - var mode = "HTML" + mode := "HTML" if strings.Contains(r.Host, "text.") { mode = "PLAIN" } diff --git a/interfacer/src/browsh/ui.go b/interfacer/src/browsh/ui.go index 973bb5de..a308fc38 100644 --- a/interfacer/src/browsh/ui.go +++ b/interfacer/src/browsh/ui.go @@ -1,20 +1,20 @@ package browsh import ( + "log/slog" + "github.com/gdamore/tcell" "github.com/spf13/viper" ) -var ( - urlInputBox = inputBox{ - X: 0, - Y: 1, - Height: 1, - text: nil, - FgColour: [3]int32{255, 255, 255}, - bgColour: [3]int32{-1, -1, -1}, - } -) +var urlInputBox = inputBox{ + X: 0, + Y: 1, + Height: 1, + text: nil, + FgColour: [3]int32{255, 255, 255}, + bgColour: [3]int32{-1, -1, -1}, +} // Render tabs, URL bar, status messages, etc func renderUI() { @@ -28,7 +28,7 @@ func renderUI() { func writeString(x, y int, str string, style tcell.Style) { xOriginal := x if viper.GetBool("http-server-mode") { - Log(str) + slog.Info(str) return } for _, c := range str { diff --git a/interfacer/test/http-server/setup.go b/interfacer/test/http-server/setup.go index 31d19b92..6702479a 100644 --- a/interfacer/test/http-server/setup.go +++ b/interfacer/test/http-server/setup.go @@ -2,18 +2,20 @@ package test import ( "fmt" - "io/ioutil" + "io" + "log/slog" "net/http" "time" - ginkgo "github.com/onsi/ginkgo" - "github.com/browsh-org/browsh/interfacer/src/browsh" + ginkgo "github.com/onsi/ginkgo" "github.com/spf13/viper" ) -var staticFileServerPort = "4444" -var rootDir = browsh.Shell("git rev-parse --show-toplevel") +var ( + staticFileServerPort = "4444" + rootDir = browsh.Shell("git rev-parse --show-toplevel") +) func startStaticFileServer() { serverMux := http.NewServeMux() @@ -59,7 +61,7 @@ func getPath(path string, mode string) string { panic(fmt.Sprintf("%s", err)) } else { defer response.Body.Close() - contents, err := ioutil.ReadAll(response.Body) + contents, err := io.ReadAll(response.Body) if err != nil { fmt.Printf("%s", err) panic(fmt.Sprintf("%s", err)) @@ -78,9 +80,9 @@ var _ = ginkgo.BeforeEach(func() { browsh.ResetTabs() waitUntilConnectedToWebExtension(15 * time.Second) browsh.IsMonochromeMode = false - browsh.Log("\n---------") - browsh.Log(ginkgo.CurrentGinkgoTestDescription().FullTestText) - browsh.Log("---------") + slog.Info("\n---------") + slog.Info(ginkgo.CurrentGinkgoTestDescription().FullTestText) + slog.Info("---------") }) var _ = ginkgo.BeforeSuite(func() { diff --git a/interfacer/test/tty/setup.go b/interfacer/test/tty/setup.go index 0d67c3ba..14202d44 100644 --- a/interfacer/test/tty/setup.go +++ b/interfacer/test/tty/setup.go @@ -2,6 +2,7 @@ package test import ( "fmt" + "log/slog" "net/http" "os" "path/filepath" @@ -9,24 +10,41 @@ import ( "time" "unicode/utf8" + "github.com/browsh-org/browsh/interfacer/src/browsh" "github.com/gdamore/tcell" "github.com/gdamore/tcell/terminfo" ginkgo "github.com/onsi/ginkgo" gomega "github.com/onsi/gomega" - - "github.com/browsh-org/browsh/interfacer/src/browsh" "github.com/spf13/viper" ) -var staticFileServerPort = "4444" -var simScreen tcell.SimulationScreen -var startupWait = 60 * time.Second -var perTestTimeout = 2000 * time.Millisecond -var rootDir = browsh.Shell("git rev-parse --show-toplevel") -var testSiteURL = "http://localhost:" + staticFileServerPort -var ti *terminfo.Terminfo -var dir, _ = os.Getwd() -var framesLogFile = fmt.Sprintf(filepath.Join(dir, "frames.log")) +var ( + staticFileServerPort = "4444" + simScreen tcell.SimulationScreen + startupWait = 60 * time.Second + perTestTimeout = 2000 * time.Millisecond + rootDir = browsh.Shell("git rev-parse --show-toplevel") + testSiteURL = "http://localhost:" + staticFileServerPort + ti *terminfo.Terminfo + framesLogFileName string + frameLogger *slog.Logger +) + +func init() { + dir, err := os.Getwd() + if err != nil { + panic(err) + } + framesLogFileName = fmt.Sprintf(filepath.Join(dir, "frames.log")) + framesLogFile, err := os.OpenFile(framesLogFileName, + os.O_CREATE|os.O_TRUNC|os.O_WRONLY, + 0o644, + ) + if err != nil { + panic(err) + } + frameLogger = slog.New(slog.NewTextHandler(framesLogFile, nil)) +} func initTerm() { // The tests check for true colour RGB values. The only downside to forcing true colour @@ -39,8 +57,8 @@ func initTerm() { // GetFrame returns the current Browsh frame's text func GetFrame() string { var frame, log string - var line = 0 - var styleDefault = ti.TParm(ti.SetFgBg, int(tcell.ColorWhite), int(tcell.ColorBlack)) + line := 0 + styleDefault := ti.TParm(ti.SetFgBg, int(tcell.ColorWhite), int(tcell.ColorBlack)) width, _ := simScreen.Size() cells, _, _ := simScreen.GetContents() for _, element := range cells { @@ -53,25 +71,12 @@ func GetFrame() string { line = 0 } } - writeFrameLog("================================================") - writeFrameLog(ginkgo.CurrentGinkgoTestDescription().FullTestText) - writeFrameLog("================================================\n") - log = "\n" + log + styleDefault - writeFrameLog(log) + frameLogger.Info("================================================") + frameLogger.Info(ginkgo.CurrentGinkgoTestDescription().FullTestText) + frameLogger.Info("================================================\n") return frame } -func writeFrameLog(log string) { - f, err := os.OpenFile(framesLogFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600) - if err != nil { - panic(err) - } - defer f.Close() - if _, err = f.WriteString(log); err != nil { - panic(err) - } -} - // Trigger the key definition specified by name func triggerUserKeyFor(name string) { key := viper.GetStringSlice(name) @@ -228,11 +233,10 @@ func initBrowsh() { browsh.IsTesting = true simScreen = tcell.NewSimulationScreen("UTF-8") browsh.Initialise() - } func stopFirefox() { - browsh.Log("Attempting to kill all firefox processes") + slog.Info("Attempting to kill all firefox processes") browsh.IsConnectedToWebExtension = false browsh.Shell(rootDir + "/webext/contrib/firefoxheadless.sh kill") time.Sleep(500 * time.Millisecond) @@ -243,19 +247,19 @@ func runeCount(text string) int { } var _ = ginkgo.BeforeEach(func() { - browsh.Log("Attempting to restart WER Firefox...") + slog.Info("Attempting to restart WER Firefox...") stopFirefox() browsh.ResetTabs() browsh.StartFirefox() sleepUntilPageLoad(startupWait) browsh.IsMonochromeMode = false - browsh.Log("\n---------") - browsh.Log(ginkgo.CurrentGinkgoTestDescription().FullTestText) - browsh.Log("---------") + slog.Info("\n---------") + slog.Info(ginkgo.CurrentGinkgoTestDescription().FullTestText) + slog.Info("---------") }) var _ = ginkgo.BeforeSuite(func() { - os.Truncate(framesLogFile, 0) + os.Truncate(framesLogFileName, 0) initTerm() initBrowsh() stopFirefox()