Reading from USB COM port in go

If you want an easy copy and paste, no nonsense way to print the output of a COM PORT to the terminal in go, then have a look at the code at the bottom of this post.

Firstly, the go.bug.st/serial/enumerator package provides a very nice interface for getting details of connected devices, and includes more details than the example code in go.bug.st/serial that I found first time around.

Thanks to the toit devs for being responsive and helping me quickly figure out how I could make my ESP spit some USB content out over the COM port.

The code

In a nutshell is this:

  • Loops forever
  • Targets a specific device ID, such a 1a86:7523
  • Waits for it to appear as connected
    • Uses baud rate 115200
    • Opens the port
    • Prints all output received to the console

Read more

Scanning for iBeacon advertisements in Go

I spent some time this evening faffing around trying to make a Raspberry Pi turn into a device that could detect nearby iBeacons, filtered by signal strength to find the closest, to basically create a kind of iBeacon scanner that spat out the UUID, minor and major values.

Eventually, I gave up on the Raspberry Pi for various reasons, and moved to my Windows laptop, found a good library, a working example to build on and managed to create a scanner that outputs what you see below!

The details

Searching around, I came across https://github.com/tinygo-org/bluetooth, which included an example that got me scanning for Bluetooth devices right away.

Read more

Autoreload go code on code change

For developers, the ability to autoreload code upon any changes is nothing short of a game-changer. It not only streamlines the development process but also fosters an environment of continuous improvement and experimentation.

There are so many packages for languages such as JavaScript for such a behaviour, but I struggled to easily find a simple-to-use go version with an example.

And that’s where this post comes in, as a simple to-the-point example extracted from what I learnt while reading https://dev.to/jacobsngoodwin/full-stack-memory-app-01-setup-go-server-with-reload-in-docker-62n

We will be making use of https://github.com/cespare/reflex, which is a go package and small tool to watch a directory and rerun a command when certain files change. 

Read more

Automatic cobra command registration with fx

Cobra is a popular Go package for creating CLIs. It provides a lot of functionality for creating commands, subcommands, and flags. However, it can be tedious to manually register all of your commands.

fx is a Go package that provides a dependency injection framework. It can be used to automatically register your application components, including but not limited to Cobra commands.

In this blog post, I will show you how you can use fx to automatically register your Cobra commands.

This code was written 5 minutes ago, but works, and I imagine it could help folks bootstrap more complex CLIs rapidly.

The problem

When you create a Cobra command, you need to manually register it with the root command. This can be tedious, especially if you have a lot of commands.

For example, the following code registers a command called hello:

func NewHelloCmd() *cobra.Command {
  cmd := &cobra.Command{
    Use:   "hello",
    Short: "Say hello",
    Run: func(cmd *cobra.Command, args []string) {
      cmd.Println("Hello, world!")
    },
  }
  return cmd
}

func main() {
  rootCmd := &cobra.Command{
    Use:   "myapp",
    Short: "My application",
  }
  rootCmd.AddCommand(NewHelloCmd())
  rootCmd.Execute()
}Code language: Go (go)

Read more

A copy-paste go SQL mock for GORM

When it comes to writing robust and reliable tests for your Go applications, having a well-structured and efficient testing setup is crucial. One common challenge in testing Go applications is dealing with database interactions. To ensure that your code functions correctly, it’s essential to create a controlled environment for database operations during testing. In this blog post, we’ll explore how to create a mock GORM database for testing purposes, allowing you to isolate and verify your database interactions in a controlled manner.

Here is some copy-and-paste code (explained below) which should get you started.

import (
	"github.com/DATA-DOG/go-sqlmock"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

func NewMockGORM() (GORM *gorm.DB, close func()) {
	db, mock, err := sqlmock.New()
	if err != nil {
		panic(err)
	}

	// GORM always runs this query, so mock it for all tests
	mock.ExpectQuery("SELECT VERSION()").WillReturnRows(sqlmock.NewRows([]string{"version"}).AddRow("5.7.0"))

	GORM, err = gorm.Open(mysql.New(mysql.Config{Conn: db}), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
	if err != nil {
		panic(err)
	}

	return GORM, func() { db.Close() }
}Code language: PHP (php)

The code block above defines a NewMockGORM function that sets up a mock GORM database instance for testing. Let’s break down what this code does and how it can be a valuable addition to your testing toolkit.

Setting up a Mock GORM Database

Read more

Dependency injection in go using fx, and replacing services for test

I’m writing a new go application and ended up giving fx (by uber) a try for dependency injection. The getting started docs were brilliant for my use case (creating an API), but the examples for how to inject mock services for tests were lacking, so I decided to write some code examples of how I am currently using fx in tests.

General app setup

I set up my whole application in a app package, which pulls in all services that are needed.

Most of these are provided as constructor functions, with some more dynamic registration of routes as is done in the getting started docs.

package app

func New(additionalOpts ...fx.Option) *fx.App {
	return fx.New(
		fx.Provide(
			config.NewDefault,
			ses.NewSES,
			ses.NewEmailSender,
			mysql.NewGormGB,
			middleware.NewLimiterFactory,
			middleware.NewAuth,
			AsRoute(handlers.UserLogin),
			AsRoute(handlers.ListStuff),
			fx.Annotate(
				router.NewGinRouter,
				fx.ParamTags(`group:"routes"`),
			),
			server.NewHTTPServer,
		),
		fx.Invoke(func(*http.Server) {}),
		fx.Options(additionalOpts...),
	)
}Code language: Go (go)

Read more

mwcli CI in Wikimedia GitLab (docker in docker)

mwcli is a golang CLI tool that I have been working on over the past year to replace the mediawiki-docker-dev development environment that I accidently created a few years back (among other things). I didn’t start the CLI, but I did this mediawiki-docker-dev like functionality.

As some point through the development journey it became clear that one of the ways to set the new and old environments apart would be through some rigorous CI and testing.

This started with CI running on a Qemu node as part of the shared Wikimedia Jenkins CI infrastructure that is hooked up to Gerrit, where the code was being developed. This ended up being quite slow, and involved lots of manual steps.

A next iteration saw the majority of development take place in my own fork on Github, making use of Github Actions. Changes would then be copied over to Gerrit for final review once CI tests had run.

And finally the repository moved to the new Wikimedia GitLab instance (work in progress), where I could make use of GitLab Runners powered by a machine in Wikimedia Cloud VPS.

Screenshot of GitLab pipelines in action for the mwcli project

Read more

dockerit v0.0.5 (Easier than docker run)

dockerit is a small CLI tool that I have been working on during the start of 2021. It’s intended to make running one off commands and CLI tooling easier in docker. Rather than having to write a long string of parameters for docker run, instead you can just use dockerit. This applies to both CLI usage, but also via bash aliases.

You can download a build binary of dockerit from the Github releases page.

Read more

Go Docker SDK, Raw Terminal Ctrl+C handling

I spent my weekend in working on a new project called dockerit. It’s a simple wrapper around Docker written in Go and making use of the Docker SDK.

One of the biggest sticking points for me, being fairly new with the Golang world, was trying to pass stdin stdout and stderr between the container and host terminal correctly, while also having good performance and doing the expected things (like Ctrl+C to cancel).

The full code for setting up and, interacting with and removing my container can be found here. The main steps are broken down below.

Read more

Simple Go defer code example

In Go, a defer statement will execute a function call just before the function it is called from returns.

I found that most of the examples of a Go defer call online seemed to do complicated things with numbers. So here is a nice simple example with just text output.

Example

You can run this code yourself in The Go Playground! You can also find a similar example in the Go Tour.

package main

import (
	"fmt"
)

func main() {
	// This will output first (in order)
	fmt.Println("One")
	
	// This will output last (before this function finishes)
	defer fmt.Println("Two")
	
	// This will be called before the above defer call "Two"
	secondary()
}


func secondary() {
	// This will output after Four (before this function finishes)
	defer fmt.Println("Three")
	
	// This will output (in order)
	fmt.Println("Four")
}

Code language: JavaScript (javascript)

Read more