Exemple #1
0
// ListBookmarks prints the list of bookmarks with their content
func ListBookmarks(env *environments.Environment) {
	bookmarksFileInfos, err := env.GetBookmarksFileInfos()
	if err != nil {
		utils.Logger.Panic(err)
	}

	maxLength := 1
	for _, fileInfo := range bookmarksFileInfos {
		name := fileInfo.Name()
		if len(name) > maxLength {
			maxLength = len(name)
		}
	}

	template := "%-" + strconv.Itoa(maxLength) + "s    %s\n"
	utils.Logger.WithFields(logrus.Fields{
		"template": template,
	}).Info("Calculated template to print")

	for _, fileInfo := range bookmarksFileInfos {
		fileName := fileInfo.Name()

		content, err := ioutil.ReadFile(env.GetBookmarkFileName(fileName))
		if err != nil {
			utils.Logger.WithFields(logrus.Fields{
				"filename": fileName,
				"error":    err,
			}).Warn("Cannot read a content of the file so skip")
			continue
		}

		fmt.Printf(template, fileName, string(content))
	}
}
Exemple #2
0
func processHistories(env *environments.Environment) (resultChan chan bool, consumeChan chan *HistoryEntry) {
	resultChan = make(chan bool, 1)
	consumeChan = make(chan *HistoryEntry, historyEventsCapacity)

	go func() {
		entries := make(map[string]bool)

		files, err := env.GetTracesFileInfos()
		if err != nil {
			utils.Logger.WithFields(logrus.Fields{
				"error": err,
			}).Warn("Error on traces directory listing")
			resultChan <- true
			return
		}

		for _, file := range files {
			entries[file.Name()] = true
		}
		utils.Logger.WithField("filenames", entries).Info("Parsed filenames")

		for entry := range consumeChan {
			if _, found := entries[entry.GetTraceName()]; found {
				entry.hasHistory = true
			}
		}
		resultChan <- true
	}()

	return
}
Exemple #3
0
// ListTrace implements l command (list trace).
func ListTrace(argument string, env *environments.Environment) {
	number, err := strconv.Atoi(argument)
	if err != nil || number < 0 {
		utils.Logger.Panicf("Cannot convert argument to a command number: %s", argument)
	}

	commands, err := historyentries.GetCommands(historyentries.GetCommandsPrecise, nil, env, number)
	if err != nil {
		utils.Logger.Panic(err)
	}
	command := commands.Result().(historyentries.HistoryEntry)
	hashFilename := command.GetTraceName()
	filename := env.GetTraceFileName(hashFilename)
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		utils.Logger.Panicf("Output for %s is not exist", argument)
	}

	file := utils.Open(filename)
	defer file.Close()
	ungzippedFile, err := gzip.NewReader(file)
	if err != nil {
		utils.Logger.Panic(err)
	}
	defer ungzippedFile.Close()

	scanner := bufio.NewScanner(ungzippedFile)
	for scanner.Scan() {
		os.Stdout.WriteString(scanner.Text())
		os.Stdout.WriteString("\n")
	}

	if err := scanner.Err(); err != nil {
		utils.Logger.Panic(err)
	}
}
Exemple #4
0
// ExecuteBookmark executes command by its bookmark name.
func ExecuteBookmark(name string, interactive bool, pseudoTTY bool, env *environments.Environment) {
	content, err := ioutil.ReadFile(env.GetBookmarkFileName(name))
	if err != nil {
		utils.Logger.Panic("Unknown bookmark")
	}

	execute(string(content), env.Shell, interactive, pseudoTTY)
}
Exemple #5
0
// ToString converts history entry to the string representation according to the environment setting.
func (he HistoryEntry) ToString(env *environments.Environment) string {
	timestamp := ""
	if formattedTimestamp := env.FormatTimeStamp(he.timestamp); formattedTimestamp != "" {
		timestamp = "  (" + formattedTimestamp + ")"
	}

	history := markHasNoHistory
	if he.hasHistory {
		history = markHasHistory
	}

	return fmt.Sprintf("!%-5d%s %c  %s", he.number, timestamp, history, he.command)
}
Exemple #6
0
// GetCommands returns a keeper for the commands based on given mode and regular expression.
// varargs is the auxiliary list of numbers which makes sense in the context of GetCommandsMode setting
// only.
func GetCommands(mode GetCommandsMode, filter *utils.Regexp, env *environments.Environment, varargs ...int) (commands Keeper, err error) {
	keeper := getKeeper(mode, varargs...)
	resultChan, consumeChan := processHistories(env)
	parser := getParser(env)

	histFileName, err := env.GetHistFileName()
	if err != nil {
		return
	}

	file := utils.Open(histFileName)
	defer file.Close()
	scanner := bufio.NewScanner(file)

	commands, err = parser(keeper, scanner, filter, consumeChan)
	if err == nil {
		<-resultChan
		return commands, nil
	}
	return
}
Exemple #7
0
// Tee implements t (trace, tee) command.
func Tee(input string, interactive bool, pseudoTTY bool, env *environments.Environment) {
	output, err := ioutil.TempFile(env.TmpDir, "ah")
	if err != nil {
		utils.Logger.Panic("Cannot create temporary file")
	}

	bufferedOutput := bufio.NewWriter(output)
	gzippedWrapper := utils.NewSynchronizedWriter(gzip.NewWriter(bufferedOutput))
	combinedStdout := io.MultiWriter(os.Stdout, gzippedWrapper)
	combinedStderr := io.MultiWriter(os.Stderr, gzippedWrapper)

	var commandError *exec.ExitError
	defer func() {
		// defer here because command may cause a panic but we do not want to lose any output
		gzippedWrapper.Close()
		bufferedOutput.Flush()
		output.Close()

		if hash, err := getPreciseHash(input, env); err == nil {
			err = os.Rename(output.Name(), env.GetTraceFileName(hash))
			if err != nil {
				utils.Logger.Errorf("Cannot save trace: %v. Get it here: %s", err, output.Name())
			} else {
				os.Remove(output.Name())
			}
		} else {
			utils.Logger.Errorf("Error occured on fetching command number: %v", err)
		}

		if commandError != nil {
			os.Exit(utils.GetStatusCode(commandError))
		}
	}()

	commandError = utils.Exec(input,
		string(env.Shell), interactive, pseudoTTY,
		os.Stdin, combinedStdout, combinedStderr)
}
Exemple #8
0
// Bookmark implements "b" (bookmark) command.
func Bookmark(commandNumber int, bookmarkAs string, env *environments.Environment) {
	if commandNumber < 0 {
		utils.Logger.Panic("Command number should be >= 0")
	}

	commandsKeeper, err := historyentries.GetCommands(historyentries.GetCommandsAll, nil, env)
	if err != nil {
		utils.Logger.Panic(err)
	}
	commands := commandsKeeper.Result().([]historyentries.HistoryEntry)
	if len(commands) <= commandNumber {
		utils.Logger.Panic("Command number does not exist")
	}
	command := commands[commandNumber-1]

	filename := env.GetBookmarkFileName(bookmarkAs)
	file, err := os.Create(filename)
	if err != nil {
		utils.Logger.Panicf("Cannot create bookmark %s: %v", filename, err)
	}
	defer file.Close()

	file.WriteString(command.GetCommand())
}
Exemple #9
0
// RemoveBookmarks removes the list of bookmarks from the storage.
func RemoveBookmarks(bookmarks []string, env *environments.Environment) {
	for _, bookmark := range bookmarks {
		utils.RemoveWithLogging(env.GetBookmarkFileName(bookmark))
	}
}
Exemple #10
0
func main() {
	defer func() {
		if exc := recover(); exc != nil {
			utils.Logger.Fatal(exc)
		}
	}()

	arguments, err := docopt.Parse(docoptOptions, nil, true, version, false)
	if err != nil {
		panic(err)
	}

	if arguments["--debug"].(bool) {
		utils.EnableLogging()
	} else {
		utils.DisableLogging()
	}
	utils.Logger.WithField("arguments", arguments).Info("Parsed arguments")

	defaultEnv := environments.MakeDefaultEnvironment()
	cmdLineEnv := new(environments.Environment)
	configEnv, err := defaultEnv.ReadFromConfig()
	if err != nil {
		utils.Logger.WithField("error", err).Warn("Cannot read config file")
	}

	argShell := arguments["--shell"]
	if argShell != nil {
		cmdLineEnv.Shell = argShell.(string)
	}

	argHistFile := arguments["--histfile"]
	if argHistFile != nil {
		cmdLineEnv.HistFile = argHistFile.(string)
	}

	argHistTimeFormat := arguments["--histtimeformat"]
	if argHistTimeFormat != nil {
		cmdLineEnv.HistTimeFormat = argHistTimeFormat.(string)
	}

	argAppDir := arguments["--appdir"]
	if argAppDir != nil {
		cmdLineEnv.AppDir = argAppDir.(string)
	}

	argTmpDir := arguments["--tmpdir"]
	if argTmpDir != nil {
		cmdLineEnv.TmpDir = argTmpDir.(string)
	}

	utils.Logger.WithFields(logrus.Fields{
		"default":    defaultEnv,
		"config":     configEnv,
		"cmdLineEnv": cmdLineEnv,
	}).Debug("Environments")

	env := environments.MergeEnvironments(defaultEnv, configEnv, cmdLineEnv)
	utils.Logger.WithField("result env", env).Debug("Ready to start")

	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.TracesDir, 0777),
	}).Info("Create traces dir")
	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.BookmarksDir, 0777),
	}).Info("Create bookmarks dir")
	utils.Logger.WithFields(logrus.Fields{
		"error": os.MkdirAll(env.TmpDir, 0777),
	}).Info("Create create temporary dir")

	var exec executor
	switch {
	case arguments["t"].(bool):
		utils.Logger.Info("Execute command 'tee'")
		exec = executeTee
	case arguments["s"].(bool):
		utils.Logger.Info("Execute command 'show'")
		exec = executeShow
	case arguments["l"].(bool):
		utils.Logger.Info("Execute command 'listTrace'")
		exec = executeListTrace
	case arguments["b"].(bool):
		utils.Logger.Info("Execute command 'listTrace'")
		exec = executeListTrace
	case arguments["e"].(bool):
		utils.Logger.Info("Execute command 'execute'")
		exec = executeExec
	case arguments["lb"].(bool):
		utils.Logger.Info("Execute command 'listBookmarks'")
		exec = executeListBookmarks
	case arguments["rb"].(bool):
		utils.Logger.Info("Execute command 'removeBookmarks'")
		exec = executeRemoveBookmarks
	case arguments["gt"].(bool) || arguments["gb"].(bool):
		utils.Logger.Info("Execute command 'gc'")
		exec = executeGC
	case arguments["al"].(bool):
		utils.Logger.Info("Execute command 'al'")
		exec = executeAl
	case arguments["ad"].(bool):
		utils.Logger.Info("Execute command 'ad'")
		exec = executeAd
	case arguments["ar"].(bool):
		utils.Logger.Info("Execute command 'ar'")
		exec = executeAr
	case arguments["at"].(bool):
		utils.Logger.Info("Execute command 'at'")
		exec = executeAt
	default:
		utils.Logger.Panic("Unknown command. Please be more precise")
		return
	}
	exec(arguments, env)
}
Exemple #11
0
// GetFormattedTime returns formatted time stamp of the history entry.
func (he HistoryEntry) GetFormattedTime(env *environments.Environment) string {
	return env.FormatTimeStamp(he.timestamp)
}