11package main
22
33import (
4- "context"
54 "fmt"
6- "io"
7- "net/http"
85 "os"
96 "os/exec"
107 "path/filepath"
11- "regexp"
12- "runtime"
13- "sort"
148
15- "github.com/google/go-github/github"
169 "github.com/google/safearchive/tar"
17- goversion "github.com/hashicorp/go-version"
1810 "github.com/spf13/cobra"
1911
2012 "github.com/uniget-org/cli/pkg/archive"
13+ "github.com/uniget-org/cli/pkg/containers"
2114 "github.com/uniget-org/cli/pkg/logging"
2215)
2316
24- var requestedVersion string
25- var allowPrereleaseVersion bool
26- var dryRun bool
27-
2817func initSelfUpgradeCmd () {
2918 rootCmd .AddCommand (selfUpgradeCmd )
30-
31- selfUpgradeCmd .Flags ().StringVar (& requestedVersion , "version" , "latest" , "Upgrade to a specific version" )
32- selfUpgradeCmd .Flags ().BoolVar (& allowPrereleaseVersion , "allow-prerelease" , false , "Allow upgrading to prerelease version" )
33- selfUpgradeCmd .Flags ().BoolVar (& dryRun , "dry-run" , false , "Do not perform the upgrade, only show what would be done" )
3419}
3520
3621var selfUpgradeCmd = & cobra.Command {
@@ -39,12 +24,20 @@ var selfUpgradeCmd = &cobra.Command{
3924 Long : header + "\n Upgrade " + projectName + " to latest version" ,
4025 Args : cobra .NoArgs ,
4126 RunE : func (cmd * cobra.Command , args []string ) error {
42- versionRegex , err := regexp . Compile ( `^\d+\.\d+\.\d+(-[a-z]+\.\d+)?$` )
27+ err := downloadMetadata ( )
4328 if err != nil {
44- return fmt .Errorf ("cannot compile regexp : %w " , err )
29+ return fmt .Errorf ("error downloading metadata : %s " , err )
4530 }
46- if ! versionRegex .MatchString (version ) {
47- return fmt .Errorf ("invalid version %s" , version )
31+ assertMetadataFileExists ()
32+ assertMetadataIsLoaded ()
33+ err = loadMetadata ()
34+ if err != nil {
35+ return fmt .Errorf ("error loading metadata: %s" , err )
36+ }
37+
38+ unigetTool , err := tools .GetByName ("uniget" )
39+ if err != nil {
40+ return fmt .Errorf ("failed to get uniget tool: %s" , err )
4841 }
4942
5043 selfExe := filepath .Base (os .Args [0 ])
@@ -64,69 +57,7 @@ var selfUpgradeCmd = &cobra.Command{
6457 logging .Debugf ("%s is available at %s\n " , selfExe , path )
6558 selfDir := filepath .Dir (path )
6659
67- if allowPrereleaseVersion && requestedVersion == "latest" {
68- logging .Debugf ("Allowing prerelease version" )
69-
70- githubClient := github .NewClient (nil )
71- releases , _ , err := githubClient .Repositories .ListReleases (context .Background (), githubOrganization , "cli" , & github.ListOptions {PerPage : 100 })
72- if err != nil {
73- return fmt .Errorf ("failed to list releases: %s" , err )
74- }
75-
76- versions := make ([]* goversion.Version , 0 )
77- for _ , release := range releases {
78- version , err := goversion .NewSemver (* release .TagName )
79- if err != nil {
80- continue
81- }
82-
83- versions = append (versions , version )
84- sort .Sort (goversion .Collection (versions ))
85- }
86- requestedVersion = versions [len (versions )- 1 ].String ()
87- }
88-
89- var url string
90- if requestedVersion == "latest" {
91- url = fmt .Sprintf ("https://github.com/%s/releases/%s/download/uniget_%s_%s.tar.gz" , projectRepository , requestedVersion , runtime .GOOS , arch )
92- } else {
93- logging .Info .Printfln ("Requested version %s" , requestedVersion )
94- url = fmt .Sprintf ("https://github.com/%s/releases/download/v%s/uniget_%s_%s.tar.gz" , projectRepository , requestedVersion , runtime .GOOS , arch )
95- }
96-
97- logging .Debugf ("Downloading from %s" , url )
98- if dryRun {
99- logging .Info .Printfln ("Would download version %s from %s" , requestedVersion , url )
100- return nil
101- }
102-
103- resp , err := downloadReleaseAsset (url )
104- if err != nil {
105- return fmt .Errorf ("failed to download %s: %s" , url , err )
106- }
107- defer func () {
108- err := resp .Body .Close ()
109- if err != nil {
110- logging .Warning .Printfln ("failed to close response body: %s" , err )
111- }
112- }()
113-
114- if resp .StatusCode != 200 {
115- return fmt .Errorf ("failed to download %s: %s" , url , resp .Status )
116- }
117-
118- requestedVersionVersion , err := goversion .NewVersion (requestedVersion )
119- if err != nil {
120- return fmt .Errorf ("failed to parse version %s: %s" , requestedVersion , err )
121- }
122- versionVersion , err := goversion .NewVersion (version )
123- if err != nil {
124- return fmt .Errorf ("failed to parse current version %s: %s" , version , err )
125- }
126- if requestedVersionVersion .LessThanOrEqual (versionVersion ) {
127- logging .Info .Printfln ("Latest version %s already installed." , version )
128- return nil
129- }
60+ logging .Info .Printfln ("Installing version %s" , unigetTool .Version )
13061
13162 logging .Debugf ("Extracting tar.gz" )
13263 err = os .Chdir (selfDir )
@@ -138,15 +69,18 @@ var selfUpgradeCmd = &cobra.Command{
13869 return fmt .Errorf ("failed to remove %s: %s" , selfExe , err )
13970 }
14071
141- bodyGz , err := io .ReadAll (resp .Body )
72+ registries , repositories := unigetTool .GetSourcesWithFallback (registry , imageRepository )
73+ ref , err := containers .FindToolRef (registries , repositories , unigetTool .Name , "main" )
14274 if err != nil {
143- return fmt .Errorf ("failed to read body: %s" , err )
75+ return fmt .Errorf ("error finding tool %s:%s: %s" , unigetTool . Name , unigetTool . Version , err )
14476 }
145- body , err := archive .Gunzip (bodyGz )
77+ logging .Debugf ("Getting image %s" , ref )
78+ layer , err := toolCache .Get (ref )
14679 if err != nil {
147- return fmt .Errorf ("failed to gunzip body : %s" , err )
80+ return fmt .Errorf ("unable to get image : %s" , err )
14881 }
149- err = archive .ProcessTarContents (body , func (tar * tar.Reader , header * tar.Header ) error {
82+
83+ err = archive .ProcessTarContents (layer , func (tar * tar.Reader , header * tar.Header ) error {
15084 if header .Name == "uniget" {
15185 logging .Debugf ("Extracting %s" , header .Name )
15286 err := archive .CallbackExtractTarItem (tar , header )
@@ -161,34 +95,6 @@ var selfUpgradeCmd = &cobra.Command{
16195 return fmt .Errorf ("failed to extract tar.gz: %s" , err )
16296 }
16397
164- logging .Info .Printfln ("Upgraded to version %s" , requestedVersion )
16598 return nil
16699 },
167100}
168-
169- func downloadReleaseAsset (url string ) (* http.Response , error ) {
170- client := & http.Client {
171- CheckRedirect : func (req * http.Request , via []* http.Request ) error {
172- re , err := regexp .Compile (`\/uniget-org\/cli\/releases\/download\/(v\d+\.\d+\.\d+)\/` )
173- if err != nil {
174- return fmt .Errorf ("cannot compile regexp: %w" , err )
175- }
176-
177- if re .MatchString (req .URL .Path ) {
178- requestedVersion = re .FindStringSubmatch (req .URL .Path )[1 ]
179- }
180- return nil
181- },
182- }
183- req , err := http .NewRequest ("GET" , url , nil )
184- if err != nil {
185- return nil , fmt .Errorf ("failed to create request: %s" , err )
186- }
187- req .Header .Set ("Accept" , "application/octet-stream" )
188- req .Header .Set ("User-Agent" , fmt .Sprintf ("%s/%s" , projectName , version ))
189- resp , err := client .Do (req )
190- if err != nil {
191- return nil , fmt .Errorf ("failed to download %s: %s" , url , err )
192- }
193- return resp , nil
194- }
0 commit comments