Compare commits

...

79 Commits

Author SHA1 Message Date
Lea Anthony 2d29b626c7 chore: version bump 2019-06-26 19:50:22 +10:00
Lea Anthony 698145be1e Merge pull request #140 from wailsapp/139-go.mod-should-reflect-current-wails-version
feat: set wails version in go.mod
2019-06-26 19:48:35 +10:00
Lea Anthony a9188cbfdd feat: set wails version in go.mod 2019-06-26 19:46:51 +10:00
Lea Anthony d07cca0278 chore: version bump 2019-06-25 18:49:18 +10:00
Lea Anthony 60d1dc51ad Merge pull request #137 from wailsapp/135-Add-Debian-support
135 add debian support
2019-06-25 18:48:24 +10:00
Lea Anthony 105073e412 fix: add Debian support across tooling 2019-06-25 18:32:25 +10:00
Lea Anthony 9d1f1fff47 feat: debian support 2019-06-25 18:29:57 +10:00
Lea Anthony 08050ec35e Merge pull request #134 from wailsapp/133-Unsupported-Platform-Requests
133 unsupported platform requests
2019-06-25 08:18:06 +10:00
Lea Anthony bd9751d888 feat: Support distribution support requests 2019-06-25 08:13:20 +10:00
Lea Anthony 7d171b0907 feat: initial support for platform requests 2019-06-24 09:11:06 +10:00
Lea Anthony 5b8f311465 Merge pull request #130 from wailsapp/123-Unify-Runtime-APIs
fix: linting
2019-06-22 08:47:25 +10:00
Lea Anthony 801465ac51 fix: linting 2019-06-22 08:45:46 +10:00
Lea Anthony a84e2ae9b3 Merge pull request #129 from wailsapp/123-Unify-Runtime-APIs
feat: unify runtime API signatures
2019-06-22 08:43:23 +10:00
Lea Anthony 9496d1d47f Merge pull request #126 from bh90210/121-react-template-build-error
fix(react template): reverting bugfix + code clean-up
2019-06-22 08:39:16 +10:00
Lea Anthony 36e575e0a2 feat: unify runtime API signatures 2019-06-22 08:36:11 +10:00
ktc 70ccb8942b fix(react template): reverting bugfix + code clean-up 2019-06-19 20:09:23 +03:00
Lea Anthony d3cd3d43bd chore: version bump 2019-06-19 21:04:27 +10:00
Lea Anthony 9116f0d06c Merge pull request #124 from wailsapp/116-Add-browser-methods-to-runtime
116 add browser methods to runtime
2019-06-19 21:01:53 +10:00
Lea Anthony 2c91e26add docs: guardrails badge 2019-06-19 21:01:00 +10:00
Lea Anthony f1647443dc chore: add .jshintrc file to indicate es6 2019-06-19 20:54:36 +10:00
Lea Anthony b6b6ce2d4a fix: linting fix 2019-06-19 20:53:04 +10:00
Lea Anthony abcc869537 feat: added OpenFile 2019-06-19 20:49:39 +10:00
Lea Anthony 3e02e1676a Merge pull request #122 from bh90210/121-react-template-build-error
fix(react template): build bugfix
2019-06-19 08:31:57 +10:00
Lea Anthony 5c8a4de446 fix: version 2019-06-19 08:29:15 +10:00
Lea Anthony 7cabef946e feat: initial support for browser.openURL for f/e 2019-06-19 08:28:31 +10:00
ktc f2519e5af2 fix(react template): build bugfix 2019-06-18 13:57:45 +03:00
Lea Anthony 5b002e88b7 feat: v0.16.0 release 2019-06-18 08:18:49 +10:00
Lea Anthony 3723e70e6f Merge pull request #117 from bh90210/master
react template
2019-06-16 17:31:02 +10:00
admin_3.exe 7c08ddbb07 Merge branch 'develop' into master 2019-06-16 10:20:36 +03:00
Lea Anthony c8027f5b81 feat: react template 2019-06-16 17:13:40 +10:00
ktc 393e418e68 react template 2019-06-15 14:52:47 +03:00
Lea Anthony dcc3e5fa79 Merge pull request #113 from wailsapp/112-deprecate-backend-injection-of-css-js
112 deprecate backend injection of css js
2019-05-30 08:46:21 +10:00
Lea Anthony f4e6c407ba chore: remove old JS/CSS api 2019-05-30 08:43:26 +10:00
Lea Anthony e718a56ed9 docs: updated contributors 2019-05-27 18:43:33 +10:00
Lea Anthony 068443f3fd Merge pull request #110 from ocelotsloth/develop
CMD: LINUX: Arch Linux detection without lsb-release
2019-05-27 18:41:26 +10:00
Mark Stenglein 1efc8cb934 CMD: LINUX: Arch Linux detection without lsb-release
The existing distribution detection does not work on Arch Linux
without the `lsb-release` package installed. This patch adds
detection using `/etc/os-release` in the same way that f9a1881
uses for Fedora and CentOS detection.

I changed the if statement that Bryn Sinclair used to a case
statement to avoid extra if-else-if statements.

I also needed to add a trim statement to remove the `"` characters
that are present in Arch Linux's `/etc/os-release` file.
2019-05-26 20:30:05 -04:00
Lea Anthony 1ce0620620 Merge pull request #107 from wailsapp/develop
Release v0.15.0
2019-05-26 14:03:47 +10:00
Lea Anthony 249a35f90f chore: release v0.15.0 2019-05-26 13:56:27 +10:00
Lea Anthony d003de3270 chore: remove old package-lock.json 2019-05-26 13:46:51 +10:00
Lea Anthony 9cb2ed10b5 Update CONTRIBUTORS.md 2019-05-26 13:32:55 +10:00
Lea Anthony 4a376f1b67 fix: windows spinner 2019-05-25 12:22:20 +10:00
Lea Anthony c540f3902c fix: polyfill for windows 2019-05-25 12:19:03 +10:00
Lea Anthony accc04ef90 chore: version bump 2019-05-25 11:30:01 +10:00
Lea Anthony d54bd3dc54 Merge pull request #106 from wailsapp/105-create-vuetify-template
Create vuetify template
2019-05-25 11:20:37 +10:00
Lea Anthony a54bbb4e14 chore: linting fixes 2019-05-25 11:17:39 +10:00
Lea Anthony 6b1b999546 feat: add vuetify template 2019-05-25 11:13:34 +10:00
Lea Anthony a5aeafc4bc chore: version bump 2019-05-25 09:28:21 +10:00
Lea Anthony 39ea5cc456 Update bug_report.md 2019-05-24 08:17:05 +10:00
Lea Anthony a225b8d50a Update bug_report.md 2019-05-24 08:13:56 +10:00
Lea Anthony e0036b1cbb Update bug_report.md 2019-05-24 08:11:18 +10:00
Lea Anthony 9a5833f7c9 Merge pull request #102 from wailsapp/98-use-snap-command
fix: use snap command for linux
2019-05-23 08:58:00 +10:00
Lea Anthony 06a1372e80 fix: use snap command for linux 2019-05-23 08:57:11 +10:00
Lea Anthony 7a16cf74f0 docs: mandate go 1.12 2019-05-22 19:25:09 +10:00
Lea Anthony 4239c89b76 Merge pull request #100 from wailsapp/99-update-issue-template
fix: align with new bug template
2019-05-22 19:14:46 +10:00
Lea Anthony 29ea5cc74d fix: slign with new bug template 2019-05-22 19:13:17 +10:00
Lea Anthony fa27be083d Update bug_report.md 2019-05-22 19:09:50 +10:00
Lea Anthony 9be56c47e4 chore: reset version 2019-05-22 08:35:38 +10:00
Lea Anthony 249720b0cc chore: version bump 2019-05-22 08:30:24 +10:00
Lea Anthony 3553cb6694 Merge pull request #97 from wailsapp/92-build-on-first-init
92 build on first init
2019-05-22 07:27:19 +10:00
Lea Anthony 3c0fa4c55e chore: lint fixes 2019-05-22 07:25:42 +10:00
Lea Anthony c07a4b6c16 Merge branch 'develop' into 92-build-on-first-init 2019-05-22 00:56:30 +10:00
Lea Anthony 8175eb4446 chore: version bump 2019-05-22 00:50:28 +10:00
Lea Anthony eeab418c90 fix: version issue 2019-05-22 00:43:56 +10:00
Lea Anthony 0eb59d823e fix: version craziness 2019-05-22 00:42:17 +10:00
Lea Anthony f07705268d feat: moar spinners 2019-05-20 23:53:14 +10:00
Lea Anthony 63fef39854 feat: build on init 2019-05-20 23:40:17 +10:00
Lea Anthony 3ea45da2c8 chore: version bump v0.14.5-pre 2019-05-20 20:47:35 +10:00
Lea Anthony eb0d9f3ba4 Merge pull request #96 from wailsapp/91-create-developer-tooling
91 create developer tooling
2019-05-20 18:58:43 +10:00
Lea Anthony 8432f725a9 chore: updated go mod files 2019-05-20 18:45:01 +10:00
Lea Anthony 7015b80888 feat: new template generator 2019-05-20 18:44:14 +10:00
Lea Anthony ddcc103f37 Update README.md 2019-05-19 13:56:58 +10:00
Lea Anthony 1ac16d1933 fix: minor fixes 2019-05-18 07:34:39 +10:00
Lea Anthony 0f36a88f0e feat: add Manjaro support 2019-05-18 07:18:34 +10:00
Lea Anthony b30031d025 feat: multiple template support 2019-05-18 07:15:15 +10:00
Lea Anthony b849964562 docs: fix awesomego link 2019-05-12 22:18:19 +10:00
Lea Anthony cd152f0cd7 Merge branch 'master' into v0.14.0-pre 2019-05-12 15:15:11 +10:00
Lea Anthony 12280b51b9 chore: version bump 2019-05-12 15:12:10 +10:00
Lea Anthony 29256c5766 fix: update check 2019-05-12 15:11:40 +10:00
Lea Anthony 8b13c0b197 chore: update version 2019-05-12 15:02:50 +10:00
73 changed files with 1658 additions and 11416 deletions
+6 -1
View File
@@ -7,6 +7,11 @@ assignees: ''
---
#####################################################
If you have a technical issue, please do not open a bug this way!
Please use the `wails issue` command!
#####################################################
**Description**
A clear and concise description of what the bug is.
@@ -24,7 +29,7 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**System Details**
Please paste the output of `wails report` here.
Please provide your platform, GO version and variables, etc
**Additional context**
Add any other context about the problem here.
+3
View File
@@ -0,0 +1,3 @@
{
"esversion": 6
}
+24 -2
View File
@@ -5,14 +5,36 @@
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"name": "Wails Init",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/wails/main.go",
"env": {},
"cwd": "/tmp",
"args": [
"setup"
"init",
"-name",
"runtime",
"-dir",
"runtime",
"-output",
"runtime",
"-template",
"vuebasic"
]
},
{
"name": "Wails Update Pre",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/wails/main.go",
"env": {},
"cwd": "/tmp",
"args": [
"update",
"-pre"
]
}
]
+24 -15
View File
@@ -1,19 +1,28 @@
2019-06-18 **v0.16.0**
* React template FTW! - Thanks [admin_3.exe](https://github.com/bh90210)!
* Updated contributors
* Arch Linux detection without lsb-release
* Removed deprecated methods for dealing with JS/CSS in the backend
<a name="v0.13.0"></a>
## [v0.13.0] - 2019-05-12
2019-05-29 **v0.14.11-pre**
* Windows fix for spinner
### Feat
- revamped 'update' system
- no need for explicit GO111MODULE=on
2019-05-29 **v0.14.10-pre**
* Windows fix for Vuetify
### Fix
- documentation typo fixes
- windows init project
- windows 10 colour
- leave windows assets on -p flag
- show prerequisite errors
2019-05-29 **v0.14.9-pre**
* Vuetify project template 🎉
### Docs
- updated contributors
- added awesomego logo
- added Redhat distro
2019-05-29 **v0.14.8-pre**
* Updated Ubuntu npm install command
2019-05-22 **v0.14.7-pre**
* New projects are built automatically when initialised
* Go 1.12 is now a minimum requirement
2019-05-21 **v0.14.6-pre**
* Hotfix for module dependency issue
2019-05-20 **v0.14.5-pre**
* Added developer tooling - New Template Generator
* Documentation fixes - Thanks [admin_3.exe](https://github.com/bh90210)!
+4 -2
View File
@@ -8,5 +8,7 @@ Wails is what it is because of the time and effort given by these great people.
* [Adrian Lanzafame](https://github.com/lanzafame)
* [0xflotus](https://github.com/0xflotus)
* [Michael D Henderson](https://github.com/mdhender)
* [fred2104] (https://github.com/fishfishfish2104)
* [intelwalk] (https://github.com/intelwalk)
* [fred2104](https://github.com/fishfishfish2104)
* [intelwalk](https://github.com/intelwalk)
* [Mark Stenglein](https://github.com/ocelotsloth)
* [admin_3.exe](https://github.com/bh90210)
+8 -4
View File
@@ -9,7 +9,8 @@
<a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a>
<a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
<a href="https://github.com/sindresorhus/awesome" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>-
<a href="https://github.com/avelino/awesome-go" rel="nofollow"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome"></a>
<a href="https://dashboard.guardrails.io/default/gh/wailsapp/wails"><img src="https://badges.guardrails.io/wailsapp/wails.svg?token=53657bc22ec360d7673c894fdd70568e918ec581d10d84427ed4de5fe1eeff1a"></a>
</p>
The traditional method of providing web interfaces to Go programs is via a built-in web server. Wails offers a different approach: it provides the ability to wrap both Go code and a web frontend into a single binary. Tools are provided to make this easy for you by handling project creation, compilation and bundling. All you have to do is get creative!
@@ -18,6 +19,7 @@ The traditional method of providing web interfaces to Go programs is via a built
- Use standard Go libraries/frameworks for the backend
- Use any frontend technology to build your UI
- Quickly create Vue, Vuetify or React frontends for your Go programs
- Expose Go methods/functions to the frontend via a single bind command
- Uses native rendering engines - no embedded browser
- Shared events system
@@ -33,7 +35,7 @@ Wails is currently in Beta. Please make sure you read the [Project Status](https
Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are:
- Go 1.11 or above
- Go 1.12
- npm
### MacOS
@@ -44,7 +46,7 @@ Make sure you have the xcode command line tools installed. This can be done by r
### Linux
#### Ubuntu 18.04
#### Ubuntu 18.04, Debian 9
`sudo apt install pkg-config build-essential libgtk-3-dev libwebkit2gtk-4.0-dev`
@@ -64,6 +66,8 @@ Windows requires gcc and related tooling. The recommended download is from [http
## Installation
**Ensure Go modules are enabled: GO111MODULE=on and go/bin is in your PATH variable.**
Installation is as simple as running the following command:
<pre style='color:white'>
@@ -95,7 +99,7 @@ Without the following people, this project would never have existed:
* [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot) - His support and feedback has been immense. More patience than you can throw a stick at (Not long now Dustin!).
* [Serge Zaitsev](https://github.com/zserge) - Creator of [Webview](https://github.com/zserge/webview) which Wails uses for the windowing.
And without [these people](CONTRIBUTORS.md), it wouldn't be what it is today.
And without [these people](CONTRIBUTORS.md), it wouldn't be what it is today. A huge thank you to each and every one of you!
Special Mentions:
-23
View File
@@ -22,11 +22,6 @@ type App struct {
bindingManager *bindingManager // Handles binding of Go code to renderer
eventManager *eventManager // Handles all the events
runtime *Runtime // The runtime object for registered structs
// This is a list of all the JS/CSS that needs injecting
// It will get injected in order
jsCache []string
cssCache []string
}
// CreateApp creates the application window with the given configuration
@@ -111,12 +106,6 @@ func (a *App) start() error {
return err
}
// Inject CSS
a.renderer.AddCSSList(a.cssCache)
// Inject JS
a.renderer.AddJSList(a.jsCache)
// Run the renderer
return a.renderer.Run()
}
@@ -126,15 +115,3 @@ func (a *App) start() error {
func (a *App) Bind(object interface{}) {
a.bindingManager.bind(object)
}
// AddJS adds a piece of Javascript to a cache that
// gets injected at runtime
func (a *App) AddJS(js string) {
a.jsCache = append(a.jsCache, js)
}
// AddCSS adds a CSS string to a cache that
// gets injected at runtime
func (a *App) AddCSS(js string) {
a.cssCache = append(a.cssCache, js)
}
+65
View File
@@ -0,0 +1,65 @@
package wails
import "strings"
import "fmt"
type internalMethods struct{
log *CustomLogger
browser *RuntimeBrowser
}
func newInternalMethods() *internalMethods {
return &internalMethods{
log: newCustomLogger("InternalCall"),
browser: newRuntimeBrowser(),
}
}
func (i *internalMethods) processCall(callData *callData) (interface{}, error) {
if !strings.HasPrefix(callData.BindingName, ".wails.") {
return nil, fmt.Errorf("Invalid call signature '%s'", callData.BindingName)
}
// Strip prefix
var splitCall = strings.Split(callData.BindingName,".")[2:]
if len(splitCall) != 2 {
return nil, fmt.Errorf("Invalid call signature '%s'", callData.BindingName)
}
group := splitCall[0]
switch group {
case "Browser":
return i.processBrowserCommand(splitCall[1], callData.Data)
default:
return nil, fmt.Errorf("Unknown internal command group '%s'", group)
}
}
func (i *internalMethods) processBrowserCommand(command string, data interface{}) (interface{}, error) {
switch command {
case "OpenURL":
url := data.(string)
// Strip string quotes. Credit: https://stackoverflow.com/a/44222648
if url[0] == '"' {
url = url[1:]
}
if i := len(url)-1; url[i] == '"' {
url = url[:i]
}
i.log.Debugf("Calling Browser.OpenURL with '%s'", url)
return nil, i.browser.OpenURL(url)
case "OpenFile":
filename := data.(string)
// Strip string quotes. Credit: https://stackoverflow.com/a/44222648
if filename[0] == '"' {
filename = filename[1:]
}
if i := len(filename)-1; filename[i] == '"' {
filename = filename[:i]
}
i.log.Debugf("Calling Browser.OpenFile with '%s'", filename)
return nil, i.browser.OpenFile(filename)
default:
return nil, fmt.Errorf("Unknown Browser command '%s'", command)
}
}
+12 -3
View File
@@ -17,6 +17,7 @@ binding:
type bindingManager struct {
methods map[string]*boundMethod
functions map[string]*boundFunction
internalMethods *internalMethods
initMethods []*boundMethod
log *CustomLogger
renderer Renderer
@@ -27,9 +28,10 @@ type bindingManager struct {
func newBindingManager() *bindingManager {
result := &bindingManager{
methods: make(map[string]*boundMethod),
functions: make(map[string]*boundFunction),
log: newCustomLogger("Bind"),
methods: make(map[string]*boundMethod),
functions: make(map[string]*boundFunction),
log: newCustomLogger("Bind"),
internalMethods: newInternalMethods(),
}
return result
}
@@ -163,6 +165,11 @@ func (b *bindingManager) bind(object interface{}) {
b.objectsToBind = append(b.objectsToBind, object)
}
func (b *bindingManager) processInternalCall(callData *callData) (interface{}, error) {
// Strip prefix
return b.internalMethods.processCall(callData)
}
func (b *bindingManager) processFunctionCall(callData *callData) (interface{}, error) {
// Return values
var result []reflect.Value
@@ -254,6 +261,8 @@ func (b *bindingManager) processCall(callData *callData) (result interface{}, er
result, err = b.processFunctionCall(callData)
case 2:
result, err = b.processMethodCall(callData)
case 3:
result, err = b.processInternalCall(callData)
default:
result = nil
err = fmt.Errorf("Invalid binding name '%s'", callData.BindingName)
+15
View File
@@ -96,6 +96,7 @@ type Command struct {
flagCount int
log *Logger
helpFlag bool
hidden bool
}
// NewCommand creates a new Command
@@ -106,6 +107,7 @@ func NewCommand(name string, description string, app *Cli, parentCommandPath str
SubCommandsMap: make(map[string]*Command),
App: app,
log: NewLogger(),
hidden: false,
}
// Set up command path
@@ -212,6 +214,9 @@ func (c *Command) PrintHelp() {
c.log.White("Available commands:")
fmt.Println("")
for _, subcommand := range c.SubCommands {
if subcommand.isHidden() {
continue
}
spacer := strings.Repeat(" ", 3+c.longestSubcommand-len(subcommand.Name))
isDefault := ""
if subcommand.isDefaultCommand() {
@@ -237,6 +242,16 @@ func (c *Command) isDefaultCommand() bool {
return c.App.defaultCommand == c
}
// isHidden returns true if the command is a hidden command
func (c *Command) isHidden() bool {
return c.hidden
}
// Hidden hides the command from the Help system
func (c *Command) Hidden() {
c.hidden = true
}
// Command - Defines a subcommand
func (c *Command) Command(name, description string) *Command {
result := NewCommand(name, description, c.App, c.CommandPath)
+2 -23
View File
File diff suppressed because one or more lines are too long
+72 -4
View File
@@ -1,13 +1,19 @@
package cmd
import (
"bytes"
"crypto/md5"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"runtime"
"github.com/leaanthony/slicer"
)
// FSHelper - Wrapper struct for File System utility commands
@@ -104,11 +110,33 @@ func (fs *FSHelper) RemoveFiles(files []string) error {
return nil
}
// Dir holds information about a directory
type Dir struct {
localPath string
fullPath string
}
// Directory creates a new Dir struct with the given directory path
func (fs *FSHelper) Directory(dir string) (*Dir, error) {
fullPath, err := filepath.Abs(dir)
return &Dir{fullPath: fullPath}, err
}
// LocalDir creates a new Dir struct based on a path relative to the caller
func (fs *FSHelper) LocalDir(dir string) (*Dir, error) {
_, filename, _, _ := runtime.Caller(1)
fullPath, err := filepath.Abs(filepath.Join(path.Dir(filename), dir))
return &Dir{
localPath: dir,
fullPath: fullPath,
}, err
}
// GetSubdirs will return a list of FQPs to subdirectories in the given directory
func (fs *FSHelper) GetSubdirs(dir string) (map[string]string, error) {
func (d *Dir) GetSubdirs() (map[string]string, error) {
// Read in the directory information
fileInfo, err := ioutil.ReadDir(dir)
fileInfo, err := ioutil.ReadDir(d.fullPath)
if err != nil {
return nil, err
}
@@ -120,25 +148,65 @@ func (fs *FSHelper) GetSubdirs(dir string) (map[string]string, error) {
// map["directoryName"] = "path/to/directoryName"
for _, file := range fileInfo {
if file.IsDir() {
subdirs[file.Name()] = filepath.Join(dir, file.Name())
subdirs[file.Name()] = filepath.Join(d.fullPath, file.Name())
}
}
return subdirs, nil
}
// GetAllFilenames returns all filename in and below this directory
func (d *Dir) GetAllFilenames() (*slicer.StringSlicer, error) {
result := slicer.String()
err := filepath.Walk(d.fullPath, func(dir string, info os.FileInfo, err error) error {
if dir == d.fullPath {
return nil
}
if err != nil {
return err
}
// Don't copy template metadata
result.Add(dir)
return nil
})
return result, err
}
// MkDir creates the given directory.
// Returns error on failure
func (fs *FSHelper) MkDir(dir string) error {
return os.Mkdir(dir, 0700)
}
// SaveAsJSON saves the JSON representation of the given data to the given filename
func (fs *FSHelper) SaveAsJSON(data interface{}, filename string) error {
var buf bytes.Buffer
e := json.NewEncoder(&buf)
e.SetEscapeHTML(false)
e.SetIndent("", " ")
e.Encode(data)
err := ioutil.WriteFile(filename, buf.Bytes(), 0755)
if err != nil {
return err
}
return nil
}
// LoadAsString will attempt to load the given file and return
// its contents as a string
func (fs *FSHelper) LoadAsString(filename string) (string, error) {
bytes, err := ioutil.ReadFile(filename)
bytes, err := fs.LoadAsBytes(filename)
return string(bytes), err
}
// LoadAsBytes returns the contents of the file as a byte slice
func (fs *FSHelper) LoadAsBytes(filename string) ([]byte, error) {
return ioutil.ReadFile(filename)
}
// FileMD5 returns the md5sum of the given file
func (fs *FSHelper) FileMD5(filename string) (string, error) {
f, err := os.Open(filename)
+88 -11
View File
@@ -3,9 +3,12 @@ package cmd
import (
"fmt"
"io/ioutil"
"net/url"
"os"
"regexp"
"runtime"
"strings"
"github.com/pkg/browser"
)
// LinuxDistribution is of type int
@@ -20,6 +23,8 @@ const (
Arch
// RedHat linux distribution
RedHat
// Debian distribution
Debian
)
// DistroInfo contains all the information relating to a linux distribution
@@ -29,6 +34,7 @@ type DistroInfo struct {
Release string
Codename string
DistributorID string
DiscoveredBy string
}
// GetLinuxDistroInfo returns information about the running linux distribution
@@ -43,7 +49,7 @@ func GetLinuxDistroInfo() *DistroInfo {
if err != nil {
return result
}
result.DiscoveredBy = "lsb"
for _, line := range strings.Split(stdout, "\n") {
if strings.Contains(line, ":") {
// Iterate lines a
@@ -56,8 +62,10 @@ func GetLinuxDistroInfo() *DistroInfo {
switch value {
case "Ubuntu":
result.Distribution = Ubuntu
case "Arch":
case "Arch", "ManjaroLinux":
result.Distribution = Arch
case "Debian":
result.Distribution = Debian
}
case "Description":
result.Description = value
@@ -65,22 +73,49 @@ func GetLinuxDistroInfo() *DistroInfo {
result.Release = value
case "Codename":
result.Codename = value
}
}
}
// check if /etc/os-release exists
} else if _, err := os.Stat("/etc/os-release"); !os.IsNotExist(err) {
// Default value
osName := "Unknown"
version := ""
// read /etc/os-release
osRelease, _ := ioutil.ReadFile("/etc/os-release")
// compile a regex to find NAME=distro
re := regexp.MustCompile(`^NAME=(.*)\n`)
// extract the distro name
osName := string(re.FindSubmatch(osRelease)[1])
// Check distro name against list of RedHat distros
if osName == "Fedora" || osName == "CentOS" {
//if it matches set result.Distribution to RedHat
// Split into lines
lines := strings.Split(string(osRelease), "\n")
// Iterate lines
for _, line := range lines {
// Split each line by the equals char
splitLine := strings.SplitN(line, "=", 2)
// Check we have
if len(splitLine) != 2 {
continue
}
switch splitLine[0] {
case "NAME":
osName = strings.Trim(splitLine[1], "\"")
case "VERSION_ID":
version = strings.Trim(splitLine[1], "\"")
}
}
// Check distro name against list of distros
result.Release = version
result.DiscoveredBy = "os-release"
switch osName {
case "Fedora":
result.Distribution = RedHat
case "CentOS":
result.Distribution = RedHat
case "Arch Linux":
result.Distribution = Arch
case "Debian GNU/Linux":
result.Distribution = Debian
default:
result.Distribution = Unknown
result.DistributorID = osName
}
}
return result
@@ -118,3 +153,45 @@ func RpmInstalled(packageName string) (bool, error) {
_, _, exitCode, _ := rpm.Run("--query", packageName)
return exitCode == 0, nil
}
// RequestSupportForDistribution promts the user to submit a request to support their
// currently unsupported distribution
func RequestSupportForDistribution(distroInfo *DistroInfo, libraryName string) error {
var logger = NewLogger()
defaultError := fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, libraryName)
logger.Yellow("Distribution '%s' is not currently supported, but we would love to!", distroInfo.DistributorID)
q := fmt.Sprintf("Would you like to submit a request to support distribution '%s'?", distroInfo.DistributorID)
result := Prompt(q, "yes")
if strings.ToLower(result) != "yes" {
return defaultError
}
title := fmt.Sprintf("Support Distribution '%s'", distroInfo.DistributorID)
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", 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))
str.WriteString(fmt.Sprintf("| Distribution ID | %s |\n", distroInfo.DistributorID))
str.WriteString(fmt.Sprintf("| Distribution Version | %s |\n", distroInfo.Release))
str.WriteString(fmt.Sprintf("| Discovered by | %s |\n", distroInfo.DiscoveredBy))
body := fmt.Sprintf("**Description**\nDistribution '%s' is curently unsupported.\n\n**Further Information**\n\n%s\n\n*Please add any extra information here, EG: libraries that are needed to make the distribution work, or commands to install them*", distroInfo.DistributorID, str.String())
fullURL := "https://github.com/wailsapp/wails/issues/new?"
params := "title=" + title + "&body=" + body
fmt.Println("Opening browser to file request.")
browser.OpenURL(fullURL + url.PathEscape(params))
return nil
}
+2 -3
View File
@@ -49,11 +49,10 @@ func getRequiredProgramsLinux() *Prerequisites {
result := &Prerequisites{}
distroInfo := GetLinuxDistroInfo()
switch distroInfo.Distribution {
case Ubuntu:
case Ubuntu, Debian:
result.Add(newPrerequisite("gcc", "Please install with `sudo apt install build-essentials` and try again"))
result.Add(newPrerequisite("pkg-config", "Please install with `sudo apt install pkg-config` and try again"))
result.Add(newPrerequisite("npm", "Please install with `sudo apt install npm` and try again"))
result.Add(newPrerequisite("npm", "Please install with `sudo snap install node --channel=12/stable --classic` and try again"))
default:
result.Add(newPrerequisite("gcc", "Please install with your system package manager and try again"))
result.Add(newPrerequisite("pkg-config", "Please install with your system package manager and try again"))
+34 -17
View File
@@ -50,12 +50,6 @@ 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)
// if !exists {
// return fmt.Errorf("template '%s' is invalid", projectOptions.Template)
// }
// Calculate project path
projectPath, err := filepath.Abs(projectOptions.OutputDirectory)
if err != nil {
@@ -90,8 +84,6 @@ func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
// ph.GenerateWindowsResourceConfig(projectOptions)
// }
ph.log.Yellow("Project '%s' generated in directory '%s'!", projectOptions.Name, projectOptions.OutputDirectory)
ph.log.Yellow("To compile the project, run 'wails build' in the project directory.")
return nil
}
@@ -151,11 +143,13 @@ type ProjectOptions struct {
log *Logger
templates *TemplateHelper
selectedTemplate *TemplateDetails
WailsVersion string
}
// Defaults sets the default project template
func (po *ProjectOptions) Defaults() {
po.Template = "vuebasic"
po.WailsVersion = Version
}
// PromptForInputs asks the user to input project details
@@ -173,19 +167,43 @@ func (po *ProjectOptions) PromptForInputs() error {
// 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 po.Template != "" {
// Check template is valid if given
if templateDetails[po.Template] == nil {
keys := make([]string, 0, len(templateDetails))
for k := range templateDetails {
keys = append(keys, k)
}
return fmt.Errorf("invalid template name '%s'. Valid options: %s", po.Template, strings.Join(keys, ", "))
}
po.selectedTemplate = templateDetails[po.Template]
} else {
if len(options.AsSlice()) > 1 {
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
for _, templateDetail := range templateDetails {
templateList.Add(templateDetail)
options.Add(fmt.Sprintf("%s - %s", templateDetail.Metadata.Name, templateDetail.Metadata.ShortDescription))
}
templateIndex := 0
if len(options.AsSlice()) > 1 {
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
}
if len(templateList.AsSlice()) == 0 {
return fmt.Errorf("aborting: no templates found")
}
// After selection do this....
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
}
// After selection do this....
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
fmt.Println("Template: " + po.selectedTemplate.Metadata.Name)
// Setup NPM Project name
po.NPMProjectName = strings.ToLower(strings.Replace(po.Name, " ", "_", -1))
@@ -266,7 +284,6 @@ func processProjectName(po *ProjectOptions) {
po.Name = Prompt("The name of the project", "My Project")
}
fmt.Println("Project Name: " + po.Name)
}
func processBinaryName(po *ProjectOptions) {
+13 -3
View File
@@ -68,6 +68,17 @@ func (s *SystemHelper) ConfigFileIsValid() bool {
return err == nil
}
// GetAuthor returns a formatted string of the user's name and email
func (s *SystemHelper) GetAuthor() (string, error) {
var config *SystemConfig
config, err := s.LoadConfig()
if err != nil {
return "", err
}
return fmt.Sprintf("%s <%s>", config.Name, config.Email), nil
}
// BackupConfig attempts to backup the system config file
func (s *SystemHelper) BackupConfig() (string, error) {
now := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
@@ -261,7 +272,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
distroInfo := GetLinuxDistroInfo()
for _, library := range *requiredLibraries {
switch distroInfo.Distribution {
case Ubuntu:
case Ubuntu, Debian:
installed, err := DpkgInstalled(library.Name)
if err != nil {
return false, err
@@ -284,7 +295,6 @@ func CheckDependencies(logger *Logger) (bool, error) {
logger.Green("Library '%s' installed.", library.Name)
}
case RedHat:
installed, err := RpmInstalled(library.Name)
if err != nil {
return false, err
@@ -296,7 +306,7 @@ func CheckDependencies(logger *Logger) (bool, error) {
logger.Green("Library '%s' installed.", library.Name)
}
default:
return false, fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, library.Name)
return false, RequestSupportForDistribution(distroInfo, library.Name)
}
}
}
+119 -58
View File
@@ -3,20 +3,21 @@ package cmd
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"path/filepath"
"regexp"
"strings"
"text/template"
mewn "github.com/leaanthony/mewn"
mewnlib "github.com/leaanthony/mewn/lib"
"github.com/kennygrant/sanitize"
"github.com/leaanthony/slicer"
)
// TemplateMetadata holds all the metadata for a Wails template
type TemplateMetadata struct {
Name string `json:"name"`
Version string `json:"version"`
ShortDescription string `json:"shortdescription"`
Description string `json:"description"`
Install string `json:"install"`
@@ -26,92 +27,149 @@ type TemplateMetadata struct {
FrontendDir string `json:"frontenddir"`
Serve string `json:"serve"`
Bridge string `json:"bridge"`
WailsDir string `json:"wailsdir"`
}
// TemplateDetails holds information about a specific template
type TemplateDetails struct {
BasePath string
Name 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, "/")[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
fs *FSHelper
}
// TemplateHelper is a utility object to help with processing templates
type TemplateHelper struct {
TemplateList *TemplateList
Files *mewnlib.FileGroup
templateDir *Dir
fs *FSHelper
metadataFilename string
}
// NewTemplateHelper creates a new template helper
func NewTemplateHelper() *TemplateHelper {
files := mewn.Group("./templates")
templateDir, err := fs.LocalDir("./templates")
if err != nil {
log.Fatal("Unable to find the template directory. Please reinstall Wails.")
}
return &TemplateHelper{
TemplateList: NewTemplateList(files),
Files: files,
templateDir: templateDir,
metadataFilename: "template.json",
}
}
// IsValidTemplate returns true if the given tempalte name resides on disk
func (t *TemplateHelper) IsValidTemplate(templateName string) bool {
pathToTemplate := filepath.Join(t.templateDir.fullPath, templateName)
return t.fs.DirExists(pathToTemplate)
}
// SanitizeFilename sanitizes the given string to make a valid filename
func (t *TemplateHelper) SanitizeFilename(name string) string {
return sanitize.Name(name)
}
// CreateNewTemplate creates a new template based on the given directory name and string
func (t *TemplateHelper) CreateNewTemplate(dirname string, details *TemplateMetadata) (string, error) {
// Check if this template has already been created
if t.IsValidTemplate(dirname) {
return "", fmt.Errorf("cannot create template in directory '%s' - already exists", dirname)
}
targetDir := filepath.Join(t.templateDir.fullPath, dirname)
err := t.fs.MkDir(targetDir)
if err != nil {
return "", err
}
targetMetadata := filepath.Join(targetDir, t.metadataFilename)
err = t.fs.SaveAsJSON(details, targetMetadata)
return targetDir, err
}
// LoadMetadata loads the template's 'metadata.json' file
func (t *TemplateHelper) LoadMetadata(dir string) (*TemplateMetadata, error) {
templateFile := filepath.Join(dir, t.metadataFilename)
result := &TemplateMetadata{}
if !t.fs.FileExists(templateFile) {
return nil, nil
}
rawJSON, err := ioutil.ReadFile(templateFile)
if err != nil {
return nil, err
}
err = json.Unmarshal(rawJSON, &result)
return result, err
}
// GetTemplateDetails returns a map of Template structs containing details
// of the found templates
func (t *TemplateHelper) GetTemplateDetails() (map[string]*TemplateDetails, error) {
// Get the subdirectory details
templateDirs, err := t.templateDir.GetSubdirs()
if err != nil {
return nil, err
}
result := make(map[string]*TemplateDetails)
for name, dir := range templateDirs {
result[name] = &TemplateDetails{
Path: dir,
}
_ = &TemplateMetadata{}
metadata, err := t.LoadMetadata(dir)
if err != nil {
return nil, err
}
result[name].Metadata = metadata
if metadata.Name != "" {
result[name].Name = metadata.Name
} else {
// Ignore bad templates?
result[name] = nil
}
}
return result, nil
}
// GetTemplateFilenames returns all the filenames of the given template
func (t *TemplateHelper) GetTemplateFilenames(template *TemplateDetails) (*slicer.StringSlicer, error) {
// Get the subdirectory details
templateDir, err := t.fs.Directory(template.Path)
if err != nil {
return nil, err
}
return templateDir.GetAllFilenames()
}
// InstallTemplate installs the template given in the project options to the
// project path given
func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *ProjectOptions) error {
// Get template files
templateFilenames, err := t.GetTemplateFilenames(projectOptions.selectedTemplate)
if err != nil {
return err
}
templatePath := projectOptions.selectedTemplate.Path
templateFilenames := slicer.String()
templateFilenames.AddSlice(projectOptions.templates.Files.Entries())
// Save the version
projectOptions.WailsVersion = Version
templateJSONFilename := filepath.Join(templatePath, "template.json")
templateJSONFilename := filepath.Join(templatePath, t.metadataFilename)
templateFiles := templateFilenames.Filter(func(filename string) bool {
filename = filepath.FromSlash(filename)
return strings.HasPrefix(filename, templatePath) && filename != templateJSONFilename
})
var err error
templateFiles.Each(func(templateFile string) {
// Setup filenames
@@ -120,11 +178,14 @@ func (t *TemplateHelper) InstallTemplate(projectPath string, projectOptions *Pro
if err != nil {
return
}
filedata := projectOptions.templates.Files.Bytes(templateFile)
filedata, err := t.fs.LoadAsBytes(templateFile)
if err != nil {
return
}
// If file is a template, process it
if strings.HasSuffix(templateFile, ".template") {
templateData := projectOptions.templates.Files.String(templateFile)
templateData := string(filedata)
tmpl := template.New(templateFile)
tmpl.Parse(templateData)
var tpl bytes.Buffer
+3
View File
@@ -0,0 +1,3 @@
{
"esversion": 6
}
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
@@ -0,0 +1,68 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.<br>
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.<br>
You will also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.<br>
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.<br>
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.<br>
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
### Analyzing the Bundle Size
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
### Making a Progressive Web App
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
### Advanced Configuration
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
### Deployment
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
### `npm run build` fails to minify
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify

Some files were not shown because too many files have changed in this diff Show More