@@ -42,13 +42,10 @@ func parseOutputCSV(s string) (client.ExportEntry, error) {
4242 if v , ok := ex .Attrs ["output" ]; ok {
4343 return ex , errors .Errorf ("output=%s not supported for --output, you meant dest=%s?" , v , v )
4444 }
45- ex .Output , ex .OutputDir , err = resolveExporterDest (ex .Type , ex .Attrs [ "dest" ], ex . Attrs )
45+ ex .Output , ex .OutputDir , err = resolveExporterDest (ex .Type , ex .Attrs )
4646 if err != nil {
4747 return ex , errors .Wrap (err , "invalid output option: output" )
4848 }
49- if ex .Output != nil || ex .OutputDir != "" {
50- delete (ex .Attrs , "dest" )
51- }
5249 return ex , nil
5350}
5451
@@ -66,55 +63,83 @@ func ParseOutput(exports []string) ([]client.ExportEntry, error) {
6663}
6764
6865// resolveExporterDest returns at most either one of io.WriteCloser (single file) or a string (directory path).
69- func resolveExporterDest (exporter , dest string , attrs map [string ]string ) (filesync.FileOutputFunc , string , error ) {
70- wrapWriter := func (wc io.WriteCloser ) func (map [string ]string ) (io.WriteCloser , error ) {
71- return func (m map [string ]string ) (io.WriteCloser , error ) {
72- return wc , nil
73- }
74- }
75-
76- var supportFile bool
77- var supportDir bool
66+ func resolveExporterDest (exporter string , attrs map [string ]string ) (destFile filesync.FileOutputFunc , destDir string , _ error ) {
67+ var destFilePath string
7868 switch exporter {
7969 case client .ExporterLocal :
80- supportDir = true
70+ var ok bool
71+ destDir , ok = attrs ["dest" ]
72+ if ! ok {
73+ return nil , "" , errors .Errorf ("%s exporter requires dest=<path>" , client .ExporterLocal )
74+ }
75+ delete (attrs , "dest" )
8176 case client .ExporterTar :
82- supportFile = true
77+ var ok bool
78+ destFilePath , ok = attrs ["dest" ]
79+ if ! ok {
80+ return nil , "" , errors .Errorf ("%s exporter requires dest=<file>" , client .ExporterTar )
81+ }
82+ delete (attrs , "dest" )
8383 case client .ExporterOCI , client .ExporterDocker :
8484 tar , err := strconv .ParseBool (attrs ["tar" ])
8585 if err != nil {
8686 tar = true
8787 }
88- supportFile = tar
89- supportDir = ! tar
88+ var ok bool
89+ if tar {
90+ destFilePath , ok = attrs ["dest" ]
91+ } else {
92+ destDir , ok = attrs ["dest" ]
93+ }
94+ if ! ok {
95+ return nil , "" , errors .Errorf ("%s exporter requires dest=<file|path>" , exporter )
96+ }
97+ delete (attrs , "dest" )
98+ case client .ExporterGateway :
99+ destFilePath = attrs ["file" ]
100+ destDir = attrs ["dir" ]
101+ if destFilePath == "" && destDir == "" {
102+ return nil , "" , errors .Errorf ("%s exporter requires file=<file> or dir=<path>" , exporter )
103+ }
104+ if destFilePath != "" && destDir != "" {
105+ return nil , "" , errors .Errorf ("%s exporter requires only one of file=<file> or dir=<path>" , exporter )
106+ }
107+ delete (attrs , "file" )
108+ delete (attrs , "dir" )
109+ default :
110+ dest , ok := attrs ["dest" ]
111+ if ok {
112+ return nil , "" , errors .Errorf ("output %s is not supported by %s exporter" , dest , exporter )
113+ }
90114 }
91115
92- if supportDir {
93- if dest == "" {
94- return nil , "" , errors .Errorf ("output directory is required for %s exporter" , exporter )
116+ if destFilePath != "" {
117+ wrapWriter := func (wc io.WriteCloser ) func (map [string ]string ) (io.WriteCloser , error ) {
118+ return func (m map [string ]string ) (io.WriteCloser , error ) {
119+ return wc , nil
120+ }
95121 }
96- return nil , dest , nil
97- } else if supportFile {
98- if dest != "" && dest != "-" {
99- fi , err := os .Stat (dest )
122+ if destFilePath != "" && destFilePath != "-" {
123+ fi , err := os .Stat (destFilePath )
100124 if err != nil && ! errors .Is (err , os .ErrNotExist ) {
101- return nil , "" , errors .Wrapf (err , "invalid destination file: %s" , dest )
125+ return nil , "" , errors .Wrapf (err , "invalid destination file: %s" , destFilePath )
102126 }
103127 if err == nil && fi .IsDir () {
104128 return nil , "" , errors .Errorf ("destination file is a directory" )
105129 }
106- w , err := os .Create (dest )
107- return wrapWriter (w ), "" , err
108- }
109- // if no output file is specified, use stdout
110- if _ , err := console .ConsoleFromFile (os .Stdout ); err == nil {
111- return nil , "" , errors .Errorf ("output file is required for %s exporter. refusing to write to console" , exporter )
130+ w , err := os .Create (destFilePath )
131+ if err != nil {
132+ return nil , "" , err
133+ }
134+ destFile = wrapWriter (w )
135+ } else {
136+ // if no output file is specified, use stdout
137+ if _ , err := console .ConsoleFromFile (os .Stdout ); err == nil {
138+ return nil , "" , errors .Errorf ("output file is required for %s exporter. refusing to write to console" , exporter )
139+ }
140+ destFile = wrapWriter (os .Stdout )
112141 }
113- return wrapWriter (os .Stdout ), "" , nil
114142 }
115- // e.g. client.ExporterImage
116- if dest != "" {
117- return nil , "" , errors .Errorf ("output %s is not supported by %s exporter" , dest , exporter )
118- }
119- return nil , "" , nil
143+
144+ return destFile , destDir , nil
120145}
0 commit comments