From aa5abebbf88e4e6468686ad9fdcb04c527df06e2 Mon Sep 17 00:00:00 2001 From: blacktop Date: Sun, 9 Mar 2025 11:26:17 -0600 Subject: [PATCH] fix: `ipsw dl ipsw --show-latest-` when also supplying `--device` #659 --- cmd/ipsw/cmd/download/download_ipsw.go | 18 +++++++++++++++++- go.mod | 1 + go.sum | 13 ++++++------- internal/download/asset_sets.go | 21 +++++++++++++-------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/cmd/ipsw/cmd/download/download_ipsw.go b/cmd/ipsw/cmd/download/download_ipsw.go index c8a92340da..f31e55a154 100644 --- a/cmd/ipsw/cmd/download/download_ipsw.go +++ b/cmd/ipsw/cmd/download/download_ipsw.go @@ -188,7 +188,7 @@ var ipswCmd = &cobra.Command{ } } - if showLatestVersion || showLatestBuild { + if (showLatestVersion || showLatestBuild) && device == "" { if ibridge { itunes, err = download.NewIBridgeXML() if err != nil { @@ -247,6 +247,22 @@ var ipswCmd = &cobra.Command{ return fmt.Errorf("failed to create itunes API: %v", err) } } + if showLatestVersion || showLatestBuild { + builds, err = itunes.GetLatestBuilds(device) + if err != nil { + return fmt.Errorf("failed to get the latest builds: %v", err) + } + if len(builds) == 0 { + return fmt.Errorf("no builds found for device: %s", device) + } + if showLatestVersion { + fmt.Println(builds[0].Version) + } + if showLatestBuild { + fmt.Println(builds[0].BuildID) + } + return nil + } } if latest { diff --git a/go.mod b/go.mod index a33390bba5..550dfb6a1a 100644 --- a/go.mod +++ b/go.mod @@ -135,6 +135,7 @@ require ( github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/gorilla/websocket v1.5.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index f955195b82..f628203c37 100644 --- a/go.sum +++ b/go.sum @@ -412,10 +412,9 @@ github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pf github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= @@ -1230,10 +1229,10 @@ google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/internal/download/asset_sets.go b/internal/download/asset_sets.go index 40c28eadaa..e9c2bacc74 100644 --- a/internal/download/asset_sets.go +++ b/internal/download/asset_sets.go @@ -129,7 +129,7 @@ func (a *AssetSets) latest(platform string) (string, string) { typ = "macOS" } - v2b := make(map[string]string) + v2b := make(map[string][]string) for _, asset := range a.PublicAssetSets[typ] { switch platform { @@ -137,33 +137,33 @@ func (a *AssetSets) latest(platform string) (string, string) { fallthrough case "ios": if utils.StrSliceContains(asset.SupportedDevices, "iP") { - v2b[asset.ProductVersion] = asset.Build + v2b[asset.ProductVersion] = append(v2b[asset.ProductVersion], asset.Build) versionsRaw = append(versionsRaw, asset.ProductVersion) } case "watchos": if utils.StrSliceContains(asset.SupportedDevices, "Watch") { - v2b[asset.ProductVersion] = asset.Build + v2b[asset.ProductVersion] = append(v2b[asset.ProductVersion], asset.Build) versionsRaw = append(versionsRaw, asset.ProductVersion) } case "audioos": if utils.StrSliceContains(asset.SupportedDevices, "AudioAccessory") { - v2b[asset.ProductVersion] = asset.Build + v2b[asset.ProductVersion] = append(v2b[asset.ProductVersion], asset.Build) versionsRaw = append(versionsRaw, asset.ProductVersion) } case "tvos": if utils.StrSliceContains(asset.SupportedDevices, "AppleTV") { - v2b[asset.ProductVersion] = asset.Build + v2b[asset.ProductVersion] = append(v2b[asset.ProductVersion], asset.Build) versionsRaw = append(versionsRaw, asset.ProductVersion) } case "visionos": if utils.StrSliceContains(asset.SupportedDevices, "Reality") { - v2b[asset.ProductVersion] = asset.Build + v2b[asset.ProductVersion] = append(v2b[asset.ProductVersion], asset.Build) versionsRaw = append(versionsRaw, asset.ProductVersion) } case "recovery": fallthrough case "macos": - v2b[asset.ProductVersion] = asset.Build + v2b[asset.ProductVersion] = append(v2b[asset.ProductVersion], asset.Build) versionsRaw = append(versionsRaw, asset.ProductVersion) } } @@ -180,6 +180,11 @@ func (a *AssetSets) latest(platform string) (string, string) { } sort.Sort(version.Collection(versions)) + if len(v2b[versions[len(versions)-1].Original()]) == 0 { + return "failed to get latest", "failed to get latest" + } + sort.Strings(v2b[versions[len(versions)-1].Original()]) + latestBuilds := v2b[versions[len(versions)-1].Original()] - return versions[len(versions)-1].Original(), v2b[versions[len(versions)-1].Original()] + return versions[len(versions)-1].Original(), latestBuilds[len(latestBuilds)-1] }