diff --git a/README.md b/README.md index e64f0d2..67512d7 100644 --- a/README.md +++ b/README.md @@ -24,57 +24,8 @@ Get the executable binary for your platform from the [Release Page](https://gith Gota command help `gota --help` -```bash -Go Over the Air installation for Android APK and iOS Ipa files! Source: https://github.com/bzon/gota - -Usage: - gota [flags] - gota [command] - -Available Commands: - help Help about any command - nexus Upload your apk or ipa file and create an over-the-air static site in a Nexus Site repository - -Flags: - --buildNumber string the apk or ipa build number. - --bundleID string if srcFile type is '.ipa', this is required. (example: com.example.bundleid) - --bundleVersion string if srcFile type is '.ipa', this is required. - --destDir string root directory of the site to create. - -h, --help help for gota - --srcFile string the apk or ipa file. - --title string application name to be displayed in the site - --versionCode string if srcfile is '.apk', this is required. - --versionName string if srcFile is '.apk', this is required. - -Use "gota [command] --help" for more information about a command. -``` - Nexus command help `gota nexus --help` -```bash -Upload your apk or ipa file and create an over-the-air static site in a Nexus Site repository - -Usage: - gota nexus [flags] - -Flags: - -h, --help help for nexus - --nexusHost string nexus host url (including http protocol) - --nexusPassword string nexus password (can be passed as env variable $NEXUS_PASSWORD) - --nexusRepo string nexus site repository id (nexus v3 raw repository not maven!) - --nexusUser string nexus username (can be passed as env variable $NEXUS_USER) - -Global Flags: - --buildNumber string the apk or ipa build number. - --bundleID string if srcFile type is '.ipa', this is required. (example: com.example.bundleid) - --bundleVersion string if srcFile type is '.ipa', this is required. - --destDir string root directory of the site to create. - --srcFile string the apk or ipa file. - --title string application name to be displayed in the site - --versionCode string if srcfile is '.apk', this is required. - --versionName string if srcFile is '.apk', this is required. -``` - ### Nexus APK Upload Upload an APK file to a Nexus Site Repository @@ -85,11 +36,7 @@ Upload an APK file to a Nexus Site Repository --nexusUser admin \ --nexusPassword admin123 \ --destDir android \ - --buildNumber 1 \ --srcFile pkg/resources/DarkSouls.apk \ - --title "DarkSouls" \ - --versionName "1.0.0" \ - --versionCode "10222333" uploaded to nexus: http://localhost:8081/repository/site/android/version.json uploaded to nexus: http://localhost:8081/repository/site/android/1.0.0.10222333/index.html @@ -112,11 +59,7 @@ Upload an IPA file to a Nexus Site Repository --nexusUser admin \ --nexusPassword admin123 \ --destDir ios \ - --buildNumber 1 \ --srcFile pkg/resources/DarkSouls.ipa \ - --title DarkSouls \ - --bundleVersion 1.0.0 \ - --bundleID com.example.com uploaded to nexus: http://localhost:8081/repository/site/ios/version.json uploaded to nexus: http://localhost:8081/repository/site/ios/1.0.0.1/DarkSouls.plist diff --git a/cmd/nexus.go b/cmd/nexus.go index 182c357..da3dd3e 100644 --- a/cmd/nexus.go +++ b/cmd/nexus.go @@ -16,10 +16,9 @@ package cmd import ( "fmt" + "log" "os" - "github.com/bzon/gota/parser" - nexuspkg "github.com/bzon/gota/nexus" "github.com/spf13/cobra" ) @@ -31,24 +30,16 @@ var nexusCmd = &cobra.Command{ Use: "nexus", Short: "Upload your apk or ipa file and create an over-the-air static site in a Nexus Site repository", Run: func(cmd *cobra.Command, args []string) { - validateAndParseArgs(cmd) - var assets []string - var err error - app := newApp() - switch app.(type) { - case parser.IOSIPA: - ipa := app.(parser.IOSIPA) - assets, err = nexus.NexusUploadIOSAssets(&ipa, destDir) - case parser.AndroidAPK: - apk := app.(parser.AndroidAPK) - assets, err = nexus.NexusUploadAndroidAssets(&apk, destDir) + app := NewMobileAppParser() + if err := app.GenerateAssets(); err != nil { + log.Fatal(err) } + assets, err := nexus.NexusUploadAssets(app, destDir) if err != nil { - fmt.Printf("failed uploading assets: %+v", err) - os.Exit(1) + log.Fatal(err) } - for _, a := range assets { - fmt.Printf("uploaded to nexus: %s\n", a) + for _, v := range assets { + fmt.Println("nexus asset url:", v) } }, } diff --git a/cmd/root.go b/cmd/root.go index 8b001c7..73befba 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -27,13 +27,21 @@ import ( "github.com/spf13/cobra" ) +var srcFile, destDir string + // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "gota", - Short: "Go Over the Air installation for Android APK and iOS Ipa files! Source: https://github.com/bzon/gota", - Run: func(cmd *cobra.Command, args []string) { - validateAndParseArgs(cmd) - }, + Short: "Go Over the Air installation for Android APK and iOS Ipa files!", + // Run: func(cmd *cobra.Command, args []string) { + // appInfo, err := ipapk.NewAppParser(srcFile) + // if err != nil { + // log.Fatal(err) + // } + // app.UploadDate = time.Now().Format(time.RFC1123) + // app.AppInfo = appInfo + // app.File = srcFile + // }, } // Execute adds all child commands to the root command and sets flags appropriately. @@ -46,16 +54,8 @@ func Execute() { } func init() { - rootCmd.PersistentFlags().StringVar(&title, "title", "", "application name to be displayed in the site") rootCmd.PersistentFlags().StringVar(&srcFile, "srcFile", "", "the apk or ipa file.") rootCmd.PersistentFlags().StringVar(&destDir, "destDir", "", "root directory of the site to create.") - rootCmd.PersistentFlags().StringVar(&buildNumber, "buildNumber", "", "the apk or ipa build number.") - rootCmd.PersistentFlags().StringVar(&bundleVersion, "bundleVersion", "", "if srcFile type is '.ipa', this is required.") - rootCmd.PersistentFlags().StringVar(&bundleID, "bundleID", "", "if srcFile type is '.ipa', this is required. (example: com.example.bundleid)") - rootCmd.PersistentFlags().StringVar(&versionName, "versionName", "", "if srcFile is '.apk', this is required.") - rootCmd.PersistentFlags().StringVar(&versionCode, "versionCode", "", "if srcfile is '.apk', this is required.") - rootCmd.MarkPersistentFlagRequired("title") rootCmd.MarkPersistentFlagRequired("srcFile") rootCmd.MarkPersistentFlagRequired("destDir") - rootCmd.MarkPersistentFlagRequired("buildNumber") } diff --git a/cmd/utils.go b/cmd/utils.go index c62569e..797e3be 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -1,77 +1,22 @@ package cmd import ( - "fmt" - "os" - "path/filepath" + "log" + "time" + + "github.com/bzon/ipapk" "github.com/bzon/gota/parser" - "github.com/spf13/cobra" ) -// common -var title, srcFile, buildNumber, destDir string - -// ios specific -var bundleID, bundleVersion string - -// android specific -var versionName, versionCode string - -func missingFlagError(cmd *cobra.Command, f string) { - fmt.Printf("Error: required flag(s) \"%s\" not set\n", f) - cmd.Usage() - os.Exit(1) -} - -func newApp() parser.MobileApp { - appFile := parser.AppFile{ - Title: title, - BuildNumber: buildNumber, - SourceFile: srcFile, - } - if fileExt() == ".ipa" { - return parser.IOSIPA{ - AppFile: appFile, - BundleID: bundleID, - BundleVersion: bundleVersion, - } - } else { - return parser.AndroidAPK{ - AppFile: appFile, - VersionCode: versionCode, - VersionName: versionName, - } - } -} - -func fileExt() string { - return filepath.Ext(srcFile) -} - -// This function must be called before executing any commands function! -func validateAndParseArgs(cmd *cobra.Command) { - if fileExt() == ".ipa" { - if bundleVersion == "" { - missingFlagError(cmd, "bundleVersion") - } - if bundleID == "" { - missingFlagError(cmd, "bundleID") - } - } else if fileExt() == ".apk" { - if versionName == "" { - missingFlagError(cmd, "versionName") - } - if versionCode == "" { - missingFlagError(cmd, "versionCode") - } - } else { - fmt.Printf("Error: srcFile %s does not have a file extension of .apk or .ipa\n", srcFile) - cmd.Usage() - os.Exit(1) - } - if _, err := os.Stat(srcFile); os.IsNotExist(err) { - fmt.Println(err) - os.Exit(1) +func NewMobileAppParser() *parser.MobileApp { + appInfo, err := ipapk.NewAppParser(srcFile) + if err != nil { + log.Fatal(err) } + var app parser.MobileApp + app.UploadDate = time.Now().Format(time.RFC1123) + app.AppInfo = appInfo + app.File = srcFile + return &app } diff --git a/nexus/nexus_upload.go b/nexus/nexus_upload.go index 8d7ded7..696f0de 100644 --- a/nexus/nexus_upload.go +++ b/nexus/nexus_upload.go @@ -18,12 +18,12 @@ type Nexus struct { // NexusComponent contains the fields that will be passed as a parameter for NexusUpload type NexusComponent struct { - SourceFile, Filename, Directory string + File, Filename, Directory string } // NexusUpload uploads a file to Nexus returns the uploaded file url func (n *Nexus) NexusUpload(c NexusComponent) (string, error) { - file, err := os.Open(c.SourceFile) + file, err := os.Open(c.File) if err != nil { return "", err } @@ -53,71 +53,48 @@ func (n *Nexus) getRepoURL() string { return n.HostURL + "/repository/" + n.SiteRepository } -// NexusUploadIOSAssets wraps NexusUpload to upload all files for iOS to nexus -func (n *Nexus) NexusUploadIOSAssets(ipa *parser.IOSIPA, dir string) ([]string, error) { - // Upload in directory with FullVersion() as name - ipaSitePath := ipa.FullVersion() + "/" + filepath.Base(ipa.SourceFile) - ipaPlistSitePath := ipa.FullVersion() + "/" + ipa.Title + ".plist" - ipaIndexHTMLSitePath := ipa.FullVersion() + "/index.html" - // assume the url before uploaded for templating - ipa.DownloadURL = n.getRepoURL() + "/" + dir + "/" + ipaSitePath - ipa.PlistURL = htmltemp.URL(n.getRepoURL() + "/" + dir + "/" + ipaPlistSitePath) - // create the assets - assets := []string{} - if err := ipa.GenerateAssets(); err != nil { - return assets, err - } - // upload assets - uri, err := n.NexusUpload(NexusComponent{"ios_assets/version.json", "version.json", dir}) - if err != nil { - return assets, err - } - assets = append(assets, uri) - uri, err = n.NexusUpload(NexusComponent{"ios_assets/app.plist", ipaPlistSitePath, dir}) - if err != nil { - return assets, err - } - assets = append(assets, uri) - uri, err = n.NexusUpload(NexusComponent{"ios_assets/index.html", ipaIndexHTMLSitePath, dir}) - if err != nil { - return assets, err - } - assets = append(assets, uri) - uri, err = n.NexusUpload(NexusComponent{ipa.SourceFile, ipaSitePath, dir}) - if err != nil { - return assets, err +// NexusUploadAssets uploads the generated files by the parser package along with the ipa or apk file +func (n *Nexus) NexusUploadAssets(app *parser.MobileApp, dir string) ([]string, error) { + // create the site path names and assume the url before uploaded for templating + appIconPath := app.Version + "/" + parser.AppIconFile + appSitePath := app.Version + "/" + filepath.Base(app.File) + appIndexHTMLSitePath := app.Version + "/" + parser.IndexHTMLFile + app.DownloadURL = n.getRepoURL() + "/" + dir + "/" + appSitePath + + // default directory of assets + assetsDir := parser.AndroidAssetsDir + + // specific for ios + var appPlistSitePath string + if app.IsIOS() { + assetsDir = parser.IOSAssetsDir + appPlistSitePath = app.Version + "/" + parser.IOSPlistFile + app.PlistURL = htmltemp.URL(n.getRepoURL() + "/" + dir + "/" + appPlistSitePath) } - assets = append(assets, uri) - return assets, nil -} -// NexusUploadAndroidAssets wraps NexusUpload to upload all files for android to nexus -func (n *Nexus) NexusUploadAndroidAssets(apk *parser.AndroidAPK, dir string) ([]string, error) { - // Upload in directory with FullVersion() as name - apkSitePath := apk.FullVersion() + "/" + filepath.Base(apk.SourceFile) - apkIndexHTMLSitePath := apk.FullVersion() + "/index.html" - // assume the url before uploaded for templating - apk.DownloadURL = n.getRepoURL() + "/" + dir + "/" + apkSitePath // create the assets assets := []string{} - if err := apk.GenerateAssets(); err != nil { + if err := app.GenerateAssets(); err != nil { return assets, err } - // upload assets - uri, err := n.NexusUpload(NexusComponent{"ios_assets/version.json", "version.json", dir}) - if err != nil { - return assets, err + + components := []NexusComponent{ + {assetsDir + "/" + parser.AppIconFile, appIconPath, dir}, + {assetsDir + "/" + parser.VersionJsonFile, parser.VersionJsonFile, dir}, + {assetsDir + "/" + parser.IndexHTMLFile, appIndexHTMLSitePath, dir}, + {app.File, appSitePath, dir}, } - assets = append(assets, uri) - uri, err = n.NexusUpload(NexusComponent{"ios_assets/index.html", apkIndexHTMLSitePath, dir}) - if err != nil { - return assets, err + if app.IsIOS() { + components = append(components, NexusComponent{assetsDir + "/" + parser.IOSPlistFile, appPlistSitePath, dir}) } - assets = append(assets, uri) - uri, err = n.NexusUpload(NexusComponent{apk.SourceFile, apkSitePath, dir}) - if err != nil { - return assets, err + + for _, component := range components { + uri, err := n.NexusUpload(component) + if err != nil { + return assets, err + } + assets = append(assets, uri) } - assets = append(assets, uri) + return assets, nil } diff --git a/nexus/nexus_upload_test.go b/nexus/nexus_upload_test.go index 9f01177..8bc8148 100644 --- a/nexus/nexus_upload_test.go +++ b/nexus/nexus_upload_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/bzon/gota/parser" + "github.com/bzon/ipapk" ) var nexus = Nexus{ @@ -17,9 +18,9 @@ var nexus = Nexus{ func TestNexusUpload(t *testing.T) { var testComponent = NexusComponent{ - SourceFile: "../resources/index.html", - Filename: "index.html", - Directory: "go_upload_test", + File: "../resources/index.html", + Filename: "index.html", + Directory: "go_upload_test", } uri, err := nexus.NexusUpload(testComponent) if err != nil { @@ -28,43 +29,36 @@ func TestNexusUpload(t *testing.T) { fmt.Println("nexus url:", uri) } -func TestGeneratedAssetsNexusUpload(t *testing.T) { - var ipa = parser.IOSIPA{ - AppFile: parser.AppFile{ - Title: "DarkSouls", - BuildDate: time.Now().Format(time.RFC822), - BuildNumber: "99", - SourceFile: "../resources/DarkSouls.ipa", // dummy file - }, - BundleID: "com.example.dark.souls", - BundleVersion: "1.0.0", +func TestNexusUploadAssets(t *testing.T) { + type tc struct { + name string + destDir string + file string } - var apk = parser.AndroidAPK{ - AppFile: parser.AppFile{ - Title: "DarkSouls Android", - BuildDate: time.Now().Format(time.RFC822), - BuildNumber: "22", - SourceFile: "../resources/DarkSouls.apk", // dummy file - }, - VersionName: "1.0.0", - VersionCode: "100222333", + tt := []tc{ + {"upload ios assets", "nexus_ios_repo", "../parser/testdata/sample.ipa"}, + {"upload android assets", "nexus_android_repo", "../parser/testdata/sample.apk"}, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + appInfo, err := ipapk.NewAppParser(tc.file) + if err != nil { + t.Fatal(err) + } + var app parser.MobileApp + app.UploadDate = time.Now().Format(time.RFC1123) + app.AppInfo = appInfo + app.File = tc.file + if err := app.GenerateAssets(); err != nil { + t.Fatal(err) + } + assets, err := nexus.NexusUploadAssets(&app, tc.destDir) + if err != nil { + t.Fatal(err) + } + for _, v := range assets { + fmt.Println("nexus url:", v) + } + }) } - t.Run("upload ipa assets", func(t *testing.T) { - assets, err := nexus.NexusUploadIOSAssets(&ipa, "nexus_ios_upload_test") - if err != nil { - t.Fatal(err) - } - for _, v := range assets { - fmt.Println("nexus url:", v) - } - }) - t.Run("upload android assets", func(t *testing.T) { - assets, err := nexus.NexusUploadAndroidAssets(&apk, "nexus_android_upload_test") - if err != nil { - t.Fatal(err) - } - for _, v := range assets { - fmt.Println("nexus url:", v) - } - }) } diff --git a/parser/create.go b/parser/create.go deleted file mode 100644 index 25317d2..0000000 --- a/parser/create.go +++ /dev/null @@ -1,114 +0,0 @@ -package parser - -import ( - "fmt" - htmltemp "html/template" - "os" - "path/filepath" - txttemp "text/template" -) - -// AppFile contains common fields of APK and IPA file -type AppFile struct { - Title, BuildDate, BuildNumber, DownloadURL, SourceFile string -} - -// AndroidAPK fields for APK file upload -type AndroidAPK struct { - AppFile - VersionName, VersionCode string -} - -// IOSIPA fields for IPA file upload -type IOSIPA struct { - AppFile - BundleID, BundleVersion string - PlistURL htmltemp.URL -} - -// MobileApp allows IOSIPA and AndroidAPK structs to be able use generateCommonFiles function -type MobileApp interface { - GenerateAssets() error - FullVersion() string - IsAndroid() bool -} - -// GenerateAssets creates files for iOS -func (ipa IOSIPA) GenerateAssets() error { - os.Remove("ios_assets") - os.Mkdir("ios_assets", 0700) - // ipa.PlistURL = url.QueryEscape(ipa.PlistURL) - if err := executeTemplate(ipa, "ios_assets/app.plist", plistTemplateString); err != nil { - return err - } - if err := generateCommonFiles(ipa, "ios_assets"); err != nil { - return err - } - return nil -} - -// GenerateAssets creates files for Android -func (apk AndroidAPK) GenerateAssets() error { - os.Remove("android_assets") - os.Mkdir("android_assets", 0700) - if err := generateCommonFiles(apk, "android_assets"); err != nil { - return err - } - return nil -} - -// FullVersion returns the full version for Android -func (apk AndroidAPK) FullVersion() string { - return apk.VersionName + "." + apk.VersionCode -} - -// FullVersion returns the full version for iOS -func (ipa IOSIPA) FullVersion() string { - return ipa.BundleVersion + "." + ipa.BuildNumber -} - -// IsAndroid is used for templating conditions. Returns true for android -func (apk AndroidAPK) IsAndroid() bool { - return true -} - -// IsAndroid is used for templating conditions. Returns true for iOS -func (ipa IOSIPA) IsAndroid() bool { - return false -} - -// Create index.html and version.json -func generateCommonFiles(app MobileApp, dir string) error { - if err := executeTemplate(app, dir+"/index.html", indexHTMLTemplateString); err != nil { - return err - } - if err := executeTemplate(app, dir+"/version.json", versionTemplateString); err != nil { - return err - } - return nil -} - -func executeTemplate(app MobileApp, filename, templateVar string) error { - if filepath.Ext(filename) == ".html" { - templ := htmltemp.Must(htmltemp.New("templ").Parse(templateVar)) - file, err := os.Create(filename) - if err != nil { - return fmt.Errorf("failed creating %s got error %v", filename, err) - } - defer file.Close() - if err := templ.Execute(file, app); err != nil { - return fmt.Errorf("failed templating %s got error %v", filename, err) - } - return nil - } - templ := txttemp.Must(txttemp.New("templ").Parse(templateVar)) - file, err := os.Create(filename) - if err != nil { - return fmt.Errorf("failed creating %s got error %v", filename, err) - } - defer file.Close() - if err := templ.Execute(file, app); err != nil { - return fmt.Errorf("failed templating %s got error %v", filename, err) - } - return nil -} diff --git a/parser/create_test.go b/parser/create_test.go deleted file mode 100644 index 6b136d5..0000000 --- a/parser/create_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package parser - -import ( - "testing" - "time" -) - -func TestGenerateAssets(t *testing.T) { - var ipa = IOSIPA{ - AppFile: AppFile{ - Title: "DarkSouls", - BuildDate: time.Now().Format(time.RFC822), - DownloadURL: "http://s3.amazon.com/bucket/DarkSouls.ipa", - BuildNumber: "99", - SourceFile: "../resources/DarkSouls.ipa", // dummy file - }, - PlistURL: "http://s3.amazon.com/bucket/DarkSouls.plist", - BundleID: "com.example.dark.souls", - BundleVersion: "1.0.0", - } - var apk = AndroidAPK{ - AppFile: AppFile{ - Title: "DarkSouls Android", - BuildDate: time.Now().Format(time.RFC822), - DownloadURL: "http://s3.amazon.com/bucket/DarkSouls.apk", - BuildNumber: "22", - SourceFile: "../resources/DarkSouls.apk", // dummy file - }, - VersionName: "1.0.0", - VersionCode: "100222333", - } - t.Run("generate ipa assets", func(t *testing.T) { - if err := ipa.GenerateAssets(); err != nil { - t.Fatal(err) - } - }) - t.Run("generate apk assets", func(t *testing.T) { - if err := apk.GenerateAssets(); err != nil { - t.Fatal(err) - } - }) -} diff --git a/parser/parser.go b/parser/parser.go new file mode 100644 index 0000000..72e7f6e --- /dev/null +++ b/parser/parser.go @@ -0,0 +1,108 @@ +package parser + +import ( + "fmt" + htmltemp "html/template" + "image/png" + "os" + "path/filepath" + txttemp "text/template" + + "github.com/bzon/ipapk" +) + +const ( + IOSAssetsDir = "ios_assets" + AndroidAssetsDir = "android_assets" + IOSPlistFile = "app.plist" + AppIconFile = "appicon.png" + VersionJsonFile = "version.json" + IndexHTMLFile = "index.html" + IPAExt = ".ipa" + APKExt = ".apk" +) + +// AppFile contains common fields of APK and IPA file +type MobileApp struct { + *ipapk.AppInfo + UploadDate string + DownloadURL string + PlistURL htmltemp.URL + File string +} + +// GenerateAssets creates the site assets that will be uploaded along with the ipa or apk file +func (app MobileApp) GenerateAssets() error { + assetsDir := AndroidAssetsDir + if app.IsIOS() { + assetsDir = IOSAssetsDir + } + os.Remove(assetsDir) + os.Mkdir(assetsDir, 0700) + if app.IsIOS() { + err := executeTemplate(app, assetsDir+"/"+IOSPlistFile, plistTemplateString) + if err != nil { + return err + } + } + err := generateCommonFiles(app, assetsDir) + if err != nil { + return err + } + return nil +} + +// IsIOS is used for templating conditions +func (app MobileApp) IsIOS() bool { + if filepath.Ext(app.File) == IPAExt { + return true + } + return false +} + +// Create index.html and version.json +func generateCommonFiles(app MobileApp, dir string) error { + // Create the image png file + if app.Icon != nil { + img, err := os.Create(dir + "/" + AppIconFile) + if err != nil { + return err + } + defer img.Close() + if err := png.Encode(img, app.Icon); err != nil { + return fmt.Errorf("failed creating an image: %v", err) + } + } + if err := executeTemplate(app, dir+"/"+IndexHTMLFile, indexHTMLTemplateString); err != nil { + return err + } + if err := executeTemplate(app, dir+"/"+VersionJsonFile, versionTemplateString); err != nil { + return err + } + return nil +} + +func executeTemplate(app MobileApp, filename, templateVar string) error { + if filepath.Ext(filename) == ".html" { + templ := htmltemp.Must(htmltemp.New("templ").Parse(templateVar)) + file, err := os.Create(filename) + if err != nil { + return fmt.Errorf("failed creating %s got error %v", filename, err) + } + defer file.Close() + if err := templ.Execute(file, app); err != nil { + return fmt.Errorf("failed templating %s got error %v", filename, err) + } + return nil + } + templ := txttemp.Must(txttemp.New("templ").Parse(templateVar)) + file, err := os.Create(filename) + if err != nil { + return fmt.Errorf("failed creating %s got error %v", filename, err) + } + defer file.Close() + if err := templ.Execute(file, app); err != nil { + return fmt.Errorf("failed templating %s got error %v", filename, err) + } + return nil +} diff --git a/parser/parser_test.go b/parser/parser_test.go new file mode 100644 index 0000000..a296696 --- /dev/null +++ b/parser/parser_test.go @@ -0,0 +1,35 @@ +package parser + +import ( + "testing" + "time" + + "github.com/bzon/ipapk" +) + +func TestGenerateAssets(t *testing.T) { + type tc struct { + name string + file string + } + tt := []tc{ + {"generate ios asset", "testdata/sample.ipa"}, + {"generate android asset", "testdata/sample.apk"}, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + appInfo, err := ipapk.NewAppParser(tc.file) + if err != nil { + t.Fatal(err) + } + var app MobileApp + app.UploadDate = time.Now().Format(time.RFC1123) + app.AppInfo = appInfo + app.File = tc.file + if err := app.GenerateAssets(); err != nil { + t.Fatal(err) + } + }) + } + +} diff --git a/parser/templates.go b/parser/templates.go index 5daaeee..ba7128d 100644 --- a/parser/templates.go +++ b/parser/templates.go @@ -1,11 +1,11 @@ package parser const versionTemplateString = `{ -"latestVersion": "{{.FullVersion}}", -{{if .IsAndroid -}} - "updateUrl": "{{.DownloadURL}}" -{{else -}} +"latestVersion": "{{.Version}}.{{.Build}}", +{{if .IsIOS -}} "updateUrl": "itms-services://?action=download-manifest&url={{.PlistURL}}" +{{else -}} + "updateUrl": "{{.DownloadURL}}" {{end -}} }` @@ -28,13 +28,13 @@ const plistTemplateString = ` metadata bundle-identifier - {{.BundleID}} + {{.BundleId}} bundle-version - {{.BundleVersion}} + {{.Version}} kind software title - {{.Title}} + {{.Name}} @@ -45,7 +45,7 @@ var indexHTMLTemplateString = ` - Install {{.Title}} + Install {{.Name}} -

{{.Title}}

- {{if .IsAndroid -}} +

{{.Name}}

+ + + {{if .IsIOS -}}
- - - Install {{.Title}} {{.VersionName}} ({{.VersionCode}}) + + + Install {{.Name}} {{.Version}} ({{.Build}})
-

Built on {{.BuildDate}}

+

Uploaded on {{.UploadDate}}

-

Please open this page on your Android device!

-

- App is being installed. You might have to close the browser. + App is being installed. Close your Browser using the home button.

{{- else}}
- - - Install {{.Title}} {{.BundleVersion}} ({{.BuildNumber}}) + + + Install {{.Name}} {{.Version}} ({{.Build}})
-

Built on {{.BuildDate}}

+

Uploaded on {{.UploadDate}}

-

Please open this page on your iPhone!

-

- App is being installed. Close Safari using the home button. + App is being installed. You might have to close the browser.

+ {{- end}}

- Contribute on Github! + This is a beta version and is not meant for the public.

- - -