mirror of
https://github.com/taigrr/wails.git
synced 2026-04-11 09:31:31 -07:00
Compare commits
7 Commits
0.9.9
...
update-com
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fafd165de | ||
|
|
5ca7bfca66 | ||
|
|
3f32c45f77 | ||
|
|
f8c805649a | ||
|
|
3ac993b01f | ||
|
|
216c84b9cf | ||
|
|
e99fffe340 |
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: bug
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Description**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behaviour:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Expected behaviour**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
**System Details**
|
|
||||||
Please paste the output of `wails report` here.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018 wailsapp
|
Copyright (c) 2018-Present Lea Anthony
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -41,14 +41,6 @@ func (fs *FSHelper) FileExists(path string) bool {
|
|||||||
return fi.Mode().IsRegular()
|
return fi.Mode().IsRegular()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFile creates a file at the given filename location with the contents
|
|
||||||
// set to the given data. It will create intermediary directories if needed.
|
|
||||||
func (fs *FSHelper) CreateFile(filename string, data []byte) error {
|
|
||||||
// Ensure directory exists
|
|
||||||
fs.MkDirs(filepath.Dir(filename))
|
|
||||||
return ioutil.WriteFile(filename, data, 0644)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MkDirs creates the given nested directories.
|
// MkDirs creates the given nested directories.
|
||||||
// Returns error on failure
|
// Returns error on failure
|
||||||
func (fs *FSHelper) MkDirs(fullPath string, mode ...os.FileMode) error {
|
func (fs *FSHelper) MkDirs(fullPath string, mode ...os.FileMode) error {
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import (
|
|||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fs = NewFSHelper()
|
|
||||||
|
|
||||||
// ValidateFrontendConfig checks if the frontend config is valid
|
// ValidateFrontendConfig checks if the frontend config is valid
|
||||||
func ValidateFrontendConfig(projectOptions *ProjectOptions) error {
|
func ValidateFrontendConfig(projectOptions *ProjectOptions) error {
|
||||||
if projectOptions.FrontEnd.Dir == "" {
|
if projectOptions.FrontEnd.Dir == "" {
|
||||||
@@ -174,7 +172,7 @@ func CheckWindres() (err error) {
|
|||||||
}
|
}
|
||||||
programHelper := NewProgramHelper()
|
programHelper := NewProgramHelper()
|
||||||
if !programHelper.IsInstalled("windres") {
|
if !programHelper.IsInstalled("windres") {
|
||||||
return fmt.Errorf("windres not installed. It comes by default with mingw. Ensure you have installed mingw correctly")
|
return fmt.Errorf("windres not installed. It comes by default with mingw. Ensure you have installed mingw correctly.")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ func NewLogger() *Logger {
|
|||||||
return &Logger{errorOnly: false}
|
return &Logger{errorOnly: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetErrorOnly ensures that only errors are logged out
|
|
||||||
func (l *Logger) SetErrorOnly(errorOnly bool) {
|
func (l *Logger) SetErrorOnly(errorOnly bool) {
|
||||||
l.errorOnly = errorOnly
|
l.errorOnly = errorOnly
|
||||||
}
|
}
|
||||||
@@ -100,7 +99,6 @@ func (l *Logger) Error(format string, a ...interface{}) {
|
|||||||
color.New(color.FgHiRed).PrintfFunc()("Error: "+format+"\n", a...)
|
color.New(color.FgHiRed).PrintfFunc()("Error: "+format+"\n", a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintSmallBanner prints a condensed banner
|
|
||||||
func (l *Logger) PrintSmallBanner(message ...string) {
|
func (l *Logger) PrintSmallBanner(message ...string) {
|
||||||
yellow := color.New(color.FgYellow).SprintFunc()
|
yellow := color.New(color.FgYellow).SprintFunc()
|
||||||
red := color.New(color.FgRed).SprintFunc()
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackageWindows packages the application for windows platforms
|
|
||||||
func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
||||||
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,15 @@ func (p *ProgramHelper) RunCommand(command string) error {
|
|||||||
return p.RunCommandArray(args)
|
return p.RunCommandArray(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ProgramHelper) GetOutputFromCommand(command string) (string, string, error) {
|
||||||
|
args := strings.Split(command, " ")
|
||||||
|
if len(args) > 1 {
|
||||||
|
return p.shell.Run(args[0], args[1:]...)
|
||||||
|
} else {
|
||||||
|
return p.shell.Run(args[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RunCommandArray runs the command specified in the array
|
// RunCommandArray runs the command specified in the array
|
||||||
func (p *ProgramHelper) RunCommandArray(args []string) error {
|
func (p *ProgramHelper) RunCommandArray(args []string) error {
|
||||||
program := args[0]
|
program := args[0]
|
||||||
|
|||||||
133
cmd/project.go
133
cmd/project.go
@@ -4,12 +4,9 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/leaanthony/slicer"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type author struct {
|
type author struct {
|
||||||
@@ -50,11 +47,15 @@ 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)
|
fs := NewFSHelper()
|
||||||
|
exists, err := ph.templates.TemplateExists(projectOptions.Template)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// if !exists {
|
if !exists {
|
||||||
// return fmt.Errorf("template '%s' is invalid", projectOptions.Template)
|
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)
|
||||||
@@ -62,8 +63,6 @@ func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = projectPath
|
|
||||||
|
|
||||||
if fs.DirExists(projectPath) {
|
if fs.DirExists(projectPath) {
|
||||||
return fmt.Errorf("directory '%s' already exists", projectPath)
|
return fmt.Errorf("directory '%s' already exists", projectPath)
|
||||||
}
|
}
|
||||||
@@ -115,14 +114,15 @@ func (ph *ProjectHelper) LoadProjectConfig(dir string) (*ProjectOptions, error)
|
|||||||
// NewProjectOptions creates a new default set of project options
|
// NewProjectOptions creates a new default set of project options
|
||||||
func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
|
func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
|
||||||
result := ProjectOptions{
|
result := ProjectOptions{
|
||||||
Name: "",
|
Name: "",
|
||||||
Description: "Enter your project description",
|
Description: "Enter your project description",
|
||||||
Version: "0.1.0",
|
Version: "0.1.0",
|
||||||
BinaryName: "",
|
BinaryName: "",
|
||||||
system: NewSystemHelper(),
|
system: NewSystemHelper(),
|
||||||
log: NewLogger(),
|
log: NewLogger(),
|
||||||
templates: NewTemplateHelper(),
|
templates: NewTemplateHelper(),
|
||||||
Author: &author{},
|
templateNameMap: make(map[string]string),
|
||||||
|
Author: &author{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate system config
|
// Populate system config
|
||||||
@@ -137,25 +137,25 @@ func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
|
|||||||
|
|
||||||
// ProjectOptions holds all the options available for a project
|
// ProjectOptions holds all the options available for a project
|
||||||
type ProjectOptions struct {
|
type ProjectOptions struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Author *author `json:"author,omitempty"`
|
Author *author `json:"author,omitempty"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
OutputDirectory string `json:"-"`
|
OutputDirectory string `json:"-"`
|
||||||
UseDefaults bool `json:"-"`
|
UseDefaults bool `json:"-"`
|
||||||
Template string `json:"-"`
|
Template string `json:"-"`
|
||||||
BinaryName string `json:"binaryname"`
|
BinaryName string `json:"binaryname"`
|
||||||
FrontEnd *frontend `json:"frontend,omitempty"`
|
FrontEnd *frontend `json:"frontend,omitempty"`
|
||||||
NPMProjectName string `json:"-"`
|
NPMProjectName string `json:"-"`
|
||||||
system *SystemHelper
|
system *SystemHelper
|
||||||
log *Logger
|
log *Logger
|
||||||
templates *TemplateHelper
|
templates *TemplateHelper
|
||||||
selectedTemplate *TemplateDetails
|
templateNameMap map[string]string // Converts template prompt text to template name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defaults sets the default project template
|
// Defaults sets the default project template
|
||||||
func (po *ProjectOptions) Defaults() {
|
func (po *ProjectOptions) Defaults() {
|
||||||
po.Template = "vuebasic"
|
po.Template = "basic"
|
||||||
}
|
}
|
||||||
|
|
||||||
// PromptForInputs asks the user to input project details
|
// PromptForInputs asks the user to input project details
|
||||||
@@ -170,31 +170,48 @@ func (po *ProjectOptions) PromptForInputs() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process Templates
|
templateDetails, err := po.templates.GetTemplateDetails()
|
||||||
templateList := slicer.Interface()
|
if err != nil {
|
||||||
options := slicer.String()
|
return err
|
||||||
for _, templateDetails := range po.templates.TemplateList.details {
|
|
||||||
templateList.Add(templateDetails)
|
|
||||||
options.Add(fmt.Sprintf("%s - %s", templateDetails.Metadata.Name, templateDetails.Metadata.ShortDescription))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templateIndex := 0
|
templates := []string{}
|
||||||
|
// Add a Custom Template
|
||||||
if len(options.AsSlice()) > 1 {
|
// templates = append(templates, "Custom - Choose your own CSS framework")
|
||||||
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// After selection do this....
|
if po.Template != "" {
|
||||||
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
|
if _, ok := templateDetails[po.Template]; !ok {
|
||||||
|
po.log.Error("Template '%s' invalid.", po.Template)
|
||||||
|
templateSelected := PromptSelection("Select template", templates)
|
||||||
|
po.Template = templates[templateSelected]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
templateSelected := PromptSelection("Select template", templates)
|
||||||
|
po.Template = templates[templateSelected]
|
||||||
|
}
|
||||||
|
|
||||||
// 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))
|
||||||
|
|
||||||
// Fix template name
|
// Fix template name
|
||||||
po.Template = strings.Split(po.selectedTemplate.Path, string(os.PathSeparator))[0]
|
if po.templateNameMap[po.Template] != "" {
|
||||||
|
po.Template = po.templateNameMap[po.Template]
|
||||||
|
}
|
||||||
|
|
||||||
// // Populate template details
|
// Populate template details
|
||||||
templateMetadata := po.selectedTemplate.Metadata
|
templateMetadata := templateDetails[po.Template].Metadata
|
||||||
|
|
||||||
err = processTemplateMetadata(templateMetadata, po)
|
err = processTemplateMetadata(templateMetadata, po)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -282,36 +299,36 @@ func processBinaryName(po *ProjectOptions) {
|
|||||||
fmt.Println("Output binary Name: " + po.BinaryName)
|
fmt.Println("Output binary Name: " + po.BinaryName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func processTemplateMetadata(templateMetadata *TemplateMetadata, po *ProjectOptions) error {
|
func processTemplateMetadata(templateMetadata map[string]interface{}, po *ProjectOptions) error {
|
||||||
if templateMetadata.FrontendDir != "" {
|
if templateMetadata["frontenddir"] != nil {
|
||||||
po.FrontEnd = &frontend{}
|
po.FrontEnd = &frontend{}
|
||||||
po.FrontEnd.Dir = templateMetadata.FrontendDir
|
po.FrontEnd.Dir = templateMetadata["frontenddir"].(string)
|
||||||
}
|
}
|
||||||
if templateMetadata.Install != "" {
|
if templateMetadata["install"] != nil {
|
||||||
if po.FrontEnd == nil {
|
if po.FrontEnd == nil {
|
||||||
return fmt.Errorf("install set in template metadata but not frontenddir")
|
return fmt.Errorf("install set in template metadata but not frontenddir")
|
||||||
}
|
}
|
||||||
po.FrontEnd.Install = templateMetadata.Install
|
po.FrontEnd.Install = templateMetadata["install"].(string)
|
||||||
}
|
}
|
||||||
if templateMetadata.Build != "" {
|
if templateMetadata["build"] != nil {
|
||||||
if po.FrontEnd == nil {
|
if po.FrontEnd == nil {
|
||||||
return fmt.Errorf("build set in template metadata but not frontenddir")
|
return fmt.Errorf("build set in template metadata but not frontenddir")
|
||||||
}
|
}
|
||||||
po.FrontEnd.Build = templateMetadata.Build
|
po.FrontEnd.Build = templateMetadata["build"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if templateMetadata.Bridge != "" {
|
if templateMetadata["bridge"] != nil {
|
||||||
if po.FrontEnd == nil {
|
if po.FrontEnd == nil {
|
||||||
return fmt.Errorf("bridge set in template metadata but not frontenddir")
|
return fmt.Errorf("bridge set in template metadata but not frontenddir")
|
||||||
}
|
}
|
||||||
po.FrontEnd.Bridge = templateMetadata.Bridge
|
po.FrontEnd.Bridge = templateMetadata["bridge"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if templateMetadata.Serve != "" {
|
if templateMetadata["serve"] != nil {
|
||||||
if po.FrontEnd == nil {
|
if po.FrontEnd == nil {
|
||||||
return fmt.Errorf("serve set in template metadata but not frontenddir")
|
return fmt.Errorf("serve set in template metadata but not frontenddir")
|
||||||
}
|
}
|
||||||
po.FrontEnd.Serve = templateMetadata.Serve
|
po.FrontEnd.Serve = templateMetadata["serve"].(string)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,25 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Prompt asks the user for a value
|
// Prompt asks the user for a value
|
||||||
func Prompt(question string, defaultValue ...string) string {
|
func Prompt(question string, defaultValue ...string) string {
|
||||||
var answer string
|
var answer string
|
||||||
|
haveDefault := len(defaultValue) > 0 && defaultValue[0] != ""
|
||||||
|
|
||||||
if len(defaultValue) > 0 {
|
if haveDefault {
|
||||||
answer = defaultValue[0]
|
question = fmt.Sprintf("%s (%s)", question, defaultValue[0])
|
||||||
question = fmt.Sprintf("%s (%s)", question, answer)
|
|
||||||
}
|
}
|
||||||
fmt.Printf(question + ": ")
|
fmt.Printf(question + ": ")
|
||||||
reader := bufio.NewReader(os.Stdin)
|
fmt.Scanln(&answer)
|
||||||
input, _ := reader.ReadString('\n')
|
if haveDefault {
|
||||||
EOL := "\n"
|
if len(answer) == 0 {
|
||||||
if runtime.GOOS == "windows" {
|
answer = defaultValue[0]
|
||||||
EOL = "\r\n"
|
}
|
||||||
}
|
}
|
||||||
input = strings.Replace(input, EOL, "", -1)
|
|
||||||
|
|
||||||
if input != "" {
|
|
||||||
answer = input
|
|
||||||
}
|
|
||||||
|
|
||||||
return answer
|
return answer
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,29 +34,18 @@ func PromptRequired(question string, defaultValue ...string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PromptSelection asks the user to choose an option
|
// PromptSelection asks the user to choose an option
|
||||||
func PromptSelection(question string, options []string, optionalDefaultValue ...int) int {
|
func PromptSelection(question string, options []string) int {
|
||||||
|
|
||||||
defaultValue := -1
|
|
||||||
message := "Please choose an option"
|
|
||||||
fmt.Println(question + ":")
|
fmt.Println(question + ":")
|
||||||
|
|
||||||
if len(optionalDefaultValue) > 0 {
|
|
||||||
defaultValue = optionalDefaultValue[0] + 1
|
|
||||||
message = fmt.Sprintf("%s [%d]", message, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
for index, option := range options {
|
for index, option := range options {
|
||||||
fmt.Printf(" %d: %s\n", index+1, option)
|
fmt.Printf(" %d: %s\n", index+1, option)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
selectedValue := -1
|
selectedValue := -1
|
||||||
|
|
||||||
for {
|
for {
|
||||||
choice := Prompt(message)
|
choice := Prompt("Please choose an option")
|
||||||
if choice == "" && defaultValue > -1 {
|
|
||||||
selectedValue = defaultValue - 1
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// index
|
// index
|
||||||
number, err := strconv.Atoi(choice)
|
number, err := strconv.Atoi(choice)
|
||||||
|
|||||||
369
cmd/templates.go
369
cmd/templates.go
@@ -3,95 +3,112 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
mewn "github.com/leaanthony/mewn"
|
|
||||||
mewnlib "github.com/leaanthony/mewn/lib"
|
|
||||||
"github.com/leaanthony/slicer"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TemplateMetadata holds all the metadata for a Wails template
|
const templateSuffix = ".template"
|
||||||
type TemplateMetadata struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
ShortDescription string `json:"shortdescription"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Install string `json:"install"`
|
|
||||||
Build string `json:"build"`
|
|
||||||
Author string `json:"author"`
|
|
||||||
Created string `json:"created"`
|
|
||||||
FrontendDir string `json:"frontenddir"`
|
|
||||||
Serve string `json:"serve"`
|
|
||||||
Bridge string `json:"bridge"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// TemplateDetails holds information about a specific template
|
// TemplateHelper helps with creating projects
|
||||||
type TemplateDetails struct {
|
|
||||||
BasePath string
|
|
||||||
Path string
|
|
||||||
Metadata *TemplateMetadata
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, string(filepath.Separator))[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
|
|
||||||
type TemplateHelper struct {
|
type TemplateHelper struct {
|
||||||
TemplateList *TemplateList
|
system *SystemHelper
|
||||||
Files *mewnlib.FileGroup
|
fs *FSHelper
|
||||||
|
templateDir string
|
||||||
|
// templates map[string]string
|
||||||
|
templateSuffix string
|
||||||
|
metadataFilename string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template defines a single template
|
||||||
|
type Template struct {
|
||||||
|
Name string
|
||||||
|
Dir string
|
||||||
|
Metadata map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTemplateHelper creates a new template helper
|
// NewTemplateHelper creates a new template helper
|
||||||
func NewTemplateHelper() *TemplateHelper {
|
func NewTemplateHelper() *TemplateHelper {
|
||||||
files := mewn.Group("./templates")
|
result := TemplateHelper{
|
||||||
|
system: NewSystemHelper(),
|
||||||
return &TemplateHelper{
|
fs: NewFSHelper(),
|
||||||
TemplateList: NewTemplateList(files),
|
templateSuffix: ".template",
|
||||||
Files: files,
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTemplateNames returns a map of all available templates
|
||||||
|
func (t *TemplateHelper) GetTemplateNames() (map[string]string, error) {
|
||||||
|
templateDirs, err := t.fs.GetSubdirs(t.templateDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return templateDirs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTemplateDetails returns a map of Template structs containing details
|
||||||
|
// of the found templates
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadMetadata loads the template's 'metadata.json' file
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// TemplateExists returns true if the given template name exists
|
||||||
|
func (t *TemplateHelper) TemplateExists(templateName string) (bool, error) {
|
||||||
|
templates, err := t.GetTemplateNames()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
_, exists := templates[templateName]
|
||||||
|
return exists, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstallTemplate installs the template given in the project options to the
|
// InstallTemplate installs the template given in the project options to the
|
||||||
@@ -99,56 +116,162 @@ func NewTemplateHelper() *TemplateHelper {
|
|||||||
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error {
|
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error {
|
||||||
|
|
||||||
// Get template files
|
// Get template files
|
||||||
templatePath := projectOptions.selectedTemplate.Path
|
template, err := t.getTemplateFiles(projectOptions.Template)
|
||||||
|
if err != nil {
|
||||||
templateFilenames := slicer.String()
|
return err
|
||||||
templateFilenames.AddSlice(projectOptions.templates.Files.Entries())
|
}
|
||||||
|
|
||||||
templateJSONFilename := filepath.Join(templatePath, "template.json")
|
|
||||||
|
|
||||||
templateFiles := templateFilenames.Filter(func(filename string) bool {
|
|
||||||
return strings.HasPrefix(filename, templatePath) && filename != templateJSONFilename
|
|
||||||
})
|
|
||||||
|
|
||||||
var err error
|
|
||||||
templateFiles.Each(func(templateFile string) {
|
|
||||||
|
|
||||||
// Setup filenames
|
|
||||||
relativeFilename := strings.TrimPrefix(templateFile, templatePath)[1:]
|
|
||||||
targetFilename, err := filepath.Abs(filepath.Join(projectOptions.OutputDirectory, relativeFilename))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
filedata := projectOptions.templates.Files.Bytes(templateFile)
|
|
||||||
|
|
||||||
// If file is a template, process it
|
|
||||||
if strings.HasSuffix(templateFile, ".template") {
|
|
||||||
templateData := projectOptions.templates.Files.String(templateFile)
|
|
||||||
tmpl := template.New(templateFile)
|
|
||||||
tmpl.Parse(templateData)
|
|
||||||
var tpl bytes.Buffer
|
|
||||||
err = tmpl.Execute(&tpl, projectOptions)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove template suffix
|
|
||||||
targetFilename = strings.TrimSuffix(targetFilename, ".template")
|
|
||||||
|
|
||||||
// Set the filedata to the template result
|
|
||||||
filedata = tpl.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normal file, just copy it
|
|
||||||
err = fs.CreateFile(targetFilename, filedata)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
// Copy files to target
|
||||||
|
err = template.Install(projectPath, projectOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
1
cmd/templates/vuebasic/frontend/package.json.md5
Normal file
1
cmd/templates/vuebasic/frontend/package.json.md5
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2b79f883dc856221fc3265755d610e40
|
||||||
@@ -11,15 +11,12 @@ func basic() string {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
js := mewn.String("./frontend/dist/app.js")
|
|
||||||
css := mewn.String("./frontend/dist/app.css")
|
|
||||||
|
|
||||||
app := wails.CreateApp(&wails.AppConfig{
|
app := wails.CreateApp(&wails.AppConfig{
|
||||||
Width: 1024,
|
Width: 1024,
|
||||||
Height: 768,
|
Height: 768,
|
||||||
Title: "{{.Name}}",
|
Title: "{{.Name}}",
|
||||||
JS: js,
|
JS: mewn.String("./frontend/dist/app.js"),
|
||||||
CSS: css,
|
CSS: mewn.String("./frontend/dist/app.css"),
|
||||||
Colour: "#131313",
|
Colour: "#131313",
|
||||||
})
|
})
|
||||||
app.Bind(basic)
|
app.Bind(basic)
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ package cmd
|
|||||||
|
|
||||||
// Version - Wails version
|
// Version - Wails version
|
||||||
// ...oO(There must be a better way)
|
// ...oO(There must be a better way)
|
||||||
const Version = "v0.9.9"
|
const Version = "v0.9.5"
|
||||||
|
|||||||
20
cmd/wails/10_version.go
Normal file
20
cmd/wails/10_version.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
commandDescription := `Outputs the current version of the wails cli tool.`
|
||||||
|
|
||||||
|
versionCommand := app.Command("version", "Print Wails cli version").
|
||||||
|
LongDescription(commandDescription)
|
||||||
|
|
||||||
|
versionCommand.Action(func() error {
|
||||||
|
fmt.Println(cmd.Version)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
49
cmd/wails/12_report.go
Normal file
49
cmd/wails/12_report.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
commandDescription := `Generates a report to help resolve issues.`
|
||||||
|
|
||||||
|
versionCommand := app.Command("report", "Generates Report").
|
||||||
|
LongDescription(commandDescription)
|
||||||
|
|
||||||
|
versionCommand.Action(func() error {
|
||||||
|
modules := os.Getenv("GO111MODULE")
|
||||||
|
if modules == "" {
|
||||||
|
modules = "(Not set)"
|
||||||
|
}
|
||||||
|
fmt.Println("Please copy and paste this report when creating issues")
|
||||||
|
fmt.Println("------------------------------------------------------")
|
||||||
|
fmt.Printf("Wails Version: %s\n", cmd.Version)
|
||||||
|
fmt.Println("Go:")
|
||||||
|
fmt.Printf(" GOOS : %s\n", runtime.GOOS)
|
||||||
|
fmt.Printf(" GOARCH : %s\n", runtime.GOARCH)
|
||||||
|
fmt.Printf(" Version : %s\n", runtime.Version())
|
||||||
|
fmt.Println("Environment:")
|
||||||
|
fmt.Printf(" Shell : %s\n", getShell())
|
||||||
|
fmt.Printf(" GO111MODULE: %s\n", modules)
|
||||||
|
fmt.Println("------------------------------------------------------")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getShell() string {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
return os.Getenv("COMSPEC")
|
||||||
|
case "linux":
|
||||||
|
return os.Getenv("SHELL")
|
||||||
|
case "darwin":
|
||||||
|
return os.Getenv("SHELL")
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,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)
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"io/ioutil"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
@@ -54,13 +55,24 @@ func init() {
|
|||||||
updateSpinner := spinner.NewSpinner()
|
updateSpinner := spinner.NewSpinner()
|
||||||
updateSpinner.SetSpinSpeed(40)
|
updateSpinner.SetSpinSpeed(40)
|
||||||
updateSpinner.Start("Updating to : " + latestVersion)
|
updateSpinner.Start("Updating to : " + latestVersion)
|
||||||
err = cmd.NewProgramHelper().RunCommandArray([]string{"go","get","-u","github.com/wailsapp/wails/cmd/wails"})
|
err = cmd.NewProgramHelper().RunCommandArray([]string{"go", "get", "-u", "-a", "github.com/wailsapp/wails/cmd/wails"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
updateSpinner.Error(err.Error())
|
updateSpinner.Error(err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
updateSpinner.Success()
|
version, _, err := cmd.NewProgramHelper().GetOutputFromCommand("wails version")
|
||||||
logger.Yellow("Wails updated to " + latestVersion)
|
version = strings.TrimSpace(version)
|
||||||
|
if err != nil {
|
||||||
|
updateSpinner.Error(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if version != latestVersion {
|
||||||
|
updateSpinner.Error()
|
||||||
|
logger.Yellow("Weird! Wails was supposed to update to %s but seems to be at %s instead.", latestVersion, version)
|
||||||
|
} else {
|
||||||
|
updateSpinner.Success()
|
||||||
|
logger.Green("Success! Wails updated to " + version)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.Yellow("Looks like you're up to date!")
|
logger.Yellow("Looks like you're up to date!")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/pkg/browser"
|
|
||||||
|
|
||||||
"github.com/wailsapp/wails/cmd"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
|
|
||||||
commandDescription := `Generates an issue in Github using the given title, description and system report.`
|
|
||||||
|
|
||||||
initCommand := app.Command("issue", "Generates an issue in Github.").
|
|
||||||
LongDescription(commandDescription)
|
|
||||||
|
|
||||||
initCommand.Action(func() error {
|
|
||||||
|
|
||||||
logger.PrintSmallBanner("Generate Issue")
|
|
||||||
fmt.Println()
|
|
||||||
message := `Thanks for taking the time to submit an issue!
|
|
||||||
|
|
||||||
To help you in this process, we will ask for some information, add Go/Wails details automatically, then prepare the issue for your editing and submission.
|
|
||||||
`
|
|
||||||
|
|
||||||
logger.Yellow(message)
|
|
||||||
|
|
||||||
title := cmd.Prompt("Issue Title")
|
|
||||||
description := cmd.Prompt("Issue Description")
|
|
||||||
|
|
||||||
var str strings.Builder
|
|
||||||
|
|
||||||
gomodule, exists := os.LookupEnv("GO111MODULE")
|
|
||||||
if !exists {
|
|
||||||
gomodule = "(Not Set)"
|
|
||||||
}
|
|
||||||
|
|
||||||
str.WriteString("\n| Name | Value |\n| ----- | ----- |\n")
|
|
||||||
str.WriteString(fmt.Sprintf("| Wails Version | %s |\n", cmd.Version))
|
|
||||||
str.WriteString(fmt.Sprintf("| Go Version | %s |\n", runtime.Version()))
|
|
||||||
str.WriteString(fmt.Sprintf("| Platform | %s |\n", runtime.GOOS))
|
|
||||||
str.WriteString(fmt.Sprintf("| Arch | %s |\n", runtime.GOARCH))
|
|
||||||
str.WriteString(fmt.Sprintf("| GO111MODULE | %s |\n", gomodule))
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
fmt.Println("Processing template and preparing for upload.")
|
|
||||||
|
|
||||||
// Grab issue template
|
|
||||||
resp, err := http.Get("https://raw.githubusercontent.com/wailsapp/wails/master/.github/ISSUE_TEMPLATE/bug_report.md")
|
|
||||||
if err != nil {
|
|
||||||
logger.Red("Unable to read in issue template. Are you online?")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
template, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
body := string(template)
|
|
||||||
body = "**Description**\n" + (strings.Split(body, "**Description**")[1])
|
|
||||||
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, "Please paste the output of `wails report` here.", str.String(), -1)
|
|
||||||
params := "title=" + title + "&body=" + body
|
|
||||||
|
|
||||||
fmt.Println("Opening browser to file issue.")
|
|
||||||
browser.OpenURL(fullURL + url.PathEscape(params))
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
11
go.mod
11
go.mod
@@ -8,18 +8,17 @@ require (
|
|||||||
github.com/go-playground/colors v1.2.0
|
github.com/go-playground/colors v1.2.0
|
||||||
github.com/gorilla/websocket v1.4.0
|
github.com/gorilla/websocket v1.4.0
|
||||||
github.com/jackmordaunt/icns v1.0.0
|
github.com/jackmordaunt/icns v1.0.0
|
||||||
github.com/leaanthony/mewn v0.9.4
|
github.com/leaanthony/mewn v0.9.1
|
||||||
github.com/leaanthony/slicer v1.2.0
|
github.com/leaanthony/slicer v1.0.0
|
||||||
github.com/leaanthony/spinner v0.5.0
|
github.com/leaanthony/spinner v0.5.0
|
||||||
github.com/mattn/go-colorable v0.1.0 // indirect
|
github.com/mattn/go-colorable v0.1.1 // 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/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.3.0
|
github.com/sirupsen/logrus v1.3.0
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
github.com/wailsapp/webview v0.2.5
|
github.com/wailsapp/webview v0.2.5
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2 // indirect
|
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f // indirect
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd // indirect
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd // indirect
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 // indirect
|
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
22
go.sum
22
go.sum
@@ -19,10 +19,10 @@ github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmA
|
|||||||
github.com/jackmordaunt/icns v1.0.0/go.mod h1:7TTQVEuGzVVfOPPlLNHJIkzA6CoV7aH1Dv9dW351oOo=
|
github.com/jackmordaunt/icns v1.0.0/go.mod h1:7TTQVEuGzVVfOPPlLNHJIkzA6CoV7aH1Dv9dW351oOo=
|
||||||
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/leaanthony/mewn v0.9.4 h1:thDAdV8DkCwqHcFLnfMLQtTHqK1N8leF7sD/SPsLMHI=
|
github.com/leaanthony/mewn v0.9.1 h1:+qmAnR5nETU/00o5wvYJ7w9Y36R9uIBRB9I15E9Ru8A=
|
||||||
github.com/leaanthony/mewn v0.9.4/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
|
github.com/leaanthony/mewn v0.9.1/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
|
||||||
github.com/leaanthony/slicer v1.2.0 h1:XZ+1l7cCO36j238iv5ZXkJAcM3hPtD0xb41/WE+QmuU=
|
github.com/leaanthony/slicer v1.0.0 h1:BV2CySexcZ20qyHp5qBTxQhsazR6e8MBTF1EHmGu1xw=
|
||||||
github.com/leaanthony/slicer v1.2.0/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ=
|
github.com/leaanthony/slicer v1.0.0/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ=
|
||||||
github.com/leaanthony/spinner v0.5.0 h1:HQykt/iTy7fmINEREtRbWrt+8j4MxC8dtvWBxEWM9oA=
|
github.com/leaanthony/spinner v0.5.0 h1:HQykt/iTy7fmINEREtRbWrt+8j4MxC8dtvWBxEWM9oA=
|
||||||
github.com/leaanthony/spinner v0.5.0/go.mod h1:8TSFz9SL1AUC4XSbEFYE6SfN5Mlus51qYluVGrie9ww=
|
github.com/leaanthony/spinner v0.5.0/go.mod h1:8TSFz9SL1AUC4XSbEFYE6SfN5Mlus51qYluVGrie9ww=
|
||||||
github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8=
|
github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8=
|
||||||
@@ -31,18 +31,18 @@ github.com/leaanthony/wincursor v0.1.0 h1:Dsyp68QcF5cCs65AMBmxoYNEm0n8K7mMchG6a8
|
|||||||
github.com/leaanthony/wincursor v0.1.0/go.mod h1:7TVwwrzSH/2Y9gLOGH+VhA+bZhoWXBRgbGNTMk+yimE=
|
github.com/leaanthony/wincursor v0.1.0/go.mod h1:7TVwwrzSH/2Y9gLOGH+VhA+bZhoWXBRgbGNTMk+yimE=
|
||||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
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-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o=
|
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||||
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||||
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 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||||
|
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
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/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/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=
|
||||||
@@ -60,8 +60,8 @@ github.com/wailsapp/webview v0.2.5/go.mod h1:XO9HJbKWokDxUYTWQEBCYg95n/To1v7Pxva
|
|||||||
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=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2 h1:NwxKRvbkH5MsNkvOtPZi3/3kmI8CAzs3mtv+GLQMkNo=
|
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f h1:qWFY9ZxP3tfI37wYIs/MnIAqK0vlXp1xnYEa5HxFSSY=
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
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 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-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
|
||||||
@@ -72,3 +72,5 @@ golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb h1:pf3XwC90UUdNPYWZdFjhGBE7D
|
|||||||
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-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-20190222171317-cd391775e71e h1:oF7qaQxUH6KzFdKN4ww7NpPdo53SZi4UlcksLrb2y/o=
|
||||||
|
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user