Compare commits

..

39 Commits

Author SHA1 Message Date
Lea Anthony
1ce0620620 Merge pull request #107 from wailsapp/develop
Release v0.15.0
2019-05-26 14:03:47 +10:00
Lea Anthony
249a35f90f chore: release v0.15.0 2019-05-26 13:56:27 +10:00
Lea Anthony
d003de3270 chore: remove old package-lock.json 2019-05-26 13:46:51 +10:00
Lea Anthony
9cb2ed10b5 Update CONTRIBUTORS.md 2019-05-26 13:32:55 +10:00
Lea Anthony
4a376f1b67 fix: windows spinner 2019-05-25 12:22:20 +10:00
Lea Anthony
c540f3902c fix: polyfill for windows 2019-05-25 12:19:03 +10:00
Lea Anthony
accc04ef90 chore: version bump 2019-05-25 11:30:01 +10:00
Lea Anthony
d54bd3dc54 Merge pull request #106 from wailsapp/105-create-vuetify-template
Create vuetify template
2019-05-25 11:20:37 +10:00
Lea Anthony
a54bbb4e14 chore: linting fixes 2019-05-25 11:17:39 +10:00
Lea Anthony
6b1b999546 feat: add vuetify template 2019-05-25 11:13:34 +10:00
Lea Anthony
a5aeafc4bc chore: version bump 2019-05-25 09:28:21 +10:00
Lea Anthony
39ea5cc456 Update bug_report.md 2019-05-24 08:17:05 +10:00
Lea Anthony
a225b8d50a Update bug_report.md 2019-05-24 08:13:56 +10:00
Lea Anthony
e0036b1cbb Update bug_report.md 2019-05-24 08:11:18 +10:00
Lea Anthony
9a5833f7c9 Merge pull request #102 from wailsapp/98-use-snap-command
fix: use snap command for linux
2019-05-23 08:58:00 +10:00
Lea Anthony
06a1372e80 fix: use snap command for linux 2019-05-23 08:57:11 +10:00
Lea Anthony
7a16cf74f0 docs: mandate go 1.12 2019-05-22 19:25:09 +10:00
Lea Anthony
4239c89b76 Merge pull request #100 from wailsapp/99-update-issue-template
fix: align with new bug template
2019-05-22 19:14:46 +10:00
Lea Anthony
29ea5cc74d fix: slign with new bug template 2019-05-22 19:13:17 +10:00
Lea Anthony
fa27be083d Update bug_report.md 2019-05-22 19:09:50 +10:00
Lea Anthony
9be56c47e4 chore: reset version 2019-05-22 08:35:38 +10:00
Lea Anthony
249720b0cc chore: version bump 2019-05-22 08:30:24 +10:00
Lea Anthony
3553cb6694 Merge pull request #97 from wailsapp/92-build-on-first-init
92 build on first init
2019-05-22 07:27:19 +10:00
Lea Anthony
3c0fa4c55e chore: lint fixes 2019-05-22 07:25:42 +10:00
Lea Anthony
c07a4b6c16 Merge branch 'develop' into 92-build-on-first-init 2019-05-22 00:56:30 +10:00
Lea Anthony
8175eb4446 chore: version bump 2019-05-22 00:50:28 +10:00
Lea Anthony
eeab418c90 fix: version issue 2019-05-22 00:43:56 +10:00
Lea Anthony
0eb59d823e fix: version craziness 2019-05-22 00:42:17 +10:00
Lea Anthony
f07705268d feat: moar spinners 2019-05-20 23:53:14 +10:00
Lea Anthony
63fef39854 feat: build on init 2019-05-20 23:40:17 +10:00
Lea Anthony
3ea45da2c8 chore: version bump v0.14.5-pre 2019-05-20 20:47:35 +10:00
Lea Anthony
eb0d9f3ba4 Merge pull request #96 from wailsapp/91-create-developer-tooling
91 create developer tooling
2019-05-20 18:58:43 +10:00
Lea Anthony
8432f725a9 chore: updated go mod files 2019-05-20 18:45:01 +10:00
Lea Anthony
7015b80888 feat: new template generator 2019-05-20 18:44:14 +10:00
Lea Anthony
ddcc103f37 Update README.md 2019-05-19 13:56:58 +10:00
Lea Anthony
1ac16d1933 fix: minor fixes 2019-05-18 07:34:39 +10:00
Lea Anthony
0f36a88f0e feat: add Manjaro support 2019-05-18 07:18:34 +10:00
Lea Anthony
b30031d025 feat: multiple template support 2019-05-18 07:15:15 +10:00
Lea Anthony
b849964562 docs: fix awesomego link 2019-05-12 22:18:19 +10:00
33 changed files with 812 additions and 11351 deletions

View File

@@ -7,6 +7,11 @@ assignees: ''
--- ---
#####################################################
If you have a technical issue, please do not open a bug this way!
Please use the `wails issue` command!
#####################################################
**Description** **Description**
A clear and concise description of what the bug is. A clear and concise description of what the bug is.
@@ -24,7 +29,7 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**System Details** **System Details**
Please paste the output of `wails report` here. Please provide your platform, GO version and variables, etc
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

23
.vscode/launch.json vendored
View File

@@ -5,12 +5,33 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Launch", "name": "Wails Init",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "auto", "mode": "auto",
"program": "${workspaceFolder}/cmd/wails/main.go", "program": "${workspaceFolder}/cmd/wails/main.go",
"env": {}, "env": {},
"cwd": "/tmp",
"args": [
"init",
"-name",
"runtime",
"-dir",
"runtime",
"-output",
"runtime",
"-template",
"vuebasic"
]
},
{
"name": "Wails Update Pre",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/wails/main.go",
"env": {},
"cwd": "/tmp",
"args": [ "args": [
"update", "update",
"-pre" "-pre"

View File

@@ -8,5 +8,6 @@ Wails is what it is because of the time and effort given by these great people.
* [Adrian Lanzafame](https://github.com/lanzafame) * [Adrian Lanzafame](https://github.com/lanzafame)
* [0xflotus](https://github.com/0xflotus) * [0xflotus](https://github.com/0xflotus)
* [Michael D Henderson](https://github.com/mdhender) * [Michael D Henderson](https://github.com/mdhender)
* [fred2104] (https://github.com/fishfishfish2104) * [fred2104](https://github.com/fishfishfish2104)
* [intelwalk] (https://github.com/intelwalk) * [intelwalk](https://github.com/intelwalk)
* [admin_3.exe](https://github.com/bh90210)

View File

@@ -9,7 +9,7 @@
<a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a> <a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a>
<a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a> <a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a> <a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
<a href="https://github.com/sindresorhus/awesome" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>- <a href="https://github.com/avelino/awesome-go" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>
</p> </p>
The traditional method of providing web interfaces to Go programs is via a built-in web server. Wails offers a different approach: it provides the ability to wrap both Go code and a web frontend into a single binary. Tools are provided to make this easy for you by handling project creation, compilation and bundling. All you have to do is get creative! The traditional method of providing web interfaces to Go programs is via a built-in web server. Wails offers a different approach: it provides the ability to wrap both Go code and a web frontend into a single binary. Tools are provided to make this easy for you by handling project creation, compilation and bundling. All you have to do is get creative!
@@ -33,7 +33,7 @@ Wails is currently in Beta. Please make sure you read the [Project Status](https
Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are: Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are:
- Go 1.11 or above - Go 1.12
- npm - npm
### MacOS ### MacOS
@@ -64,6 +64,8 @@ Windows requires gcc and related tooling. The recommended download is from [http
## Installation ## Installation
**Ensure Go modules are enabled: GO111MODULE=on and go/bin is in your PATH variable.**
Installation is as simple as running the following command: Installation is as simple as running the following command:
<pre style='color:white'> <pre style='color:white'>

View File

@@ -96,6 +96,7 @@ type Command struct {
flagCount int flagCount int
log *Logger log *Logger
helpFlag bool helpFlag bool
hidden bool
} }
// NewCommand creates a new Command // NewCommand creates a new Command
@@ -106,6 +107,7 @@ func NewCommand(name string, description string, app *Cli, parentCommandPath str
SubCommandsMap: make(map[string]*Command), SubCommandsMap: make(map[string]*Command),
App: app, App: app,
log: NewLogger(), log: NewLogger(),
hidden: false,
} }
// Set up command path // Set up command path
@@ -212,6 +214,9 @@ func (c *Command) PrintHelp() {
c.log.White("Available commands:") c.log.White("Available commands:")
fmt.Println("") fmt.Println("")
for _, subcommand := range c.SubCommands { for _, subcommand := range c.SubCommands {
if subcommand.isHidden() {
continue
}
spacer := strings.Repeat(" ", 3+c.longestSubcommand-len(subcommand.Name)) spacer := strings.Repeat(" ", 3+c.longestSubcommand-len(subcommand.Name))
isDefault := "" isDefault := ""
if subcommand.isDefaultCommand() { if subcommand.isDefaultCommand() {
@@ -237,6 +242,16 @@ func (c *Command) isDefaultCommand() bool {
return c.App.defaultCommand == c return c.App.defaultCommand == c
} }
// isHidden returns true if the command is a hidden command
func (c *Command) isHidden() bool {
return c.hidden
}
// Hidden hides the command from the Help system
func (c *Command) Hidden() {
c.hidden = true
}
// Command - Defines a subcommand // Command - Defines a subcommand
func (c *Command) Command(name, description string) *Command { func (c *Command) Command(name, description string) *Command {
result := NewCommand(name, description, c.App, c.CommandPath) result := NewCommand(name, description, c.App, c.CommandPath)

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,19 @@
package cmd package cmd
import ( import (
"bytes"
"crypto/md5" "crypto/md5"
"encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"path"
"path/filepath" "path/filepath"
"runtime"
"github.com/leaanthony/slicer"
) )
// FSHelper - Wrapper struct for File System utility commands // FSHelper - Wrapper struct for File System utility commands
@@ -104,11 +110,33 @@ func (fs *FSHelper) RemoveFiles(files []string) error {
return nil return nil
} }
// Dir holds information about a directory
type Dir struct {
localPath string
fullPath string
}
// Directory creates a new Dir struct with the given directory path
func (fs *FSHelper) Directory(dir string) (*Dir, error) {
fullPath, err := filepath.Abs(dir)
return &Dir{fullPath: fullPath}, err
}
// LocalDir creates a new Dir struct based on a path relative to the caller
func (fs *FSHelper) LocalDir(dir string) (*Dir, error) {
_, filename, _, _ := runtime.Caller(1)
fullPath, err := filepath.Abs(filepath.Join(path.Dir(filename), dir))
return &Dir{
localPath: dir,
fullPath: fullPath,
}, err
}
// GetSubdirs will return a list of FQPs to subdirectories in the given directory // GetSubdirs will return a list of FQPs to subdirectories in the given directory
func (fs *FSHelper) GetSubdirs(dir string) (map[string]string, error) { func (d *Dir) GetSubdirs() (map[string]string, error) {
// Read in the directory information // Read in the directory information
fileInfo, err := ioutil.ReadDir(dir) fileInfo, err := ioutil.ReadDir(d.fullPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -120,25 +148,65 @@ func (fs *FSHelper) GetSubdirs(dir string) (map[string]string, error) {
// map["directoryName"] = "path/to/directoryName" // map["directoryName"] = "path/to/directoryName"
for _, file := range fileInfo { for _, file := range fileInfo {
if file.IsDir() { if file.IsDir() {
subdirs[file.Name()] = filepath.Join(dir, file.Name()) subdirs[file.Name()] = filepath.Join(d.fullPath, file.Name())
} }
} }
return subdirs, nil return subdirs, nil
} }
// GetAllFilenames returns all filename in and below this directory
func (d *Dir) GetAllFilenames() (*slicer.StringSlicer, error) {
result := slicer.String()
err := filepath.Walk(d.fullPath, func(dir string, info os.FileInfo, err error) error {
if dir == d.fullPath {
return nil
}
if err != nil {
return err
}
// Don't copy template metadata
result.Add(dir)
return nil
})
return result, err
}
// MkDir creates the given directory. // MkDir creates the given directory.
// Returns error on failure // Returns error on failure
func (fs *FSHelper) MkDir(dir string) error { func (fs *FSHelper) MkDir(dir string) error {
return os.Mkdir(dir, 0700) return os.Mkdir(dir, 0700)
} }
// SaveAsJSON saves the JSON representation of the given data to the given filename
func (fs *FSHelper) SaveAsJSON(data interface{}, filename string) error {
var buf bytes.Buffer
e := json.NewEncoder(&buf)
e.SetEscapeHTML(false)
e.SetIndent("", " ")
e.Encode(data)
err := ioutil.WriteFile(filename, buf.Bytes(), 0755)
if err != nil {
return err
}
return nil
}
// LoadAsString will attempt to load the given file and return // LoadAsString will attempt to load the given file and return
// its contents as a string // its contents as a string
func (fs *FSHelper) LoadAsString(filename string) (string, error) { func (fs *FSHelper) LoadAsString(filename string) (string, error) {
bytes, err := ioutil.ReadFile(filename) bytes, err := fs.LoadAsBytes(filename)
return string(bytes), err return string(bytes), err
} }
// LoadAsBytes returns the contents of the file as a byte slice
func (fs *FSHelper) LoadAsBytes(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)
}
// FileMD5 returns the md5sum of the given file // FileMD5 returns the md5sum of the given file
func (fs *FSHelper) FileMD5(filename string) (string, error) { func (fs *FSHelper) FileMD5(filename string) (string, error) {
f, err := os.Open(filename) f, err := os.Open(filename)

View File

@@ -56,9 +56,7 @@ func GetLinuxDistroInfo() *DistroInfo {
switch value { switch value {
case "Ubuntu": case "Ubuntu":
result.Distribution = Ubuntu result.Distribution = Ubuntu
case "Arch": case "Arch", "ManjaroLinux":
result.Distribution = Arch
case "ManjaroLinux":
result.Distribution = Arch result.Distribution = Arch
} }
case "Description": case "Description":

View File

@@ -52,7 +52,7 @@ func getRequiredProgramsLinux() *Prerequisites {
case Ubuntu: case Ubuntu:
result.Add(newPrerequisite("gcc", "Please install with `sudo apt install build-essentials` and try again")) result.Add(newPrerequisite("gcc", "Please install with `sudo apt install build-essentials` and try again"))
result.Add(newPrerequisite("pkg-config", "Please install with `sudo apt install pkg-config` and try again")) result.Add(newPrerequisite("pkg-config", "Please install with `sudo apt install pkg-config` and try again"))
result.Add(newPrerequisite("npm", "Please install with `sudo apt install npm` and try again")) result.Add(newPrerequisite("npm", "Please install with `sudo snap install node --channel=12/stable --classic` and try again"))
default: default:
result.Add(newPrerequisite("gcc", "Please install with your system package manager and try again")) result.Add(newPrerequisite("gcc", "Please install with your system package manager and try again"))

View File

@@ -50,12 +50,6 @@ func NewProjectHelper() *ProjectHelper {
// GenerateProject generates a new project using the options given // GenerateProject generates a new project using the options given
func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error { func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
// exists := ph.templates.TemplateExists(projectOptions.Template)
// if !exists {
// return fmt.Errorf("template '%s' is invalid", projectOptions.Template)
// }
// Calculate project path // Calculate project path
projectPath, err := filepath.Abs(projectOptions.OutputDirectory) projectPath, err := filepath.Abs(projectOptions.OutputDirectory)
if err != nil { if err != nil {
@@ -90,8 +84,6 @@ func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
// ph.GenerateWindowsResourceConfig(projectOptions) // ph.GenerateWindowsResourceConfig(projectOptions)
// } // }
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 return nil
} }
@@ -173,19 +165,43 @@ func (po *ProjectOptions) PromptForInputs() error {
// Process Templates // Process Templates
templateList := slicer.Interface() templateList := slicer.Interface()
options := slicer.String() options := slicer.String()
for _, templateDetails := range po.templates.TemplateList.details { templateDetails, err := po.templates.GetTemplateDetails()
templateList.Add(templateDetails) if err != nil {
options.Add(fmt.Sprintf("%s - %s", templateDetails.Metadata.Name, templateDetails.Metadata.ShortDescription)) return err
} }
templateIndex := 0 if po.Template != "" {
// Check template is valid if given
if templateDetails[po.Template] == nil {
keys := make([]string, 0, len(templateDetails))
for k := range templateDetails {
keys = append(keys, k)
}
return fmt.Errorf("invalid template name '%s'. Valid options: %s", po.Template, strings.Join(keys, ", "))
}
po.selectedTemplate = templateDetails[po.Template]
} else {
if len(options.AsSlice()) > 1 { for _, templateDetail := range templateDetails {
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0) templateList.Add(templateDetail)
options.Add(fmt.Sprintf("%s - %s", templateDetail.Metadata.Name, templateDetail.Metadata.ShortDescription))
}
templateIndex := 0
if len(options.AsSlice()) > 1 {
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
}
if len(templateList.AsSlice()) == 0 {
return fmt.Errorf("aborting: no templates found")
}
// After selection do this....
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
} }
// After selection do this.... fmt.Println("Template: " + po.selectedTemplate.Metadata.Name)
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
// Setup NPM Project name // Setup NPM Project name
po.NPMProjectName = strings.ToLower(strings.Replace(po.Name, " ", "_", -1)) po.NPMProjectName = strings.ToLower(strings.Replace(po.Name, " ", "_", -1))
@@ -266,7 +282,6 @@ func processProjectName(po *ProjectOptions) {
po.Name = Prompt("The name of the project", "My Project") po.Name = Prompt("The name of the project", "My Project")
} }
fmt.Println("Project Name: " + po.Name) fmt.Println("Project Name: " + po.Name)
} }
func processBinaryName(po *ProjectOptions) { func processBinaryName(po *ProjectOptions) {

View File

@@ -68,6 +68,17 @@ func (s *SystemHelper) ConfigFileIsValid() bool {
return err == nil return err == nil
} }
// GetAuthor returns a formatted string of the user's name and email
func (s *SystemHelper) GetAuthor() (string, error) {
var config *SystemConfig
config, err := s.LoadConfig()
if err != nil {
return "", err
}
return fmt.Sprintf("%s <%s>", config.Name, config.Email), nil
}
// BackupConfig attempts to backup the system config file // BackupConfig attempts to backup the system config file
func (s *SystemHelper) BackupConfig() (string, error) { func (s *SystemHelper) BackupConfig() (string, error) {
now := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) now := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)

View File

@@ -3,20 +3,21 @@ package cmd
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt"
"io/ioutil"
"log" "log"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
"text/template" "text/template"
mewn "github.com/leaanthony/mewn" "github.com/kennygrant/sanitize"
mewnlib "github.com/leaanthony/mewn/lib"
"github.com/leaanthony/slicer" "github.com/leaanthony/slicer"
) )
// TemplateMetadata holds all the metadata for a Wails template // TemplateMetadata holds all the metadata for a Wails template
type TemplateMetadata struct { type TemplateMetadata struct {
Name string `json:"name"` Name string `json:"name"`
Version string `json:"version"`
ShortDescription string `json:"shortdescription"` ShortDescription string `json:"shortdescription"`
Description string `json:"description"` Description string `json:"description"`
Install string `json:"install"` Install string `json:"install"`
@@ -26,92 +27,146 @@ type TemplateMetadata struct {
FrontendDir string `json:"frontenddir"` FrontendDir string `json:"frontenddir"`
Serve string `json:"serve"` Serve string `json:"serve"`
Bridge string `json:"bridge"` Bridge string `json:"bridge"`
WailsDir string `json:"wailsdir"`
} }
// TemplateDetails holds information about a specific template // TemplateDetails holds information about a specific template
type TemplateDetails struct { type TemplateDetails struct {
BasePath string Name string
Path string Path string
Metadata *TemplateMetadata Metadata *TemplateMetadata
} fs *FSHelper
// TemplateList is a list of available templates
type TemplateList struct {
details map[string]*TemplateDetails
}
// NewTemplateList creates a new TemplateList object
func NewTemplateList(filenames *mewnlib.FileGroup) *TemplateList {
// Iterate each template and store information
result := &TemplateList{details: make(map[string]*TemplateDetails)}
entries := slicer.String()
entries.AddSlice(filenames.Entries())
// Find all template.json files
metadataFiles := entries.Filter(func(filename string) bool {
match, _ := regexp.MatchString("(.)+template.json$", filename)
return match
})
// Load each metadata file
metadataFiles.Each(func(filename string) {
fileData := filenames.Bytes(filename)
var metadata TemplateMetadata
err := json.Unmarshal(fileData, &metadata)
if err != nil {
log.Fatalf("corrupt metadata for template: %s", filename)
}
path := strings.Split(filename, "/")[0]
thisTemplate := &TemplateDetails{Path: path, Metadata: &metadata}
result.details[filename] = thisTemplate
})
return result
}
// Template holds details about a Wails template
type Template struct {
Name string
Path string
Description string
} }
// TemplateHelper is a utility object to help with processing templates // TemplateHelper is a utility object to help with processing templates
type TemplateHelper struct { type TemplateHelper struct {
TemplateList *TemplateList templateDir *Dir
Files *mewnlib.FileGroup fs *FSHelper
metadataFilename string
} }
// NewTemplateHelper creates a new template helper // NewTemplateHelper creates a new template helper
func NewTemplateHelper() *TemplateHelper { func NewTemplateHelper() *TemplateHelper {
files := mewn.Group("./templates")
templateDir, err := fs.LocalDir("./templates")
if err != nil {
log.Fatal("Unable to find the template directory. Please reinstall Wails.")
}
return &TemplateHelper{ return &TemplateHelper{
TemplateList: NewTemplateList(files), templateDir: templateDir,
Files: files, metadataFilename: "template.json",
} }
} }
// IsValidTemplate returns true if the given tempalte name resides on disk
func (t *TemplateHelper) IsValidTemplate(templateName string) bool {
pathToTemplate := filepath.Join(t.templateDir.fullPath, templateName)
return t.fs.DirExists(pathToTemplate)
}
// SanitizeFilename sanitizes the given string to make a valid filename
func (t *TemplateHelper) SanitizeFilename(name string) string {
return sanitize.Name(name)
}
// CreateNewTemplate creates a new template based on the given directory name and string
func (t *TemplateHelper) CreateNewTemplate(dirname string, details *TemplateMetadata) (string, error) {
// Check if this template has already been created
if t.IsValidTemplate(dirname) {
return "", fmt.Errorf("cannot create template in directory '%s' - already exists", dirname)
}
targetDir := filepath.Join(t.templateDir.fullPath, dirname)
err := t.fs.MkDir(targetDir)
if err != nil {
return "", err
}
targetMetadata := filepath.Join(targetDir, t.metadataFilename)
err = t.fs.SaveAsJSON(details, targetMetadata)
return targetDir, err
}
// LoadMetadata loads the template's 'metadata.json' file
func (t *TemplateHelper) LoadMetadata(dir string) (*TemplateMetadata, error) {
templateFile := filepath.Join(dir, t.metadataFilename)
result := &TemplateMetadata{}
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
}
// GetTemplateDetails returns a map of Template structs containing details
// of the found templates
func (t *TemplateHelper) GetTemplateDetails() (map[string]*TemplateDetails, error) {
// Get the subdirectory details
templateDirs, err := t.templateDir.GetSubdirs()
if err != nil {
return nil, err
}
result := make(map[string]*TemplateDetails)
for name, dir := range templateDirs {
result[name] = &TemplateDetails{
Path: dir,
}
_ = &TemplateMetadata{}
metadata, err := t.LoadMetadata(dir)
if err != nil {
return nil, err
}
result[name].Metadata = metadata
if metadata.Name != "" {
result[name].Name = metadata.Name
} else {
// Ignore bad templates?
result[name] = nil
}
}
return result, nil
}
// GetTemplateFilenames returns all the filenames of the given template
func (t *TemplateHelper) GetTemplateFilenames(template *TemplateDetails) (*slicer.StringSlicer, error) {
// Get the subdirectory details
templateDir, err := t.fs.Directory(template.Path)
if err != nil {
return nil, err
}
return templateDir.GetAllFilenames()
}
// InstallTemplate installs the template given in the project options to the // InstallTemplate installs the template given in the project options to the
// project path given // project path given
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error { func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error {
// Get template files // Get template files
templateFilenames, err := t.GetTemplateFilenames(projectOptions.selectedTemplate)
if err != nil {
return err
}
templatePath := projectOptions.selectedTemplate.Path templatePath := projectOptions.selectedTemplate.Path
templateFilenames := slicer.String() templateJSONFilename := filepath.Join(templatePath, t.metadataFilename)
templateFilenames.AddSlice(projectOptions.templates.Files.Entries())
templateJSONFilename := filepath.Join(templatePath, "template.json")
templateFiles := templateFilenames.Filter(func(filename string) bool { templateFiles := templateFilenames.Filter(func(filename string) bool {
filename = filepath.FromSlash(filename) filename = filepath.FromSlash(filename)
return strings.HasPrefix(filename, templatePath) && filename != templateJSONFilename return strings.HasPrefix(filename, templatePath) && filename != templateJSONFilename
}) })
var err error
templateFiles.Each(func(templateFile string) { templateFiles.Each(func(templateFile string) {
// Setup filenames // Setup filenames
@@ -120,11 +175,14 @@ func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *Pro
if err != nil { if err != nil {
return return
} }
filedata := projectOptions.templates.Files.Bytes(templateFile) filedata, err := t.fs.LoadAsBytes(templateFile)
if err != nil {
return
}
// If file is a template, process it // If file is a template, process it
if strings.HasSuffix(templateFile, ".template") { if strings.HasSuffix(templateFile, ".template") {
templateData := projectOptions.templates.Files.String(templateFile) templateData := string(filedata)
tmpl := template.New(templateFile) tmpl := template.New(templateFile)
tmpl.Parse(templateData) tmpl.Parse(templateData)
var tpl bytes.Buffer var tpl bytes.Buffer

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
{
"esversion": 6
}

View File

@@ -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*

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/app'
]
}

View File

@@ -0,0 +1,52 @@
{
"name": "{{.NPMProjectName}}",
"author": "{{.Author.Name}}<{{.Author.Email}}>",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"core-js": "^2.6.4",
"material-design-icons-iconfont": "^5.0.1",
"vue": "^2.5.22",
"vuetify": "^1.5.14"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.4.0",
"@vue/cli-plugin-eslint": "^3.4.0",
"@vue/cli-service": "^3.4.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.8.0",
"eslint-plugin-vue": "^5.0.0",
"eventsource-polyfill": "^0.9.6",
"vue-template-compiler": "^2.5.21",
"webpack-hot-middleware": "^2.24.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

View File

@@ -0,0 +1,60 @@
<template>
<v-app id="inspire" dark>
<v-navigation-drawer v-model="drawer" clipped fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>dashboard</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Dashboard</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>settings</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Settings</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar app fixed clipped-left>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
<v-content>
<v-container fluid class="px-0">
<v-layout justify-center align-center class="px-0">
<hello-world></hello-world>
</v-layout>
</v-container>
</v-content>
<v-footer app fixed>
<span style="margin-left:1em">&copy; You</span>
</v-footer>
</v-app>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
data: () => ({
drawer: false
}),
components: {
HelloWorld
},
props: {
source: String
}
};
</script>
<style>
.logo {
width: 16em;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

View File

@@ -0,0 +1,83 @@
<template>
<v-container fluid class="px-0">
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-card raised="raised" class="pa-4 ma-4">
<v-layout justify-center align-center class="pa-4 ma-4">
<v-img :src="require('../assets/images/logo.png')"></v-img>
</v-layout>
<v-card-actions>
<v-layout justify-center align-center class="px-0">
<v-btn color="blue" dark @click="getMessage">Press Me</v-btn>
</v-layout>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
<div class="text-xs-center">
<v-dialog v-model="dialog" width="500">
<v-card>
<v-card-title class="headline" primary-title>Message from Go</v-card-title>
<v-card-text>{{message}}</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" flat @click="dialog = false">Awesome</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</v-container>
</template>
<script>
export default {
data() {
return {
message: " ",
raised: true,
dialog: false
};
},
methods: {
getMessage: function() {
var self = this;
window.backend.basic().then(result => {
self.message = result;
self.dialog = true;
});
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1 {
margin-top: 2em;
position: relative;
min-height: 5rem;
width: 100%;
}
a:hover {
font-size: 1.7em;
border-color: blue;
background-color: blue;
color: white;
border: 3px solid white;
border-radius: 10px;
padding: 9px;
cursor: pointer;
transition: 500ms;
}
a {
font-size: 1.7em;
border-color: white;
background-color: #121212;
color: white;
border: 3px solid white;
border-radius: 10px;
padding: 9px;
cursor: pointer;
}
</style>

View File

@@ -0,0 +1,21 @@
import 'babel-polyfill';
import Vue from "vue";
// Setup Vuetify
import Vuetify from 'vuetify';
Vue.use(Vuetify);
import 'vuetify/dist/vuetify.min.css';
import 'material-design-icons-iconfont';
import App from "./App.vue";
Vue.config.productionTip = false;
Vue.config.devtools = true;
import Bridge from "./wailsbridge";
Bridge.Start(() => {
new Vue({
render: h => h(App)
}).$mount("#app");
});

View File

@@ -0,0 +1,43 @@
let cssConfig = {};
if (process.env.NODE_ENV == "production") {
cssConfig = {
extract: {
filename: "[name].css",
chunkFilename: "[name].css"
}
};
}
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: cssConfig,
configureWebpack: {
output: {
filename: "[name].js"
},
optimization: {
splitChunks: false
}
},
devServer: {
disableHostCheck: true,
host: "localhost"
}
};

View File

@@ -0,0 +1 @@
module {{.BinaryName}}

View File

@@ -0,0 +1,27 @@
package main
import (
"github.com/leaanthony/mewn"
"github.com/wailsapp/wails"
)
func basic() string {
return "Hello World!"
}
func main() {
js := mewn.String("./frontend/dist/app.js")
css := mewn.String("./frontend/dist/app.css")
app := wails.CreateApp(&wails.AppConfig{
Width: 1024,
Height: 768,
Title: "{{.Name}}",
JS: js,
CSS: css,
Colour: "#131313",
})
app.Bind(basic)
app.Run()
}

View File

@@ -0,0 +1,14 @@
{
"name": "Vuetify Basic",
"version": "1.0.0",
"shortdescription": "Vuetify + Webpack",
"description": "Basic template using Vuetify and bundled using Webpack",
"install": "npm install",
"build": "npm run build",
"author": "lea <lea.anthony@gmail.com>",
"created": "2019-05-25 09:39:40.009307 +1000 AEST m=+59.539991073",
"frontenddir": "frontend",
"serve": "npm run serve",
"bridge": "src",
"wailsdir": ""
}

View File

@@ -1,4 +1,4 @@
package cmd package cmd
// Version - Wails version // Version - Wails version
const Version = "v0.14.0-pre" const Version = "v0.15.0"

View File

@@ -0,0 +1,121 @@
// +build dev
package main
import (
"fmt"
"time"
"github.com/wailsapp/wails/cmd"
"gopkg.in/AlecAivazis/survey.v1"
)
var templateHelper = cmd.NewTemplateHelper()
var qs = []*survey.Question{
{
Name: "Name",
Prompt: &survey.Input{Message: "Please enter the name of your template (eg: React/Webpack Basic):"},
Validate: survey.Required,
},
{
Name: "ShortDescription",
Prompt: &survey.Input{Message: "Please enter a short description for the template (eg: React with Webpack 4):"},
Validate: survey.Required,
},
{
Name: "Description",
Prompt: &survey.Input{Message: "Please enter a long description:"},
Validate: survey.Required,
},
{
Name: "FrontendDir",
Prompt: &survey.Input{Message: "Please enter the name of the directory the frontend code resides (eg: frontend):"},
Validate: survey.Required,
},
{
Name: "Install",
Prompt: &survey.Input{Message: "Please enter the install command (eg: npm install):"},
Validate: survey.Required,
},
{
Name: "Build",
Prompt: &survey.Input{Message: "Please enter the build command (eg: npm run build):"},
Validate: survey.Required,
},
{
Name: "Serve",
Prompt: &survey.Input{Message: "Please enter the serve command (eg: npm run serve):"},
Validate: survey.Required,
},
{
Name: "Bridge",
Prompt: &survey.Input{Message: "Please enter the name of the directory to copy the wails bridge runtime (eg: src):"},
Validate: survey.Required,
},
}
func newTemplate(devCommand *cmd.Command) {
commandDescription := `This command scaffolds everything needed to develop a new template.`
newTemplate := devCommand.Command("newtemplate", "Generate a new template").
LongDescription(commandDescription)
newTemplate.Action(func() error {
logger.PrintSmallBanner("Generating new project template")
fmt.Println()
var answers cmd.TemplateMetadata
// perform the questions
err := survey.Ask(qs, &answers)
if err != nil {
fmt.Println(err.Error())
return err
}
dirname := templateHelper.SanitizeFilename(answers.Name)
prompt := []*survey.Question{{
Prompt: &survey.Input{
Message: "Please enter a directory name for the template:",
Default: dirname,
},
Validate: func(val interface{}) error {
err := survey.Required(val)
if err != nil {
return err
}
if templateHelper.IsValidTemplate(val.(string)) {
return fmt.Errorf("template directory already exists")
}
if templateHelper.SanitizeFilename(val.(string)) != val.(string) {
return fmt.Errorf("invalid directory name '%s'", val.(string))
}
return nil
},
}}
err = survey.Ask(prompt, &dirname)
if err != nil {
return err
}
answers.Version = "1.0.0"
answers.Created = time.Now().String()
// Get Author info from system info
system := cmd.NewSystemHelper()
author, err := system.GetAuthor()
if err == nil {
answers.Author = author
}
templateDirectory, err := templateHelper.CreateNewTemplate(dirname, &answers)
if err != nil {
return err
}
logger.Green("Created new template '%s' in directory '%s'", answers.Name, templateDirectory)
return nil
})
}

18
cmd/wails/10_dev.go Normal file
View File

@@ -0,0 +1,18 @@
// +build dev
package main
func init() {
commandDescription := `This command provides access to developer tooling.`
devCommand := app.Command("dev", "A selection of developer tools").
LongDescription(commandDescription)
// Add subcommands
newTemplate(devCommand)
devCommand.Action(func() error {
devCommand.PrintHelp()
return nil
})
}

View File

@@ -2,7 +2,10 @@ package main
import ( import (
"fmt" "fmt"
"os"
"path/filepath"
"github.com/leaanthony/spinner"
"github.com/wailsapp/wails/cmd" "github.com/wailsapp/wails/cmd"
) )
@@ -17,7 +20,7 @@ Any flags that are required and not given will be prompted for.`
LongDescription(commandDescription). LongDescription(commandDescription).
BoolFlag("f", "Use defaults", &projectOptions.UseDefaults). BoolFlag("f", "Use defaults", &projectOptions.UseDefaults).
StringFlag("dir", "Directory to create project in", &projectOptions.OutputDirectory). StringFlag("dir", "Directory to create project in", &projectOptions.OutputDirectory).
// StringFlag("template", "Template name", &projectOptions.Template). StringFlag("template", "Template name", &projectOptions.Template).
StringFlag("name", "Project name", &projectOptions.Name). StringFlag("name", "Project name", &projectOptions.Name).
StringFlag("description", "Project description", &projectOptions.Description). StringFlag("description", "Project description", &projectOptions.Description).
StringFlag("output", "Output binary name", &projectOptions.BinaryName) StringFlag("output", "Output binary name", &projectOptions.BinaryName)
@@ -50,11 +53,33 @@ Any flags that are required and not given will be prompted for.`
} }
} }
genSpinner := spinner.NewSpinner()
genSpinner.SetSpinSpeed(50)
genSpinner.Start("Generating project...")
// Generate the project // Generate the project
err = projectHelper.GenerateProject(projectOptions) err = projectHelper.GenerateProject(projectOptions)
if err != nil { if err != nil {
logger.Error(err.Error()) genSpinner.Error()
return err
} }
genSpinner.Success()
// Build the project
cwd, _ := os.Getwd()
projectDir := filepath.Join(cwd, projectOptions.OutputDirectory)
program := cmd.NewProgramHelper()
buildSpinner := spinner.NewSpinner()
buildSpinner.SetSpinSpeed(50)
buildSpinner.Start("Building project (this may take a while)...")
err = program.RunCommandArray([]string{"wails", "build"}, projectDir)
if err != nil {
buildSpinner.Error(err.Error())
return err
}
buildSpinner.Success()
logger.Yellow("Project '%s' built in directory '%s'!", projectOptions.Name, projectOptions.OutputDirectory)
return err return err
}) })
} }

View File

@@ -64,7 +64,7 @@ To help you in this process, we will ask for some information, add Go/Wails deta
body = "**Description**\n" + (strings.Split(body, "**Description**")[1]) body = "**Description**\n" + (strings.Split(body, "**Description**")[1])
fullURL := "https://github.com/wailsapp/wails/issues/new?" fullURL := "https://github.com/wailsapp/wails/issues/new?"
body = strings.Replace(body, "A clear and concise description of what the bug is.", description, -1) body = strings.Replace(body, "A clear and concise description of what the bug is.", description, -1)
body = strings.Replace(body, "Please paste the output of `wails report` here.", str.String(), -1) body = strings.Replace(body, "Please provide your platform, GO version and variables, etc", str.String(), -1)
params := "title=" + title + "&body=" + body params := "title=" + title + "&body=" + body
fmt.Println("Opening browser to file issue.") fmt.Println("Opening browser to file issue.")

28
go.mod
View File

@@ -1,45 +1,31 @@
module github.com/wailsapp/wails module github.com/wailsapp/wails
require ( require (
cloud.google.com/go v0.38.0 // indirect
github.com/Masterminds/semver v1.4.2 // indirect github.com/Masterminds/semver v1.4.2 // indirect
github.com/dchest/cssmin v0.0.0-20151210170030-fb8d9b44afdc // indirect github.com/dchest/cssmin v0.0.0-20151210170030-fb8d9b44afdc // indirect
github.com/dchest/htmlmin v0.0.0-20150526090704-e254725e81ac github.com/dchest/htmlmin v0.0.0-20150526090704-e254725e81ac
github.com/dchest/jsmin v0.0.0-20160823214000-faeced883947 // indirect github.com/dchest/jsmin v0.0.0-20160823214000-faeced883947 // indirect
github.com/fatih/color v1.7.0 github.com/fatih/color v1.7.0
github.com/go-playground/colors v1.2.0 github.com/go-playground/colors v1.2.0
github.com/golang/mock v1.3.0 // indirect
github.com/google/btree v1.0.0 // indirect
github.com/google/go-cmp v0.3.0 // indirect
github.com/google/pprof v0.0.0-20190502144155-8358a9778bd1 // indirect
github.com/gorilla/websocket v1.4.0 github.com/gorilla/websocket v1.4.0
github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/jackmordaunt/icns v1.0.0 github.com/jackmordaunt/icns v1.0.0
github.com/kennygrant/sanitize v1.2.4
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/leaanthony/mewn v0.10.5 github.com/leaanthony/mewn v0.10.7
github.com/leaanthony/slicer v1.3.1 github.com/leaanthony/slicer v1.3.1
github.com/leaanthony/spinner v0.5.0 github.com/leaanthony/spinner v0.5.3
github.com/masterminds/semver v1.4.2 github.com/masterminds/semver v1.4.2
github.com/mattn/go-colorable v0.1.1 // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
github.com/pkg/errors v0.8.1 // indirect github.com/pkg/errors v0.8.1 // indirect
github.com/ribice/glice v0.0.0-20190502213737-321f539fdca1 // indirect
github.com/sirupsen/logrus v1.4.1 github.com/sirupsen/logrus v1.4.1
github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.3.0 // indirect
github.com/wailsapp/webview v0.2.7 github.com/wailsapp/webview v0.2.7
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 // indirect
golang.org/x/image v0.0.0-20190507092727-e4e5bf290fec // indirect
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 // indirect
golang.org/x/mobile v0.0.0-20190509164839-32b2708ab171 // indirect
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
golang.org/x/text v0.3.2 // indirect gopkg.in/AlecAivazis/survey.v1 v1.8.4
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
golang.org/x/tools v0.0.0-20190511041617-99f201b6807e // indirect
google.golang.org/api v0.5.0 // indirect
google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8 // indirect
google.golang.org/grpc v1.20.1 // indirect
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a // indirect
) )

119
go.sum
View File

@@ -1,11 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -19,40 +15,28 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/go-playground/colors v1.2.0 h1:0EdjTXKrr2g1L/LQTYtIqabeHpZuGZz1U4osS1T8+5M= github.com/go-playground/colors v1.2.0 h1:0EdjTXKrr2g1L/LQTYtIqabeHpZuGZz1U4osS1T8+5M=
github.com/go-playground/colors v1.2.0/go.mod h1:miw1R2JIE19cclPxsXqNdzLZsk4DP4iF+m88bRc7kfM= github.com/go-playground/colors v1.2.0/go.mod h1:miw1R2JIE19cclPxsXqNdzLZsk4DP4iF+m88bRc7kfM=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.0/go.mod h1:c8YoAQJ7+qIz9IQm9G72MJ4uDcrPeLjkrQ4yYIHdhyw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190502144155-8358a9778bd1/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmAMQ= github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmAMQ=
github.com/jackmordaunt/icns v1.0.0/go.mod h1:7TTQVEuGzVVfOPPlLNHJIkzA6CoV7aH1Dv9dW351oOo= github.com/jackmordaunt/icns v1.0.0/go.mod h1:7TTQVEuGzVVfOPPlLNHJIkzA6CoV7aH1Dv9dW351oOo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/keighl/metabolize v0.0.0-20150915210303-97ab655d4034/go.mod h1:xxAJtNhpzBtSWAYybYGKfMFYx71aqCyNe/8FraO/1ac= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/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/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/leaanthony/mewn v0.10.5 h1:QKYVj8tI94alvVFZer7wPy66IcNpyNPITIkdhXbThX4= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/leaanthony/mewn v0.10.5/go.mod h1:i3ygCWW96qVQlGa8sjWnTM0IKAijoFvTwATDIZgK4k0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/leaanthony/mewn v0.10.7 h1:jCcNJyIUOpwj+I5SuATvCugDjHkoo+j6ubEOxxrxmPA=
github.com/leaanthony/mewn v0.10.7/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
github.com/leaanthony/slicer v1.3.1 h1:n2iIV2sxvL/3bpnmVY0vBjXf3yYFWcB6CYLVMrzJxRw= github.com/leaanthony/slicer v1.3.1 h1:n2iIV2sxvL/3bpnmVY0vBjXf3yYFWcB6CYLVMrzJxRw=
github.com/leaanthony/slicer v1.3.1/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ= github.com/leaanthony/slicer v1.3.1/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ=
github.com/leaanthony/spinner v0.5.0 h1:HQykt/iTy7fmINEREtRbWrt+8j4MxC8dtvWBxEWM9oA= github.com/leaanthony/spinner v0.5.3 h1:IMTvgdQCec5QA4qRy0wil4XsRP+QcG1OwLWVK/LPZ5Y=
github.com/leaanthony/spinner v0.5.0/go.mod h1:8TSFz9SL1AUC4XSbEFYE6SfN5Mlus51qYluVGrie9ww= github.com/leaanthony/spinner v0.5.3/go.mod h1:oHlrvWicr++CVV7ALWYi+qHk/XNA91D9IJ48IqmpVUo=
github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8= github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8=
github.com/leaanthony/synx v0.1.0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs= github.com/leaanthony/synx v0.1.0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs=
github.com/leaanthony/wincursor v0.1.0 h1:Dsyp68QcF5cCs65AMBmxoYNEm0n8K7mMchG6a8fYxf8= github.com/leaanthony/wincursor v0.1.0 h1:Dsyp68QcF5cCs65AMBmxoYNEm0n8K7mMchG6a8fYxf8=
@@ -63,110 +47,53 @@ github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRU
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= 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-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 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/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ribice/glice v0.0.0-20181011133736-685f13fa9b12/go.mod h1:A+ednilkKNW0CJGLsrLkq0D49M4EhlCi8gvnkwoZFn0=
github.com/ribice/glice v0.0.0-20190502213737-321f539fdca1/go.mod h1:p4S+fsfJ+wO7Cexs43Ub6bcvj2zotI5XwY67Pu0WvvY=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/wailsapp/webview v0.2.7 h1:fN5L5H9Oivg9IJPk7uaXQnjqB68Fny11ZWkIaTIZHmk= github.com/wailsapp/webview v0.2.7 h1:fN5L5H9Oivg9IJPk7uaXQnjqB68Fny11ZWkIaTIZHmk=
github.com/wailsapp/webview v0.2.7/go.mod h1:XO9HJbKWokDxUYTWQEBCYg95n/To1v7PxvanDNVf8hY= github.com/wailsapp/webview v0.2.7/go.mod h1:XO9HJbKWokDxUYTWQEBCYg95n/To1v7PxvanDNVf8hY=
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb/go.mod h1:a1CV8KR4Dd1eP2g+mEijGOp+HKczwdKHWyx0aPHKvo4= github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb/go.mod h1:a1CV8KR4Dd1eP2g+mEijGOp+HKczwdKHWyx0aPHKvo4=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190507092727-e4e5bf290fec/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190509164839-32b2708ab171/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak= golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
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/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb h1:pf3XwC90UUdNPYWZdFjhGBE7DUFuK3Ct1zWmZ65QN30= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb h1:pf3XwC90UUdNPYWZdFjhGBE7DUFuK3Ct1zWmZ65QN30=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug= golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug=
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/AlecAivazis/survey.v1 v1.8.4 h1:10xXXN3wgIhPheb5NI58zFgZv32Ana7P3Tl4shW+0Qc=
golang.org/x/text v0.3.1/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= gopkg.in/AlecAivazis/survey.v1 v1.8.4/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190511041617-99f201b6807e/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=