Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7ed283c

Browse files
committed
feat: Add stage to build logs
This adds a stage property to logs, and refactors the job logscliui.It also adds tests to the cliui for build logs!
1 parent4448ba2 commit7ed283c

29 files changed

+581
-262
lines changed

‎cli/cliui/cliui.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ func ValidateNotEmpty(s string) error {
2323
// Styles compose visual elements of the UI!
2424
varStyles=struct {
2525
Bold,
26+
Checkmark,
2627
Code,
28+
Crossmark,
2729
Field,
2830
Keyword,
2931
Paragraph,
@@ -36,7 +38,9 @@ var Styles = struct {
3638
Wrap lipgloss.Style
3739
}{
3840
Bold:lipgloss.NewStyle().Bold(true),
41+
Checkmark:defaultStyles.Checkmark,
3942
Code:defaultStyles.Code,
43+
Crossmark:defaultStyles.Error.Copy().SetString("✘"),
4044
Field:defaultStyles.Code.Copy().Foreground(lipgloss.AdaptiveColor{Light:"#000000",Dark:"#FFFFFF"}),
4145
Keyword:defaultStyles.Keyword,
4246
Paragraph:defaultStyles.Paragraph,

‎cli/cliui/job.go

Lines changed: 0 additions & 157 deletions
This file was deleted.

‎cli/cliui/provisionerjob.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package cliui
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"os/signal"
8+
"sync"
9+
"time"
10+
11+
"github.com/spf13/cobra"
12+
"golang.org/x/xerrors"
13+
14+
"github.com/coder/coder/coderd/database"
15+
"github.com/coder/coder/codersdk"
16+
)
17+
18+
typeProvisionerJobOptionsstruct {
19+
Fetchfunc() (codersdk.ProvisionerJob,error)
20+
Cancelfunc()error
21+
Logsfunc() (<-chan codersdk.ProvisionerJobLog,error)
22+
23+
FetchInterval time.Duration
24+
}
25+
26+
// ProvisionerJob renders a provisioner job with interactive cancellation.
27+
funcProvisionerJob(cmd*cobra.Command,optsProvisionerJobOptions)error {
28+
ifopts.FetchInterval==0 {
29+
opts.FetchInterval=time.Second
30+
}
31+
32+
var (
33+
currentStage="Queued"
34+
currentStageStartedAt=time.Now().UTC()
35+
didLogBetweenStage=false
36+
ctx,cancelFunc=context.WithCancel(cmd.Context())
37+
38+
errChan=make(chanerror)
39+
job codersdk.ProvisionerJob
40+
jobMutex sync.Mutex
41+
)
42+
defercancelFunc()
43+
44+
printStage:=func() {
45+
_,_=fmt.Fprintf(cmd.OutOrStdout(),Styles.Prompt.Render("⧗")+"%s\n",Styles.Field.Render(currentStage))
46+
}
47+
printStage()
48+
49+
updateStage:=func(stagestring,startedAt time.Time) {
50+
ifcurrentStage!="" {
51+
prefix:=""
52+
if!didLogBetweenStage {
53+
prefix="\033[1A\r"
54+
}
55+
mark:=Styles.Checkmark
56+
ifjob.CompletedAt!=nil&&job.Status!=codersdk.ProvisionerJobSucceeded {
57+
mark=Styles.Crossmark
58+
}
59+
_,_=fmt.Fprintf(cmd.OutOrStdout(),prefix+mark.String()+Styles.Placeholder.Render(" %s [%dms]")+"\n",currentStage,startedAt.Sub(currentStageStartedAt).Milliseconds())
60+
}
61+
ifstage=="" {
62+
return
63+
}
64+
currentStage=stage
65+
currentStageStartedAt=startedAt
66+
didLogBetweenStage=false
67+
printStage()
68+
}
69+
70+
updateJob:=func() {
71+
varerrerror
72+
jobMutex.Lock()
73+
deferjobMutex.Unlock()
74+
job,err=opts.Fetch()
75+
iferr!=nil {
76+
errChan<-xerrors.Errorf("fetch: %w",err)
77+
return
78+
}
79+
ifjob.StartedAt==nil {
80+
return
81+
}
82+
ifcurrentStage!="Queued" {
83+
// If another stage is already running, there's no need
84+
// for us to notify the user we're running!
85+
return
86+
}
87+
updateStage("Running",*job.StartedAt)
88+
}
89+
updateJob()
90+
91+
// Handles ctrl+c to cancel a job.
92+
stopChan:=make(chan os.Signal,1)
93+
defersignal.Stop(stopChan)
94+
gofunc() {
95+
signal.Notify(stopChan,os.Interrupt)
96+
select {
97+
case<-ctx.Done():
98+
return
99+
case_,ok:=<-stopChan:
100+
if!ok {
101+
return
102+
}
103+
}
104+
// Stop listening for signals so another one kills it!
105+
signal.Stop(stopChan)
106+
_,_=fmt.Fprintf(cmd.OutOrStdout(),"\033[2K\r\n"+Styles.FocusedPrompt.String()+Styles.Bold.Render("Gracefully canceling... wait for exit or data loss may occur!")+"\n\n")
107+
err:=opts.Cancel()
108+
iferr!=nil {
109+
errChan<-xerrors.Errorf("cancel: %w",err)
110+
return
111+
}
112+
updateJob()
113+
}()
114+
115+
logs,err:=opts.Logs()
116+
iferr!=nil {
117+
returnxerrors.Errorf("logs: %w",err)
118+
}
119+
120+
ticker:=time.NewTicker(opts.FetchInterval)
121+
for {
122+
select {
123+
caseerr=<-errChan:
124+
returnerr
125+
case<-ctx.Done():
126+
returnctx.Err()
127+
case<-ticker.C:
128+
updateJob()
129+
caselog,ok:=<-logs:
130+
if!ok {
131+
// The logs stream will end when the job does,
132+
// so it's safe to
133+
updateJob()
134+
jobMutex.Lock()
135+
ifjob.CompletedAt!=nil {
136+
updateStage("",*job.CompletedAt)
137+
}
138+
switchjob.Status {
139+
casecodersdk.ProvisionerJobCanceled:
140+
jobMutex.Unlock()
141+
returnCanceled
142+
casecodersdk.ProvisionerJobSucceeded:
143+
jobMutex.Unlock()
144+
returnnil
145+
casecodersdk.ProvisionerJobFailed:
146+
}
147+
jobMutex.Unlock()
148+
returnxerrors.New(job.Error)
149+
}
150+
output:=""
151+
switchlog.Level {
152+
casedatabase.LogLevelTrace,database.LogLevelDebug,database.LogLevelError:
153+
output=defaultStyles.Error.Render(log.Output)
154+
casedatabase.LogLevelWarn:
155+
output=Styles.Warn.Render(log.Output)
156+
casedatabase.LogLevelInfo:
157+
output=log.Output
158+
}
159+
iflog.Stage!=currentStage&&log.Stage!="" {
160+
jobMutex.Lock()
161+
updateStage(log.Stage,log.CreatedAt)
162+
jobMutex.Unlock()
163+
continue
164+
}
165+
_,_=fmt.Fprintf(cmd.OutOrStdout(),"%s %s\n",Styles.Placeholder.Render(" "),output)
166+
didLogBetweenStage=true
167+
}
168+
}
169+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp