11package main
22
33import (
4- "bytes"
54 "context"
65 "flag"
76 "fmt"
@@ -20,26 +19,14 @@ import (
2019 "github.com/AdguardTeam/golibs/logutil/slogutil"
2120 "github.com/AdguardTeam/golibs/netutil"
2221 "github.com/AdguardTeam/golibs/syncutil"
22+ "github.com/AdguardTeam/golibs/validate"
2323)
2424
2525// download and save all translations.
26- func (c * twoskyClient ) download (ctx context.Context , l * slog.Logger ) (err error ) {
27- var numWorker int
28-
29- flagSet := flag .NewFlagSet ("download" , flag .ExitOnError )
30- flagSet .Usage = func () {
31- usage ("download command error" )
32- }
33- flagSet .IntVar (& numWorker , "n" , 1 , "number of concurrent downloads" )
34-
35- err = flagSet .Parse (os .Args [2 :])
26+ func (c * twoskyClient ) download (ctx context.Context , l * slog.Logger ) {
27+ numWorker , err := parseDownloadArgs ()
3628 if err != nil {
37- // Don't wrap the error since it's informative enough as is.
38- return err
39- }
40-
41- if numWorker < 1 {
42- usage ("count must be positive" )
29+ usage (err .Error ())
4330 }
4431
4532 downloadURI := c .uri .JoinPath ("download" )
@@ -62,8 +49,7 @@ func (c *twoskyClient) download(ctx context.Context, l *slog.Logger) (err error)
6249 }
6350
6451 for _ , baseFile := range c .localizableFiles {
65- file := filepath .Base (baseFile )
66- dir := filepath .Dir (baseFile )
52+ dir , file := filepath .Split (baseFile )
6753
6854 for _ , lang := range c .langs {
6955 uri := translationURL (downloadURI , file , c .projectID , lang )
@@ -79,8 +65,20 @@ func (c *twoskyClient) download(ctx context.Context, l *slog.Logger) (err error)
7965 wg .Wait ()
8066
8167 printFailedLocales (ctx , l , dw .failed )
68+ }
8269
83- return nil
70+ // parseDownloadArgs parses command-line arguments for the download command.
71+ func parseDownloadArgs () (numWorker int , err error ) {
72+ flagSet := flag .NewFlagSet ("download" , flag .ExitOnError )
73+ flagSet .IntVar (& numWorker , "n" , 1 , "number of concurrent downloads" )
74+
75+ err = flagSet .Parse (os .Args [2 :])
76+ if err != nil {
77+ // Don't wrap the error since it's informative enough as is.
78+ return 0 , err
79+ }
80+
81+ return numWorker , validate .Positive ("count" , numWorker )
8482}
8583
8684// printFailedLocales prints sorted list of failed downloads, if any. l and
@@ -137,9 +135,6 @@ func (w *downloadWorker) run() {
137135 }
138136}
139137
140- // newLineSuffix is the suffix required for each text file.
141- var newLineSuffix = []byte ("\n " )
142-
143138// saveToFile downloads translation by url and saves it to a file, or returns
144139// error.
145140func saveToFile (
@@ -155,8 +150,8 @@ func saveToFile(
155150 return fmt .Errorf ("getting translation %q: %s" , code , err )
156151 }
157152
158- if ! bytes . HasSuffix (data , newLineSuffix ) {
159- data = append (data , newLineSuffix ... )
153+ if data [ len (data ) - 1 ] != '\n' {
154+ data = append (data , '\n' )
160155 }
161156
162157 name := filepath .Join (localesDir , code + ".json" )
@@ -171,7 +166,8 @@ func saveToFile(
171166}
172167
173168// getTranslation returns received translation data and error. If err is not
174- // nil, data may contain a response from server for inspection.
169+ // nil, data may contain a response from server for inspection. Otherwise, the
170+ // data is guaranteed to be non-empty.
175171func getTranslation (
176172 ctx context.Context ,
177173 l * slog.Logger ,
@@ -194,8 +190,11 @@ func getTranslation(
194190 limitReader := ioutil .LimitReader (resp .Body , readLimit .Bytes ())
195191
196192 data , readErr := io .ReadAll (limitReader )
193+ if readErr != nil {
194+ return nil , errors .WithDeferred (err , readErr )
195+ }
197196
198- return data , errors . WithDeferred ( err , readErr )
197+ return data , validate . NotEmptySlice ( "response" , data )
199198}
200199
201200// translationURL returns a new url.URL with provided query parameters.
0 commit comments