From 9d6ebf0fd40cabbc2ba81e4cfa90d85aca11d210 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 8 Aug 2019 21:04:59 +1000 Subject: [PATCH] Linux db (#182) * feat: refactor linux distro detection * linux db updates * feat: add gccversioncommand + windows support * fix: build-essential --- .vscode/launch.json | 7 +++ cmd/cmd-mewn.go | 1 + cmd/linux.go | 118 +++++++++++++++++++++------------------- cmd/linux_test.go | 26 +++++++++ cmd/linuxdb.go | 91 +++++++++++++++++++++++++++++++ cmd/linuxdb.yaml | 124 +++++++++++++++++++++++++++++++++++++++++++ cmd/linuxdb_test.go | 81 ++++++++++++++++++++++++++++ cmd/prerequisites.go | 87 ++++++------------------------ cmd/wails/9_issue.go | 33 ++++++------ go.mod | 1 + go.sum | 4 ++ 11 files changed, 429 insertions(+), 144 deletions(-) create mode 100644 cmd/linux_test.go create mode 100644 cmd/linuxdb.go create mode 100644 cmd/linuxdb.yaml create mode 100644 cmd/linuxdb_test.go diff --git a/.vscode/launch.json b/.vscode/launch.json index 652828b51..51158b5ba 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,13 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Test cmd package", + "type": "go", + "request": "launch", + "mode": "test", + "program": "${workspaceFolder}/cmd/" + }, { "name": "Wails Init", "type": "go", diff --git a/cmd/cmd-mewn.go b/cmd/cmd-mewn.go index 991263fa2..79a9e45dd 100644 --- a/cmd/cmd-mewn.go +++ b/cmd/cmd-mewn.go @@ -7,4 +7,5 @@ import "github.com/leaanthony/mewn" func init() { mewn.AddAsset(".", "../runtime/assets/bridge.js", "1f8b08000000000000ffac597b73e2ba92ff1b3e85eedc3a05392498f7f3cca93586109200e19507776f6585ddd8025b3696c0c04cbefb966c032693ccccdd5a66482ca9d5ddfaa99f8ef4671cbda2e0f31a3ebc864ff1efe8bb3f2121e9f5f515bd265f2ffca7577f45fa2e1604edff48e1d3ab245624f15fec09a69382db058a7f7f7d95c4f7bf5f5f2f5f25ff9fd881507c6c0032896e700fc44f3477b1059eed2ed1dc769107b32b932c0161c761f1a47a81ee01239972c3a63b94cb64ab578e0b0c288fff29c5a53fd182198472046c032e2336ada112fa538ac7e76baa7262534428e1c90bf42d1e9324d47089a603b2670b50793ce611aad95edac3c464b360e9aba08cb9a0da9482cafb1b704dbcab21ba36cdcbe8ca9858e0d6503e9311d31e9b0cef6b28e1b19a2499b68a4dc366bc962f64b34529609d1074e16662d311c71c4e7c559bce895e43dfde7c763063b6ba041e21c0a639c3eaf2346307badd8cbbf7b5782c164bfca5910d524dccd8d72ffe99ae8eda5e85c45ffefe0da22bd5a61c28ff3d624eb8095ffe7e12cb21c07f491ad9fcfdd7ccfd2d06a68d354275e6104ac1fdf2f7bbdd44fb7cab058c613d90ce09d57d1b122801d54236919f89086aca68148096fe84f737c766445c546d4eb6a0d5b9edd4327513e6bc96a97b44e3462d9bc9fc51377c330e9e8564ddb5d754abb9fa0c273397e25fba74519fdb945fcdb145cc5d8d61caae18b8645ed708738479519b427d7f45a806db5ad5ffbc7da6d8e176be395813b8d57219678bf219675be7b0e557d8243aada94039b8a1a2b90c58f5e3795c3031271b38aa5e00ab3eb35d0ddc2b176b64cd6a59b0ea167675426bc53f105e731b6522a7bb526dd3766bff9ccfe7f599bdbd6206d66caf9675b6487c03859c6d7407b1b00eb5b56b2635cc71cd1f4a0ed5eb33cca054b8248f8dfed0cbdcb5755b9665b9379a18ad892ecbb25211e3b52277c5e0c199c96531b1ba6e741f5b13f93ffcb41af2e0a3e7c3587c9bb2d7158f62eef0fbf0898e1559ef88ef7b9a8fe805dd7faaeb7563f074a72c4a0120f9e1686c76e57bd259358d65bb2133ef76f190696f1f4abd61e1a92aedf962d8ec1a4f9362a65dd58b70f3bc994dabcfad4e753b1dababa999c3a67667178b03cf5636d389be37046356bd1db6ae27a32ef44c80a7d5429e18934c43c137f90e275e757f37aee653fb762637b8cb1a9654bcb94e2df6d3dbd27c002575f7dc4a2df4ea73d9ae7adbf5ceec74e685f126f7984fcdfa6eeb99ce2b9a3790ee069d76b3979346a942df7a541e9fefa591daa07332db4e86ab4e63f72019fd5eabe256c6a959b36b0eaa95bb91597ea918fb8533aa6cb22bde342aebe2bc723770dace9c3e3c18ab76e5166cbd972fdfacaa807bb9edd0e878326ed38dc72ad7d991b15ddd15ed598e7b2f247b2d779b05f799bd70aa48b72d329c990575e22a4f06ed2af7c36bb09e61ff3c9b15ab83bbc2933cea33ab44734fd95441698c73b716df0f4a73e6cedaebd950ea5dcfb49c5e7cc996aba9a227b55b37f88edd2c5e14e06545779f2779bec56e4f29bf6cfb8fb7bcb32848ade1beab4de77b359f359c54456d96a0ddb9d7b13b7da9aea7d99c21b34c7e336f34ab4ab69cd547c5beb52ff7d5cd56be1f7468615d190e1b8d86ca48f5e929e7d9fd2a71eef5f9de7931755dcf4f87dab03f512a77e3f2e07eb5ca3f55ef1ac5c64cbb7ed40bd55c75a9794e29b5c253da55945e435ba47abb5ef6a952290e77927c9f6f16e4c18c3d3e16a8ad90aea454f2cbddcbaa9279369bf2cb80bbd8ec93e6de1eca37a6cd9fccca2ac7179b17b3afab7a56ae2c5ab233c52925531a3734799f1b6c32de3a9bed48fb697f773b28b5bc36ec730fb959e5a13370b386e75179cae4ad271726f24b7ff73cd976a5ad53e237322db427d643bb5b1de62af6e356573220ed07b7b79d527367eca659b7bcde0f0786a33e95b7e5cd183f8df677a3760983532e2f5d7bdc32f3934a763d7ac49331d75b9dde5ca980b34d0d0ad7d591e39837ed4aa1b52c5985a1bcaa4ae3fb65bfe16e77b0d6b4a971b369779cecf3f3fc7a979fe637dcebcdccbb3669d2d46daa9adb789edcb8d18d45f986eecd51f6a6b86c14aaf274a3b5956b9d341e56a5ea6afefce0e677a9d48e98d7997eaf30acc0b0cc1c99dd3bd36ab1b7929f8a1ccfb26a61b39c5a256c025ea846d77b196b9dfbc160ecb572fdc742363bed569ff6bcb9785899d99c8a1ba4a4379dc99dd5d40a93ec734f1b6ca785fbcef3a0288dddc243b953e52feab5dbbccb0751ccbc1e2f47eb81a52817d100ec820398d7a81d3e45d78ea921c81a9fa71e3fd77ff39319237ba8e5c0fa9c384cce11f26c3affb30de785c037c726429b2bd800e52cc891613e4b17c13aa4af6010e4af5aba001662b64934c45d4c99835da0fc90ddc2b4956f95ca2d05fd1300fc1fef925f31f3471d5362611f92885228cb9049286017113a1785251cb2a44891f56342161abdfdd712767e71cb5084c73751287cf3759bdbae55736d510726f3a58c06fac5db9b5fa398b65e43c70a361902e917b13151c6023309e5571a617866c21515695f282696559b32db84b469eb49318e25fe50918f380a4bdc3f54944029147245299440bed4582c112960d03f31ce6432993a0a50437eb647e750892c8f32e157647c74c04014027574ba7a9449975db03e1494c954abbf12140a3808fcb52021e7a21e8fc5dee2b1b77afc2d1e9724246bd8e1a0a1b96b5ba2d7d810f0d015e206a64b86f60c5c1dfe11ed1d449fa08c464995311ffe0d76119860a1af48b3d5b50594a755173087960962944c30be332121440bc234032e73ee92d99a4332c1770e242e5142546a92ca984f47e62819d08aad2303800777fd6e32ad3236862d475f91ca583d1e7b436032389162c701aa290631b5e43bf5c4be9ead817f1221f42d388c01588b1ec61f7fff7e9ad0818747638ddd18eb3d6c413221c81217ffcafcbb1e8f89e733d142978b03e48a2f9e218ca8ad012214710350d3b64e30071afada05fe7ae9630c948f770e5c22a25d063d84907d89c2faf7781fdae797116173009a6801b65a9a888d440bb0104b4719078ae38440fcf01ca18f2822f889a825ba31411d2c05b4c1a1ce6f47a8e3025fbb146907a846c0195a3b3e40614c3c81c480af9db01d4d1ecf3eb3b55df4f8625c0f967c9f0ffa3101ad50ea84b3a0bb44098d6c84350601396c538566eff69e1dedc7a6391de944eb71bfd1eef89e133d095246a378ece4519fb35146a3a3f58c38760336d1fe32828a580f268f4dfe4820750662ec1c3ca1e307e28f4d37faeaf7d8f50fa9a2edff4f09dfbf43885ed36a0dee6e0426a8dc764598feb40d4dc4fd28f6b922875709e8abb84e16ce8296086f6264d81e3b47e3849e617bc3776a0630fece8182c8940e7b58217f66daea32e11bbd2ffb8668f0996c8368f0ff295b940711d1e19b1ed872702936d3846eec251c813ccc87ef7b82d5b39ccbf430dffecc52d20ca8e6d39e328d2f5ed63411f298ea1287236e1f825eda5f1d82656f8021c211992326cea621078b6281838b0843dc5d433a8216d6b491cf2b19b0bc44aecf23d051b83bfb594af2f7f89e1d633fcb480bbcc1e7c4625a098219fa1a9e47ac9c258cb3d0c67cff3a1d13f9559cc03aac3858907e7d44fa5d81fe1c25a3c789b1741032fdd813ac9c780738870686a9660a20a96a5b84eae8e4c327f76051abf33728c1dae7e6268aa784727025717fe14ba500968f6d57aca82660b7230ebcc1e647312e1a3efc1d3f352f9baaa6cd846f078a378f0efe1b5b0f05de617337187fb2f38370128d25ef113f017d0a3a3f027dd2f717583723912b308f33c07f2f5affdfa2642cf67118ac9f5ed7262f4e008cdd9db08770e5e0daa1b60836e0ee503e93b1184a6a30c76b93a30d36d77011b8be6260aa03e20661c1fca122b230a128fa263a78491d0d02bf84f25d6e62c08fa6788a6ca18f09a7fb39ac01ae21f92faf003cf404b3913ffe90319b0cef7d507f69b8b603f468b5cac9de7fb9115cd716073f1df61051623148336e3b1dcb028d600e0faeed60dd6ff192a15621c9c72b8eebb7a1cde04a8f0bbf6998b1d8a1d89b63934130f5e6ff7a1301edf2a3aaeafc4f0d07137ce761a1539ff788220189f4135a920788e8d476012d18c25413dd43d8db04e131c63cc255e3d869a635ccf1bf32ff3e720b8a2f93cc5ceceed055b8f91ffe9f2518a08497f05fa69fb25494519a99448564f622480c825fcff6c29ed45d534e2c10394f74c9a05d860b73dbf5fdc205aced900f7eb8d93f41f8d79083fff9de831de77dc24eb7fc9707e93e4d06556e2d9092b8443f78c4a7c12938fd502892082ffe13ef39a875b4bacf58f66c4ee63b91b1b0e39844f5cd2df113ab3a703e931ad2bff976140c3e1378ef1f3bbcc861007a286fe6025ed68f37c3c93cd4871def97fed6fd5efa65cb074c1b848a5efdc86e16b0f31b9860097d451fb20c3988237c09b9d4d017943aecbbf8e1c25fd33df042d2e481ea4795146c9a7ed43e2aa59e943a80ddc41cff54b3779295c3254519bc131e2685da0fdbef6d3ddd12012c9998d025b53d7a7c45236a34e4820a64035a2dfaf6e6e8a9e77551d036cd767e852fe08dd4e0e9743afe69caf377a7d369e1639873b082ea35248c4713e25bfc5d1b968c5affa1133bf4b3812d8a0690f0a3a011de80bf7ad8f971a373f0f5af47ba7af498614f183beb05cff5eb08a967cef94e639fdcb2b5b50969d83ab6cb453dfdcddf88deeaff1b0000ffff2d8ed2993a1f0000") mewn.AddAsset(".", "../runtime/js/runtime/init.js", "1f8b08000000000000ff544c4d4b0331103d3bbfe21d7783dda807418ba047c1a3e04518d3edd48dcd264b92ba4ab7ff5db26d0f2633c3e37d6945601c1f9f009f104d986642433333b8e27a463c2b7a2a42f17ee813625d145da6648e7455da6ad0c4accbbe335fb29e7f4900f4da099cfdecf228e562134d2f63885b6c42c428ab85b35b81198644555be3450c9e7cee82ffc5cdd5f5dd628892c467529ab4c257eaaccf90f42d31d9e0ef710ba589b4520485676fb335ce2649c89de0cd589710773edb5e08b3e77130d1f4d86f76becd36f8035ae3dccab45b2a55677aeeaace528d3d5d8cd6afc3d88ca5b4e1e6bf614907a23eac774e1af91942cc090f25556c7458fe050000ffffb89259798e010000") + mewn.AddAsset(".", "./linuxdb.yaml", "1f8b08000000000000ffec55b16edb3010ddf31537a54002da4dda494087a245bb046880a04b9786a22e142b8a5479641217fdf842922dca9015cb8ed2299e7c94eebdd3bd773cc6d849a6c83b9506afaca1e40420a4c1f850ff035059b28e9bd0a1464e48ed43800cef78d07e1302185e6202df6346fdbb4747ca9a64f37af7a072563a5e5202a72dc9fa85cd79f722005b434b217aa70039ea2a81eba62c50863cd71a1e94cfe19642668157be3b4e83d2194322345e714db7c04d06dead804baecc0eb6aa904c5873a7e4d1a411623f9da9caa93c22380d8cae20f7bea264b9cc305d189b21d9e0042e842d97843e543f2f2e178ff0179ac2524e3930383d854d9d4c62ac95ada086f835da19ad52c79dc28162dd831d5fa5552a7dc1deb10cef8f6e631f647f23b54a1f302d94bfac93de2fde3e977b88362c22c3547113e7a68da7cdcde888b4dff339426dcfcdd9d373d3d3eb6c54af8a3b677dacbb8d67a9fb3a42cd5ff71feb54afdd4d384bd53f3aa4ada25f6fa3a779c8f0aa3bafef11604ce4dc18d41f2e2e97e479aa9b33cd89949870c78c6b2fd0784b51fc369e45fd4f68fcb79b17917f15caee580ac1c4f93994bcc01793be4f5815b24660ff6b21b9aa3c7821f5eb3d6819b5fa4f5846d217cd0e417dbc721dc4fe06c6bdf15cd601d290fc0e33eb781c8a369e6528be44a8d7a198321443aa43fc7c36ea67ee441e15aea359f4fde8440e57ca84c79ec6e8f07750a43cf684ee0fd2c9f4a6575c94dc00bb6912c75a301c9ba32862fa3ea26db31ef01162747ff5dc593bea28f875ee3e8a6d274e873755398496b5e56cf4561bcfe2aeaf116a9ab3ce9343bc85253a89ebbc69d66287596bcd107367f055206524ac6c70402bf258bea15aa2824b84921b2ed1edf2d4f0c69b0d7d829da6c0fe0b0000ffff8a56ac8255100000") } diff --git a/cmd/linux.go b/cmd/linux.go index c949044b9..c5b22a60d 100644 --- a/cmd/linux.go +++ b/cmd/linux.go @@ -42,71 +42,80 @@ type DistroInfo struct { ID string Description string Release string - DiscoveredBy string } // GetLinuxDistroInfo returns information about the running linux distribution func GetLinuxDistroInfo() *DistroInfo { - result := &DistroInfo{Distribution: Unknown} - + result := &DistroInfo{ + Distribution: Unknown, + ID: "unknown", + Name: "Unknown", + } _, err := os.Stat("/etc/os-release") if !os.IsNotExist(err) { - // Default value - osID := "unknown" - osNAME := "Unknown" - version := "" - // read /etc/os-release osRelease, _ := ioutil.ReadFile("/etc/os-release") - // Split into lines - 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 "ID": - osID = 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 - result.Release = version - result.DiscoveredBy = "/etc/os-release" - switch osID { - case "debian": - result.Distribution = Debian - case "ubuntu": - result.Distribution = Ubuntu - case "arch": - result.Distribution = Arch - case "fedora": - result.Distribution = Fedora - case "centos": - result.Distribution = CentOS - case "gentoo": - result.Distribution = Gentoo - case "zorin": - result.Distribution = Zorin - case "parrot": - result.Distribution = Parrot - default: - result.Distribution = Unknown - } - - result.ID = osID - result.Name = osNAME + result = parseOsRelease(string(osRelease)) } 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.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 + result.Release = version + switch osID { + case "fedora": + result.Distribution = Fedora + case "centos": + result.Distribution = CentOS + case "arch": + result.Distribution = Arch + 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 + default: + result.Distribution = Unknown + } + + result.ID = osID + result.Name = osNAME + return result +} + // EqueryInstalled uses equery to see if a package is installed func EqueryInstalled(packageName string) (bool, error) { program := NewProgramHelper() @@ -182,7 +191,6 @@ func RequestSupportForDistribution(distroInfo *DistroInfo, libraryName string) e 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("| 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.ID, str.String()) fullURL := "https://github.com/wailsapp/wails/issues/new?" diff --git a/cmd/linux_test.go b/cmd/linux_test.go new file mode 100644 index 000000000..61a63145e --- /dev/null +++ b/cmd/linux_test.go @@ -0,0 +1,26 @@ +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) + } + +} diff --git a/cmd/linuxdb.go b/cmd/linuxdb.go new file mode 100644 index 000000000..90e92548f --- /dev/null +++ b/cmd/linuxdb.go @@ -0,0 +1,91 @@ +package cmd + +import ( + "log" + + "github.com/leaanthony/mewn" + "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(name string) *Release { + result := d.Releases[name] + 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(name string) *Distribution { + return l.Distributions[name] +} + +// NewLinuxDB creates a new LinuxDB instance from the bundled +// linuxdb.yaml file. +func NewLinuxDB() *LinuxDB { + data := mewn.Bytes("./linuxdb.yaml") + result := LinuxDB{ + Distributions: make(map[string]*Distribution), + } + err := result.ImportData(data) + if err != nil { + log.Fatal(err) + } + return &result +} diff --git a/cmd/linuxdb.yaml b/cmd/linuxdb.yaml new file mode 100644 index 000000000..87528f884 --- /dev/null +++ b/cmd/linuxdb.yaml @@ -0,0 +1,124 @@ +--- +distributions: + ubuntu: + id: ubuntu + releases: + default: + name: Ubuntu + version: default + gccversioncommand: &gccdumpfullversion -dumpfullversion + programs: &ubuntudefaultprograms + - name: gcc + help: Please install with `sudo apt install build-essential` and try again + - name: pkg-config + help: Please install with `sudo apt 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: &ubuntudefaultlibraries + - name: libgtk-3-dev + help: Please install with `sudo apt install libgtk-3-dev` and try again + - name: libwebkit2gtk-4.0-dev + help: Please install with `sudo apt install libwebkit2gtk-4.0-dev` and try again + debian: + id: debian + releases: + default: + version: default + name: Debian + gccversioncommand: &gccdumpversion -dumpversion + programs: *ubuntudefaultprograms + libraries: *ubuntudefaultlibraries + parrot: + id: parrot + releases: + default: + version: default + name: Parrot + gccversioncommand: *gccdumpversion + programs: *ubuntudefaultprograms + libraries: *ubuntudefaultlibraries + zorin: + id: zorin + releases: + default: + version: default + name: Zorin + gccversioncommand: *gccdumpversion + programs: + - name: gcc + help: Please install with `sudo apt install build-essential` and try again + - name: pkg-config + help: Please install with `sudo apt install pkg-config` and try again + - name: npm + help: Please install with `sudo snap install node --channel=12/stable --classic` and try again + libraries: *ubuntudefaultlibraries + centos: + id: centos + releases: + default: + version: default + name: CentOS + 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 `curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash - && sudo yum install -y nodejs` and try again + libraries: ¢osdefaultlibraries + - 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 + 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 -y nodejs` and try again + libraries: *centosdefaultlibraries + arch: + id: arch + releases: + default: + version: default + name: Arch Linux + gccversioncommand: *gccdumpversion + prerequisites: + - 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 + - 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 + gentoo: + id: gentoo + releases: + default: + version: default + name: Gentoo + gccversioncommand: *gccdumpversion + prerequisites: + - 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 + - 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 diff --git a/cmd/linuxdb_test.go b/cmd/linuxdb_test.go new file mode 100644 index 000000000..795a010d2 --- /dev/null +++ b/cmd/linuxdb_test.go @@ -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)) + } +} diff --git a/cmd/prerequisites.go b/cmd/prerequisites.go index d9fa3e0ac..3f88ae8ce 100644 --- a/cmd/prerequisites.go +++ b/cmd/prerequisites.go @@ -5,13 +5,6 @@ import ( "runtime" ) -// Prerequisite defines a Prerequisite! -type Prerequisite struct { - Name string - Help string - Path string -} - func newPrerequisite(name, help string) *Prerequisite { return &Prerequisite{Name: name, Help: help} } @@ -48,43 +41,13 @@ func getRequiredProgramsOSX() *Prerequisites { func getRequiredProgramsLinux() *Prerequisites { result := &Prerequisites{} distroInfo := GetLinuxDistroInfo() - switch distroInfo.Distribution { - case Debian: - 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")) - result.Add(newPrerequisite("npm", "Please install with `curl -sL https://deb.nodesource.com/setup_12.x | sudo bash - && sudo apt-get install -y nodejs` and try again")) - 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")) - result.Add(newPrerequisite("npm", "Please install with `curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - && sudo apt-get install -y nodejs` and try again")) - case Arch: - result.Add(newPrerequisite("gcc", "Please install with `sudo pacman -S base-devel` and try again")) - result.Add(newPrerequisite("pkg-config", "Please install with `sudo pacman -S base-devel` and try again")) - result.Add(newPrerequisite("npm", "Please install with `pacman -S npm nodejs` and try again")) - case CentOS: - result.Add(newPrerequisite("gcc", "Please install with `sudo yum install gcc gcc-c++ make` and try again")) - result.Add(newPrerequisite("pkg-config", "Please install with `sudo yum install pkgconfig` and try again")) - result.Add(newPrerequisite("npm", "Please install with `curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash - && sudo yum install -y nodejs` and try again")) - case Fedora: - result.Add(newPrerequisite("gcc", "Please install with `sudo yum install gcc-c++ make` and try again")) - result.Add(newPrerequisite("pkg-config", "Please install with `sudo yum install pkgconf-pkg-config` and try again")) - result.Add(newPrerequisite("npm", "Please install with `curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash - && sudo yum install -y nodejs` and try again")) - case Gentoo: - result.Add(newPrerequisite("gcc", "Please install with `sudo emerge gcc make` and try again")) - result.Add(newPrerequisite("pkg-config", "Please install with `sudo emerge pkg-config` and try again")) - result.Add(newPrerequisite("npm", "Please install with `sudo emerge nodejs` and try again")) - case Zorin: - 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")) - result.Add(newPrerequisite("npm", "Please install with `sudo snap install node --channel=12/stable --classic` and try again")) - case Parrot: - 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")) - result.Add(newPrerequisite("npm", "Please install with `sudo apt install npm nodejs` 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")) - result.Add(newPrerequisite("npm", "Please install from https://nodejs.org/en/download/ and try again")) + if distroInfo.Distribution != Unknown { + var linuxDB = NewLinuxDB() + distro := linuxDB.GetDistro(distroInfo.ID) + release := distro.GetRelease(distroInfo.Release) + for _, program := range release.Programs { + result.Add(program) + } } return result } @@ -118,35 +81,15 @@ func getRequiredLibrariesOSX() (*Prerequisites, error) { func getRequiredLibrariesLinux() (*Prerequisites, error) { result := &Prerequisites{} + // The Linux Distribution DB distroInfo := GetLinuxDistroInfo() - switch distroInfo.Distribution { - case Debian: - 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")) - 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")) - 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 CentOS: - result.Add(newPrerequisite("gtk3-devel", "Please install with `sudo yum install gtk3-devel` and try again")) - result.Add(newPrerequisite("webkitgtk3-devel", "Please install with `sudo yum install webkitgtk3-devel` and try again")) - case Fedora: - 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")) - case Gentoo: - result.Add(newPrerequisite("gtk+:3", "Please install with `sudo emerge gtk+:3` and try again")) - result.Add(newPrerequisite("webkit-gtk", "Please install with `sudo emerge webkit-gtk` and try again")) - case Zorin: - 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")) - case Parrot: - 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")) + if distroInfo.Distribution != Unknown { + var linuxDB = NewLinuxDB() + distro := linuxDB.GetDistro(distroInfo.ID) + release := distro.GetRelease(distroInfo.Release) + for _, library := range release.Libraries { + result.Add(library) + } } return result, nil } diff --git a/cmd/wails/9_issue.go b/cmd/wails/9_issue.go index 24d7f64da..09bf5faaa 100644 --- a/cmd/wails/9_issue.go +++ b/cmd/wails/9_issue.go @@ -58,24 +58,23 @@ To help you in this process, we will ask for some information, add Go/Wails deta case "linux": // for linux we have to collect // the distribution name - distro := cmd.GetLinuxDistroInfo() - // and use it as nested switch - switch distro.ID { - default: // most supported distros are printing the right result with just 'gcc -dumpversion' - gcc := program.FindProgram("gcc") - if gcc != nil { - stdout, _, _, _ := gcc.Run("-dumpversion") - gccVersion = strings.TrimSpace(stdout) - } - case "fedora", "ubuntu": // except fedora & ubuntu that require 'gcc -dumpfullversion' - gcc := program.FindProgram("gcc") - if gcc != nil { - stdout, _, _, _ := gcc.Run("-dumpfullversion") - gccVersion = strings.TrimSpace(stdout) - } - } + distroInfo := cmd.GetLinuxDistroInfo() + linuxDB := cmd.NewLinuxDB() + distro := linuxDB.GetDistro(distroInfo.ID) + release := distro.GetRelease(distroInfo.Release) + gccVersionCommand := release.GccVersionCommand - // TODO: windows support + 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") diff --git a/go.mod b/go.mod index 840e155b9..a78d23f41 100644 --- a/go.mod +++ b/go.mod @@ -27,4 +27,5 @@ require ( golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 // indirect golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 gopkg.in/AlecAivazis/survey.v1 v1.8.4 + gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22 ) diff --git a/go.sum b/go.sum index d67835ac2..370cbd8ce 100644 --- a/go.sum +++ b/go.sum @@ -89,3 +89,7 @@ golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7w 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/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=