github.com/kcmerrill/alfred@v0.0.0-20180727171036-06445dcb5e3d/pkg/alfred/context.go (about)

     1  package alfred
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/mgutz/ansi"
    12  )
    13  
    14  // Context contains the state of a task
    15  type Context struct {
    16  	TaskName      string
    17  	Stdin         string
    18  	Started       time.Time
    19  	Log           map[string]*os.File
    20  	Args          []string
    21  	AllArgs       string
    22  	Register      map[string]string
    23  	Ok            bool
    24  	Skip          string
    25  	Text          TextConfig
    26  	Silent        bool
    27  	Status        string
    28  	Component     string
    29  	Vars          map[string]string
    30  	Lock          *sync.Mutex
    31  	Out           io.Writer
    32  	Debug         bool
    33  	FileName      string
    34  	Interactive   bool
    35  	hasBeenInited bool
    36  	lock          *sync.Mutex
    37  	rootDir       string
    38  }
    39  
    40  // TextConfig contains configuration needed to display text
    41  type TextConfig struct {
    42  	DisableFormatting bool
    43  	Success           string
    44  	SuccessIcon       string
    45  	Failure           string
    46  	FailureIcon       string
    47  	Task              string
    48  	Warning           string
    49  	Args              string
    50  	Command           string
    51  	Reset             string
    52  
    53  	// color codes
    54  	Grey   string
    55  	Orange string
    56  	Green  string
    57  }
    58  
    59  // SetVar will the vars map with a given value
    60  func (c *Context) SetVar(key, value string) {
    61  	c.Lock.Lock()
    62  	defer c.Lock.Unlock()
    63  
    64  	c.Vars[key] = value
    65  }
    66  
    67  // GetVar will return a value with a given key, else returns default
    68  func (c *Context) GetVar(key, defaults string) string {
    69  	c.Lock.Lock()
    70  	defer c.Lock.Unlock()
    71  
    72  	if v, exists := c.Vars[key]; exists {
    73  		return v
    74  	}
    75  	return defaults
    76  }
    77  
    78  // InitialContext will return an empty context
    79  func InitialContext(args []string) *Context {
    80  	return &Context{
    81  		TaskName: "n/a",
    82  		Args:     args,
    83  		AllArgs:  strings.Join(args, " "),
    84  		Register: make(map[string]string),
    85  		Log:      make(map[string]*os.File, 0),
    86  		Ok:       true, // innocent until proven guilty
    87  		Started:  time.Now(),
    88  		Status:   "",
    89  		Vars:     make(map[string]string, 0),
    90  		Lock:     &sync.Mutex{},
    91  		Out:      os.Stdout,
    92  		lock:     &sync.Mutex{},
    93  		rootDir:  curDir(),
    94  		FileName: "alfred",
    95  		Text: TextConfig{
    96  			// TODO: I don't like this, let me chew on this a bit more
    97  			Success:     ansi.ColorCode("green"),
    98  			SuccessIcon: "✔",
    99  			Failure:     ansi.ColorCode("9"),
   100  			FailureIcon: "✘",
   101  			Task:        ansi.ColorCode("33"),
   102  			Warning:     ansi.ColorCode("185"),
   103  			Command:     ansi.ColorCode("reset"),
   104  			Args:        ansi.ColorCode("162"),
   105  			Reset:       ansi.ColorCode("reset"),
   106  
   107  			// Color codes
   108  			Grey:   ansi.ColorCode("238"),
   109  			Orange: ansi.ColorCode("202"),
   110  			Green:  ansi.ColorCode("green"),
   111  		}}
   112  }
   113  
   114  func copyContex(context *Context, args []string) Context {
   115  	context.Lock.Lock()
   116  	defer context.Lock.Unlock()
   117  
   118  	// silly maps, pointers are for kids
   119  	c := *context
   120  
   121  	regs := make(map[string]string)
   122  	for k, v := range c.Register {
   123  		regs[k] = v
   124  	}
   125  	c.Register = regs
   126  
   127  	a := make([]string, 0)
   128  	for x := 0; x < len(c.Args); x++ {
   129  		a = append(a, c.Args[x])
   130  	}
   131  	c.Args = a
   132  
   133  	for idx, v := range args {
   134  		if idx < len(c.Args) {
   135  			c.Args[idx] = v
   136  		} else {
   137  			c.Args = append(c.Args, v)
   138  		}
   139  	}
   140  
   141  	logs := make(map[string]*os.File)
   142  	for k, v := range c.Log {
   143  		logs[k] = v
   144  	}
   145  	c.Log = logs
   146  
   147  	return c
   148  }
   149  
   150  func (c *Context) relativePath(dir string) string {
   151  	if strings.HasPrefix(dir, string(os.PathSeparator)) {
   152  		return dir
   153  	}
   154  
   155  	combined := filepath.Clean(c.rootDir + string(os.PathSeparator) + dir)
   156  
   157  	return combined
   158  }