@@ -24,6 +24,7 @@ import (
2424 "io"
2525 "io/ioutil"
2626 "os"
27+ "strings"
2728
2829 "github.com/grycap/oscar-cli/v2/pkg/config"
2930 "github.com/grycap/oscar-cli/v2/pkg/service"
@@ -58,6 +59,7 @@ func serviceRunFunc(cmd *cobra.Command, args []string) error {
5859 inputFile , _ := cmd .Flags ().GetString ("file-input" )
5960 textInput , _ := cmd .Flags ().GetString ("text-input" )
6061 outputFile , _ := cmd .Flags ().GetString ("output" )
62+ decodeOutput , _ := cmd .Flags ().GetBool ("decode-output" )
6163 if inputFile == "" && textInput == "" {
6264 return errors .New ("you must specify \" --file-input\" or \" --text-input\" flag" )
6365 }
@@ -110,28 +112,28 @@ func serviceRunFunc(cmd *cobra.Command, args []string) error {
110112 return errors .New ("unable to copy the response" )
111113 }
112114
113- // Decode the result body
114- tmpfile .Seek (0 , 0 )
115- decoder := base64 .NewDecoder (base64 .StdEncoding , tmpfile )
116-
117- // Parse output (store file if --output is set)
118- var out * os.File
119-
120- if outputFile != "" {
121- // Create the file if --output is set
122- out , err = os .Create (outputFile )
115+ if decodeOutput {
116+ tmpfile .Seek (0 , 0 )
117+ response , err := io .ReadAll (tmpfile )
123118 if err != nil {
124- return fmt . Errorf ("unable to create the file \" %s \" " , outputFile )
119+ return errors . New ("unable to read the response" )
125120 }
126- } else {
127- // Create a temporary file
128- out , err = ioutil .TempFile ("" , "" )
121+ decoded , err := decodeLastBase64Line (response )
129122 if err != nil {
130- return errors . New ( "unable to create a temporary file to decode the result" )
123+ return err
131124 }
132- defer os .Remove (out .Name ())
125+ return writeServiceRunOutput (outputFile , bytes .NewReader (decoded ))
126+ }
127+
128+ // Decode the result body
129+ tmpfile .Seek (0 , 0 )
130+ decoder := base64 .NewDecoder (base64 .StdEncoding , tmpfile )
131+
132+ out , err := createServiceRunOutput (outputFile )
133+ if err != nil {
134+ return err
133135 }
134- defer out . Close ( )
136+ defer closeServiceRunOutput ( out , outputFile )
135137
136138 // Copy the decoder stream into out
137139 _ , err = io .Copy (out , decoder )
@@ -158,6 +160,68 @@ func serviceRunFunc(cmd *cobra.Command, args []string) error {
158160 return nil
159161}
160162
163+ func decodeLastBase64Line (response []byte ) ([]byte , error ) {
164+ lines := strings .Split (string (response ), "\n " )
165+ decoder := base64 .StdEncoding .Strict ()
166+
167+ for i := len (lines ) - 1 ; i >= 0 ; i -- {
168+ line := strings .TrimSpace (lines [i ])
169+ if line == "" {
170+ continue
171+ }
172+ decoded , err := decoder .DecodeString (line )
173+ if err == nil {
174+ return decoded , nil
175+ }
176+ }
177+
178+ return nil , errors .New ("unable to find base64-encoded output in the response" )
179+ }
180+
181+ func writeServiceRunOutput (outputFile string , input io.Reader ) error {
182+ out , err := createServiceRunOutput (outputFile )
183+ if err != nil {
184+ return err
185+ }
186+ defer closeServiceRunOutput (out , outputFile )
187+
188+ if _ , err := io .Copy (out , input ); err != nil {
189+ return errors .New ("unable to copy the response" )
190+ }
191+
192+ if outputFile == "" {
193+ out .Seek (0 , 0 )
194+ if _ , err := io .Copy (os .Stdout , out ); err != nil {
195+ return errors .New ("unable to print the result" )
196+ }
197+ }
198+
199+ return nil
200+ }
201+
202+ func createServiceRunOutput (outputFile string ) (* os.File , error ) {
203+ if outputFile != "" {
204+ out , err := os .Create (outputFile )
205+ if err != nil {
206+ return nil , fmt .Errorf ("unable to create the file \" %s\" " , outputFile )
207+ }
208+ return out , nil
209+ }
210+
211+ out , err := ioutil .TempFile ("" , "" )
212+ if err != nil {
213+ return nil , errors .New ("unable to create a temporary file to decode the result" )
214+ }
215+ return out , nil
216+ }
217+
218+ func closeServiceRunOutput (out * os.File , outputFile string ) {
219+ if outputFile == "" {
220+ os .Remove (out .Name ())
221+ }
222+ out .Close ()
223+ }
224+
161225func makeServiceRunCmd () * cobra.Command {
162226 serviceRunCmd := & cobra.Command {
163227 Use : "run SERVICE_NAME {--file-input | --text-input}" ,
@@ -173,6 +237,7 @@ func makeServiceRunCmd() *cobra.Command {
173237 serviceRunCmd .Flags ().StringP ("file-input" , "f" , "" , "input file for the request" )
174238 serviceRunCmd .Flags ().StringP ("text-input" , "i" , "" , "text input string for the request" )
175239 serviceRunCmd .Flags ().StringP ("output" , "o" , "" , "file path to store the output" )
240+ serviceRunCmd .Flags ().Bool ("decode-output" , false , "decode the last base64-encoded line in the response and ignore logs" )
176241
177242 return serviceRunCmd
178243}
0 commit comments