How to use AbsolutePaths method of utils Package

Best Rod code snippet using utils.AbsolutePaths

utils.go

Source:utils.go Github

copy

Full Screen

1package config2import (3 "errors"4 "fmt"5 "os"6 "path/filepath"7 "strconv"8 "strings"9 g "github.com/cloudposse/atmos/pkg/globals"10 u "github.com/cloudposse/atmos/pkg/utils"11)12// FindAllStackConfigsInPathsForStack finds all stack config files in the paths specified by globs for the provided stack13func FindAllStackConfigsInPathsForStack(14 stack string,15 includeStackPaths []string,16 excludeStackPaths []string,17) ([]string, []string, bool, error) {18 var absolutePaths []string19 var relativePaths []string20 var stackIsDir = strings.IndexAny(stack, "/") > 021 for _, p := range includeStackPaths {22 pathWithExt := p23 ext := filepath.Ext(p)24 if ext == "" {25 ext = g.DefaultStackConfigFileExtension26 pathWithExt = p + ext27 }28 // Find all matches in the glob29 matches, err := u.GetGlobMatches(pathWithExt)30 if err != nil || len(matches) == 0 {31 // Retry (b/c we are using `doublestar` library, and it sometimes has issues reading many files in a Docker container)32 // TODO: review `doublestar` library33 matches, err = u.GetGlobMatches(pathWithExt)34 if err != nil {35 return nil, nil, false, err36 }37 }38 // Exclude files that match any of the excludePaths39 for _, matchedFileAbsolutePath := range matches {40 matchedFileRelativePath := u.TrimBasePathFromPath(ProcessedConfig.StacksBaseAbsolutePath+"/", matchedFileAbsolutePath)41 // Check if the provided stack matches a file in the config folders (excluding the files from `excludeStackPaths`)42 stackMatch := strings.HasSuffix(matchedFileAbsolutePath, stack+g.DefaultStackConfigFileExtension)43 if stackMatch {44 allExcluded := true45 for _, excludePath := range excludeStackPaths {46 excludeMatch, err := u.PathMatch(excludePath, matchedFileAbsolutePath)47 if err != nil {48 u.PrintError(err)49 continue50 } else if excludeMatch {51 allExcluded = false52 break53 }54 }55 if allExcluded && stackIsDir {56 return []string{matchedFileAbsolutePath}, []string{matchedFileRelativePath}, true, nil57 }58 }59 include := true60 for _, excludePath := range excludeStackPaths {61 excludeMatch, err := u.PathMatch(excludePath, matchedFileAbsolutePath)62 if err != nil {63 u.PrintError(err)64 include = false65 continue66 } else if excludeMatch {67 include = false68 continue69 }70 }71 if include {72 absolutePaths = append(absolutePaths, matchedFileAbsolutePath)73 relativePaths = append(relativePaths, matchedFileRelativePath)74 }75 }76 }77 return absolutePaths, relativePaths, false, nil78}79// FindAllStackConfigsInPaths finds all stack config files in the paths specified by globs80func FindAllStackConfigsInPaths(81 includeStackPaths []string,82 excludeStackPaths []string,83) ([]string, []string, error) {84 var absolutePaths []string85 var relativePaths []string86 for _, p := range includeStackPaths {87 pathWithExt := p88 ext := filepath.Ext(p)89 if ext == "" {90 ext = g.DefaultStackConfigFileExtension91 pathWithExt = p + ext92 }93 // Find all matches in the glob94 matches, err := u.GetGlobMatches(pathWithExt)95 if err != nil || len(matches) == 0 {96 // Retry (b/c we are using `doublestar` library, and it sometimes has issues reading many files in a Docker container)97 // TODO: review `doublestar` library98 matches, err = u.GetGlobMatches(pathWithExt)99 if err != nil {100 return nil, nil, err101 }102 }103 // Exclude files that match any of the excludePaths104 for _, matchedFileAbsolutePath := range matches {105 matchedFileRelativePath := u.TrimBasePathFromPath(ProcessedConfig.StacksBaseAbsolutePath+"/", matchedFileAbsolutePath)106 include := true107 for _, excludePath := range excludeStackPaths {108 excludeMatch, err := u.PathMatch(excludePath, matchedFileAbsolutePath)109 if err != nil {110 u.PrintError(err)111 include = false112 continue113 } else if excludeMatch {114 include = false115 continue116 }117 }118 if include {119 absolutePaths = append(absolutePaths, matchedFileAbsolutePath)120 relativePaths = append(relativePaths, matchedFileRelativePath)121 }122 }123 }124 return absolutePaths, relativePaths, nil125}126func processEnvVars() error {127 basePath := os.Getenv("ATMOS_BASE_PATH")128 if len(basePath) > 0 {129 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_BASE_PATH=%s", basePath))130 Config.BasePath = basePath131 }132 stacksBasePath := os.Getenv("ATMOS_STACKS_BASE_PATH")133 if len(stacksBasePath) > 0 {134 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_STACKS_BASE_PATH=%s", stacksBasePath))135 Config.Stacks.BasePath = stacksBasePath136 }137 stacksIncludedPaths := os.Getenv("ATMOS_STACKS_INCLUDED_PATHS")138 if len(stacksIncludedPaths) > 0 {139 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_STACKS_INCLUDED_PATHS=%s", stacksIncludedPaths))140 Config.Stacks.IncludedPaths = strings.Split(stacksIncludedPaths, ",")141 }142 stacksExcludedPaths := os.Getenv("ATMOS_STACKS_EXCLUDED_PATHS")143 if len(stacksExcludedPaths) > 0 {144 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_STACKS_EXCLUDED_PATHS=%s", stacksExcludedPaths))145 Config.Stacks.ExcludedPaths = strings.Split(stacksExcludedPaths, ",")146 }147 stacksNamePattern := os.Getenv("ATMOS_STACKS_NAME_PATTERN")148 if len(stacksNamePattern) > 0 {149 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_STACKS_NAME_PATTERN=%s", stacksNamePattern))150 Config.Stacks.NamePattern = stacksNamePattern151 }152 componentsTerraformBasePath := os.Getenv("ATMOS_COMPONENTS_TERRAFORM_BASE_PATH")153 if len(componentsTerraformBasePath) > 0 {154 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_TERRAFORM_BASE_PATH=%s", componentsTerraformBasePath))155 Config.Components.Terraform.BasePath = componentsTerraformBasePath156 }157 componentsTerraformApplyAutoApprove := os.Getenv("ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE")158 if len(componentsTerraformApplyAutoApprove) > 0 {159 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE=%s", componentsTerraformApplyAutoApprove))160 applyAutoApproveBool, err := strconv.ParseBool(componentsTerraformApplyAutoApprove)161 if err != nil {162 return err163 }164 Config.Components.Terraform.ApplyAutoApprove = applyAutoApproveBool165 }166 componentsTerraformDeployRunInit := os.Getenv("ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT")167 if len(componentsTerraformDeployRunInit) > 0 {168 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT=%s", componentsTerraformDeployRunInit))169 deployRunInitBool, err := strconv.ParseBool(componentsTerraformDeployRunInit)170 if err != nil {171 return err172 }173 Config.Components.Terraform.DeployRunInit = deployRunInitBool174 }175 componentsInitRunReconfigure := os.Getenv("ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE")176 if len(componentsInitRunReconfigure) > 0 {177 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE=%s", componentsInitRunReconfigure))178 initRunReconfigureBool, err := strconv.ParseBool(componentsInitRunReconfigure)179 if err != nil {180 return err181 }182 Config.Components.Terraform.InitRunReconfigure = initRunReconfigureBool183 }184 componentsTerraformAutoGenerateBackendFile := os.Getenv("ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE")185 if len(componentsTerraformAutoGenerateBackendFile) > 0 {186 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE=%s", componentsTerraformAutoGenerateBackendFile))187 componentsTerraformAutoGenerateBackendFileBool, err := strconv.ParseBool(componentsTerraformAutoGenerateBackendFile)188 if err != nil {189 return err190 }191 Config.Components.Terraform.AutoGenerateBackendFile = componentsTerraformAutoGenerateBackendFileBool192 }193 componentsHelmfileBasePath := os.Getenv("ATMOS_COMPONENTS_HELMFILE_BASE_PATH")194 if len(componentsHelmfileBasePath) > 0 {195 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_HELMFILE_BASE_PATH=%s", componentsHelmfileBasePath))196 Config.Components.Helmfile.BasePath = componentsHelmfileBasePath197 }198 componentsHelmfileKubeconfigPath := os.Getenv("ATMOS_COMPONENTS_HELMFILE_KUBECONFIG_PATH")199 if len(componentsHelmfileKubeconfigPath) > 0 {200 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_HELMFILE_KUBECONFIG_PATH=%s", componentsHelmfileKubeconfigPath))201 Config.Components.Helmfile.KubeconfigPath = componentsHelmfileKubeconfigPath202 }203 componentsHelmfileHelmAwsProfilePattern := os.Getenv("ATMOS_COMPONENTS_HELMFILE_HELM_AWS_PROFILE_PATTERN")204 if len(componentsHelmfileHelmAwsProfilePattern) > 0 {205 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_HELMFILE_HELM_AWS_PROFILE_PATTERN=%s", componentsHelmfileHelmAwsProfilePattern))206 Config.Components.Helmfile.HelmAwsProfilePattern = componentsHelmfileHelmAwsProfilePattern207 }208 componentsHelmfileClusterNamePattern := os.Getenv("ATMOS_COMPONENTS_HELMFILE_CLUSTER_NAME_PATTERN")209 if len(componentsHelmfileClusterNamePattern) > 0 {210 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_COMPONENTS_HELMFILE_CLUSTER_NAME_PATTERN=%s", componentsHelmfileClusterNamePattern))211 Config.Components.Helmfile.ClusterNamePattern = componentsHelmfileClusterNamePattern212 }213 workflowsBasePath := os.Getenv("ATMOS_WORKFLOWS_BASE_PATH")214 if len(workflowsBasePath) > 0 {215 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_WORKFLOWS_BASE_PATH=%s", workflowsBasePath))216 Config.Workflows.BasePath = workflowsBasePath217 }218 jsonschemaBasePath := os.Getenv("ATMOS_SCHEMAS_JSONSCHEMA_BASE_PATH")219 if len(jsonschemaBasePath) > 0 {220 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_SCHEMAS_JSONSCHEMA_BASE_PATH=%s", jsonschemaBasePath))221 Config.Schemas.JsonSchema.BasePath = jsonschemaBasePath222 }223 opaBasePath := os.Getenv("ATMOS_SCHEMAS_OPA_BASE_PATH")224 if len(opaBasePath) > 0 {225 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_SCHEMAS_OPA_BASE_PATH=%s", opaBasePath))226 Config.Schemas.Opa.BasePath = opaBasePath227 }228 cueBasePath := os.Getenv("ATMOS_SCHEMAS_CUE_BASE_PATH")229 if len(cueBasePath) > 0 {230 u.PrintInfoVerbose(fmt.Sprintf("Found ENV var ATMOS_SCHEMAS_CUE_BASE_PATH=%s", cueBasePath))231 Config.Schemas.Cue.BasePath = cueBasePath232 }233 return nil234}235func checkConfig() error {236 if len(Config.Stacks.BasePath) < 1 {237 return errors.New("stack base path must be provided in 'stacks.base_path' config or ATMOS_STACKS_BASE_PATH' ENV variable")238 }239 if len(Config.Stacks.IncludedPaths) < 1 {240 return errors.New("at least one path must be provided in 'stacks.included_paths' config or ATMOS_STACKS_INCLUDED_PATHS' ENV variable")241 }242 return nil243}244func processCommandLineArgs(configAndStacksInfo ConfigAndStacksInfo) error {245 if len(configAndStacksInfo.BasePath) > 0 {246 Config.BasePath = configAndStacksInfo.BasePath247 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as base path for stacks and components", configAndStacksInfo.BasePath))248 }249 if len(configAndStacksInfo.TerraformDir) > 0 {250 Config.Components.Terraform.BasePath = configAndStacksInfo.TerraformDir251 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as terraform directory", configAndStacksInfo.TerraformDir))252 }253 if len(configAndStacksInfo.HelmfileDir) > 0 {254 Config.Components.Helmfile.BasePath = configAndStacksInfo.HelmfileDir255 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as helmfile directory", configAndStacksInfo.HelmfileDir))256 }257 if len(configAndStacksInfo.ConfigDir) > 0 {258 Config.Stacks.BasePath = configAndStacksInfo.ConfigDir259 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as stacks directory", configAndStacksInfo.ConfigDir))260 }261 if len(configAndStacksInfo.StacksDir) > 0 {262 Config.Stacks.BasePath = configAndStacksInfo.StacksDir263 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as stacks directory", configAndStacksInfo.StacksDir))264 }265 if len(configAndStacksInfo.DeployRunInit) > 0 {266 deployRunInitBool, err := strconv.ParseBool(configAndStacksInfo.DeployRunInit)267 if err != nil {268 return err269 }270 Config.Components.Terraform.DeployRunInit = deployRunInitBool271 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s=%s'", g.DeployRunInitFlag, configAndStacksInfo.DeployRunInit))272 }273 if len(configAndStacksInfo.AutoGenerateBackendFile) > 0 {274 autoGenerateBackendFileBool, err := strconv.ParseBool(configAndStacksInfo.AutoGenerateBackendFile)275 if err != nil {276 return err277 }278 Config.Components.Terraform.AutoGenerateBackendFile = autoGenerateBackendFileBool279 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s=%s'", g.AutoGenerateBackendFileFlag, configAndStacksInfo.AutoGenerateBackendFile))280 }281 if len(configAndStacksInfo.WorkflowsDir) > 0 {282 Config.Workflows.BasePath = configAndStacksInfo.WorkflowsDir283 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as workflows directory", configAndStacksInfo.WorkflowsDir))284 }285 if len(configAndStacksInfo.InitRunReconfigure) > 0 {286 initRunReconfigureBool, err := strconv.ParseBool(configAndStacksInfo.InitRunReconfigure)287 if err != nil {288 return err289 }290 Config.Components.Terraform.InitRunReconfigure = initRunReconfigureBool291 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s=%s'", g.InitRunReconfigure, configAndStacksInfo.InitRunReconfigure))292 }293 if len(configAndStacksInfo.JsonSchemaDir) > 0 {294 Config.Schemas.JsonSchema.BasePath = configAndStacksInfo.JsonSchemaDir295 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as JsonSchema schemas directory", configAndStacksInfo.JsonSchemaDir))296 }297 if len(configAndStacksInfo.OpaDir) > 0 {298 Config.Schemas.Opa.BasePath = configAndStacksInfo.OpaDir299 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as OPA schemas directory", configAndStacksInfo.OpaDir))300 }301 if len(configAndStacksInfo.CueDir) > 0 {302 Config.Schemas.Cue.BasePath = configAndStacksInfo.CueDir303 u.PrintInfoVerbose(fmt.Sprintf("Using command line argument '%s' as CUE schemas directory", configAndStacksInfo.CueDir))304 }305 return nil306}307func processLogsConfig() error {308 logVerbose := os.Getenv("ATMOS_LOGS_VERBOSE")309 if len(logVerbose) > 0 {310 u.PrintInfo(fmt.Sprintf("Found ENV var ATMOS_LOGS_VERBOSE=%s", logVerbose))311 logVerboseBool, err := strconv.ParseBool(logVerbose)312 if err != nil {313 return err314 }315 Config.Logs.Verbose = logVerboseBool316 g.LogVerbose = logVerboseBool317 }318 return nil319}320// GetContextFromVars creates a context object from the provided variables321func GetContextFromVars(vars map[any]any) Context {322 var context Context323 if namespace, ok := vars["namespace"].(string); ok {324 context.Namespace = namespace325 }326 if tenant, ok := vars["tenant"].(string); ok {327 context.Tenant = tenant328 }329 if environment, ok := vars["environment"].(string); ok {330 context.Environment = environment331 }332 if stage, ok := vars["stage"].(string); ok {333 context.Stage = stage334 }335 if region, ok := vars["region"].(string); ok {336 context.Region = region337 }338 if attributes, ok := vars["attributes"].([]string); ok {339 context.Attributes = attributes340 }341 return context342}343// GetContextPrefix calculates context prefix from the context344func GetContextPrefix(stack string, context Context, stackNamePattern string, stackFile string) (string, error) {345 if len(stackNamePattern) == 0 {346 return "",347 errors.New("stack name pattern must be provided in 'stacks.name_pattern' config or 'ATMOS_STACKS_NAME_PATTERN' ENV variable")348 }349 contextPrefix := ""350 stackNamePatternParts := strings.Split(stackNamePattern, "-")351 for _, part := range stackNamePatternParts {352 if part == "{namespace}" {353 if len(context.Namespace) == 0 {354 return "",355 fmt.Errorf("the stack name pattern '%s' specifies 'namespace`, but the stack '%s' does not have a namespace defined in the stack file '%s'",356 stackNamePattern,357 stack,358 stackFile,359 )360 }361 if len(contextPrefix) == 0 {362 contextPrefix = context.Namespace363 } else {364 contextPrefix = contextPrefix + "-" + context.Namespace365 }366 } else if part == "{tenant}" {367 if len(context.Tenant) == 0 {368 return "",369 fmt.Errorf("the stack name pattern '%s' specifies 'tenant`, but the stack '%s' does not have a tenant defined in the stack file '%s'",370 stackNamePattern,371 stack,372 stackFile,373 )374 }375 if len(contextPrefix) == 0 {376 contextPrefix = context.Tenant377 } else {378 contextPrefix = contextPrefix + "-" + context.Tenant379 }380 } else if part == "{environment}" {381 if len(context.Environment) == 0 {382 return "",383 fmt.Errorf("the stack name pattern '%s' specifies 'environment`, but the stack '%s' does not have an environment defined in the stack file '%s'",384 stackNamePattern,385 stack,386 stackFile,387 )388 }389 if len(contextPrefix) == 0 {390 contextPrefix = context.Environment391 } else {392 contextPrefix = contextPrefix + "-" + context.Environment393 }394 } else if part == "{stage}" {395 if len(context.Stage) == 0 {396 return "",397 fmt.Errorf("the stack name pattern '%s' specifies 'stage`, but the stack '%s' does not have a stage defined in the stack file '%s'",398 stackNamePattern,399 stack,400 stackFile,401 )402 }403 if len(contextPrefix) == 0 {404 contextPrefix = context.Stage405 } else {406 contextPrefix = contextPrefix + "-" + context.Stage407 }408 }409 }410 return contextPrefix, nil411}412// ReplaceContextTokens replaces context tokens in the provided pattern and returns a string with all the tokens replaced413func ReplaceContextTokens(context Context, pattern string) string {414 r := strings.NewReplacer(415 "{base-component}", context.BaseComponent,416 "{component}", context.Component,417 "{component-path}", context.ComponentPath,418 "{namespace}", context.Namespace,419 "{environment}", context.Environment,420 "{region}", context.Region,421 "{tenant}", context.Tenant,422 "{stage}", context.Stage,423 "{workspace}", context.Workspace,424 "{attributes}", strings.Join(context.Attributes, "-"),425 )426 return r.Replace(pattern)427}428// GetStackNameFromContextAndStackNamePattern calculates stack name from the provided context using the provided stack name pattern429func GetStackNameFromContextAndStackNamePattern(430 namespace string,431 tenant string,432 environment string,433 stage string,434 stackNamePattern string,435) (string, error) {436 if len(stackNamePattern) == 0 {437 return "",438 fmt.Errorf("stack name pattern must be provided")439 }440 var stack string441 stackNamePatternParts := strings.Split(stackNamePattern, "-")442 for _, part := range stackNamePatternParts {443 if part == "{namespace}" {444 if len(namespace) == 0 {445 return "", fmt.Errorf("stack name pattern '%s' includes '{namespace}', but namespace is not provided", stackNamePattern)446 }447 if len(stack) == 0 {448 stack = namespace449 } else {450 stack = fmt.Sprintf("%s-%s", stack, namespace)451 }452 } else if part == "{tenant}" {453 if len(tenant) == 0 {454 return "", fmt.Errorf("stack name pattern '%s' includes '{tenant}', but tenant is not provided", stackNamePattern)455 }456 if len(stack) == 0 {457 stack = tenant458 } else {459 stack = fmt.Sprintf("%s-%s", stack, tenant)460 }461 } else if part == "{environment}" {462 if len(environment) == 0 {463 return "", fmt.Errorf("stack name pattern '%s' includes '{environment}', but environment is not provided", stackNamePattern)464 }465 if len(stack) == 0 {466 stack = environment467 } else {468 stack = fmt.Sprintf("%s-%s", stack, environment)469 }470 } else if part == "{stage}" {471 if len(stage) == 0 {472 return "", fmt.Errorf("stack name pattern '%s' includes '{stage}', but stage is not provided", stackNamePattern)473 }474 if len(stack) == 0 {475 stack = stage476 } else {477 stack = fmt.Sprintf("%s-%s", stack, stage)478 }479 }480 }481 return stack, nil482}...

Full Screen

Full Screen

options.go

Source:options.go Github

copy

Full Screen

1/*2 Copyright 2020 The Compose Specification Authors.3 Licensed under the Apache License, Version 2.0 (the "License");4 you may not use this file except in compliance with the License.5 You may obtain a copy of the License at6 http://www.apache.org/licenses/LICENSE-2.07 Unless required by applicable law or agreed to in writing, software8 distributed under the License is distributed on an "AS IS" BASIS,9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.10 See the License for the specific language governing permissions and11 limitations under the License.12*/13package cli14import (15 "fmt"16 "io"17 "os"18 "path/filepath"19 "strings"20 "github.com/compose-spec/compose-go/consts"21 "github.com/compose-spec/compose-go/dotenv"22 "github.com/compose-spec/compose-go/errdefs"23 "github.com/compose-spec/compose-go/loader"24 "github.com/compose-spec/compose-go/types"25 "github.com/compose-spec/compose-go/utils"26 "github.com/pkg/errors"27 "github.com/sirupsen/logrus"28)29// ProjectOptions groups the command line options recommended for a Compose implementation30type ProjectOptions struct {31 Name string32 WorkingDir string33 ConfigPaths []string34 Environment map[string]string35 EnvFile string36 loadOptions []func(*loader.Options)37}38type ProjectOptionsFn func(*ProjectOptions) error39// NewProjectOptions creates ProjectOptions40func NewProjectOptions(configs []string, opts ...ProjectOptionsFn) (*ProjectOptions, error) {41 options := &ProjectOptions{42 ConfigPaths: configs,43 Environment: map[string]string{},44 }45 for _, o := range opts {46 err := o(options)47 if err != nil {48 return nil, err49 }50 }51 return options, nil52}53// WithName defines ProjectOptions' name54func WithName(name string) ProjectOptionsFn {55 return func(o *ProjectOptions) error {56 if name != loader.NormalizeProjectName(name) {57 return fmt.Errorf("%q is not a valid project name", name)58 }59 o.Name = name60 return nil61 }62}63// WithWorkingDirectory defines ProjectOptions' working directory64func WithWorkingDirectory(wd string) ProjectOptionsFn {65 return func(o *ProjectOptions) error {66 if wd == "" {67 return nil68 }69 abs, err := filepath.Abs(wd)70 if err != nil {71 return err72 }73 o.WorkingDir = abs74 return nil75 }76}77// WithConfigFileEnv allow to set compose config file paths by COMPOSE_FILE environment variable78func WithConfigFileEnv(o *ProjectOptions) error {79 if len(o.ConfigPaths) > 0 {80 return nil81 }82 sep := o.Environment[consts.ComposePathSeparator]83 if sep == "" {84 sep = string(os.PathListSeparator)85 }86 f, ok := o.Environment[consts.ComposeFilePath]87 if ok {88 paths, err := absolutePaths(strings.Split(f, sep))89 o.ConfigPaths = paths90 return err91 }92 return nil93}94// WithDefaultConfigPath searches for default config files from working directory95func WithDefaultConfigPath(o *ProjectOptions) error {96 if len(o.ConfigPaths) > 0 {97 return nil98 }99 pwd, err := o.GetWorkingDir()100 if err != nil {101 return err102 }103 for {104 candidates := findFiles(DefaultFileNames, pwd)105 if len(candidates) > 0 {106 winner := candidates[0]107 if len(candidates) > 1 {108 logrus.Warnf("Found multiple config files with supported names: %s", strings.Join(candidates, ", "))109 logrus.Warnf("Using %s", winner)110 }111 o.ConfigPaths = append(o.ConfigPaths, winner)112 overrides := findFiles(DefaultOverrideFileNames, pwd)113 if len(overrides) > 0 {114 if len(overrides) > 1 {115 logrus.Warnf("Found multiple override files with supported names: %s", strings.Join(overrides, ", "))116 logrus.Warnf("Using %s", overrides[0])117 }118 o.ConfigPaths = append(o.ConfigPaths, overrides[0])119 }120 return nil121 }122 parent := filepath.Dir(pwd)123 if parent == pwd {124 // no config file found, but that's not a blocker if caller only needs project name125 return nil126 }127 pwd = parent128 }129}130// WithEnv defines a key=value set of variables used for compose file interpolation131func WithEnv(env []string) ProjectOptionsFn {132 return func(o *ProjectOptions) error {133 for k, v := range utils.GetAsEqualsMap(env) {134 o.Environment[k] = v135 }136 return nil137 }138}139// WithDiscardEnvFiles sets discards the `env_file` section after resolving to140// the `environment` section141func WithDiscardEnvFile(o *ProjectOptions) error {142 o.loadOptions = append(o.loadOptions, loader.WithDiscardEnvFiles)143 return nil144}145// WithLoadOptions provides a hook to control how compose files are loaded146func WithLoadOptions(loadOptions ...func(*loader.Options)) ProjectOptionsFn {147 return func(o *ProjectOptions) error {148 o.loadOptions = append(o.loadOptions, loadOptions...)149 return nil150 }151}152// WithOsEnv imports environment variables from OS153func WithOsEnv(o *ProjectOptions) error {154 for k, v := range utils.GetAsEqualsMap(os.Environ()) {155 if _, set := o.Environment[k]; set {156 continue157 }158 o.Environment[k] = v159 }160 return nil161}162// WithEnvFile set an alternate env file163func WithEnvFile(file string) ProjectOptionsFn {164 return func(options *ProjectOptions) error {165 options.EnvFile = file166 return nil167 }168}169// WithDotEnv imports environment variables from .env file170func WithDotEnv(o *ProjectOptions) error {171 wd, err := o.GetWorkingDir()172 if err != nil {173 return err174 }175 envMap, err := GetEnvFromFile(o.Environment, wd, o.EnvFile)176 if err != nil {177 return err178 }179 for k, v := range envMap {180 o.Environment[k] = v181 if osVal, ok := os.LookupEnv(k); ok {182 o.Environment[k] = osVal183 }184 }185 return nil186}187func GetEnvFromFile(currentEnv map[string]string, workingDir string, filename string) (map[string]string, error) {188 envMap := make(map[string]string)189 dotEnvFile := filename190 if dotEnvFile == "" {191 dotEnvFile = filepath.Join(workingDir, ".env")192 }193 abs, err := filepath.Abs(dotEnvFile)194 if err != nil {195 return envMap, err196 }197 dotEnvFile = abs198 s, err := os.Stat(dotEnvFile)199 if os.IsNotExist(err) {200 if filename != "" {201 return nil, errors.Errorf("Couldn't find env file: %s", filename)202 }203 return envMap, nil204 }205 if err != nil {206 return envMap, err207 }208 if s.IsDir() {209 if filename == "" {210 return envMap, nil211 }212 return envMap, errors.Errorf("%s is a directory", dotEnvFile)213 }214 file, err := os.Open(dotEnvFile)215 if err != nil {216 return envMap, err217 }218 defer file.Close()219 env, err := dotenv.ParseWithLookup(file, func(k string) (string, bool) {220 v, ok := currentEnv[k]221 if !ok {222 return "", false223 }224 return v, true225 })226 if err != nil {227 return envMap, err228 }229 for k, v := range env {230 envMap[k] = v231 }232 return envMap, nil233}234// WithInterpolation set ProjectOptions to enable/skip interpolation235func WithInterpolation(interpolation bool) ProjectOptionsFn {236 return func(o *ProjectOptions) error {237 o.loadOptions = append(o.loadOptions, func(options *loader.Options) {238 options.SkipInterpolation = !interpolation239 })240 return nil241 }242}243// WithNormalization set ProjectOptions to enable/skip normalization244func WithNormalization(normalization bool) ProjectOptionsFn {245 return func(o *ProjectOptions) error {246 o.loadOptions = append(o.loadOptions, func(options *loader.Options) {247 options.SkipNormalization = !normalization248 })249 return nil250 }251}252// WithResolvedPaths set ProjectOptions to enable paths resolution253func WithResolvedPaths(resolve bool) ProjectOptionsFn {254 return func(o *ProjectOptions) error {255 o.loadOptions = append(o.loadOptions, func(options *loader.Options) {256 options.ResolvePaths = resolve257 })258 return nil259 }260}261// DefaultFileNames defines the Compose file names for auto-discovery (in order of preference)262var DefaultFileNames = []string{"compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml"}263// DefaultOverrideFileNames defines the Compose override file names for auto-discovery (in order of preference)264var DefaultOverrideFileNames = []string{"compose.override.yml", "compose.override.yaml", "docker-compose.override.yml", "docker-compose.override.yaml"}265func (o ProjectOptions) GetWorkingDir() (string, error) {266 if o.WorkingDir != "" {267 return o.WorkingDir, nil268 }269 for _, path := range o.ConfigPaths {270 if path != "-" {271 absPath, err := filepath.Abs(path)272 if err != nil {273 return "", err274 }275 return filepath.Dir(absPath), nil276 }277 }278 return os.Getwd()279}280// ProjectFromOptions load a compose project based on command line options281func ProjectFromOptions(options *ProjectOptions) (*types.Project, error) {282 configPaths, err := getConfigPathsFromOptions(options)283 if err != nil {284 return nil, err285 }286 var configs []types.ConfigFile287 for _, f := range configPaths {288 var b []byte289 if f == "-" {290 b, err = io.ReadAll(os.Stdin)291 if err != nil {292 return nil, err293 }294 } else {295 f, err := filepath.Abs(f)296 if err != nil {297 return nil, err298 }299 b, err = os.ReadFile(f)300 if err != nil {301 return nil, err302 }303 }304 configs = append(configs, types.ConfigFile{305 Filename: f,306 Content: b,307 })308 }309 workingDir, err := options.GetWorkingDir()310 if err != nil {311 return nil, err312 }313 absWorkingDir, err := filepath.Abs(workingDir)314 if err != nil {315 return nil, err316 }317 options.loadOptions = append(options.loadOptions,318 withNamePrecedenceLoad(absWorkingDir, options),319 withConvertWindowsPaths(options))320 project, err := loader.Load(types.ConfigDetails{321 ConfigFiles: configs,322 WorkingDir: workingDir,323 Environment: options.Environment,324 }, options.loadOptions...)325 if err != nil {326 return nil, err327 }328 project.ComposeFiles = configPaths329 return project, nil330}331func withNamePrecedenceLoad(absWorkingDir string, options *ProjectOptions) func(*loader.Options) {332 return func(opts *loader.Options) {333 if options.Name != "" {334 opts.SetProjectName(options.Name, true)335 } else if nameFromEnv, ok := options.Environment[consts.ComposeProjectName]; ok && nameFromEnv != "" {336 opts.SetProjectName(nameFromEnv, true)337 } else {338 opts.SetProjectName(filepath.Base(absWorkingDir), false)339 }340 }341}342func withConvertWindowsPaths(options *ProjectOptions) func(*loader.Options) {343 return func(o *loader.Options) {344 o.ConvertWindowsPaths = utils.StringToBool(options.Environment["COMPOSE_CONVERT_WINDOWS_PATHS"])345 o.ResolvePaths = true346 }347}348// getConfigPathsFromOptions retrieves the config files for project based on project options349func getConfigPathsFromOptions(options *ProjectOptions) ([]string, error) {350 if len(options.ConfigPaths) != 0 {351 return absolutePaths(options.ConfigPaths)352 }353 return nil, errors.Wrap(errdefs.ErrNotFound, "no configuration file provided")354}355func findFiles(names []string, pwd string) []string {356 candidates := []string{}357 for _, n := range names {358 f := filepath.Join(pwd, n)359 if _, err := os.Stat(f); err == nil {360 candidates = append(candidates, f)361 }362 }363 return candidates364}365func absolutePaths(p []string) ([]string, error) {366 var paths []string367 for _, f := range p {368 if f == "-" {369 paths = append(paths, f)370 continue371 }372 abs, err := filepath.Abs(f)373 if err != nil {374 return nil, err375 }376 f = abs377 if _, err := os.Stat(f); err != nil {378 return nil, err379 }380 paths = append(paths, f)381 }382 return paths, nil383}...

Full Screen

Full Screen

fileutils.go

Source:fileutils.go Github

copy

Full Screen

...9 panic(err)10 }11 return ex12}13func RelativeToAbsolutePaths(relativePaths []string) []string {14 currentFolder := GetExecutingPath()15 absolutePaths := make([]string, len(relativePaths))16 for i, path := range relativePaths {17 absolutePaths[i] = filepath.Join(currentFolder, path)18 }19 return absolutePaths20}...

Full Screen

Full Screen

AbsolutePaths

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 absPath, err := utils.AbsolutePaths("D:\\golang\\src\\utils")4 if err != nil {5 fmt.Println(err)6 } else {7 fmt.Println(absPath)8 }9}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful