66 "bytes"
77 "compress/gzip"
88 "context"
9+ "errors"
910 "flag"
1011 "fmt"
1112 "io"
@@ -34,7 +35,7 @@ func main() {
3435 }
3536
3637 // Load current versions table
37- var table []* tableRow
38+ var table []tableRow
3839 fd , err := os .Open (* versionsFile )
3940 if os .IsNotExist (err ) {
4041 // File doesn't exist yet. That's alright.
@@ -109,39 +110,53 @@ func getReleases(ctx context.Context) ([]*github.RepositoryRelease, error) {
109110 return releases , nil
110111}
111112
112- func getReleaseVersion (rel * github.RepositoryRelease ) (* tableRow , error ) {
113+ func getReleaseVersion (rel * github.RepositoryRelease ) (tableRow , error ) {
113114 goos := runtime .GOOS
114115 if goos == "darwin" {
115116 goos = "macos"
116117 }
118+
119+ row := tableRow {
120+ Version : rel .GetTagName (),
121+ Date : rel .GetCreatedAt ().Format ("2006-01-01" ),
122+ }
123+
117124 find := fmt .Sprintf ("syncthing-%s-%s" , goos , runtime .GOARCH )
118125 for _ , asset := range rel .Assets {
119126 if strings .HasPrefix (* asset .Name , find ) {
120127 log .Println ("Downloading" , * asset .Name )
121128 resp , err := http .Get (* asset .BrowserDownloadURL )
122129 if err != nil {
123- return nil , err
130+ return tableRow {} , err
124131 }
125132 bs , err := io .ReadAll (resp .Body )
126133 resp .Body .Close ()
127134 if err != nil {
128- return nil , err
135+ return tableRow {} , err
129136 }
130137 switch filepath .Ext (* asset .Name ) {
131138 case ".zip" :
132- return getReleaseVersionZip (bs )
139+ r , err := getReleaseVersionZip (bs )
140+ if err != nil {
141+ return tableRow {}, err
142+ }
143+ return row .merge (r ), nil
133144 default :
134- return getReleaseVersionTarGz (bs )
145+ r , err := getReleaseVersionTarGz (bs )
146+ if err != nil {
147+ return tableRow {}, err
148+ }
149+ return row .merge (r ), nil
135150 }
136151 }
137152 }
138- return nil , fmt .Errorf ("no asset found" )
153+ return tableRow {} , fmt .Errorf ("no asset found" )
139154}
140155
141- func getReleaseVersionZip (bs []byte ) (* tableRow , error ) {
156+ func getReleaseVersionZip (bs []byte ) (tableRow , error ) {
142157 zr , err := zip .NewReader (bytes .NewReader (bs ), int64 (len (bs )))
143158 if err != nil {
144- return nil , err
159+ return tableRow {} , err
145160 }
146161 for _ , f := range zr .File {
147162 if strings .Contains (path .Dir (f .Name ), "/" ) {
@@ -153,18 +168,18 @@ func getReleaseVersionZip(bs []byte) (*tableRow, error) {
153168 }
154169 rd , err := f .Open ()
155170 if err != nil {
156- return nil , err
171+ return tableRow {} , err
157172 }
158173
159174 return getVersionFromReader (rd )
160175 }
161- return nil , fmt .Errorf ("no syncthing binary found" )
176+ return tableRow {} , fmt .Errorf ("no syncthing binary found" )
162177}
163178
164- func getReleaseVersionTarGz (bs []byte ) (* tableRow , error ) {
179+ func getReleaseVersionTarGz (bs []byte ) (tableRow , error ) {
165180 gr , err := gzip .NewReader (bytes .NewReader (bs ))
166181 if err != nil {
167- return nil , err
182+ return tableRow {} , err
168183 }
169184 tr := tar .NewReader (gr )
170185 for {
@@ -178,36 +193,64 @@ func getReleaseVersionTarGz(bs []byte) (*tableRow, error) {
178193
179194 return getVersionFromReader (tr )
180195 }
181- return nil , fmt .Errorf ("no syncthing binary found" )
196+ return tableRow {} , fmt .Errorf ("no syncthing binary found" )
182197}
183198
184- func getVersionFromReader (r io.Reader ) (* tableRow , error ) {
199+ func getVersionFromReader (r io.Reader ) (tableRow , error ) {
185200 fd , err := os .CreateTemp ("" , "syncthing" )
186201 if err != nil {
187- return nil , err
202+ return tableRow {} , err
188203 }
189204 if _ , err := io .Copy (fd , r ); err != nil {
190- return nil , err
205+ return tableRow {} , err
191206 }
192207 fd .Close ()
193208 defer os .Remove (fd .Name ())
194209 if err := os .Chmod (fd .Name (), 0o755 ); err != nil {
195- return nil , err
210+ return tableRow {} , err
196211 }
197212
198- return getVersionFromCommand (fd .Name ())
213+ if row , err := getVersionFromCommand (fd .Name ()); err == nil {
214+ return row , nil
215+ }
216+ return getVersionFromGo (fd .Name ())
217+ }
218+
219+ func getVersionFromGo (name string ) (tableRow , error ) {
220+ cmd := exec .Command ("go" , "version" , "-m" , name )
221+ out , err := cmd .Output ()
222+ if err != nil {
223+ return tableRow {}, err
224+ }
225+
226+ // % go version -m ~/bin/syncthing
227+ // /Users/jb/bin/syncthing: go1.25.7
228+ // path github.com/syncthing/syncthing/cmd/syncthing
229+ // ...
230+
231+ if idx := bytes .Index (out , []byte {'\n' }); idx < 0 {
232+ return tableRow {}, errors .New ("no version" )
233+ } else {
234+ out = out [:idx ]
235+ }
236+
237+ if idx := bytes .LastIndex (out , []byte {' ' }); idx < 0 {
238+ return tableRow {}, errors .New ("no version" )
239+ } else {
240+ return tableRow {Runtime : string (out [idx + 1 :])}, nil
241+ }
199242}
200243
201- func getVersionFromCommand (name string ) (* tableRow , error ) {
244+ func getVersionFromCommand (name string ) (tableRow , error ) {
202245 cmd := exec .Command (name , "--version" )
203246 out , err := cmd .Output ()
204247 if err != nil {
205- return nil , err
248+ return tableRow {} , err
206249 }
207250
208251 var r tableRow
209252 if err := r .fromVersion (string (out )); err != nil {
210- return nil , err
253+ return tableRow {} , err
211254 }
212- return & r , nil
255+ return r , nil
213256}
0 commit comments