mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 09:00:38 +08:00
Initial commit of the Setup command
This commit is contained in:
parent
5de8efff32
commit
db550f81cd
268
cmd/cli.go
Normal file
268
cmd/cli.go
Normal file
@ -0,0 +1,268 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NewCli - Creates a new Cli application object
|
||||
func NewCli(name, description string) *Cli {
|
||||
result := &Cli{}
|
||||
result.rootCommand = NewCommand(name, description, result, "")
|
||||
result.log = NewLogger()
|
||||
return result
|
||||
}
|
||||
|
||||
// Cli - The main application object
|
||||
type Cli struct {
|
||||
rootCommand *Command
|
||||
defaultCommand *Command
|
||||
preRunCommand func(*Cli) error
|
||||
log *Logger
|
||||
}
|
||||
|
||||
// Version - Set the Application version string
|
||||
func (c *Cli) Version(version string) {
|
||||
c.rootCommand.AppVersion = version
|
||||
}
|
||||
|
||||
// PrintHelp - Prints the application's help
|
||||
func (c *Cli) PrintHelp() {
|
||||
c.rootCommand.PrintHelp()
|
||||
}
|
||||
|
||||
// Run - Runs the application with the given arguments
|
||||
func (c *Cli) Run(args ...string) error {
|
||||
if c.preRunCommand != nil {
|
||||
err := c.preRunCommand(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(args) == 0 {
|
||||
args = os.Args[1:]
|
||||
}
|
||||
return c.rootCommand.Run(args)
|
||||
}
|
||||
|
||||
// DefaultCommand - Sets the given command as the command to run when
|
||||
// no other commands given
|
||||
func (c *Cli) DefaultCommand(defaultCommand *Command) *Cli {
|
||||
c.defaultCommand = defaultCommand
|
||||
return c
|
||||
}
|
||||
|
||||
// Command - Adds a command to the application
|
||||
func (c *Cli) Command(name, description string) *Command {
|
||||
return c.rootCommand.Command(name, description)
|
||||
}
|
||||
|
||||
// PreRun - Calls the given function before running the specific command
|
||||
func (c *Cli) PreRun(callback func(*Cli) error) {
|
||||
c.preRunCommand = callback
|
||||
}
|
||||
|
||||
// BoolFlag - Adds a boolean flag to the root command
|
||||
func (c *Cli) BoolFlag(name, description string, variable *bool) *Command {
|
||||
c.rootCommand.BoolFlag(name, description, variable)
|
||||
return c.rootCommand
|
||||
}
|
||||
|
||||
// StringFlag - Adds a string flag to the root command
|
||||
func (c *Cli) StringFlag(name, description string, variable *string) *Command {
|
||||
c.rootCommand.StringFlag(name, description, variable)
|
||||
return c.rootCommand
|
||||
}
|
||||
|
||||
// Action represents a function that gets calls when the command is called by
|
||||
// the user
|
||||
type Action func() error
|
||||
|
||||
// Command represents a command that may be run by the user
|
||||
type Command struct {
|
||||
Name string
|
||||
CommandPath string
|
||||
Shortdescription string
|
||||
Longdescription string
|
||||
AppVersion string
|
||||
SubCommands []*Command
|
||||
SubCommandsMap map[string]*Command
|
||||
longestSubcommand int
|
||||
ActionCallback Action
|
||||
App *Cli
|
||||
Flags *flag.FlagSet
|
||||
flagCount int
|
||||
log *Logger
|
||||
helpFlag bool
|
||||
}
|
||||
|
||||
// NewCommand creates a new Command
|
||||
func NewCommand(name string, description string, app *Cli, parentCommandPath string) *Command {
|
||||
result := &Command{
|
||||
Name: name,
|
||||
Shortdescription: description,
|
||||
SubCommandsMap: make(map[string]*Command),
|
||||
App: app,
|
||||
}
|
||||
|
||||
// Set up command path
|
||||
if parentCommandPath != "" {
|
||||
result.CommandPath += parentCommandPath + " "
|
||||
}
|
||||
result.CommandPath += name
|
||||
|
||||
// Set up flag set
|
||||
result.Flags = flag.NewFlagSet(result.CommandPath, flag.ContinueOnError)
|
||||
result.BoolFlag("help", "Get help on the '"+result.CommandPath+"' command.", &result.helpFlag)
|
||||
|
||||
// result.Flags.Usage = result.PrintHelp
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// parseFlags parses the given flags
|
||||
func (c *Command) parseFlags(args []string) error {
|
||||
// Parse flags
|
||||
tmp := os.Stderr
|
||||
os.Stderr = nil
|
||||
err := c.Flags.Parse(args)
|
||||
os.Stderr = tmp
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n\n", err.Error())
|
||||
c.PrintHelp()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Run - Runs the Command with the given arguments
|
||||
func (c *Command) Run(args []string) error {
|
||||
|
||||
// If we have arguments, process them
|
||||
if len(args) > 0 {
|
||||
// Check for subcommand
|
||||
subcommand := c.SubCommandsMap[args[0]]
|
||||
if subcommand != nil {
|
||||
return subcommand.Run(args[1:])
|
||||
}
|
||||
|
||||
// Parse flags
|
||||
err := c.parseFlags(args)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %s\n\n", err.Error())
|
||||
c.PrintHelp()
|
||||
return err
|
||||
}
|
||||
|
||||
// Help takes precedence
|
||||
if c.helpFlag {
|
||||
c.PrintHelp()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have an action?
|
||||
if c.ActionCallback != nil {
|
||||
return c.ActionCallback()
|
||||
}
|
||||
|
||||
// If we haven't specified a subcommand
|
||||
// check for an app level default command
|
||||
if c.App.defaultCommand != nil {
|
||||
// Prevent recursion!
|
||||
if c.App.defaultCommand != c {
|
||||
return c.App.defaultCommand.Run(args)
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing left we can do
|
||||
c.PrintHelp()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Action - Define an action from this command
|
||||
func (c *Command) Action(callback Action) *Command {
|
||||
c.ActionCallback = callback
|
||||
return c
|
||||
}
|
||||
|
||||
// PrintHelp - Output the help text for this command
|
||||
func (c *Command) PrintHelp() {
|
||||
versionString := c.AppVersion
|
||||
if versionString != "" {
|
||||
versionString = " " + versionString
|
||||
}
|
||||
commandTitle := c.CommandPath
|
||||
if c.Shortdescription != "" {
|
||||
commandTitle += " - " + c.Shortdescription
|
||||
}
|
||||
// Ignore root command
|
||||
if c.CommandPath != c.Name {
|
||||
c.log.Yellow(commandTitle)
|
||||
}
|
||||
if c.Longdescription != "" {
|
||||
fmt.Println()
|
||||
fmt.Println(c.Longdescription + "\n")
|
||||
}
|
||||
if len(c.SubCommands) > 0 {
|
||||
fmt.Println("")
|
||||
c.log.White("Available commands:")
|
||||
fmt.Println("")
|
||||
for _, subcommand := range c.SubCommands {
|
||||
spacer := strings.Repeat(" ", 3+c.longestSubcommand-len(subcommand.Name))
|
||||
isDefault := ""
|
||||
if subcommand.isDefaultCommand() {
|
||||
isDefault = "[default]"
|
||||
}
|
||||
fmt.Printf(" %s%s%s %s\n", subcommand.Name, spacer, subcommand.Shortdescription, isDefault)
|
||||
}
|
||||
}
|
||||
if c.flagCount > 0 {
|
||||
fmt.Println("")
|
||||
c.log.White("Flags:")
|
||||
fmt.Println()
|
||||
c.Flags.SetOutput(os.Stdout)
|
||||
c.Flags.PrintDefaults()
|
||||
c.Flags.SetOutput(os.Stderr)
|
||||
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// isDefaultCommand returns true if called on the default command
|
||||
func (c *Command) isDefaultCommand() bool {
|
||||
return c.App.defaultCommand == c
|
||||
}
|
||||
|
||||
// Command - Defines a subcommand
|
||||
func (c *Command) Command(name, description string) *Command {
|
||||
result := NewCommand(name, description, c.App, c.CommandPath)
|
||||
result.log = c.log
|
||||
c.SubCommands = append(c.SubCommands, result)
|
||||
c.SubCommandsMap[name] = result
|
||||
if len(name) > c.longestSubcommand {
|
||||
c.longestSubcommand = len(name)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// BoolFlag - Adds a boolean flag to the command
|
||||
func (c *Command) BoolFlag(name, description string, variable *bool) *Command {
|
||||
c.Flags.BoolVar(variable, name, *variable, description)
|
||||
c.flagCount++
|
||||
return c
|
||||
}
|
||||
|
||||
// StringFlag - Adds a string flag to the command
|
||||
func (c *Command) StringFlag(name, description string, variable *string) *Command {
|
||||
c.Flags.StringVar(variable, name, *variable, description)
|
||||
c.flagCount++
|
||||
return c
|
||||
}
|
||||
|
||||
// LongDescription - Sets the long description for the command
|
||||
func (c *Command) LongDescription(Longdescription string) *Command {
|
||||
c.Longdescription = Longdescription
|
||||
return c
|
||||
}
|
130
cmd/fs.go
Normal file
130
cmd/fs.go
Normal file
@ -0,0 +1,130 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type FSHelper struct {
|
||||
}
|
||||
|
||||
func NewFSHelper() *FSHelper {
|
||||
result := &FSHelper{}
|
||||
return result
|
||||
}
|
||||
|
||||
// Returns true if the given path resolves to a directory on the filesystem
|
||||
func (fs *FSHelper) DirExists(path string) bool {
|
||||
fi, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return fi.Mode().IsDir()
|
||||
}
|
||||
|
||||
// FileExists returns a boolean value indicating whether
|
||||
// the given file exists
|
||||
func (fs *FSHelper) FileExists(path string) bool {
|
||||
fi, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return fi.Mode().IsRegular()
|
||||
}
|
||||
|
||||
// MkDirs creates the given nested directories.
|
||||
// Returns error on failure
|
||||
func (fs *FSHelper) MkDirs(fullPath string, mode ...os.FileMode) error {
|
||||
var perms os.FileMode
|
||||
perms = 0700
|
||||
if len(mode) == 1 {
|
||||
perms = mode[0]
|
||||
}
|
||||
return os.MkdirAll(fullPath, perms)
|
||||
}
|
||||
|
||||
// CopyFile from source to target
|
||||
func (fs *FSHelper) CopyFile(source, target string) error {
|
||||
s, err := os.Open(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer s.Close()
|
||||
d, err := os.Create(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(d, s); err != nil {
|
||||
d.Close()
|
||||
return err
|
||||
}
|
||||
return d.Close()
|
||||
}
|
||||
|
||||
// Cwd returns the current working directory
|
||||
// Aborts on Failure
|
||||
func (fs *FSHelper) Cwd() string {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal("Unable to get working directory!")
|
||||
}
|
||||
return cwd
|
||||
}
|
||||
|
||||
// GetSubdirs will return a list of FQPs to subdirectories in the given directory
|
||||
func (fs *FSHelper) GetSubdirs(dir string) (map[string]string, error) {
|
||||
|
||||
// Read in the directory information
|
||||
fileInfo, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Allocate space for the list
|
||||
subdirs := make(map[string]string)
|
||||
|
||||
// Pull out the directories and store in the map as
|
||||
// map["directoryName"] = "path/to/directoryName"
|
||||
for _, file := range fileInfo {
|
||||
if file.IsDir() {
|
||||
subdirs[file.Name()] = filepath.Join(dir, file.Name())
|
||||
}
|
||||
}
|
||||
return subdirs, nil
|
||||
}
|
||||
|
||||
// MkDir creates the given directory.
|
||||
// Returns error on failure
|
||||
func (fs *FSHelper) MkDir(dir string) error {
|
||||
return os.Mkdir(dir, 0700)
|
||||
}
|
||||
|
||||
// LoadAsString will attempt to load the given file and return
|
||||
// its contents as a string
|
||||
func (fs *FSHelper) LoadAsString(filename string) (string, error) {
|
||||
bytes, err := ioutil.ReadFile(filename)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
// FileMD5 returns the md5sum of the given file
|
||||
func (fs *FSHelper) FileMD5(filename string) (string, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
h := md5.New()
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%x", h.Sum(nil)), nil
|
||||
}
|
82
cmd/log.go
Normal file
82
cmd/log.go
Normal file
@ -0,0 +1,82 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
// Logger struct
|
||||
type Logger struct {
|
||||
}
|
||||
|
||||
// NewLogger creates a new logger!
|
||||
func NewLogger() *Logger {
|
||||
return &Logger{}
|
||||
}
|
||||
|
||||
// Yellow - Outputs yellow text
|
||||
func (l *Logger) Yellow(format string, a ...interface{}) {
|
||||
color.New(color.FgHiYellow).PrintfFunc()(format+"\n", a...)
|
||||
}
|
||||
|
||||
// Yellowf - Outputs yellow text without the newline
|
||||
func (l *Logger) Yellowf(format string, a ...interface{}) {
|
||||
color.New(color.FgHiYellow).PrintfFunc()(format, a...)
|
||||
}
|
||||
|
||||
// Green - Outputs Green text
|
||||
func (l *Logger) Green(format string, a ...interface{}) {
|
||||
color.New(color.FgHiGreen).PrintfFunc()(format+"\n", a...)
|
||||
}
|
||||
|
||||
// White - Outputs White text
|
||||
func (l *Logger) White(format string, a ...interface{}) {
|
||||
color.New(color.FgHiWhite).PrintfFunc()(format+"\n", a...)
|
||||
}
|
||||
|
||||
// WhiteUnderline - Outputs White text with underline
|
||||
func (l *Logger) WhiteUnderline(format string, a ...interface{}) {
|
||||
l.White(format, a...)
|
||||
l.White(l.underline(format))
|
||||
}
|
||||
|
||||
// YellowUnderline - Outputs Yellow text with underline
|
||||
func (l *Logger) YellowUnderline(format string, a ...interface{}) {
|
||||
l.Yellow(format, a...)
|
||||
l.Yellow(l.underline(format))
|
||||
}
|
||||
|
||||
// underline returns a string of a line, the length of the message given to it
|
||||
func (l *Logger) underline(message string) string {
|
||||
return strings.Repeat("-", len(message))
|
||||
}
|
||||
|
||||
// Red - Outputs Red text
|
||||
func (l *Logger) Red(format string, a ...interface{}) {
|
||||
color.New(color.FgHiRed).PrintfFunc()(format+"\n", a...)
|
||||
}
|
||||
|
||||
// Error - Outputs an Error message
|
||||
func (l *Logger) Error(format string, a ...interface{}) {
|
||||
color.New(color.FgHiRed).PrintfFunc()("Error: "+format+"\n", a...)
|
||||
}
|
||||
|
||||
// PrintBanner prints the Wails banner before running commands
|
||||
func (l *Logger) PrintBanner() error {
|
||||
banner1 := ` _ __ _ __
|
||||
| | / /___ _(_) /____
|
||||
| | /| / / __ ` + "`" + `/ / / ___/
|
||||
| |/ |/ / /_/ / / (__ ) `
|
||||
banner2 := `|__/|__/\__,_/_/_/____/ `
|
||||
|
||||
l.Yellowf(banner1)
|
||||
l.Red(Version)
|
||||
l.Yellowf(banner2)
|
||||
l.Green("https://wails.app")
|
||||
l.White("The lightweight framework for web-like apps")
|
||||
fmt.Println()
|
||||
|
||||
return nil
|
||||
}
|
43
cmd/program.go
Normal file
43
cmd/program.go
Normal file
@ -0,0 +1,43 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// ProgramHelper - Utility functions around installed applications
|
||||
type ProgramHelper struct{}
|
||||
|
||||
// NewProgramHelper - Creates a new ProgramHelper
|
||||
func NewProgramHelper() *ProgramHelper {
|
||||
return &ProgramHelper{}
|
||||
}
|
||||
|
||||
// IsInstalled tries to determine if the given binary name is installed
|
||||
func (p *ProgramHelper) IsInstalled(programName string) bool {
|
||||
_, err := exec.LookPath(programName)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Program - A struct to define an installed application/binary
|
||||
type Program struct {
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// FindProgram attempts to find the given program on the system.FindProgram
|
||||
// Returns a struct with the name and path to the program
|
||||
func (p *ProgramHelper) FindProgram(programName string) *Program {
|
||||
path, err := exec.LookPath(programName)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
path, err = filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &Program{
|
||||
Name: programName,
|
||||
Path: path,
|
||||
}
|
||||
}
|
1
cmd/setup.go
Normal file
1
cmd/setup.go
Normal file
@ -0,0 +1 @@
|
||||
package cmd
|
200
cmd/system.go
Normal file
200
cmd/system.go
Normal file
@ -0,0 +1,200 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/AlecAivazis/survey"
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
type SystemHelper struct {
|
||||
log *Logger
|
||||
fs *FSHelper
|
||||
configFilename string
|
||||
homeDir string
|
||||
wailsSystemDir string
|
||||
wailsSystemConfig string
|
||||
}
|
||||
|
||||
func NewSystemHelper() *SystemHelper {
|
||||
result := &SystemHelper{
|
||||
fs: NewFSHelper(),
|
||||
log: NewLogger(),
|
||||
configFilename: "wails.json",
|
||||
}
|
||||
result.setSystemDirs()
|
||||
return result
|
||||
}
|
||||
|
||||
// Internal
|
||||
// setSystemDirs calculates the system directories it is interested in
|
||||
func (s *SystemHelper) setSystemDirs() {
|
||||
var err error
|
||||
s.homeDir, err = homedir.Dir()
|
||||
if err != nil {
|
||||
log.Fatal("Cannot find home directory! Please file a bug report!")
|
||||
}
|
||||
// TODO: A better config system
|
||||
s.wailsSystemDir = filepath.Join(s.homeDir, ".wails")
|
||||
s.wailsSystemConfig = filepath.Join(s.wailsSystemDir, s.configFilename)
|
||||
}
|
||||
|
||||
// ConfigFileExists - Returns true if it does!
|
||||
func (s *SystemHelper) ConfigFileExists() bool {
|
||||
return s.fs.FileExists(s.wailsSystemConfig)
|
||||
}
|
||||
|
||||
// SystemDirExists - Returns true if it does!
|
||||
func (s *SystemHelper) systemDirExists() bool {
|
||||
return s.fs.DirExists(s.wailsSystemDir)
|
||||
}
|
||||
|
||||
// LoadConfig attempts to load the Wails system config
|
||||
func (s *SystemHelper) LoadConfig() (*SystemConfig, error) {
|
||||
return NewSystemConfig(s.wailsSystemConfig)
|
||||
}
|
||||
|
||||
// ConfigFileIsValid checks if the config file is valid
|
||||
func (s *SystemHelper) ConfigFileIsValid() bool {
|
||||
_, err := NewSystemConfig(s.wailsSystemConfig)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// BackupConfig attempts to backup the system config file
|
||||
func (s *SystemHelper) BackupConfig() (string, error) {
|
||||
now := strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
|
||||
backupFilename := s.wailsSystemConfig + "." + now
|
||||
err := s.fs.CopyFile(s.wailsSystemConfig, backupFilename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return backupFilename, nil
|
||||
}
|
||||
|
||||
func (s *SystemHelper) setup() error {
|
||||
|
||||
// Answers. We all need them.
|
||||
answers := &SystemConfig{}
|
||||
|
||||
// Try to load current values - ignore errors
|
||||
config, err := s.LoadConfig()
|
||||
defaultName := ""
|
||||
defaultEmail := ""
|
||||
if config != nil {
|
||||
defaultName = config.Name
|
||||
defaultEmail = config.Email
|
||||
}
|
||||
// Questions
|
||||
var simpleQs = []*survey.Question{
|
||||
{
|
||||
Name: "Name",
|
||||
Prompt: &survey.Input{
|
||||
Message: "What is your name:",
|
||||
Default: defaultName,
|
||||
},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
{
|
||||
Name: "Email",
|
||||
Prompt: &survey.Input{
|
||||
Message: "What is your email address:",
|
||||
Default: defaultEmail,
|
||||
},
|
||||
Validate: survey.Required,
|
||||
},
|
||||
}
|
||||
|
||||
// ask the questions
|
||||
err = survey.Ask(simpleQs, answers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the directory
|
||||
err = s.fs.MkDirs(s.wailsSystemDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
s.log.White("Wails config saved to: " + s.wailsSystemConfig)
|
||||
s.log.White("Feel free to customise these settings.")
|
||||
fmt.Println()
|
||||
|
||||
return answers.Save(s.wailsSystemConfig)
|
||||
}
|
||||
|
||||
// Initialise attempts to set up the Wails system.
|
||||
// An error is returns if there is a problem
|
||||
func (s *SystemHelper) Initialise() error {
|
||||
|
||||
// System dir doesn't exist
|
||||
if !s.systemDirExists() {
|
||||
s.log.Green("Welcome to Wails!")
|
||||
s.log.Green("To get you set up, I'll need to ask you a few things...")
|
||||
return s.setup()
|
||||
}
|
||||
|
||||
// Config doesn't exist
|
||||
if !s.ConfigFileExists() {
|
||||
s.log.Green("Looks like the system config is missing.")
|
||||
s.log.Green("To get you back on track, I'll need to ask you a few things...")
|
||||
return s.setup()
|
||||
}
|
||||
|
||||
// Config exists but isn't valid.
|
||||
if !s.ConfigFileIsValid() {
|
||||
s.log.Green("Looks like the system config got corrupted.")
|
||||
backupFile, err := s.BackupConfig()
|
||||
if err != nil {
|
||||
s.log.Green("I tried to backup your config file but got this error: %s", err.Error())
|
||||
} else {
|
||||
s.log.Green("Just in case you needed it, I backed up your config file here: %s", backupFile)
|
||||
}
|
||||
s.log.Green("To get you back on track, I'll need to ask you a few things...")
|
||||
return s.setup()
|
||||
}
|
||||
|
||||
return s.setup()
|
||||
}
|
||||
|
||||
type SystemConfig struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
func NewSystemConfig(filename string) (*SystemConfig, error) {
|
||||
result := &SystemConfig{}
|
||||
err := result.load(filename)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (sc *SystemConfig) Save(filename string) error {
|
||||
// Convert config to JSON string
|
||||
theJSON, err := json.MarshalIndent(sc, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write it out to the config file
|
||||
return ioutil.WriteFile(filename, theJSON, 0644)
|
||||
}
|
||||
|
||||
func (sc *SystemConfig) load(filename string) error {
|
||||
configData, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Load and unmarshall!
|
||||
err = json.Unmarshal(configData, &sc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
5
cmd/version.go
Normal file
5
cmd/version.go
Normal file
@ -0,0 +1,5 @@
|
||||
package cmd
|
||||
|
||||
// Version - Wails version
|
||||
// ...oO(There must be a better way)
|
||||
const Version = "v0.5 Alpha"
|
60
cmd/wails/0_setup.go
Normal file
60
cmd/wails/0_setup.go
Normal file
@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/wailsapp/wails/cmd"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
commandDescription := `Sets up your local environment to develop Wails apps.`
|
||||
|
||||
initCommand := app.Command("setup", "Setup the Wails environment").
|
||||
LongDescription(commandDescription)
|
||||
|
||||
initCommand.Action(func() error {
|
||||
|
||||
system := cmd.NewSystemHelper()
|
||||
err := system.Initialise()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var successMessage string
|
||||
|
||||
logger.Yellow("Checking for prerequisites...")
|
||||
// Check we have a cgo capable environment
|
||||
programHelper := cmd.NewProgramHelper()
|
||||
prerequisites := make(map[string]map[string]string)
|
||||
prerequisites["darwin"] = make(map[string]string)
|
||||
prerequisites["darwin"]["clang"] = "Please install with `xcode-select --install` and try again"
|
||||
prerequisites["darwin"]["npm"] = "Please download and install npm + node from here: https://nodejs.org/en/"
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
successMessage = "🚀 Awesome! We are going to the moon! 🚀"
|
||||
default:
|
||||
return fmt.Errorf("platform '%s' is unsupported at this time", runtime.GOOS)
|
||||
}
|
||||
|
||||
errors := false
|
||||
for name, help := range prerequisites[runtime.GOOS] {
|
||||
bin := programHelper.FindProgram(name)
|
||||
if bin == nil {
|
||||
errors = true
|
||||
logger.Red("Unable to find '%s' - %s", name, help)
|
||||
} else {
|
||||
logger.Green("Found program '%s' at '%s'", name, bin.Path)
|
||||
}
|
||||
}
|
||||
|
||||
if errors {
|
||||
err = fmt.Errorf("There were missing dependencies")
|
||||
} else {
|
||||
logger.Yellow(successMessage)
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
26
cmd/wails/main.go
Normal file
26
cmd/wails/main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/cmd"
|
||||
)
|
||||
|
||||
// Create Logger
|
||||
var logger = cmd.NewLogger()
|
||||
|
||||
// Create main app
|
||||
var app = cmd.NewCli("wails", "A cli tool for building Wails applications.")
|
||||
|
||||
// Prints the cli banner
|
||||
func printBanner(app *cmd.Cli) error {
|
||||
logger.PrintBanner()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Main!
|
||||
func main() {
|
||||
app.PreRun(printBanner)
|
||||
err := app.Run()
|
||||
if err != nil {
|
||||
logger.Error(err.Error())
|
||||
}
|
||||
}
|
14
go.mod
Normal file
14
go.mod
Normal file
@ -0,0 +1,14 @@
|
||||
module github.com/wailsapp/wails
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey v1.7.1
|
||||
github.com/fatih/color v1.7.0
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/leaanthony/spinner v0.5.0
|
||||
github.com/leaanthony/synx v0.0.0-20180923230033-60efbd9984b0 // indirect
|
||||
github.com/mattn/go-colorable v0.0.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.4 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/mitchellh/go-homedir v1.0.0
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.7.1 // indirect
|
||||
)
|
21
go.sum
Normal file
21
go.sum
Normal file
@ -0,0 +1,21 @@
|
||||
github.com/AlecAivazis/survey v1.7.1 h1:a84v5MG2296rBkTP0e+dd4l7NxFQ69v4jzMpErkjVxc=
|
||||
github.com/AlecAivazis/survey v1.7.1/go.mod h1:MVECab6WqEH1aXhj8nKIwF7HEAJAj2bhhGiSjNy3wII=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/leaanthony/spinner v0.5.0 h1:OJKn+0KP6ilHxwCEOv5Lo0wPM4PgWZWLJTeUprGJK0g=
|
||||
github.com/leaanthony/spinner v0.5.0/go.mod h1:2Mmv+8Brcw3NwPT1DdOLmW6+zWpSamDDFFsUvVHo2cc=
|
||||
github.com/leaanthony/synx v0.0.0-20180923230033-60efbd9984b0 h1:1bGojw4YacLY5bqQalojiQ7mSfQbe4WIWCEgPZagowU=
|
||||
github.com/leaanthony/synx v0.0.0-20180923230033-60efbd9984b0/go.mod h1:Iz7eybeeG8bdq640iR+CwYb8p+9EOsgMWghkSRyZcqs=
|
||||
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-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
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/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/wailsapp/wails v0.0.0-20181215232634-5de8efff325d h1:lk91T4sKD98eGcaz/xC6ER+3o9Kaun7Mk8e/cNZOPMc=
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.7.1 h1:mzQIVyOPSXJaQWi1m6AFCjrCEPIwQBSOn48Ri8ZpzAg=
|
||||
gopkg.in/AlecAivazis/survey.v1 v1.7.1/go.mod h1:2Ehl7OqkBl3Xb8VmC4oFW2bItAhnUfzIjrOzwRxCrOU=
|
Loading…
Reference in New Issue
Block a user