github.com/tooploox/oya@v0.0.21-0.20230524103240-1cda1861aad6/cmd/internal/run.go (about)

     1  package internal
     2  
     3  import (
     4  	"io"
     5  	"regexp"
     6  	"strings"
     7  
     8  	"github.com/tooploox/oya/pkg/project"
     9  	"github.com/tooploox/oya/pkg/task"
    10  	"github.com/tooploox/oya/pkg/template"
    11  	"github.com/tooploox/oya/pkg/types"
    12  )
    13  
    14  type Args struct {
    15  	All        []string
    16  	Positional []string
    17  	Flags      map[string]string
    18  }
    19  
    20  func Run(workDir, taskName string, taskArgs Args, recurse, changeset bool, stdout, stderr io.Writer) error {
    21  	installDir, err := installDir()
    22  	if err != nil {
    23  		return err
    24  	}
    25  	p, err := project.Detect(workDir, installDir)
    26  	if err != nil {
    27  		return err
    28  	}
    29  	err = p.InstallPacks()
    30  	if err != nil {
    31  		return err
    32  	}
    33  	tn := task.Name(taskName)
    34  
    35  	// If OYA_SCOPE alias is present, prefix task with the alias.
    36  	// Then update OYA_SCOPE to contain the newly built task alias,
    37  	// so when oya run are recursively called in imported tasks,
    38  	// the scope is correctly resolved.
    39  	// Examples:
    40  	// | OYA_SCOPE | task    | new OYA_SCOPE | aliased task |
    41  	// |           | xxx     |               | xxx          |
    42  	// | foo       | xxx     | foo           | foo.xxx      |
    43  	// | foo       | bar.xxx | foo.bar       | foo.bar.xxx  |
    44  	passedOyaScope, _ := lookupOyaScope()
    45  	if len(passedOyaScope) > 0 {
    46  		tn = tn.Aliased(types.Alias(passedOyaScope))
    47  	}
    48  	alias, _ := tn.Split()
    49  	if err := setOyaScope(alias.String()); err != nil {
    50  		return err
    51  	}
    52  	defer mustSetOyaScope(passedOyaScope) // Mostly useful in tests, child processes naturally implement stacks.
    53  
    54  	oyaCmd, found := lookupOyaCmd()
    55  	if found {
    56  		// Tests only.
    57  		task.OyaCmdOverride = &oyaCmd
    58  	}
    59  
    60  	return p.Run(workDir, tn, recurse, changeset, taskArgs.All,
    61  		toScope(taskArgs), stdout, stderr)
    62  }
    63  
    64  func toScope(taskArgs Args) template.Scope {
    65  	return template.Scope{
    66  		"Args":  taskArgs.Positional,
    67  		"Flags": camelizeFlags(taskArgs.Flags),
    68  	}
    69  }
    70  
    71  func camelizeFlags(flags map[string]string) map[string]string {
    72  	result := make(map[string]string)
    73  	for k, v := range flags {
    74  		result[camelize(k)] = v
    75  	}
    76  	return result
    77  }
    78  
    79  var sepRx = regexp.MustCompile("(-|_).")
    80  
    81  // camelize turns - or _ separated identifiers into camel case.
    82  // Example: "aa-bb" becomes "aaBb".
    83  func camelize(s string) string {
    84  	return sepRx.ReplaceAllStringFunc(s, func(match string) string {
    85  		return strings.ToUpper(match[1:])
    86  	})
    87  
    88  }