mirror of
https://github.com/taigrr/wails.git
synced 2026-04-04 06:02:43 -07:00
Compare commits
321 Commits
runtime-re
...
bugfix/syn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddcaf58a90 | ||
|
|
f851b89350 | ||
|
|
7f72189231 | ||
|
|
ef79dd95cf | ||
|
|
d49b146eaa | ||
|
|
8c051e004d | ||
|
|
c02b9ac032 | ||
|
|
35f839ae65 | ||
|
|
8a6c44963d | ||
|
|
d31c5522e9 | ||
|
|
6e5b2ce871 | ||
|
|
c2c9c331cd | ||
|
|
9d5280d4d6 | ||
|
|
0474f15c05 | ||
|
|
ba0af0c16d | ||
|
|
c9f1247284 | ||
|
|
baa661532d | ||
|
|
43a5f410d9 | ||
|
|
0ab6a93e0c | ||
|
|
485df87560 | ||
|
|
176c447e87 | ||
|
|
aa9cb5e58e | ||
|
|
9a7be38462 | ||
|
|
678c2194db | ||
|
|
9f9c9e27de | ||
|
|
01a1288364 | ||
|
|
5cd34e07b9 | ||
|
|
2290f36939 | ||
|
|
670986df5b | ||
|
|
086cd02cd4 | ||
|
|
d8c8dd57fa | ||
|
|
2d158d449a | ||
|
|
04577c242b | ||
|
|
ac0d4493d3 | ||
|
|
b123156331 | ||
|
|
23468ce7c7 | ||
|
|
7b6bb5e259 | ||
|
|
77bd34d601 | ||
|
|
d750077a90 | ||
|
|
71df64087b | ||
|
|
5565f8ba94 | ||
|
|
3bc91f20c5 | ||
|
|
0a15cbaa1d | ||
|
|
c650671265 | ||
|
|
7106c338df | ||
|
|
be2cef4a63 | ||
|
|
ee93f3c1e6 | ||
|
|
b9ffe53732 | ||
|
|
bbc16fe03a | ||
|
|
bdfc3ca631 | ||
|
|
490d66cf77 | ||
|
|
bce686d779 | ||
|
|
c0b0ef0200 | ||
|
|
8e869baed7 | ||
|
|
7522428d5c | ||
|
|
bc570999e8 | ||
|
|
393a4fceb2 | ||
|
|
da20bcc8d2 | ||
|
|
b091baa16f | ||
|
|
ecaaafa9d9 | ||
|
|
0009da9585 | ||
|
|
6235e83677 | ||
|
|
9f93e7d979 | ||
|
|
949bc40317 | ||
|
|
81777f29d8 | ||
|
|
5d35dd3105 | ||
|
|
ad034d3950 | ||
|
|
98337df92d | ||
|
|
9cc417cf04 | ||
|
|
030b954971 | ||
|
|
7a3ab27977 | ||
|
|
0e6265a9d7 | ||
|
|
b003a080b0 | ||
|
|
376ba743f4 | ||
|
|
aa8ffff68d | ||
|
|
613a44af5e | ||
|
|
2e15c4e045 | ||
|
|
421c13805d | ||
|
|
cc204ab1f7 | ||
|
|
a94a1a9fcb | ||
|
|
e860bd06ec | ||
|
|
6da02e6b44 | ||
|
|
7cd78df1cd | ||
|
|
bcecd854bc | ||
|
|
6339f230f9 | ||
|
|
131fd973cd | ||
|
|
f1d16a03ec | ||
|
|
cc99dcce80 | ||
|
|
a8ecc1e872 | ||
|
|
6fc419ab48 | ||
|
|
400bb37c03 | ||
|
|
10fc7d762b | ||
|
|
61b9e50b8e | ||
|
|
47916216de | ||
|
|
a2b066decb | ||
|
|
8d1238289f | ||
|
|
b232b608fa | ||
|
|
3b034ceadb | ||
|
|
75be8f698a | ||
|
|
a78acbb247 | ||
|
|
6e29d1b087 | ||
|
|
8171b644ca | ||
|
|
a691ef0580 | ||
|
|
151b4bff06 | ||
|
|
fb093c58d2 | ||
|
|
b68c69f4eb | ||
|
|
8405ce37f9 | ||
|
|
76edc7976e | ||
|
|
2ab8fc37ab | ||
|
|
c66e9cba5a | ||
|
|
b33794c883 | ||
|
|
5d719685d3 | ||
|
|
5b2e5b1d85 | ||
|
|
773bad45f6 | ||
|
|
404cd7d14e | ||
|
|
ea703acfed | ||
|
|
4750ee5d22 | ||
|
|
1bd9408e9e | ||
|
|
34202f1a2f | ||
|
|
9d6d77f768 | ||
|
|
fbff822ea9 | ||
|
|
da28683ddc | ||
|
|
b7f0155c3b | ||
|
|
f220e0e5bd | ||
|
|
b5bad14124 | ||
|
|
0f36ee7030 | ||
|
|
58761ccff4 | ||
|
|
059cbbfd9a | ||
|
|
339b0ecbaf | ||
|
|
615cc55b31 | ||
|
|
577b59aa89 | ||
|
|
45a507673e | ||
|
|
eb8a1f2303 | ||
|
|
566914a9c2 | ||
|
|
0866a633a3 | ||
|
|
0e7981cf87 | ||
|
|
ce3bd8f56f | ||
|
|
a3cc1de0a2 | ||
|
|
8d3c32c630 | ||
|
|
7ae2acac90 | ||
|
|
7d822dfe8d | ||
|
|
c0f5c28e3b | ||
|
|
79188c503f | ||
|
|
bd6745bef0 | ||
|
|
8a14cc9a4c | ||
|
|
8a7c098041 | ||
|
|
030bd629df | ||
|
|
cad65f8f3f | ||
|
|
0c790bb08c | ||
|
|
fa1bc016fe | ||
|
|
5fc41949ae | ||
|
|
3d13368043 | ||
|
|
0bca7b57e0 | ||
|
|
332e9d66ea | ||
|
|
93884a5aeb | ||
|
|
c1fbca834b | ||
|
|
60fe2c0912 | ||
|
|
2e1e8b1513 | ||
|
|
dd49292b68 | ||
|
|
af30e5e6ba | ||
|
|
558cc9681c | ||
|
|
62f6bece57 | ||
|
|
084d412d86 | ||
|
|
788d22740b | ||
|
|
34ef3de737 | ||
|
|
8149cbc3c0 | ||
|
|
2032ef8225 | ||
|
|
38e897f646 | ||
|
|
de2f9a1e9e | ||
|
|
c506c95506 | ||
|
|
955cfbb689 | ||
|
|
aa698b993d | ||
|
|
a6fa5feb0c | ||
|
|
67a52b2a57 | ||
|
|
99d22fdcb7 | ||
|
|
7051ffd425 | ||
|
|
bac823566c | ||
|
|
401ebee719 | ||
|
|
b5b92c4afa | ||
|
|
2c2aee2d30 | ||
|
|
806b1aa8e0 | ||
|
|
416bd7bfc4 | ||
|
|
aca72d3f7a | ||
|
|
ad20e2622b | ||
|
|
94c56115a5 | ||
|
|
daeda501f4 | ||
|
|
fb1e8647bc | ||
|
|
723236f348 | ||
|
|
394a823d82 | ||
|
|
afe57802ad | ||
|
|
914642bd1d | ||
|
|
dafd9bcb24 | ||
|
|
7f75f27f6b | ||
|
|
d77fa1ee74 | ||
|
|
82e00ff83a | ||
|
|
14f91ab109 | ||
|
|
19706a12a4 | ||
|
|
52e6091f0f | ||
|
|
2db1624faf | ||
|
|
f5d3fb0848 | ||
|
|
85a64914aa | ||
|
|
0819207e33 | ||
|
|
50a0bc7701 | ||
|
|
c51f0cad6f | ||
|
|
6795f6c678 | ||
|
|
315ef5f7ea | ||
|
|
24530d9da4 | ||
|
|
d572418ec3 | ||
|
|
8c7480d277 | ||
|
|
96fc70df26 | ||
|
|
1c8d4c902a | ||
|
|
08fc1d53d0 | ||
|
|
6c5d5e40f4 | ||
|
|
3f1dfe931c | ||
|
|
cb850c9653 | ||
|
|
8d8f47363a | ||
|
|
d399b7580d | ||
|
|
1b04b71254 | ||
|
|
0b19ad1427 | ||
|
|
9aca99911e | ||
|
|
a7f61e335e | ||
|
|
9fff0a513e | ||
|
|
f453be12c8 | ||
|
|
20428b0407 | ||
|
|
7fd5b77cbe | ||
|
|
d2cac50f93 | ||
|
|
00f1f82520 | ||
|
|
02fbb14e34 | ||
|
|
f961659ada | ||
|
|
93942111bc | ||
|
|
dc5a68acce | ||
|
|
12ff0f8c97 | ||
|
|
c375c281ee | ||
|
|
7d86b0f7c4 | ||
|
|
990f7dd06c | ||
|
|
0b6f256d55 | ||
|
|
694f80434a | ||
|
|
0a57fa4035 | ||
|
|
099967ae94 | ||
|
|
718bb1b852 | ||
|
|
af1a1a2498 | ||
|
|
cc0617d247 | ||
|
|
99a3f87cef | ||
|
|
1ccdb1bc4e | ||
|
|
62b1967e45 | ||
|
|
c10303e7c0 | ||
|
|
4a61584827 | ||
|
|
cf249ba836 | ||
|
|
08fe7b64d6 | ||
|
|
77939ea414 | ||
|
|
468394d03c | ||
|
|
dc87699a1e | ||
|
|
36e906507d | ||
|
|
a5f9688708 | ||
|
|
880f900e51 | ||
|
|
349306cf73 | ||
|
|
f140697857 | ||
|
|
3d9e9a1342 | ||
|
|
1a82406d2b | ||
|
|
26ff8df7e5 | ||
|
|
54b4b157b3 | ||
|
|
add7e89097 | ||
|
|
b7dae216df | ||
|
|
0b9d093d6c | ||
|
|
7f282ad071 | ||
|
|
d6ed583e07 | ||
|
|
930cab2d9d | ||
|
|
ae41f33dcc | ||
|
|
5af6b7cafe | ||
|
|
68ac3763d0 | ||
|
|
cdc66b556e | ||
|
|
3ff16322c2 | ||
|
|
d60066a0b1 | ||
|
|
9d6ebf0fd4 | ||
|
|
839815e2fb | ||
|
|
846fe479bf | ||
|
|
62f7070e0c | ||
|
|
dd418b36c2 | ||
|
|
f4f04f2199 | ||
|
|
3a7514bbdc | ||
|
|
213f07fed4 | ||
|
|
ed3ed8aa18 | ||
|
|
d038dca37c | ||
|
|
bb86d770a1 | ||
|
|
33daa8621e | ||
|
|
6c124fcff4 | ||
|
|
45833574b3 | ||
|
|
5cb00eb481 | ||
|
|
e2105331c1 | ||
|
|
21d2383e63 | ||
|
|
6c945a4eed | ||
|
|
6c8d34dfd3 | ||
|
|
b9b42c059e | ||
|
|
3f657b34cf | ||
|
|
6e81a36ada | ||
|
|
ddec01a429 | ||
|
|
21fdb3be7d | ||
|
|
c1a13ab6d0 | ||
|
|
750a02efc6 | ||
|
|
5e047debfc | ||
|
|
9cac336708 | ||
|
|
827c2b9a95 | ||
|
|
b36a3c4abb | ||
|
|
0bac205565 | ||
|
|
67a8ad8e12 | ||
|
|
9de2f66f50 | ||
|
|
9370030ff3 | ||
|
|
e38d6e7ef0 | ||
|
|
2f21fc3575 | ||
|
|
63e73f5f64 | ||
|
|
e1adc1ba49 | ||
|
|
030e911ea4 | ||
|
|
d2f114e44e | ||
|
|
700d3f84d3 | ||
|
|
1d49042013 | ||
|
|
8671b1e6cf | ||
|
|
517d6c44ec | ||
|
|
a082a659ea | ||
|
|
083153efc9 | ||
|
|
65a2560153 | ||
|
|
29535c10a3 |
@@ -1 +1 @@
|
|||||||
runtime/js/dist/wails.js
|
runtime/assets/default.html
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true
|
"es6": true,
|
||||||
|
"node": true,
|
||||||
},
|
},
|
||||||
"extends": "eslint:recommended",
|
"extends": "eslint:recommended",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
|
|||||||
19
.github/stale.yml
vendored
Normal file
19
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Number of days of inactivity before an issue becomes stale
|
||||||
|
daysUntilStale: 30
|
||||||
|
# Number of days of inactivity before a stale issue is closed
|
||||||
|
daysUntilClose: 7
|
||||||
|
# Issues with these labels will never be considered stale
|
||||||
|
exemptLabels:
|
||||||
|
- pinned
|
||||||
|
- security
|
||||||
|
- onhold
|
||||||
|
- inprogress
|
||||||
|
# Label to use when marking an issue as stale
|
||||||
|
staleLabel: wontfix
|
||||||
|
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||||
|
markComment: >
|
||||||
|
This issue has been automatically marked as stale because it has not had
|
||||||
|
recent activity. It will be closed if no further activity occurs. Thank you
|
||||||
|
for your contributions.
|
||||||
|
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||||
|
closeComment: false
|
||||||
32
.github/workflows/latest-pre.yml
vendored
Normal file
32
.github/workflows/latest-pre.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: latest pre-release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '**-pre**'
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Test Build Latest Pre-Release
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Set up Go 1.13
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.13
|
||||||
|
id: go
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Get dependencies
|
||||||
|
run: |
|
||||||
|
go get -v -d ./...
|
||||||
|
- name: Build
|
||||||
|
run: go build -v ./cmd/wails
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: ./wails version
|
||||||
32
.github/workflows/pr.yml
vendored
Normal file
32
.github/workflows/pr.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: pr
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Test Build PR
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Set up Go 1.13
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.13
|
||||||
|
id: go
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Get dependencies
|
||||||
|
run: |
|
||||||
|
go get -v -d ./...
|
||||||
|
- name: Build
|
||||||
|
run: go build -v ./cmd/wails
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: ./wails version
|
||||||
34
.github/workflows/release.yml
vendored
Normal file
34
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- '!**pre**'
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Test Build Latest Release
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Set up Go 1.13
|
||||||
|
uses: actions/setup-go@v1
|
||||||
|
with:
|
||||||
|
go-version: 1.13
|
||||||
|
id: go
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Get dependencies
|
||||||
|
run: |
|
||||||
|
go get -v -d ./...
|
||||||
|
- name: Build
|
||||||
|
run: go build -v ./cmd/wails
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: ./wails version
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,4 +16,4 @@ examples/**/example*
|
|||||||
cmd/wails/wails
|
cmd/wails/wails
|
||||||
.DS_Store
|
.DS_Store
|
||||||
tmp
|
tmp
|
||||||
node_modules
|
node_modules/
|
||||||
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@@ -4,6 +4,13 @@
|
|||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Test cmd package",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "test",
|
||||||
|
"program": "${workspaceFolder}/cmd/"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Wails Init",
|
"name": "Wails Init",
|
||||||
"type": "go",
|
"type": "go",
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
|
||||||
|
2019-07-20 **v0.17.6-pre**
|
||||||
|
* Significant refactor of runtime
|
||||||
|
* Removed wailsbridge file - now a unified approach taken
|
||||||
|
* Fixed React on Windows - Thanks [Florian Didran](https://github.com/fdidron)!
|
||||||
|
|
||||||
2019-06-18 **v0.16.0**
|
2019-06-18 **v0.16.0**
|
||||||
* React template FTW! - Thanks [admin_3.exe](https://github.com/bh90210)!
|
* React template FTW! - Thanks [admin_3.exe](https://github.com/bh90210)!
|
||||||
* Updated contributors
|
* Updated contributors
|
||||||
|
|||||||
@@ -2,15 +2,34 @@
|
|||||||
|
|
||||||
Wails is what it is because of the time and effort given by these great people. A huge thank you to each and every one!
|
Wails is what it is because of the time and effort given by these great people. A huge thank you to each and every one!
|
||||||
|
|
||||||
* [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot)
|
* [Dustin Krysak](https://wiki.ubuntu.com/bashfulrobot)
|
||||||
* [Qais Patankar](https://github.com/qaisjp)
|
* [Qais Patankar](https://github.com/qaisjp)
|
||||||
* [Anthony Lee](https://github.com/alee792)
|
* [Anthony Lee](https://github.com/alee792)
|
||||||
* [Adrian Lanzafame](https://github.com/lanzafame)
|
* [Adrian Lanzafame](https://github.com/lanzafame)
|
||||||
* [0xflotus](https://github.com/0xflotus)
|
* [Mattn](https://github.com/mattn)
|
||||||
* [Michael D Henderson](https://github.com/mdhender)
|
* [0xflotus](https://github.com/0xflotus)
|
||||||
* [fred2104](https://github.com/fishfishfish2104)
|
* [Michael D Henderson](https://github.com/mdhender)
|
||||||
* [intelwalk](https://github.com/intelwalk)
|
* [fred2104](https://github.com/fishfishfish2104)
|
||||||
* [Mark Stenglein](https://github.com/ocelotsloth)
|
* [intelwalk](https://github.com/intelwalk)
|
||||||
* [admin_3.exe](https://github.com/bh90210)
|
* [Mark Stenglein](https://github.com/ocelotsloth)
|
||||||
* [iceleo-com](https://github.com/iceleo-com)
|
* [admin_3.exe](https://github.com/bh90210)
|
||||||
* [fallendusk](https://github.com/fallendusk)
|
* [iceleo-com](https://github.com/iceleo-com)
|
||||||
|
* [fallendusk](https://github.com/fallendusk)
|
||||||
|
* [Nikolai Zimmermann](https://github.com/Chronophylos)
|
||||||
|
* [Toyam Cox](https://github.com/Vaelatern)
|
||||||
|
* [Robin Eklind](https://github.com/mewmew)
|
||||||
|
* [Kris Raney](https://github.com/kraney)
|
||||||
|
* [Jack Mordaunt](https://github.com/JackMordaunt)
|
||||||
|
* [Michael Hipp](https://github.com/MichaelHipp)
|
||||||
|
* [Travis McLane](https://github.com/tmclane)
|
||||||
|
* [Reuben Thomas-Davis](https://github.com/Rested)
|
||||||
|
* [Jarek](https://github.com/Jarek-SRT)
|
||||||
|
* [Konez2k](https://github.com/konez2k)
|
||||||
|
* [msms](https://github.com/sayuthisobri)
|
||||||
|
* [dedo1911](https://github.com/dedo1911)
|
||||||
|
* [Florian Didron](https://github.com/fdidron)
|
||||||
|
* [Christopher Murphy](https://github.com/Splode)
|
||||||
|
* [Zámbó, Levente](https://github.com/Lyimmi)
|
||||||
|
* [artem](https://github.com/Unix4ever)
|
||||||
|
* [Tim Kipp](https://github.com/timkippdev)
|
||||||
|
* [Dmitry Gomzyakov](https://github.com/kyoto44)
|
||||||
|
|||||||
63
README.md
63
README.md
@@ -1,5 +1,5 @@
|
|||||||
<p align="center" style="text-align: center">
|
<p align="center" style="text-align: center">
|
||||||
<img src="https://github.com/wailsapp/docs/raw/master/.vuepress/public/media/logo_cropped.png" width="40%"><br/>
|
<img src="logo_cropped.png" width="40%"><br/>
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
A framework for building desktop applications using Go & Web Technologies.<br/><br/>
|
A framework for building desktop applications using Go & Web Technologies.<br/><br/>
|
||||||
@@ -8,13 +8,17 @@
|
|||||||
<a href="http://godoc.org/github.com/wailsapp/wails"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></a>
|
<a href="http://godoc.org/github.com/wailsapp/wails"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></a>
|
||||||
<a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a>
|
<a href="https://www.codefactor.io/repository/github/wailsapp/wails"><img src="https://www.codefactor.io/repository/github/wailsapp/wails/badge" alt="CodeFactor" /></a>
|
||||||
<a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
|
<a href="https://github.com/wailsapp/wails/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
|
||||||
|
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=shield"/></a>
|
||||||
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
|
<a href="https://houndci.com"><img src="https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg"/></a>
|
||||||
<a href="https://github.com/avelino/awesome-go" 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>
|
<a href="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/release/badge.svg?branch=master" alt="Release Pipelines"></a>
|
||||||
|
<a href="https://github.com/wailsapp/wails/workflows/latest-pre/badge.svg?branch=masterr" rel="nofollow"><img src="https://github.com/wailsapp/wails/workflows/latest-pre/badge.svg?branch=master" alt="Pre-Release Pipelines"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
The traditional method of providing web interfaces to Go programs is via a built-in web server. Wails offers a different approach: it provides the ability to wrap both Go code and a web frontend into a single binary. Tools are provided to make this easy for you by handling project creation, compilation and bundling. All you have to do is get creative!
|
The traditional method of providing web interfaces to Go programs is via a built-in web server. Wails offers a different approach: it provides the ability to wrap both Go code and a web frontend into a single binary. Tools are provided to make this easy for you by handling project creation, compilation and bundling. All you have to do is get creative!
|
||||||
|
|
||||||
|
The official docs can be found at [https://wails.app](https://wails.app).
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Use standard Go libraries/frameworks for the backend
|
- Use standard Go libraries/frameworks for the backend
|
||||||
@@ -27,15 +31,12 @@ The traditional method of providing web interfaces to Go programs is via a built
|
|||||||
- Powerful cli tool
|
- Powerful cli tool
|
||||||
- Multiplatform
|
- Multiplatform
|
||||||
|
|
||||||
## Project Status
|
|
||||||
|
|
||||||
Wails is currently in Beta. Please make sure you read the [Project Status](https://wails.app/project_status.html) if you are interested in using this project.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are:
|
Wails uses cgo to bind to the native rendering engines so a number of platform dependent libraries are needed as well as an installation of Go. The basic requirements are:
|
||||||
|
|
||||||
- Go 1.12
|
- Go 1.13
|
||||||
- npm
|
- npm
|
||||||
|
|
||||||
### MacOS
|
### MacOS
|
||||||
@@ -46,19 +47,41 @@ Make sure you have the xcode command line tools installed. This can be done by r
|
|||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
#### Ubuntu 18.04, Debian 9, Zorin 15
|
#### Debian/Ubuntu
|
||||||
|
|
||||||
`sudo apt install pkg-config build-essential libgtk-3-dev libwebkit2gtk-4.0-dev`
|
`sudo apt install libgtk-3-dev libwebkit2gtk-4.0-dev`
|
||||||
|
|
||||||
#### Arch Linux
|
_Debian: 8, 9, 10_
|
||||||
|
|
||||||
|
_Ubuntu: 16.04, 18.04, 19.04_
|
||||||
|
|
||||||
|
_Also succesfully tested on: Zorin 15, Parrot 4.7, Linuxmint 19, Elementary 5, Kali, Neon_, Pop!_OS
|
||||||
|
|
||||||
|
#### Arch Linux / ArchLabs / Ctlos Linux
|
||||||
|
|
||||||
`sudo pacman -S webkit2gtk gtk3`
|
`sudo pacman -S webkit2gtk gtk3`
|
||||||
|
|
||||||
#### Red Hat Based Distros
|
_Also succesfully test on: Manjaro & ArcoLinux_
|
||||||
|
|
||||||
`sudo yum install webkit2gtk-devel gtk3-devel`
|
#### Centos
|
||||||
|
|
||||||
Note: If you have successfully installed these dependencies on a different flavour of Linux, please consider submitting a PR.
|
`sudo yum install webkitgtk3-devel gtk3-devel`
|
||||||
|
|
||||||
|
_CentOS 6, 7_
|
||||||
|
|
||||||
|
#### Fedora
|
||||||
|
|
||||||
|
`sudo yum install webkit2gtk3-devel gtk3-devel`
|
||||||
|
|
||||||
|
_Fedora 29, 30_
|
||||||
|
|
||||||
|
#### VoidLinux & VoidLinux-musl
|
||||||
|
|
||||||
|
`xbps-install gtk+3-devel webkit2gtk-devel`
|
||||||
|
|
||||||
|
#### Gentoo
|
||||||
|
|
||||||
|
`sudo emerge gtk+:3 webkit-gtk`
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
@@ -71,7 +94,7 @@ Windows requires gcc and related tooling. The recommended download is from [http
|
|||||||
Installation is as simple as running the following command:
|
Installation is as simple as running the following command:
|
||||||
|
|
||||||
<pre style='color:white'>
|
<pre style='color:white'>
|
||||||
go get github.com/wailsapp/wails/cmd/wails
|
go get -u github.com/wailsapp/wails/cmd/wails
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
@@ -103,8 +126,7 @@ And without [these people](CONTRIBUTORS.md), it wouldn't be what it is today. A
|
|||||||
|
|
||||||
Special Mentions:
|
Special Mentions:
|
||||||
|
|
||||||
* [Bill Kennedy](https://twitter.com/goinggodotnet) - Go guru, encourager and all-round nice guy, whose infectious energy and inspiration powered me on when I had none left.
|
* [Byron](https://github.com/bh90210) - At times, Byron has single handedly kept this project alive. Without his incredible input, we never would have got to v1.
|
||||||
* [Mark Bates](https://github.com/markbates) - Creator of [Packr](https://github.com/gobuffalo/packr), inspiration for packing strategies which fed into some of the tooling.
|
|
||||||
|
|
||||||
This project was mainly coded to the following albums:
|
This project was mainly coded to the following albums:
|
||||||
|
|
||||||
@@ -122,3 +144,14 @@ This project was mainly coded to the following albums:
|
|||||||
* [Maxthor - Another World](https://open.spotify.com/album/3tklE2Fgw1hCIUstIwPBJF)
|
* [Maxthor - Another World](https://open.spotify.com/album/3tklE2Fgw1hCIUstIwPBJF)
|
||||||
* [Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v)
|
* [Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v)
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_large)
|
||||||
|
|
||||||
|
## Special Thank You
|
||||||
|
|
||||||
|
<p align="center" style="text-align: center">
|
||||||
|
A special thank you to JetBrains for donating licenses to us!<br/><br/>
|
||||||
|
Please click the logo to let them know your appreciation!<br/><br/>
|
||||||
|
<a href="https://www.jetbrains.com?from=Wails"><img src="jetbrains-grayscale.png" width="30%"></a>
|
||||||
|
</p>
|
||||||
|
|||||||
92
app.go
92
app.go
@@ -1,14 +1,19 @@
|
|||||||
package wails
|
package wails
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/syossan27/tebata"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
"github.com/wailsapp/wails/lib/logger"
|
|
||||||
"github.com/wailsapp/wails/runtime/go/runtime"
|
|
||||||
"github.com/wailsapp/wails/lib/renderer"
|
|
||||||
"github.com/wailsapp/wails/lib/binding"
|
"github.com/wailsapp/wails/lib/binding"
|
||||||
"github.com/wailsapp/wails/lib/ipc"
|
|
||||||
"github.com/wailsapp/wails/lib/event"
|
"github.com/wailsapp/wails/lib/event"
|
||||||
"github.com/wailsapp/wails/lib/interfaces"
|
"github.com/wailsapp/wails/lib/interfaces"
|
||||||
|
"github.com/wailsapp/wails/lib/ipc"
|
||||||
|
"github.com/wailsapp/wails/lib/logger"
|
||||||
|
"github.com/wailsapp/wails/lib/renderer"
|
||||||
|
wailsruntime "github.com/wailsapp/wails/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// -------------------------------- Compile time Flags ------------------------------
|
// -------------------------------- Compile time Flags ------------------------------
|
||||||
@@ -16,19 +21,29 @@ import (
|
|||||||
// BuildMode indicates what mode we are in
|
// BuildMode indicates what mode we are in
|
||||||
var BuildMode = cmd.BuildModeProd
|
var BuildMode = cmd.BuildModeProd
|
||||||
|
|
||||||
|
// Runtime is the Go Runtime struct
|
||||||
|
type Runtime = wailsruntime.Runtime
|
||||||
|
|
||||||
|
// Store is a state store used for syncing with
|
||||||
|
// the front end
|
||||||
|
type Store = wailsruntime.Store
|
||||||
|
|
||||||
|
// CustomLogger is a specialised logger
|
||||||
|
type CustomLogger = logger.CustomLogger
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// App defines the main application struct
|
// App defines the main application struct
|
||||||
type App struct {
|
type App struct {
|
||||||
config *AppConfig // The Application configuration object
|
config *AppConfig // The Application configuration object
|
||||||
cli *cmd.Cli // In debug mode, we have a cli
|
cli *cmd.Cli // In debug mode, we have a cli
|
||||||
renderer interfaces.Renderer // The renderer is what we will render the app to
|
renderer interfaces.Renderer // The renderer is what we will render the app to
|
||||||
logLevel string // The log level of the app
|
logLevel string // The log level of the app
|
||||||
ipc interfaces.IPCManager // Handles the IPC calls
|
ipc interfaces.IPCManager // Handles the IPC calls
|
||||||
log *logger.CustomLogger // Logger
|
log *logger.CustomLogger // Logger
|
||||||
bindingManager interfaces.BindingManager // Handles binding of Go code to renderer
|
bindingManager interfaces.BindingManager // Handles binding of Go code to renderer
|
||||||
eventManager interfaces.EventManager // Handles all the events
|
eventManager interfaces.EventManager // Handles all the events
|
||||||
runtime interfaces.Runtime // The runtime object for registered structs
|
runtime interfaces.Runtime // The runtime object for registered structs
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateApp creates the application window with the given configuration
|
// CreateApp creates the application window with the given configuration
|
||||||
@@ -40,7 +55,7 @@ func CreateApp(optionalConfig ...*AppConfig) *App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result := &App{
|
result := &App{
|
||||||
logLevel: "info",
|
logLevel: "debug",
|
||||||
renderer: renderer.NewWebView(),
|
renderer: renderer.NewWebView(),
|
||||||
ipc: ipc.NewManager(),
|
ipc: ipc.NewManager(),
|
||||||
bindingManager: binding.NewManager(),
|
bindingManager: binding.NewManager(),
|
||||||
@@ -62,11 +77,15 @@ func CreateApp(optionalConfig ...*AppConfig) *App {
|
|||||||
result.config.DisableInspector = true
|
result.config.DisableInspector = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Platform specific init
|
||||||
|
platformInit()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the app
|
// Run the app
|
||||||
func (a *App) Run() error {
|
func (a *App) Run() error {
|
||||||
|
|
||||||
if BuildMode != cmd.BuildModeProd {
|
if BuildMode != cmd.BuildModeProd {
|
||||||
return a.cli.Run()
|
return a.cli.Run()
|
||||||
}
|
}
|
||||||
@@ -87,9 +106,9 @@ func (a *App) start() error {
|
|||||||
// Log starup
|
// Log starup
|
||||||
a.log.Info("Starting")
|
a.log.Info("Starting")
|
||||||
|
|
||||||
// Check if we are to run in headless mode
|
// Check if we are to run in bridge mode
|
||||||
if BuildMode == cmd.BuildModeBridge {
|
if BuildMode == cmd.BuildModeBridge {
|
||||||
a.renderer = &renderer.Headless{}
|
a.renderer = renderer.NewBridge()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise the renderer
|
// Initialise the renderer
|
||||||
@@ -98,6 +117,18 @@ func (a *App) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable console for Windows debug builds
|
||||||
|
if runtime.GOOS == "windows" && BuildMode == cmd.BuildModeDebug {
|
||||||
|
a.renderer.EnableConsole()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start signal handler
|
||||||
|
t := tebata.New(os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL)
|
||||||
|
t.Reserve(func() {
|
||||||
|
a.log.Debug("SIGNAL CAUGHT! Starting Shutdown")
|
||||||
|
a.renderer.Close()
|
||||||
|
})
|
||||||
|
|
||||||
// Start event manager and give it our renderer
|
// Start event manager and give it our renderer
|
||||||
a.eventManager.Start(a.renderer)
|
a.eventManager.Start(a.renderer)
|
||||||
|
|
||||||
@@ -105,7 +136,7 @@ func (a *App) start() error {
|
|||||||
a.ipc.Start(a.eventManager, a.bindingManager)
|
a.ipc.Start(a.eventManager, a.bindingManager)
|
||||||
|
|
||||||
// Create the runtime
|
// Create the runtime
|
||||||
a.runtime = runtime.NewRuntime(a.eventManager, a.renderer)
|
a.runtime = wailsruntime.NewRuntime(a.eventManager, a.renderer)
|
||||||
|
|
||||||
// Start binding manager and give it our renderer
|
// Start binding manager and give it our renderer
|
||||||
err = a.bindingManager.Start(a.renderer, a.runtime)
|
err = a.bindingManager.Start(a.renderer, a.runtime)
|
||||||
@@ -113,8 +144,33 @@ func (a *App) start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defer the shutdown
|
||||||
|
defer a.shutdown()
|
||||||
|
|
||||||
// Run the renderer
|
// Run the renderer
|
||||||
return a.renderer.Run()
|
err = a.renderer.Run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// shutdown the app
|
||||||
|
func (a *App) shutdown() {
|
||||||
|
// Make sure this is only called once
|
||||||
|
a.log.Debug("Shutting down")
|
||||||
|
|
||||||
|
// Shutdown Binding Manager
|
||||||
|
a.bindingManager.Shutdown()
|
||||||
|
|
||||||
|
// Shutdown IPC Manager
|
||||||
|
a.ipc.Shutdown()
|
||||||
|
|
||||||
|
// Shutdown Event Manager
|
||||||
|
a.eventManager.Shutdown()
|
||||||
|
|
||||||
|
a.log.Debug("Cleanly Shutdown")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind allows the user to bind the given object
|
// Bind allows the user to bind the given object
|
||||||
|
|||||||
7
app_other.go
Normal file
7
app_other.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// +build linux darwin !windows
|
||||||
|
|
||||||
|
package wails
|
||||||
|
|
||||||
|
func platformInit() {
|
||||||
|
|
||||||
|
}
|
||||||
27
app_windows.go
Normal file
27
app_windows.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// +build windows !linux !darwin
|
||||||
|
|
||||||
|
package wails
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func platformInit() {
|
||||||
|
err := SetProcessDPIAware()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetProcessDPIAware via user32.dll
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiaware
|
||||||
|
// Also, thanks Jack Mordaunt! https://github.com/wailsapp/wails/issues/293
|
||||||
|
func SetProcessDPIAware() error {
|
||||||
|
status, r, err := syscall.NewLazyDLL("user32.dll").NewProc("SetProcessDPIAware").Call()
|
||||||
|
if status == 0 {
|
||||||
|
return fmt.Errorf("exit status %d: %v %v", status, r, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
3
cli.go
3
cli.go
@@ -11,10 +11,9 @@ func (app *App) setupCli() *cmd.Cli {
|
|||||||
result := cmd.NewCli(app.config.Title, "Debug build")
|
result := cmd.NewCli(app.config.Title, "Debug build")
|
||||||
result.Version(cmd.Version)
|
result.Version(cmd.Version)
|
||||||
|
|
||||||
// Setup cli to handle loglevel and headless flags
|
// Setup cli to handle loglevel
|
||||||
result.
|
result.
|
||||||
StringFlag("loglevel", "Sets the log level [debug|info|error|panic|fatal]. Default debug", &app.logLevel).
|
StringFlag("loglevel", "Sets the log level [debug|info|error|panic|fatal]. Default debug", &app.logLevel).
|
||||||
// BoolFlag("headless", "Runs the app in headless mode", &app.headless).
|
|
||||||
Action(app.start)
|
Action(app.start)
|
||||||
|
|
||||||
// Banner
|
// Banner
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
31
cmd/fs.go
31
cmd/fs.go
@@ -12,6 +12,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
)
|
)
|
||||||
@@ -47,6 +48,22 @@ func (fs *FSHelper) FileExists(path string) bool {
|
|||||||
return fi.Mode().IsRegular()
|
return fi.Mode().IsRegular()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindFile returns the first occurrence of match inside path.
|
||||||
|
func (fs *FSHelper) FindFile(path, match string) (string, error) {
|
||||||
|
files, err := ioutil.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
if !f.IsDir() && strings.Contains(f.Name(), match) {
|
||||||
|
return f.Name(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("file not found")
|
||||||
|
}
|
||||||
|
|
||||||
// CreateFile creates a file at the given filename location with the contents
|
// CreateFile creates a file at the given filename location with the contents
|
||||||
// set to the given data. It will create intermediary directories if needed.
|
// set to the given data. It will create intermediary directories if needed.
|
||||||
func (fs *FSHelper) CreateFile(filename string, data []byte) error {
|
func (fs *FSHelper) CreateFile(filename string, data []byte) error {
|
||||||
@@ -100,10 +117,10 @@ func (fs *FSHelper) RemoveFile(filename string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoveFiles removes the given filenames
|
// RemoveFiles removes the given filenames
|
||||||
func (fs *FSHelper) RemoveFiles(files []string) error {
|
func (fs *FSHelper) RemoveFiles(files []string, continueOnError bool) error {
|
||||||
for _, filename := range files {
|
for _, filename := range files {
|
||||||
err := os.Remove(filename)
|
err := os.Remove(filename)
|
||||||
if err != nil {
|
if err != nil && !continueOnError {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,6 +149,16 @@ func (fs *FSHelper) LocalDir(dir string) (*Dir, error) {
|
|||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadRelativeFile loads the given file relative to the caller's directory
|
||||||
|
func (fs *FSHelper) LoadRelativeFile(relativePath string) ([]byte, error) {
|
||||||
|
_, filename, _, _ := runtime.Caller(0)
|
||||||
|
fullPath, err := filepath.Abs(filepath.Join(path.Dir(filename), relativePath))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ioutil.ReadFile(fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
// GetSubdirs will return a list of FQPs to subdirectories in the given directory
|
// GetSubdirs will return a list of FQPs to subdirectories in the given directory
|
||||||
func (d *Dir) GetSubdirs() (map[string]string, error) {
|
func (d *Dir) GetSubdirs() (map[string]string, error) {
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func NewGitHubHelper() *GitHubHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetVersionTags gets the list of tags on the Wails repo
|
// GetVersionTags gets the list of tags on the Wails repo
|
||||||
// It retuns a list of sorted tags in descending order
|
// It returns a list of sorted tags in descending order
|
||||||
func (g *GitHubHelper) GetVersionTags() ([]*SemanticVersion, error) {
|
func (g *GitHubHelper) GetVersionTags() ([]*SemanticVersion, error) {
|
||||||
|
|
||||||
result := []*SemanticVersion{}
|
result := []*SemanticVersion{}
|
||||||
|
|||||||
78
cmd/gomod.go
Normal file
78
cmd/gomod.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetWailsVersion() (*semver.Version, error) {
|
||||||
|
var FS = NewFSHelper()
|
||||||
|
var result *semver.Version
|
||||||
|
|
||||||
|
// Load file
|
||||||
|
var err error
|
||||||
|
goModFile, err := filepath.Abs(filepath.Join(".", "go.mod"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to load go.mod at %s", goModFile)
|
||||||
|
}
|
||||||
|
goMod, err := FS.LoadAsString(goModFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to load go.mod")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find wails version
|
||||||
|
versionRegexp := regexp.MustCompile(`.*github.com/wailsapp/wails.*(v\d+.\d+.\d+(?:-pre\d+)?)`)
|
||||||
|
versions := versionRegexp.FindStringSubmatch(goMod)
|
||||||
|
|
||||||
|
if len(versions) != 2 {
|
||||||
|
return nil, fmt.Errorf("Unable to determine Wails version")
|
||||||
|
}
|
||||||
|
|
||||||
|
version := versions[1]
|
||||||
|
result, err = semver.NewVersion(version)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to parse Wails version: %s", version)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCurrentVersion() (*semver.Version, error) {
|
||||||
|
result, err := semver.NewVersion(Version)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to parse Wails version: %s", Version)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GoModOutOfSync() (bool, error) {
|
||||||
|
gomodversion, err := GetWailsVersion()
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
currentVersion, err := GetCurrentVersion()
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
result := !currentVersion.Equal(gomodversion)
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateGoModVersion() error {
|
||||||
|
currentVersion, err := GetCurrentVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
currentVersionString := currentVersion.String()
|
||||||
|
|
||||||
|
requireLine := "-require=github.com/wailsapp/wails@v" + currentVersionString
|
||||||
|
|
||||||
|
// Issue: go mod edit -require=github.com/wailsapp/wails@1.0.2-pre5
|
||||||
|
helper := NewProgramHelper()
|
||||||
|
command := []string{"go", "mod", "edit", requireLine}
|
||||||
|
return helper.RunCommandArray(command)
|
||||||
|
|
||||||
|
}
|
||||||
468
cmd/helpers.go
468
cmd/helpers.go
@@ -5,11 +5,15 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
mewn "github.com/leaanthony/mewn"
|
"github.com/leaanthony/mewn"
|
||||||
|
"github.com/leaanthony/mewn/lib"
|
||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
)
|
)
|
||||||
@@ -35,34 +39,161 @@ func ValidateFrontendConfig(projectOptions *ProjectOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InstallGoDependencies will run go get in the current directory
|
// InstallGoDependencies will run go get in the current directory
|
||||||
func InstallGoDependencies() error {
|
func InstallGoDependencies(verbose bool) error {
|
||||||
depSpinner := spinner.New("Ensuring Dependencies are up to date...")
|
var depSpinner *spinner.Spinner
|
||||||
depSpinner.SetSpinSpeed(50)
|
if !verbose {
|
||||||
depSpinner.Start()
|
depSpinner = spinner.New("Ensuring Dependencies are up to date...")
|
||||||
err := NewProgramHelper().RunCommand("go get")
|
depSpinner.SetSpinSpeed(50)
|
||||||
|
depSpinner.Start()
|
||||||
|
}
|
||||||
|
err := NewProgramHelper(verbose).RunCommand("go get")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
depSpinner.Error()
|
if !verbose {
|
||||||
|
depSpinner.Error()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
depSpinner.Success()
|
if !verbose {
|
||||||
|
depSpinner.Success()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildApplication will attempt to build the project based on the given inputs
|
// EmbedAssets will embed the built frontend assets via mewn.
|
||||||
func BuildApplication(binaryName string, forceRebuild bool, buildMode string, packageApp bool, projectOptions *ProjectOptions) error {
|
func EmbedAssets() ([]string, error) {
|
||||||
|
mewnFiles := lib.GetMewnFiles([]string{}, false)
|
||||||
|
|
||||||
// Generate Windows assets if needed
|
referencedAssets, err := lib.GetReferencedAssets(mewnFiles)
|
||||||
if runtime.GOOS == "windows" {
|
if err != nil {
|
||||||
cleanUp := !packageApp
|
return []string{}, err
|
||||||
err := NewPackageHelper().PackageWindows(projectOptions, cleanUp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Mewn is installed
|
targetFiles := []string{}
|
||||||
err := CheckMewn()
|
|
||||||
|
for _, referencedAsset := range referencedAssets {
|
||||||
|
packfileData, err := lib.GeneratePackFileString(referencedAsset, false)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
targetFile := filepath.Join(referencedAsset.BaseDir, referencedAsset.PackageName+"-mewn.go")
|
||||||
|
targetFiles = append(targetFiles, targetFile)
|
||||||
|
ioutil.WriteFile(targetFile, []byte(packfileData), 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetFiles, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitializeCrossCompilation(verbose bool) error {
|
||||||
|
// Check Docker
|
||||||
|
if err := CheckIfInstalled("docker"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var packSpinner *spinner.Spinner
|
||||||
|
if !verbose {
|
||||||
|
packSpinner = spinner.New("Pulling wailsapp/xgo:latest docker image... (may take a while)")
|
||||||
|
packSpinner.SetSpinSpeed(50)
|
||||||
|
packSpinner.Start()
|
||||||
|
} else {
|
||||||
|
println("Pulling wailsapp/xgo:latest docker image... (may take a while)")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := NewProgramHelper(verbose).RunCommandArray([]string{"docker",
|
||||||
|
"pull", "wailsapp/xgo:latest"})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if packSpinner != nil {
|
||||||
|
packSpinner.Error()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if packSpinner != nil {
|
||||||
|
packSpinner.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildDocker builds the project using the cross compiling wailsapp/xgo:latest container
|
||||||
|
func BuildDocker(binaryName string, buildMode string, projectOptions *ProjectOptions) error {
|
||||||
|
var packSpinner *spinner.Spinner
|
||||||
|
if buildMode == BuildModeBridge {
|
||||||
|
return fmt.Errorf("you cant serve the application in cross-compilation")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check build directory
|
||||||
|
buildDirectory := filepath.Join(fs.Cwd(), "build")
|
||||||
|
if !fs.DirExists(buildDirectory) {
|
||||||
|
fs.MkDir(buildDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildCommand := slicer.String()
|
||||||
|
userid := 1000
|
||||||
|
user, _ := user.Current()
|
||||||
|
if i, err := strconv.Atoi(user.Uid); err == nil {
|
||||||
|
userid = i
|
||||||
|
}
|
||||||
|
for _, arg := range []string{
|
||||||
|
"docker",
|
||||||
|
"run",
|
||||||
|
"--rm",
|
||||||
|
"-v", fmt.Sprintf("%s:/build", filepath.Join(fs.Cwd(), "build")),
|
||||||
|
"-v", fmt.Sprintf("%s:/source", fs.Cwd()),
|
||||||
|
"-e", fmt.Sprintf("LOCAL_USER_ID=%v", userid),
|
||||||
|
"-e", fmt.Sprintf("FLAG_LDFLAGS=%s", ldFlags(projectOptions, buildMode)),
|
||||||
|
"-e", "FLAG_V=false",
|
||||||
|
"-e", "FLAG_X=false",
|
||||||
|
"-e", "FLAG_RACE=false",
|
||||||
|
"-e", "FLAG_BUILDMODE=default",
|
||||||
|
"-e", "FLAG_TRIMPATH=false",
|
||||||
|
"-e", fmt.Sprintf("TARGETS=%s", projectOptions.Platform+"/"+projectOptions.Architecture),
|
||||||
|
"-e", "GOPROXY=",
|
||||||
|
"-e", "GO111MODULE=on",
|
||||||
|
"wailsapp/xgo:latest",
|
||||||
|
".",
|
||||||
|
} {
|
||||||
|
buildCommand.Add(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
compileMessage := fmt.Sprintf(
|
||||||
|
"Packing + Compiling project for %s/%s using docker image wailsapp/xgo:latest",
|
||||||
|
projectOptions.Platform, projectOptions.Architecture)
|
||||||
|
|
||||||
|
if buildMode == BuildModeDebug {
|
||||||
|
compileMessage += " (Debug Mode)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if !projectOptions.Verbose {
|
||||||
|
packSpinner = spinner.New(compileMessage + "...")
|
||||||
|
packSpinner.SetSpinSpeed(50)
|
||||||
|
packSpinner.Start()
|
||||||
|
} else {
|
||||||
|
println(compileMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := NewProgramHelper(projectOptions.Verbose).RunCommandArray(buildCommand.AsSlice())
|
||||||
|
if err != nil {
|
||||||
|
if packSpinner != nil {
|
||||||
|
packSpinner.Error()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if packSpinner != nil {
|
||||||
|
packSpinner.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildNative builds on the target platform itself.
|
||||||
|
func BuildNative(binaryName string, forceRebuild bool, buildMode string, projectOptions *ProjectOptions) error {
|
||||||
|
|
||||||
|
// Check Mewn is installed
|
||||||
|
if err := CheckMewn(projectOptions.Verbose); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := CheckWindres(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,23 +203,37 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
|
|||||||
compileMessage += " (Debug Mode)"
|
compileMessage += " (Debug Mode)"
|
||||||
}
|
}
|
||||||
|
|
||||||
packSpinner := spinner.New(compileMessage + "...")
|
var packSpinner *spinner.Spinner
|
||||||
packSpinner.SetSpinSpeed(50)
|
if !projectOptions.Verbose {
|
||||||
packSpinner.Start()
|
packSpinner = spinner.New(compileMessage + "...")
|
||||||
|
packSpinner.SetSpinSpeed(50)
|
||||||
|
packSpinner.Start()
|
||||||
|
} else {
|
||||||
|
println(compileMessage)
|
||||||
|
}
|
||||||
|
|
||||||
buildCommand := slicer.String()
|
buildCommand := slicer.String()
|
||||||
buildCommand.Add("mewn")
|
buildCommand.Add("go")
|
||||||
|
|
||||||
|
buildCommand.Add("build")
|
||||||
if buildMode == BuildModeBridge {
|
if buildMode == BuildModeBridge {
|
||||||
// Ignore errors
|
// Ignore errors
|
||||||
buildCommand.Add("-i")
|
buildCommand.Add("-i")
|
||||||
}
|
}
|
||||||
|
|
||||||
buildCommand.Add("build")
|
|
||||||
|
|
||||||
if binaryName != "" {
|
if binaryName != "" {
|
||||||
buildCommand.Add("-o")
|
// Alter binary name based on OS
|
||||||
buildCommand.Add(binaryName)
|
switch projectOptions.Platform {
|
||||||
|
case "windows":
|
||||||
|
if !strings.HasSuffix(binaryName, ".exe") {
|
||||||
|
binaryName += ".exe"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if strings.HasSuffix(binaryName, ".exe") {
|
||||||
|
binaryName = strings.TrimSuffix(binaryName, ".exe")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildCommand.Add("-o", filepath.Join("build", binaryName))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are forcing a rebuild
|
// If we are forcing a rebuild
|
||||||
@@ -96,28 +241,74 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
|
|||||||
buildCommand.Add("-a")
|
buildCommand.Add("-a")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup ld flags
|
buildCommand.AddSlice([]string{"-ldflags", ldFlags(projectOptions, buildMode)})
|
||||||
ldflags := "-w -s "
|
|
||||||
if buildMode == BuildModeDebug {
|
if projectOptions.Verbose {
|
||||||
ldflags = ""
|
fmt.Printf("Command: %v\n", buildCommand.AsSlice())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add windows flags
|
err := NewProgramHelper(projectOptions.Verbose).RunCommandArray(buildCommand.AsSlice())
|
||||||
if runtime.GOOS == "windows" {
|
if err != nil {
|
||||||
ldflags += "-H windowsgui "
|
if packSpinner != nil {
|
||||||
}
|
packSpinner.Error()
|
||||||
|
}
|
||||||
ldflags += "-X github.com/wailsapp/wails.BuildMode=" + buildMode
|
return err
|
||||||
|
}
|
||||||
buildCommand.AddSlice([]string{"-ldflags", ldflags})
|
if packSpinner != nil {
|
||||||
err = NewProgramHelper().RunCommandArray(buildCommand.AsSlice())
|
packSpinner.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildApplication will attempt to build the project based on the given inputs
|
||||||
|
func BuildApplication(binaryName string, forceRebuild bool, buildMode string, packageApp bool, projectOptions *ProjectOptions) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// embed resources
|
||||||
|
targetFiles, err := EmbedAssets()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if projectOptions.CrossCompile {
|
||||||
|
if err := InitializeCrossCompilation(projectOptions.Verbose); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
helper := NewPackageHelper(projectOptions.Platform)
|
||||||
|
|
||||||
|
// Generate windows resources
|
||||||
|
if projectOptions.Platform == "windows" {
|
||||||
|
if err := helper.PackageWindows(projectOptions, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup temporary embedded assets
|
||||||
|
defer func() {
|
||||||
|
for _, filename := range targetFiles {
|
||||||
|
if err := os.Remove(filename); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Removed by popular demand
|
||||||
|
// TODO: Potentially add a flag to cleanup
|
||||||
|
// if projectOptions.Platform == "windows" {
|
||||||
|
// helper.CleanWindows(projectOptions)
|
||||||
|
// }
|
||||||
|
}()
|
||||||
|
|
||||||
|
if projectOptions.CrossCompile {
|
||||||
|
err = BuildDocker(binaryName, buildMode, projectOptions)
|
||||||
|
} else {
|
||||||
|
err = BuildNative(binaryName, forceRebuild, buildMode, projectOptions)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
packSpinner.Error()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
packSpinner.Success()
|
|
||||||
|
|
||||||
// packageApp
|
|
||||||
if packageApp {
|
if packageApp {
|
||||||
err = PackageApplication(projectOptions)
|
err = PackageApplication(projectOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -130,61 +321,76 @@ func BuildApplication(binaryName string, forceRebuild bool, buildMode string, pa
|
|||||||
|
|
||||||
// PackageApplication will attempt to package the application in a platform dependent way
|
// PackageApplication will attempt to package the application in a platform dependent way
|
||||||
func PackageApplication(projectOptions *ProjectOptions) error {
|
func PackageApplication(projectOptions *ProjectOptions) error {
|
||||||
// Package app
|
var packageSpinner *spinner.Spinner
|
||||||
message := "Generating .app"
|
if projectOptions.Verbose {
|
||||||
if runtime.GOOS == "windows" {
|
packageSpinner = spinner.New("Packaging application...")
|
||||||
err := CheckWindres()
|
packageSpinner.SetSpinSpeed(50)
|
||||||
if err != nil {
|
packageSpinner.Start()
|
||||||
return err
|
|
||||||
}
|
|
||||||
message = "Generating resource bundle"
|
|
||||||
}
|
}
|
||||||
packageSpinner := spinner.New(message)
|
|
||||||
packageSpinner.SetSpinSpeed(50)
|
err := NewPackageHelper(projectOptions.Platform).Package(projectOptions)
|
||||||
packageSpinner.Start()
|
|
||||||
err := NewPackageHelper().Package(projectOptions)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
packageSpinner.Error()
|
if packageSpinner != nil {
|
||||||
|
packageSpinner.Error()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
packageSpinner.Success()
|
if packageSpinner != nil {
|
||||||
|
packageSpinner.Success()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildFrontend runs the given build command
|
// BuildFrontend runs the given build command
|
||||||
func BuildFrontend(buildCommand string) error {
|
func BuildFrontend(projectOptions *ProjectOptions) error {
|
||||||
buildFESpinner := spinner.New("Building frontend...")
|
var buildFESpinner *spinner.Spinner
|
||||||
buildFESpinner.SetSpinSpeed(50)
|
if !projectOptions.Verbose {
|
||||||
buildFESpinner.Start()
|
buildFESpinner = spinner.New("Building frontend...")
|
||||||
err := NewProgramHelper().RunCommand(buildCommand)
|
buildFESpinner.SetSpinSpeed(50)
|
||||||
|
buildFESpinner.Start()
|
||||||
|
} else {
|
||||||
|
println("Building frontend...")
|
||||||
|
}
|
||||||
|
err := NewProgramHelper(projectOptions.Verbose).RunCommand(projectOptions.FrontEnd.Build)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buildFESpinner.Error()
|
if buildFESpinner != nil {
|
||||||
|
buildFESpinner.Error()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buildFESpinner.Success()
|
if buildFESpinner != nil {
|
||||||
|
buildFESpinner.Success()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckMewn checks if mewn is installed and if not, attempts to fetch it
|
// CheckMewn checks if mewn is installed and if not, attempts to fetch it
|
||||||
func CheckMewn() (err error) {
|
func CheckMewn(verbose bool) (err error) {
|
||||||
programHelper := NewProgramHelper()
|
programHelper := NewProgramHelper(verbose)
|
||||||
if !programHelper.IsInstalled("mewn") {
|
if !programHelper.IsInstalled("mewn") {
|
||||||
buildSpinner := spinner.New()
|
var buildSpinner *spinner.Spinner
|
||||||
buildSpinner.SetSpinSpeed(50)
|
if !verbose {
|
||||||
buildSpinner.Start("Installing Mewn asset packer...")
|
buildSpinner = spinner.New()
|
||||||
|
buildSpinner.SetSpinSpeed(50)
|
||||||
|
buildSpinner.Start("Installing Mewn asset packer...")
|
||||||
|
}
|
||||||
err := programHelper.InstallGoPackage("github.com/leaanthony/mewn/cmd/mewn")
|
err := programHelper.InstallGoPackage("github.com/leaanthony/mewn/cmd/mewn")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
buildSpinner.Error()
|
if buildSpinner != nil {
|
||||||
|
buildSpinner.Error()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buildSpinner.Success()
|
if buildSpinner != nil {
|
||||||
|
buildSpinner.Success()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckWindres checks if Windres is installed and if not, aborts
|
// CheckWindres checks if Windres is installed and if not, aborts
|
||||||
func CheckWindres() (err error) {
|
func CheckWindres() (err error) {
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" { // FIXME: Handle windows cross-compile for windows!
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
programHelper := NewProgramHelper()
|
programHelper := NewProgramHelper()
|
||||||
@@ -194,6 +400,15 @@ func CheckWindres() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckIfInstalled returns if application is installed
|
||||||
|
func CheckIfInstalled(application string) (err error) {
|
||||||
|
programHelper := NewProgramHelper()
|
||||||
|
if !programHelper.IsInstalled(application) {
|
||||||
|
return fmt.Errorf("%s not installed. Ensure you have installed %s correctly", application, application)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// InstallFrontendDeps attempts to install the frontend dependencies based on the given options
|
// InstallFrontendDeps attempts to install the frontend dependencies based on the given options
|
||||||
func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forceRebuild bool, caller string) error {
|
func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forceRebuild bool, caller string) error {
|
||||||
|
|
||||||
@@ -204,9 +419,14 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if frontend deps have been updated
|
// Check if frontend deps have been updated
|
||||||
feSpinner := spinner.New("Ensuring frontend dependencies are up to date (This may take a while)")
|
var feSpinner *spinner.Spinner
|
||||||
feSpinner.SetSpinSpeed(50)
|
if !projectOptions.Verbose {
|
||||||
feSpinner.Start()
|
feSpinner = spinner.New("Ensuring frontend dependencies are up to date (This may take a while)")
|
||||||
|
feSpinner.SetSpinSpeed(50)
|
||||||
|
feSpinner.Start()
|
||||||
|
} else {
|
||||||
|
println("Ensuring frontend dependencies are up to date (This may take a while)")
|
||||||
|
}
|
||||||
|
|
||||||
requiresNPMInstall := true
|
requiresNPMInstall := true
|
||||||
|
|
||||||
@@ -219,6 +439,15 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
|
|||||||
|
|
||||||
const md5sumFile = "package.json.md5"
|
const md5sumFile = "package.json.md5"
|
||||||
|
|
||||||
|
// If node_modules does not exist, force a rebuild.
|
||||||
|
nodeModulesPath, err := filepath.Abs(filepath.Join(".", "node_modules"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !fs.DirExists(nodeModulesPath) {
|
||||||
|
forceRebuild = true
|
||||||
|
}
|
||||||
|
|
||||||
// If we aren't forcing the install and the md5sum file exists
|
// If we aren't forcing the install and the md5sum file exists
|
||||||
if !forceRebuild && fs.FileExists(md5sumFile) {
|
if !forceRebuild && fs.FileExists(md5sumFile) {
|
||||||
// Yes - read contents
|
// Yes - read contents
|
||||||
@@ -229,7 +458,11 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
|
|||||||
if savedMD5sum == packageJSONMD5 {
|
if savedMD5sum == packageJSONMD5 {
|
||||||
// Same - no need for reinstall
|
// Same - no need for reinstall
|
||||||
requiresNPMInstall = false
|
requiresNPMInstall = false
|
||||||
feSpinner.Success("Skipped frontend dependencies (-f to force rebuild)")
|
if feSpinner != nil {
|
||||||
|
feSpinner.Success("Skipped frontend dependencies (-f to force rebuild)")
|
||||||
|
} else {
|
||||||
|
println("Skipped frontend dependencies (-f to force rebuild)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,47 +471,58 @@ func InstallFrontendDeps(projectDir string, projectOptions *ProjectOptions, forc
|
|||||||
// Different? Build
|
// Different? Build
|
||||||
if requiresNPMInstall || forceRebuild {
|
if requiresNPMInstall || forceRebuild {
|
||||||
// Install dependencies
|
// Install dependencies
|
||||||
err = NewProgramHelper().RunCommand(projectOptions.FrontEnd.Install)
|
err = NewProgramHelper(projectOptions.Verbose).RunCommand(projectOptions.FrontEnd.Install)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
feSpinner.Error()
|
if feSpinner != nil {
|
||||||
|
feSpinner.Error()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
feSpinner.Success()
|
if feSpinner != nil {
|
||||||
|
feSpinner.Success()
|
||||||
|
}
|
||||||
|
|
||||||
// Update md5sum file
|
// Update md5sum file
|
||||||
ioutil.WriteFile(md5sumFile, []byte(packageJSONMD5), 0644)
|
ioutil.WriteFile(md5sumFile, []byte(packageJSONMD5), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install the bridge library
|
// Install the runtime
|
||||||
err = InstallBridge(caller, projectDir, projectOptions)
|
err = InstallRuntime(caller, projectDir, projectOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build frontend
|
// Build frontend
|
||||||
err = BuildFrontend(projectOptions.FrontEnd.Build)
|
err = BuildFrontend(projectOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstallBridge installs the relevant bridge javascript library
|
// InstallRuntime installs the correct runtime for the type of build
|
||||||
func InstallBridge(caller string, projectDir string, projectOptions *ProjectOptions) error {
|
func InstallRuntime(caller string, projectDir string, projectOptions *ProjectOptions) error {
|
||||||
bridgeFile := "wailsbridge.prod.js"
|
if caller == "build" {
|
||||||
if caller == "serve" {
|
return InstallProdRuntime(projectDir, projectOptions)
|
||||||
bridgeFile = "wailsbridge.js"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy bridge to project
|
return InstallBridge(projectDir, projectOptions)
|
||||||
bridgeAssets := mewn.Group("../runtime/bridge/")
|
}
|
||||||
bridgeFileData := bridgeAssets.Bytes(bridgeFile)
|
|
||||||
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, projectOptions.FrontEnd.Bridge, "wailsbridge.js")
|
// InstallBridge installs the relevant bridge javascript library
|
||||||
err := fs.CreateFile(bridgeFileTarget, bridgeFileData)
|
func InstallBridge(projectDir string, projectOptions *ProjectOptions) error {
|
||||||
if err != nil {
|
bridgeFileData := mewn.String("../runtime/assets/bridge.js")
|
||||||
return err
|
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "init.js")
|
||||||
}
|
err := fs.CreateFile(bridgeFileTarget, []byte(bridgeFileData))
|
||||||
return nil
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstallProdRuntime installs the production runtime
|
||||||
|
func InstallProdRuntime(projectDir string, projectOptions *ProjectOptions) error {
|
||||||
|
prodInit := mewn.String("../runtime/js/runtime/init.js")
|
||||||
|
bridgeFileTarget := filepath.Join(projectDir, projectOptions.FrontEnd.Dir, "node_modules", "@wailsapp", "runtime", "init.js")
|
||||||
|
err := fs.CreateFile(bridgeFileTarget, []byte(prodInit))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeProject attempts to serve up the current project so that it may be connected to
|
// ServeProject attempts to serve up the current project so that it may be connected to
|
||||||
@@ -288,7 +532,7 @@ func ServeProject(projectOptions *ProjectOptions, logger *Logger) error {
|
|||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
logger.Green(">>>>> To connect, you will need to run '" + projectOptions.FrontEnd.Serve + "' in the '" + projectOptions.FrontEnd.Dir + "' directory <<<<<")
|
logger.Green(">>>>> To connect, you will need to run '" + projectOptions.FrontEnd.Serve + "' in the '" + projectOptions.FrontEnd.Dir + "' directory <<<<<")
|
||||||
}()
|
}()
|
||||||
location, err := filepath.Abs(projectOptions.BinaryName)
|
location, err := filepath.Abs(filepath.Join("build", projectOptions.BinaryName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -304,3 +548,33 @@ func ServeProject(projectOptions *ProjectOptions, logger *Logger) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ldFlags(po *ProjectOptions, buildMode string) string {
|
||||||
|
// Setup ld flags
|
||||||
|
ldflags := "-w -s "
|
||||||
|
if buildMode == BuildModeDebug {
|
||||||
|
ldflags = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add windows flags
|
||||||
|
if po.Platform == "windows" && buildMode == BuildModeProd {
|
||||||
|
ldflags += "-H windowsgui "
|
||||||
|
}
|
||||||
|
|
||||||
|
ldflags += "-X github.com/wailsapp/wails.BuildMode=" + buildMode
|
||||||
|
|
||||||
|
// Add additional ldflags passed in via the `ldflags` cli flag
|
||||||
|
if len(po.LdFlags) > 0 {
|
||||||
|
ldflags += " " + po.LdFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we wish to generate typescript
|
||||||
|
if po.typescriptDefsFilename != "" {
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err == nil {
|
||||||
|
filename := filepath.Join(cwd, po.FrontEnd.Dir, po.typescriptDefsFilename)
|
||||||
|
ldflags += " -X github.com/wailsapp/wails/lib/binding.typescriptDefinitionFilename=" + filename
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ldflags
|
||||||
|
}
|
||||||
|
|||||||
285
cmd/linux.go
285
cmd/linux.go
@@ -17,122 +17,174 @@ type LinuxDistribution int
|
|||||||
const (
|
const (
|
||||||
// Unknown is the catch-all distro
|
// Unknown is the catch-all distro
|
||||||
Unknown LinuxDistribution = iota
|
Unknown LinuxDistribution = iota
|
||||||
|
// Debian distribution
|
||||||
|
Debian
|
||||||
// Ubuntu distribution
|
// Ubuntu distribution
|
||||||
Ubuntu
|
Ubuntu
|
||||||
// Arch linux distribution
|
// Arch linux distribution
|
||||||
Arch
|
Arch
|
||||||
// RedHat linux distribution
|
// CentOS linux distribution
|
||||||
RedHat
|
CentOS
|
||||||
// Debian distribution
|
// Fedora linux distribution
|
||||||
Debian
|
Fedora
|
||||||
// Gentoo distribution
|
// Gentoo distribution
|
||||||
Gentoo
|
Gentoo
|
||||||
// Zorin distribution
|
// Zorin distribution
|
||||||
Zorin
|
Zorin
|
||||||
|
// Parrot distribution
|
||||||
|
Parrot
|
||||||
|
// Linuxmint distribution
|
||||||
|
Linuxmint
|
||||||
|
// VoidLinux distribution
|
||||||
|
VoidLinux
|
||||||
|
// Elementary distribution
|
||||||
|
Elementary
|
||||||
|
// Kali distribution
|
||||||
|
Kali
|
||||||
|
// Neon distribution
|
||||||
|
Neon
|
||||||
|
// ArcoLinux distribution
|
||||||
|
ArcoLinux
|
||||||
|
// Manjaro distribution
|
||||||
|
Manjaro
|
||||||
|
// ManjaroARM distribution
|
||||||
|
ManjaroARM
|
||||||
|
// Deepin distribution
|
||||||
|
Deepin
|
||||||
|
// Raspbian distribution
|
||||||
|
Raspbian
|
||||||
|
// Tumbleweed (OpenSUSE) distribution
|
||||||
|
Tumbleweed
|
||||||
|
// Leap (OpenSUSE) distribution
|
||||||
|
Leap
|
||||||
|
// ArchLabs distribution
|
||||||
|
ArchLabs
|
||||||
|
// PopOS distribution
|
||||||
|
PopOS
|
||||||
|
// Solus distribution
|
||||||
|
Solus
|
||||||
|
// Ctlos Linux distribution
|
||||||
|
Ctlos
|
||||||
)
|
)
|
||||||
|
|
||||||
// DistroInfo contains all the information relating to a linux distribution
|
// DistroInfo contains all the information relating to a linux distribution
|
||||||
type DistroInfo struct {
|
type DistroInfo struct {
|
||||||
Distribution LinuxDistribution
|
Distribution LinuxDistribution
|
||||||
Description string
|
Name string
|
||||||
Release string
|
ID string
|
||||||
Codename string
|
Description string
|
||||||
DistributorID string
|
Release string
|
||||||
DiscoveredBy string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLinuxDistroInfo returns information about the running linux distribution
|
// GetLinuxDistroInfo returns information about the running linux distribution
|
||||||
func GetLinuxDistroInfo() *DistroInfo {
|
func GetLinuxDistroInfo() *DistroInfo {
|
||||||
result := &DistroInfo{Distribution: Unknown}
|
result := &DistroInfo{
|
||||||
program := NewProgramHelper()
|
Distribution: Unknown,
|
||||||
// Does lsb_release exist?
|
ID: "unknown",
|
||||||
|
Name: "Unknown",
|
||||||
lsbRelease := program.FindProgram("lsb_release")
|
}
|
||||||
if lsbRelease != nil {
|
_, err := os.Stat("/etc/os-release")
|
||||||
stdout, _, _, err := lsbRelease.Run("-a")
|
if !os.IsNotExist(err) {
|
||||||
if err != nil {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
result.DiscoveredBy = "lsb"
|
|
||||||
for _, line := range strings.Split(stdout, "\n") {
|
|
||||||
if strings.Contains(line, ":") {
|
|
||||||
// Iterate lines a
|
|
||||||
details := strings.Split(line, ":")
|
|
||||||
key := strings.TrimSpace(details[0])
|
|
||||||
value := strings.TrimSpace(details[1])
|
|
||||||
switch key {
|
|
||||||
case "Distributor ID":
|
|
||||||
result.DistributorID = value
|
|
||||||
switch value {
|
|
||||||
case "Ubuntu":
|
|
||||||
result.Distribution = Ubuntu
|
|
||||||
case "Arch", "ManjaroLinux":
|
|
||||||
result.Distribution = Arch
|
|
||||||
case "Debian":
|
|
||||||
result.Distribution = Debian
|
|
||||||
case "Gentoo":
|
|
||||||
result.Distribution = Gentoo
|
|
||||||
case "Zorin":
|
|
||||||
result.Distribution = Zorin
|
|
||||||
case "Fedora":
|
|
||||||
result.Distribution = RedHat
|
|
||||||
}
|
|
||||||
case "Description":
|
|
||||||
result.Description = value
|
|
||||||
case "Release":
|
|
||||||
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")
|
osRelease, _ := ioutil.ReadFile("/etc/os-release")
|
||||||
// Split into lines
|
result = parseOsRelease(string(osRelease))
|
||||||
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
|
|
||||||
case "Gentoo/Linux":
|
|
||||||
result.Distribution = Gentoo
|
|
||||||
default:
|
|
||||||
result.Distribution = Unknown
|
|
||||||
result.DistributorID = osName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseOsRelease parses the given os-release data and returns
|
||||||
|
// a DistroInfo struct with the details
|
||||||
|
func parseOsRelease(osRelease string) *DistroInfo {
|
||||||
|
result := &DistroInfo{Distribution: Unknown}
|
||||||
|
|
||||||
|
// Default value
|
||||||
|
osID := "unknown"
|
||||||
|
osNAME := "Unknown"
|
||||||
|
version := ""
|
||||||
|
|
||||||
|
// Split into lines
|
||||||
|
lines := strings.Split(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 "ID":
|
||||||
|
osID = strings.ToLower(strings.Trim(splitLine[1], "\""))
|
||||||
|
case "NAME":
|
||||||
|
osNAME = strings.Trim(splitLine[1], "\"")
|
||||||
|
case "VERSION_ID":
|
||||||
|
version = strings.Trim(splitLine[1], "\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check distro name against list of distros
|
||||||
|
switch osID {
|
||||||
|
case "fedora":
|
||||||
|
result.Distribution = Fedora
|
||||||
|
case "centos":
|
||||||
|
result.Distribution = CentOS
|
||||||
|
case "arch":
|
||||||
|
result.Distribution = Arch
|
||||||
|
case "archlabs":
|
||||||
|
result.Distribution = ArchLabs
|
||||||
|
case "ctlos":
|
||||||
|
result.Distribution = Ctlos
|
||||||
|
case "debian":
|
||||||
|
result.Distribution = Debian
|
||||||
|
case "ubuntu":
|
||||||
|
result.Distribution = Ubuntu
|
||||||
|
case "gentoo":
|
||||||
|
result.Distribution = Gentoo
|
||||||
|
case "zorin":
|
||||||
|
result.Distribution = Zorin
|
||||||
|
case "parrot":
|
||||||
|
result.Distribution = Parrot
|
||||||
|
case "linuxmint":
|
||||||
|
result.Distribution = Linuxmint
|
||||||
|
case "void":
|
||||||
|
result.Distribution = VoidLinux
|
||||||
|
case "elementary":
|
||||||
|
result.Distribution = Elementary
|
||||||
|
case "kali":
|
||||||
|
result.Distribution = Kali
|
||||||
|
case "neon":
|
||||||
|
result.Distribution = Neon
|
||||||
|
case "arcolinux":
|
||||||
|
result.Distribution = ArcoLinux
|
||||||
|
case "manjaro":
|
||||||
|
result.Distribution = Manjaro
|
||||||
|
case "manjaro-arm":
|
||||||
|
result.Distribution = ManjaroARM
|
||||||
|
case "deepin":
|
||||||
|
result.Distribution = Deepin
|
||||||
|
case "raspbian":
|
||||||
|
result.Distribution = Raspbian
|
||||||
|
case "opensuse-tumbleweed":
|
||||||
|
result.Distribution = Tumbleweed
|
||||||
|
case "opensuse-leap":
|
||||||
|
result.Distribution = Leap
|
||||||
|
case "pop":
|
||||||
|
result.Distribution = PopOS
|
||||||
|
case "solus":
|
||||||
|
result.Distribution = Solus
|
||||||
|
default:
|
||||||
|
result.Distribution = Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Name = osNAME
|
||||||
|
result.ID = osID
|
||||||
|
result.Release = version
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// CheckPkgInstalled is all functions that use local programs to see if a package is installed
|
||||||
|
type CheckPkgInstalled func(string) (bool, error)
|
||||||
|
|
||||||
// EqueryInstalled uses equery to see if a package is installed
|
// EqueryInstalled uses equery to see if a package is installed
|
||||||
func EqueryInstalled(packageName string) (bool, error) {
|
func EqueryInstalled(packageName string) (bool, error) {
|
||||||
program := NewProgramHelper()
|
program := NewProgramHelper()
|
||||||
@@ -155,6 +207,17 @@ func DpkgInstalled(packageName string) (bool, error) {
|
|||||||
return exitCode == 0, nil
|
return exitCode == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EOpkgInstalled uses dpkg to see if a package is installed
|
||||||
|
func EOpkgInstalled(packageName string) (bool, error) {
|
||||||
|
program := NewProgramHelper()
|
||||||
|
eopkg := program.FindProgram("eopkg")
|
||||||
|
if eopkg == nil {
|
||||||
|
return false, fmt.Errorf("cannot check dependencies: eopkg not found")
|
||||||
|
}
|
||||||
|
stdout, _, _, _ := eopkg.Run("info", packageName)
|
||||||
|
return strings.HasPrefix(stdout, "Installed"), nil
|
||||||
|
}
|
||||||
|
|
||||||
// PacmanInstalled uses pacman to see if a package is installed.
|
// PacmanInstalled uses pacman to see if a package is installed.
|
||||||
func PacmanInstalled(packageName string) (bool, error) {
|
func PacmanInstalled(packageName string) (bool, error) {
|
||||||
program := NewProgramHelper()
|
program := NewProgramHelper()
|
||||||
@@ -166,6 +229,17 @@ func PacmanInstalled(packageName string) (bool, error) {
|
|||||||
return exitCode == 0, nil
|
return exitCode == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XbpsInstalled uses pacman to see if a package is installed.
|
||||||
|
func XbpsInstalled(packageName string) (bool, error) {
|
||||||
|
program := NewProgramHelper()
|
||||||
|
xbpsQuery := program.FindProgram("xbps-query")
|
||||||
|
if xbpsQuery == nil {
|
||||||
|
return false, fmt.Errorf("cannot check dependencies: xbps-query not found")
|
||||||
|
}
|
||||||
|
_, _, exitCode, _ := xbpsQuery.Run("-S", packageName)
|
||||||
|
return exitCode == 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RpmInstalled uses rpm to see if a package is installed
|
// RpmInstalled uses rpm to see if a package is installed
|
||||||
func RpmInstalled(packageName string) (bool, error) {
|
func RpmInstalled(packageName string) (bool, error) {
|
||||||
program := NewProgramHelper()
|
program := NewProgramHelper()
|
||||||
@@ -179,18 +253,18 @@ func RpmInstalled(packageName string) (bool, error) {
|
|||||||
|
|
||||||
// RequestSupportForDistribution promts the user to submit a request to support their
|
// RequestSupportForDistribution promts the user to submit a request to support their
|
||||||
// currently unsupported distribution
|
// currently unsupported distribution
|
||||||
func RequestSupportForDistribution(distroInfo *DistroInfo, libraryName string) error {
|
func RequestSupportForDistribution(distroInfo *DistroInfo) error {
|
||||||
var logger = NewLogger()
|
var logger = NewLogger()
|
||||||
defaultError := fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, libraryName)
|
defaultError := fmt.Errorf("unable to check libraries on distribution '%s'", distroInfo.Name)
|
||||||
|
|
||||||
logger.Yellow("Distribution '%s' is not currently supported, but we would love to!", distroInfo.DistributorID)
|
logger.Yellow("Distribution '%s' is not currently supported, but we would love to!", distroInfo.Name)
|
||||||
q := fmt.Sprintf("Would you like to submit a request to support distribution '%s'?", distroInfo.DistributorID)
|
q := fmt.Sprintf("Would you like to submit a request to support distribution '%s'?", distroInfo.Name)
|
||||||
result := Prompt(q, "yes")
|
result := Prompt(q, "yes")
|
||||||
if strings.ToLower(result) != "yes" {
|
if strings.ToLower(result) != "yes" {
|
||||||
return defaultError
|
return defaultError
|
||||||
}
|
}
|
||||||
|
|
||||||
title := fmt.Sprintf("Support Distribution '%s'", distroInfo.DistributorID)
|
title := fmt.Sprintf("Support Distribution '%s'", distroInfo.Name)
|
||||||
|
|
||||||
var str strings.Builder
|
var str strings.Builder
|
||||||
|
|
||||||
@@ -205,16 +279,19 @@ func RequestSupportForDistribution(distroInfo *DistroInfo, libraryName string) e
|
|||||||
str.WriteString(fmt.Sprintf("| Platform | %s |\n", runtime.GOOS))
|
str.WriteString(fmt.Sprintf("| Platform | %s |\n", runtime.GOOS))
|
||||||
str.WriteString(fmt.Sprintf("| Arch | %s |\n", runtime.GOARCH))
|
str.WriteString(fmt.Sprintf("| Arch | %s |\n", runtime.GOARCH))
|
||||||
str.WriteString(fmt.Sprintf("| GO111MODULE | %s |\n", gomodule))
|
str.WriteString(fmt.Sprintf("| GO111MODULE | %s |\n", gomodule))
|
||||||
str.WriteString(fmt.Sprintf("| Distribution ID | %s |\n", distroInfo.DistributorID))
|
str.WriteString(fmt.Sprintf("| Distribution ID | %s |\n", distroInfo.ID))
|
||||||
|
str.WriteString(fmt.Sprintf("| Distribution Name | %s |\n", distroInfo.Name))
|
||||||
str.WriteString(fmt.Sprintf("| Distribution Version | %s |\n", distroInfo.Release))
|
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 currently 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())
|
body := fmt.Sprintf("**Description**\nDistribution '%s' is currently 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.ID, str.String())
|
||||||
fullURL := "https://github.com/wailsapp/wails/issues/new?"
|
fullURL := "https://github.com/wailsapp/wails/issues/new?"
|
||||||
params := "title=" + title + "&body=" + body
|
params := "title=" + title + "&body=" + body
|
||||||
|
|
||||||
fmt.Println("Opening browser to file request.")
|
fmt.Println("Opening browser to file request.")
|
||||||
browser.OpenURL(fullURL + url.PathEscape(params))
|
browser.OpenURL(fullURL + url.PathEscape(params))
|
||||||
|
result = Prompt("We have a guide for adding support for your distribution. Would you like to view it?", "yes")
|
||||||
|
if strings.ToLower(result) == "yes" {
|
||||||
|
browser.OpenURL("https://wails.app/guides/distro/")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
46
cmd/linux_test.go
Normal file
46
cmd/linux_test.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestUbuntuDetection(t *testing.T) {
|
||||||
|
osrelease := `
|
||||||
|
NAME="Ubuntu"
|
||||||
|
VERSION="18.04.2 LTS (Bionic Beaver)"
|
||||||
|
ID=ubuntu
|
||||||
|
ID_LIKE=debian
|
||||||
|
PRETTY_NAME="Ubuntu 18.04.2 LTS"
|
||||||
|
VERSION_ID="18.04"
|
||||||
|
HOME_URL="https://www.ubuntu.com/"
|
||||||
|
SUPPORT_URL="https://help.ubuntu.com/"
|
||||||
|
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
|
||||||
|
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
|
||||||
|
VERSION_CODENAME=bionic
|
||||||
|
UBUNTU_CODENAME=bionic
|
||||||
|
`
|
||||||
|
|
||||||
|
result := parseOsRelease(osrelease)
|
||||||
|
if result.Distribution != Ubuntu {
|
||||||
|
t.Errorf("expected 'Ubuntu' ID but got '%d'", result.Distribution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTumbleweedDetection(t *testing.T) {
|
||||||
|
osrelease := `
|
||||||
|
NAME="openSUSE Tumbleweed"
|
||||||
|
# VERSION="20200414"
|
||||||
|
ID="opensuse-tumbleweed"
|
||||||
|
ID_LIKE="opensuse suse"
|
||||||
|
VERSION_ID="20200414"
|
||||||
|
PRETTY_NAME="openSUSE Tumbleweed"
|
||||||
|
ANSI_COLOR="0;32"
|
||||||
|
CPE_NAME="cpe:/o:opensuse:tumbleweed:20200414"
|
||||||
|
BUG_REPORT_URL="https://bugs.opensuse.org"
|
||||||
|
HOME_URL="https://www.opensuse.org/"
|
||||||
|
LOGO="distributor-logo"
|
||||||
|
`
|
||||||
|
|
||||||
|
result := parseOsRelease(osrelease)
|
||||||
|
if result.Distribution != Tumbleweed {
|
||||||
|
t.Errorf("expected 'Tumbleweed' ID but got '%d'", result.Distribution)
|
||||||
|
}
|
||||||
|
}
|
||||||
93
cmd/linuxdb.go
Normal file
93
cmd/linuxdb.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LinuxDB is the database for linux distribution data.
|
||||||
|
type LinuxDB struct {
|
||||||
|
Distributions map[string]*Distribution `yaml:"distributions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distribution holds the os-release ID and a map of releases.
|
||||||
|
type Distribution struct {
|
||||||
|
ID string `yaml:"id"`
|
||||||
|
Releases map[string]*Release `yaml:"releases"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRelease attempts to return the specific Release information
|
||||||
|
// for the given release name. If there is no specific match, the
|
||||||
|
// default release data is returned.
|
||||||
|
func (d *Distribution) GetRelease(version string) *Release {
|
||||||
|
result := d.Releases[version]
|
||||||
|
if result == nil {
|
||||||
|
result = d.Releases["default"]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release holds the name and version of the release as given by
|
||||||
|
// os-release. Programs is a slice of dependant programs required
|
||||||
|
// to be present on the local installation for Wails to function.
|
||||||
|
// Libraries is a slice of libraries that must be present for Wails
|
||||||
|
// applications to compile.
|
||||||
|
type Release struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Version string `yaml:"version"`
|
||||||
|
GccVersionCommand string `yaml:"gccversioncommand"`
|
||||||
|
Programs []*Prerequisite `yaml:"programs"`
|
||||||
|
Libraries []*Prerequisite `yaml:"libraries"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prerequisite is a simple struct containing a program/library name
|
||||||
|
// plus the distribution specific help text indicating how to install
|
||||||
|
// it.
|
||||||
|
type Prerequisite struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Help string `yaml:"help,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load will load the given filename from disk and attempt to
|
||||||
|
// import the data into the LinuxDB.
|
||||||
|
func (l *LinuxDB) Load(filename string) error {
|
||||||
|
if fs.FileExists(filename) {
|
||||||
|
data, err := fs.LoadAsBytes(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return l.ImportData(data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImportData will unmarshal the given YAML formatted data
|
||||||
|
// into the LinuxDB
|
||||||
|
func (l *LinuxDB) ImportData(data []byte) error {
|
||||||
|
return yaml.Unmarshal(data, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDistro returns the Distribution information for the
|
||||||
|
// given distribution name. If the distribution is not supported,
|
||||||
|
// nil is returned.
|
||||||
|
func (l *LinuxDB) GetDistro(distro string) *Distribution {
|
||||||
|
return l.Distributions[distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLinuxDB creates a new LinuxDB instance from the bundled
|
||||||
|
// linuxdb.yaml file.
|
||||||
|
func NewLinuxDB() *LinuxDB {
|
||||||
|
data, err := fs.LoadRelativeFile("./linuxdb.yaml")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Could not load linuxdb.yaml")
|
||||||
|
}
|
||||||
|
result := LinuxDB{
|
||||||
|
Distributions: make(map[string]*Distribution),
|
||||||
|
}
|
||||||
|
err = result.ImportData(data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return &result
|
||||||
|
}
|
||||||
300
cmd/linuxdb.yaml
Normal file
300
cmd/linuxdb.yaml
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
---
|
||||||
|
distributions:
|
||||||
|
debian:
|
||||||
|
id: debian
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
name: Debian
|
||||||
|
version: default
|
||||||
|
gccversioncommand: &gccdumpversion -dumpversion
|
||||||
|
programs: &debiandefaultprograms
|
||||||
|
- name: gcc
|
||||||
|
help: Please install with `sudo apt-get install build-essential` and try again
|
||||||
|
- name: pkg-config
|
||||||
|
help: Please install with `sudo apt-get install pkg-config` and try again
|
||||||
|
- name: npm
|
||||||
|
help: Please install with `curl -sL https://deb.nodesource.com/setup_12.x | sudo bash - && sudo apt-get install -y nodejs` and try again
|
||||||
|
libraries: &debiandefaultlibraries
|
||||||
|
- name: libgtk-3-dev
|
||||||
|
help: Please install with `sudo apt-get install libgtk-3-dev` and try again
|
||||||
|
- name: libwebkit2gtk-4.0-dev
|
||||||
|
help: Please install with `sudo apt-get install libwebkit2gtk-4.0-dev` and try again
|
||||||
|
ubuntu:
|
||||||
|
id: ubuntu
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Ubuntu
|
||||||
|
gccversioncommand: &gccdumpfullversion -dumpfullversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
pop:
|
||||||
|
id: pop
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Pop!_OS
|
||||||
|
gccversioncommand: &gccdumpfullversion -dumpfullversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
kali:
|
||||||
|
id: kali
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Kali GNU/Linux
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
parrot:
|
||||||
|
id: parrot
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Parrot GNU/Linux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
zorin:
|
||||||
|
id: zorin
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Zorin
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
linuxmint:
|
||||||
|
id: linuxmint
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Linux Mint
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
elementary:
|
||||||
|
id: elementary
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: elementary OS
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
neon:
|
||||||
|
id: neon
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: KDE neon
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
deepin:
|
||||||
|
id: deepin
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Deepin
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
void:
|
||||||
|
id: void
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: VoidLinux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs:
|
||||||
|
- name: gcc
|
||||||
|
help: Please install with `xbps-install base-devel` and try again
|
||||||
|
- name: pkg-config
|
||||||
|
help: Please install with `xbps-install pkg-config` and try again
|
||||||
|
- name: npm
|
||||||
|
help: Please install with `xbps-install nodejs` and try again
|
||||||
|
libraries:
|
||||||
|
- name: gtk+3-devel
|
||||||
|
help: Please install with `xbps-install gtk+3-devel` and try again
|
||||||
|
- name: webkit2gtk-devel
|
||||||
|
help: Please install with `xbps-install webkit2gtk-devel` and try again
|
||||||
|
centos:
|
||||||
|
id: centos
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: CentOS Linux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs:
|
||||||
|
- name: gcc
|
||||||
|
help: Please install with `sudo yum install gcc-c++ make` and try again
|
||||||
|
- name: pkg-config
|
||||||
|
help: Please install with `sudo yum install pkgconf-pkg-config` and try again
|
||||||
|
- name: npm
|
||||||
|
help: Please install with `sudo yum install epel-release && sudo yum install nodejs` and try again
|
||||||
|
libraries:
|
||||||
|
- name: gtk3-devel
|
||||||
|
help: Please install with `sudo yum install gtk3-devel` and try again
|
||||||
|
- name: webkitgtk3-devel
|
||||||
|
help: Please install with `sudo yum install webkitgtk3-devel` and try again
|
||||||
|
fedora:
|
||||||
|
id: fedora
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Fedora
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs:
|
||||||
|
- name: gcc
|
||||||
|
help: Please install with `sudo yum install gcc-c++ make` and try again
|
||||||
|
- name: pkg-config
|
||||||
|
help: Please install with `sudo yum install pkgconf-pkg-config` and try again
|
||||||
|
- name: npm
|
||||||
|
help: Please install `sudo yum install nodejs` and try again
|
||||||
|
libraries:
|
||||||
|
- name: gtk3-devel
|
||||||
|
help: Please install with `sudo yum install gtk3-devel` and try again
|
||||||
|
- name: webkit2gtk3-devel
|
||||||
|
help: Please install with `sudo yum install webkit2gtk3-devel` and try again
|
||||||
|
arch:
|
||||||
|
id: arch
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Arch Linux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: &archdefaultprograms
|
||||||
|
- name: gcc
|
||||||
|
help: Please install with `sudo pacman -S gcc` and try again
|
||||||
|
- name: pkgconf
|
||||||
|
help: Please install with `sudo pacman -S pkgconf` and try again
|
||||||
|
- name: npm
|
||||||
|
help: Please install with `sudo pacman -S npm` and try again
|
||||||
|
libraries: &archdefaultlibraries
|
||||||
|
- name: gtk3
|
||||||
|
help: Please install with `sudo pacman -S gtk3` and try again
|
||||||
|
- name: webkit2gtk
|
||||||
|
help: Please install with `sudo pacman -S webkit2gtk` and try again
|
||||||
|
arcolinux:
|
||||||
|
id: arcolinux
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: ArcoLinux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *archdefaultprograms
|
||||||
|
libraries: *archdefaultlibraries
|
||||||
|
archlabs:
|
||||||
|
id: archlabs
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: ArchLabs
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *archdefaultprograms
|
||||||
|
libraries: *archdefaultlibraries
|
||||||
|
ctlos:
|
||||||
|
id: ctlos
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Ctlos Linux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *archdefaultprograms
|
||||||
|
libraries: *archdefaultlibraries
|
||||||
|
manjaro:
|
||||||
|
id: manjaro
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Manjaro Linux
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *archdefaultprograms
|
||||||
|
libraries: *archdefaultlibraries
|
||||||
|
manjaro-arm:
|
||||||
|
id: manjaro-arm
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Manjaro-ARM
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs: *archdefaultprograms
|
||||||
|
libraries: *archdefaultlibraries
|
||||||
|
gentoo:
|
||||||
|
id: gentoo
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Gentoo
|
||||||
|
gccversioncommand: *gccdumpversion
|
||||||
|
programs:
|
||||||
|
- name: gcc
|
||||||
|
help: Please install using your system's package manager
|
||||||
|
- name: pkg-config
|
||||||
|
help: Please install using your system's package manager
|
||||||
|
- name: npm
|
||||||
|
help: Please install using your system's package manager
|
||||||
|
libraries:
|
||||||
|
- name: gtk+:3
|
||||||
|
help: Please install with `sudo emerge gtk+:3` and try again
|
||||||
|
- name: webkit-gtk
|
||||||
|
help: Please install with `sudo emerge webkit-gtk` and try again
|
||||||
|
|
||||||
|
raspbian:
|
||||||
|
id: raspbian
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Raspbian
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: *debiandefaultprograms
|
||||||
|
libraries: *debiandefaultlibraries
|
||||||
|
solus:
|
||||||
|
id: solus
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: Solus
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: &solusdefaultprograms
|
||||||
|
- name: gcc
|
||||||
|
help: Please install with `sudo eopkg it -c system.devel` and try again
|
||||||
|
- name: pkg-config
|
||||||
|
help: Please install with `sudo eopkg it -c system.devel` and try again
|
||||||
|
- name: npm
|
||||||
|
help: Please install with `sudo eopkg it nodejs` and try again
|
||||||
|
libraries: &solusdefaultlibraries
|
||||||
|
- name: libgtk-3-devel
|
||||||
|
help: Please install with `sudo eopkg it libgtk-3-devel` and try again
|
||||||
|
- name: libwebkit-gtk-devel
|
||||||
|
help: Please install with `sudo eopkg it libwebkit-gtk-devel` and try again
|
||||||
|
|
||||||
|
opensuse-tumbleweed:
|
||||||
|
id: opensuse-tumbleweed
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: openSUSE Tumbleweed
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: &opensusedefaultprograms
|
||||||
|
- name: gcc
|
||||||
|
help: Please install with `sudo zypper in gcc-c++` and try again
|
||||||
|
- name: pkg-config
|
||||||
|
help: Please install with `sudo zypper in pkgconf-pkg-config` and try again
|
||||||
|
- name: npm
|
||||||
|
help: Please install `sudo zypper in nodejs` and try again
|
||||||
|
libraries: &opensusedefaultlibraries
|
||||||
|
- name: gtk3-devel
|
||||||
|
help: Please install with `sudo zypper in gtk3-devel` and try again
|
||||||
|
- name: webkit2gtk3-devel
|
||||||
|
help: Please install with `sudo zypper in webkit2gtk3-devel` and try again
|
||||||
|
opensuse-leap:
|
||||||
|
id: opensuse-leap
|
||||||
|
releases:
|
||||||
|
default:
|
||||||
|
version: default
|
||||||
|
name: openSUSE Leap
|
||||||
|
gccversioncommand: *gccdumpfullversion
|
||||||
|
programs: *opensusedefaultprograms
|
||||||
|
libraries: *opensusedefaultlibraries
|
||||||
81
cmd/linuxdb_test.go
Normal file
81
cmd/linuxdb_test.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestNewLinuxDB(t *testing.T) {
|
||||||
|
_ = NewLinuxDB()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKnownDistro(t *testing.T) {
|
||||||
|
var linuxDB = NewLinuxDB()
|
||||||
|
result := linuxDB.GetDistro("ubuntu")
|
||||||
|
if result == nil {
|
||||||
|
t.Error("Cannot get distro 'ubuntu'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnknownDistro(t *testing.T) {
|
||||||
|
var linuxDB = NewLinuxDB()
|
||||||
|
result := linuxDB.GetDistro("unknown")
|
||||||
|
if result != nil {
|
||||||
|
t.Error("Should get nil for distribution 'unknown'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultRelease(t *testing.T) {
|
||||||
|
var linuxDB = NewLinuxDB()
|
||||||
|
result := linuxDB.GetDistro("ubuntu")
|
||||||
|
if result == nil {
|
||||||
|
t.Error("Cannot get distro 'ubuntu'")
|
||||||
|
}
|
||||||
|
|
||||||
|
release := result.GetRelease("default")
|
||||||
|
if release == nil {
|
||||||
|
t.Error("Cannot get release 'default' for distro 'ubuntu'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnknownRelease(t *testing.T) {
|
||||||
|
var linuxDB = NewLinuxDB()
|
||||||
|
result := linuxDB.GetDistro("ubuntu")
|
||||||
|
if result == nil {
|
||||||
|
t.Error("Cannot get distro 'ubuntu'")
|
||||||
|
}
|
||||||
|
|
||||||
|
release := result.GetRelease("16.04")
|
||||||
|
if release == nil {
|
||||||
|
t.Error("Failed to get release 'default' for unknown release version '16.04'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if release.Version != "default" {
|
||||||
|
t.Errorf("Got version '%s' instead of 'default' for unknown release version '16.04'", result.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetPrerequisites(t *testing.T) {
|
||||||
|
var linuxDB = NewLinuxDB()
|
||||||
|
result := linuxDB.GetDistro("debian")
|
||||||
|
if result == nil {
|
||||||
|
t.Error("Cannot get distro 'debian'")
|
||||||
|
}
|
||||||
|
|
||||||
|
release := result.GetRelease("default")
|
||||||
|
if release == nil {
|
||||||
|
t.Error("Failed to get release 'default' for unknown release version '16.04'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if release.Version != "default" {
|
||||||
|
t.Errorf("Got version '%s' instead of 'default' for unknown release version '16.04'", result.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if release.Name != "Debian" {
|
||||||
|
t.Errorf("Got Release Name '%s' instead of 'debian' for unknown release version '16.04'", release.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(release.Programs) != 3 {
|
||||||
|
t.Errorf("Expected %d programs for unknown release version '16.04'", len(release.Programs))
|
||||||
|
}
|
||||||
|
if len(release.Libraries) != 2 {
|
||||||
|
t.Errorf("Expected %d libraries for unknown release version '16.04'", len(release.Libraries))
|
||||||
|
}
|
||||||
|
}
|
||||||
291
cmd/package.go
291
cmd/package.go
@@ -1,9 +1,12 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"image/png"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -14,21 +17,24 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackmordaunt/icns"
|
"github.com/jackmordaunt/icns"
|
||||||
|
"golang.org/x/image/draw"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageHelper helps with the 'wails package' command
|
// PackageHelper helps with the 'wails package' command
|
||||||
type PackageHelper struct {
|
type PackageHelper struct {
|
||||||
fs *FSHelper
|
platform string
|
||||||
log *Logger
|
fs *FSHelper
|
||||||
system *SystemHelper
|
log *Logger
|
||||||
|
system *SystemHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPackageHelper creates a new PackageHelper!
|
// NewPackageHelper creates a new PackageHelper!
|
||||||
func NewPackageHelper() *PackageHelper {
|
func NewPackageHelper(platform string) *PackageHelper {
|
||||||
return &PackageHelper{
|
return &PackageHelper{
|
||||||
fs: NewFSHelper(),
|
platform: platform,
|
||||||
log: NewLogger(),
|
fs: NewFSHelper(),
|
||||||
system: NewSystemHelper(),
|
log: NewLogger(),
|
||||||
|
system: NewSystemHelper(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +59,111 @@ func newPlistData(title, exe, packageID, version, author string) *plistData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type windowsIcoHeader struct {
|
||||||
|
_ uint16
|
||||||
|
imageType uint16
|
||||||
|
imageCount uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type windowsIcoDescriptor struct {
|
||||||
|
width uint8
|
||||||
|
height uint8
|
||||||
|
colours uint8
|
||||||
|
_ uint8
|
||||||
|
planes uint16
|
||||||
|
bpp uint16
|
||||||
|
size uint32
|
||||||
|
offset uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type windowsIcoContainer struct {
|
||||||
|
Header windowsIcoDescriptor
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateWindowsIcon(pngFilename string, iconfile string) error {
|
||||||
|
sizes := []int{256, 128, 64, 48, 32, 16}
|
||||||
|
|
||||||
|
pngfile, err := os.Open(pngFilename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer pngfile.Close()
|
||||||
|
|
||||||
|
pngdata, err := png.Decode(pngfile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
icons := []windowsIcoContainer{}
|
||||||
|
|
||||||
|
for _, size := range sizes {
|
||||||
|
rect := image.Rect(0, 0, int(size), int(size))
|
||||||
|
rawdata := image.NewRGBA(rect)
|
||||||
|
scale := draw.CatmullRom
|
||||||
|
scale.Scale(rawdata, rect, pngdata, pngdata.Bounds(), draw.Over, nil)
|
||||||
|
|
||||||
|
icondata := new(bytes.Buffer)
|
||||||
|
writer := bufio.NewWriter(icondata)
|
||||||
|
err = png.Encode(writer, rawdata)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
writer.Flush()
|
||||||
|
|
||||||
|
imgSize := size
|
||||||
|
if imgSize >= 256 {
|
||||||
|
imgSize = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
data := icondata.Bytes()
|
||||||
|
|
||||||
|
icn := windowsIcoContainer{
|
||||||
|
Header: windowsIcoDescriptor{
|
||||||
|
width: uint8(imgSize),
|
||||||
|
height: uint8(imgSize),
|
||||||
|
planes: 1,
|
||||||
|
bpp: 32,
|
||||||
|
size: uint32(len(data)),
|
||||||
|
},
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
icons = append(icons, icn)
|
||||||
|
}
|
||||||
|
|
||||||
|
outfile, err := os.Create(iconfile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer outfile.Close()
|
||||||
|
|
||||||
|
ico := windowsIcoHeader{
|
||||||
|
imageType: 1,
|
||||||
|
imageCount: uint16(len(sizes)),
|
||||||
|
}
|
||||||
|
err = binary.Write(outfile, binary.LittleEndian, ico)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := uint32(6 + 16*len(sizes))
|
||||||
|
for _, icon := range icons {
|
||||||
|
icon.Header.offset = offset
|
||||||
|
err = binary.Write(outfile, binary.LittleEndian, icon.Header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
offset += icon.Header.size
|
||||||
|
}
|
||||||
|
for _, icon := range icons {
|
||||||
|
_, err = outfile.Write(icon.Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func defaultString(val string, defaultVal string) string {
|
func defaultString(val string, defaultVal string) string {
|
||||||
if val != "" {
|
if val != "" {
|
||||||
return val
|
return val
|
||||||
@@ -63,29 +174,30 @@ func defaultString(val string, defaultVal string) string {
|
|||||||
func (b *PackageHelper) getPackageFileBaseDir() string {
|
func (b *PackageHelper) getPackageFileBaseDir() string {
|
||||||
// Calculate template base dir
|
// Calculate template base dir
|
||||||
_, filename, _, _ := runtime.Caller(1)
|
_, filename, _, _ := runtime.Caller(1)
|
||||||
return filepath.Join(path.Dir(filename), "packages", runtime.GOOS)
|
return filepath.Join(path.Dir(filename), "packages", b.platform)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package the application into a platform specific package
|
// Package the application into a platform specific package
|
||||||
func (b *PackageHelper) Package(po *ProjectOptions) error {
|
func (b *PackageHelper) Package(po *ProjectOptions) error {
|
||||||
switch runtime.GOOS {
|
switch b.platform {
|
||||||
case "darwin":
|
case "darwin":
|
||||||
// Check we have the exe
|
|
||||||
if !b.fs.FileExists(po.BinaryName) {
|
|
||||||
return fmt.Errorf("cannot bundle non-existent binary file '%s'. Please build with 'wails build' first", po.BinaryName)
|
|
||||||
}
|
|
||||||
return b.packageOSX(po)
|
return b.packageOSX(po)
|
||||||
case "windows":
|
case "windows":
|
||||||
return b.PackageWindows(po, false)
|
return b.PackageWindows(po, true)
|
||||||
case "linux":
|
case "linux":
|
||||||
return fmt.Errorf("linux is not supported at this time. Please see https://github.com/wailsapp/wails/issues/2")
|
return b.packageLinux(po)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("platform '%s' not supported for bundling yet", runtime.GOOS)
|
return fmt.Errorf("platform '%s' not supported for bundling yet", b.platform)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *PackageHelper) packageLinux(po *ProjectOptions) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Package the application for OSX
|
// Package the application for OSX
|
||||||
func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
||||||
|
build := path.Join(b.fs.Cwd(), "build")
|
||||||
|
|
||||||
system := NewSystemHelper()
|
system := NewSystemHelper()
|
||||||
config, err := system.LoadConfig()
|
config, err := system.LoadConfig()
|
||||||
@@ -100,39 +212,68 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
|||||||
packageID := strings.Join([]string{"wails", name, version}, ".")
|
packageID := strings.Join([]string{"wails", name, version}, ".")
|
||||||
plistData := newPlistData(name, exe, packageID, version, author)
|
plistData := newPlistData(name, exe, packageID, version, author)
|
||||||
appname := po.Name + ".app"
|
appname := po.Name + ".app"
|
||||||
|
plistFilename := path.Join(build, appname, "Contents", "Info.plist")
|
||||||
|
customPlist := path.Join(b.fs.Cwd(), "info.plist")
|
||||||
|
|
||||||
// Check binary exists
|
// Check binary exists
|
||||||
source := path.Join(b.fs.Cwd(), exe)
|
source := path.Join(build, exe)
|
||||||
if !b.fs.FileExists(source) {
|
if po.CrossCompile == true {
|
||||||
// We need to build!
|
file, err := b.fs.FindFile(build, "darwin")
|
||||||
return fmt.Errorf("Target '%s' not available. Has it been compiled yet?", exe)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
source = path.Join(build, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !b.fs.FileExists(source) {
|
||||||
|
// We need to build!
|
||||||
|
return fmt.Errorf("Target '%s' not available. Has it been compiled yet?", source)
|
||||||
|
}
|
||||||
// Remove the existing package
|
// Remove the existing package
|
||||||
os.RemoveAll(appname)
|
os.RemoveAll(appname)
|
||||||
|
|
||||||
exeDir := path.Join(b.fs.Cwd(), appname, "/Contents/MacOS")
|
// Create directories
|
||||||
|
exeDir := path.Join(build, appname, "/Contents/MacOS")
|
||||||
b.fs.MkDirs(exeDir, 0755)
|
b.fs.MkDirs(exeDir, 0755)
|
||||||
resourceDir := path.Join(b.fs.Cwd(), appname, "/Contents/Resources")
|
resourceDir := path.Join(build, appname, "/Contents/Resources")
|
||||||
b.fs.MkDirs(resourceDir, 0755)
|
b.fs.MkDirs(resourceDir, 0755)
|
||||||
tmpl := template.New("infoPlist")
|
|
||||||
plistFile := filepath.Join(b.getPackageFileBaseDir(), "info.plist")
|
|
||||||
infoPlist, err := ioutil.ReadFile(plistFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tmpl.Parse(string(infoPlist))
|
|
||||||
|
|
||||||
// Write the template to a buffer
|
// Do we have a custom plist in the project directory?
|
||||||
var tpl bytes.Buffer
|
if !fs.FileExists(customPlist) {
|
||||||
err = tmpl.Execute(&tpl, plistData)
|
|
||||||
if err != nil {
|
// No - create a new plist from our defaults
|
||||||
return err
|
tmpl := template.New("infoPlist")
|
||||||
}
|
plistFile := filepath.Join(b.getPackageFileBaseDir(), "info.plist")
|
||||||
filename := path.Join(b.fs.Cwd(), appname, "Contents", "Info.plist")
|
infoPlist, err := ioutil.ReadFile(plistFile)
|
||||||
err = ioutil.WriteFile(filename, tpl.Bytes(), 0644)
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
|
tmpl.Parse(string(infoPlist))
|
||||||
|
|
||||||
|
// Write the template to a buffer
|
||||||
|
var tpl bytes.Buffer
|
||||||
|
err = tmpl.Execute(&tpl, plistData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save to the package
|
||||||
|
err = ioutil.WriteFile(plistFilename, tpl.Bytes(), 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also write to project directory for customisation
|
||||||
|
err = ioutil.WriteFile(customPlist, tpl.Bytes(), 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Yes - we have a plist. Copy it to the package verbatim
|
||||||
|
err = fs.CopyFile(customPlist, plistFilename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy executable
|
// Copy executable
|
||||||
@@ -150,22 +291,37 @@ func (b *PackageHelper) packageOSX(po *ProjectOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CleanWindows removes any windows related files found in the directory
|
||||||
|
func (b *PackageHelper) CleanWindows(po *ProjectOptions) {
|
||||||
|
pdir := b.fs.Cwd()
|
||||||
|
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
||||||
|
exts := []string{".ico", ".exe.manifest", ".rc", "-res.syso"}
|
||||||
|
rsrcs := []string{}
|
||||||
|
for _, ext := range exts {
|
||||||
|
rsrcs = append(rsrcs, filepath.Join(pdir, basename+ext))
|
||||||
|
}
|
||||||
|
b.fs.RemoveFiles(rsrcs, true)
|
||||||
|
}
|
||||||
|
|
||||||
// PackageWindows packages the application for windows platforms
|
// 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 {
|
||||||
|
outputDir := b.fs.Cwd()
|
||||||
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
basename := strings.TrimSuffix(po.BinaryName, ".exe")
|
||||||
|
|
||||||
// Copy icon
|
// Copy default icon if needed
|
||||||
tgtIconFile := filepath.Join(b.fs.Cwd(), basename+".ico")
|
icon, err := b.copyIcon()
|
||||||
if !b.fs.FileExists(tgtIconFile) {
|
if err != nil {
|
||||||
srcIconfile := filepath.Join(b.getPackageFileBaseDir(), "wails.ico")
|
return err
|
||||||
err := b.fs.CopyFile(srcIconfile, tgtIconFile)
|
}
|
||||||
if err != nil {
|
|
||||||
return err
|
// Generate icon from PNG
|
||||||
}
|
err = generateWindowsIcon(icon, basename+".ico")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy manifest
|
// Copy manifest
|
||||||
tgtManifestFile := filepath.Join(b.fs.Cwd(), basename+".exe.manifest")
|
tgtManifestFile := filepath.Join(outputDir, basename+".exe.manifest")
|
||||||
if !b.fs.FileExists(tgtManifestFile) {
|
if !b.fs.FileExists(tgtManifestFile) {
|
||||||
srcManifestfile := filepath.Join(b.getPackageFileBaseDir(), "wails.exe.manifest")
|
srcManifestfile := filepath.Join(b.getPackageFileBaseDir(), "wails.exe.manifest")
|
||||||
err := b.fs.CopyFile(srcManifestfile, tgtManifestFile)
|
err := b.fs.CopyFile(srcManifestfile, tgtManifestFile)
|
||||||
@@ -175,7 +331,7 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy rc file
|
// Copy rc file
|
||||||
tgtRCFile := filepath.Join(b.fs.Cwd(), basename+".rc")
|
tgtRCFile := filepath.Join(outputDir, basename+".rc")
|
||||||
if !b.fs.FileExists(tgtRCFile) {
|
if !b.fs.FileExists(tgtRCFile) {
|
||||||
srcRCfile := filepath.Join(b.getPackageFileBaseDir(), "wails.rc")
|
srcRCfile := filepath.Join(b.getPackageFileBaseDir(), "wails.rc")
|
||||||
rcfilebytes, err := ioutil.ReadFile(srcRCfile)
|
rcfilebytes, err := ioutil.ReadFile(srcRCfile)
|
||||||
@@ -190,26 +346,37 @@ func (b *PackageHelper) PackageWindows(po *ProjectOptions, cleanUp bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build syso
|
// Build syso
|
||||||
sysofile := filepath.Join(b.fs.Cwd(), basename+"-res.syso")
|
sysofile := filepath.Join(outputDir, basename+"-res.syso")
|
||||||
windresCommand := []string{"windres", "-o", sysofile, tgtRCFile}
|
|
||||||
err := NewProgramHelper().RunCommandArray(windresCommand)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up
|
// cross-compile
|
||||||
if cleanUp {
|
if b.platform != runtime.GOOS {
|
||||||
filesToDelete := []string{tgtIconFile, tgtManifestFile, tgtRCFile, sysofile}
|
args := []string{
|
||||||
err := b.fs.RemoveFiles(filesToDelete)
|
"docker", "run", "--rm",
|
||||||
|
"-v", outputDir + ":/build",
|
||||||
|
"--entrypoint", "/bin/sh",
|
||||||
|
"wailsapp/xgo:latest",
|
||||||
|
"-c", "/usr/bin/x86_64-w64-mingw32-windres -o /build/" + basename + "-res.syso /build/" + basename + ".rc",
|
||||||
|
}
|
||||||
|
if err := NewProgramHelper().RunCommandArray(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
batfile, err := fs.LocalDir(".")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
windresBatFile := filepath.Join(batfile.fullPath, "windres.bat")
|
||||||
|
windresCommand := []string{windresBatFile, sysofile, tgtRCFile}
|
||||||
|
err = NewProgramHelper().RunCommandArray(windresCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *PackageHelper) copyIcon(resourceDir string) (string, error) {
|
func (b *PackageHelper) copyIcon() (string, error) {
|
||||||
|
|
||||||
// TODO: Read this from project.json
|
// TODO: Read this from project.json
|
||||||
const appIconFilename = "appicon.png"
|
const appIconFilename = "appicon.png"
|
||||||
@@ -234,7 +401,7 @@ func (b *PackageHelper) copyIcon(resourceDir string) (string, error) {
|
|||||||
|
|
||||||
func (b *PackageHelper) packageIconOSX(resourceDir string) error {
|
func (b *PackageHelper) packageIconOSX(resourceDir string) error {
|
||||||
|
|
||||||
srcIcon, err := b.copyIcon(resourceDir)
|
srcIcon, err := b.copyIcon()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0"><dict>
|
<plist version="1.0"><dict>
|
||||||
|
<key>CFBundlePackageType</key><string>APPL</string>
|
||||||
<key>CFBundleName</key><string>{{.Title}}</string>
|
<key>CFBundleName</key><string>{{.Title}}</string>
|
||||||
<key>CFBundleExecutable</key><string>{{.Exe}}</string>
|
<key>CFBundleExecutable</key><string>{{.Exe}}</string>
|
||||||
<key>CFBundleIdentifier</key><string>{{.PackageID}}</string>
|
<key>CFBundleIdentifier</key><string>{{.PackageID}}</string>
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
100 ICON "$NAME$.ico"
|
100 ICON "$NAME$.ico"
|
||||||
100 24 "$NAME$.exe.manifest"
|
110 24 "$NAME$.exe.manifest"
|
||||||
@@ -5,13 +5,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Prerequisite defines a Prerequisite!
|
|
||||||
type Prerequisite struct {
|
|
||||||
Name string
|
|
||||||
Help string
|
|
||||||
Path string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPrerequisite(name, help string) *Prerequisite {
|
func newPrerequisite(name, help string) *Prerequisite {
|
||||||
return &Prerequisite{Name: name, Help: help}
|
return &Prerequisite{Name: name, Help: help}
|
||||||
}
|
}
|
||||||
@@ -48,16 +41,13 @@ func getRequiredProgramsOSX() *Prerequisites {
|
|||||||
func getRequiredProgramsLinux() *Prerequisites {
|
func getRequiredProgramsLinux() *Prerequisites {
|
||||||
result := &Prerequisites{}
|
result := &Prerequisites{}
|
||||||
distroInfo := GetLinuxDistroInfo()
|
distroInfo := GetLinuxDistroInfo()
|
||||||
switch distroInfo.Distribution {
|
if distroInfo.Distribution != Unknown {
|
||||||
case Ubuntu, Debian, Zorin:
|
var linuxDB = NewLinuxDB()
|
||||||
result.Add(newPrerequisite("gcc", "Please install with `sudo apt install build-essentials` and try again"))
|
distro := linuxDB.GetDistro(distroInfo.ID)
|
||||||
result.Add(newPrerequisite("pkg-config", "Please install with `sudo apt install pkg-config` and try again"))
|
release := distro.GetRelease(distroInfo.Release)
|
||||||
result.Add(newPrerequisite("npm", "Please install with `sudo snap install node --channel=12/stable --classic` and try again"))
|
for _, program := range release.Programs {
|
||||||
default:
|
result.Add(program)
|
||||||
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"))
|
|
||||||
result.Add(newPrerequisite("npm", "Please install from https://nodejs.org/en/download/ and try again"))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -91,23 +81,15 @@ func getRequiredLibrariesOSX() (*Prerequisites, error) {
|
|||||||
|
|
||||||
func getRequiredLibrariesLinux() (*Prerequisites, error) {
|
func getRequiredLibrariesLinux() (*Prerequisites, error) {
|
||||||
result := &Prerequisites{}
|
result := &Prerequisites{}
|
||||||
|
// The Linux Distribution DB
|
||||||
distroInfo := GetLinuxDistroInfo()
|
distroInfo := GetLinuxDistroInfo()
|
||||||
switch distroInfo.Distribution {
|
if distroInfo.Distribution != Unknown {
|
||||||
case Ubuntu, Debian, Zorin:
|
var linuxDB = NewLinuxDB()
|
||||||
result.Add(newPrerequisite("libgtk-3-dev", "Please install with `sudo apt install libgtk-3-dev` and try again"))
|
distro := linuxDB.GetDistro(distroInfo.ID)
|
||||||
result.Add(newPrerequisite("libwebkit2gtk-4.0-dev", "Please install with `sudo apt install libwebkit2gtk-4.0-dev` and try again"))
|
release := distro.GetRelease(distroInfo.Release)
|
||||||
case Gentoo:
|
for _, library := range release.Libraries {
|
||||||
result.Add(newPrerequisite("gtk+:3", "Please install with `sudo emerge gtk+:3` and try again"))
|
result.Add(library)
|
||||||
result.Add(newPrerequisite("webkit-gtk", "Please install with `sudo emerge webkit-gtk` and try again"))
|
}
|
||||||
case Arch:
|
|
||||||
result.Add(newPrerequisite("gtk3", "Please install with `sudo pacman -S gtk3` and try again"))
|
|
||||||
result.Add(newPrerequisite("webkit2gtk", "Please install with `sudo pacman -S webkit2gtk` and try again"))
|
|
||||||
case RedHat:
|
|
||||||
result.Add(newPrerequisite("gtk3-devel", "Please install with `sudo yum install gtk3-devel` and try again"))
|
|
||||||
result.Add(newPrerequisite("webkit2gtk3-devel", "Please install with `sudo yum install webkit2gtk3-devel` and try again"))
|
|
||||||
default:
|
|
||||||
result.Add(newPrerequisite("libgtk-3-dev", "Please install with your system package manager and try again"))
|
|
||||||
result.Add(newPrerequisite("libwebkit2gtk-4.0-dev", "Please install with your system package manager and try again"))
|
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -11,14 +12,22 @@ import (
|
|||||||
|
|
||||||
// ProgramHelper - Utility functions around installed applications
|
// ProgramHelper - Utility functions around installed applications
|
||||||
type ProgramHelper struct {
|
type ProgramHelper struct {
|
||||||
shell *ShellHelper
|
shell *ShellHelper
|
||||||
|
verbose bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProgramHelper - Creates a new ProgramHelper
|
// NewProgramHelper - Creates a new ProgramHelper
|
||||||
func NewProgramHelper() *ProgramHelper {
|
func NewProgramHelper(verbose ...bool) *ProgramHelper {
|
||||||
return &ProgramHelper{
|
result := &ProgramHelper{
|
||||||
shell: NewShellHelper(),
|
shell: NewShellHelper(),
|
||||||
}
|
}
|
||||||
|
if len(verbose) > 0 {
|
||||||
|
result.verbose = verbose[0]
|
||||||
|
if result.verbose {
|
||||||
|
result.shell.SetVerbose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInstalled tries to determine if the given binary name is installed
|
// IsInstalled tries to determine if the given binary name is installed
|
||||||
@@ -29,8 +38,9 @@ func (p *ProgramHelper) IsInstalled(programName string) bool {
|
|||||||
|
|
||||||
// Program - A struct to define an installed application/binary
|
// Program - A struct to define an installed application/binary
|
||||||
type Program struct {
|
type Program struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
|
verbose bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindProgram attempts to find the given program on the system.FindProgram
|
// FindProgram attempts to find the given program on the system.FindProgram
|
||||||
@@ -45,8 +55,9 @@ func (p *ProgramHelper) FindProgram(programName string) *Program {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &Program{
|
return &Program{
|
||||||
Name: programName,
|
Name: programName,
|
||||||
Path: path,
|
Path: path,
|
||||||
|
verbose: p.verbose,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,12 +74,18 @@ func (p *Program) Run(vars ...string) (stdout, stderr string, exitCode int, err
|
|||||||
return "", "", 1, err
|
return "", "", 1, err
|
||||||
}
|
}
|
||||||
cmd := exec.Command(command, vars...)
|
cmd := exec.Command(command, vars...)
|
||||||
var stdo, stde bytes.Buffer
|
if !p.verbose {
|
||||||
cmd.Stdout = &stdo
|
var stdo, stde bytes.Buffer
|
||||||
cmd.Stderr = &stde
|
cmd.Stdout = &stdo
|
||||||
err = cmd.Run()
|
cmd.Stderr = &stde
|
||||||
stdout = string(stdo.Bytes())
|
err = cmd.Run()
|
||||||
stderr = string(stde.Bytes())
|
stdout = string(stdo.Bytes())
|
||||||
|
stderr = string(stde.Bytes())
|
||||||
|
} else {
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
err = cmd.Run()
|
||||||
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/10385551/get-exit-code-go
|
// https://stackoverflow.com/questions/10385551/get-exit-code-go
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -100,6 +117,19 @@ func (p *ProgramHelper) InstallGoPackage(packageName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InstallNPMPackage installs the given npm package
|
||||||
|
func (p *ProgramHelper) InstallNPMPackage(packageName string, save bool) error {
|
||||||
|
args := strings.Split("install "+packageName, " ")
|
||||||
|
if save {
|
||||||
|
args = append(args, "--save")
|
||||||
|
}
|
||||||
|
_, stderr, err := p.shell.Run("npm", args...)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(stderr)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// RunCommand runs the given command
|
// RunCommand runs the given command
|
||||||
func (p *ProgramHelper) RunCommand(command string) error {
|
func (p *ProgramHelper) RunCommand(command string) error {
|
||||||
args := strings.Split(command, " ")
|
args := strings.Split(command, " ")
|
||||||
@@ -108,23 +138,25 @@ func (p *ProgramHelper) RunCommand(command string) error {
|
|||||||
|
|
||||||
// RunCommandArray runs the command specified in the array
|
// RunCommandArray runs the command specified in the array
|
||||||
func (p *ProgramHelper) RunCommandArray(args []string, dir ...string) error {
|
func (p *ProgramHelper) RunCommandArray(args []string, dir ...string) error {
|
||||||
program := args[0]
|
programCommand := args[0]
|
||||||
// TODO: Run FindProgram here and get the full path to the exe
|
// TODO: Run FindProgram here and get the full path to the exe
|
||||||
program, err := exec.LookPath(program)
|
program, err := exec.LookPath(programCommand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: Looks like '%s' isn't installed. Please install and try again.", program)
|
fmt.Printf("ERROR: Looks like '%s' isn't installed. Please install and try again.", programCommand)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
var stderr string
|
var stderr string
|
||||||
// fmt.Printf("RunCommandArray = %s %+v\n", program, args)
|
var stdout string
|
||||||
if len(dir) > 0 {
|
if len(dir) > 0 {
|
||||||
_, stderr, err = p.shell.RunInDirectory(dir[0], program, args...)
|
stdout, stderr, err = p.shell.RunInDirectory(dir[0], program, args...)
|
||||||
} else {
|
} else {
|
||||||
_, stderr, err = p.shell.Run(program, args...)
|
stdout, stderr, err = p.shell.Run(program, args...)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(stderr)
|
fmt.Println(stderr)
|
||||||
|
fmt.Println(stdout)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,24 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/leaanthony/slicer"
|
"github.com/leaanthony/slicer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PackageManager indicates different package managers
|
||||||
|
type PackageManager int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UNKNOWN package manager
|
||||||
|
UNKNOWN PackageManager = iota
|
||||||
|
// NPM package manager
|
||||||
|
NPM
|
||||||
|
// YARN package manager
|
||||||
|
YARN
|
||||||
|
)
|
||||||
|
|
||||||
type author struct {
|
type author struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
@@ -112,9 +123,9 @@ func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
|
|||||||
Description: "Enter your project description",
|
Description: "Enter your project description",
|
||||||
Version: "0.1.0",
|
Version: "0.1.0",
|
||||||
BinaryName: "",
|
BinaryName: "",
|
||||||
system: NewSystemHelper(),
|
system: ph.system,
|
||||||
log: NewLogger(),
|
log: ph.log,
|
||||||
templates: NewTemplateHelper(),
|
templates: ph.templates,
|
||||||
Author: &author{},
|
Author: &author{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,21 +141,27 @@ func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
|
|||||||
|
|
||||||
// ProjectOptions holds all the options available for a project
|
// ProjectOptions holds all the options available for a project
|
||||||
type ProjectOptions struct {
|
type ProjectOptions struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Author *author `json:"author,omitempty"`
|
Author *author `json:"author,omitempty"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
OutputDirectory string `json:"-"`
|
OutputDirectory string `json:"-"`
|
||||||
UseDefaults bool `json:"-"`
|
UseDefaults bool `json:"-"`
|
||||||
Template string `json:"-"`
|
Template string `json:"-"`
|
||||||
BinaryName string `json:"binaryname"`
|
BinaryName string `json:"binaryname"`
|
||||||
FrontEnd *frontend `json:"frontend,omitempty"`
|
FrontEnd *frontend `json:"frontend,omitempty"`
|
||||||
NPMProjectName string `json:"-"`
|
NPMProjectName string `json:"-"`
|
||||||
system *SystemHelper
|
system *SystemHelper
|
||||||
log *Logger
|
log *Logger
|
||||||
templates *TemplateHelper
|
templates *TemplateHelper
|
||||||
selectedTemplate *TemplateDetails
|
selectedTemplate *TemplateDetails
|
||||||
WailsVersion string
|
WailsVersion string
|
||||||
|
typescriptDefsFilename string
|
||||||
|
Verbose bool `json:"-"`
|
||||||
|
CrossCompile bool
|
||||||
|
Platform string
|
||||||
|
Architecture string
|
||||||
|
LdFlags string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defaults sets the default project template
|
// Defaults sets the default project template
|
||||||
@@ -153,6 +170,28 @@ func (po *ProjectOptions) Defaults() {
|
|||||||
po.WailsVersion = Version
|
po.WailsVersion = Version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTypescriptDefsFilename indicates that we want to generate typescript bindings to the given file
|
||||||
|
func (po *ProjectOptions) SetTypescriptDefsFilename(filename string) {
|
||||||
|
po.typescriptDefsFilename = filename
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNPMBinaryName returns the type of package manager used by the project
|
||||||
|
func (po *ProjectOptions) GetNPMBinaryName() (PackageManager, error) {
|
||||||
|
if po.FrontEnd == nil {
|
||||||
|
return UNKNOWN, fmt.Errorf("No frontend specified in project options")
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Index(po.FrontEnd.Install, "npm") > -1 {
|
||||||
|
return NPM, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Index(po.FrontEnd.Install, "yarn") > -1 {
|
||||||
|
return YARN, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNKNOWN, nil
|
||||||
|
}
|
||||||
|
|
||||||
// PromptForInputs asks the user to input project details
|
// PromptForInputs asks the user to input project details
|
||||||
func (po *ProjectOptions) PromptForInputs() error {
|
func (po *ProjectOptions) PromptForInputs() error {
|
||||||
|
|
||||||
@@ -297,11 +336,6 @@ func processBinaryName(po *ProjectOptions) {
|
|||||||
if po.BinaryName == "" {
|
if po.BinaryName == "" {
|
||||||
var binaryNameComputed = computeBinaryName(po.Name)
|
var binaryNameComputed = computeBinaryName(po.Name)
|
||||||
po.BinaryName = Prompt("The output binary name", binaryNameComputed)
|
po.BinaryName = Prompt("The output binary name", binaryNameComputed)
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
if !strings.HasSuffix(po.BinaryName, ".exe") {
|
|
||||||
po.BinaryName += ".exe"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fmt.Println("Output binary Name: " + po.BinaryName)
|
fmt.Println("Output binary Name: " + po.BinaryName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -20,11 +19,7 @@ func Prompt(question string, defaultValue ...string) string {
|
|||||||
fmt.Printf(question + ": ")
|
fmt.Printf(question + ": ")
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
input, _ := reader.ReadString('\n')
|
input, _ := reader.ReadString('\n')
|
||||||
EOL := "\n"
|
input = strings.TrimSpace(input)
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
EOL = "\r\n"
|
|
||||||
}
|
|
||||||
input = strings.Replace(input, EOL, "", -1)
|
|
||||||
|
|
||||||
if input != "" {
|
if input != "" {
|
||||||
answer = input
|
answer = input
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/masterminds/semver"
|
"github.com/Masterminds/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SemanticVersion is a struct containing a semantic version
|
// SemanticVersion is a struct containing a semantic version
|
||||||
|
|||||||
42
cmd/shell.go
42
cmd/shell.go
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
// ShellHelper helps with Shell commands
|
// ShellHelper helps with Shell commands
|
||||||
type ShellHelper struct {
|
type ShellHelper struct {
|
||||||
|
verbose bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewShellHelper creates a new ShellHelper!
|
// NewShellHelper creates a new ShellHelper!
|
||||||
@@ -15,16 +16,27 @@ func NewShellHelper() *ShellHelper {
|
|||||||
return &ShellHelper{}
|
return &ShellHelper{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetVerbose sets the verbose flag
|
||||||
|
func (sh *ShellHelper) SetVerbose() {
|
||||||
|
sh.verbose = true
|
||||||
|
}
|
||||||
|
|
||||||
// Run the given command
|
// Run the given command
|
||||||
func (sh *ShellHelper) Run(command string, vars ...string) (stdout, stderr string, err error) {
|
func (sh *ShellHelper) Run(command string, vars ...string) (stdout, stderr string, err error) {
|
||||||
cmd := exec.Command(command, vars...)
|
cmd := exec.Command(command, vars...)
|
||||||
cmd.Env = append(os.Environ(), "GO111MODULE=on")
|
cmd.Env = append(os.Environ(), "GO111MODULE=on")
|
||||||
var stdo, stde bytes.Buffer
|
if !sh.verbose {
|
||||||
cmd.Stdout = &stdo
|
var stdo, stde bytes.Buffer
|
||||||
cmd.Stderr = &stde
|
cmd.Stdout = &stdo
|
||||||
err = cmd.Run()
|
cmd.Stderr = &stde
|
||||||
stdout = string(stdo.Bytes())
|
err = cmd.Run()
|
||||||
stderr = string(stde.Bytes())
|
stdout = string(stdo.Bytes())
|
||||||
|
stderr = string(stde.Bytes())
|
||||||
|
} else {
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
err = cmd.Run()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,11 +45,17 @@ func (sh *ShellHelper) RunInDirectory(dir string, command string, vars ...string
|
|||||||
cmd := exec.Command(command, vars...)
|
cmd := exec.Command(command, vars...)
|
||||||
cmd.Dir = dir
|
cmd.Dir = dir
|
||||||
cmd.Env = append(os.Environ(), "GO111MODULE=on")
|
cmd.Env = append(os.Environ(), "GO111MODULE=on")
|
||||||
var stdo, stde bytes.Buffer
|
if !sh.verbose {
|
||||||
cmd.Stdout = &stdo
|
var stdo, stde bytes.Buffer
|
||||||
cmd.Stderr = &stde
|
cmd.Stdout = &stdo
|
||||||
err = cmd.Run()
|
cmd.Stderr = &stde
|
||||||
stdout = string(stdo.Bytes())
|
err = cmd.Run()
|
||||||
stderr = string(stde.Bytes())
|
stdout = string(stdo.Bytes())
|
||||||
|
stderr = string(stde.Bytes())
|
||||||
|
} else {
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
err = cmd.Run()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
homedir "github.com/mitchellh/go-homedir"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SystemHelper - Defines everything related to the system
|
// SystemHelper - Defines everything related to the system
|
||||||
@@ -38,10 +37,11 @@ func NewSystemHelper() *SystemHelper {
|
|||||||
// setSystemDirs calculates the system directories it is interested in
|
// setSystemDirs calculates the system directories it is interested in
|
||||||
func (s *SystemHelper) setSystemDirs() {
|
func (s *SystemHelper) setSystemDirs() {
|
||||||
var err error
|
var err error
|
||||||
s.homeDir, err = homedir.Dir()
|
s.homeDir, err = os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Cannot find home directory! Please file a bug report!")
|
log.Fatal("Cannot find home directory! Please file a bug report!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: A better config system
|
// TODO: A better config system
|
||||||
s.wailsSystemDir = filepath.Join(s.homeDir, ".wails")
|
s.wailsSystemDir = filepath.Join(s.homeDir, ".wails")
|
||||||
s.wailsSystemConfig = filepath.Join(s.wailsSystemDir, s.configFilename)
|
s.wailsSystemConfig = filepath.Join(s.wailsSystemDir, s.configFilename)
|
||||||
@@ -132,7 +132,7 @@ func (s *SystemHelper) setup() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const introText = `
|
const introText = `
|
||||||
Wails is a lightweight framework for creating web-like desktop apps in Go.
|
Wails is a lightweight framework for creating web-like desktop apps in Go.
|
||||||
I'll need to ask you a few questions so I can fill in your project templates and then I will try and see if you have the correct dependencies installed. If you don't have the right tools installed, I'll try and suggest how to install them.
|
I'll need to ask you a few questions so I can fill in your project templates and then I will try and see if you have the correct dependencies installed. If you don't have the right tools installed, I'll try and suggest how to install them.
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -269,55 +269,37 @@ func CheckDependencies(logger *Logger) (bool, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var libraryChecker CheckPkgInstalled
|
||||||
distroInfo := GetLinuxDistroInfo()
|
distroInfo := GetLinuxDistroInfo()
|
||||||
|
|
||||||
|
switch distroInfo.Distribution {
|
||||||
|
case Ubuntu, Debian, Zorin, Parrot, Linuxmint, Elementary, Kali, Neon, Deepin, Raspbian, PopOS:
|
||||||
|
libraryChecker = DpkgInstalled
|
||||||
|
case Arch, ArcoLinux, ArchLabs, Ctlos, Manjaro, ManjaroARM:
|
||||||
|
libraryChecker = PacmanInstalled
|
||||||
|
case CentOS, Fedora, Tumbleweed, Leap:
|
||||||
|
libraryChecker = RpmInstalled
|
||||||
|
case Gentoo:
|
||||||
|
libraryChecker = EqueryInstalled
|
||||||
|
case VoidLinux:
|
||||||
|
libraryChecker = XbpsInstalled
|
||||||
|
case Solus:
|
||||||
|
libraryChecker = EOpkgInstalled
|
||||||
|
default:
|
||||||
|
return false, RequestSupportForDistribution(distroInfo)
|
||||||
|
}
|
||||||
|
|
||||||
for _, library := range *requiredLibraries {
|
for _, library := range *requiredLibraries {
|
||||||
switch distroInfo.Distribution {
|
installed, err := libraryChecker(library.Name)
|
||||||
case Ubuntu, Zorin, Debian:
|
if err != nil {
|
||||||
installed, err := DpkgInstalled(library.Name)
|
return false, err
|
||||||
if err != nil {
|
}
|
||||||
return false, err
|
if !installed {
|
||||||
}
|
errors = true
|
||||||
if !installed {
|
logger.Error("Library '%s' not found. %s", library.Name, library.Help)
|
||||||
errors = true
|
} else {
|
||||||
logger.Error("Library '%s' not found. %s", library.Name, library.Help)
|
logger.Green("Library '%s' installed.", library.Name)
|
||||||
} else {
|
|
||||||
logger.Green("Library '%s' installed.", library.Name)
|
|
||||||
}
|
|
||||||
case Arch:
|
|
||||||
installed, err := PacmanInstalled(library.Name)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if !installed {
|
|
||||||
errors = true
|
|
||||||
logger.Error("Library '%s' not found. %s", library.Name, library.Help)
|
|
||||||
} else {
|
|
||||||
logger.Green("Library '%s' installed.", library.Name)
|
|
||||||
}
|
|
||||||
case RedHat:
|
|
||||||
installed, err := RpmInstalled(library.Name)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if !installed {
|
|
||||||
errors = true
|
|
||||||
logger.Error("Library '%s' not found. %s", library.Name, library.Help)
|
|
||||||
} else {
|
|
||||||
logger.Green("Library '%s' installed.", library.Name)
|
|
||||||
}
|
|
||||||
case Gentoo:
|
|
||||||
installed, err := EqueryInstalled(library.Name)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if !installed {
|
|
||||||
errors = true
|
|
||||||
logger.Error("Library '%s' not found. %s", library.Name, library.Help)
|
|
||||||
} else {
|
|
||||||
logger.Green("Library '%s' installed.", library.Name)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false, RequestSupportForDistribution(distroInfo, library.Name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func NewTemplateHelper() *TemplateHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidTemplate returns true if the given tempalte name resides on disk
|
// IsValidTemplate returns true if the given template name resides on disk
|
||||||
func (t *TemplateHelper) IsValidTemplate(templateName string) bool {
|
func (t *TemplateHelper) IsValidTemplate(templateName string) bool {
|
||||||
pathToTemplate := filepath.Join(t.templateDir.fullPath, templateName)
|
pathToTemplate := filepath.Join(t.templateDir.fullPath, templateName)
|
||||||
return t.fs.DirExists(pathToTemplate)
|
return t.fs.DirExists(pathToTemplate)
|
||||||
|
|||||||
@@ -9,4 +9,4 @@
|
|||||||
last 2 versions
|
last 2 versions
|
||||||
Firefox ESR
|
Firefox ESR
|
||||||
not dead
|
not dead
|
||||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
IE 9-11 # For IE 9-11 support, remove 'not'.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "npx ng",
|
"ng": "npx ng",
|
||||||
"start": "npx ng serve --poll=2000",
|
"start": "npx ng serve --poll=2000 --host=0.0.0.0",
|
||||||
"build": "npx ng build --single-bundle true --output-hashing none --prod --bundle-styles false",
|
"build": "npx ng build --single-bundle true --output-hashing none --prod --bundle-styles false",
|
||||||
"test": "npx ng test",
|
"test": "npx ng test",
|
||||||
"lint": "npx ng lint",
|
"lint": "npx ng lint",
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
"@angular/platform-browser": "~8.0.1",
|
"@angular/platform-browser": "~8.0.1",
|
||||||
"@angular/platform-browser-dynamic": "~8.0.1",
|
"@angular/platform-browser-dynamic": "~8.0.1",
|
||||||
"@angular/router": "~8.0.1",
|
"@angular/router": "~8.0.1",
|
||||||
|
"@wailsapp/runtime": "^1.0.0",
|
||||||
|
"core-js": "^3.4.4",
|
||||||
"ngx-build-plus": "^8.0.3",
|
"ngx-build-plus": "^8.0.3",
|
||||||
"rxjs": "~6.4.0",
|
"rxjs": "~6.4.0",
|
||||||
"tslib": "^1.9.0",
|
"tslib": "^1.9.0",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'core-js/stable';
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
@@ -6,13 +7,13 @@ import { environment } from './environments/environment';
|
|||||||
|
|
||||||
import 'zone.js'
|
import 'zone.js'
|
||||||
|
|
||||||
import Bridge from './wailsbridge';
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
if (environment.production) {
|
if (environment.production) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
Bridge.Start(() => {
|
Wails.Init(() => {
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
.catch(err => console.error(err));
|
.catch(err => console.error(err));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
Wails Bridge (c) 2019-present Lea Anthony
|
|
||||||
|
|
||||||
This prod version is to get around having to rewrite your code
|
|
||||||
for production. When doing a release build, this file will be used
|
|
||||||
instead of the full version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// The main function
|
|
||||||
// Passes the main Wails object to the callback if given.
|
|
||||||
Start: function(callback) {
|
|
||||||
if (callback) {
|
|
||||||
window.wails.events.on("wails:ready", callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "es2015",
|
"target": "es5",
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"node_modules/@types"
|
"node_modules/@types"
|
||||||
],
|
],
|
||||||
@@ -20,4 +20,4 @@
|
|||||||
"dom"
|
"dom"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ func basic() string {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
js := mewn.String("./frontend/dist/my-app/main-es2015.js")
|
js := mewn.String("./frontend/dist/my-app/main.js")
|
||||||
css := mewn.String("./frontend/dist/my-app/styles.css")
|
css := mewn.String("./frontend/dist/my-app/styles.css")
|
||||||
|
|
||||||
app := wails.CreateApp(&wails.AppConfig{
|
app := wails.CreateApp(&wails.AppConfig{
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^16.8.6",
|
"core-js": "^3.6.4",
|
||||||
"react-dom": "^16.8.6",
|
"react": "^16.13.1",
|
||||||
|
"react-dom": "^16.13.1",
|
||||||
"wails-react-scripts": "3.0.1-2",
|
"wails-react-scripts": "3.0.1-2",
|
||||||
"react-modal": "3.8.1"
|
"react-modal": "3.11.2",
|
||||||
|
"@wailsapp/runtime": "^1.0.10"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -1,10 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta name="description" content="Web site created using create-react-app" />
|
||||||
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<!--
|
<!--
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
@@ -20,8 +23,9 @@
|
|||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>React App</title>
|
<title>React App</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<!--
|
<!--
|
||||||
@@ -34,5 +38,6 @@
|
|||||||
To begin the development, run `npm start` or `yarn start`.
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
-->
|
-->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
BIN
cmd/templates/create-react-app/frontend/public/logo192.png
Normal file
BIN
cmd/templates/create-react-app/frontend/public/logo192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
BIN
cmd/templates/create-react-app/frontend/public/logo512.png
Normal file
BIN
cmd/templates/create-react-app/frontend/public/logo512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 176 KiB |
@@ -6,6 +6,16 @@
|
|||||||
"src": "favicon.ico",
|
"src": "favicon.ico",
|
||||||
"sizes": "64x64 32x32 24x24 16x16",
|
"sizes": "64x64 32x32 24x24 16x16",
|
||||||
"type": "image/x-icon"
|
"type": "image/x-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "logo192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "logo512.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
@@ -3,11 +3,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.App-logo {
|
.App-logo {
|
||||||
animation: App-logo-spin infinite 20s linear;
|
|
||||||
height: 40vmin;
|
height: 40vmin;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
.App-logo {
|
||||||
|
animation: App-logo-spin infinite 20s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.App-header {
|
.App-header {
|
||||||
background-color: #282c34;
|
background-color: #282c34;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
|||||||
@@ -1,48 +1,35 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
|
|
||||||
class HelloWorld extends React.Component {
|
function HelloWorld() {
|
||||||
constructor(props, context) {
|
const [showModal, setShowModal] = useState(false);
|
||||||
super();
|
const [result, setResult] = useState(null);
|
||||||
this.state = {
|
|
||||||
showModal: false
|
|
||||||
};
|
|
||||||
|
|
||||||
this.handleOpenModal = this.handleOpenModal.bind(this);
|
const handleOpenModal = () => {
|
||||||
this.handleCloseModal = this.handleCloseModal.bind(this);
|
setShowModal(true);
|
||||||
}
|
|
||||||
|
|
||||||
handleOpenModal () {
|
window.backend.basic().then((result) => setResult(result));
|
||||||
this.setState({ showModal: true });
|
};
|
||||||
|
|
||||||
window.backend.basic().then(result =>
|
const handleCloseModal = () => {
|
||||||
this.setState({
|
setShowModal(false);
|
||||||
result
|
};
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleCloseModal () {
|
return (
|
||||||
this.setState({ showModal: false });
|
<div className="App">
|
||||||
}
|
<button onClick={() => handleOpenModal()} type="button">
|
||||||
|
Hello
|
||||||
render() {
|
</button>
|
||||||
const { result } = this.state;
|
<Modal
|
||||||
return (
|
appElement={document.getElementById("app")}
|
||||||
<div className="App">
|
isOpen={showModal}
|
||||||
<button onClick={this.handleOpenModal} type="button">
|
contentLabel="Minimal Modal Example"
|
||||||
Hello
|
>
|
||||||
</button>
|
<p>{result}</p>
|
||||||
<Modal
|
<button onClick={() => handleCloseModal()}>Close Modal</button>
|
||||||
isOpen={this.state.showModal}
|
</Modal>
|
||||||
contentLabel="Minimal Modal Example"
|
</div>
|
||||||
>
|
);
|
||||||
<p>{result}</p>
|
|
||||||
<button onClick={this.handleCloseModal}>Close Modal</button>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default HelloWorld;
|
export default HelloWorld;
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import 'core-js/stable';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
import * as serviceWorker from './serviceWorker';
|
||||||
|
|
||||||
import Bridge from "./wailsbridge";
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
Bridge.Start(() => {
|
Wails.Init(() => {
|
||||||
ReactDOM.render(<App />, document.getElementById('app'));
|
ReactDOM.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
document.getElementById("app")
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If you want your app to work offline and load faster, you can change
|
||||||
|
// unregister() to register() below. Note this comes with some pitfalls.
|
||||||
|
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||||
|
serviceWorker.unregister();
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
Wails Bridge (c) 2019-present Lea Anthony
|
|
||||||
|
|
||||||
This prod version is to get around having to rewrite your code
|
|
||||||
for production. When doing a release build, this file will be used
|
|
||||||
instead of the full version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// The main function
|
|
||||||
// Passes the main Wails object to the callback if given.
|
|
||||||
Start: function (callback) {
|
|
||||||
if (callback) {
|
|
||||||
window.wails.Events.On("wails:ready", callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "React JS",
|
"name": "React JS",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"shortdescription": "Create React App v3 template",
|
"shortdescription": "Create React App v4 template",
|
||||||
"description": "Create React App v3 standar tooling",
|
"description": "Create React App v4 standard tooling",
|
||||||
"install": "npm install",
|
"install": "npm install",
|
||||||
"build": "npm run build",
|
"build": "npm run build",
|
||||||
"author": "bh90210 <ktc@pm.me>",
|
"author": "bh90210 <ktc@pm.me>",
|
||||||
|
|||||||
5
cmd/templates/vanilla/README.md
Normal file
5
cmd/templates/vanilla/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# README
|
||||||
|
|
||||||
|
This is an experimental template for vanilla HTML/JS/CSS.
|
||||||
|
|
||||||
|
The webpack rules may need to be adjusted to correctly embed all assets. Babel may also need to be setup correctly.
|
||||||
46
cmd/templates/vanilla/counter.go
Normal file
46
cmd/templates/vanilla/counter.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Counter is what we use for counting
|
||||||
|
type Counter struct {
|
||||||
|
r *wails.Runtime
|
||||||
|
store *wails.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// WailsInit is called when the component is being initialised
|
||||||
|
func (c *Counter) WailsInit(runtime *wails.Runtime) error {
|
||||||
|
c.r = runtime
|
||||||
|
c.store = runtime.Store.New("Counter", 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandomValue sets the counter to a random value
|
||||||
|
func (c *Counter) RandomValue() {
|
||||||
|
c.store.Set(rand.Intn(1000))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment will increment the counter
|
||||||
|
func (c *Counter) Increment() {
|
||||||
|
|
||||||
|
increment := func(data int) int {
|
||||||
|
return data + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the store using the increment function
|
||||||
|
c.store.Update(increment)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement will decrement the counter
|
||||||
|
func (c *Counter) Decrement() {
|
||||||
|
|
||||||
|
decrement := func(data int) int {
|
||||||
|
return data - 1
|
||||||
|
}
|
||||||
|
// Update the store using the decrement function
|
||||||
|
c.store.Update(decrement)
|
||||||
|
}
|
||||||
42
cmd/templates/vanilla/frontend/package.json.template
Normal file
42
cmd/templates/vanilla/frontend/package.json.template
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "vanilla",
|
||||||
|
"author": "Lea<l>",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "webpack-dev-server",
|
||||||
|
"build": "npx webpack"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^3.6.4",
|
||||||
|
"regenerator-runtime": "^0.13.3",
|
||||||
|
"@wailsapp/runtime": "^1.0.10"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"copy-webpack-plugin": "^6.0.2",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eventsource-polyfill": "^0.9.6",
|
||||||
|
"webpack": "^4.43.0",
|
||||||
|
"webpack-cli": "^3.3.11",
|
||||||
|
"webpack-dev-server": "^3.11.0",
|
||||||
|
"webpack-hot-middleware": "^2.25.0"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"rules": {},
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not ie <= 8"
|
||||||
|
]
|
||||||
|
}
|
||||||
9
cmd/templates/vanilla/frontend/src/index.html
Normal file
9
cmd/templates/vanilla/frontend/src/index.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" type="text/css" href="main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
41
cmd/templates/vanilla/frontend/src/main.css
Normal file
41
cmd/templates/vanilla/frontend/src/main.css
Normal file
File diff suppressed because one or more lines are too long
47
cmd/templates/vanilla/frontend/src/main.js
Normal file
47
cmd/templates/vanilla/frontend/src/main.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import 'core-js/stable';
|
||||||
|
const runtime = require('@wailsapp/runtime');
|
||||||
|
|
||||||
|
// Main entry point
|
||||||
|
function start() {
|
||||||
|
|
||||||
|
var mystore = wails.Store.New('Counter');
|
||||||
|
|
||||||
|
// Ensure the default app div is 100% wide/high
|
||||||
|
var app = document.getElementById('app');
|
||||||
|
app.style.width = '100%';
|
||||||
|
app.style.height = '100%';
|
||||||
|
|
||||||
|
// Inject html
|
||||||
|
app.innerHTML = `
|
||||||
|
<div class='logo'></div>
|
||||||
|
<div class='container'>
|
||||||
|
<button onClick='window.backend.Counter.Increment()'>
|
||||||
|
Increment Counter
|
||||||
|
</button>
|
||||||
|
<button onClick='window.backend.Counter.Decrement()'>
|
||||||
|
Decrement Counter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class='result'>Counter: <span id='counter'></span></div>
|
||||||
|
<div class='container'>
|
||||||
|
<input id='newCounter' type="number" value="0"/>
|
||||||
|
<button id='setvalue'>Set Counter Value</button>
|
||||||
|
<button onclick='window.backend.Counter.RandomValue()'>Set to Random Value</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Connect counter value button to Go method
|
||||||
|
document.getElementById('setvalue').onclick = function() {
|
||||||
|
let newValue = parseInt(document.getElementById('newCounter').value,10);
|
||||||
|
mystore.set(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
mystore.subscribe( (state) => {
|
||||||
|
document.getElementById('counter').innerText = state;
|
||||||
|
});
|
||||||
|
|
||||||
|
mystore.set(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// We provide our entrypoint as a callback for runtime.Init
|
||||||
|
runtime.Init(start);
|
||||||
56
cmd/templates/vanilla/frontend/webpack.config.js
Normal file
56
cmd/templates/vanilla/frontend/webpack.config.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
|
|
||||||
|
let imageSizeLimit = 9007199254740991; // Number.MAX_SAFE_INTEGER
|
||||||
|
let sourceDir = path.resolve(__dirname, 'src');
|
||||||
|
let buildDir = path.resolve(__dirname, 'build');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: {
|
||||||
|
index: path.resolve(sourceDir, 'main.js')
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: buildDir,
|
||||||
|
filename: 'main.js'
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
splitChunks: false
|
||||||
|
},
|
||||||
|
devServer: {
|
||||||
|
disableHostCheck: true,
|
||||||
|
contentBase: path.join(__dirname, 'src'),
|
||||||
|
compress: true,
|
||||||
|
open: true,
|
||||||
|
port: 8090
|
||||||
|
},
|
||||||
|
mode: 'production',
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(png|gif|jpg|woff2?|eot|ttf|otf|svg)(\?.*)?$/i,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: 'url-loader',
|
||||||
|
options: {
|
||||||
|
limit: imageSizeLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [
|
||||||
|
{
|
||||||
|
from: path.resolve(sourceDir, 'main.css'),
|
||||||
|
to: path.resolve(buildDir, 'main.css')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
from: path.resolve(sourceDir, 'index.html'),
|
||||||
|
to: path.resolve(buildDir, 'index.html')
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
5
cmd/templates/vanilla/go.mod.template
Normal file
5
cmd/templates/vanilla/go.mod.template
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module {{.BinaryName}}
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/wailsapp/wails {{.WailsVersion}}
|
||||||
|
)
|
||||||
23
cmd/templates/vanilla/main.go.template
Normal file
23
cmd/templates/vanilla/main.go.template
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/leaanthony/mewn"
|
||||||
|
"github.com/wailsapp/wails"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
js := mewn.String("./frontend/build/main.js")
|
||||||
|
css := mewn.String("./frontend/build/main.css")
|
||||||
|
|
||||||
|
app := wails.CreateApp(&wails.AppConfig{
|
||||||
|
Width: 1024,
|
||||||
|
Height: 768,
|
||||||
|
Title: "{{.Name}}",
|
||||||
|
JS: js,
|
||||||
|
CSS: css,
|
||||||
|
Colour: "#131313",
|
||||||
|
})
|
||||||
|
app.Bind(&Counter{})
|
||||||
|
app.Run()
|
||||||
|
}
|
||||||
12
cmd/templates/vanilla/template.json
Normal file
12
cmd/templates/vanilla/template.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "Vanilla",
|
||||||
|
"shortdescription": "A Vanilla HTML/JS template",
|
||||||
|
"description": "A basic template using plain html/js and bundled using Webpack 4",
|
||||||
|
"author": "Lea Anthony<lea.anthony@gmail.com>",
|
||||||
|
"created": "2020-06-14",
|
||||||
|
"frontenddir": "frontend",
|
||||||
|
"install": "npm install",
|
||||||
|
"build": "npm run build",
|
||||||
|
"serve": "npm run serve",
|
||||||
|
"bridge": "src"
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [
|
||||||
'@vue/app'
|
[ '@vue/app', { useBuiltIns: 'entry' } ]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,19 +8,21 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^2.6.4",
|
"core-js": "^3.6.4",
|
||||||
"vue": "^2.5.22"
|
"regenerator-runtime": "^0.13.3",
|
||||||
|
"vue": "^2.6.11",
|
||||||
|
"@wailsapp/runtime": "^1.0.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^3.4.0",
|
"@vue/cli-plugin-babel": "^4.2.3",
|
||||||
"@vue/cli-plugin-eslint": "^3.4.0",
|
"@vue/cli-plugin-eslint": "^4.2.3",
|
||||||
"@vue/cli-service": "^3.4.0",
|
"@vue/cli-service": "^4.2.3",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint": "^5.8.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-plugin-vue": "^5.0.0",
|
"eslint-plugin-vue": "^6.2.1",
|
||||||
"eventsource-polyfill": "^0.9.6",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
"vue-template-compiler": "^2.5.21",
|
"vue-template-compiler": "^2.6.11",
|
||||||
"webpack-hot-middleware": "^2.24.3"
|
"webpack-hot-middleware": "^2.25.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import Vue from "vue";
|
import 'core-js/stable';
|
||||||
import App from "./App.vue";
|
import 'regenerator-runtime/runtime';
|
||||||
|
import Vue from 'vue';
|
||||||
|
import App from './App.vue';
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
Vue.config.devtools = true;
|
Vue.config.devtools = true;
|
||||||
|
|
||||||
import Bridge from "./wailsbridge";
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
Bridge.Start(() => {
|
Wails.Init(() => {
|
||||||
new Vue({
|
new Vue({
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
}).$mount("#app");
|
}).$mount('#app');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
Wails Bridge (c) 2019-present Lea Anthony
|
|
||||||
|
|
||||||
This prod version is to get around having to rewrite your code
|
|
||||||
for production. When doing a release build, this file will be used
|
|
||||||
instead of the full version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default {
|
|
||||||
// The main function
|
|
||||||
// Passes the main Wails object to the callback if given.
|
|
||||||
Start: function (callback) {
|
|
||||||
if (callback) {
|
|
||||||
window.wails.Events.On("wails:ready", callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -37,7 +37,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
disableHostCheck: true,
|
disableHostCheck: true
|
||||||
host: "localhost"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [
|
||||||
'@vue/app'
|
[ '@vue/app', { useBuiltIns: 'entry' } ]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,23 +7,24 @@
|
|||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-polyfill": "^6.26.0",
|
"core-js": "^3.6.4",
|
||||||
"core-js": "^2.6.4",
|
"regenerator-runtime": "^0.13.3",
|
||||||
"material-design-icons-iconfont": "^5.0.1",
|
"material-design-icons-iconfont": "^5.0.1",
|
||||||
"vue": "^2.5.22",
|
"vue": "^2.5.22",
|
||||||
"vuetify": "^1.5.14"
|
"vuetify": "^1.5.14",
|
||||||
|
"@wailsapp/runtime": "^1.0.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "^3.4.0",
|
"@vue/cli-plugin-babel": "^4.2.3",
|
||||||
"@vue/cli-plugin-eslint": "^3.4.0",
|
"@vue/cli-plugin-eslint": "^4.2.3",
|
||||||
"@vue/cli-service": "^3.4.0",
|
"@vue/cli-service": "^4.2.3",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint": "^5.8.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-plugin-vue": "^5.0.0",
|
"eslint-plugin-vue": "^6.2.1",
|
||||||
"eventsource-polyfill": "^0.9.6",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
"vue-template-compiler": "^2.5.21",
|
"vue-template-compiler": "^2.6.11",
|
||||||
"webpack-hot-middleware": "^2.24.3"
|
"webpack-hot-middleware": "^2.25.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
@@ -49,4 +50,4 @@
|
|||||||
"last 2 versions",
|
"last 2 versions",
|
||||||
"not ie <= 8"
|
"not ie <= 8"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'babel-polyfill';
|
import 'core-js/stable';
|
||||||
import Vue from "vue";
|
import 'regenerator-runtime/runtime';
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
// Setup Vuetify
|
// Setup Vuetify
|
||||||
import Vuetify from 'vuetify';
|
import Vuetify from 'vuetify';
|
||||||
@@ -7,15 +8,15 @@ Vue.use(Vuetify);
|
|||||||
import 'vuetify/dist/vuetify.min.css';
|
import 'vuetify/dist/vuetify.min.css';
|
||||||
import 'material-design-icons-iconfont';
|
import 'material-design-icons-iconfont';
|
||||||
|
|
||||||
import App from "./App.vue";
|
import App from './App.vue';
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
Vue.config.devtools = true;
|
Vue.config.devtools = true;
|
||||||
|
|
||||||
import Bridge from "./wailsbridge";
|
import * as Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
Bridge.Start(() => {
|
Wails.Init(() => {
|
||||||
new Vue({
|
new Vue({
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
}).$mount("#app");
|
}).$mount('#app');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
disableHostCheck: true,
|
disableHostCheck: true
|
||||||
host: "localhost"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "Vuetify Basic",
|
"name": "Vuetify1.5/Webpack Basic",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"shortdescription": "Vuetify + Webpack",
|
"shortdescription": "A basic Vuetify1.5/Webpack4 template",
|
||||||
"description": "Basic template using Vuetify and bundled using Webpack",
|
"description": "Basic template using Vuetify v1.5 and bundled using Webpack",
|
||||||
"install": "npm install",
|
"install": "npm install",
|
||||||
"build": "npm run build",
|
"build": "npm run build",
|
||||||
"author": "lea <lea.anthony@gmail.com>",
|
"author": "lea <lea.anthony@gmail.com>",
|
||||||
@@ -11,4 +11,4 @@
|
|||||||
"serve": "npm run serve",
|
"serve": "npm run serve",
|
||||||
"bridge": "src",
|
"bridge": "src",
|
||||||
"wailsdir": ""
|
"wailsdir": ""
|
||||||
}
|
}
|
||||||
|
|||||||
3
cmd/templates/vuetify2-basic/.jshint
Normal file
3
cmd/templates/vuetify2-basic/.jshint
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"esversion": 6
|
||||||
|
}
|
||||||
21
cmd/templates/vuetify2-basic/frontend/.gitignore
vendored
Normal file
21
cmd/templates/vuetify2-basic/frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw*
|
||||||
5
cmd/templates/vuetify2-basic/frontend/babel.config.js
Normal file
5
cmd/templates/vuetify2-basic/frontend/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
[ '@vue/app', { useBuiltIns: 'entry' } ]
|
||||||
|
]
|
||||||
|
};
|
||||||
53
cmd/templates/vuetify2-basic/frontend/package.json.template
Normal file
53
cmd/templates/vuetify2-basic/frontend/package.json.template
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"name": "{{.NPMProjectName}}",
|
||||||
|
"author": "{{.Author.Name}}<{{.Author.Email}}>",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^3.6.4",
|
||||||
|
"regenerator-runtime": "^0.13.3",
|
||||||
|
"vue": "^2.6.11",
|
||||||
|
"vuetify": "^2.2.15",
|
||||||
|
"@wailsapp/runtime": "^1.0.10"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@mdi/font": "^4.9.95",
|
||||||
|
"@vue/cli-plugin-babel": "^4.2.3",
|
||||||
|
"@vue/cli-plugin-eslint": "^4.2.3",
|
||||||
|
"@vue/cli-service": "^4.2.3",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-plugin-vue": "^6.2.1",
|
||||||
|
"eventsource-polyfill": "^0.9.6",
|
||||||
|
"vue-template-compiler": "^2.6.11",
|
||||||
|
"webpack-hot-middleware": "^2.25.0"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"rules": {},
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postcss": {
|
||||||
|
"plugins": {
|
||||||
|
"autoprefixer": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not ie <= 8"
|
||||||
|
]
|
||||||
|
}
|
||||||
60
cmd/templates/vuetify2-basic/frontend/src/App.vue
Normal file
60
cmd/templates/vuetify2-basic/frontend/src/App.vue
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<v-app id="inspire">
|
||||||
|
<v-navigation-drawer v-model="drawer" clipped fixed app>
|
||||||
|
<v-list dense>
|
||||||
|
<v-list-item>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>mdi-view-dashboard</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>Dashboard</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>mdi-settings</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>Settings</v-list-item-title>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-navigation-drawer>
|
||||||
|
<v-app-bar app fixed clipped-left>
|
||||||
|
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
|
||||||
|
<v-toolbar-title>Application</v-toolbar-title>
|
||||||
|
</v-app-bar>
|
||||||
|
<v-content>
|
||||||
|
<v-container fluid class="px-0">
|
||||||
|
<v-layout justify-center align-center class="px-0">
|
||||||
|
<hello-world></hello-world>
|
||||||
|
</v-layout>
|
||||||
|
</v-container>
|
||||||
|
</v-content>
|
||||||
|
<v-footer app fixed>
|
||||||
|
<span style="margin-left:1em">© You</span>
|
||||||
|
</v-footer>
|
||||||
|
</v-app>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import HelloWorld from "./components/HelloWorld.vue"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data: () => ({
|
||||||
|
drawer: false
|
||||||
|
}),
|
||||||
|
components: {
|
||||||
|
HelloWorld
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
source: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.logo {
|
||||||
|
width: 16em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
BIN
cmd/templates/vuetify2-basic/frontend/src/assets/images/logo.png
Normal file
BIN
cmd/templates/vuetify2-basic/frontend/src/assets/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 301 KiB |
@@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<v-container fluid class="px-0">
|
||||||
|
<v-layout>
|
||||||
|
<v-flex xs12 sm6 offset-sm3>
|
||||||
|
<v-card raised="raised" class="pa-4 ma-4">
|
||||||
|
<v-layout justify-center align-center class="pa-4 ma-4">
|
||||||
|
<v-img :src="require('../assets/images/logo.png')"></v-img>
|
||||||
|
</v-layout>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-layout justify-center align-center class="px-0">
|
||||||
|
<v-btn color="blue" @click="getMessage">Press Me</v-btn>
|
||||||
|
</v-layout>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
<div class="text-xs-center">
|
||||||
|
<v-dialog v-model="dialog" width="500">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="headline" primary-title>Message from Go</v-card-title>
|
||||||
|
<v-card-text>{{message}}</v-card-text>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="primary" text @click="dialog = false">Awesome</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
message: " ",
|
||||||
|
raised: true,
|
||||||
|
dialog: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getMessage: function () {
|
||||||
|
var self = this
|
||||||
|
window.backend.basic().then(result => {
|
||||||
|
self.message = result
|
||||||
|
self.dialog = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
h1 {
|
||||||
|
margin-top: 2em;
|
||||||
|
position: relative;
|
||||||
|
min-height: 5rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
font-size: 1.7em;
|
||||||
|
border-color: blue;
|
||||||
|
background-color: blue;
|
||||||
|
color: white;
|
||||||
|
border: 3px solid white;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 9px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 500ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 1.7em;
|
||||||
|
border-color: white;
|
||||||
|
background-color: #121212;
|
||||||
|
color: white;
|
||||||
|
border: 3px solid white;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 9px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
29
cmd/templates/vuetify2-basic/frontend/src/main.js
Normal file
29
cmd/templates/vuetify2-basic/frontend/src/main.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import 'core-js/stable';
|
||||||
|
import 'regenerator-runtime/runtime';
|
||||||
|
import '@mdi/font/css/materialdesignicons.css';
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Vuetify from 'vuetify';
|
||||||
|
import 'vuetify/dist/vuetify.min.css';
|
||||||
|
|
||||||
|
Vue.use(Vuetify);
|
||||||
|
|
||||||
|
import App from './App.vue';
|
||||||
|
|
||||||
|
Vue.config.productionTip = false;
|
||||||
|
Vue.config.devtools = true;
|
||||||
|
|
||||||
|
import Wails from '@wailsapp/runtime';
|
||||||
|
|
||||||
|
Wails.Init(() => {
|
||||||
|
new Vue({
|
||||||
|
vuetify: new Vuetify({
|
||||||
|
icons: {
|
||||||
|
iconfont: 'mdi'
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
dark: true
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
render: h => h(App)
|
||||||
|
}).$mount('#app');
|
||||||
|
});
|
||||||
42
cmd/templates/vuetify2-basic/frontend/vue.config.js
Normal file
42
cmd/templates/vuetify2-basic/frontend/vue.config.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
let cssConfig = {};
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV == 'production') {
|
||||||
|
cssConfig = {
|
||||||
|
extract: {
|
||||||
|
filename: '[name].css',
|
||||||
|
chunkFilename: '[name].css'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
chainWebpack: config => {
|
||||||
|
let limit = 9999999999999999;
|
||||||
|
config.module
|
||||||
|
.rule('images')
|
||||||
|
.test(/\.(png|gif|jpg)(\?.*)?$/i)
|
||||||
|
.use('url-loader')
|
||||||
|
.loader('url-loader')
|
||||||
|
.tap(options => Object.assign(options, { limit: limit }));
|
||||||
|
config.module
|
||||||
|
.rule('fonts')
|
||||||
|
.test(/\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/i)
|
||||||
|
.use('url-loader')
|
||||||
|
.loader('url-loader')
|
||||||
|
.options({
|
||||||
|
limit: limit
|
||||||
|
});
|
||||||
|
},
|
||||||
|
css: cssConfig,
|
||||||
|
configureWebpack: {
|
||||||
|
output: {
|
||||||
|
filename: '[name].js'
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
splitChunks: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
devServer: {
|
||||||
|
disableHostCheck: true
|
||||||
|
}
|
||||||
|
};
|
||||||
5
cmd/templates/vuetify2-basic/go.mod.template
Normal file
5
cmd/templates/vuetify2-basic/go.mod.template
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module {{.BinaryName}}
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/wailsapp/wails {{.WailsVersion}}
|
||||||
|
)
|
||||||
27
cmd/templates/vuetify2-basic/main.go.template
Normal file
27
cmd/templates/vuetify2-basic/main.go.template
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/leaanthony/mewn"
|
||||||
|
"github.com/wailsapp/wails"
|
||||||
|
)
|
||||||
|
|
||||||
|
func basic() string {
|
||||||
|
return "Hello World!"
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
js := mewn.String("./frontend/dist/app.js")
|
||||||
|
css := mewn.String("./frontend/dist/app.css")
|
||||||
|
|
||||||
|
app := wails.CreateApp(&wails.AppConfig{
|
||||||
|
Width: 1024,
|
||||||
|
Height: 768,
|
||||||
|
Title: "{{.Name}}",
|
||||||
|
JS: js,
|
||||||
|
CSS: css,
|
||||||
|
Colour: "#131313",
|
||||||
|
})
|
||||||
|
app.Bind(basic)
|
||||||
|
app.Run()
|
||||||
|
}
|
||||||
14
cmd/templates/vuetify2-basic/template.json
Executable file
14
cmd/templates/vuetify2-basic/template.json
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "Vuetify2/Webpack Basic",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"shortdescription": "A basic Vuetify2/Webpack4 template",
|
||||||
|
"description": "Basic template using Vuetify v2 and bundled using Webpack",
|
||||||
|
"install": "npm install",
|
||||||
|
"build": "npm run build",
|
||||||
|
"author": "Michael Hipp <michael@redmule.com>",
|
||||||
|
"created": "2019-09-06",
|
||||||
|
"frontenddir": "frontend",
|
||||||
|
"serve": "npm run serve",
|
||||||
|
"bridge": "src",
|
||||||
|
"wailsdir": ""
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
// Version - Wails version
|
// Version - Wails version
|
||||||
const Version = "v0.17.4-pre"
|
const Version = "v1.7.2-pre5"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
@@ -24,7 +23,7 @@ func init() {
|
|||||||
|
|
||||||
system := cmd.NewSystemHelper()
|
system := cmd.NewSystemHelper()
|
||||||
err = system.Initialise()
|
err = system.Initialise()
|
||||||
if err == nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,103 +32,27 @@ Create your first project by running 'wails init'.`
|
|||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
successMessage = "🚀 " + successMessage
|
successMessage = "🚀 " + successMessage
|
||||||
}
|
}
|
||||||
// Platform check
|
|
||||||
err = platformCheck()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check we have a cgo capable environment
|
// Chrck for programs and libraries dependencies
|
||||||
logger.Yellow("Checking for prerequisites...")
|
errors, err := cmd.CheckDependencies(logger)
|
||||||
var requiredProgramErrors bool
|
|
||||||
requiredProgramErrors, err = checkRequiredPrograms()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linux has library deps
|
|
||||||
var libraryErrors bool
|
|
||||||
libraryErrors, err = checkLibraries()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Mewn
|
// Check Mewn
|
||||||
err = cmd.CheckMewn()
|
err = cmd.CheckMewn(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.White("")
|
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
var errors = libraryErrors || requiredProgramErrors
|
// CheckDependencies() returns !errors
|
||||||
if !errors {
|
// so to get the right message in this
|
||||||
|
// check we have to do it in reversed
|
||||||
|
if errors {
|
||||||
logger.Yellow(successMessage)
|
logger.Yellow(successMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func platformCheck() error {
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
logger.Yellow("Detected Platform: OSX")
|
|
||||||
case "windows":
|
|
||||||
logger.Yellow("Detected Platform: Windows")
|
|
||||||
case "linux":
|
|
||||||
logger.Yellow("Detected Platform: Linux")
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Platform %s is currently not supported", runtime.GOOS)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkLibraries() (errors bool, err error) {
|
|
||||||
if runtime.GOOS == "linux" {
|
|
||||||
// Check library prerequisites
|
|
||||||
requiredLibraries, err := cmd.GetRequiredLibraries()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
distroInfo := cmd.GetLinuxDistroInfo()
|
|
||||||
for _, library := range *requiredLibraries {
|
|
||||||
switch distroInfo.Distribution {
|
|
||||||
case cmd.Ubuntu, cmd.Zorin, cmd.Debian:
|
|
||||||
installed, err := cmd.DpkgInstalled(library.Name)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if !installed {
|
|
||||||
errors = true
|
|
||||||
logger.Red("Library '%s' not found. %s", library.Name, library.Help)
|
|
||||||
} else {
|
|
||||||
logger.Green("Library '%s' installed.", library.Name)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false, cmd.RequestSupportForDistribution(distroInfo, library.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkRequiredPrograms() (errors bool, err error) {
|
|
||||||
requiredPrograms, err := cmd.GetRequiredPrograms()
|
|
||||||
if err != nil {
|
|
||||||
return true, err
|
|
||||||
}
|
|
||||||
errors = false
|
|
||||||
programHelper := cmd.NewProgramHelper()
|
|
||||||
for _, program := range *requiredPrograms {
|
|
||||||
bin := programHelper.FindProgram(program.Name)
|
|
||||||
if bin == nil {
|
|
||||||
errors = true
|
|
||||||
logger.Red("Program '%s' not found. %s", program.Name, program.Help)
|
|
||||||
} else {
|
|
||||||
logger.Green("Program '%s' found: %s", program.Name, bin.Path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|||||||
385
cmd/wails/15_migrate.go
Normal file
385
cmd/wails/15_migrate.go
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Masterminds/semver"
|
||||||
|
"github.com/leaanthony/spinner"
|
||||||
|
"github.com/wailsapp/wails/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
var checkSpinner = spinner.NewSpinner()
|
||||||
|
var migrateProjectOptions = &cmd.ProjectOptions{}
|
||||||
|
var migrateFS = cmd.NewFSHelper()
|
||||||
|
var migrateGithub = cmd.NewGitHubHelper()
|
||||||
|
var programHelper = cmd.NewProgramHelper()
|
||||||
|
var lessThanV1 *semver.Constraints
|
||||||
|
|
||||||
|
// The user's go.mod
|
||||||
|
var goMod string
|
||||||
|
var goModFile string
|
||||||
|
|
||||||
|
// The user's main.js
|
||||||
|
var mainJSFile string
|
||||||
|
var mainJSContents string
|
||||||
|
|
||||||
|
// Frontend directory
|
||||||
|
var frontEndDir string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
var dryrun bool
|
||||||
|
var err error
|
||||||
|
|
||||||
|
lessThanV1, err = semver.NewConstraint("< v1.0.0")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// var forceRebuild = false
|
||||||
|
checkSpinner.SetSpinSpeed(50)
|
||||||
|
|
||||||
|
commandDescription := `EXPERIMENTAL - This command attempts to migrate projects to the latest Wails version.`
|
||||||
|
updateCmd := app.Command("migrate", "Migrate projects to latest Wails release").
|
||||||
|
LongDescription(commandDescription).
|
||||||
|
BoolFlag("dryrun", "Only display what would be done", &dryrun)
|
||||||
|
|
||||||
|
updateCmd.Action(func() error {
|
||||||
|
|
||||||
|
message := "Migrate Project"
|
||||||
|
logger.PrintSmallBanner(message)
|
||||||
|
logger.Red("WARNING: This is an experimental command. Ensure you have backups of your project!")
|
||||||
|
logger.Red("It currently only supports npm based projects.")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check project directory
|
||||||
|
err := checkProjectDirectory()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find Wails version from go.mod
|
||||||
|
wailsVersion, err := getWailsVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get latest stable version
|
||||||
|
var latestVersion *semver.Version
|
||||||
|
latestVersion, err = getLatestWailsVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var canMigrate bool
|
||||||
|
canMigrate, err = canMigrateVersion(wailsVersion, latestVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !canMigrate {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for wailsbridge
|
||||||
|
wailsBridge, err := checkWailsBridge()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is main.js using bridge.Init()
|
||||||
|
canUpdateMainJS, err := checkMainJS()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check if we are using legacy js runtime
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
logger.Yellow("Operations to perform:")
|
||||||
|
|
||||||
|
logger.Yellowf(" - Update to Wails v%s\n", latestVersion)
|
||||||
|
|
||||||
|
if len(wailsBridge) > 0 {
|
||||||
|
logger.Yellow(" - Delete wailsbridge.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
if canUpdateMainJS {
|
||||||
|
logger.Yellow(" - Patch main.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Yellow(" - Ensure '@wailsapp/runtime` module is installed")
|
||||||
|
|
||||||
|
if dryrun {
|
||||||
|
logger.White("Exiting: Dry Run")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Red("*WARNING* About to modify your project!")
|
||||||
|
logger.Red("Type 'YES' to continue: ")
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
scanner.Scan()
|
||||||
|
input := scanner.Text()
|
||||||
|
if input != "YES" {
|
||||||
|
logger.Red("ABORTED!")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Yellow("Let's do this!")
|
||||||
|
|
||||||
|
err = updateWailsVersion(wailsVersion, latestVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(wailsBridge) > 0 {
|
||||||
|
err = deleteWailsBridge(wailsBridge)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if canUpdateMainJS {
|
||||||
|
err = patchMainJS()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install runtime
|
||||||
|
err = installWailsRuntime()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
logger.Yellow("Migration complete! Check project by running `wails build`.")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkProjectDirectory() error {
|
||||||
|
// Get versions
|
||||||
|
checkSpinner.Start("Check Project Directory")
|
||||||
|
|
||||||
|
// Check we are in project directory
|
||||||
|
err := migrateProjectOptions.LoadConfig(migrateFS.Cwd())
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWailsVersion() (*semver.Version, error) {
|
||||||
|
checkSpinner.Start("Get Wails Version")
|
||||||
|
|
||||||
|
result, err := cmd.GetWailsVersion()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func canMigrateVersion(wailsVersion *semver.Version, latestVersion *semver.Version) (bool, error) {
|
||||||
|
checkSpinner.Start("Checking ability to Migrate")
|
||||||
|
|
||||||
|
// Check if we are at the latest version!!!!
|
||||||
|
if wailsVersion.Equal(latestVersion) || wailsVersion.GreaterThan(latestVersion) {
|
||||||
|
checkSpinner.Errorf("Checking ability to Migrate: No! (v%s >= v%s)", wailsVersion, latestVersion)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for < v1.0.0
|
||||||
|
if lessThanV1.Check(wailsVersion) {
|
||||||
|
checkSpinner.Successf("Checking ability to Migrate: Yes! (v%s < v1.0.0)", wailsVersion)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
checkSpinner.Error("Unable to migrate")
|
||||||
|
return false, fmt.Errorf("No migration rules for version %s", wailsVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkWailsBridge() (string, error) {
|
||||||
|
checkSpinner.Start("Checking if legacy Wails Bridge present")
|
||||||
|
|
||||||
|
// Check frontend dir is available
|
||||||
|
if migrateProjectOptions.FrontEnd == nil ||
|
||||||
|
len(migrateProjectOptions.FrontEnd.Dir) == 0 ||
|
||||||
|
!migrateFS.DirExists(migrateProjectOptions.FrontEnd.Dir) {
|
||||||
|
checkSpinner.Error("Unable to determine frontend directory")
|
||||||
|
return "", fmt.Errorf("Unable to determine frontend directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
frontEndDir = migrateProjectOptions.FrontEnd.Dir
|
||||||
|
|
||||||
|
wailsBridgePath, err := filepath.Abs(filepath.Join(".", frontEndDir, "src", "wailsbridge.js"))
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error(err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it doesn't exist, return blank string
|
||||||
|
if !migrateFS.FileExists(wailsBridgePath) {
|
||||||
|
checkSpinner.Success("Checking if legacy Wails Bridge present: No")
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success("Checking if legacy Wails Bridge present: Yes")
|
||||||
|
return wailsBridgePath, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function determines if the main.js file using wailsbridge can be auto-updated
|
||||||
|
func checkMainJS() (bool, error) {
|
||||||
|
|
||||||
|
checkSpinner.Start("Checking if main.js can be migrated")
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Check main.js is there
|
||||||
|
if migrateProjectOptions.FrontEnd == nil ||
|
||||||
|
len(migrateProjectOptions.FrontEnd.Dir) == 0 ||
|
||||||
|
!migrateFS.DirExists(migrateProjectOptions.FrontEnd.Dir) {
|
||||||
|
checkSpinner.Error("Unable to determine frontend directory")
|
||||||
|
return false, fmt.Errorf("Unable to determine frontend directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
frontEndDir = migrateProjectOptions.FrontEnd.Dir
|
||||||
|
|
||||||
|
mainJSFile, err = filepath.Abs(filepath.Join(".", frontEndDir, "src", "main.js"))
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error("Unable to find main.js")
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mainJSContents, err = migrateFS.LoadAsString(mainJSFile)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error("Unable to load main.js")
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check we have a line like: import Bridge from "./wailsbridge";
|
||||||
|
if strings.Index(mainJSContents, `import Bridge from "./wailsbridge";`) == -1 {
|
||||||
|
checkSpinner.Success("Checking if main.js can be migrated: No - Cannot find `import Bridge`")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check we have a line like: Bridge.Start(() => {
|
||||||
|
if strings.Index(mainJSContents, `Bridge.Start(`) == -1 {
|
||||||
|
checkSpinner.Success("Checking if main.js can be migrated: No - Cannot find `Bridge.Start`")
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
checkSpinner.Success("Checking if main.js can be migrated: Yes")
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLatestWailsVersion() (*semver.Version, error) {
|
||||||
|
checkSpinner.Start("Checking GitHub for latest Wails version")
|
||||||
|
version, err := migrateGithub.GetLatestStableRelease()
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error("Checking GitHub for latest Wails version: Failed")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Successf("Checking GitHub for latest Wails version: v%s", version)
|
||||||
|
return version.Version, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateWailsVersion(currentVersion, latestVersion *semver.Version) error {
|
||||||
|
// Patch go.mod
|
||||||
|
checkSpinner.Start("Patching go.mod")
|
||||||
|
|
||||||
|
wailsModule := "github.com/wailsapp/wails"
|
||||||
|
old := fmt.Sprintf("%s v%s", wailsModule, currentVersion)
|
||||||
|
new := fmt.Sprintf("%s v%s", wailsModule, latestVersion)
|
||||||
|
|
||||||
|
goMod = strings.Replace(goMod, old, new, -1)
|
||||||
|
err := ioutil.WriteFile(goModFile, []byte(goMod), 0600)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteWailsBridge(bridgeFilename string) error {
|
||||||
|
// Patch go.mod
|
||||||
|
checkSpinner.Start("Delete legacy wailsbridge.js")
|
||||||
|
|
||||||
|
err := migrateFS.RemoveFile(bridgeFilename)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func patchMainJS() error {
|
||||||
|
// Patch main.js
|
||||||
|
checkSpinner.Start("Patching main.js")
|
||||||
|
|
||||||
|
// Patch import line
|
||||||
|
oldImportLine := `import Bridge from "./wailsbridge";`
|
||||||
|
newImportLine := `import * as Wails from "@wailsapp/runtime";`
|
||||||
|
mainJSContents = strings.Replace(mainJSContents, oldImportLine, newImportLine, -1)
|
||||||
|
|
||||||
|
// Patch Start line
|
||||||
|
oldStartLine := `Bridge.Start`
|
||||||
|
newStartLine := `Wails.Init`
|
||||||
|
mainJSContents = strings.Replace(mainJSContents, oldStartLine, newStartLine, -1)
|
||||||
|
|
||||||
|
err := ioutil.WriteFile(mainJSFile, []byte(mainJSContents), 0600)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func installWailsRuntime() error {
|
||||||
|
|
||||||
|
checkSpinner.Start("Installing @wailsapp/runtime module")
|
||||||
|
|
||||||
|
// Change to the frontend directory
|
||||||
|
err := os.Chdir(frontEndDir)
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine package manager
|
||||||
|
packageManager, err := migrateProjectOptions.GetNPMBinaryName()
|
||||||
|
if err != nil {
|
||||||
|
checkSpinner.Error()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch packageManager {
|
||||||
|
case cmd.NPM:
|
||||||
|
// npm install --save @wailsapp/runtime
|
||||||
|
programHelper.InstallNPMPackage("@wailsapp/runtime", true)
|
||||||
|
default:
|
||||||
|
checkSpinner.Error()
|
||||||
|
return fmt.Errorf("Unknown package manager")
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSpinner.Success()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -3,16 +3,34 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// getSupportedPlatforms returns a slice of platform/architecture
|
||||||
|
// targets that are buildable using the cross-platform 'x' option.
|
||||||
|
func getSupportedPlatforms() []string {
|
||||||
|
return []string{
|
||||||
|
"darwin/amd64",
|
||||||
|
"linux/amd64",
|
||||||
|
"linux/arm-7",
|
||||||
|
"windows/amd64",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
var packageApp = false
|
var packageApp = false
|
||||||
var forceRebuild = false
|
var forceRebuild = false
|
||||||
var debugMode = false
|
var debugMode = false
|
||||||
|
var typescriptFilename = ""
|
||||||
|
var verbose = false
|
||||||
|
var platform = ""
|
||||||
|
var ldflags = ""
|
||||||
|
|
||||||
buildSpinner := spinner.NewSpinner()
|
buildSpinner := spinner.NewSpinner()
|
||||||
buildSpinner.SetSpinSpeed(50)
|
buildSpinner.SetSpinSpeed(50)
|
||||||
|
|
||||||
@@ -21,7 +39,18 @@ func init() {
|
|||||||
LongDescription(commandDescription).
|
LongDescription(commandDescription).
|
||||||
BoolFlag("p", "Package application on successful build", &packageApp).
|
BoolFlag("p", "Package application on successful build", &packageApp).
|
||||||
BoolFlag("f", "Force rebuild of application components", &forceRebuild).
|
BoolFlag("f", "Force rebuild of application components", &forceRebuild).
|
||||||
BoolFlag("d", "Build in Debug mode", &debugMode)
|
BoolFlag("d", "Build in Debug mode", &debugMode).
|
||||||
|
BoolFlag("verbose", "Verbose output", &verbose).
|
||||||
|
StringFlag("t", "Generate Typescript definitions to given file (at runtime)", &typescriptFilename).
|
||||||
|
StringFlag("ldflags", "Extra options for -ldflags", &ldflags)
|
||||||
|
|
||||||
|
var b strings.Builder
|
||||||
|
for _, plat := range getSupportedPlatforms() {
|
||||||
|
fmt.Fprintf(&b, " - %s\n", plat)
|
||||||
|
}
|
||||||
|
initCmd.StringFlag("x",
|
||||||
|
fmt.Sprintf("Cross-compile application to specified platform via xgo\n%s", b.String()),
|
||||||
|
&platform)
|
||||||
|
|
||||||
initCmd.Action(func() error {
|
initCmd.Action(func() error {
|
||||||
|
|
||||||
@@ -37,6 +66,7 @@ func init() {
|
|||||||
|
|
||||||
// Project options
|
// Project options
|
||||||
projectOptions := &cmd.ProjectOptions{}
|
projectOptions := &cmd.ProjectOptions{}
|
||||||
|
projectOptions.Verbose = verbose
|
||||||
|
|
||||||
// Check we are in project directory
|
// Check we are in project directory
|
||||||
// Check project.json loads correctly
|
// Check project.json loads correctly
|
||||||
@@ -46,6 +76,28 @@ func init() {
|
|||||||
return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory")
|
return fmt.Errorf("Unable to find 'project.json'. Please check you are in a Wails project directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set cross-compile
|
||||||
|
projectOptions.Platform = runtime.GOOS
|
||||||
|
if len(platform) > 0 {
|
||||||
|
supported := false
|
||||||
|
for _, plat := range getSupportedPlatforms() {
|
||||||
|
if plat == platform {
|
||||||
|
supported = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !supported {
|
||||||
|
return fmt.Errorf("unsupported platform '%s' specified.\nPlease run `wails build -h` to see the supported platform/architecture options", platform)
|
||||||
|
}
|
||||||
|
|
||||||
|
projectOptions.CrossCompile = true
|
||||||
|
plat := strings.Split(platform, "/")
|
||||||
|
projectOptions.Platform = plat[0]
|
||||||
|
projectOptions.Architecture = plat[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add ldflags
|
||||||
|
projectOptions.LdFlags = ldflags
|
||||||
|
|
||||||
// Validate config
|
// Validate config
|
||||||
// Check if we have a frontend
|
// Check if we have a frontend
|
||||||
err = cmd.ValidateFrontendConfig(projectOptions)
|
err = cmd.ValidateFrontendConfig(projectOptions)
|
||||||
@@ -72,6 +124,12 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that runtime init.js is the production version
|
||||||
|
err = cmd.InstallProdRuntime(projectDir, projectOptions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to project directory
|
// Move to project directory
|
||||||
@@ -81,7 +139,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install dependencies
|
// Install dependencies
|
||||||
err = cmd.InstallGoDependencies()
|
err = cmd.InstallGoDependencies(projectOptions.Verbose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -92,6 +150,32 @@ func init() {
|
|||||||
buildMode = cmd.BuildModeDebug
|
buildMode = cmd.BuildModeDebug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save if we wish to dump typescript or not
|
||||||
|
if typescriptFilename != "" {
|
||||||
|
projectOptions.SetTypescriptDefsFilename(typescriptFilename)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update go.mod if it is out of sync with current version
|
||||||
|
outofsync, err := cmd.GoModOutOfSync()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gomodVersion, err := cmd.GetWailsVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if outofsync {
|
||||||
|
syncMessage := fmt.Sprintf("Updating go.mod (Wails version %s => %s)", gomodVersion, cmd.Version)
|
||||||
|
buildSpinner := spinner.NewSpinner(syncMessage)
|
||||||
|
buildSpinner.Start()
|
||||||
|
err := cmd.UpdateGoModVersion()
|
||||||
|
if err != nil {
|
||||||
|
buildSpinner.Error(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
buildSpinner.Success()
|
||||||
|
}
|
||||||
|
|
||||||
err = cmd.BuildApplication(projectOptions.BinaryName, forceRebuild, buildMode, packageApp, projectOptions)
|
err = cmd.BuildApplication(projectOptions.BinaryName, forceRebuild, buildMode, packageApp, projectOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
@@ -10,12 +11,14 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
var forceRebuild = false
|
var forceRebuild = false
|
||||||
|
var verbose = false
|
||||||
buildSpinner := spinner.NewSpinner()
|
buildSpinner := spinner.NewSpinner()
|
||||||
buildSpinner.SetSpinSpeed(50)
|
buildSpinner.SetSpinSpeed(50)
|
||||||
|
|
||||||
commandDescription := `This command builds then serves your application in bridge mode. Useful for developing your app in a browser.`
|
commandDescription := `This command builds then serves your application in bridge mode. Useful for developing your app in a browser.`
|
||||||
initCmd := app.Command("serve", "Run your Wails project in bridge mode").
|
initCmd := app.Command("serve", "Run your Wails project in bridge mode").
|
||||||
LongDescription(commandDescription).
|
LongDescription(commandDescription).
|
||||||
|
BoolFlag("verbose", "Verbose output", &verbose).
|
||||||
BoolFlag("f", "Force rebuild of application components", &forceRebuild)
|
BoolFlag("f", "Force rebuild of application components", &forceRebuild)
|
||||||
|
|
||||||
initCmd.Action(func() error {
|
initCmd.Action(func() error {
|
||||||
@@ -25,7 +28,7 @@ func init() {
|
|||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
// Check Mewn is installed
|
// Check Mewn is installed
|
||||||
err := cmd.CheckMewn()
|
err := cmd.CheckMewn(verbose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -41,17 +44,21 @@ func init() {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set project options
|
||||||
|
projectOptions.Verbose = verbose
|
||||||
|
projectOptions.Platform = runtime.GOOS
|
||||||
|
|
||||||
// Save project directory
|
// Save project directory
|
||||||
projectDir := fs.Cwd()
|
projectDir := fs.Cwd()
|
||||||
|
|
||||||
// Install the bridge library
|
// Install the bridge library
|
||||||
err = cmd.InstallBridge("serve", projectDir, projectOptions)
|
err = cmd.InstallBridge(projectDir, projectOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install dependencies
|
// Install dependencies
|
||||||
err = cmd.InstallGoDependencies()
|
err = cmd.InstallGoDependencies(projectOptions.Verbose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/leaanthony/spinner"
|
"github.com/leaanthony/spinner"
|
||||||
"github.com/mitchellh/go-homedir"
|
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ func updateToVersion(targetVersion *cmd.SemanticVersion, force bool) error {
|
|||||||
updateSpinner.Start("Installing Wails " + desiredVersion)
|
updateSpinner.Start("Installing Wails " + desiredVersion)
|
||||||
|
|
||||||
// Run command in non module directory
|
// Run command in non module directory
|
||||||
homeDir, err := homedir.Dir()
|
homeDir, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Cannot find home directory! Please file a bug report!")
|
log.Fatal("Cannot find home directory! Please file a bug report!")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,65 @@ To help you in this process, we will ask for some information, add Go/Wails deta
|
|||||||
gomodule = "(Not Set)"
|
gomodule = "(Not Set)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get version numbers for GCC, node & npm
|
||||||
|
program := cmd.NewProgramHelper()
|
||||||
|
// string helpers
|
||||||
|
var gccVersion, nodeVersion, npmVersion string
|
||||||
|
|
||||||
|
// choose between OS (mac,linux,win)
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
gcc := program.FindProgram("gcc")
|
||||||
|
if gcc != nil {
|
||||||
|
stdout, _, _, _ := gcc.Run("-dumpversion")
|
||||||
|
gccVersion = strings.TrimSpace(stdout)
|
||||||
|
}
|
||||||
|
case "linux":
|
||||||
|
// for linux we have to collect
|
||||||
|
// the distribution name
|
||||||
|
distroInfo := cmd.GetLinuxDistroInfo()
|
||||||
|
linuxDB := cmd.NewLinuxDB()
|
||||||
|
distro := linuxDB.GetDistro(distroInfo.ID)
|
||||||
|
release := distro.GetRelease(distroInfo.Release)
|
||||||
|
gccVersionCommand := release.GccVersionCommand
|
||||||
|
|
||||||
|
gcc := program.FindProgram("gcc")
|
||||||
|
if gcc != nil {
|
||||||
|
stdout, _, _, _ := gcc.Run(gccVersionCommand)
|
||||||
|
gccVersion = strings.TrimSpace(stdout)
|
||||||
|
}
|
||||||
|
case "windows":
|
||||||
|
gcc := program.FindProgram("gcc")
|
||||||
|
if gcc != nil {
|
||||||
|
stdout, _, _, _ := gcc.Run("-dumpversion")
|
||||||
|
gccVersion = strings.TrimSpace(stdout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
npm := program.FindProgram("npm")
|
||||||
|
if npm != nil {
|
||||||
|
stdout, _, _, _ := npm.Run("--version")
|
||||||
|
npmVersion = stdout
|
||||||
|
npmVersion = npmVersion[:len(npmVersion)-1]
|
||||||
|
npmVersion = strings.TrimSpace(npmVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
node := program.FindProgram("node")
|
||||||
|
if node != nil {
|
||||||
|
stdout, _, _, _ := node.Run("--version")
|
||||||
|
nodeVersion = stdout
|
||||||
|
nodeVersion = nodeVersion[:len(nodeVersion)-1]
|
||||||
|
}
|
||||||
|
|
||||||
str.WriteString("\n| Name | Value |\n| ----- | ----- |\n")
|
str.WriteString("\n| Name | Value |\n| ----- | ----- |\n")
|
||||||
str.WriteString(fmt.Sprintf("| Wails Version | %s |\n", cmd.Version))
|
str.WriteString(fmt.Sprintf("| Wails Version | %s |\n", cmd.Version))
|
||||||
str.WriteString(fmt.Sprintf("| Go Version | %s |\n", runtime.Version()))
|
str.WriteString(fmt.Sprintf("| Go Version | %s |\n", runtime.Version()))
|
||||||
str.WriteString(fmt.Sprintf("| Platform | %s |\n", runtime.GOOS))
|
str.WriteString(fmt.Sprintf("| Platform | %s |\n", runtime.GOOS))
|
||||||
str.WriteString(fmt.Sprintf("| Arch | %s |\n", runtime.GOARCH))
|
str.WriteString(fmt.Sprintf("| Arch | %s |\n", runtime.GOARCH))
|
||||||
str.WriteString(fmt.Sprintf("| GO111MODULE | %s |\n", gomodule))
|
str.WriteString(fmt.Sprintf("| GO111MODULE | %s |\n", gomodule))
|
||||||
|
str.WriteString(fmt.Sprintf("| GCC | %s |\n", gccVersion))
|
||||||
|
str.WriteString(fmt.Sprintf("| Npm | %s |\n", npmVersion))
|
||||||
|
str.WriteString(fmt.Sprintf("| Node | %s |\n", nodeVersion))
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Processing template and preparing for upload.")
|
fmt.Println("Processing template and preparing for upload.")
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
"github.com/wailsapp/wails/cmd"
|
"github.com/wailsapp/wails/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,5 +18,9 @@ func main() {
|
|||||||
err := app.Run()
|
err := app.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err.Error())
|
logger.Error(err.Error())
|
||||||
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||||
|
os.Exit(exitErr.ExitCode())
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
cmd/windres.bat
Normal file
1
cmd/windres.bat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
windres.exe -o %1 %2
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
package wails
|
package wails
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/leaanthony/mewn"
|
||||||
|
"github.com/wailsapp/wails/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
// AppConfig is the configuration structure used when creating a Wails App object
|
// AppConfig is the configuration structure used when creating a Wails App object
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
@@ -29,7 +33,7 @@ func (a *AppConfig) GetTitle() string {
|
|||||||
return a.Title
|
return a.Title
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultHTML returns the desired window title
|
// GetDefaultHTML returns the default HTML
|
||||||
func (a *AppConfig) GetDefaultHTML() string {
|
func (a *AppConfig) GetDefaultHTML() string {
|
||||||
return a.defaultHTML
|
return a.defaultHTML
|
||||||
}
|
}
|
||||||
@@ -64,7 +68,7 @@ func (a *AppConfig) merge(in *AppConfig) error {
|
|||||||
a.CSS = in.CSS
|
a.CSS = in.CSS
|
||||||
}
|
}
|
||||||
if in.Title != "" {
|
if in.Title != "" {
|
||||||
a.Title = in.Title
|
a.Title = runtime.ProcessEncoding(in.Title)
|
||||||
}
|
}
|
||||||
|
|
||||||
if in.Colour != "" {
|
if in.Colour != "" {
|
||||||
@@ -95,6 +99,7 @@ func newConfig(userConfig *AppConfig) (*AppConfig, error) {
|
|||||||
Resizable: true,
|
Resizable: true,
|
||||||
Title: "My Wails App",
|
Title: "My Wails App",
|
||||||
Colour: "#FFF", // White by default
|
Colour: "#FFF", // White by default
|
||||||
|
HTML: mewn.String("./runtime/assets/default.html"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if userConfig != nil {
|
if userConfig != nil {
|
||||||
|
|||||||
22
go.mod
22
go.mod
@@ -1,10 +1,8 @@
|
|||||||
module github.com/wailsapp/wails
|
module github.com/wailsapp/wails
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/semver v1.4.2 // indirect
|
github.com/Masterminds/semver v1.4.2
|
||||||
github.com/dchest/cssmin v0.0.0-20151210170030-fb8d9b44afdc // indirect
|
github.com/abadojack/whatlanggo v1.0.1
|
||||||
github.com/dchest/htmlmin v0.0.0-20150526090704-e254725e81ac
|
|
||||||
github.com/dchest/jsmin v0.0.0-20160823214000-faeced883947 // indirect
|
|
||||||
github.com/fatih/color v1.7.0
|
github.com/fatih/color v1.7.0
|
||||||
github.com/go-playground/colors v1.2.0
|
github.com/go-playground/colors v1.2.0
|
||||||
github.com/gorilla/websocket v1.4.0
|
github.com/gorilla/websocket v1.4.0
|
||||||
@@ -12,20 +10,22 @@ require (
|
|||||||
github.com/kennygrant/sanitize v1.2.4
|
github.com/kennygrant/sanitize v1.2.4
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||||
github.com/leaanthony/mewn v0.10.7
|
github.com/leaanthony/mewn v0.10.7
|
||||||
github.com/leaanthony/slicer v1.3.2
|
github.com/leaanthony/slicer v1.4.0
|
||||||
github.com/leaanthony/spinner v0.5.3
|
github.com/leaanthony/spinner v0.5.3
|
||||||
github.com/masterminds/semver v1.4.2
|
|
||||||
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.7 // indirect
|
github.com/mattn/go-isatty v0.0.7 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.4.1
|
||||||
github.com/stretchr/testify v1.3.0 // indirect
|
github.com/stretchr/testify v1.3.0 // indirect
|
||||||
github.com/wailsapp/webview v0.2.7
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 // indirect
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
|
||||||
|
golang.org/x/text v0.3.0
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|||||||
46
go.sum
46
go.sum
@@ -2,15 +2,11 @@ github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITg
|
|||||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
|
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
|
||||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||||
|
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
|
||||||
|
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dchest/cssmin v0.0.0-20151210170030-fb8d9b44afdc h1:VBS1z48BFEe00G81z8MKOtwX7f/ISkuH38NscT8iVPw=
|
|
||||||
github.com/dchest/cssmin v0.0.0-20151210170030-fb8d9b44afdc/go.mod h1:ABJPuor7YlcsHmvJ1QxX38e2NcufLY3hm0yXv+cy9sI=
|
|
||||||
github.com/dchest/htmlmin v0.0.0-20150526090704-e254725e81ac h1:DpMwFluHWoZpV9ex5XjkWO4HyCz5HLVI8XbHw0FhHi4=
|
|
||||||
github.com/dchest/htmlmin v0.0.0-20150526090704-e254725e81ac/go.mod h1:XsAE+b4rOZc8gvgsgF+wU75mNBvBcyED1wdd9PBLlJ0=
|
|
||||||
github.com/dchest/jsmin v0.0.0-20160823214000-faeced883947 h1:Fm10/KNuoAyBm2P5P5H91Xy21hGcZnBdjR+cMdytv1M=
|
|
||||||
github.com/dchest/jsmin v0.0.0-20160823214000-faeced883947/go.mod h1:Dv9D0NUlAsaQcGQZa5kc5mqR9ua72SmA8VXi4cd+cBw=
|
|
||||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/go-playground/colors v1.2.0 h1:0EdjTXKrr2g1L/LQTYtIqabeHpZuGZz1U4osS1T8+5M=
|
github.com/go-playground/colors v1.2.0 h1:0EdjTXKrr2g1L/LQTYtIqabeHpZuGZz1U4osS1T8+5M=
|
||||||
@@ -25,7 +21,6 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
|||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||||
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
|
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
|
||||||
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
|
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
@@ -33,30 +28,24 @@ github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
|||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/leaanthony/mewn v0.10.7 h1:jCcNJyIUOpwj+I5SuATvCugDjHkoo+j6ubEOxxrxmPA=
|
github.com/leaanthony/mewn v0.10.7 h1:jCcNJyIUOpwj+I5SuATvCugDjHkoo+j6ubEOxxrxmPA=
|
||||||
github.com/leaanthony/mewn v0.10.7/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
|
github.com/leaanthony/mewn v0.10.7/go.mod h1:CRkTx8unLiSSilu/Sd7i1LwrdaAL+3eQ3ses99qGMEQ=
|
||||||
github.com/leaanthony/slicer v1.3.2 h1:kGWWFoyaY5WzwGrUsHXMmGbssuYthP4qYBNlkNpNAB8=
|
github.com/leaanthony/slicer v1.4.0 h1:Q9u4w+UBU4WHjXnEDdz+eRLMKF/rnyosRBiqULnc1J8=
|
||||||
github.com/leaanthony/slicer v1.3.2/go.mod h1:VMB/HGvr3uR3MRpFWHWAm0w+DHQLzPHYe2pKfpFlQIQ=
|
github.com/leaanthony/slicer v1.4.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||||
github.com/leaanthony/spinner v0.5.3 h1:IMTvgdQCec5QA4qRy0wil4XsRP+QcG1OwLWVK/LPZ5Y=
|
github.com/leaanthony/spinner v0.5.3 h1:IMTvgdQCec5QA4qRy0wil4XsRP+QcG1OwLWVK/LPZ5Y=
|
||||||
github.com/leaanthony/spinner v0.5.3/go.mod h1:oHlrvWicr++CVV7ALWYi+qHk/XNA91D9IJ48IqmpVUo=
|
github.com/leaanthony/spinner v0.5.3/go.mod h1:oHlrvWicr++CVV7ALWYi+qHk/XNA91D9IJ48IqmpVUo=
|
||||||
github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8=
|
github.com/leaanthony/synx v0.1.0 h1:R0lmg2w6VMb8XcotOwAe5DLyzwjLrskNkwU7LLWsyL8=
|
||||||
github.com/leaanthony/synx v0.1.0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs=
|
github.com/leaanthony/synx v0.1.0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs=
|
||||||
github.com/leaanthony/wincursor v0.1.0 h1:Dsyp68QcF5cCs65AMBmxoYNEm0n8K7mMchG6a8fYxf8=
|
github.com/leaanthony/wincursor v0.1.0 h1:Dsyp68QcF5cCs65AMBmxoYNEm0n8K7mMchG6a8fYxf8=
|
||||||
github.com/leaanthony/wincursor v0.1.0/go.mod h1:7TVwwrzSH/2Y9gLOGH+VhA+bZhoWXBRgbGNTMk+yimE=
|
github.com/leaanthony/wincursor v0.1.0/go.mod h1:7TVwwrzSH/2Y9gLOGH+VhA+bZhoWXBRgbGNTMk+yimE=
|
||||||
github.com/masterminds/semver v1.4.2 h1:BgrAYDjlAebjtOwS7C/1QZoh5WgyXx4b59ydc+Ph8xI=
|
|
||||||
github.com/masterminds/semver v1.4.2/go.mod h1:s7KNT9fnd7edGzwwP7RBX4H0v/CYd5qdOLfkL1V75yg=
|
|
||||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
|
||||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0/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/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
|
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=
|
||||||
@@ -73,27 +62,30 @@ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/wailsapp/webview v0.2.7 h1:fN5L5H9Oivg9IJPk7uaXQnjqB68Fny11ZWkIaTIZHmk=
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba h1:2DHfQOxcpWdGf5q5IzCUFPNvRX9Icf+09RvQK2VnJq0=
|
||||||
github.com/wailsapp/webview v0.2.7/go.mod h1:XO9HJbKWokDxUYTWQEBCYg95n/To1v7PxvanDNVf8hY=
|
github.com/syossan27/tebata v0.0.0-20180602121909-b283fe4bc5ba/go.mod h1:iLnlXG2Pakcii2CU0cbY07DRCSvpWNa7nFxtevhOChk=
|
||||||
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb/go.mod h1:a1CV8KR4Dd1eP2g+mEijGOp+HKczwdKHWyx0aPHKvo4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529 h1:iMGN4xG0cnqj3t+zOM8wUB0BiPKHEwSxEZCvzcbZuvk=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
|
||||||
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||||
golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb h1:pf3XwC90UUdNPYWZdFjhGBE7DUFuK3Ct1zWmZ65QN30=
|
|
||||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||||
golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4 h1:10xXXN3wgIhPheb5NI58zFgZv32Ana7P3Tl4shW+0Qc=
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4 h1:10xXXN3wgIhPheb5NI58zFgZv32Ana7P3Tl4shW+0Qc=
|
||||||
gopkg.in/AlecAivazis/survey.v1 v1.8.4/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
|
gopkg.in/AlecAivazis/survey.v1 v1.8.4/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22 h1:0efs3hwEZhFKsCoP8l6dDB1AZWMgnEl3yWXWRZTOaEA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
BIN
jetbrains-grayscale.png
Normal file
BIN
jetbrains-grayscale.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/wailsapp/wails/lib/logger"
|
"github.com/wailsapp/wails/lib/logger"
|
||||||
"github.com/wailsapp/wails/lib/messages"
|
"github.com/wailsapp/wails/lib/messages"
|
||||||
"github.com/wailsapp/wails/runtime/go/runtime"
|
"github.com/wailsapp/wails/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type internalMethods struct {
|
type internalMethods struct {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user