func createKamelWithModelineCommand()

in pkg/cmd/modeline.go [90:193]


func createKamelWithModelineCommand(ctx context.Context, args []string) (*cobra.Command, []string, error) {
	rootCmd, err := NewKamelCommand(ctx)
	if err != nil {
		return rootCmd, nil, err
	}

	target, flags, err := rootCmd.Find(args)
	if err != nil {
		return rootCmd, nil, err
	}

	isLocalBuild := target.Name() == buildCmdName && target.Parent().Name() == localCmdName
	isInspect := target.Name() == inspectCmdName

	if target.Name() != runCmdName && !isLocalBuild && !isInspect {
		return rootCmd, args, nil
	}

	err = target.ParseFlags(flags)
	if errors.Is(err, pflag.ErrHelp) {
		return rootCmd, args, nil
	} else if err != nil {
		return rootCmd, nil, err
	}

	fg := target.Flags()

	// Only the run command has source flag (for now). Remove condition when
	// local run also supports source.
	additionalSources := make([]string, 0)
	if target.Name() == runCmdName && target.Parent().Name() != localCmdName {
		additionalSources, err = fg.GetStringArray(runCmdSourcesArgs)
		if err != nil {
			return rootCmd, nil, err
		}
	}

	files := make([]string, 0, len(fg.Args())+len(additionalSources))
	files = append(files, fg.Args()...)
	files = append(files, additionalSources...)

	opts, err := extractModelineOptions(ctx, files, rootCmd)
	if err != nil {
		return rootCmd, nil, fmt.Errorf("cannot read sources: %w", err)
	}

	// Extract list of property/trait names already specified by the user.
	cliParamNames := []string{}
	index := 0
	for _, arg := range args {
		if arg == "-p" || arg == "--property" || arg == "-t" || arg == "--trait" || arg == "--build-property" {
			// Property or trait is assumed to be in the form: <name>=<value>
			splitValues := strings.Split(args[index+1], "=")
			cliParamNames = append(cliParamNames, splitValues[0])
		}
		index++
	}

	// filter out in place non-run options
	nOpts := 0
	for _, o := range opts {
		// Check if property name is given by user.
		paramAlreadySpecifiedByUser := false
		if o.Name == "property" || o.Name == "trait" || o.Name == "build-property" {
			paramComponents := strings.Split(o.Value, "=")
			for _, paramName := range cliParamNames {
				if paramName == paramComponents[0] {
					paramAlreadySpecifiedByUser = true
					break
				}
			}
		}

		// Skip properties already specified by the user otherwise add all options.
		if !paramAlreadySpecifiedByUser && !nonRunOptions[o.Name] {
			opts[nOpts] = o
			nOpts++
		}
	}

	opts = opts[:nOpts]

	for _, o := range opts {
		prefix := "-"
		if len(o.Name) > 1 {
			prefix = "--"
		}
		// Using the k=v syntax to avoid issues with booleans
		if len(o.Value) > 0 {
			args = append(args, fmt.Sprintf("%s%s=%s", prefix, o.Name, o.Value))
		} else {
			args = append(args, fmt.Sprintf("%s%s", prefix, o.Name))
		}
	}

	// Recreating the command as it's dirty
	rootCmd, err = NewKamelCommand(ctx)
	if err != nil {
		return rootCmd, nil, err
	}
	rootCmd.SetArgs(args)

	return rootCmd, args, nil
}