From b6b31e8ae20d04d90c75eea6ea1b25b8a3abfede Mon Sep 17 00:00:00 2001 From: idk Date: Sun, 27 Mar 2022 00:18:08 -0400 Subject: [PATCH] metaplugin generator progres --- cmd/i2p.plugin.native.metaplugin/main.go | 131 ++++++++++++++++++++++- plugin-config.go | 1 + replace.go | 9 +- 3 files changed, 136 insertions(+), 5 deletions(-) diff --git a/cmd/i2p.plugin.native.metaplugin/main.go b/cmd/i2p.plugin.native.metaplugin/main.go index 5230479..bcd377b 100644 --- a/cmd/i2p.plugin.native.metaplugin/main.go +++ b/cmd/i2p.plugin.native.metaplugin/main.go @@ -5,7 +5,16 @@ import ( // "runtime" + "archive/zip" + "flag" + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" + . "i2pgit.org/idk/i2p.plugin.native" + "i2pgit.org/idk/reseed-tools/su3" ) var pc PluginConfig @@ -14,7 +23,7 @@ var cc ClientConfig // The goal here is to create a plugin which can be installed which has no contents, but contains update // information for other plugins, i.e. // -// i2p.plugins.tor-manager-amd64 +// i2p.plugins.tor-manager.su3 // // would contain meta-information that matches the $OS and $ARCH of the runtime machine // which would then update at the first opportunity, downloading the latest version of the plugin @@ -22,6 +31,126 @@ var cc ClientConfig // it should be nice for the user to be able to install the plugin without having to comb through // OS/ARCH pairs they don't really give a damn about. +var wd, wderr = os.Getwd() +var dir = flag.String("dir", wd, "Directory to look for plugins in") + +func flagSet() { + if wderr != nil { + log.Fatal(wderr) + } + flag.Parse() +} + +func FindSu3sInDir(dir string) ([]string, error) { + files, err := ioutil.ReadDir(dir) + if err != nil { + return nil, err + } + var su3s []string + for _, f := range files { + if f.IsDir() { + continue + } + if strings.HasSuffix(f.Name(), ".su3") { + su3s = append(su3s, f.Name()) + } + } + return su3s, nil +} + +func MatchSu3sWithOSARCH(su3s []string) []string { + var matched []string + for _, su3 := range su3s { + for _, osarch := range ARCHES { + if strings.Contains(su3, osarch) { + matched = append(matched, su3) + } + } + for _, osarch := range OSES { + if strings.Contains(su3, osarch) { + matched = append(matched, su3) + } + } + } + return removeDuplicateValues(matched) +} + +func removeDuplicateValues(stringSlice []string) []string { + keys := make(map[string]bool) + list := []string{} + + // If the key(values of the slice) is not equal + // to the already present value in new slice (list) + // then we append it. else we jump on another element. + for _, entry := range stringSlice { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} + func main() { + flagSet() + absdir, err := filepath.Abs(*dir) + if err != nil { + log.Fatal(err) + } + su3s, err := FindSu3sInDir(absdir) + if err != nil { + log.Fatal(err) + } + su3s = MatchSu3sWithOSARCH(su3s) + // extract the plugin.config and the clients.config from topmost su3 + // and get the plugin name from the plugin.config file. + // copy the plugin.config and clients.config to meta/plugin.config and meta/clients.config + // create a script that says "this is a meta plugin, downloading an update for the plugin + // will install a real version" in each location per-platform, i.e. plugin-name-os-arch + // use sh for Linux and OSX and bat for Windows + su3file := su3.New() + bytes, err := ioutil.ReadFile(filepath.Join(absdir, su3s[0])) + if err != nil { + log.Fatal(err) + } + err = su3file.UnmarshalBinary(bytes) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(su3s[0]+".zip", su3file.Content, 0644) + zipReader, err := zip.OpenReader(su3s[0] + ".zip") + if err != nil { + log.Fatal(err) + } + defer zipReader.Close() + clientConfig, err := zipReader.Open("clients.config") + if err != nil { + log.Fatal(err) + } + defer clientConfig.Close() + pluginConfig, err := zipReader.Open("plugin.config") + if err != nil { + log.Fatal(err) + } + defer pluginConfig.Close() + clientConfigBytes, err := ioutil.ReadAll(clientConfig) + if err != nil { + log.Fatal(err) + } + pluginConfigBytes, err := ioutil.ReadAll(pluginConfig) + if err != nil { + log.Fatal(err) + } + os.Mkdir("meta", 0755) + replacedClientConfigBytes := []byte(Replace(string(clientConfigBytes))) + replacedPluginConfigBytes := []byte(Replace(string(pluginConfigBytes))) + err = ioutil.WriteFile("meta/clients.config", replacedClientConfigBytes, 0644) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile("meta/plugin.config", replacedPluginConfigBytes, 0644) + if err != nil { + log.Fatal(err) + } } diff --git a/plugin-config.go b/plugin-config.go index 232da9e..01ecc73 100644 --- a/plugin-config.go +++ b/plugin-config.go @@ -45,6 +45,7 @@ type PluginConfig struct { ConsoleLinkTip *string //26 ConsoleLinkTipLang []*string //27 SignerDirectory *string //28 + FileType *int //29 } func (pc *PluginConfig) Print() string { diff --git a/replace.go b/replace.go index 0d5e6e0..87ab7cc 100644 --- a/replace.go +++ b/replace.go @@ -2,13 +2,14 @@ package shellservice import "strings" +var OSES = []string{"mac", "linux", "windows"} +var ARCHES = []string{"386", "amd64", "arm", "arm64"} + func Replace(r string) string { - oses := []string{"mac", "linux", "windows"} - for _, os := range oses { + for _, os := range OSES { r = strings.Replace(r, os, "$OS", -1) } - arches := []string{"386", "amd64", "arm", "arm64"} - for _, arch := range arches { + for _, arch := range ARCHES { r = strings.Replace(r, arch, "$ARCH", -1) } return r