Featured image by Egon Elbre
-
In all my life of using mkdir -p, I never knew you can create multiple subdirectories the easy way. UPDATE: This is actually the shell doing some path expansion and thus can work anywhere.
$ mkdir -p ~/temp/some/path/{dir1,dir2,dir3/even/more} $ tree ~/temp/some /Users/andre/temp/some └── path ├── dir1 ├── dir2 └── dir3 └── even └── more
-
Use
os.CreateTemp()
to create a temporary file on the system. You can specify a directory if needed and also a file name pattern the will be randomised. E.g “config_*.json” -
You can also use
os.os.MkdirTemp()
to create a temporary directory. -
Go comes with template rendering for HTML and Text.
-
Learned a little bit about Colly – the web scraping package for Go.
Working with file systems
- Use the package
path/filepath
to work agnostically with the system’s file path. E.g. this takes into account that Windows uses\
versus Unix based os uses ` - You can use
filepath.Walk
to recursively walk a directory and it will call the function you specify on each found file or directory. There is a note that WalkDir performs better. See the documentation for WalkFunc.
filepath.Walk("./somewhere/here",
func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
// See the WalkFunc documentation for what this function can do to control
// how the Walk behaves
}
}
- fs.FileInfo is declared as:
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() any // underlying data source (can return nil)
}
- To get just the file extension. Use
filepath.Ext()
import "path/filepath"
fmt.Println(filepath.Ext("/dir/filename.txt")) // .txt
fmt.Printf("%q", filepath.Ext("/dir/filename")) // "" <- note it is empty string
- Recall from earlier you can use
os.Remove()
to delete a single file. You can also useos.RemoveAll()
to recursively delete a directory.
Unit-testing
Gophers (Go programmers) use this concept called “Table-Driven testing” by which you build up a table of inputs and expected outputs and then in your unit-test you iterate over the table and check that feeding inputs produce the expected outputs.
I like this and can already see many places where I can apply the same idea to my Swift and other languages.
See Dave Cheney’s article on this.
Note: You can also use t.Run(nameOfTest, func (t *testing.T) { ... } )
to run sub tests inside of a unit-test. Couple this with the for _, testCase := range testCases
and you have super powers.
- You can define Helper functions for your unit-tests. They are usefull for reusing the same code in multiple unit-tests but also if the helper raises errors like
t.Fatal()
then the line number etc. is reported as the unit-test that called the helper and not the helper function it self.
func iamAHelper(t *testing.T, someOtherArgs string) {
t.Helper() // mark this as a helper
// so that calls like this, will output line etc. where this helper was called
t.Fatal(someError)
}