Compare commits

..

30 Commits

Author SHA1 Message Date
Lea Anthony
c5276cca6c fix: convert js nulls to Go zero values 2019-03-19 08:20:45 +11:00
Lea Anthony
74dbbbed8a Merge pull request #65 from wailsapp/improved-ipc-encoding
Use hex encoded strings for callbacks
2019-03-17 16:57:50 +11:00
Lea Anthony
629ac4b93c Use hex encoded strings for callbacks 2019-03-17 16:56:41 +11:00
Lea Anthony
5ece7e84b3 Release 0.11.0 2019-03-10 17:03:55 +11:00
Lea Anthony
eaba857676 Add frontend build back to serve 2019-03-10 17:02:57 +11:00
Lea Anthony
db489a3cae Remove banner from application cli 2019-03-10 17:02:36 +11:00
Lea Anthony
4821ab8597 Automate version bumps 2019-03-10 17:02:12 +11:00
Lea Anthony
670b769f82 version bump 2019-03-09 05:18:23 +11:00
Lea Anthony
eb53399824 add wails bridge assets 2019-03-08 20:39:09 +11:00
Lea Anthony
24e4fbfb68 ignore frontend files when using wails serve 2019-03-08 20:38:55 +11:00
Lea Anthony
7f54ca4ac3 version bump 2019-03-07 21:30:30 +11:00
Lea Anthony
b224803e4d fix vue basic template 2019-03-07 21:29:55 +11:00
Lea Anthony
28b2025aaa Merge pull request #63 from wailsapp/0.9.9
0.9.9
2019-03-07 08:25:23 +11:00
Lea Anthony
77e85705d1 Version bump 2019-03-07 08:23:38 +11:00
Lea Anthony
9fd24595c7 fix asset imports in vue basic template 2019-03-07 08:23:29 +11:00
Lea Anthony
69067e85f5 Merge pull request #62 from wailsapp/Default-Prompts-not-populating
Default prompts not populating
2019-03-07 05:48:15 +11:00
Lea Anthony
c8db58e00e Version bump 2019-03-07 05:47:13 +11:00
Lea Anthony
e96e0e0999 fix default prompts 2019-03-07 05:46:20 +11:00
Lea Anthony
2da21ec528 Merge pull request #60 from wailsapp/0.9.97
0.9.7
2019-03-06 19:14:46 +11:00
Lea Anthony
cda0b40414 Version bump 2019-03-06 19:12:38 +11:00
Lea Anthony
7f4229dd6b Add issue command 2019-03-06 19:12:12 +11:00
Lea Anthony
68651b77f4 use os specific path seperator 2019-03-06 19:11:46 +11:00
Lea Anthony
bf001f5ad2 Improve prompt handling 2019-03-06 19:11:03 +11:00
Lea Anthony
d1907b4ce5 Update issue templates 2019-03-06 07:59:24 +11:00
Lea Anthony
56363d193d Update issue templates 2019-03-04 22:36:00 +11:00
Lea Anthony
8553f43080 Misc linting fixes and version bump 2019-03-03 11:34:00 +11:00
Lea Anthony
587681bb8d Bump version 2019-03-02 12:56:56 +11:00
Lea Anthony
afbf80ea4a Merge pull request #59 from wailsapp/0.9.5
use mewn for templates
2019-03-02 12:55:36 +11:00
Lea Anthony
c180d7dccb use mewn for templates
massively improve template handling
2019-03-02 12:54:10 +11:00
Lea Anthony
c20aabc8f8 Merge pull request #58 from wailsapp/update-command
initial update command
2019-02-23 10:23:32 +11:00
32 changed files with 499 additions and 472 deletions

30
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,30 @@
---
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.

1
.gitignore vendored
View File

@@ -16,3 +16,4 @@ examples/**/example*
cmd/wails/wails cmd/wails/wails
.DS_Store .DS_Store
tmp tmp
dist

26
.goreleaser.yml Normal file
View File

@@ -0,0 +1,26 @@
# 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 MIT License
Copyright (c) 2018-Present Lea Anthony Copyright (c) 2018 wailsapp
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

View File

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

View File

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

31
cmd/cmd-mewn.go Normal file

File diff suppressed because one or more lines are too long

View File

@@ -41,6 +41,14 @@ 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 {

View File

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

View File

@@ -17,6 +17,7 @@ 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
} }
@@ -99,6 +100,7 @@ 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()

View File

@@ -150,6 +150,7 @@ 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")

View File

@@ -106,15 +106,6 @@ 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]

View File

@@ -4,9 +4,12 @@ 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 {
@@ -47,15 +50,11 @@ 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 {
fs := NewFSHelper() // exists := ph.templates.TemplateExists(projectOptions.Template)
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)
@@ -63,6 +62,8 @@ 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)
} }
@@ -114,15 +115,14 @@ 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(),
templateNameMap: make(map[string]string), Author: &author{},
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
templateNameMap map[string]string // Converts template prompt text to template name selectedTemplate *TemplateDetails
} }
// Defaults sets the default project template // Defaults sets the default project template
func (po *ProjectOptions) Defaults() { func (po *ProjectOptions) Defaults() {
po.Template = "basic" po.Template = "vuebasic"
} }
// PromptForInputs asks the user to input project details // PromptForInputs asks the user to input project details
@@ -170,48 +170,31 @@ func (po *ProjectOptions) PromptForInputs() error {
return err return err
} }
templateDetails, err := po.templates.GetTemplateDetails() // Process Templates
if err != nil { templateList := slicer.Interface()
return err 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))
} }
templates := []string{} templateIndex := 0
// Add a Custom Template
// templates = append(templates, "Custom - Choose your own CSS framework") if len(options.AsSlice()) > 1 {
for templateName, templateDetails := range templateDetails { templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
templateText := templateName
// Check if metadata json exists
if templateDetails.Metadata != nil {
shortdescription := templateDetails.Metadata["shortdescription"]
if shortdescription != "" {
templateText += " - " + shortdescription.(string)
}
}
templates = append(templates, templateText)
po.templateNameMap[templateText] = templateName
} }
if po.Template != "" { // After selection do this....
if _, ok := templateDetails[po.Template]; !ok { po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
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
if po.templateNameMap[po.Template] != "" { po.Template = strings.Split(po.selectedTemplate.Path, string(os.PathSeparator))[0]
po.Template = po.templateNameMap[po.Template]
}
// Populate template details // // Populate template details
templateMetadata := templateDetails[po.Template].Metadata templateMetadata := po.selectedTemplate.Metadata
err = processTemplateMetadata(templateMetadata, po) err = processTemplateMetadata(templateMetadata, po)
if err != nil { if err != nil {
@@ -299,36 +282,36 @@ func processBinaryName(po *ProjectOptions) {
fmt.Println("Output binary Name: " + po.BinaryName) fmt.Println("Output binary Name: " + po.BinaryName)
} }
func processTemplateMetadata(templateMetadata map[string]interface{}, po *ProjectOptions) error { func processTemplateMetadata(templateMetadata *TemplateMetadata, po *ProjectOptions) error {
if templateMetadata["frontenddir"] != nil { if templateMetadata.FrontendDir != "" {
po.FrontEnd = &frontend{} po.FrontEnd = &frontend{}
po.FrontEnd.Dir = templateMetadata["frontenddir"].(string) po.FrontEnd.Dir = templateMetadata.FrontendDir
} }
if templateMetadata["install"] != nil { if templateMetadata.Install != "" {
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"].(string) po.FrontEnd.Install = templateMetadata.Install
} }
if templateMetadata["build"] != nil { if templateMetadata.Build != "" {
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"].(string) po.FrontEnd.Build = templateMetadata.Build
} }
if templateMetadata["bridge"] != nil { if templateMetadata.Bridge != "" {
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"].(string) po.FrontEnd.Bridge = templateMetadata.Bridge
} }
if templateMetadata["serve"] != nil { if templateMetadata.Serve != "" {
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"].(string) po.FrontEnd.Serve = templateMetadata.Serve
} }
return nil return nil
} }

View File

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

View File

@@ -3,112 +3,95 @@ package cmd
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "log"
"io/ioutil"
"os"
"path"
"path/filepath" "path/filepath"
"runtime" "regexp"
"strings" "strings"
"text/template" "text/template"
mewn "github.com/leaanthony/mewn"
mewnlib "github.com/leaanthony/mewn/lib"
"github.com/leaanthony/slicer"
) )
const templateSuffix = ".template" // TemplateMetadata holds all the metadata for a Wails template
type TemplateMetadata struct {
// TemplateHelper helps with creating projects Name string `json:"name"`
type TemplateHelper struct { ShortDescription string `json:"shortdescription"`
system *SystemHelper Description string `json:"description"`
fs *FSHelper Install string `json:"install"`
templateDir string Build string `json:"build"`
// templates map[string]string Author string `json:"author"`
templateSuffix string Created string `json:"created"`
metadataFilename string FrontendDir string `json:"frontenddir"`
Serve string `json:"serve"`
Bridge string `json:"bridge"`
} }
// Template defines a single 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 { type Template struct {
Name string Name string
Dir string Path string
Metadata map[string]interface{} Description string
}
// TemplateHelper is a utility object to help with processing templates
type TemplateHelper struct {
TemplateList *TemplateList
Files *mewnlib.FileGroup
} }
// NewTemplateHelper creates a new template helper // NewTemplateHelper creates a new template helper
func NewTemplateHelper() *TemplateHelper { func NewTemplateHelper() *TemplateHelper {
result := TemplateHelper{ files := mewn.Group("./templates")
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 return &TemplateHelper{
func (t *TemplateHelper) GetTemplateNames() (map[string]string, error) { TemplateList: NewTemplateList(files),
templateDirs, err := t.fs.GetSubdirs(t.templateDir) Files: files,
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
@@ -116,161 +99,55 @@ func (t *TemplateHelper) TemplateExists(templateName string) (bool, error) {
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error { func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error {
// Get template files // Get template files
template, err := t.getTemplateFiles(projectOptions.Template) templatePath := projectOptions.selectedTemplate.Path
if err != nil {
return err
}
// Copy files to target templateFilenames := slicer.String()
err = template.Install(projectPath, projectOptions) templateFilenames.AddSlice(projectOptions.templates.Files.Entries())
if err != nil {
return err
}
return nil templateJSONFilename := filepath.Join(templatePath, "template.json")
}
// templateFiles categorises files found in a template templateFiles := templateFilenames.Filter(func(filename string) bool {
type templateFiles struct { return strings.HasPrefix(filename, templatePath) && filename != templateJSONFilename
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 var err error
for _, filename := range t.StandardFiles { templateFiles.Each(func(templateFile string) {
sourceFile = filepath.Join(t.BaseDir, filename)
targetFile = filepath.Join(projectPath, filename)
err = fs.CopyFile(sourceFile, targetFile) // Setup filenames
relativeFilename := strings.TrimPrefix(templateFile, templatePath)[1:]
targetFilename, err := filepath.Abs(filepath.Join(projectOptions.OutputDirectory, relativeFilename))
if err != nil { if err != nil {
return err return
} }
} filedata := projectOptions.templates.Files.Bytes(templateFile)
// Do we have template files? // If file is a template, process it
if len(t.Templates) > 0 { if strings.HasSuffix(templateFile, ".template") {
templateData := projectOptions.templates.Files.String(templateFile)
// Iterate over the templates tmpl := template.New(templateFile)
var templateFile string tmpl.Parse(templateData)
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 var tpl bytes.Buffer
err = tmpl.Execute(&tpl, projectOptions) err = tmpl.Execute(&tpl, projectOptions)
if err != nil { if err != nil {
fmt.Println("ERROR!!! " + err.Error()) return
return err
} }
// Save buffer to disk // Remove template suffix
targetFilename := strings.TrimSuffix(filename, templateSuffix) targetFilename = strings.TrimSuffix(targetFilename, ".template")
targetFile = filepath.Join(projectPath, targetFilename)
err = ioutil.WriteFile(targetFile, tpl.Bytes(), 0644) // Set the filedata to the template result
if err != nil { filedata = tpl.Bytes()
return err
}
} }
// Normal file, just copy it
err = fs.CreateFile(targetFilename, filedata)
if err != nil {
return
}
})
if err != nil {
return err
} }
return nil return nil

View File

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

View File

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

View File

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

View File

@@ -1,20 +0,0 @@
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
})
}

View File

@@ -1,49 +0,0 @@
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). 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)

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"os"
"github.com/leaanthony/spinner" "github.com/leaanthony/spinner"
"github.com/wailsapp/wails/cmd" "github.com/wailsapp/wails/cmd"
@@ -24,19 +25,53 @@ func init() {
logger.PrintSmallBanner(message) logger.PrintSmallBanner(message)
fmt.Println() fmt.Println()
// Check Mewn is installed
err := cmd.CheckMewn()
if err != nil {
return err
}
// Project options // Project options
projectOptions := &cmd.ProjectOptions{} projectOptions := &cmd.ProjectOptions{}
// Check we are in project directory // Check we are in project directory
// Check project.json loads correctly // Check project.json loads correctly
fs := cmd.NewFSHelper() fs := cmd.NewFSHelper()
err := projectOptions.LoadConfig(fs.Cwd()) err = projectOptions.LoadConfig(fs.Cwd())
if err != nil { if err != nil {
return err return err
} }
// Check Mewn is installed // Validate config
err = cmd.CheckMewn() // 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)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -1,11 +1,10 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil"
"net/http" "net/http"
"strings" "io/ioutil"
"encoding/json"
"github.com/leaanthony/spinner" "github.com/leaanthony/spinner"
"github.com/wailsapp/wails/cmd" "github.com/wailsapp/wails/cmd"
@@ -55,24 +54,13 @@ 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", "-a", "github.com/wailsapp/wails/cmd/wails"}) err = cmd.NewProgramHelper().RunCommandArray([]string{"go","get","-u","github.com/wailsapp/wails/cmd/wails"})
if err != nil { if err != nil {
updateSpinner.Error(err.Error()) updateSpinner.Error(err.Error())
return err return err
} }
version, _, err := cmd.NewProgramHelper().GetOutputFromCommand("wails version") updateSpinner.Success()
version = strings.TrimSpace(version) logger.Yellow("Wails updated to " + latestVersion)
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!")
} }

74
cmd/wails/9_issue.go Normal file
View File

@@ -0,0 +1,74 @@
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,17 +8,20 @@ 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.1 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/leaanthony/slicer v1.0.0 github.com/leaanthony/mewn v0.10.2
github.com/leaanthony/slicer v1.3.1
github.com/leaanthony/spinner v0.5.0 github.com/leaanthony/spinner v0.5.0
github.com/mattn/go-colorable v0.1.1 // indirect 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/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-20190222235706-ffb98f73852f // indirect golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd // indirect golang.org/x/net v0.0.0-20190310014029-b774fd8d5c0f // indirect
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e // indirect golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa // indirect
) )

28
go.sum
View File

@@ -19,10 +19,12 @@ 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.1 h1:+qmAnR5nETU/00o5wvYJ7w9Y36R9uIBRB9I15E9Ru8A= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/leaanthony/mewn v0.9.1/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/leaanthony/slicer v1.0.0 h1:BV2CySexcZ20qyHp5qBTxQhsazR6e8MBTF1EHmGu1xw= github.com/leaanthony/mewn v0.10.2 h1:Kzu1NqHHXriuMyGiHDMLk4aTzydZ3qbvz/qmoquGkvQ=
github.com/leaanthony/slicer v1.0.0/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ= 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/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=
@@ -35,14 +37,17 @@ 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-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-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/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,17 +65,18 @@ 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-20190222235706-ffb98f73852f h1:qWFY9ZxP3tfI37wYIs/MnIAqK0vlXp1xnYEa5HxFSSY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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-20190310014029-b774fd8d5c0f h1:CxcNDReoTQBlkHuyVUepQrMJTSa7q1+j65kVRv6jK3c=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190310014029-b774fd8d5c0f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb h1:pf3XwC90UUdNPYWZdFjhGBE7DUFuK3Ct1zWmZ65QN30= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb h1:pf3XwC90UUdNPYWZdFjhGBE7DUFuK3Ct1zWmZ65QN30=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-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-20190310054646-10058d7d4faa h1:lqti/xP+yD/6zH5TqEwx2MilNIJY5Vbc6Qr8J3qyPIQ=
golang.org/x/sys v0.0.0-20190222171317-cd391775e71e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

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

8
scripts/updateversion.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/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>', '<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: 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)}}", ".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 // eslint-disable-next-line
console.log( console.log(
"%c wails bridge %c " + message + " ", "%c wails bridge %c " + message + " ",
@@ -102,7 +102,7 @@ function startBridge() {
// Bridge external.invoke // Bridge external.invoke
window.external = { window.external = {
invoke: function(msg) { invoke: function (msg) {
window.wailsbridge.websocket.send(msg); window.wailsbridge.websocket.send(msg);
} }
}; };
@@ -142,11 +142,11 @@ function startBridge() {
// Try to connect to the backend every 300ms (default value). // Try to connect to the backend every 300ms (default value).
// Change this value in the main wailsbridge object. // Change this value in the main wailsbridge object.
function connect() { function connect() {
window.wailsbridge.connectTimer = setInterval(function() { window.wailsbridge.connectTimer = setInterval(function () {
if (window.wailsbridge.websocket == null) { if (window.wailsbridge.websocket == null) {
window.wailsbridge.websocket = new WebSocket(window.wailsbridge.wsURL); window.wailsbridge.websocket = new WebSocket(window.wailsbridge.wsURL);
window.wailsbridge.websocket.onopen = handleConnect; window.wailsbridge.websocket.onopen = handleConnect;
window.wailsbridge.websocket.onerror = function(e) { window.wailsbridge.websocket.onerror = function (e) {
e.stopImmediatePropagation(); e.stopImmediatePropagation();
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
@@ -159,7 +159,6 @@ function startBridge() {
function handleMessage(message) { function handleMessage(message) {
// As a bridge we ignore js and css injections // As a bridge we ignore js and css injections
switch (message.data[0]) { switch (message.data[0]) {
// Wails library - inject! // Wails library - inject!
case "w": case "w":
@@ -167,7 +166,7 @@ function startBridge() {
// Now wails runtime is loaded, wails for the ready event // Now wails runtime is loaded, wails for the ready event
// and callback to the main app // 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"); window.wailsbridge.log("Wails Ready");
if (window.wailsbridge.callback) { if (window.wailsbridge.callback) {
window.wailsbridge.log("Notifying application"); window.wailsbridge.log("Notifying application");
@@ -189,7 +188,6 @@ function startBridge() {
// Call back // Call back
case "c": case "c":
var callbackData = message.data.slice(1); var callbackData = message.data.slice(1);
window.wailsbridge.log("Callback = " + callbackData);
window.wails._.callback(callbackData); window.wails._.callback(callbackData);
break; break;
} }
@@ -205,7 +203,7 @@ function startBridge() {
export default { export default {
// The main function // The main function
// Passes the main Wails object to the callback if given. // Passes the main Wails object to the callback if given.
Start: function(callback) { Start: function (callback) {
// Save the callback // Save the callback
window.wailsbridge.callback = callback; window.wailsbridge.callback = callback;

View File

@@ -1 +1 @@
(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");})(); !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")}();

View File

@@ -10,7 +10,7 @@
function cryptoRandom() { function cryptoRandom() {
var array = new Uint32Array(1); var array = new Uint32Array(1);
return window.crypto.getRandomValues(array)[0]; return window.crypto.getRandomValues(array)[0];
} }
// LOLRandom // LOLRandom
@@ -203,6 +203,10 @@
// Called by the backend to return data to a previously called // Called by the backend to return data to a previously called
// binding invocation // binding invocation
function callback(incomingMessage) { 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 // Parse the message
var message; var message;
try { try {
@@ -243,7 +247,7 @@
// notify informs frontend listeners that an event was emitted with the given data // notify informs frontend listeners that an event was emitted with the given data
function notify(eventName, data) { function notify(eventName, data) {
if (eventListeners[eventName]) { if (eventListeners[eventName]) {
eventListeners[eventName].forEach(function(element) { eventListeners[eventName].forEach(function (element) {
var parsedData = []; var parsedData = [];
// Parse data if we have it // Parse data if we have it
if (data) { if (data) {
@@ -332,7 +336,7 @@
callbacks: callbacks, callbacks: callbacks,
injectCSS: injectCSS, injectCSS: injectCSS,
addScript: addScript, addScript: addScript,
} }
/************************************************************/ /************************************************************/