99 "path"
1010 "path/filepath"
1111 "reflect"
12+ "sort"
1213 "strings"
1314
1415 osh "github.com/Kubuxu/go-os-helper"
@@ -236,7 +237,13 @@ func parseArgs(req *cmds.Request, root *cmds.Command, stdin *os.File) error {
236237 }
237238
238239 stringArgs := make ([]string , 0 , numInputs )
239- fileArgs := make (map [string ]files.Node )
240+ fileArgs := make ([]files.DirEntry , 0 )
241+ // Each file argument's import directory name is recorded under its base name
242+ // to reject two files with the same name but different import directories
243+ // (same directory just means the _exact_ same file, so we can skip it):
244+ // file base name -> file directory name
245+ fileImportDirName := make (map [string ]string )
246+ var fileStdin files.Node
240247
241248 // the index of the current argument definition
242249 iArgDef := 0
@@ -266,7 +273,7 @@ func parseArgs(req *cmds.Request, root *cmds.Command, stdin *os.File) error {
266273 stringArgs , inputs = append (stringArgs , inputs [0 ]), inputs [1 :]
267274 } else if stdin != nil && argDef .SupportsStdin && ! fillingVariadic {
268275 if r , err := maybeWrapStdin (stdin , msgStdinInfo ); err == nil {
269- fileArgs [ "stdin" ] , err = files .NewReaderPathFile (stdin .Name (), r , nil )
276+ fileStdin , err = files .NewReaderPathFile (stdin .Name (), r , nil )
270277 if err != nil {
271278 return err
272279 }
@@ -291,17 +298,7 @@ func parseArgs(req *cmds.Request, root *cmds.Command, stdin *os.File) error {
291298 return err
292299 }
293300 } else if u := isURL (fpath ); u != nil {
294- base := urlBase (u )
295- fpath = base
296- if _ , ok := fileArgs [fpath ]; ok {
297- // Ensure a unique fpath by suffixing ' (n)'.
298- for i := 1 ; ; i ++ {
299- fpath = fmt .Sprintf ("%s (%d)" , base , i )
300- if _ , ok := fileArgs [fpath ]; ! ok {
301- break
302- }
303- }
304- }
301+ fpath = urlBase (u )
305302 file = files .NewWebFile (u )
306303 } else {
307304 fpath = filepath .Clean (fpath )
@@ -333,18 +330,29 @@ func parseArgs(req *cmds.Request, root *cmds.Command, stdin *os.File) error {
333330 }
334331
335332 fpath = filepath .Base (fpath )
333+ importDir := filepath .Dir (fpath )
334+ prevDir , ok := fileImportDirName [fpath ]
335+ if ! ok {
336+ fileImportDirName [fpath ] = importDir
337+ } else {
338+ if prevDir != importDir {
339+ return fmt .Errorf ("file name %s repeated under different import directories: %s and %s" ,
340+ fpath , importDir , prevDir )
341+ }
342+ continue // Skip repeated files.
343+ }
336344 file = nf
337345 }
338346
339- fileArgs [ fpath ] = file
347+ fileArgs = append ( fileArgs , files . FileEntry ( fpath , file ))
340348 } else if stdin != nil && argDef .SupportsStdin &&
341349 argDef .Required && ! fillingVariadic {
342350 r , err := maybeWrapStdin (stdin , msgStdinInfo )
343351 if err != nil {
344352 return err
345353 }
346354
347- fileArgs [ stdinName ( req )] , err = files .NewReaderPathFile (stdin .Name (), r , nil )
355+ fileStdin , err = files .NewReaderPathFile (stdin .Name (), r , nil )
348356 if err != nil {
349357 return err
350358 }
@@ -370,8 +378,14 @@ func parseArgs(req *cmds.Request, root *cmds.Command, stdin *os.File) error {
370378 }
371379
372380 req .Arguments = stringArgs
381+ if fileStdin != nil {
382+ fileArgs = append (fileArgs , files .FileEntry (stdinName (req ), fileStdin ))
383+ }
373384 if len (fileArgs ) > 0 {
374- req .Files = files .NewMapDirectory (fileArgs )
385+ sort .Slice (fileArgs , func (i , j int ) bool {
386+ return fileArgs [i ].Name () < fileArgs [j ].Name ()
387+ })
388+ req .Files = files .NewSliceDirectory (fileArgs )
375389 }
376390
377391 return nil
0 commit comments