File: info.go

package info (click to toggle)
golang-github-cue-lang-cue 0.12.0.-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 19,072 kB
  • sloc: sh: 57; makefile: 17
file content (139 lines) | stat: -rw-r--r-- 3,545 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package debug exports debug information for gopls.
package debug

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"runtime"
	"runtime/debug"
	"strings"

	"cuelang.org/go/internal/golangorgx/gopls/version"
)

type PrintMode int

const (
	PlainText = PrintMode(iota)
	Markdown
	HTML
	JSON
)

// ServerVersion is the format used by gopls to report its version to the
// client. This format is structured so that the client can parse it easily.
type ServerVersion struct {
	*debug.BuildInfo
	Version string
}

// VersionInfo returns the build info for the gopls process. If it was not
// built in module mode, we return a GOPATH-specific message with the
// hardcoded version.
func VersionInfo() *ServerVersion {
	if info, ok := debug.ReadBuildInfo(); ok {
		return &ServerVersion{
			Version:   version.Version(),
			BuildInfo: info,
		}
	}
	return &ServerVersion{
		Version: version.Version(),
		BuildInfo: &debug.BuildInfo{
			Path:      "gopls, built in GOPATH mode",
			GoVersion: runtime.Version(),
		},
	}
}

// PrintServerInfo writes HTML debug info to w for the Instance.
func (i *Instance) PrintServerInfo(ctx context.Context, w io.Writer) {
	workDir, _ := os.Getwd()
	section(w, HTML, "Server Instance", func() {
		fmt.Fprintf(w, "Start time: %v\n", i.StartTime)
		fmt.Fprintf(w, "LogFile: %s\n", i.Logfile)
		fmt.Fprintf(w, "pid: %d\n", os.Getpid())
		fmt.Fprintf(w, "Working directory: %s\n", workDir)
		fmt.Fprintf(w, "Address: %s\n", i.ServerAddress)
		fmt.Fprintf(w, "Debug address: %s\n", i.DebugAddress())
	})
	PrintVersionInfo(ctx, w, true, HTML)
	section(w, HTML, "Command Line", func() {
		fmt.Fprintf(w, "<a href=/debug/pprof/cmdline>cmdline</a>")
	})
}

// PrintVersionInfo writes version information to w, using the output format
// specified by mode. verbose controls whether additional information is
// written, including section headers.
func PrintVersionInfo(_ context.Context, w io.Writer, verbose bool, mode PrintMode) error {
	info := VersionInfo()
	if mode == JSON {
		return printVersionInfoJSON(w, info)
	}

	if !verbose {
		printBuildInfo(w, info, false, mode)
		return nil
	}
	section(w, mode, "Build info", func() {
		printBuildInfo(w, info, true, mode)
	})
	return nil
}

func printVersionInfoJSON(w io.Writer, info *ServerVersion) error {
	js, err := json.MarshalIndent(info, "", "\t")
	if err != nil {
		return err
	}
	_, err = fmt.Fprint(w, string(js))
	return err
}

func section(w io.Writer, mode PrintMode, title string, body func()) {
	switch mode {
	case PlainText:
		fmt.Fprintln(w, title)
		fmt.Fprintln(w, strings.Repeat("-", len(title)))
		body()
	case Markdown:
		fmt.Fprintf(w, "#### %s\n\n```\n", title)
		body()
		fmt.Fprintf(w, "```\n")
	case HTML:
		fmt.Fprintf(w, "<h3>%s</h3>\n<pre>\n", title)
		body()
		fmt.Fprint(w, "</pre>\n")
	}
}

func printBuildInfo(w io.Writer, info *ServerVersion, verbose bool, mode PrintMode) {
	fmt.Fprintf(w, "%v %v\n", info.Path, version.Version())
	if !verbose {
		return
	}
	printModuleInfo(w, info.Main, mode)
	for _, dep := range info.Deps {
		printModuleInfo(w, *dep, mode)
	}
	fmt.Fprintf(w, "go: %v\n", info.GoVersion)
}

func printModuleInfo(w io.Writer, m debug.Module, _ PrintMode) {
	fmt.Fprintf(w, "    %s@%s", m.Path, m.Version)
	if m.Sum != "" {
		fmt.Fprintf(w, " %s", m.Sum)
	}
	if m.Replace != nil {
		fmt.Fprintf(w, " => %v", m.Replace.Path)
	}
	fmt.Fprintf(w, "\n")
}