Add doctor.

This commit is contained in:
Lea Anthony 2023-09-03 08:39:23 +10:00
commit 4bb522d303
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
11 changed files with 299 additions and 17 deletions

View file

@ -27,6 +27,7 @@ func init() {
func main() {
app := clir.NewCli("wails", "The Wails CLI", "v3")
app.NewSubCommandFunction("build", "Build the project", commands.Build)
app.NewSubCommandFunction("doctor", "System status report", commands.Doctor)
app.NewSubCommandFunction("init", "Initialise a new project", commands.Init)
task := app.NewSubCommand("task", "Run and list tasks")
var taskFlags commands.RunTaskOptions

View file

@ -30,7 +30,6 @@ require (
github.com/tc-hib/winres v0.1.6
github.com/wailsapp/go-webview2 v1.0.6-0.20230901120557-e959fdf1ccc3
github.com/wailsapp/mimetype v1.4.1
github.com/wailsapp/wails/v3/cmd/wails3/ui v0.0.0-20210706143420-7d21f8c997e2
golang.org/x/net v0.10.0
golang.org/x/sys v0.11.0
modernc.org/sqlite v1.21.0
@ -100,5 +99,3 @@ require (
)
replace github.com/ebitengine/purego v0.4.0-alpha.4 => github.com/tmclane/purego v0.0.0-20230601213035-1f25e70d7b01
replace github.com/wailsapp/wails/v3/cmd/wails3/ui => D:\GolandProjects\wails\v3\cmd\wails3\ui

View file

@ -299,16 +299,15 @@ github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY=
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY=
github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo=
github.com/samber/lo v1.37.0 h1:XjVcB8g6tgUp8rsPsJ2CvhClfImrpL04YpQHXeHPhRw=
github.com/samber/lo v1.37.0/go.mod h1:9vaz2O4o8oOnK23pd2TrXufcbdbJIa3b6cstBWKpopA=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
@ -335,8 +334,7 @@ github.com/tc-hib/winres v0.1.6 h1:qgsYHze+BxQPEYilxIz/KCQGaClvI2+yLBAZs+3+0B8=
github.com/tc-hib/winres v0.1.6/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A=
github.com/tmclane/purego v0.0.0-20230601213035-1f25e70d7b01 h1:oQwu3iNDywGp1Hry+PDvz+grwbCGpzY+ckSnWKCnX5Y=
github.com/tmclane/purego v0.0.0-20230601213035-1f25e70d7b01/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
github.com/wailsapp/go-webview2 v1.0.5 h1:VtPABYX2Zwpi0BxGy0vpZ9mTOGDHxCDLZa0gvgJWhhI=
github.com/wailsapp/go-webview2 v1.0.5/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
github.com/wailsapp/go-webview2 v1.0.6-0.20230901120557-e959fdf1ccc3 h1:lN7ATT1NZrwKjn2F/VSRJxJeWQZvuypzRHeLwr2No4Q=
github.com/wailsapp/go-webview2 v1.0.6-0.20230901120557-e959fdf1ccc3/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
@ -437,8 +435,7 @@ golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5o
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -516,8 +513,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -565,8 +562,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View file

@ -0,0 +1,11 @@
package commands
import (
"github.com/wailsapp/wails/v3/internal/doctor"
)
type DoctorOptions struct{}
func Doctor(_ *DoctorOptions) error {
return doctor.Run()
}

View file

@ -2,14 +2,12 @@ package commands
import (
_ "embed"
"github.com/wailsapp/wails/v3/internal/version"
)
//go:embed version.txt
var VersionString string
type VersionOptions struct{}
func Version(_ *VersionOptions) error {
println(VersionString)
println(version.VersionString)
return nil
}

View file

@ -0,0 +1,235 @@
package doctor
import (
"fmt"
"github.com/go-git/go-git/v5"
"github.com/pterm/pterm"
"github.com/samber/lo"
"github.com/wailsapp/wails/v3/internal/operatingsystem"
"github.com/wailsapp/wails/v3/internal/version"
"path/filepath"
"runtime"
"runtime/debug"
"slices"
)
func Run() (err error) {
pterm.DefaultSection = *pterm.DefaultSection.
WithBottomPadding(0).
WithStyle(pterm.NewStyle(pterm.FgBlue, pterm.Bold))
pterm.Println() // Spacer
pterm.DefaultHeader.WithBackgroundStyle(pterm.NewStyle(pterm.BgLightBlue)).WithMargin(10).Println("Wails Doctor")
pterm.Println() // Spacer
spinner, _ := pterm.DefaultSpinner.WithRemoveWhenDone().Start("Scanning system - Please wait (this may take a long time)...")
defer func() {
if err != nil {
spinner.Fail()
}
}()
/** Build **/
// BuildSettings contains the build settings for the application
var BuildSettings map[string]string
// BuildInfo contains the build info for the application
var BuildInfo *debug.BuildInfo
var ok bool
BuildInfo, ok = debug.ReadBuildInfo()
if !ok {
return fmt.Errorf("could not read build info from binary")
}
BuildSettings = lo.Associate(BuildInfo.Settings, func(setting debug.BuildSetting) (string, string) {
return setting.Key, setting.Value
})
/** Operating System **/
// Get system info
info, err := operatingsystem.Info()
if err != nil {
pterm.Error.Println("Failed to get system information")
return err
}
/** Wails **/
wailsPackage, _ := lo.Find(BuildInfo.Deps, func(dep *debug.Module) bool {
return dep.Path == "github.com/wailsapp/wails/v3"
})
wailsVersion := version.VersionString
if wailsPackage != nil && wailsPackage.Replace != nil {
wailsVersion = "(local) => " + filepath.ToSlash(wailsPackage.Replace.Path)
// Get the latest commit hash
repo, err := git.PlainOpen(filepath.Join(wailsPackage.Replace.Path, ".."))
if err == nil {
head, err := repo.Head()
if err == nil {
wailsVersion += " (" + head.Hash().String()[:8] + ")"
}
}
}
platformExtras := getInfo()
spinner.Success()
/** Output **/
pterm.DefaultSection.Println("Build Environment")
tableData := pterm.TableData{
{"Wails CLI", wailsVersion},
{"Go Version", runtime.Version()},
}
if buildInfo, _ := debug.ReadBuildInfo(); buildInfo != nil {
buildSettingToName := map[string]string{
"vcs.revision": "Revision",
"vcs.modified": "Modified",
}
for _, buildSetting := range buildInfo.Settings {
name := buildSettingToName[buildSetting.Key]
if name == "" {
continue
}
tableData = append(tableData, []string{name, buildSetting.Value})
}
}
mapKeys := lo.Keys(BuildSettings)
slices.Sort(mapKeys)
for _, key := range mapKeys {
tableData = append(tableData, []string{key, BuildSettings[key]})
}
//// Exit early if PM not found
//if info.PM != nil {
// wailsTableData = append(wailsTableData, []string{"Package Manager", info.PM.Name()})
//}
err = pterm.DefaultTable.WithData(tableData).Render()
if err != nil {
return err
}
pterm.DefaultSection.Println("Operating System")
systemTabledata := pterm.TableData{
{pterm.Sprint("Name"), info.Name},
{pterm.Sprint("Version"), info.Version},
{pterm.Sprint("ID"), info.ID},
{pterm.Sprint("Branding"), info.Branding},
{pterm.Sprint("Platform"), runtime.GOOS},
{pterm.Sprint("Architecture"), runtime.GOARCH},
}
mapKeys = lo.Keys(platformExtras)
slices.Sort(mapKeys)
for _, key := range mapKeys {
systemTabledata = append(systemTabledata, []string{key, platformExtras[key]})
}
err = pterm.DefaultTable.WithData(systemTabledata).Render()
if err != nil {
return err
}
/*
pterm.DefaultSection.Println("Dependencies")
// Output Dependencies Status
var dependenciesMissing []string
var externalPackages []*packagemanager.Dependency
var dependenciesAvailableRequired = 0
var dependenciesAvailableOptional = 0
dependenciesTableData := pterm.TableData{
{"Dependency", "Package Name", "Status", "Version"},
}
hasOptionalDependencies := false
// Loop over dependencies
for _, dependency := range info.Dependencies {
name := dependency.Name
if dependency.Optional {
name = pterm.Gray("*") + name
hasOptionalDependencies = true
}
packageName := "Unknown"
status := pterm.LightRed("Not Found")
// If we found the package
if dependency.PackageName != "" {
packageName = dependency.PackageName
// If it's installed, update the status
if dependency.Installed {
status = pterm.LightGreen("Installed")
} else {
// Generate meaningful status text
status = pterm.LightMagenta("Available")
if dependency.Optional {
dependenciesAvailableOptional++
} else {
dependenciesAvailableRequired++
}
}
} else {
if !dependency.Optional {
dependenciesMissing = append(dependenciesMissing, dependency.Name)
}
if dependency.External {
externalPackages = append(externalPackages, dependency)
}
}
dependenciesTableData = append(dependenciesTableData, []string{name, packageName, status, dependency.Version})
}
dependenciesTableString, _ := pterm.DefaultTable.WithHasHeader(true).WithData(dependenciesTableData).Srender()
dependenciesBox := pterm.DefaultBox.WithTitleBottomCenter()
if hasOptionalDependencies {
dependenciesBox = dependenciesBox.WithTitle(pterm.Gray("*") + " - Optional Dependency")
}
dependenciesBox.Println(dependenciesTableString)
pterm.DefaultSection.Println("Diagnosis")
// Generate an appropriate diagnosis
if dependenciesAvailableRequired != 0 {
pterm.Println("Required package(s) installation details: \n" + info.Dependencies.InstallAllRequiredCommand())
}
if dependenciesAvailableOptional != 0 {
pterm.Println("Optional package(s) installation details: \n" + info.Dependencies.InstallAllOptionalCommand())
}
if len(dependenciesMissing) == 0 && dependenciesAvailableRequired == 0 {
pterm.Success.Println("Your system is ready for Wails development!")
} else {
pterm.Warning.Println("Your system has missing dependencies!")
}
if len(dependenciesMissing) != 0 {
pterm.Println("Fatal:")
pterm.Println("Required dependencies missing: " + strings.Join(dependenciesMissing, " "))
pterm.Println("Please read this article on how to resolve this: https://wails.io/guides/resolving-missing-packages")
}
pterm.Println() // Spacer for sponsor message
*/
return nil
}

View file

@ -0,0 +1,8 @@
//go:build darwin
package doctor
func getInfo() map[string]string {
result := make(map[string]string)
return result
}

View file

@ -0,0 +1,8 @@
//go:build linux
package doctor
func getInfo() map[string]string {
result := make(map[string]string)
return result
}

View file

@ -0,0 +1,20 @@
//go:build windows
package doctor
import (
"github.com/samber/lo"
"github.com/wailsapp/go-webview2/webviewloader"
)
func getInfo() map[string]string {
result := make(map[string]string)
result["Go WebView2Loader"] = lo.Ternary(webviewloader.UsingGoWebview2Loader, "true", "false")
webviewVersion, err := webviewloader.GetAvailableCoreWebView2BrowserVersionString("")
if err != nil {
webviewVersion = "Error:" + err.Error()
}
result["WebView2 Version"] = webviewVersion
return result
}

View file

@ -0,0 +1,8 @@
package version
import (
_ "embed"
)
//go:embed version.txt
var VersionString string