mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 07:41:37 +08:00

* feat: attempt to support Zorin * chore: bump version * Add support for Gentoo * docs: update contributors * feat: test support for Fedora * chore: version bump * Update README.md * feat: major refactor * fix: config errors * fix: capitalisation and binding fix * fix: lint * fix: linting * config: eslint * fix: more lint fixes * fix: linting for hound * Even more fixes * chore: bump version * fix: eslintrc config * fix: renamed global logger * fix: Print stdout on error :rolleyes: * fix: add promises polyfill for the windows target * style: replace double quotes with single quotes * Update contributors * feat: significant overhaul of runtime * chore: Version Bump * Fix Masterminds/semver reference import path (case-sensitivity) * drop lsb_release Signed-off-by: Chronophylos <nikolai@chronophylos.com> * change DistributionID to NAME= Signed-off-by: Chronophylos <nikolai@chronophylos.com> * show distro id when creating a issue Signed-off-by: Chronophylos <nikolai@chronophylos.com> * fix assumption Signed-off-by: Chronophylos <nikolai@chronophylos.com> * docs: updated contributors * fix: add support back for ubuntu, redhat * chore: version bump * fix(linux): fedora & centos support * feat: gcc,npm,node versions on issues * linux working * darwin working * feat: show gcc, node, npm version on issue report * Delete npm-debug.log * fix: crashing typo * trim gcc string * chore: version bump * fix: gitbash fixes * chore: hotfix * fix: issue report * fix: typo * chore: hotfix version bump * 179 parrot distributionsupport (#181) * feat: parrot support && git push * feat: parrot support * feat: parrot support * fix: arch support * fix: gentoos support * Update README.md * Update README.md * chore: bump version * Linux db (#182) * feat: refactor linux distro detection * linux db updates * feat: add gccversioncommand + windows support * fix: build-essential * chore: linter fixes (#185) * 182 linux bd (#183) * fix: linuxdb.yaml entries * fix: typo * fix: yaml syntax error * 188 support distribution linux mint (#189) * chore: update linux db * chore: bump version * chore: merge webview back in * chore: rename webview for clarity * chore: add stale issue bot config * chore: add inprogress label * Azure Pipelines (#192) * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * test: azure pipeline * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * feat: azure pipelines * chore: remove unused mewn file * chore: deduplicate library verificaation code * Update contributors * fix: undefined: webview during build * feat: VoidLinux support * Yaml bug (#207) * test: azure pipeline * fix: azure pipeline yaml * feat: elementary support * feat: opensuse support * fix: 0_setup.go line 27 * fix: 0_setup.go line 27 * fix: opensuse yaml * fix: opensuse yaml * fix: opensuse yaml * fix: opensuse yaml * fix: opensuse yaml * fix: opensuse yaml * fix: yaml * fix: yaml * fix: yaml * fix: opensuse yaml * fix: opensuse * fix: opensuse * fix: opensuse * fix: opensuse * fix: string trim os osRelease field NAME * fix: 0_setup.go if err typo * test * test * fix: typo in linux.go * test: remove quotes from opensuse case * test: revert * test: "" * test: "" * test: "" * test: "" * fix: replace trim with replace * fix: drop 0_setup.go and run checks by system.go * fix: elementary os yaml name * fix: open suse yaml entry * fix: commented out result.Release = version * fix: commented out result.Release = version * fix: revert Replace to Trim * fix: Linux Mint yaml entry * fix: capitalize distros entries * fix: capitalize distros entries * fix: capitalize distros entries * test * test * fix: open suse yaml entry * fix: yaml entris * test * test * test * test * test * test * branch changing * fix: bug in setup process * debugging * debugging * debugging * debugging * fix: yaml entries & err == nil bug * Update prerequisites.go * fix: bug * fix: 0_setup.go * fix: yaml bug * fix: yaml bug * chore: bump version * Elementary support + readme update (#210) * test: azure pipeline * fix: azure pipeline yaml * feat: elementary support+readme udpate * fix: upgrade eslint * 215 support distribution kali (#219) * test: azure pipeline * fix: azure pipeline yaml * feat: kali linux support * feat: kali linux support * fix: allow 0 return types * duplicate code spotted (#221) * fix: duplicate code * chore: release v0.17.14-pre * chore: remove debug output * (FIX) 215 support distribution kali (#224) * fix: kali support * docs: add Mattn * feat: KDE neon support (#234) * chore: version bump * chore: remove some debug output * fix: binding more than one struct method (#245) * feat: add runtime typings * fix: multiple runtime fixes * manjaro (#248) * manjaro * Update go.mod * chore: version bump * fix: update runtime * chore: version bump * cmd/wails: report error status code to OS (#252) Fixes #251. * Update CONTRIBUTORS.md * chore: version bump * fix: importing runtime (#254) * chore: supress warnings * Patch for file dialog on OSX (#258) * Patch for file dialog on OSX * Update CONTRIBUTORS.md * 262 add wails shutdown method (#264) * feat: support close in bridge mode * feat: WailsShutdown callback Now handles proper shutdown through: * runtime.Window.Close() * Killing the main window * Ctrl-C * chore: version bump * fix: force install when node_modules missing (#268) * fix: detect encoding on windows (#266) * fix: linting * chore: bump version * Migrate tool (#270) Experimental migration tool for projects < v1.0.0 * chore: version bump * fix: add flag to fix windows builds (#272) * Bump version to v0.18.9-pre * 261 korean fonts (#273) * fix: linting * chore: bump version * fix: unicode text for Windows * release v0.18.10-pre * 274 support spaces in windows paths (#275) * fix: escape windows commands * fix: allow spaces in path to windres * Update go.mod * release v0.18.11-pre * 261 korean fonts (#276) * fix: linting * chore: bump version * fix: unicode text for Windows * fix: re-add webview_set_title * release v0.18.12-pre * hotfix: build issue for windows * fix: npm/node version reporting * fix: debug build should use terminal * fix: make binary name more os specific * Backport (#283) * Develop (#265) * Patch for file dialog on OSX * Update CONTRIBUTORS.md * 262 add wails shutdown method (#264) * feat: support close in bridge mode * feat: WailsShutdown callback Now handles proper shutdown through: * runtime.Window.Close() * Killing the main window * Ctrl-C * chore: version bump * chore: version bump * feat: adjust binary name for OS * fix: allow spaces in gcc path * feat: migrate command * fix: npm/node versions * fix: allow IE for serve * feat: go build script * fix: make runtime ES2015 compliant * fix: remove invoke patch * fix: allow any line endings * chore: remove legacy bridge files * chore: latest assets * v0.18.15-pre * fix: remove unicode flag * chore: bump version * release v0.19.0
371 lines
9.3 KiB
Go
371 lines
9.3 KiB
Go
package cmd
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"sort"
|
|
"strings"
|
|
|
|
"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 {
|
|
Name string `json:"name"`
|
|
Email string `json:"email"`
|
|
}
|
|
|
|
type frontend struct {
|
|
Dir string `json:"dir"`
|
|
Install string `json:"install"`
|
|
Build string `json:"build"`
|
|
Bridge string `json:"bridge"`
|
|
Serve string `json:"serve"`
|
|
}
|
|
|
|
type framework struct {
|
|
Name string `json:"name"`
|
|
BuildTag string `json:"buildtag"`
|
|
Options map[string]string `json:"options,omitempty"`
|
|
}
|
|
|
|
// ProjectHelper is a helper struct for managing projects
|
|
type ProjectHelper struct {
|
|
log *Logger
|
|
system *SystemHelper
|
|
templates *TemplateHelper
|
|
}
|
|
|
|
// NewProjectHelper creates a new Project helper struct
|
|
func NewProjectHelper() *ProjectHelper {
|
|
return &ProjectHelper{
|
|
log: NewLogger(),
|
|
system: NewSystemHelper(),
|
|
templates: NewTemplateHelper(),
|
|
}
|
|
}
|
|
|
|
// GenerateProject generates a new project using the options given
|
|
func (ph *ProjectHelper) GenerateProject(projectOptions *ProjectOptions) error {
|
|
|
|
// Calculate project path
|
|
projectPath, err := filepath.Abs(projectOptions.OutputDirectory)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_ = projectPath
|
|
|
|
if fs.DirExists(projectPath) {
|
|
return fmt.Errorf("directory '%s' already exists", projectPath)
|
|
}
|
|
|
|
// Create project directory
|
|
err = fs.MkDir(projectPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create and save project config
|
|
err = projectOptions.WriteProjectConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = ph.templates.InstallTemplate(projectPath, projectOptions)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// // If we are on windows, dump a windows_resource.json
|
|
// if runtime.GOOS == "windows" {
|
|
// ph.GenerateWindowsResourceConfig(projectOptions)
|
|
// }
|
|
|
|
return nil
|
|
}
|
|
|
|
// // GenerateWindowsResourceConfig generates the default windows resource file
|
|
// func (ph *ProjectHelper) GenerateWindowsResourceConfig(po *ProjectOptions) {
|
|
|
|
// fmt.Println(buffer.String())
|
|
|
|
// // vi.Build()
|
|
// // vi.Walk()
|
|
// // err := vi.WriteSyso(outPath, runtime.GOARCH)
|
|
// }
|
|
|
|
// LoadProjectConfig loads the project config from the given directory
|
|
func (ph *ProjectHelper) LoadProjectConfig(dir string) (*ProjectOptions, error) {
|
|
po := ph.NewProjectOptions()
|
|
err := po.LoadConfig(dir)
|
|
return po, err
|
|
}
|
|
|
|
// NewProjectOptions creates a new default set of project options
|
|
func (ph *ProjectHelper) NewProjectOptions() *ProjectOptions {
|
|
result := ProjectOptions{
|
|
Name: "",
|
|
Description: "Enter your project description",
|
|
Version: "0.1.0",
|
|
BinaryName: "",
|
|
system: ph.system,
|
|
log: ph.log,
|
|
templates: ph.templates,
|
|
Author: &author{},
|
|
}
|
|
|
|
// Populate system config
|
|
config, err := ph.system.LoadConfig()
|
|
if err == nil {
|
|
result.Author.Name = config.Name
|
|
result.Author.Email = config.Email
|
|
}
|
|
|
|
return &result
|
|
}
|
|
|
|
// ProjectOptions holds all the options available for a project
|
|
type ProjectOptions struct {
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Author *author `json:"author,omitempty"`
|
|
Version string `json:"version"`
|
|
OutputDirectory string `json:"-"`
|
|
UseDefaults bool `json:"-"`
|
|
Template string `json:"-"`
|
|
BinaryName string `json:"binaryname"`
|
|
FrontEnd *frontend `json:"frontend,omitempty"`
|
|
NPMProjectName string `json:"-"`
|
|
system *SystemHelper
|
|
log *Logger
|
|
templates *TemplateHelper
|
|
selectedTemplate *TemplateDetails
|
|
WailsVersion string
|
|
}
|
|
|
|
// Defaults sets the default project template
|
|
func (po *ProjectOptions) Defaults() {
|
|
po.Template = "vuebasic"
|
|
po.WailsVersion = Version
|
|
}
|
|
|
|
// 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
|
|
func (po *ProjectOptions) PromptForInputs() error {
|
|
|
|
processProjectName(po)
|
|
|
|
processBinaryName(po)
|
|
|
|
err := processOutputDirectory(po)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Process Templates
|
|
templateList := slicer.Interface()
|
|
options := slicer.String()
|
|
templateDetails, err := po.templates.GetTemplateDetails()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if po.Template != "" {
|
|
// Check template is valid if given
|
|
if templateDetails[po.Template] == nil {
|
|
keys := make([]string, 0, len(templateDetails))
|
|
for k := range templateDetails {
|
|
keys = append(keys, k)
|
|
}
|
|
return fmt.Errorf("invalid template name '%s'. Valid options: %s", po.Template, strings.Join(keys, ", "))
|
|
}
|
|
po.selectedTemplate = templateDetails[po.Template]
|
|
} else {
|
|
|
|
keys := make([]string, 0)
|
|
for k := range templateDetails {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
for _, k := range keys {
|
|
templateDetail := templateDetails[k]
|
|
templateList.Add(templateDetail)
|
|
options.Add(fmt.Sprintf("%s - %s", templateDetail.Metadata.Name, templateDetail.Metadata.ShortDescription))
|
|
}
|
|
|
|
templateIndex := 0
|
|
|
|
if len(options.AsSlice()) > 1 {
|
|
templateIndex = PromptSelection("Please select a template", options.AsSlice(), 0)
|
|
}
|
|
|
|
if len(templateList.AsSlice()) == 0 {
|
|
return fmt.Errorf("aborting: no templates found")
|
|
}
|
|
|
|
// After selection do this....
|
|
po.selectedTemplate = templateList.AsSlice()[templateIndex].(*TemplateDetails)
|
|
}
|
|
|
|
fmt.Println("Template: " + po.selectedTemplate.Metadata.Name)
|
|
|
|
// Setup NPM Project name
|
|
po.NPMProjectName = strings.ToLower(strings.Replace(po.Name, " ", "_", -1))
|
|
|
|
// Fix template name
|
|
po.Template = strings.Split(po.selectedTemplate.Path, string(os.PathSeparator))[0]
|
|
|
|
// // Populate template details
|
|
templateMetadata := po.selectedTemplate.Metadata
|
|
|
|
err = processTemplateMetadata(templateMetadata, po)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// WriteProjectConfig writes the project configuration into
|
|
// the project directory
|
|
func (po *ProjectOptions) WriteProjectConfig() error {
|
|
targetDir, err := filepath.Abs(po.OutputDirectory)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
targetFile := filepath.Join(targetDir, "project.json")
|
|
filedata, err := json.MarshalIndent(po, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return ioutil.WriteFile(targetFile, filedata, 0600)
|
|
}
|
|
|
|
// LoadConfig loads the project configuration file from the
|
|
// given directory
|
|
func (po *ProjectOptions) LoadConfig(projectDir string) error {
|
|
targetFile := filepath.Join(projectDir, "project.json")
|
|
rawBytes, err := ioutil.ReadFile(targetFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.Unmarshal(rawBytes, po)
|
|
}
|
|
|
|
func computeBinaryName(projectName string) string {
|
|
if projectName == "" {
|
|
return ""
|
|
}
|
|
var binaryNameComputed = strings.ToLower(projectName)
|
|
binaryNameComputed = strings.Replace(binaryNameComputed, " ", "-", -1)
|
|
binaryNameComputed = strings.Replace(binaryNameComputed, string(filepath.Separator), "-", -1)
|
|
binaryNameComputed = strings.Replace(binaryNameComputed, ":", "-", -1)
|
|
return binaryNameComputed
|
|
}
|
|
|
|
func processOutputDirectory(po *ProjectOptions) error {
|
|
// po.OutputDirectory
|
|
if po.OutputDirectory == "" {
|
|
po.OutputDirectory = PromptRequired("Project directory name", computeBinaryName(po.Name))
|
|
}
|
|
projectPath, err := filepath.Abs(po.OutputDirectory)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if NewFSHelper().DirExists(projectPath) {
|
|
return fmt.Errorf("directory '%s' already exists", projectPath)
|
|
}
|
|
|
|
fmt.Println("Project Directory: " + po.OutputDirectory)
|
|
return nil
|
|
}
|
|
|
|
func processProjectName(po *ProjectOptions) {
|
|
if po.Name == "" {
|
|
po.Name = Prompt("The name of the project", "My Project")
|
|
}
|
|
fmt.Println("Project Name: " + po.Name)
|
|
}
|
|
|
|
func processBinaryName(po *ProjectOptions) {
|
|
if po.BinaryName == "" {
|
|
var binaryNameComputed = computeBinaryName(po.Name)
|
|
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)
|
|
}
|
|
|
|
func processTemplateMetadata(templateMetadata *TemplateMetadata, po *ProjectOptions) error {
|
|
if templateMetadata.FrontendDir != "" {
|
|
po.FrontEnd = &frontend{}
|
|
po.FrontEnd.Dir = templateMetadata.FrontendDir
|
|
}
|
|
if templateMetadata.Install != "" {
|
|
if po.FrontEnd == nil {
|
|
return fmt.Errorf("install set in template metadata but not frontenddir")
|
|
}
|
|
po.FrontEnd.Install = templateMetadata.Install
|
|
}
|
|
if templateMetadata.Build != "" {
|
|
if po.FrontEnd == nil {
|
|
return fmt.Errorf("build set in template metadata but not frontenddir")
|
|
}
|
|
po.FrontEnd.Build = templateMetadata.Build
|
|
}
|
|
|
|
if templateMetadata.Bridge != "" {
|
|
if po.FrontEnd == nil {
|
|
return fmt.Errorf("bridge set in template metadata but not frontenddir")
|
|
}
|
|
po.FrontEnd.Bridge = templateMetadata.Bridge
|
|
}
|
|
|
|
if templateMetadata.Serve != "" {
|
|
if po.FrontEnd == nil {
|
|
return fmt.Errorf("serve set in template metadata but not frontenddir")
|
|
}
|
|
po.FrontEnd.Serve = templateMetadata.Serve
|
|
}
|
|
return nil
|
|
}
|