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

     1  package alfred
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  
     7  	event "github.com/kcmerrill/hook"
     8  )
     9  
    10  // NewTask will execute a task
    11  func NewTask(task string, context *Context, loadedTasks map[string]Task) {
    12  	dir, t, tasks := FetchTask(task, context, loadedTasks)
    13  
    14  	// register plugins ...
    15  	plugin(t, context, tasks)
    16  	event.Trigger("dir", &dir)
    17  	event.Trigger("t", &t)
    18  	event.Trigger("tasks", &tasks)
    19  
    20  	// Skip the task, if we need to skip
    21  	if t.Skip {
    22  		return
    23  	}
    24  
    25  	// innocent until proven guilty
    26  	context.Ok = true
    27  
    28  	// set our taskname
    29  	_, context.TaskName = TaskParser(task, "alfred:list")
    30  
    31  	// interactive mode?
    32  	context.Interactive = t.Interactive
    33  
    34  	if !context.hasBeenInited {
    35  		context.hasBeenInited = true
    36  		NewTask(MagicTaskURL(task)+"__init", context, tasks)
    37  	}
    38  
    39  	components := []Component{
    40  		Component{"log", log},
    41  		Component{"summary", summary},
    42  		Component{"prompt", prompt},
    43  		Component{"register", register},
    44  		Component{"defaults", defaults},
    45  		Component{"stdin", stdin},
    46  		Component{"config", configC},
    47  		Component{"env", env},
    48  		Component{"check", check},
    49  		Component{"watch", watch},
    50  		Component{"serve", serve},
    51  		Component{"setup", setup},
    52  		Component{"include", include},
    53  		Component{"multitask", multitask},
    54  		Component{"tasks", tasksC},
    55  		Component{"for", forC},
    56  		Component{"command", commandC},
    57  		Component{"commands", commands},
    58  		Component{"httptasks", httptasks},
    59  		Component{"result", result},
    60  		Component{"ok", ok},
    61  		Component{"fail", fail},
    62  		Component{"wait", wait},
    63  		Component{"every", every},
    64  	}
    65  
    66  	// cycle through our components ...
    67  	event.Trigger("task.started", t, context, tasks)
    68  	for _, component := range components {
    69  		context.Component = component.Name
    70  		event.Trigger("before."+component.Name, context)
    71  		component.F(t, context, tasks)
    72  		event.Trigger("after."+component.Name, context)
    73  
    74  		if context.Skip != "" {
    75  			outOK(context.Skip, "skipped", context)
    76  			event.Trigger("task.skipped", context)
    77  			return
    78  		}
    79  	}
    80  	event.Trigger("task.completed", context)
    81  }
    82  
    83  // Task holds all of our task components
    84  type Task struct {
    85  	Aliases  string
    86  	Summary  string
    87  	Usage    string
    88  	Args     []string
    89  	Setup    string
    90  	Defaults []string
    91  	Dir      string
    92  	For      struct {
    93  		Tasks     string
    94  		MultiTask string
    95  		Args      string
    96  	}
    97  	SlackSlashCommands struct {
    98  		token string
    99  		port  string
   100  	} `yaml:"slack.slash.commands"`
   101  	HTTPTasks struct {
   102  		Port     string
   103  		Password string
   104  	} `yaml:"http.tasks"`
   105  	Config      string
   106  	Log         string
   107  	Every       string
   108  	Command     string
   109  	Retry       int
   110  	Register    map[string]string
   111  	Env         map[string]string
   112  	Commands    string
   113  	Serve       string
   114  	Script      string
   115  	Stdin       string
   116  	Prompt      map[string]string
   117  	Tasks       string
   118  	MultiTask   string
   119  	Ok          string
   120  	Fail        string
   121  	Wait        string
   122  	Watch       string
   123  	Private     bool
   124  	ExitCode    int `yaml:"exit"`
   125  	Skip        bool
   126  	Interactive bool
   127  	Plugin      map[string]string
   128  	Check       string
   129  	Include     string
   130  }
   131  
   132  // Exit determins whether a task should exit or not
   133  func (t *Task) Exit(context *Context, tasks map[string]Task) {
   134  	context.Ok = false
   135  	if t.ExitCode != 0 {
   136  		outFail("["+strings.Join(context.Args, ", ")+"]", "{{ .Text.Failure }}{{ .Text.FailureIcon }} exiting ...", context)
   137  		NewTask("__exit", context, tasks)
   138  		os.Exit(t.ExitCode)
   139  	}
   140  
   141  	if t.Skip {
   142  		// skip
   143  		context.Skip = "command"
   144  	}
   145  }
   146  
   147  // IsPrivate determines if a task is private
   148  func (t *Task) IsPrivate() bool {
   149  	// I like the idea of not needing to put an astrick next to a task
   150  	// ... Descriptions automagically qualify for "important tasks"
   151  	// No descriptions means it's filler, or private
   152  	// Summaries WITH private: true are private
   153  	if t.Summary == "" || t.Private {
   154  		return true
   155  	}
   156  
   157  	return false
   158  }