@@ -300,57 +300,120 @@ func (s *Server) exportEnvVars(appName string) map[string]string {
300300 return envs
301301}
302302
303- func (s * Server ) exportRuntimeArgs (
303+ // partitionArgs separates arguments into positional (non-flag) and flag arguments.
304+ // Positional args come before any flags. Once a flag is encountered, all remaining
305+ // args are treated as flags or flag values.
306+ func partitionArgs (args []string ) (positional []string , flags []string ) {
307+ for i , arg := range args {
308+ if strings .HasPrefix (arg , "--" ) {
309+ // split here
310+ positional = args [:i ]
311+ flags = args [i :]
312+ return
313+ }
314+ }
315+ // no flags found
316+ positional = args
317+ return
318+ }
319+
320+ // exportPositionalArgs transforms positional arguments into environment variable placeholders.
321+ // Arguments are numbered starting from 1 (ARG_1, ARG_2, etc.).
322+ func (s * Server ) exportPositionalArgs (
323+ positional []string ,
304324 appName string ,
305- seen map [string ]struct {},
306325 recordContractFunc func (k , v string ),
307326) []string {
308- var args []string
327+ if len (positional ) == 0 {
328+ return nil
329+ }
309330
310- // Filter out args with cross-server references.
311- filteredArgs := s .filterArgs (s .Args )
331+ result := make ([]string , 0 , len (positional ))
332+ for i := range positional {
333+ // Number positional args starting from 1.
334+ argKey := fmt .Sprintf ("ARG_%d" , i + 1 )
335+ envVarName := buildEnvVarName (appName , s .Name (), argKey )
336+ envVarRef := fmt .Sprintf ("${%s}" , envVarName )
337+ result = append (result , envVarRef )
338+ recordContractFunc (envVarName , envVarRef )
339+ }
340+ return result
341+ }
312342
313- for i := 0 ; i < len (filteredArgs ); i ++ {
314- rawArg := filteredArgs [i ]
343+ // exportFlagArgs processes flag arguments and transforms them into environment variable placeholders.
344+ func (s * Server ) exportFlagArgs (
345+ flags []string ,
346+ appName string ,
347+ seen map [string ]struct {},
348+ recordContractFunc func (k , v string ),
349+ ) []string {
350+ if len (flags ) == 0 {
351+ return nil
352+ }
315353
316- // Sanity check for arg.
317- if ! strings .HasPrefix (rawArg , "--" ) {
318- continue // value
319- }
354+ var result []string
355+ for i := 0 ; i < len (flags ); i ++ {
356+ flag := flags [i ]
320357
321- arg := extractArgNameWithPrefix ( rawArg )
322- if _ , ok := seen [ arg ]; ok {
323- continue // Already handled.
358+ // Skip non-flag arguments (values).
359+ if ! strings . HasPrefix ( flag , "--" ) {
360+ continue
324361 }
325362
326- // --arg=val case
327- if strings .HasPrefix (rawArg , arg + "=" ) {
328- t := transformValueArg (appName , s .Name (), rawArg )
329- args = append (args , t .FormattedArg )
330- recordContractFunc (t .EnvVarName , t .EnvVarReference )
331- seen [arg ] = struct {}{}
363+ argName := extractArgNameWithPrefix (flag )
364+
365+ // Skip if already processed.
366+ if _ , ok := seen [argName ]; ok {
332367 continue
333368 }
334369
335- // --arg val case
336- if rawArg == arg && i + 1 < len ( filteredArgs ) && ! strings .HasPrefix ( filteredArgs [ i + 1 ] , "-- " ) {
337- t := transformValueArg (appName , s .Name (), rawArg )
338- args = append (args , t .FormattedArg )
370+ // Handle --arg=value format.
371+ if strings .Contains ( flag , "= " ) {
372+ t := transformValueArg (appName , s .Name (), flag )
373+ result = append (result , t .FormattedArg )
339374 recordContractFunc (t .EnvVarName , t .EnvVarReference )
340- seen [arg ] = struct {}{}
341- i ++ // Skip the next item since it's an actual value.
375+ seen [argName ] = struct {}{}
342376 continue
343377 }
344378
345- // bool flag
346- if rawArg == arg {
347- args = append (args , arg )
348- seen [arg ] = struct {}{}
379+ // Handle --arg value format (check next item).
380+ if i + 1 < len (flags ) && ! strings .HasPrefix (flags [i + 1 ], "--" ) {
381+ t := transformValueArg (appName , s .Name (), flag )
382+ result = append (result , t .FormattedArg )
383+ recordContractFunc (t .EnvVarName , t .EnvVarReference )
384+ seen [argName ] = struct {}{}
385+ i ++ // Skip the value.
349386 continue
350387 }
388+
389+ // Handle boolean flag.
390+ result = append (result , flag )
391+ seen [argName ] = struct {}{}
351392 }
352393
353- return args
394+ return result
395+ }
396+
397+ func (s * Server ) exportRuntimeArgs (
398+ appName string ,
399+ seen map [string ]struct {},
400+ recordContractFunc func (k , v string ),
401+ ) []string {
402+ // Filter out args with cross-server references.
403+ filteredArgs := s .filterArgs (s .Args )
404+ if len (filteredArgs ) == 0 {
405+ return nil
406+ }
407+
408+ // Partition into positional and flag arguments.
409+ positional , flags := partitionArgs (filteredArgs )
410+
411+ // Process each type separately and combine results.
412+ var result []string
413+ result = append (result , s .exportPositionalArgs (positional , appName , recordContractFunc )... )
414+ result = append (result , s .exportFlagArgs (flags , appName , seen , recordContractFunc )... )
415+
416+ return result
354417}
355418
356419func (s * Servers ) Export (path string ) (map [string ]string , error ) {
0 commit comments