5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-03 06:51:26 +08:00

feat: support checking prerequisites

This commit is contained in:
Lea Anthony 2018-12-22 18:40:36 -08:00
parent 3e97a4cc4d
commit 807f772055
3 changed files with 144 additions and 85 deletions

View File

@ -1,6 +1,7 @@
package cmd
import (
"fmt"
"strings"
)
@ -8,8 +9,9 @@ import (
type LinuxDistribution int
const (
// Ubuntu distro
Ubuntu LinuxDistribution = 0
// Unknown is the catch-all distro
Unknown LinuxDistribution = 0
Ubuntu LinuxDistribution = 1
)
// DistroInfo contains all the information relating to a linux distribution
@ -18,11 +20,12 @@ type DistroInfo struct {
Description string
Release string
Codename string
DistributorId string
DistributorID string
}
// GetLinuxDistroInfo returns information about the running linux distribution
func GetLinuxDistroInfo() *DistroInfo {
result := &DistroInfo{}
result := &DistroInfo{Distribution: Unknown}
program := NewProgramHelper()
// Does lsb_release exist?
@ -30,7 +33,7 @@ func GetLinuxDistroInfo() *DistroInfo {
if lsbRelease != nil {
stdout, _, err, _ := lsbRelease.Run("-a")
if err != nil {
return nil
return result
}
for _, line := range strings.Split(stdout, "\n") {
@ -41,7 +44,11 @@ func GetLinuxDistroInfo() *DistroInfo {
value := strings.TrimSpace(details[1])
switch key {
case "Distributor ID":
result.DistributorId = value
result.DistributorID = value
switch value {
case "Ubuntu":
result.Distribution = Ubuntu
}
case "Description":
result.Description = value
case "Release":
@ -56,3 +63,16 @@ func GetLinuxDistroInfo() *DistroInfo {
}
return result
}
// DpkgInstalled uses dpkg to see if a package is installed
func DpkgInstalled(packageName string) (bool, error) {
result := false
program := NewProgramHelper()
dpkg := program.FindProgram("dpkg")
if dpkg == nil {
return false, fmt.Errorf("cannot check dependencies: dpkg not found")
}
_, _, _, exitCode := dpkg.Run("-L", packageName)
result = exitCode == 0
return result, nil
}

View File

@ -5,88 +5,100 @@ import (
"runtime"
)
// binaryPrerequisite defines a binaryPrerequisite
type binaryPrerequisite struct {
// Prerequisite defines a Prerequisite!
type Prerequisite struct {
Name string
Help string
Path string
}
func newBinaryPrerequisite(name, help string) *binaryPrerequisite {
return &binaryPrerequisite{Name: name, Help: help}
func newPrerequisite(name, help string) *Prerequisite {
return &Prerequisite{Name: name, Help: help}
}
// binaryPrerequisites is a list of binaryPrerequisites
type binaryPrerequisites []*binaryPrerequisite
// Prerequisites is a list of things required to use Wails
type Prerequisites []*Prerequisite
// Add given prereq object to list
func (p *binaryPrerequisites) Add(prereq *binaryPrerequisite) {
func (p *Prerequisites) Add(prereq *Prerequisite) {
*p = append(*p, prereq)
}
func (p *binaryPrerequisites) check() (success *binaryPrerequisites, failed *binaryPrerequisites) {
success = &binaryPrerequisites{}
failed = &binaryPrerequisites{}
programHelper := NewProgramHelper()
for _, prereq := range *p {
bin := programHelper.FindProgram(prereq.Name)
if bin == nil {
failed.Add(prereq)
} else {
path, err := bin.GetFullPathToBinary()
if err != nil {
failed.Add(prereq)
} else {
prereq.Path = path
success.Add(prereq)
}
}
}
return success, failed
}
var platformbinaryPrerequisites = make(map[string]*binaryPrerequisites)
func init() {
platformbinaryPrerequisites["darwin"] = &binaryPrerequisites{}
newDarwinbinaryPrerequisite("clang", "Please install with `xcode-select --install` and try again")
platformbinaryPrerequisites["linux"] = &binaryPrerequisites{}
linuxInfo := GetLinuxDistroInfo()
switch linuxInfo.Distribution {
case Ubuntu:
newLinuxbinaryPrerequisite("gcc", "Please install with 'sudo apt install build-essential' ")
// GetRequiredPrograms returns a list of programs required for the platform
func GetRequiredPrograms() (*Prerequisites, error) {
switch runtime.GOOS {
case "darwin":
return getRequiredProgramsOSX(), nil
case "linux":
return getRequiredProgramsLinux(), nil
case "windows":
return getRequiredProgramsWindows(), nil
default:
newLinuxbinaryPrerequisite("gcc", "Please install with your system package manager.")
return nil, fmt.Errorf("platform '%s' not supported at this time", runtime.GOOS)
}
}
func newDarwinbinaryPrerequisite(name, help string) {
prereq := newBinaryPrerequisite(name, help)
platformbinaryPrerequisites["darwin"].Add(prereq)
func getRequiredProgramsOSX() *Prerequisites {
result := &Prerequisites{}
result.Add(newPrerequisite("clang", "Please install with `xcode-select --install` and try again"))
return result
}
func newLinuxbinaryPrerequisite(name, help string) {
prereq := newBinaryPrerequisite(name, help)
platformbinaryPrerequisites["linux"].Add(prereq)
}
func CheckBinaryPrerequisites() (*binaryPrerequisites, *binaryPrerequisites, error) {
platformPreReqs := platformbinaryPrerequisites[runtime.GOOS]
if platformPreReqs == nil {
return nil, nil, fmt.Errorf("Platform '%s' is not supported at this time", runtime.GOOS)
}
success, failed := platformPreReqs.check()
return success, failed, nil
}
func CheckNonBinaryPrerequisites() error {
var err error
// Check non-binaries
if runtime.GOOS == "linux" {
func getRequiredProgramsLinux() *Prerequisites {
result := &Prerequisites{}
distroInfo := GetLinuxDistroInfo()
switch distroInfo.Distribution {
case Ubuntu:
result.Add(newPrerequisite("gcc", "Please install with `sudo apt install build-essentials` and try again"))
result.Add(newPrerequisite("pkg-config", "Please install with `sudo apt install pkg-config` and try again"))
default:
result.Add(newPrerequisite("gcc", "Please install with your system package manager and try again"))
result.Add(newPrerequisite("pkg-config", "Please install with your system package manager and try again"))
}
return err
return result
}
// TODO: Test this on Windows
func getRequiredProgramsWindows() *Prerequisites {
result := &Prerequisites{}
return result
}
// GetRequiredLibraries returns a list of libraries (packages) required for the platform
func GetRequiredLibraries() (*Prerequisites, error) {
switch runtime.GOOS {
case "darwin":
return getRequiredLibrariesOSX()
case "linux":
return getRequiredLibrariesLinux()
case "windows":
return getRequiredLibrariesWindows()
default:
return nil, fmt.Errorf("platform '%s' not supported at this time", runtime.GOOS)
}
}
func getRequiredLibrariesOSX() (*Prerequisites, error) {
result := &Prerequisites{}
return result, nil
}
func getRequiredLibrariesLinux() (*Prerequisites, error) {
result := &Prerequisites{}
distroInfo := GetLinuxDistroInfo()
switch distroInfo.Distribution {
case Ubuntu:
result.Add(newPrerequisite("libgtk-3-dev", "Please install with `sudo apt install libgtk-3-dev` and try again"))
result.Add(newPrerequisite("libwebkit2gtk-4.0-dev", "Please install with `sudo apt install libwebkit2gtk-4.0-dev` 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
}
func getRequiredLibrariesWindows() (*Prerequisites, error) {
result := &Prerequisites{}
return result, nil
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"runtime"
"github.com/leaanthony/spinner"
"github.com/wailsapp/wails/cmd"
)
@ -41,29 +42,55 @@ Create your first project by running 'wails init'.`
logger.Yellow("Checking for prerequisites...")
// Check we have a cgo capable environment
successDeps, failedDeps, err := cmd.CheckBinaryPrerequisites()
requiredPrograms, err := cmd.GetRequiredPrograms()
if err != nil {
return err
}
errors := false
spinner := spinner.New()
programHelper := cmd.NewProgramHelper()
for _, program := range *requiredPrograms {
spinner.Start("Looking for program '%s'", program.Name)
bin := programHelper.FindProgram(program.Name)
if bin == nil {
errors = true
spinner.Errorf("Program '%s' not found. %s", program.Name, program.Help)
} else {
spinner.Successf("Program '%s' found: %s", program.Name, bin.Path)
}
}
for _, dep := range *successDeps {
logger.Green("Found '%s' at '%s'", dep.Name, dep.Path)
// Linux has library deps
if runtime.GOOS == "linux" {
// Check library prerequisites
requiredLibraries, err := cmd.GetRequiredLibraries()
if err != nil {
return err
}
distroInfo := cmd.GetLinuxDistroInfo()
for _, library := range *requiredLibraries {
spinner.Start()
switch distroInfo.Distribution {
case cmd.Ubuntu:
installed, err := cmd.DpkgInstalled(library.Name)
if err != nil {
return err
}
if !installed {
errors = true
spinner.Errorf("Library '%s' not found. %s", library.Name, library.Help)
} else {
spinner.Successf("Library '%s' installed.", library.Name)
}
default:
return fmt.Errorf("unable to check libraries on distribution '%s'. Please ensure that the '%s' equivalent is installed", distroInfo.DistributorID, library.Name)
}
}
}
logger.White("")
for _, dep := range *failedDeps {
logger.Red("PreRequisite '%s' missing. %s", dep.Name, dep.Help)
}
// Check non-binary prerequisites
err = cmd.CheckNonBinaryPrerequisites()
if err != nil {
return err
}
if len(*failedDeps) == 0 {
if !errors {
logger.Yellow(successMessage)
}