github.com/dnephin/dobi@v0.15.0/tasks/env/env.go (about)

     1  package env
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/dnephin/dobi/config"
     9  	"github.com/dnephin/dobi/logging"
    10  	"github.com/dnephin/dobi/tasks/context"
    11  	"github.com/dnephin/dobi/tasks/task"
    12  	"github.com/dnephin/dobi/tasks/types"
    13  	"github.com/docker/cli/opts"
    14  )
    15  
    16  // GetTaskConfig returns a new task for the action
    17  func GetTaskConfig(name, action string, conf *config.EnvConfig) (types.TaskConfig, error) {
    18  	switch action {
    19  	case "", "set":
    20  		return types.NewTaskConfig(
    21  			task.NewDefaultName(name, "set"), conf, task.NoDependencies, newTask), nil
    22  	case "rm":
    23  		return types.NewTaskConfig(
    24  			task.NewName(name, "rm"), conf, task.NoDependencies, newRemoveTask), nil
    25  	default:
    26  		return nil, fmt.Errorf("invalid env action %q for task %q", action, name)
    27  	}
    28  }
    29  
    30  // Task sets environment variables
    31  type Task struct {
    32  	types.NoStop
    33  	name   task.Name
    34  	config *config.EnvConfig
    35  }
    36  
    37  func newTask(name task.Name, conf config.Resource) types.Task {
    38  	return &Task{name: name, config: conf.(*config.EnvConfig)}
    39  }
    40  
    41  // Name returns the name of the task
    42  func (t *Task) Name() task.Name {
    43  	return t.name
    44  }
    45  
    46  // Repr formats the task for logging
    47  func (t *Task) Repr() string {
    48  	return t.name.Format("env")
    49  }
    50  
    51  // Run sets environment variables
    52  func (t *Task) Run(_ *context.ExecuteContext, _ bool) (bool, error) {
    53  	var modified int
    54  	for _, filename := range t.config.Files {
    55  		vars, err := opts.ParseEnvFile(filename)
    56  		if err != nil {
    57  			return false, err
    58  		}
    59  		count, err := setVariables(vars)
    60  		if err != nil {
    61  			return false, err
    62  		}
    63  		modified += count
    64  	}
    65  	count, err := setVariables(t.config.Variables)
    66  	if err != nil {
    67  		return false, err
    68  	}
    69  	modified += count
    70  	logging.ForTask(t).Info("Done")
    71  	return modified > 0, nil
    72  }
    73  
    74  func setVariables(vars []string) (int, error) {
    75  	var count int
    76  	for _, variable := range vars {
    77  		key, value, err := splitVar(variable)
    78  		if err != nil {
    79  			return 0, err
    80  		}
    81  		if current, ok := os.LookupEnv(key); ok && current == value {
    82  			continue
    83  		}
    84  		if err := os.Setenv(key, value); err != nil {
    85  			return 0, err
    86  		}
    87  		count++
    88  	}
    89  	return count, nil
    90  }
    91  
    92  func splitVar(variable string) (string, string, error) {
    93  	parts := strings.SplitN(variable, "=", 2)
    94  	if len(parts) < 2 {
    95  		return variable, "", fmt.Errorf("invalid variable format %q", variable)
    96  	}
    97  	return parts[0], parts[1], nil
    98  }
    99  
   100  func newRemoveTask(name task.Name, conf config.Resource) types.Task {
   101  	return &removeTask{name: name}
   102  }
   103  
   104  type removeTask struct {
   105  	types.NoStop
   106  	name task.Name
   107  }
   108  
   109  // Name returns the name of the task
   110  func (t *removeTask) Name() task.Name {
   111  	return t.name
   112  }
   113  
   114  // Repr formats the task for logging
   115  func (t *removeTask) Repr() string {
   116  	return t.name.Format("env")
   117  }
   118  
   119  // Run does nothing
   120  func (t *removeTask) Run(ctx *context.ExecuteContext, _ bool) (bool, error) {
   121  	return false, nil
   122  }