github.com/developest/gtm-enhanced@v1.0.4-0.20220111132249-cc80a3372c3f/command/record.go (about)

     1  // Copyright 2016 Michael Schenk. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package command
     6  
     7  import (
     8  	"bytes"
     9  	"flag"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"path/filepath"
    14  	"strings"
    15  
    16  	"github.com/DEVELOPEST/gtm-core/event"
    17  	"github.com/DEVELOPEST/gtm-core/metric"
    18  	"github.com/DEVELOPEST/gtm-core/note"
    19  	"github.com/DEVELOPEST/gtm-core/project"
    20  	"github.com/DEVELOPEST/gtm-core/report"
    21  	"github.com/DEVELOPEST/gtm-core/scm"
    22  
    23  	"github.com/mitchellh/cli"
    24  )
    25  
    26  // RecordCmd contains method for record command
    27  type RecordCmd struct {
    28  	UI  cli.Ui
    29  	Out *bytes.Buffer
    30  }
    31  
    32  func (c RecordCmd) output(s string) {
    33  	var err error
    34  	if c.Out != nil {
    35  		_, err = fmt.Fprint(c.Out, s)
    36  	} else {
    37  		_, err = fmt.Fprint(os.Stdout, s)
    38  	}
    39  	if err != nil {
    40  		fmt.Printf("Error printing output, %s\n", err)
    41  	}
    42  }
    43  
    44  // NewRecord return new RecordCmd struct
    45  func NewRecord() (cli.Command, error) {
    46  	return RecordCmd{}, nil
    47  }
    48  
    49  // Help returns help for record command
    50  func (c RecordCmd) Help() string {
    51  	helpText := `
    52  Usage: gtm record [options] [/path/file or app event]
    53  
    54    Record file or app events.
    55  
    56  Options:
    57  
    58    -terminal=false            Record a terminal event.
    59  
    60    -status=false              Return total time recorded for event.
    61  
    62    -long-duration=false       Return total time recorded in long duration format.
    63  
    64    -app=false [event_name]    Record an app event.
    65  `
    66  	return strings.TrimSpace(helpText)
    67  }
    68  
    69  // Run executes record command with args
    70  func (c RecordCmd) Run(args []string) int {
    71  	var status, terminal, longDuration, app bool
    72  	var cwd string
    73  	cmdFlags := flag.NewFlagSet("record", flag.ContinueOnError)
    74  	cmdFlags.BoolVar(&status, "status", false, "")
    75  	cmdFlags.BoolVar(&terminal, "terminal", false, "")
    76  	cmdFlags.BoolVar(&longDuration, "long-duration", false, "")
    77  	cmdFlags.BoolVar(&app, "app", false, "")
    78  	cmdFlags.StringVar(&cwd, "cwd", "", "")
    79  	cmdFlags.Usage = func() { c.UI.Output(c.Help()) }
    80  	if err := cmdFlags.Parse(args); err != nil {
    81  		return 1
    82  	}
    83  
    84  	if !terminal && len(cmdFlags.Args()) == 0 {
    85  		c.UI.Error("Unable to record, file not provided")
    86  		return 1
    87  	}
    88  
    89  	var fileToRecord string
    90  	if terminal {
    91  		fileToRecord = c.appToFile("terminal", cwd)
    92  	} else if app {
    93  		fileToRecord = c.appToFile(strings.Join(cmdFlags.Args(), "-"), cwd)
    94  	} else {
    95  		fileToRecord = cmdFlags.Args()[0]
    96  	}
    97  
    98  	if !(0 <= len(fileToRecord)) {
    99  		return 0
   100  	}
   101  
   102  	if err := event.Record(fileToRecord); err != nil && !(err == project.ErrNotInitialized || err == project.ErrFileNotFound) {
   103  		return 1
   104  	} else if err == nil && status {
   105  		var (
   106  			err        error
   107  			commitNote note.CommitNote
   108  			out        string
   109  			wd         string
   110  		)
   111  
   112  		wd, err = os.Getwd()
   113  		if err != nil {
   114  			c.UI.Error(err.Error())
   115  			return 1
   116  		}
   117  		defer func() {
   118  			if err := os.Chdir(wd); err != nil {
   119  				fmt.Printf("Unable to change back to working directory, %s\n", err)
   120  			}
   121  		}()
   122  
   123  		err = os.Chdir(filepath.Dir(fileToRecord))
   124  		if err != nil {
   125  			c.UI.Error(err.Error())
   126  			return 1
   127  		}
   128  
   129  		if commitNote, err = metric.Process(true); err != nil {
   130  			c.UI.Error(err.Error())
   131  			return 1
   132  		}
   133  		out, err = report.Status(commitNote, report.OutputOptions{TotalOnly: true, LongDuration: longDuration})
   134  		if err != nil {
   135  			c.UI.Error(err.Error())
   136  			return 1
   137  		}
   138  		c.output(out)
   139  	}
   140  
   141  	return 0
   142  }
   143  
   144  // Given an app name creates (if it not was already created) the file ".gtm/{name}.app"
   145  // that we use to track events, and returns the full path
   146  func (c RecordCmd) appToFile(appName string, cwd string) string {
   147  	if len(cwd) <= 0 {
   148  		return eventToFile(appName, "app")
   149  	}
   150  	return eventToFile(appName, "app", cwd)
   151  }
   152  
   153  func eventToFile(event string, eventType string, cwd ...string) string {
   154  	if !(len(event) > 0) {
   155  		return ""
   156  	}
   157  	projPath, err := scm.GitRepoPath(cwd...)
   158  	if err != nil {
   159  		return ""
   160  	}
   161  	projPath, err = scm.Workdir(projPath)
   162  	if err != nil {
   163  		return ""
   164  	}
   165  	var file = filepath.Join(projPath, ".gtm", event+"."+eventType)
   166  	if _, err := os.Stat(file); os.IsNotExist(err) {
   167  		_ = ioutil.WriteFile(
   168  			file,
   169  			[]byte{},
   170  			0644)
   171  	}
   172  
   173  	return file
   174  }
   175  
   176  // Synopsis returns help
   177  func (c RecordCmd) Synopsis() string {
   178  	return "Record file, terminal and app events"
   179  }