Compare commits

..

7 Commits

Author SHA1 Message Date
Lea Anthony
6fafd165de Updated update command :-) 2019-02-23 18:26:36 +11:00
Lea Anthony
5ca7bfca66 improve messages 2019-02-23 15:53:19 +11:00
Lea Anthony
3f32c45f77 Try pulling in module at latest version 2019-02-23 15:25:14 +11:00
Lea Anthony
f8c805649a add report command 2019-02-23 15:24:26 +11:00
Lea Anthony
3ac993b01f Version bump 2019-02-23 13:26:03 +11:00
Lea Anthony
216c84b9cf Added version command to check after update 2019-02-23 12:56:40 +11:00
Lea Anthony
e99fffe340 Version bump 2019-02-23 10:25:31 +11:00
34 changed files with 488 additions and 534 deletions

View File

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

3
.gitignore vendored
View File

@@ -15,5 +15,4 @@ examples/**/example*
!examples/**/*.*
cmd/wails/wails
.DS_Store
tmp
dist
tmp

View File

@@ -1,26 +0,0 @@
# This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
before:
hooks:
- ./scripts/updateversion.sh
builds:
- env:
- CGO_ENABLED=0
main: ./cmd/wails/main.go
archive:
replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

View File

@@ -1,6 +1,6 @@
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
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,6 +1,8 @@
package wails
import (
"fmt"
"github.com/wailsapp/wails/cmd"
)
@@ -19,6 +21,8 @@ func (app *App) setupCli() *cmd.Cli {
// Banner
result.PreRun(func(cli *cmd.Cli) error {
log := cmd.NewLogger()
log.PrintSmallBanner()
fmt.Println()
log.YellowUnderline(app.config.Title + " - Debug Build")
return nil
})

View File

@@ -153,11 +153,8 @@ func (b *boundFunction) setInputValue(index int, typ reflect.Type, val interface
}
}()
// Translate javascript null values
if val == nil {
result = reflect.Zero(typ)
} else {
result = reflect.ValueOf(val).Convert(typ)
}
// Do the conversion
result = reflect.ValueOf(val).Convert(typ)
return result, err
}

File diff suppressed because one or more lines are too long

View File

@@ -41,14 +41,6 @@ func (fs *FSHelper) FileExists(path string) bool {
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.
// Returns error on failure
func (fs *FSHelper) MkDirs(fullPath string, mode ...os.FileMode) error {

View File

@@ -5,17 +5,15 @@ import (
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"time"
mewn "github.com/leaanthony/mewn"
"github.com/leaanthony/slicer"
"github.com/leaanthony/spinner"
)
var fs = NewFSHelper()
// ValidateFrontendConfig checks if the frontend config is valid
func ValidateFrontendConfig(projectOptions *ProjectOptions) error {
if projectOptions.FrontEnd.Dir == "" {
@@ -77,13 +75,7 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
packSpinner.Start()
buildCommand := slicer.String()
buildCommand.Add("mewn")
if buildMode == BuildModeBridge {
// Ignore errors
buildCommand.Add("-i")
}
buildCommand.Add("build")
buildCommand.AddSlice([]string{"mewn", "build"})
if binaryName != "" {
buildCommand.Add("-o")
@@ -116,14 +108,6 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
}
packSpinner.Success()
// packageApp
if packageApp {
err = PackageApplication(projectOptions)
if err != nil {
return err
}
}
return nil
}
@@ -188,7 +172,7 @@ func CheckWindres() (err error) {
}
programHelper := NewProgramHelper()
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
}
@@ -254,10 +238,10 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
}
// Copy bridge to project
bridgeAssets := mewn.Group("../wailsruntimeassets/bridge/")
bridgeFileData := bridgeAssets.Bytes(bridgeFile)
_, filename, _, _ := runtime.Caller(1)
bridgeFileSource := filepath.Join(path.Dir(filename), "..", "..", "wailsruntimeassets", "bridge", bridgeFile)
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, projectOptions.FrontEnd.Bridge, "wailsbridge.js")
err = fs.CreateFile(bridgeFileTarget, bridgeFileData)
err = fs.CopyFile(bridgeFileSource, bridgeFileTarget)
if err != nil {
return err
}

View File

@@ -17,7 +17,6 @@ func NewLogger() *Logger {
return &Logger{errorOnly: false}
}
// SetErrorOnly ensures that only errors are logged out
func (l *Logger) SetErrorOnly(errorOnly bool) {
l.errorOnly = errorOnly
}
@@ -100,7 +99,6 @@ func (l *Logger) Error(format string, a ...interface{}) {
color.New(color.FgHiRed).PrintfFunc()("Error: "+format+"\n", a...)
}
// PrintSmallBanner prints a condensed banner
func (l *Logger) PrintSmallBanner(message ...string) {
yellow := color.New(color.FgYellow).SprintFunc()
red := color.New(color.FgRed).SprintFunc()

View File

@@ -150,7 +150,6 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
return err
}
// PackageWindows packages the application for windows platforms
func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
basename := strings.TrimSuffix(po.BinaryName, ".exe")

View File

@@ -106,6 +106,15 @@ func (p *ProgramHelper) RunCommand(command string) error {
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
func (p *ProgramHelper) RunCommandArray(args []string) error {
program := args[0]

View File

@@ -4,12 +4,9 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/leaanthony/slicer"
)
type author struct {
@@ -50,11 +47,15 @@ func NewProjectHelper() *ProjectHelper {
// GenerateProject generates a new project using the options given
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 {
// return fmt.Errorf("template '%s' is invalid", projectOptions.Template)
// }
if !exists {
return fmt.Errorf("template '%s' is invalid", projectOptions.Template)
}
// Calculate project path
projectPath, err := filepath.Abs(projectOptions.OutputDirectory)
@@ -62,8 +63,6 @@ func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
return err
}
_ = projectPath
if fs.DirExists(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
func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
result := ProjectOptions{
Name: "",
Description: "Enter your project description",
Version: "0.1.0",
BinaryName: "",
system: NewSystemHelper(),
log: NewLogger(),
templates: NewTemplateHelper(),
Author: &author{},
Name: "",
Description: "Enter your project description",
Version: "0.1.0",
BinaryName: "",
system: NewSystemHelper(),
log: NewLogger(),
templates: NewTemplateHelper(),
templateNameMap: make(map[string]string),
Author: &author{},
}
// Populate system config
@@ -137,25 +137,25 @@ func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
// ProjectOptions holds all the options available for a project
type ProjectOptions struct {
Name string `json:"name"`
Description string `json:"description"`
Author *author `json:"author,omitempty"`
Version string `json:"version"`
OutputDirectory string `json:"-"`
UseDefaults bool `json:"-"`
Template string `json:"-"`
BinaryName string `json:"binaryname"`
FrontEnd *frontend `json:"frontend,omitempty"`
NPMProjectName string `json:"-"`
system *SystemHelper
log *Logger
templates *TemplateHelper
selectedTemplate *TemplateDetails
Name string `json:"name"`
Description string `json:"description"`
Author *author `json:"author,omitempty"`
Version string `json:"version"`
OutputDirectory string `json:"-"`
UseDefaults bool `json:"-"`
Template string `json:"-"`
BinaryName string `json:"binaryname"`
FrontEnd *frontend `json:"frontend,omitempty"`
NPMProjectName string `json:"-"`
system *SystemHelper
log *Logger
templates *TemplateHelper
templateNameMap map[string]string // Converts template prompt text to template name
}
// Defaults sets the default project template
func (po *ProjectOptions) Defaults() {
po.Template = "vuebasic"
po.Template = "basic"
}
// PromptForInputs asks the user to input project details
@@ -170,31 +170,48 @@ func (po *ProjectOptions) PromptForInputs() error {
return err
}
// Process Templates
templateList := slicer.Interface()
options := slicer.String()
for _, templateDetails := range po.templates.TemplateList.details {
templateList.Add(templateDetails)
options.Add(fmt.Sprintf("%s - %s", templateDetails.Metadata.Name, templateDetails.Metadata.ShortDescription))
templateDetails, err := po.templates.GetTemplateDetails()
if err != nil {
return err
}
templateIndex := 0
if len(options.AsSlice()) > 1 {
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
templates := []string{}
// Add a Custom Template
// templates = append(templates, "Custom - Choose your own CSS framework")
for templateName, templateDetails := range templateDetails {
templateText := templateName
// Check if metadata json exists
if templateDetails.Metadata != nil {
shortdescription := templateDetails.Metadata["shortdescription"]
if shortdescription != "" {
templateText += " - " + shortdescription.(string)
}
}
templates = append(templates, templateText)
po.templateNameMap[templateText] = templateName
}
// After selection do this....
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
if po.Template != "" {
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
po.NPMProjectName = strings.ToLower(strings.Replace(po.Name, " ", "_", -1))
// 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
templateMetadata := po.selectedTemplate.Metadata
// Populate template details
templateMetadata := templateDetails[po.Template].Metadata
err = processTemplateMetadata(templateMetadata, po)
if err != nil {
@@ -282,36 +299,36 @@ func processBinaryName(po *ProjectOptions) {
fmt.Println("Output binary Name: " + po.BinaryName)
}
func processTemplateMetadata(templateMetadata *TemplateMetadata, po *ProjectOptions) error {
if templateMetadata.FrontendDir != "" {
func processTemplateMetadata(templateMetadata map[string]interface{}, po *ProjectOptions) error {
if templateMetadata["frontenddir"] != nil {
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 {
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 {
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 {
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 {
return fmt.Errorf("serve set in template metadata but not frontenddir")
}
po.FrontEnd.Serve = templateMetadata.Serve
po.FrontEnd.Serve = templateMetadata["serve"].(string)
}
return nil
}

View File

@@ -1,35 +1,25 @@
package cmd
import (
"bufio"
"fmt"
"os"
"runtime"
"strconv"
"strings"
)
// Prompt asks the user for a value
func Prompt(question string, defaultValue ...string) string {
var answer string
haveDefault := len(defaultValue) > 0 && defaultValue[0] != ""
if len(defaultValue) > 0 {
answer = defaultValue[0]
question = fmt.Sprintf("%s (%s)", question, answer)
if haveDefault {
question = fmt.Sprintf("%s (%s)", question, defaultValue[0])
}
fmt.Printf(question + ": ")
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
EOL := "\n"
if runtime.GOOS == "windows" {
EOL = "\r\n"
fmt.Scanln(&answer)
if haveDefault {
if len(answer) == 0 {
answer = defaultValue[0]
}
}
input = strings.Replace(input, EOL, "", -1)
if input != "" {
answer = input
}
return answer
}
@@ -44,29 +34,18 @@ func PromptRequired(question string, defaultValue ...string) string {
}
// 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 + ":")
if len(optionalDefaultValue) > 0 {
defaultValue = optionalDefaultValue[0] + 1
message = fmt.Sprintf("%s [%d]", message, defaultValue)
}
for index, option := range options {
fmt.Printf(" %d: %s\n", index+1, option)
}
fmt.Println()
selectedValue := -1
for {
choice := Prompt(message)
if choice == "" && defaultValue > -1 {
selectedValue = defaultValue - 1
break
}
choice := Prompt("Please choose an option")
// index
number, err := strconv.Atoi(choice)

View File

@@ -3,95 +3,112 @@ package cmd
import (
"bytes"
"encoding/json"
"log"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"runtime"
"strings"
"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
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"`
}
const templateSuffix = ".template"
// TemplateDetails holds information about a specific template
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
// TemplateHelper helps with creating projects
type TemplateHelper struct {
TemplateList *TemplateList
Files *mewnlib.FileGroup
system *SystemHelper
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
func NewTemplateHelper() *TemplateHelper {
files := mewn.Group("./templates")
return &TemplateHelper{
TemplateList: NewTemplateList(files),
Files: files,
result := TemplateHelper{
system: NewSystemHelper(),
fs: NewFSHelper(),
templateSuffix: ".template",
metadataFilename: "template.json",
}
// Calculate template base dir
_, filename, _, _ := runtime.Caller(1)
result.templateDir = filepath.Join(path.Dir(filename), "templates")
// result.templateDir = filepath.Join(result.system.homeDir, "go", "src", "github.com", "wailsapp", "wails", "cmd", "templates")
return &result
}
// 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
@@ -99,56 +116,162 @@ func NewTemplateHelper() *TemplateHelper {
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error {
// Get template files
templatePath := projectOptions.selectedTemplate.Path
templateFilenames := slicer.String()
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
}
})
template, err := t.getTemplateFiles(projectOptions.Template)
if err != nil {
return err
}
// Copy files to target
err = template.Install(projectPath, projectOptions)
if err != nil {
return err
}
return nil
}
// templateFiles categorises files found in a template
type templateFiles struct {
BaseDir string
StandardFiles []string
Templates []string
Dirs []string
}
// newTemplateFiles returns a new TemplateFiles struct
func (t *TemplateHelper) newTemplateFiles(dir string) *templateFiles {
pathsep := string(os.PathSeparator)
// Ensure base directory has trailing slash
if !strings.HasSuffix(dir, pathsep) {
dir = dir + pathsep
}
return &templateFiles{
BaseDir: dir,
}
}
// AddStandardFile adds the given file to the list of standard files
func (t *templateFiles) AddStandardFile(filename string) {
localPath := strings.TrimPrefix(filename, t.BaseDir)
t.StandardFiles = append(t.StandardFiles, localPath)
}
// AddTemplate adds the given file to the list of template files
func (t *templateFiles) AddTemplate(filename string) {
localPath := strings.TrimPrefix(filename, t.BaseDir)
t.Templates = append(t.Templates, localPath)
}
// AddDir adds the given directory to the list of template dirs
func (t *templateFiles) AddDir(dir string) {
localPath := strings.TrimPrefix(dir, t.BaseDir)
t.Dirs = append(t.Dirs, localPath)
}
// getTemplateFiles returns a struct categorising files in
// the template directory
func (t *TemplateHelper) getTemplateFiles(templateName string) (*templateFiles, error) {
templates, err := t.GetTemplateNames()
if err != nil {
return nil, err
}
templateDir := templates[templateName]
result := t.newTemplateFiles(templateDir)
var localPath string
err = filepath.Walk(templateDir, func(dir string, info os.FileInfo, err error) error {
if dir == templateDir {
return nil
}
if err != nil {
return err
}
// Don't copy template metadata
localPath = strings.TrimPrefix(dir, templateDir+string(filepath.Separator))
if localPath == t.metadataFilename {
return nil
}
// Categorise the file
switch {
case info.IsDir():
result.AddDir(dir)
case strings.HasSuffix(info.Name(), templateSuffix):
result.AddTemplate(dir)
default:
result.AddStandardFile(dir)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("error processing template '%s' in path '%q': %v", templateName, templateDir, err)
}
return result, err
}
// Install the template files into the given project path
func (t *templateFiles) Install(projectPath string, projectOptions *ProjectOptions) error {
fs := NewFSHelper()
// Create directories
var targetDir string
for _, dirname := range t.Dirs {
targetDir = filepath.Join(projectPath, dirname)
fs.MkDir(targetDir)
}
// Copy standard files
var targetFile, sourceFile string
var err error
for _, filename := range t.StandardFiles {
sourceFile = filepath.Join(t.BaseDir, filename)
targetFile = filepath.Join(projectPath, filename)
err = fs.CopyFile(sourceFile, targetFile)
if err != nil {
return err
}
}
// Do we have template files?
if len(t.Templates) > 0 {
// Iterate over the templates
var templateFile string
var tmpl *template.Template
for _, filename := range t.Templates {
// Load template text
templateFile = filepath.Join(t.BaseDir, filename)
templateText, err := fs.LoadAsString(templateFile)
if err != nil {
return err
}
// Apply template
tmpl = template.New(templateFile)
tmpl.Parse(templateText)
// Write the template to a buffer
var tpl bytes.Buffer
err = tmpl.Execute(&tpl, projectOptions)
if err != nil {
fmt.Println("ERROR!!! " + err.Error())
return err
}
// Save buffer to disk
targetFilename := strings.TrimSuffix(filename, templateSuffix)
targetFile = filepath.Join(projectPath, targetFilename)
err = ioutil.WriteFile(targetFile, tpl.Bytes(), 0644)
if err != nil {
return err
}
}
}
return nil
}

View File

@@ -0,0 +1 @@
2b79f883dc856221fc3265755d610e40

View File

@@ -11,15 +11,12 @@ func basic() string {
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,
JS: mewn.String("./frontend/dist/app.js"),
CSS: mewn.String("./frontend/dist/app.css"),
Colour: "#131313",
})
app.Bind(basic)

View File

@@ -1,4 +1,5 @@
package cmd
// Version - Wails version
const Version = "v0.11.0"
// ...oO(There must be a better way)
const Version = "v0.9.5"

20
cmd/wails/10_version.go Normal file
View 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
View 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 ""
}
}

View File

@@ -17,7 +17,7 @@ Any flags that are required and not given will be prompted for.`
LongDescription(commandDescription).
BoolFlag("f", "Use defaults", &projectOptions.UseDefaults).
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("description", "Project description", &projectOptions.Description).
StringFlag("output", "Output binary name", &projectOptions.BinaryName)

View File

@@ -26,9 +26,6 @@ func init() {
initCmd.Action(func() error {
message := "Building Application"
if packageApp {
message = "Packaging Application"
}
if forceRebuild {
message += " (force rebuild)"
}

View File

@@ -2,7 +2,6 @@ package main
import (
"fmt"
"os"
"github.com/leaanthony/spinner"
"github.com/wailsapp/wails/cmd"
@@ -25,53 +24,19 @@ func init() {
logger.PrintSmallBanner(message)
fmt.Println()
// Check Mewn is installed
err := cmd.CheckMewn()
if err != nil {
return err
}
// Project options
projectOptions := &cmd.ProjectOptions{}
// Check we are in project directory
// Check project.json loads correctly
fs := cmd.NewFSHelper()
err = projectOptions.LoadConfig(fs.Cwd())
err := projectOptions.LoadConfig(fs.Cwd())
if err != nil {
return err
}
// Validate config
// Check if we have a frontend
err = cmd.ValidateFrontendConfig(projectOptions)
if err != nil {
return err
}
// Program checker
program := cmd.NewProgramHelper()
if projectOptions.FrontEnd != nil {
// npm
if !program.IsInstalled("npm") {
return fmt.Errorf("it appears npm is not installed. Please install and run again")
}
}
// Save project directory
projectDir := fs.Cwd()
// Install deps
if projectOptions.FrontEnd != nil {
err = cmd.InstallFrontendDeps(projectDir, projectOptions, forceRebuild, "serve")
if err != nil {
return err
}
}
// Move to project directory
err = os.Chdir(projectDir)
// Check Mewn is installed
err = cmd.CheckMewn()
if err != nil {
return err
}

View File

@@ -1,10 +1,11 @@
package main
import (
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/leaanthony/spinner"
"github.com/wailsapp/wails/cmd"
@@ -54,13 +55,24 @@ func init() {
updateSpinner := spinner.NewSpinner()
updateSpinner.SetSpinSpeed(40)
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 {
updateSpinner.Error(err.Error())
return err
}
updateSpinner.Success()
logger.Yellow("Wails updated to " + latestVersion)
version, _, err := cmd.NewProgramHelper().GetOutputFromCommand("wails version")
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 {
logger.Yellow("Looks like you're up to date!")
}

View File

@@ -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
})
}

13
go.mod
View File

@@ -8,20 +8,17 @@ require (
github.com/go-playground/colors v1.2.0
github.com/gorilla/websocket v1.4.0
github.com/jackmordaunt/icns v1.0.0
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/leaanthony/mewn v0.10.2
github.com/leaanthony/slicer v1.3.1
github.com/leaanthony/mewn v0.9.1
github.com/leaanthony/slicer v1.0.0
github.com/leaanthony/spinner v0.5.0
github.com/mattn/go-colorable v0.1.1 // indirect
github.com/mattn/go-isatty v0.0.6 // indirect
github.com/mitchellh/go-homedir v1.1.0
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/sirupsen/logrus v1.3.0
github.com/stretchr/testify v1.3.0 // indirect
github.com/wailsapp/webview v0.2.5
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect
golang.org/x/net v0.0.0-20190310014029-b774fd8d5c0f // indirect
golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa // indirect
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f // indirect
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd // indirect
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e // indirect
)

28
go.sum
View File

@@ -19,12 +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/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.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/leaanthony/mewn v0.10.2 h1:Kzu1NqHHXriuMyGiHDMLk4aTzydZ3qbvz/qmoquGkvQ=
github.com/leaanthony/mewn v0.10.2/go.mod h1:i3ygCWW96qVQlGa8sjWnTM0IKAijoFvTwATDIZgK4k0=
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/mewn v0.9.1 h1:+qmAnR5nETU/00o5wvYJ7w9Y36R9uIBRB9I15E9Ru8A=
github.com/leaanthony/mewn v0.9.1/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
github.com/leaanthony/slicer v1.0.0 h1:BV2CySexcZ20qyHp5qBTxQhsazR6e8MBTF1EHmGu1xw=
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/go.mod h1:8TSFz9SL1AUC4XSbEFYE6SfN5Mlus51qYluVGrie9ww=
github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8=
@@ -37,17 +35,14 @@ github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0X
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/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-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA=
github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
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/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/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/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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -65,18 +60,17 @@ 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=
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-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-20190222235706-ffb98f73852f h1:qWFY9ZxP3tfI37wYIs/MnIAqK0vlXp1xnYEa5HxFSSY=
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/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190310014029-b774fd8d5c0f h1:CxcNDReoTQBlkHuyVUepQrMJTSa7q1+j65kVRv6jK3c=
golang.org/x/net v0.0.0-20190310014029-b774fd8d5c0f/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/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
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/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/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa h1:lqti/xP+yD/6zH5TqEwx2MilNIJY5Vbc6Qr8J3qyPIQ=
golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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=

View File

@@ -1,8 +1,8 @@
package wails
import (
"encoding/hex"
"encoding/json"
"strings"
)
// ipcResponse contains the response data from an RPC call
@@ -37,9 +37,7 @@ func newSuccessResponse(callbackID string, data interface{}) *ipcResponse {
// Serialise formats the response to a string
func (i *ipcResponse) Serialise() (string, error) {
b, err := json.Marshal(i)
if err != nil {
return "", err
}
result := hex.EncodeToString(b)
result := strings.Replace(string(b), "\\", "\\\\", -1)
result = strings.Replace(result, "'", "\\'", -1)
return result, err
}

View File

@@ -5,7 +5,6 @@ import (
"fmt"
"net/http"
"strings"
"sync"
"github.com/dchest/htmlmin"
"github.com/gorilla/websocket"
@@ -46,9 +45,6 @@ type Headless struct {
initialisationJS []string
server *http.Server
theConnection *websocket.Conn
// Mutex for writing to the socket
lock sync.Mutex
}
// Initialise the Headless Renderer
@@ -107,10 +103,6 @@ func (h *Headless) wsBridgeHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *Headless) sendMessage(conn *websocket.Conn, msg string) {
h.lock.Lock()
defer h.lock.Unlock()
if err := conn.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
h.log.Error(err.Error())
}

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
TAG=$(git describe --abbrev=0 --tags)
cat << EOF > cmd/version.go
package cmd
// Version - Wails version
const Version = "${TAG}"
EOF

File diff suppressed because one or more lines are too long

View File

@@ -29,7 +29,7 @@ window.wailsbridge = {
'<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-title">Wails Bridge</div><br><div class="wails-reconnect-overlay-loadingspinner"></div><br><div id="wails-reconnect-overlay-message">Waiting for backend</div></div></div>',
overlayCSS:
".wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);font-family:sans-serif;display:none;z-index:999999}.wails-reconnect-overlay-content{padding:20px 30px;text-align:center;width:20em;position:relative;height:14em;border-radius:1em;margin:5% auto 0;background-color:#fff;box-shadow:1px 1px 20px 3px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAqFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAEBAQAAAAAAAAAAAAEBAQEBAQDAwMBAQEAAAABAQEAAAAAAAAAAAABAQEAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWKCj6oAAAAN3RSTlMALiIqDhkGBAswJjP0GxP6NR4W9/ztjRDMhWU50G9g5eHXvbZ9XEI9xZTcqZl2aldKo55QwoCvZUgzhAAAAs9JREFUSMeNleeWqjAUhU0BCaH3Itiw9zKT93+zG02QK1hm/5HF+jzZJ6fQe6cyXE+jg9X7o9wxuylIIf4Tv2V3+bOrEXnf8dwQ/KQIGDN2/S+4OmVCVXL/ScBnfibxURqIByP/hONE8r8T+bDMlQ98KSl7Y8hzjpS8v1qtDh8u5f8KQpGpfnPPhqG8JeogN37Hq9eaN2xRhIwAaGnvws8F1ShxqK5ob2twYi1FAMD4rXsYtnC/JEiRbl4cUrCWhnMCLRFemXezXbb59QK4WASOsm6n2W1+4CBT2JmtzQ6fsrbGubR/NFbd2g5Y179+5w/GEHaKsHjYCet7CgrXU3txarNC7YxOVJtIj4/ERzMdZfzc31hp+8cD6eGILgarZY9uZ12hAs03vfBD9C171gS5Omz7OcvxALQIn4u8RRBBBcsi9WW2woO9ipLgfzpYlggg3ZRdROUC8KT7QLqq3W9KB5BbdFVg4929kdwp6+qaZnMCCNBdj+NyN1W885Ry/AL3D4AQbsVV4noCiM/C83kyYq80XlDAYQtralOiDzoRAHlotWl8q2tjvYlOgcg1A8jEApZa+C06TBdAz2Qv0wu11I/zZOyJQ6EwGez2P2b8PIQr1hwwnAZsAxwA4UAYOyXUxM/xp6tHAn4GUmPGM9R28oVxgC0e/zQJJI6DyhyZ1r7uzRQhpcW7x7vTaWSzKSG6aep77kroTEl3U81uSVaUTtgEINfC8epx+Q4F9SpplHG84Ek6m4RAq9/TLkOBrxyeuddZhHvGIp1XXfFy3Z3vtwNblKGiDn+J+92vwwABHghj7HnzlS1H5kB49AZvdGCFgiBPq69qfXPr3y++yilF0ON4R8eR7spAsLpZ95NqAW5tab1c4vkZm6aleajchMwYTdILQQTwE2OV411ZM9WztDjPql12caBi6gDpUKmDd4U1XNdQxZ4LIXQ5/Tr4P7I9tYcFrDK3AAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-title{font-size:2em}.wails-reconnect-overlay-message{font-size:1.3em}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#3E67EC #eee #eee;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg)}}",
log: function (message) {
log: function(message) {
// eslint-disable-next-line
console.log(
"%c wails bridge %c " + message + " ",
@@ -102,7 +102,7 @@ function startBridge() {
// Bridge external.invoke
window.external = {
invoke: function (msg) {
invoke: function(msg) {
window.wailsbridge.websocket.send(msg);
}
};
@@ -142,11 +142,11 @@ function startBridge() {
// Try to connect to the backend every 300ms (default value).
// Change this value in the main wailsbridge object.
function connect() {
window.wailsbridge.connectTimer = setInterval(function () {
window.wailsbridge.connectTimer = setInterval(function() {
if (window.wailsbridge.websocket == null) {
window.wailsbridge.websocket = new WebSocket(window.wailsbridge.wsURL);
window.wailsbridge.websocket.onopen = handleConnect;
window.wailsbridge.websocket.onerror = function (e) {
window.wailsbridge.websocket.onerror = function(e) {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
@@ -159,6 +159,7 @@ function startBridge() {
function handleMessage(message) {
// As a bridge we ignore js and css injections
switch (message.data[0]) {
// Wails library - inject!
case "w":
@@ -166,7 +167,7 @@ function startBridge() {
// Now wails runtime is loaded, wails for the ready event
// and callback to the main app
window.wails.events.on("wails:loaded", function () {
window.wails.events.on("wails:loaded", function() {
window.wailsbridge.log("Wails Ready");
if (window.wailsbridge.callback) {
window.wailsbridge.log("Notifying application");
@@ -188,6 +189,7 @@ function startBridge() {
// Call back
case "c":
var callbackData = message.data.slice(1);
window.wailsbridge.log("Callback = " + callbackData);
window.wails._.callback(callbackData);
break;
}
@@ -203,7 +205,7 @@ function startBridge() {
export default {
// The main function
// Passes the main Wails object to the callback if given.
Start: function (callback) {
Start: function(callback) {
// Save the callback
window.wailsbridge.callback = callback;

View File

@@ -1 +1 @@
!function(){var e;function n(e){try{return new Function("var "+e),!0}catch(e){return!1}}window.wails=window.wails||{},window.backend={},e=window.crypto?function(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}:function(){return 9007199254740991*Math.random()};var a=window.backend;var t={};var i={};function r(e,n){n={type:"log",payload:{level:e,message:n}},external.invoke(JSON.stringify(n))}window.wails.events={emit:function(e){var n=JSON.stringify([].slice.apply(arguments).slice(1));message={type:"event",payload:{name:e,data:n}},external.invoke(JSON.stringify(message))},on:function(e,n){i[e]=i[e]||[],i[e].push(n)}},window.wails.log={debug:function(e){r("debug",e)},info:function(e){r("info",e)},warning:function(e){r("warning",e)},error:function(e){r("error",e)},fatal:function(e){r("fatal",e)}},window.wails._={newBinding:function(i){var r,l=i.split(".").splice(1),o=l.pop(),c=function(e){var t=a;for(var i in e){var r=e[i];if(!n(r))return[null,new Error(r+" is not a valid javascript identifier.")];t[r]||(t[r]={}),t=t[r]}return[t,null]}(l),s=c[0];if(null!=(r=c[1]))return r;s[o]=function(){var n=0;function a(){var a=[].slice.call(arguments);return function(n,a,i){return null!=i&&null!=i||(i=0),new Promise(function(r,l){var o;do{o=n+"-"+e()}while(t[o]);if(i>0)var c=setTimeout(function(){l(Error("Call to "+n+" timed out. Request ID: "+o))},i);t[o]={timeoutHandle:c,reject:l,resolve:r};try{var s=JSON.stringify(a);message={type:"call",callbackid:o,payload:{bindingName:n,data:s}};var u=JSON.stringify(message);external.invoke(u)}catch(e){console.error(e)}})}(i,a,n)}return a.setTimeout=function(e){n=e},a.getTimeout=function(){return n},a}()},callback:function(e){var n;e=decodeURIComponent(e.replace(/\s+/g,"").replace(/[0-9a-f]{2}/g,"%$&"));try{n=JSON.parse(e)}catch(n){return wails.log.debug("Invalid JSON passed to callback: "+n.message),void wails.log.debug("Message: "+e)}if(callbackID=n.callbackid,callbackData=t[callbackID],callbackData)return clearTimeout(callbackData.timeoutHandle),delete t[callbackID],n.error?callbackData.reject(n.error):callbackData.resolve(n.data);console.error("Callback '"+callbackID+"' not registed!!!")},notify:function(e,n){i[e]&&i[e].forEach(function(a){var t=[];if(n)try{t=JSON.parse(n)}catch(n){wails.log.error("Invalid JSON data sent to notify. Event name = "+e)}a.apply(null,t)})},sendLogMessage:r,callbacks:t,injectCSS:function(e){var n=document.createElement("style");n.setAttribute("type","text/css"),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e)),(document.head||document.getElementsByTagName("head")[0]).appendChild(n)},addScript:function(e,n){var a=document.createElement("script");a.text=e,document.body.appendChild(a),window.wails.events.emit(n)}},window.wails.events.emit("wails:loaded")}();
(function(){window.wails=window.wails||{};window.backend={};function cryptoRandom(){var array=new Uint32Array(1);return window.crypto.getRandomValues(array)[0]}function basicRandom(){return Math.random()*9007199254740991}var randomFunc;if(window.crypto){randomFunc=cryptoRandom}else{randomFunc=basicRandom}function isValidIdentifier(name){try{new Function("var "+name);return true}catch(e){return false}}function addScript(js,callbackID){var script=document.createElement("script");script.text=js;document.body.appendChild(script);window.wails.events.emit(callbackID)}function injectCSS(css){var elem=document.createElement('style');elem.setAttribute('type','text/css');if(elem.styleSheet){elem.styleSheet.cssText=css}else{elem.appendChild(document.createTextNode(css))}var head=document.head||document.getElementsByTagName('head')[0];head.appendChild(elem)}var bindingsBasePath=window.backend;function addBindingPath(pathSections){var currentPath=bindingsBasePath;for(var sectionIndex in pathSections){var section=pathSections[sectionIndex];if(!isValidIdentifier(section)){var errMessage=section+" is not a valid javascript identifier.";var err=new Error(errMessage);return[null,err]}if(!currentPath[section]){currentPath[section]={}}currentPath=currentPath[section]}return[currentPath,null]}function newBinding(bindingName){var bindingSections=bindingName.split('.').splice(1);var callName=bindingSections.pop();var pathToBinding;var err;var bs=addBindingPath(bindingSections);var pathToBinding=bs[0];var err=bs[1];if(err!=null){return err}pathToBinding[callName]=function(){var timeout=0;function dynamic(){var args=[].slice.call(arguments);return call(bindingName,args,timeout)}dynamic.setTimeout=function(newTimeout){timeout=newTimeout};dynamic.getTimeout=function(){return timeout};return dynamic}()}var callbacks={};function call(bindingName,data,timeout){if(timeout==null||timeout==undefined){timeout=0}return new Promise(function(resolve,reject){var callbackID;do{callbackID=bindingName+"-"+randomFunc()}while(callbacks[callbackID]);if(timeout>0){var timeoutHandle=setTimeout(function(){reject(Error("Call to "+bindingName+" timed out. Request ID: "+callbackID))},timeout)}callbacks[callbackID]={timeoutHandle:timeoutHandle,reject:reject,resolve:resolve};try{var payloaddata=JSON.stringify(data);message={type:"call",callbackid:callbackID,payload:{bindingName:bindingName,data:payloaddata}};var payload=JSON.stringify(message);external.invoke(payload)}catch(e){console.error(e)}})}function callback(incomingMessage){var message;try{message=JSON.parse(incomingMessage)}catch(e){wails.log.debug("Invalid JSON passed to callback: "+e.message);wails.log.debug("Message: "+incomingMessage);return}callbackID=message.callbackid;callbackData=callbacks[callbackID];if(!callbackData){console.error("Callback '"+callbackID+"' not registed!!!");return}clearTimeout(callbackData.timeoutHandle);delete callbacks[callbackID];if(message.error){return callbackData.reject(message.error)}return callbackData.resolve(message.data)}var eventListeners={};function on(eventName,callback){eventListeners[eventName]=eventListeners[eventName]||[];eventListeners[eventName].push(callback)}function notify(eventName,data){if(eventListeners[eventName]){eventListeners[eventName].forEach(function(element){var parsedData=[];if(data){try{parsedData=JSON.parse(data)}catch(e){wails.log.error("Invalid JSON data sent to notify. Event name = "+eventName)}}element.apply(null,parsedData)})}}function emit(eventName){var data=JSON.stringify([].slice.apply(arguments).slice(1));message={type:"event",payload:{name:eventName,data:data}};external.invoke(JSON.stringify(message))}window.wails.events={emit:emit,on:on};function sendLogMessage(level,message){message={type:"log",payload:{level:level,message:message}};external.invoke(JSON.stringify(message))}function logDebug(message){sendLogMessage("debug",message)}function logInfo(message){sendLogMessage("info",message)}function logWarning(message){sendLogMessage("warning",message)}function logError(message){sendLogMessage("error",message)}function logFatal(message){sendLogMessage("fatal",message)}window.wails.log={debug:logDebug,info:logInfo,warning:logWarning,error:logError,fatal:logFatal};window.wails._={newBinding:newBinding,callback:callback,notify:notify,sendLogMessage:sendLogMessage,callbacks:callbacks,injectCSS:injectCSS,addScript:addScript};window.wails.events.emit("wails:loaded");})();

View File

@@ -10,8 +10,8 @@
function cryptoRandom() {
var array = new Uint32Array(1);
return window.crypto.getRandomValues(array)[0];
}
}
// LOLRandom
function basicRandom() {
@@ -203,10 +203,6 @@
// Called by the backend to return data to a previously called
// binding invocation
function callback(incomingMessage) {
// Decode the message - Credit: https://stackoverflow.com/a/13865680
incomingMessage = decodeURIComponent(incomingMessage.replace(/\s+/g, '').replace(/[0-9a-f]{2}/g, '%$&'));
// Parse the message
var message;
try {
@@ -247,7 +243,7 @@
// notify informs frontend listeners that an event was emitted with the given data
function notify(eventName, data) {
if (eventListeners[eventName]) {
eventListeners[eventName].forEach(function (element) {
eventListeners[eventName].forEach(function(element) {
var parsedData = [];
// Parse data if we have it
if (data) {
@@ -336,8 +332,8 @@
callbacks: callbacks,
injectCSS: injectCSS,
addScript: addScript,
}
}
/************************************************************/