You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: main.go
    path of file: ./repos/nanobox
    
    the code of the file until where you have to start completion: // Nanobox automates the creation of isolated, repeatable environments for local
// and production applications. When developing locally, Nanobox provisions your
// app's infrastructure inside of a virtual machine (VM) and mounts your local
// codebase into the VM. Any changes made to your codebase are reflected inside
// the virtual environment.
//
// Once code is built and tested locally, Nanobox provisions and deploys an
// identical infrastructure on a production platform.
package main

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"runtime/debug"
	"strings"

	"github.com/jcelliott/lumber"

	"github.com/nanobox-io/nanobox/commands"
	"github.com/nanobox-io/nanobox/models"
	"github.com/nanobox-io/nanobox/processors"
	proc_provider "github.com/nanobox-io/nanobox/processors/provider"
	"github.com/nanobox-io/nanobox/util"
	"gith
    
func main() {
	// setup a file logger, this will be replaced in verbose mode.
	fileLogger, err := lumber.NewTruncateLogger(filepath.ToSlash(filepath.Join(config.GlobalDir(), "nanobox.log")))
	if err != nil {
		fmt.Println("logging error:", err)
	}

	//
	lumber.SetLogger(fileLogger)
	lumber.Level(lumber.INFO)
	defer lumber.Close()

	// if it is running the server just run it
	// skip the tratiotional messaging
	if len(os.Args) >= 2 && (os.Args[1] == "server" ||
		os.Args[1] == "version" ||
		os.Args[1] == "tunnel" ||
		os.Args[1] == "console" ||
		os.Args[1] == "log" ||
		os.Args[1] == "login" ||
		os.Args[1] == "logout") {
		err := commands.NanoboxCmd.Execute()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		return
	}

	// verify that we support the prompt they are using
	if badTerminal() {
		display.BadTerminal()
		os.Exit(1)
	}

	// do the commands configure check here
	command := strings.Join(os.Args, " ")
	if _, err := models.LoadConfig(); err != nil && !strings.Contains(command, " config") && !strings.Contains(command, "env server") {
		err = processors.Configure()
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(1)
		}
	}

	migrationCheck()

	fixRunArgs()

	configModel, _ := models.LoadConfig()

	// build the viper config because viper cannot handle concurrency
	// so it has to be done at the beginning even if we dont need it
	providerName := configModel.Provider

	// make sure nanobox has all the necessry parts
	if !strings.Contains(command, " config") && !strings.Contains(command, " server") {
		err, missingParts := provider.Valid()
		if err != nil {
			fmt.Printf("Failed to validate provider - %s\n", err.Error())
			if len(missingParts) > 0 {
				display.MissingDependencies(providerName, missingParts)
			}
			os.Exit(1)
		}
	}

	// global panic handler; this is done to avoid showing any panic output if
	// something happens to fail. The output is logged and "pretty" message is
	// shown
	defer func() {
		if r := recover(); r != nil {
			// put r into your log ( it contains the panic message)
			// Then log debug.Stack (from the runtime/debug package)

			stack := debug.Stack()

			// in a panic state we dont want to try loading or using any non standard libraries.
			// so we will just use the ones we already have
			lumber.Fatal(fmt.Sprintf("Cause of failure: %v", r))
			lumber.Fatal(fmt.Sprintf("Error output:\n%v\n", string(stack)))
			lumber.Close()
			fmt.Println("Nanobox encountered an unexpected error. Please see ~/.nanobox/nanobox.log and submit the issue to us.")
			os.Exit(1)
		}
	}()

	//
	commands.NanoboxCmd.Execute()
}