Example #1
0
// Main starts mc application
func Main() {
	// Enable profiling supported modes are [cpu, mem, block].
	// ``MC_PROFILER`` supported options are [cpu, mem, block].
	switch os.Getenv("MC_PROFILER") {
	case "cpu":
		defer profile.Start(profile.CPUProfile, profile.ProfilePath(mustGetProfileDir())).Stop()
	case "mem":
		defer profile.Start(profile.MemProfile, profile.ProfilePath(mustGetProfileDir())).Stop()
	case "block":
		defer profile.Start(profile.BlockProfile, profile.ProfilePath(mustGetProfileDir())).Stop()
	}

	probe.Init() // Set project's root source path.
	probe.SetAppInfo("Release-Tag", ReleaseTag)
	probe.SetAppInfo("Commit", ShortCommitID)

	app := registerApp()
	app.Before = registerBefore
	app.ExtraInfo = func() map[string]string {
		if _, e := pb.GetTerminalWidth(); e != nil {
			globalQuiet = true
		}
		if globalDebug {
			return getSystemData()
		}
		return make(map[string]string)
	}
	app.RunAndExitOnError()
}
Example #2
0
// colorizeUpdateMessage - inspired from Yeoman project npm package https://github.com/yeoman/update-notifier.
func colorizeUpdateMessage(updateString string) (string, *probe.Error) {
	// initialize coloring
	cyan := color.New(color.FgCyan, color.Bold).SprintFunc()
	yellow := color.New(color.FgYellow, color.Bold).SprintfFunc()

	// calculate length without color coding, due to ANSI color characters padded to actual
	// string the final length is wrong than the original string length.
	line1Str := fmt.Sprintf("  New update available, please execute the following command to update: ")
	line2Str := fmt.Sprintf("  %s ", updateString)
	line1Length := len(line1Str)
	line2Length := len(line2Str)

	// populate lines with color coding.
	line1InColor := line1Str
	line2InColor := fmt.Sprintf("  %s ", cyan(updateString))

	// calculate the rectangular box size.
	maxContentWidth := int(math.Max(float64(line1Length), float64(line2Length)))
	line1Rest := maxContentWidth - line1Length
	line2Rest := maxContentWidth - line2Length

	termWidth, e := pb.GetTerminalWidth()
	if e != nil {
		return "", probe.NewError(e)
	}
	var message string
	switch {
	case len(line2Str) > termWidth:
		message = "\n" + line1InColor + "\n" + line2InColor + "\n"
	default:
		// on windows terminal turn off unicode characters.
		var top, bottom, sideBar string
		if runtime.GOOS == "windows" {
			top = yellow("*" + strings.Repeat("*", maxContentWidth) + "*")
			bottom = yellow("*" + strings.Repeat("*", maxContentWidth) + "*")
			sideBar = yellow("|")
		} else {
			// color the rectangular box, use unicode characters here.
			top = yellow("┏" + strings.Repeat("━", maxContentWidth) + "┓")
			bottom = yellow("┗" + strings.Repeat("━", maxContentWidth) + "┛")
			sideBar = yellow("┃")
		}
		// fill spaces to the rest of the area.
		spacePaddingLine1 := strings.Repeat(" ", line1Rest)
		spacePaddingLine2 := strings.Repeat(" ", line2Rest)

		// construct the final message.
		message = "\n" + top + "\n" +
			sideBar + line1InColor + spacePaddingLine1 + sideBar + "\n" +
			sideBar + line2InColor + spacePaddingLine2 + sideBar + "\n" +
			bottom + "\n"
	}
	// return the final message
	return message, nil
}
Example #3
0
// colorizeUpdateMessage - inspired from Yeoman project npm package https://github.com/yeoman/update-notifier
func colorizeUpdateMessage(updateString string) string {
	// Initialize coloring.
	cyan := color.New(color.FgCyan, color.Bold).SprintFunc()
	yellow := color.New(color.FgYellow, color.Bold).SprintfFunc()

	// Calculate length without color coding, due to ANSI color
	// characters padded to actual string the final length is wrong
	// than the original string length.
	line1Str := fmt.Sprintf("  New update: %s ", updateString)
	line1Length := len(line1Str)

	// Populate lines with color coding.
	line1InColor := fmt.Sprintf("  New update: %s ", cyan(updateString))

	// Calculate the rectangular box size.
	maxContentWidth := line1Length
	line1Rest := maxContentWidth - line1Length

	// termWidth is set to a default one to use when we are
	// not able to calculate terminal width via OS syscalls
	termWidth := 25

	if width, err := pb.GetTerminalWidth(); err == nil {
		termWidth = width
	}

	var message string
	switch {
	case len(line1Str) > termWidth:
		message = "\n" + line1InColor + "\n"
	default:
		// On windows terminal turn off unicode characters.
		var top, bottom, sideBar string
		if runtime.GOOS == "windows" {
			top = yellow("*" + strings.Repeat("*", maxContentWidth) + "*")
			bottom = yellow("*" + strings.Repeat("*", maxContentWidth) + "*")
			sideBar = yellow("|")
		} else {
			// Color the rectangular box, use unicode characters here.
			top = yellow("┏" + strings.Repeat("━", maxContentWidth) + "┓")
			bottom = yellow("┗" + strings.Repeat("━", maxContentWidth) + "┛")
			sideBar = yellow("┃")
		}
		// Fill spaces to the rest of the area.
		spacePaddingLine1 := strings.Repeat(" ", line1Rest)

		// Construct the final message.
		message = "\n" + top + "\n" +
			sideBar + line1InColor + spacePaddingLine1 + sideBar + "\n" +
			bottom + "\n"
	}
	// Return the final message.
	return message
}
Example #4
0
// scanBarFactory returns a progress bar function to report URL scanning.
func scanBarFactory() scanBarFunc {
	fileCount := 0
	termWidth, e := pb.GetTerminalWidth()
	fatalIf(probe.NewError(e), "Unable to get terminal size. Please use --quiet option.")

	// Cursor animate channel.
	cursorCh := cursorAnimate()
	return func(source string) {
		scanPrefix := fmt.Sprintf("[%s] %s ", humanize.Comma(int64(fileCount)), string(<-cursorCh))
		source = fixateScanBar(source, termWidth-len([]rune(scanPrefix)))
		barText := scanPrefix + source
		console.PrintC("\r" + barText + "\r")
		fileCount++
	}
}
Example #5
0
// scanBarFactory returns a progress bar function to report URL scanning.
func scanBarFactory() scanBarFunc {
	fileCount := 0
	termWidth, err := pb.GetTerminalWidth()
	if err != nil {
		termWidth = 80
	}

	// Cursor animate channel.
	cursorCh := cursorAnimate()
	return func(source string) {
		scanPrefix := fmt.Sprintf("[%s] %s ", humanize.Comma(int64(fileCount)), string(<-cursorCh))
		source = fixateScanBar(source, termWidth-len([]rune(scanPrefix)))
		barText := scanPrefix + source
		console.PrintC("\r" + barText + "\r")
		fileCount++
	}
}
Example #6
0
// FormatJSONSyntaxError generates a pretty printed json syntax error since
// golang doesn't provide an easy way to report the location of the error
func FormatJSONSyntaxError(data io.Reader, sErr *json.SyntaxError) error {
	if sErr == nil {
		return nil
	}

	var readLine bytes.Buffer

	bio := bufio.NewReader(data)
	errLine := int64(1)
	readBytes := int64(0)

	// termWidth is set to a default one to use when we are
	// not able to calculate terminal width via OS syscalls
	termWidth := 25

	// errorShift is the length of the minimum needed place for
	// error msg accessories, like <--, etc.. We calculate it
	// dynamically to avoid an eventual bug after modifying errorFmt
	errorShift := len(fmt.Sprintf(errorFmt, 1, ""))

	if width, err := pb.GetTerminalWidth(); err == nil {
		termWidth = width
	}

	for {
		b, err := bio.ReadByte()
		if err != nil {
			if err != io.EOF {
				return err
			}
			break
		}
		readBytes++
		if readBytes > sErr.Offset {
			break
		}
		switch b {
		case '\n':
			readLine.Reset()
			errLine++
		case '\t':
			readLine.WriteByte(' ')
		case '\r':
			break
		default:
			readLine.WriteByte(b)
		}
	}

	lineLen := readLine.Len()
	idx := lineLen - termWidth + errorShift
	if idx < 0 || idx > lineLen-1 {
		idx = 0
	}

	errorStr := fmt.Sprintf("JSON syntax error at line %d, col %d : %s.\n",
		errLine, readLine.Len(), sErr)
	errorStr += fmt.Sprintf(errorFmt, errLine, readLine.String()[idx:])

	return errors.New(errorStr)
}