There are many solutions that provide filesystem backup capabilities. These include everything from apps such as Dropbox, Box, Carbonite to hardware solutions such as Apple's Time Machine, Seagate, or network-attached storage products, to name a few. Most consumer tools provide some key automatic functionality, along with an app or website for you to manage your policies and content. Often, especially for developers, these tools don't quite do the things we need them to. However, thanks to Go's standard library (that includes packages such as ioutil
and os
) we have everything we need to build a backup solution that behaves exactly as we need it to.
For our final project, we will build a simple filesystem backup for our source code projects that archive specified folders and save a snapshot of them every time we make a change. The change could be when we tweak a file and save it, or if we add new files and folders, or even if we delete a file. We want to be able to go back to any point in time to retrieve old files.
Specifically in this chapter, you will learn:
os
package allows you to interact with a filesystemfilepath.Walk
to iterate over files and foldersarchive/zip
package to zip filesWe will start by listing some high-level acceptance criteria for our solution and the approach we want to take:
It is common in Go solutions to have, in a single project, both a package that allows other Go programmers to use your capabilities, and a command-line tool that allows end users to use your code.
A convention is emerging to structure the project by having the package in the main project folder, and the command-line tool inside a subfolder called cmd
, or cmds
if you have multiple commands. Because all packages (regardless of the directory tree) are equal in Go, you can import the main package from the subpackages, knowing you'll never need to import the commands from the main package. This may seem like an unnecessary abstraction, but is actually quite a common pattern and can be seen in the standard Go tool chain with examples such as gofmt
and goimports
.
For example, for our project we are going to write a package called backup
, and two command-line tools: the daemon and the user interaction tool. We will structure our project in the following way:
/backup - package /backup/cmds/backup – user interaction tool /backup/cmds/backupd – worker daemon