diff --git a/cmd/frameworks.go b/cmd/frameworks.go new file mode 100644 index 000000000..610a5254f --- /dev/null +++ b/cmd/frameworks.go @@ -0,0 +1,69 @@ +package cmd + +import ( + "encoding/json" + "io/ioutil" + "path" + "path/filepath" + "runtime" +) + +// FrameworkMetadata contains information about a given framework +type FrameworkMetadata struct { + Name string `json:"name"` + BuildTag string `json:"buildtag"` + Description string `json:"description"` +} + +// Utility function for creating new FrameworkMetadata structs +func loadFrameworkMetadata(pathToMetadataJSON string) (*FrameworkMetadata, error) { + result := &FrameworkMetadata{} + configData, err := ioutil.ReadFile(pathToMetadataJSON) + if err != nil { + return nil, err + } + // Load and unmarshall! + err = json.Unmarshal(configData, result) + if err != nil { + return nil, err + } + return result, nil +} + +// GetFrameworks returns information about all the available frameworks +func GetFrameworks() ([]*FrameworkMetadata, error) { + + var err error + + // Calculate framework base dir + _, filename, _, _ := runtime.Caller(1) + frameworksBaseDir := filepath.Join(path.Dir(filename), "frameworks") + + // Get the subdirectories + fs := NewFSHelper() + frameworkDirs, err := fs.GetSubdirs(frameworksBaseDir) + if err != nil { + return nil, err + } + + // Prepare result + result := []*FrameworkMetadata{} + + // Iterate framework directories, looking for metadata.json files + for _, frameworkDir := range frameworkDirs { + var frameworkMetadata FrameworkMetadata + metadataFile := filepath.Join(frameworkDir, "metadata.json") + jsonData, err := ioutil.ReadFile(metadataFile) + if err != nil { + return nil, err + } + err = json.Unmarshal(jsonData, &frameworkMetadata) + if err != nil { + return nil, err + } + result = append(result, &frameworkMetadata) + } + + // Read in framework metadata + return result, nil +} diff --git a/cmd/project.go b/cmd/project.go new file mode 100644 index 000000000..682db2eaf --- /dev/null +++ b/cmd/project.go @@ -0,0 +1,336 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "path/filepath" + "strings" + + "github.com/AlecAivazis/survey" +) + +type author struct { + Name string `json:"name"` + Email string `json:"email"` +} + +type frontend struct { + Dir string `json:"dir"` + Install string `json:"install"` + Build string `json:"build"` +} + +type framework struct { + Name string `json:"name"` + BuildTag string `json:"buildtag"` + Options map[string]string `json:"options,omitempty"` +} + +// ProjectHelper is a helper struct for managing projects +type ProjectHelper struct { + log *Logger + system *SystemHelper + templates *TemplateHelper +} + +// NewProjectHelper creates a new Project helper struct +func NewProjectHelper() *ProjectHelper { + return &ProjectHelper{ + log: NewLogger(), + system: NewSystemHelper(), + templates: NewTemplateHelper(), + } +} + +// GenerateProject generates a new project using the options given +func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error { + + fs := NewFSHelper() + exists, err := ph.templates.TemplateExists(projectOptions.Template) + if err != nil { + return err + } + + if !exists { + return fmt.Errorf("template '%s' is invalid", projectOptions.Template) + } + + // Calculate project path + projectPath, err := filepath.Abs(projectOptions.OutputDirectory) + if err != nil { + return err + } + + if fs.DirExists(projectPath) { + return fmt.Errorf("directory '%s' already exists", projectPath) + } + + // Create project directory + err = fs.MkDir(projectPath) + if err != nil { + return err + } + + // Create and save project config + err = projectOptions.WriteProjectConfig() + if err != nil { + return err + } + + err = ph.templates.InstallTemplate(projectPath, projectOptions) + if err != nil { + return err + } + ph.log.Yellow("Project '%s' generated in directory '%s'!", projectOptions.Name, projectOptions.OutputDirectory) + ph.log.Yellow("To compile the project, run 'wails build' in the project directory.") + return nil +} + +// LoadProjectConfig loads the project config from the given directory +func (ph *ProjectHelper) LoadProjectConfig(dir string) (*ProjectOptions, error) { + po := ph.NewProjectOptions() + err := po.LoadConfig(dir) + return po, err +} + +// NewProjectOptions creates a new default set of project options +func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions { + result := ProjectOptions{ + Name: "", + Description: "Enter your project description", + Version: "0.1.0", + BinaryName: "", + system: NewSystemHelper(), + log: NewLogger(), + templates: NewTemplateHelper(), + templateNameMap: make(map[string]string), + Author: &author{}, + } + + // Populate system config + config, err := ph.system.LoadConfig() + if err == nil { + result.Author.Name = config.Name + result.Author.Email = config.Email + } + + return &result +} + +// SelectQuestion creates a new select type question for Survey +func SelectQuestion(name, message string, options []string, defaultValue string, required bool) *survey.Question { + result := survey.Question{ + Name: name, + Prompt: &survey.Select{ + Message: message, + Options: options, + Default: defaultValue, + }, + } + if required { + result.Validate = survey.Required + } + return &result +} + +// InputQuestion creates a new input type question for Survey +func InputQuestion(name, message string, defaultValue string, required bool) *survey.Question { + result := survey.Question{ + Name: name, + Prompt: &survey.Input{ + Message: message + ":", + Default: defaultValue, + }, + } + if required { + result.Validate = survey.Required + } + return &result +} + +// ProjectOptions holds all the options available for a project +type ProjectOptions struct { + Name string `json:"name"` + Description string `json:"description"` + Author *author `json:"author,omitempty"` + Version string `json:"version"` + OutputDirectory string `json:"-"` + UseDefaults bool `json:"-"` + Template string `json:"-"` + BinaryName string `json:"binaryname"` + FrontEnd *frontend `json:"frontend,omitempty"` + NPMProjectName string `json:"-"` + Framework *framework `json:"framework,omitempty"` + system *SystemHelper + log *Logger + templates *TemplateHelper + templateNameMap map[string]string // Converts template prompt text to template name +} + +// Defaults sets the default project template +func (po *ProjectOptions) Defaults() { + po.Template = "basic" +} + +// PromptForInputs asks the user to input project details +func (po *ProjectOptions) PromptForInputs() error { + + var questions []*survey.Question + fs := NewFSHelper() + + if po.Name == "" { + questions = append(questions, InputQuestion("Name", "The name of the project", "My Project", true)) + } else { + fmt.Println("Project Name: " + po.Name) + } + + if po.BinaryName == "" { + var binaryNameComputed string + if po.Name != "" { + binaryNameComputed = strings.ToLower(po.Name) + binaryNameComputed = strings.Replace(binaryNameComputed, " ", "-", -1) + binaryNameComputed = strings.Replace(binaryNameComputed, string(filepath.Separator), "-", -1) + binaryNameComputed = strings.Replace(binaryNameComputed, ":", "-", -1) + } + questions = append(questions, InputQuestion("BinaryName", "The output binary name", binaryNameComputed, true)) + } else { + fmt.Println("Output binary Name: " + po.BinaryName) + } + + if po.OutputDirectory != "" { + projectPath, err := filepath.Abs(po.OutputDirectory) + if err != nil { + return err + } + + if fs.DirExists(projectPath) { + return fmt.Errorf("directory '%s' already exists", projectPath) + } + + fmt.Println("Project Directory: " + po.OutputDirectory) + } else { + questions = append(questions, InputQuestion("OutputDirectory", "Project directory name", "", true)) + } + + templateDetails, err := po.templates.GetTemplateDetails() + if err != nil { + return err + } + + templates := []string{} + // Add a Custom Template + // templates = append(templates, "Custom - Choose your own CSS framework") + for templateName, templateDetails := range templateDetails { + templateText := templateName + // Check if metadata json exists + if templateDetails.Metadata != nil { + shortdescription := templateDetails.Metadata["shortdescription"] + if shortdescription != "" { + templateText += " - " + shortdescription.(string) + } + } + templates = append(templates, templateText) + po.templateNameMap[templateText] = templateName + } + + if po.Template != "" { + if _, ok := templateDetails[po.Template]; !ok { + po.log.Error("Template '%s' invalid.", po.Template) + questions = append(questions, SelectQuestion("Template", "Select template", templates, templates[0], true)) + } + } else { + questions = append(questions, SelectQuestion("Template", "Select template", templates, templates[0], true)) + } + + err = survey.Ask(questions, po) + if err != nil { + return err + } + + // Setup NPM Project name + po.NPMProjectName = strings.Replace(po.Name, " ", "_", -1) + + // If we selected custom, prompt for framework + if po.Template == "custom - Choose your own CSS Framework" { + // Ask for the framework + var frameworkName string + frameworks, err := GetFrameworks() + fmt.Printf("Frameworks = %+v\n", frameworks) + frameworkNames := []string{} + metadataMap := make(map[string]*FrameworkMetadata) + for _, frameworkMetadata := range frameworks { + frameworkDetails := fmt.Sprintf("%s - %s", frameworkMetadata.Name, frameworkMetadata.Description) + metadataMap[frameworkDetails] = frameworkMetadata + frameworkNames = append(frameworkNames, frameworkDetails) + } + if err != nil { + return err + } + var frameworkQuestion []*survey.Question + frameworkQuestion = append(frameworkQuestion, SelectQuestion("Framework", "Select framework", frameworkNames, frameworkNames[0], true)) + err = survey.Ask(frameworkQuestion, &frameworkName) + if err != nil { + return err + } + // Get metadata + metadata := metadataMap[frameworkName] + + // Add to project config + po.Framework = &framework{ + Name: metadata.Name, + BuildTag: metadata.BuildTag, + } + + } + + // Fix template name + if po.templateNameMap[po.Template] != "" { + po.Template = po.templateNameMap[po.Template] + } + + // Populate template details + templateMetadata := templateDetails[po.Template].Metadata + if templateMetadata["frontenddir"] != nil { + po.FrontEnd = &frontend{} + po.FrontEnd.Dir = templateMetadata["frontenddir"].(string) + } + if templateMetadata["install"] != nil { + if po.FrontEnd == nil { + return fmt.Errorf("install set in template metadata but not frontenddir") + } + po.FrontEnd.Install = templateMetadata["install"].(string) + } + if templateMetadata["build"] != nil { + if po.FrontEnd == nil { + return fmt.Errorf("build set in template metadata but not frontenddir") + } + po.FrontEnd.Build = templateMetadata["build"].(string) + } + + return nil +} + +func (po *ProjectOptions) WriteProjectConfig() error { + targetDir, err := filepath.Abs(po.OutputDirectory) + if err != nil { + return err + } + + targetFile := filepath.Join(targetDir, "project.json") + filedata, err := json.MarshalIndent(po, "", " ") + if err != nil { + return err + } + + return ioutil.WriteFile(targetFile, filedata, 0600) +} + +func (po *ProjectOptions) LoadConfig(projectDir string) error { + targetFile := filepath.Join(projectDir, "project.json") + rawBytes, err := ioutil.ReadFile(targetFile) + if err != nil { + return err + } + return json.Unmarshal(rawBytes, po) +} diff --git a/cmd/system.go b/cmd/system.go index c8dd6a35a..d61cd8474 100644 --- a/cmd/system.go +++ b/cmd/system.go @@ -6,10 +6,12 @@ import ( "io/ioutil" "log" "path/filepath" + "runtime" "strconv" "time" "github.com/AlecAivazis/survey" + "github.com/leaanthony/spinner" homedir "github.com/mitchellh/go-homedir" ) @@ -137,6 +139,16 @@ Wails is a lightweight framework for creating web-like desktop apps in Go. I'll need to ask you a few questions so I can fill in your project templates and then I will try and see if you have the correct dependencies installed. If you don't have the right tools installed, I'll try and suggest how to install them. ` +// CheckInitialised checks if the system has been set up +// and if not, runs setup +func (s *SystemHelper) CheckInitialised() error { + if !s.systemDirExists() { + s.log.Yellow("System not initialised. Running setup.") + return s.setup() + } + return nil +} + // Initialise attempts to set up the Wails system. // An error is returns if there is a problem func (s *SystemHelper) Initialise() error { @@ -208,3 +220,71 @@ func (sc *SystemConfig) load(filename string) error { } return nil } + +// CheckDependencies will look for Wails dependencies on the system +// Errors are reported in error and the bool return value is whether +// the dependencies are all installed. +func CheckDependencies(logger *Logger) (error, bool) { + + switch runtime.GOOS { + case "darwin": + logger.Yellow("Detected Platform: OSX") + case "windows": + logger.Yellow("Detected Platform: Windows") + case "linux": + logger.Yellow("Detected Platform: Linux") + default: + return fmt.Errorf("Platform %s is currently not supported", runtime.GOOS), false + } + + logger.Yellow("Checking for prerequisites...") + // Check we have a cgo capable environment + + requiredPrograms, err := GetRequiredPrograms() + if err != nil { + return nil, false + } + errors := false + spinner := spinner.New() + programHelper := NewProgramHelper() + for _, program := range *requiredPrograms { + spinner.Start("Looking for program '%s'", program.Name) + bin := programHelper.FindProgram(program.Name) + if bin == nil { + errors = true + spinner.Errorf("Program '%s' not found. %s", program.Name, program.Help) + } else { + spinner.Successf("Program '%s' found: %s", program.Name, bin.Path) + } + } + + // Linux has library deps + if runtime.GOOS == "linux" { + // Check library prerequisites + requiredLibraries, err := GetRequiredLibraries() + if err != nil { + return err, false + } + distroInfo := GetLinuxDistroInfo() + for _, library := range *requiredLibraries { + spinner.Start() + switch distroInfo.Distribution { + case Ubuntu: + installed, err := DpkgInstalled(library.Name) + if err != nil { + return err, false + } + if !installed { + errors = true + spinner.Errorf("Library '%s' not found. %s", library.Name, library.Help) + } else { + spinner.Successf("Library '%s' installed.", library.Name) + } + default: + return fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, library.Name), false + } + } + } + + return err, !errors +} diff --git a/cmd/templates.go b/cmd/templates.go new file mode 100644 index 000000000..1647cae2b --- /dev/null +++ b/cmd/templates.go @@ -0,0 +1,268 @@ +package cmd + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + "runtime" + "strings" + + "github.com/alecthomas/template" +) + +const templateSuffix = ".template" + +type TemplateHelper struct { + system *SystemHelper + fs *FSHelper + templateDir string + // templates map[string]string + templateSuffix string + metadataFilename string +} + +type Template struct { + Name string + Dir string + Metadata map[string]interface{} +} + +func NewTemplateHelper() *TemplateHelper { + result := TemplateHelper{ + system: NewSystemHelper(), + fs: NewFSHelper(), + templateSuffix: ".template", + metadataFilename: "template.json", + } + // Calculate template base dir + _, filename, _, _ := runtime.Caller(1) + result.templateDir = filepath.Join(path.Dir(filename), "templates") + // result.templateDir = filepath.Join(result.system.homeDir, "go", "src", "github.com", "wailsapp", "wails", "cmd", "templates") + return &result +} + +func (t *TemplateHelper) GetTemplateNames() (map[string]string, error) { + templateDirs, err := t.fs.GetSubdirs(t.templateDir) + if err != nil { + return nil, err + } + return templateDirs, nil +} + +func (t *TemplateHelper) GetTemplateDetails() (map[string]*Template, error) { + templateDirs, err := t.fs.GetSubdirs(t.templateDir) + if err != nil { + return nil, err + } + + result := make(map[string]*Template) + + for name, dir := range templateDirs { + result[name] = &Template{ + Dir: dir, + } + metadata, err := t.LoadMetadata(dir) + if err != nil { + return nil, err + } + result[name].Metadata = metadata + if metadata["name"] != nil { + result[name].Name = metadata["name"].(string) + } else { + // Ignore bad templates? + result[name] = nil + } + } + + return result, nil +} + +func (t *TemplateHelper) LoadMetadata(dir string) (map[string]interface{}, error) { + templateFile := filepath.Join(dir, t.metadataFilename) + result := make(map[string]interface{}) + if !t.fs.FileExists(templateFile) { + return nil, nil + } + rawJSON, err := ioutil.ReadFile(templateFile) + if err != nil { + return nil, err + } + err = json.Unmarshal(rawJSON, &result) + return result, err +} + +func (t *TemplateHelper) TemplateExists(templateName string) (bool, error) { + templates, err := t.GetTemplateNames() + if err != nil { + return false, err + } + _, exists := templates[templateName] + return exists, nil +} + +func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error { + + // Get template files + template, err := t.getTemplateFiles(projectOptions.Template) + if err != nil { + return err + } + + // Copy files to target + err = template.Install(projectPath, projectOptions) + if err != nil { + return err + } + + return nil +} + +// templateFiles categorises files found in a template +type templateFiles struct { + BaseDir string + StandardFiles []string + Templates []string + Dirs []string +} + +// newTemplateFiles returns a new TemplateFiles struct +func (t *TemplateHelper) newTemplateFiles(dir string) *templateFiles { + pathsep := string(os.PathSeparator) + // Ensure base directory has trailing slash + if !strings.HasSuffix(dir, pathsep) { + dir = dir + pathsep + } + return &templateFiles{ + BaseDir: dir, + } +} + +// AddStandardFile adds the given file to the list of standard files +func (t *templateFiles) AddStandardFile(filename string) { + localPath := strings.TrimPrefix(filename, t.BaseDir) + t.StandardFiles = append(t.StandardFiles, localPath) +} + +// AddTemplate adds the given file to the list of template files +func (t *templateFiles) AddTemplate(filename string) { + localPath := strings.TrimPrefix(filename, t.BaseDir) + t.Templates = append(t.Templates, localPath) +} + +// AddDir adds the given directory to the list of template dirs +func (t *templateFiles) AddDir(dir string) { + localPath := strings.TrimPrefix(dir, t.BaseDir) + t.Dirs = append(t.Dirs, localPath) +} + +// getTemplateFiles returns a struct categorising files in +// the template directory +func (t *TemplateHelper) getTemplateFiles(templateName string) (*templateFiles, error) { + + templates, err := t.GetTemplateNames() + if err != nil { + return nil, err + } + templateDir := templates[templateName] + result := t.newTemplateFiles(templateDir) + var localPath string + err = filepath.Walk(templateDir, func(dir string, info os.FileInfo, err error) error { + if dir == templateDir { + return nil + } + if err != nil { + return err + } + + // Don't copy template metadata + localPath = strings.TrimPrefix(dir, templateDir+string(filepath.Separator)) + if localPath == t.metadataFilename { + return nil + } + + // Categorise the file + switch { + case info.IsDir(): + result.AddDir(dir) + case strings.HasSuffix(info.Name(), templateSuffix): + result.AddTemplate(dir) + default: + result.AddStandardFile(dir) + } + return nil + }) + + if err != nil { + return nil, fmt.Errorf("error processing template '%s' in path '%q': %v", templateName, templateDir, err) + } + return result, err +} + +// Install the template files into the given project path +func (t *templateFiles) Install(projectPath string, projectOptions *ProjectOptions) error { + + fs := NewFSHelper() + + // Create directories + var targetDir string + for _, dirname := range t.Dirs { + targetDir = filepath.Join(projectPath, dirname) + fs.MkDir(targetDir) + } + + // Copy standard files + var targetFile, sourceFile string + var err error + for _, filename := range t.StandardFiles { + sourceFile = filepath.Join(t.BaseDir, filename) + targetFile = filepath.Join(projectPath, filename) + + err = fs.CopyFile(sourceFile, targetFile) + if err != nil { + return err + } + } + + // Do we have template files? + if len(t.Templates) > 0 { + + // Iterate over the templates + var templateFile string + var tmpl *template.Template + for _, filename := range t.Templates { + + // Load template text + templateFile = filepath.Join(t.BaseDir, filename) + templateText, err := fs.LoadAsString(templateFile) + if err != nil { + return err + } + + // Apply template + tmpl = template.New(templateFile) + tmpl.Parse(templateText) + + // Write the template to a buffer + var tpl bytes.Buffer + err = tmpl.Execute(&tpl, projectOptions) + if err != nil { + fmt.Println("ERROR!!! " + err.Error()) + return err + } + + // Save buffer to disk + targetFilename := strings.TrimSuffix(filename, templateSuffix) + targetFile = filepath.Join(projectPath, targetFilename) + err = ioutil.WriteFile(targetFile, tpl.Bytes(), 0644) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/cmd/templates/basic/main.go b/cmd/templates/basic/main.go new file mode 100644 index 000000000..269b1d396 --- /dev/null +++ b/cmd/templates/basic/main.go @@ -0,0 +1,19 @@ +package main + +import ( + wails "github.com/wailsapp/wails" +) + +var html = `

Basic Template

` + +func main() { + + // Initialise the app + app := wails.CreateApp(&wails.AppConfig{ + Width: 1024, + Height: 768, + Title: "My Project", + HTML: html, + }) + app.Run() +} diff --git a/cmd/templates/basic/template.json b/cmd/templates/basic/template.json new file mode 100644 index 000000000..6035732d4 --- /dev/null +++ b/cmd/templates/basic/template.json @@ -0,0 +1,7 @@ +{ + "name": "Basic", + "shortdescription": "A basic template", + "description": "A basic template using vanilla JS", + "author": "Lea Anthony", + "created": "2018-10-18" +} \ No newline at end of file diff --git a/cmd/templates/vuewebpack/frontend/.browserslistrc b/cmd/templates/vuewebpack/frontend/.browserslistrc new file mode 100644 index 000000000..9dee64646 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not ie <= 8 diff --git a/cmd/templates/vuewebpack/frontend/.gitignore b/cmd/templates/vuewebpack/frontend/.gitignore new file mode 100644 index 000000000..185e66319 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/.gitignore @@ -0,0 +1,21 @@ +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* diff --git a/cmd/templates/vuewebpack/frontend/README.md b/cmd/templates/vuewebpack/frontend/README.md new file mode 100644 index 000000000..4735dcb87 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/README.md @@ -0,0 +1,29 @@ +# frontend + +## Project setup +``` +npm install +``` + +### Compiles and hot-reloads for development +``` +npm run serve +``` + +### Compiles and minifies for production +``` +npm run build +``` + +### Run your tests +``` +npm run test +``` + +### Lints and fixes files +``` +npm run lint +``` + +### Customize configuration +See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/cmd/templates/vuewebpack/frontend/babel.config.js b/cmd/templates/vuewebpack/frontend/babel.config.js new file mode 100644 index 000000000..ba179669a --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/app' + ] +} diff --git a/cmd/templates/vuewebpack/frontend/package.json b/cmd/templates/vuewebpack/frontend/package.json new file mode 100644 index 000000000..7d05448d7 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/package.json @@ -0,0 +1,17 @@ +{ + "name": "frontend", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build" + }, + "dependencies": { + "vue": "^2.5.17" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "^3.1.1", + "@vue/cli-service": "^3.1.4", + "vue-template-compiler": "^2.5.17" + } +} diff --git a/cmd/templates/vuewebpack/frontend/postcss.config.js b/cmd/templates/vuewebpack/frontend/postcss.config.js new file mode 100644 index 000000000..961986e2b --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/cmd/templates/vuewebpack/frontend/public/favicon.ico b/cmd/templates/vuewebpack/frontend/public/favicon.ico new file mode 100644 index 000000000..c7b9a43c8 Binary files /dev/null and b/cmd/templates/vuewebpack/frontend/public/favicon.ico differ diff --git a/cmd/templates/vuewebpack/frontend/public/index.html b/cmd/templates/vuewebpack/frontend/public/index.html new file mode 100644 index 000000000..1fe8d7369 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/public/index.html @@ -0,0 +1,17 @@ + + + + + + + + frontend + + + +
+ + + diff --git a/cmd/templates/vuewebpack/frontend/src/App.vue b/cmd/templates/vuewebpack/frontend/src/App.vue new file mode 100644 index 000000000..279b0a94e --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/App.vue @@ -0,0 +1,22 @@ + + + + diff --git a/cmd/templates/vuewebpack/frontend/src/assets/css/main.css b/cmd/templates/vuewebpack/frontend/src/assets/css/main.css new file mode 100644 index 000000000..1a5e18b93 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/assets/css/main.css @@ -0,0 +1,55 @@ +#app { + font-family: "Roboto", Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: center; + color: #eee; + margin-top: 60px; +} + +html { + height: 100%; + overflow: hidden; + /* https://leaverou.github.io/css3patterns/#carbon */ + background: linear-gradient(27deg, #151515 5px, transparent 5px) 0 5px, + linear-gradient(207deg, #151515 5px, transparent 5px) 10px 0px, + linear-gradient(27deg, #222 5px, transparent 5px) 0px 10px, + linear-gradient(207deg, #222 5px, transparent 5px) 10px 5px, + linear-gradient(90deg, #1b1b1b 10px, transparent 10px), + linear-gradient( + #1d1d1d 25%, + #1a1a1a 25%, + #1a1a1a 50%, + transparent 50%, + transparent 75%, + #242424 75%, + #242424 + ); + background-color: #131313; + background-size: 20px 20px; +} + +.logo { + width: 16em; +} + +/* roboto-regular - latin */ +@font-face { + font-family: "Roboto"; + font-style: normal; + font-weight: 400; + src: url("../fonts/roboto/roboto-v18-latin-regular.eot"); /* IE9 Compat Modes */ + src: local("Roboto"), local("Roboto-Regular"), + url("../fonts/roboto/roboto-v18-latin-regular.eot?#iefix") + format("embedded-opentype"), + /* IE6-IE8 */ url("../fonts/roboto/roboto-v18-latin-regular.woff2") + format("woff2"), + /* Super Modern Browsers */ + url("../fonts/roboto/roboto-v18-latin-regular.woff") format("woff"), + /* Modern Browsers */ + url("../fonts/roboto/roboto-v18-latin-regular.ttf") + format("truetype"), + /* Safari, Android, iOS */ + url("../fonts/roboto/roboto-v18-latin-regular.svg#Roboto") + format("svg"); /* Legacy iOS */ +} \ No newline at end of file diff --git a/cmd/templates/vuewebpack/frontend/src/assets/css/quote.css b/cmd/templates/vuewebpack/frontend/src/assets/css/quote.css new file mode 100644 index 000000000..edfc8d3f5 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/assets/css/quote.css @@ -0,0 +1,75 @@ +/** + Credit: https://codepen.io/harmputman/pen/IpAnb +**/ + +body { + font: normal 300 1em/1.5em sans-serif; +} + +.container { + background: #fff; + width: 100%; + max-width: 480px; + min-width: 320px; + margin: 2em auto 0; + padding: 1.5em; + opacity: 0.8; + border-radius: 1em; + border-color: #117; +} + +p { margin-bottom: 1.5em; } +p:last-child { margin-bottom: 0; } + +blockquote { + display: block; + border-width: 2px 0; + border-style: solid; + border-color: #eee; + padding: 1.5em 0 0.5em; + margin: 1.5em 0; + position: relative; + color: #117; +} +blockquote:before { + content: '\201C'; + position: absolute; + top: 0em; + left: 50%; + transform: translate(-50%, -50%); + background: #fff; + width: 3rem; + height: 2rem; + font: 6em/1.08em sans-serif; + color: #666; + text-align: center; +} +blockquote:after { + content: "\2013 \2003" attr(cite); + display: block; + text-align: right; + font-size: 0.875em; + color: #e70000; +} + +/* https://fdossena.com/?p=html5cool/buttons/i.frag */ +button { + display:inline-block; + padding:0.35em 1.2em; + border:0.1em solid #000; + margin:0 0.3em 0.3em 0; + border-radius:0.12em; + box-sizing: border-box; + text-decoration:none; + font-family:'Roboto',sans-serif; + font-weight:300; + font-size: 1em; + color:#000; + text-align:center; + transition: all 0.2s; +} +button:hover{ + color:#FFF; + background-color:#000; + cursor: pointer; +} \ No newline at end of file diff --git a/cmd/templates/vuewebpack/frontend/src/assets/fonts/LICENSE.txt b/cmd/templates/vuewebpack/frontend/src/assets/fonts/LICENSE.txt new file mode 100644 index 000000000..75b52484e --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/assets/fonts/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.eot b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.eot new file mode 100644 index 000000000..a0780d6e3 Binary files /dev/null and b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.eot differ diff --git a/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.svg b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.svg new file mode 100644 index 000000000..627f5a368 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.svg @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.ttf b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.ttf new file mode 100644 index 000000000..b91bf3f7e Binary files /dev/null and b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.ttf differ diff --git a/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff new file mode 100644 index 000000000..92dfacc61 Binary files /dev/null and b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff differ diff --git a/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff2 b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff2 new file mode 100644 index 000000000..7e854e669 Binary files /dev/null and b/cmd/templates/vuewebpack/frontend/src/assets/fonts/roboto/roboto-v18-latin-regular.woff2 differ diff --git a/cmd/templates/vuewebpack/frontend/src/assets/images/logo.png b/cmd/templates/vuewebpack/frontend/src/assets/images/logo.png new file mode 100644 index 000000000..31fc8249c Binary files /dev/null and b/cmd/templates/vuewebpack/frontend/src/assets/images/logo.png differ diff --git a/cmd/templates/vuewebpack/frontend/src/components/HelloWorld.vue b/cmd/templates/vuewebpack/frontend/src/components/HelloWorld.vue new file mode 100644 index 000000000..d231b0189 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/components/HelloWorld.vue @@ -0,0 +1,38 @@ + + + + + + diff --git a/cmd/templates/vuewebpack/frontend/src/components/Quote.vue b/cmd/templates/vuewebpack/frontend/src/components/Quote.vue new file mode 100644 index 000000000..a72a1d7ba --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/components/Quote.vue @@ -0,0 +1,54 @@ + + + + + + diff --git a/cmd/templates/vuewebpack/frontend/src/main.js b/cmd/templates/vuewebpack/frontend/src/main.js new file mode 100644 index 000000000..63eb05f71 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/src/main.js @@ -0,0 +1,8 @@ +import Vue from 'vue' +import App from './App.vue' + +Vue.config.productionTip = false + +new Vue({ + render: h => h(App), +}).$mount('#app') diff --git a/cmd/templates/vuewebpack/frontend/vue.config.js b/cmd/templates/vuewebpack/frontend/vue.config.js new file mode 100644 index 000000000..7df80db09 --- /dev/null +++ b/cmd/templates/vuewebpack/frontend/vue.config.js @@ -0,0 +1,35 @@ + +module.exports = { + chainWebpack: (config) => { + let limit = 9999999999999999; + config.module + .rule('images') + .test(/\.(png|gif|jpg)(\?.*)?$/i) + .use('url-loader') + .loader('url-loader') + .tap(options => Object.assign(options, { limit: limit })); + config.module + .rule('fonts') + .test(/\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/i) + .use('url-loader') + .loader('url-loader') + .options({ + limit: limit, + }) + }, + css: { + extract: { + filename: '[name].css', + chunkFilename: '[name].css', + } + }, + configureWebpack: { + output: { + filename: '[name].js', + }, + optimization: { + splitChunks: false + } + }, + +} diff --git a/cmd/templates/vuewebpack/main.go b/cmd/templates/vuewebpack/main.go new file mode 100644 index 000000000..088100122 --- /dev/null +++ b/cmd/templates/vuewebpack/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "github.com/gobuffalo/packr" + "github.com/wailsapp/wails" +) + +func main() { + + assets := packr.NewBox("./frontend/dist") + + app := wails.CreateApp(&wails.AppConfig{ + Width: 1024, + Height: 768, + Title: "Vue Simple", + JS: assets.String("app.js"), + CSS: assets.String("app.css"), + }) + app.Bind(newQuotesCollection()) + app.Run() +} diff --git a/cmd/templates/vuewebpack/quotes.go b/cmd/templates/vuewebpack/quotes.go new file mode 100644 index 000000000..d01b2f200 --- /dev/null +++ b/cmd/templates/vuewebpack/quotes.go @@ -0,0 +1,61 @@ +package main + +import ( + "math/rand" + "time" +) + +// Quote holds a single quote and the person who said it +type Quote struct { + Text string `json:"text"` + Person string `json:"person"` +} + +// QuotesCollection holds a collection of quotes! +type QuotesCollection struct { + quotes []*Quote +} + +// AddQuote creates a Quote object with the given inputs and +// adds it to the Quotes collection +func (Q *QuotesCollection) AddQuote(text, person string) { + Q.quotes = append(Q.quotes, &Quote{Text: text, Person: person}) +} + +// GetQuote returns a random Quote object from the Quotes collection +func (Q *QuotesCollection) GetQuote() *Quote { + return Q.quotes[rand.Intn(len(Q.quotes))] +} + +// newQuotesCollection creates a new QuotesCollection +func newQuotesCollection() *QuotesCollection { + result := &QuotesCollection{} + rand.Seed(time.Now().Unix()) + result.AddQuote("Age is an issue of mind over matter. If you don't mind, it doesn't matter", "Mark Twain") + result.AddQuote("Anyone who stops learning is old, whether at twenty or eighty. Anyone who keeps learning stays young. The greatest thing in life is to keep your mind young", "Henry Ford") + result.AddQuote("Wrinkles should merely indicate where smiles have been", "Mark Twain") + result.AddQuote("True terror is to wake up one morning and discover that your high school class is running the country", "Kurt Vonnegut") + result.AddQuote("A diplomat is a man who always remembers a woman's birthday but never remembers her age", "Robert Frost") + result.AddQuote("As I grow older, I pay less attention to what men say. I just watch what they do", "Andrew Carnegie") + result.AddQuote("How incessant and great are the ills with which a prolonged old age is replete", "C. S. Lewis") + result.AddQuote("Old age, believe me, is a good and pleasant thing. It is true you are gently shouldered off the stage, but then you are given such a comfortable front stall as spectator", "Confucius") + result.AddQuote("Old age has deformities enough of its own. It should never add to them the deformity of vice", "Eleanor Roosevelt") + result.AddQuote("Nobody grows old merely by living a number of years. We grow old by deserting our ideals. Years may wrinkle the skin, but to give up enthusiasm wrinkles the soul", "Samuel Ullman") + result.AddQuote("An archaeologist is the best husband a woman can have. The older she gets the more interested he is in her", "Agatha Christie") + result.AddQuote("All diseases run into one, old age", "Ralph Waldo Emerson") + result.AddQuote("Bashfulness is an ornament to youth, but a reproach to old age", "Aristotle") + result.AddQuote("Like everyone else who makes the mistake of getting older, I begin each day with coffee and obituaries", "Bill Cosby") + result.AddQuote("Age appears to be best in four things old wood best to burn, old wine to drink, old friends to trust, and old authors to read", "Francis Bacon") + result.AddQuote("None are so old as those who have outlived enthusiasm", "Henry David Thoreau") + result.AddQuote("Every man over forty is a scoundrel", "George Bernard Shaw") + result.AddQuote("Forty is the old age of youth fifty the youth of old age", "Victor Hugo") + result.AddQuote("You can't help getting older, but you don't have to get old", "George Burns") + result.AddQuote("Alas, after a certain age every man is responsible for his face", "Albert Camus") + result.AddQuote("Youth is when you're allowed to stay up late on New Year's Eve. Middle age is when you're forced to", "Bill Vaughan") + result.AddQuote("Old age is like everything else. To make a success of it, you've got to start young", "Theodore Roosevelt") + result.AddQuote("A comfortable old age is the reward of a well-spent youth. Instead of its bringing sad and melancholy prospects of decay, it would give us hopes of eternal youth in a better world", "Maurice Chevalier") + result.AddQuote("A man growing old becomes a child again", "Sophocles") + result.AddQuote("I will never be an old man. To me, old age is always 15 years older than I am", "Francis Bacon") + result.AddQuote("Age considers youth ventures", "Rabindranath Tagore") + return result +} diff --git a/cmd/templates/vuewebpack/template.json b/cmd/templates/vuewebpack/template.json new file mode 100644 index 000000000..c225d7e09 --- /dev/null +++ b/cmd/templates/vuewebpack/template.json @@ -0,0 +1,10 @@ +{ + "name": "Vue2/Webpack", + "shortdescription": "A basic Vue2/WebPack4 template", + "description": "A basic template using Vue 2 and bundled using Webpack 4", + "author": "Lea Anthony", + "created": "2018-12-01", + "frontenddir": "frontend", + "install": "npm install", + "build": "npm run build" +} \ No newline at end of file diff --git a/cmd/version.go b/cmd/version.go index 31f1d5364..4ef3ee547 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -2,4 +2,4 @@ package cmd // Version - Wails version // ...oO(There must be a better way) -const Version = "v0.5 Alpha" +const Version = "v0.5.0" diff --git a/cmd/wails/0_setup.go b/cmd/wails/0_setup.go index 790c646a7..25e322a67 100644 --- a/cmd/wails/0_setup.go +++ b/cmd/wails/0_setup.go @@ -1,10 +1,8 @@ package main import ( - "fmt" "runtime" - "github.com/leaanthony/spinner" "github.com/wailsapp/wails/cmd" ) @@ -19,83 +17,27 @@ func init() { setupCommand.Action(func() error { + var successMessage = `Ready for take off! +Create your first project by running 'wails init'.` + if runtime.GOOS != "windows" { + successMessage = "🚀 " + successMessage + } + system := cmd.NewSystemHelper() err := system.Initialise() if err != nil { return err } - var successMessage = `Ready for take off! -Create your first project by running 'wails init'.` - if runtime.GOOS != "windows" { - successMessage = "🚀 " + successMessage - } - switch runtime.GOOS { - case "darwin": - logger.Yellow("Detected Platform: OSX") - case "windows": - logger.Yellow("Detected Platform: Windows") - case "linux": - logger.Yellow("Detected Platform: Linux") - default: - return fmt.Errorf("Platform %s is currently not supported", runtime.GOOS) - } - - logger.Yellow("Checking for prerequisites...") - // Check we have a cgo capable environment - - requiredPrograms, err := cmd.GetRequiredPrograms() + err, success := cmd.CheckDependencies(logger) if err != nil { return err } - errors := false - spinner := spinner.New() - programHelper := cmd.NewProgramHelper() - for _, program := range *requiredPrograms { - spinner.Start("Looking for program '%s'", program.Name) - bin := programHelper.FindProgram(program.Name) - if bin == nil { - errors = true - spinner.Errorf("Program '%s' not found. %s", program.Name, program.Help) - } else { - spinner.Successf("Program '%s' found: %s", program.Name, bin.Path) - } - } - - // Linux has library deps - if runtime.GOOS == "linux" { - // Check library prerequisites - requiredLibraries, err := cmd.GetRequiredLibraries() - if err != nil { - return err - } - distroInfo := cmd.GetLinuxDistroInfo() - for _, library := range *requiredLibraries { - spinner.Start() - switch distroInfo.Distribution { - case cmd.Ubuntu: - installed, err := cmd.DpkgInstalled(library.Name) - if err != nil { - return err - } - if !installed { - errors = true - spinner.Errorf("Library '%s' not found. %s", library.Name, library.Help) - } else { - spinner.Successf("Library '%s' installed.", library.Name) - } - default: - return fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, library.Name) - } - } - } - logger.White("") - if !errors { + if success { logger.Yellow(successMessage) } - - return err + return nil }) } diff --git a/cmd/wails/1_init.go b/cmd/wails/1_init.go new file mode 100644 index 000000000..c3a053845 --- /dev/null +++ b/cmd/wails/1_init.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + + "github.com/wailsapp/wails/cmd" +) + +func init() { + + projectHelper := cmd.NewProjectHelper() + projectOptions := projectHelper.NewProjectOptions() + commandDescription := `Generates a new Wails project using the given flags. +Any flags that are required and not given will be prompted for.` + + initCommand := app.Command("init", "Initialises a new Wails project"). + LongDescription(commandDescription). + BoolFlag("f", "Use defaults", &projectOptions.UseDefaults). + StringFlag("dir", "Directory to create project in", &projectOptions.OutputDirectory). + StringFlag("template", "Template name", &projectOptions.Template). + StringFlag("name", "Project name", &projectOptions.Name). + StringFlag("description", "Project description", &projectOptions.Description). + StringFlag("output", "Output binary name", &projectOptions.BinaryName) + + initCommand.Action(func() error { + + logger.WhiteUnderline("Initialising project") + fmt.Println() + + // Check if the system is initialised + system := cmd.NewSystemHelper() + err := system.CheckInitialised() + if err != nil { + return err + } + + err, success := cmd.CheckDependencies(logger) + if !success { + return err + } + + logger.White("") + + // Do we want to just force defaults? + if projectOptions.UseDefaults { + // Use defaults + projectOptions.Defaults() + } else { + err = projectOptions.PromptForInputs() + if err != nil { + return err + } + } + + // Generate the project + err = projectHelper.GenerateProject(projectOptions) + if err != nil { + logger.Error(err.Error()) + } + return err + }) +} diff --git a/go.mod b/go.mod index d171210a6..92c424322 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,9 @@ module github.com/wailsapp/wails require ( github.com/AlecAivazis/survey v1.7.1 + github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc github.com/fatih/color v1.7.0 + github.com/gobuffalo/packr v1.21.9 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/leaanthony/spinner v0.4.0 github.com/leaanthony/synx v0.0.0-20180923230033-60efbd9984b0 // indirect diff --git a/go.sum b/go.sum index 1df5885c4..35b380abd 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,209 @@ github.com/AlecAivazis/survey v1.7.1 h1:a84v5MG2296rBkTP0e+dd4l7NxFQ69v4jzMpErkjVxc= github.com/AlecAivazis/survey v1.7.1/go.mod h1:MVECab6WqEH1aXhj8nKIwF7HEAJAj2bhhGiSjNy3wII= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= +github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/gobuffalo/buffalo v0.12.8-0.20181004233540-fac9bb505aa8/go.mod h1:sLyT7/dceRXJUxSsE813JTQtA3Eb1vjxWfo/N//vXIY= +github.com/gobuffalo/buffalo v0.13.0/go.mod h1:Mjn1Ba9wpIbpbrD+lIDMy99pQ0H0LiddMIIDGse7qT4= +github.com/gobuffalo/buffalo-plugins v1.0.2/go.mod h1:pOp/uF7X3IShFHyobahTkTLZaeUXwb0GrUTb9ngJWTs= +github.com/gobuffalo/buffalo-plugins v1.0.4/go.mod h1:pWS1vjtQ6uD17MVFWf7i3zfThrEKWlI5+PYLw/NaDB4= +github.com/gobuffalo/buffalo-plugins v1.4.3/go.mod h1:uCzTY0woez4nDMdQjkcOYKanngeUVRO2HZi7ezmAjWY= +github.com/gobuffalo/buffalo-plugins v1.5.1/go.mod h1:jbmwSZK5+PiAP9cC09VQOrGMZFCa/P0UMlIS3O12r5w= +github.com/gobuffalo/buffalo-plugins v1.6.4/go.mod h1:/+N1aophkA2jZ1ifB2O3Y9yGwu6gKOVMtUmJnbg+OZI= +github.com/gobuffalo/buffalo-plugins v1.6.5/go.mod h1:0HVkbgrVs/MnPZ/FOseDMVanCTm2RNcdM0PuXcL1NNI= +github.com/gobuffalo/buffalo-plugins v1.6.7/go.mod h1:ZGZRkzz2PiKWHs0z7QsPBOTo2EpcGRArMEym6ghKYgk= +github.com/gobuffalo/buffalo-plugins v1.6.9/go.mod h1:yYlYTrPdMCz+6/+UaXg5Jm4gN3xhsvsQ2ygVatZV5vw= +github.com/gobuffalo/buffalo-plugins v1.6.11/go.mod h1:eAA6xJIL8OuynJZ8amXjRmHND6YiusVAaJdHDN1Lu8Q= +github.com/gobuffalo/buffalo-plugins v1.8.2/go.mod h1:9te6/VjEQ7pKp7lXlDIMqzxgGpjlKoAcAANdCgoR960= +github.com/gobuffalo/buffalo-plugins v1.8.3/go.mod h1:IAWq6vjZJVXebIq2qGTLOdlXzmpyTZ5iJG5b59fza5U= +github.com/gobuffalo/buffalo-pop v1.0.5/go.mod h1:Fw/LfFDnSmB/vvQXPvcXEjzP98Tc+AudyNWUBWKCwQ8= +github.com/gobuffalo/envy v1.6.4/go.mod h1:Abh+Jfw475/NWtYMEt+hnJWRiC8INKWibIMyNt1w2Mc= +github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.6/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.7/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.8/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.9/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= +github.com/gobuffalo/envy v1.6.10/go.mod h1:X0CFllQjTV5ogsnUrg+Oks2yTI+PU2dGYBJOEI2D1Uo= +github.com/gobuffalo/envy v1.6.11 h1:dCKSFypLRvqaaUtyzkfKKF2j35ce5agsqfyIrRmm02E= +github.com/gobuffalo/envy v1.6.11/go.mod h1:Fiq52W7nrHGDggFPhn2ZCcHw4u/rqXkqo+i7FB6EAcg= +github.com/gobuffalo/events v1.0.3/go.mod h1:Txo8WmqScapa7zimEQIwgiJBvMECMe9gJjsKNPN3uZw= +github.com/gobuffalo/events v1.0.7/go.mod h1:z8txf6H9jWhQ5Scr7YPLWg/cgXBRj8Q4uYI+rsVCCSQ= +github.com/gobuffalo/events v1.0.8/go.mod h1:A5KyqT1sA+3GJiBE4QKZibse9mtOcI9nw8gGrDdqYGs= +github.com/gobuffalo/events v1.1.3/go.mod h1:9yPGWYv11GENtzrIRApwQRMYSbUgCsZ1w6R503fCfrk= +github.com/gobuffalo/events v1.1.4/go.mod h1:09/YRRgZHEOts5Isov+g9X2xajxdvOAcUuAHIX/O//A= +github.com/gobuffalo/events v1.1.5/go.mod h1:3YUSzgHfYctSjEjLCWbkXP6djH2M+MLaVRzb4ymbAK0= +github.com/gobuffalo/events v1.1.7/go.mod h1:6fGqxH2ing5XMb3EYRq9LEkVlyPGs4oO/eLzh+S8CxY= +github.com/gobuffalo/events v1.1.8/go.mod h1:UFy+W6X6VbCWS8k2iT81HYX65dMtiuVycMy04cplt/8= +github.com/gobuffalo/fizz v1.0.12/go.mod h1:C0sltPxpYK8Ftvf64kbsQa2yiCZY4RZviurNxXdAKwc= +github.com/gobuffalo/flect v0.0.0-20180907193754-dc14d8acaf9f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181002182613-4571df4b1daf/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181007231023-ae7ed6bfe683/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181018182602-fd24a256709f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181019110701-3d6f0b585514/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181024204909-8f6be1a8c6c2/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181104133451-1f6e9779237a/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA= +github.com/gobuffalo/flect v0.0.0-20181114183036-47375f6d8328/go.mod h1:0HvNbHdfh+WOvDSIASqJOSxTOWSxCCUF++k/Y53v9rI= +github.com/gobuffalo/genny v0.0.0-20180924032338-7af3a40f2252/go.mod h1:tUTQOogrr7tAQnhajMSH6rv1BVev34H2sa1xNHMy94g= +github.com/gobuffalo/genny v0.0.0-20181003150629-3786a0744c5d/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM= +github.com/gobuffalo/genny v0.0.0-20181005145118-318a41a134cc/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM= +github.com/gobuffalo/genny v0.0.0-20181007153042-b8de7d566757/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA= +github.com/gobuffalo/genny v0.0.0-20181012161047-33e5f43d83a6/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA= +github.com/gobuffalo/genny v0.0.0-20181017160347-90a774534246/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA= +github.com/gobuffalo/genny v0.0.0-20181024195656-51392254bf53/go.mod h1:o9GEH5gn5sCKLVB5rHFC4tq40rQ3VRUzmx6WwmaqISE= +github.com/gobuffalo/genny v0.0.0-20181025145300-af3f81d526b8/go.mod h1:uZ1fFYvdcP8mu0B/Ynarf6dsGvp7QFIpk/QACUuFUVI= +github.com/gobuffalo/genny v0.0.0-20181027191429-94d6cfb5c7fc/go.mod h1:x7SkrQQBx204Y+O9EwRXeszLJDTaWN0GnEasxgLrQTA= +github.com/gobuffalo/genny v0.0.0-20181027195209-3887b7171c4f/go.mod h1:JbKx8HSWICu5zyqWOa0dVV1pbbXOHusrSzQUprW6g+w= +github.com/gobuffalo/genny v0.0.0-20181106193839-7dcb0924caf1/go.mod h1:x61yHxvbDCgQ/7cOAbJCacZQuHgB0KMSzoYcw5debjU= +github.com/gobuffalo/genny v0.0.0-20181107223128-f18346459dbe/go.mod h1:utQD3aKKEsdb03oR+Vi/6ztQb1j7pO10N3OBoowRcSU= +github.com/gobuffalo/genny v0.0.0-20181114215459-0a4decd77f5d/go.mod h1:kN2KZ8VgXF9VIIOj/GM0Eo7YK+un4Q3tTreKOf0q1ng= +github.com/gobuffalo/genny v0.0.0-20181119162812-e8ff4adce8bb/go.mod h1:BA9htSe4bZwBDJLe8CUkoqkypq3hn3+CkoHqVOW718E= +github.com/gobuffalo/genny v0.0.0-20181127225641-2d959acc795b/go.mod h1:l54xLXNkteX/PdZ+HlgPk1qtcrgeOr3XUBBPDbH+7CQ= +github.com/gobuffalo/genny v0.0.0-20181128191930-77e34f71ba2a/go.mod h1:FW/D9p7cEEOqxYA71/hnrkOWm62JZ5ZNxcNIVJEaWBU= +github.com/gobuffalo/genny v0.0.0-20181203165245-fda8bcce96b1/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM= +github.com/gobuffalo/genny v0.0.0-20181203201232-849d2c9534ea/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM= +github.com/gobuffalo/genny v0.0.0-20181206121324-d6fb8a0dbe36/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM= +github.com/gobuffalo/genny v0.0.0-20181207164119-84844398a37d/go.mod h1:y0ysCHGGQf2T3vOhCrGHheYN54Y/REj0ayd0Suf4C/8= +github.com/gobuffalo/genny v0.0.0-20181211165820-e26c8466f14d/go.mod h1:sHnK+ZSU4e2feXP3PA29ouij6PUEiN+RCwECjCTB3yM= +github.com/gobuffalo/github_flavored_markdown v1.0.4/go.mod h1:uRowCdK+q8d/RF0Kt3/DSalaIXbb0De/dmTqMQdkQ4I= +github.com/gobuffalo/github_flavored_markdown v1.0.5/go.mod h1:U0643QShPF+OF2tJvYNiYDLDGDuQmJZXsf/bHOJPsMY= +github.com/gobuffalo/github_flavored_markdown v1.0.7/go.mod h1:w93Pd9Lz6LvyQXEG6DktTPHkOtCbr+arAD5mkwMzXLI= +github.com/gobuffalo/httptest v1.0.2/go.mod h1:7T1IbSrg60ankme0aDLVnEY0h056g9M1/ZvpVThtB7E= +github.com/gobuffalo/licenser v0.0.0-20180924033006-eae28e638a42/go.mod h1:Ubo90Np8gpsSZqNScZZkVXXAo5DGhTb+WYFIjlnog8w= +github.com/gobuffalo/licenser v0.0.0-20181025145548-437d89de4f75/go.mod h1:x3lEpYxkRG/XtGCUNkio+6RZ/dlOvLzTI9M1auIwFcw= +github.com/gobuffalo/licenser v0.0.0-20181027200154-58051a75da95/go.mod h1:BzhaaxGd1tq1+OLKObzgdCV9kqVhbTulxOpYbvMQWS0= +github.com/gobuffalo/licenser v0.0.0-20181109171355-91a2a7aac9a7/go.mod h1:m+Ygox92pi9bdg+gVaycvqE8RVSjZp7mWw75+K5NPHk= +github.com/gobuffalo/licenser v0.0.0-20181128165715-cc7305f8abed/go.mod h1:oU9F9UCE+AzI/MueCKZamsezGOOHfSirltllOVeRTAE= +github.com/gobuffalo/licenser v0.0.0-20181203160806-fe900bbede07/go.mod h1:ph6VDNvOzt1CdfaWC+9XwcBnlSTBz2j49PBwum6RFaU= +github.com/gobuffalo/logger v0.0.0-20181022175615-46cfb361fc27/go.mod h1:8sQkgyhWipz1mIctHF4jTxmJh1Vxhp7mP8IqbljgJZo= +github.com/gobuffalo/logger v0.0.0-20181027144941-73d08d2bb969/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8= +github.com/gobuffalo/logger v0.0.0-20181027193913-9cf4dd0efe46/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8= +github.com/gobuffalo/logger v0.0.0-20181109185836-3feeab578c17/go.mod h1:oNErH0xLe+utO+OW8ptXMSA5DkiSEDW1u3zGIt8F9Ew= +github.com/gobuffalo/logger v0.0.0-20181117211126-8e9b89b7c264/go.mod h1:5etB91IE0uBlw9k756fVKZJdS+7M7ejVhmpXXiSFj0I= +github.com/gobuffalo/logger v0.0.0-20181127160119-5b956e21995c/go.mod h1:+HxKANrR9VGw9yN3aOAppJKvhO05ctDi63w4mDnKv2U= +github.com/gobuffalo/makr v1.1.5/go.mod h1:Y+o0btAH1kYAMDJW/TX3+oAXEu0bmSLLoC9mIFxtzOw= +github.com/gobuffalo/mapi v1.0.0/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/meta v0.0.0-20181018155829-df62557efcd3/go.mod h1:XTTOhwMNryif3x9LkTTBO/Llrveezd71u3quLd0u7CM= +github.com/gobuffalo/meta v0.0.0-20181018192820-8c6cef77dab3/go.mod h1:E94EPzx9NERGCY69UWlcj6Hipf2uK/vnfrF4QD0plVE= +github.com/gobuffalo/meta v0.0.0-20181025145500-3a985a084b0a/go.mod h1:YDAKBud2FP7NZdruCSlmTmDOZbVSa6bpK7LJ/A/nlKg= +github.com/gobuffalo/meta v0.0.0-20181114191255-b130ebedd2f7/go.mod h1:K6cRZ29ozr4Btvsqkjvg5nDFTLOgTqf03KA70Ks0ypE= +github.com/gobuffalo/meta v0.0.0-20181127070345-0d7e59dd540b/go.mod h1:RLO7tMvE0IAKAM8wny1aN12pvEKn7EtkBLkUZR00Qf8= +github.com/gobuffalo/mw-basicauth v1.0.3/go.mod h1:dg7+ilMZOKnQFHDefUzUHufNyTswVUviCBgF244C1+0= +github.com/gobuffalo/mw-contenttype v0.0.0-20180802152300-74f5a47f4d56/go.mod h1:7EvcmzBbeCvFtQm5GqF9ys6QnCxz2UM1x0moiWLq1No= +github.com/gobuffalo/mw-csrf v0.0.0-20180802151833-446ff26e108b/go.mod h1:sbGtb8DmDZuDUQoxjr8hG1ZbLtZboD9xsn6p77ppcHo= +github.com/gobuffalo/mw-forcessl v0.0.0-20180802152810-73921ae7a130/go.mod h1:JvNHRj7bYNAMUr/5XMkZaDcw3jZhUZpsmzhd//FFWmQ= +github.com/gobuffalo/mw-i18n v0.0.0-20180802152014-e3060b7e13d6/go.mod h1:91AQfukc52A6hdfIfkxzyr+kpVYDodgAeT5cjX1UIj4= +github.com/gobuffalo/mw-paramlogger v0.0.0-20181005191442-d6ee392ec72e/go.mod h1:6OJr6VwSzgJMqWMj7TYmRUqzNe2LXu/W1rRW4MAz/ME= +github.com/gobuffalo/mw-tokenauth v0.0.0-20181001105134-8545f626c189/go.mod h1:UqBF00IfKvd39ni5+yI5MLMjAf4gX7cDKN/26zDOD6c= +github.com/gobuffalo/packd v0.0.0-20181027182251-01ad393492c8/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc= +github.com/gobuffalo/packd v0.0.0-20181027190505-aafc0d02c411/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc= +github.com/gobuffalo/packd v0.0.0-20181027194105-7ae579e6d213/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc= +github.com/gobuffalo/packd v0.0.0-20181031195726-c82734870264/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181104210303-d376b15f8e96/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181111195323-b2e760a5f0ff/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181114190715-f25c5d2471d7/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI= +github.com/gobuffalo/packd v0.0.0-20181124090624-311c6248e5fb/go.mod h1:Foenia9ZvITEvG05ab6XpiD5EfBHPL8A6hush8SJ0o8= +github.com/gobuffalo/packd v0.0.0-20181207120301-c49825f8f6f4/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA= +github.com/gobuffalo/packd v0.0.0-20181212173646-eca3b8fd6687 h1:uZ+G4JprR0UEq0aHZs+6eP7TEZuFfrIkmQWejIBV/QQ= +github.com/gobuffalo/packd v0.0.0-20181212173646-eca3b8fd6687/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA= +github.com/gobuffalo/packr v1.13.7/go.mod h1:KkinLIn/n6+3tVXMwg6KkNvWwVsrRAz4ph+jgpk3Z24= +github.com/gobuffalo/packr v1.15.0/go.mod h1:t5gXzEhIviQwVlNx/+3SfS07GS+cZ2hn76WLzPp6MGI= +github.com/gobuffalo/packr v1.15.1/go.mod h1:IeqicJ7jm8182yrVmNbM6PR4g79SjN9tZLH8KduZZwE= +github.com/gobuffalo/packr v1.19.0/go.mod h1:MstrNkfCQhd5o+Ct4IJ0skWlxN8emOq8DsoT1G98VIU= +github.com/gobuffalo/packr v1.20.0/go.mod h1:JDytk1t2gP+my1ig7iI4NcVaXr886+N0ecUga6884zw= +github.com/gobuffalo/packr v1.21.0/go.mod h1:H00jGfj1qFKxscFJSw8wcL4hpQtPe1PfU2wa6sg/SR0= +github.com/gobuffalo/packr v1.21.9 h1:zBaEhCmJpYy/UdHGAGIC3vO5Uh7RW091le41+Ydcg4E= +github.com/gobuffalo/packr v1.21.9/go.mod h1:GC76q6nMzRtR+AEN/VV4w0z2/4q7SOaEmXh3Ooa8sOE= +github.com/gobuffalo/packr/v2 v2.0.0-rc.8/go.mod h1:y60QCdzwuMwO2R49fdQhsjCPv7tLQFR0ayzxxla9zes= +github.com/gobuffalo/packr/v2 v2.0.0-rc.9/go.mod h1:fQqADRfZpEsgkc7c/K7aMew3n4aF1Kji7+lIZeR98Fc= +github.com/gobuffalo/packr/v2 v2.0.0-rc.10/go.mod h1:4CWWn4I5T3v4c1OsJ55HbHlUEKNWMITG5iIkdr4Px4w= +github.com/gobuffalo/packr/v2 v2.0.0-rc.11/go.mod h1:JoieH/3h3U4UmatmV93QmqyPUdf4wVM9HELaHEu+3fk= +github.com/gobuffalo/packr/v2 v2.0.0-rc.12/go.mod h1:FV1zZTsVFi1DSCboO36Xgs4pzCZBjB/tDV9Cz/lSaR8= +github.com/gobuffalo/packr/v2 v2.0.0-rc.13/go.mod h1:2Mp7GhBFMdJlOK8vGfl7SYtfMP3+5roE39ejlfjw0rA= +github.com/gobuffalo/plush v3.7.16+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.20+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.21+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.22+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.23+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.30+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.31+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plush v3.7.32+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI= +github.com/gobuffalo/plushgen v0.0.0-20181128164830-d29dcb966cb2/go.mod h1:r9QwptTFnuvSaSRjpSp4S2/4e2D3tJhARYbvEBcKSb4= +github.com/gobuffalo/plushgen v0.0.0-20181203163832-9fc4964505c2/go.mod h1:opEdT33AA2HdrIwK1aibqnTJDVVKXC02Bar/GT1YRVs= +github.com/gobuffalo/plushgen v0.0.0-20181207152837-eedb135bd51b/go.mod h1:Lcw7HQbEVm09sAQrCLzIxuhFbB3nAgp4c55E+UlynR0= +github.com/gobuffalo/pop v4.8.2+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg= +github.com/gobuffalo/pop v4.8.3+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg= +github.com/gobuffalo/pop v4.8.4+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg= +github.com/gobuffalo/release v1.0.35/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4= +github.com/gobuffalo/release v1.0.38/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4= +github.com/gobuffalo/release v1.0.42/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug= +github.com/gobuffalo/release v1.0.52/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug= +github.com/gobuffalo/release v1.0.53/go.mod h1:FdF257nd8rqhNaqtDWFGhxdJ/Ig4J7VcS3KL7n/a+aA= +github.com/gobuffalo/release v1.0.54/go.mod h1:Pe5/RxRa/BE8whDpGfRqSI7D1a0evGK1T4JDm339tJc= +github.com/gobuffalo/release v1.0.61/go.mod h1:mfIO38ujUNVDlBziIYqXquYfBF+8FDHUjKZgYC1Hj24= +github.com/gobuffalo/release v1.0.72/go.mod h1:NP5NXgg/IX3M5XmHmWR99D687/3Dt9qZtTK/Lbwc1hU= +github.com/gobuffalo/release v1.1.1/go.mod h1:Sluak1Xd6kcp6snkluR1jeXAogdJZpFFRzTYRs/2uwg= +github.com/gobuffalo/release v1.1.3/go.mod h1:CuXc5/m+4zuq8idoDt1l4va0AXAn/OSs08uHOfMVr8E= +github.com/gobuffalo/shoulders v1.0.1/go.mod h1:V33CcVmaQ4gRUmHKwq1fiTXuf8Gp/qjQBUL5tHPmvbA= +github.com/gobuffalo/syncx v0.0.0-20181120191700-98333ab04150/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobuffalo/syncx v0.0.0-20181120194010-558ac7de985f h1:S5EeH1reN93KR0L6TQvkRpu9YggCYXrUqFh1iEgvdC0= +github.com/gobuffalo/syncx v0.0.0-20181120194010-558ac7de985f/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/gobuffalo/tags v2.0.11+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY= +github.com/gobuffalo/tags v2.0.14+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY= +github.com/gobuffalo/uuid v2.0.3+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE= +github.com/gobuffalo/uuid v2.0.4+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE= +github.com/gobuffalo/uuid v2.0.5+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE= +github.com/gobuffalo/validate v2.0.3+incompatible/go.mod h1:N+EtDe0J8252BgfzQUChBgfd6L93m9weay53EWFVsMM= +github.com/gobuffalo/x v0.0.0-20181003152136-452098b06085/go.mod h1:WevpGD+5YOreDJznWevcn8NTmQEW5STSBgIkpkjzqXc= +github.com/gobuffalo/x v0.0.0-20181007152206-913e47c59ca7/go.mod h1:9rDPXaB3kXdKWzMc4odGQQdG2e2DIEmANy5aSJ9yesY= +github.com/gofrs/uuid v3.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.1.2/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= +github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= +github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= +github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= +github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= +github.com/karrick/godirwalk v1.7.7/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/leaanthony/spinner v0.4.0 h1:y/7FqQqqObRKYI+33bg9DGhHIY7cQHicm+Vz0Uda0Ik= github.com/leaanthony/spinner v0.4.0/go.mod h1:2Mmv+8Brcw3NwPT1DdOLmW6+zWpSamDDFFsUvVHo2cc= github.com/leaanthony/spinner v0.5.0 h1:OJKn+0KP6ilHxwCEOv5Lo0wPM4PgWZWLJTeUprGJK0g= @@ -12,14 +212,160 @@ github.com/leaanthony/synx v0.0.0-20180923230033-60efbd9984b0 h1:1bGojw4YacLY5bq github.com/leaanthony/synx v0.0.0-20180923230033-60efbd9984b0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs= github.com/leaanthony/wincursor v0.0.0-20180705115120-056510f32d15 h1:166LIty6ldcyOc7tbgfu5smsGATvEo0JZV6bnbzyEc4= github.com/leaanthony/wincursor v0.0.0-20180705115120-056510f32d15/go.mod h1:7TVwwrzSH/2Y9gLOGH+VhA+bZhoWXBRgbGNTMk+yimE= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/markbates/deplist v1.0.4/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM= +github.com/markbates/deplist v1.0.5/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM= +github.com/markbates/going v1.0.2/go.mod h1:UWCk3zm0UKefHZ7l8BNqi26UyiEMniznk8naLdTcy6c= +github.com/markbates/grift v1.0.4/go.mod h1:wbmtW74veyx+cgfwFhlnnMWqhoz55rnHR47oMXzsyVs= +github.com/markbates/hmax v1.0.0/go.mod h1:cOkR9dktiESxIMu+65oc/r/bdY4bE8zZw3OLhLx0X2c= +github.com/markbates/inflect v1.0.0/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88= +github.com/markbates/inflect v1.0.1/go.mod h1:uv3UVNBe5qBIfCm8O8Q+DW+S1EopeyINj+Ikhc7rnCk= +github.com/markbates/inflect v1.0.3/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= +github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= +github.com/markbates/oncer v0.0.0-20180924031910-e862a676800b/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v0.0.0-20180924034138-723ad0170a46/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v0.0.0-20181014194634-05fccaae8fc4/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2 h1:JgVTCPf0uBVcUSWpyXmGpgOc62nK5HWUBKAGc3Qqa5k= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/refresh v1.4.10/go.mod h1:NDPHvotuZmTmesXxr95C9bjlw1/0frJwtME2dzcVKhc= +github.com/markbates/safe v1.0.0/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/markbates/sigtx v1.0.0/go.mod h1:QF1Hv6Ic6Ca6W+T+DL0Y/ypborFKyvUY9HmuCD4VeTc= +github.com/markbates/willie v1.0.9/go.mod h1:fsrFVWl91+gXpx/6dv715j7i11fYPfZ9ZGfH0DQzY7w= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/monoculum/formam v0.0.0-20180901015400-4e68be1d79ba/go.mod h1:RKgILGEJq24YyJ2ban8EO0RUVSJlF1pGsEvoLEACr/Q= +github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.0.0 h1:o4VLZ5jqHE+HahLT6drNtSGTrrUA3wPBmtpgqtdbClo= +github.com/rogpeppe/go-internal v1.0.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20170515013102-78fb10f4a5f8/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/octicon v0.0.0-20180602230221-c42b0e3b24d9/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.1.0/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= +github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI= +github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/unrolled/secure v0.0.0-20180918153822-f340ee86eb8b/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA= +github.com/unrolled/secure v0.0.0-20181005190816-ff9db2ff917f/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA= github.com/wailsapp/wails v0.0.0-20181215232634-5de8efff325d h1:lk91T4sKD98eGcaz/xC6ER+3o9Kaun7Mk8e/cNZOPMc= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181024171144-74cb1d3d52f4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181025113841-85e1b3f9139a/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180816102801-aaf60122140d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180921000356-2f5d2388922f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181017193950-04a2e542c03f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181207154023-610586996380/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180921163948-d47a0f339242/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180927150500-dad3d9fb7b6e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181011152604-fa43e7bc11ba/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181022134430-8a28ead16f52/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181024145615-5cd93ef61a7c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181025063200-d989b31c8746/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026064943-731415f00dce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181106135930-3a76605856fd/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181003024731-2f84ea8ef872/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181006002542-f60d9635b16a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181013182035-5e66757b835f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181017214349-06f26fdaaa28/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181024171208-a2dc47679d30/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181105230042-78dc5bac0cac/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181107215632-34b416bd17b3/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181114190951-94339b83286c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181119130350-139d099f6620/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181127195227-b4e97c0ed882/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181127232545-e782529d0ddd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181203210056-e5f3ab76ea4b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181205224935-3576414c54a4/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181206194817-bcd4e47d0288/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181207183836-8bc39b988060/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181212172921-837e80568c09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/AlecAivazis/survey.v1 v1.7.1 h1:mzQIVyOPSXJaQWi1m6AFCjrCEPIwQBSOn48Ri8ZpzAg= gopkg.in/AlecAivazis/survey.v1 v1.7.1/go.mod h1:2Ehl7OqkBl3Xb8VmC4oFW2bItAhnUfzIjrOzwRxCrOU= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/mail.v2 v2.0.0-20180731213649-a0242b2233b4/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=