func SaveMetadata(metadata *Metadata) error {
	path, err := install.GetInstallPath()
	if err != nil {
		return err
	}
	os.MkdirAll(path, 0777)
	metadataPath := filepath.Join(path, cliMetadataFile)
	metadataWriter, err := os.Create(metadataPath)
	if err != nil {
		return err
	}
	defer metadataWriter.Close()
	err = json.NewEncoder(metadataWriter).Encode(metadata)
	if err != nil {
		return err
	}
	return nil
}
SaveMetadata Save the given metadata in the standard location
package metadata
import (
	"encoding/json"
	"os"
	"path/filepath"
	"time"
	"github.com/stackfoundation/sandbox/install"
	"github.com/stackfoundation/sandbox/io"
)
const cliMetadataFile = "cli.json"
const modificationWarning = "Used internally by the Sandbox CLI. Please do not modify this JSON file."
type Metadata struct {
	Description string    `json:"description"`
	Bootstrap   Version   `json:"bootstrap"`
	Core        Version   `json:"core"`
	Checked     time.Time `json:"checked"`
	Driver      string    `json:"driver"`
	VirtualBox  string    `json:"virtualBox"`
}
type Version struct {
	Version  string `json:"version"`
	Updated  string `json:"updated"`
	Checksum string `json:"checksum"`
	Local    string `json:"local"`
	Remote   string `json:"remote"`
}
func WithVersions(bootstrapVersion Version, coreVersion Version) *Metadata {
	return &Metadata{
		Description: modificationWarning,
		Bootstrap:   bootstrapVersion,
		Core:        coreVersion,
		Checked:     time.Now(),
	}
}
func GetMetadata() (*Metadata, error) {
	path, err := install.GetInstallPath()
	if err != nil {
		return nil, err
	}
	metadataPath := filepath.Join(path, cliMetadataFile)
	exists, err := io.Exists(metadataPath)
	if err != nil {
		return nil, err
	}
	if exists {
		return readMetadata(metadataPath)
	}
	return nil, nil
}
func (metadata *Metadata) NeedsUpdate() bool {
	return metadata == nil ||
		len(metadata.Bootstrap.Version) == 0 ||
		len(metadata.Core.Version) == 0 ||
		time.Since(metadata.Checked) > time.Duration(12)*time.Hour
}
func readMetadata(metadataPath string) (*Metadata, error) {
	metadataReader, err := os.Open(metadataPath)
	if err != nil {
		return nil, err
	}
	defer metadataReader.Close()
	var storedMetadata Metadata
	err = json.NewDecoder(metadataReader).Decode(&storedMetadata)
	if err != nil {
		return nil, err
	}
	return &storedMetadata, nil
}