mirror of
https://github.com/go-task/task.git
synced 2026-06-23 04:35:52 +00:00
feat: better functional options for reader (#2148)
This commit is contained in:
@@ -28,14 +28,14 @@ Continue?`
|
||||
)
|
||||
|
||||
type (
|
||||
// ReaderDebugFunc is a function that is called when the [Reader] wants to
|
||||
// log debug messages
|
||||
ReaderDebugFunc func(string)
|
||||
// ReaderPromptFunc is a function that is called when the [Reader] wants to
|
||||
// prompt the user in some way
|
||||
ReaderPromptFunc func(string) error
|
||||
// ReaderOption is a function that configures a [Reader].
|
||||
ReaderOption func(*Reader)
|
||||
// DebugFunc is a function that can be called to log debug messages.
|
||||
DebugFunc func(string)
|
||||
// PromptFunc is a function that can be called to prompt the user for input.
|
||||
PromptFunc func(string) error
|
||||
// A ReaderOption is any type that can apply a configuration to a [Reader].
|
||||
ReaderOption interface {
|
||||
ApplyToReader(*Reader)
|
||||
}
|
||||
// A Reader will recursively read Taskfiles from a given [Node] and build a
|
||||
// [ast.TaskfileGraph] from them.
|
||||
Reader struct {
|
||||
@@ -46,8 +46,8 @@ type (
|
||||
offline bool
|
||||
timeout time.Duration
|
||||
tempDir string
|
||||
debugFunc ReaderDebugFunc
|
||||
promptFunc ReaderPromptFunc
|
||||
debugFunc DebugFunc
|
||||
promptFunc PromptFunc
|
||||
promptMutex sync.Mutex
|
||||
}
|
||||
)
|
||||
@@ -78,72 +78,113 @@ func NewReader(
|
||||
// the [Reader].
|
||||
func (r *Reader) Options(opts ...ReaderOption) {
|
||||
for _, opt := range opts {
|
||||
opt(r)
|
||||
opt.ApplyToReader(r)
|
||||
}
|
||||
}
|
||||
|
||||
// ReaderWithInsecure allows the [Reader] to make insecure connections when
|
||||
// reading remote taskfiles. By default, insecure connections are rejected.
|
||||
func ReaderWithInsecure(insecure bool) ReaderOption {
|
||||
return func(r *Reader) {
|
||||
r.insecure = insecure
|
||||
}
|
||||
// WithInsecure allows the [Reader] to make insecure connections when reading
|
||||
// remote taskfiles. By default, insecure connections are rejected.
|
||||
func WithInsecure(insecure bool) ReaderOption {
|
||||
return &insecureOption{insecure: insecure}
|
||||
}
|
||||
|
||||
// ReaderWithDownload forces the [Reader] to download a fresh copy of the
|
||||
// taskfile from the remote source.
|
||||
func ReaderWithDownload(download bool) ReaderOption {
|
||||
return func(r *Reader) {
|
||||
r.download = download
|
||||
}
|
||||
type insecureOption struct {
|
||||
insecure bool
|
||||
}
|
||||
|
||||
// ReaderWithOffline stops the [Reader] from being able to make network
|
||||
// connections. It will still be able to read local files and cached copies of
|
||||
// remote files.
|
||||
func ReaderWithOffline(offline bool) ReaderOption {
|
||||
return func(r *Reader) {
|
||||
r.offline = offline
|
||||
}
|
||||
func (o *insecureOption) ApplyToReader(r *Reader) {
|
||||
r.insecure = o.insecure
|
||||
}
|
||||
|
||||
// ReaderWithTimeout sets the [Reader]'s timeout for fetching remote taskfiles.
|
||||
// By default, the timeout is set to 10 seconds.
|
||||
func ReaderWithTimeout(timeout time.Duration) ReaderOption {
|
||||
return func(r *Reader) {
|
||||
r.timeout = timeout
|
||||
}
|
||||
// WithDownload forces the [Reader] to download a fresh copy of the taskfile
|
||||
// from the remote source.
|
||||
func WithDownload(download bool) ReaderOption {
|
||||
return &downloadOption{download: download}
|
||||
}
|
||||
|
||||
// ReaderWithTempDir sets the temporary directory that will be used by the
|
||||
// [Reader]. By default, the reader uses [os.TempDir].
|
||||
func ReaderWithTempDir(tempDir string) ReaderOption {
|
||||
return func(r *Reader) {
|
||||
r.tempDir = tempDir
|
||||
}
|
||||
type downloadOption struct {
|
||||
download bool
|
||||
}
|
||||
|
||||
// ReaderWithDebugFunc sets the debug function to be used by the [Reader]. If
|
||||
// set, this function will be called with debug messages. This can be useful if
|
||||
// the caller wants to log debug messages from the [Reader]. By default, no
|
||||
// debug function is set and the logs are not written.
|
||||
func ReaderWithDebugFunc(debugFunc ReaderDebugFunc) ReaderOption {
|
||||
return func(r *Reader) {
|
||||
r.debugFunc = debugFunc
|
||||
}
|
||||
func (o *downloadOption) ApplyToReader(r *Reader) {
|
||||
r.download = o.download
|
||||
}
|
||||
|
||||
// ReaderWithPromptFunc sets the prompt function to be used by the [Reader]. If
|
||||
// set, this function will be called with prompt messages. The function should
|
||||
// WithOffline stops the [Reader] from being able to make network connections.
|
||||
// It will still be able to read local files and cached copies of remote files.
|
||||
func WithOffline(offline bool) ReaderOption {
|
||||
return &offlineOption{offline: offline}
|
||||
}
|
||||
|
||||
type offlineOption struct {
|
||||
offline bool
|
||||
}
|
||||
|
||||
func (o *offlineOption) ApplyToReader(r *Reader) {
|
||||
r.offline = o.offline
|
||||
}
|
||||
|
||||
// WithTimeout sets the [Reader]'s timeout for fetching remote taskfiles. By
|
||||
// default, the timeout is set to 10 seconds.
|
||||
func WithTimeout(timeout time.Duration) ReaderOption {
|
||||
return &timeoutOption{timeout: timeout}
|
||||
}
|
||||
|
||||
type timeoutOption struct {
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func (o *timeoutOption) ApplyToReader(r *Reader) {
|
||||
r.timeout = o.timeout
|
||||
}
|
||||
|
||||
// WithTempDir sets the temporary directory that will be used by the [Reader].
|
||||
// By default, the reader uses [os.TempDir].
|
||||
func WithTempDir(tempDir string) ReaderOption {
|
||||
return &tempDirOption{tempDir: tempDir}
|
||||
}
|
||||
|
||||
type tempDirOption struct {
|
||||
tempDir string
|
||||
}
|
||||
|
||||
func (o *tempDirOption) ApplyToReader(r *Reader) {
|
||||
r.tempDir = o.tempDir
|
||||
}
|
||||
|
||||
// WithDebugFunc sets the debug function to be used by the [Reader]. If set,
|
||||
// this function will be called with debug messages. This can be useful if the
|
||||
// caller wants to log debug messages from the [Reader]. By default, no debug
|
||||
// function is set and the logs are not written.
|
||||
func WithDebugFunc(debugFunc DebugFunc) ReaderOption {
|
||||
return &debugFuncOption{debugFunc: debugFunc}
|
||||
}
|
||||
|
||||
type debugFuncOption struct {
|
||||
debugFunc DebugFunc
|
||||
}
|
||||
|
||||
func (o *debugFuncOption) ApplyToReader(r *Reader) {
|
||||
r.debugFunc = o.debugFunc
|
||||
}
|
||||
|
||||
// WithPromptFunc sets the prompt function to be used by the [Reader]. If set,
|
||||
// this function will be called with prompt messages. The function should
|
||||
// optionally log the message to the user and return nil if the prompt is
|
||||
// accepted and the execution should continue. Otherwise, it should return an
|
||||
// error which describes why the the prompt was rejected. This can then be
|
||||
// caught and used later when calling the [Reader.Read] method. By default, no
|
||||
// prompt function is set and all prompts are automatically accepted.
|
||||
func ReaderWithPromptFunc(promptFunc ReaderPromptFunc) ReaderOption {
|
||||
return func(r *Reader) {
|
||||
r.promptFunc = promptFunc
|
||||
}
|
||||
// error which describes why the prompt was rejected. This can then be caught
|
||||
// and used later when calling the [Reader.Read] method. By default, no prompt
|
||||
// function is set and all prompts are automatically accepted.
|
||||
func WithPromptFunc(promptFunc PromptFunc) ReaderOption {
|
||||
return &promptFuncOption{promptFunc: promptFunc}
|
||||
}
|
||||
|
||||
type promptFuncOption struct {
|
||||
promptFunc PromptFunc
|
||||
}
|
||||
|
||||
func (o *promptFuncOption) ApplyToReader(r *Reader) {
|
||||
r.promptFunc = o.promptFunc
|
||||
}
|
||||
|
||||
// Read will read the Taskfile defined by the [Reader]'s [Node] and recurse
|
||||
@@ -292,9 +333,9 @@ func (r *Reader) readNode(node Node) (*ast.Taskfile, error) {
|
||||
taskfileDecodeErr := &errors.TaskfileDecodeError{}
|
||||
if errors.As(err, &taskfileDecodeErr) {
|
||||
snippet := NewSnippet(b,
|
||||
SnippetWithLine(taskfileDecodeErr.Line),
|
||||
SnippetWithColumn(taskfileDecodeErr.Column),
|
||||
SnippetWithPadding(2),
|
||||
WithLine(taskfileDecodeErr.Line),
|
||||
WithColumn(taskfileDecodeErr.Column),
|
||||
WithPadding(2),
|
||||
)
|
||||
return nil, taskfileDecodeErr.WithFileInfo(node.Location(), snippet.String())
|
||||
}
|
||||
|
||||
@@ -33,8 +33,10 @@ func init() {
|
||||
}
|
||||
|
||||
type (
|
||||
// SnippetOption is a function that configures a [Snippet].
|
||||
SnippetOption func(*Snippet)
|
||||
// A SnippetOption is any type that can apply a configuration to a [Snippet].
|
||||
SnippetOption interface {
|
||||
ApplyToSnippet(*Snippet)
|
||||
}
|
||||
// A Snippet is a syntax highlighted snippet of a Taskfile with optional
|
||||
// padding and a line and column indicator.
|
||||
Snippet struct {
|
||||
@@ -55,9 +57,7 @@ type (
|
||||
// determines the number of lines to include before and after the chosen line.
|
||||
func NewSnippet(b []byte, opts ...SnippetOption) *Snippet {
|
||||
snippet := &Snippet{}
|
||||
for _, opt := range opts {
|
||||
opt(snippet)
|
||||
}
|
||||
snippet.Options(opts...)
|
||||
|
||||
// Syntax highlight the input and split it into lines
|
||||
buf := &bytes.Buffer{}
|
||||
@@ -80,40 +80,61 @@ func NewSnippet(b []byte, opts ...SnippetOption) *Snippet {
|
||||
// to the [Snippet].
|
||||
func (s *Snippet) Options(opts ...SnippetOption) {
|
||||
for _, opt := range opts {
|
||||
opt(s)
|
||||
opt.ApplyToSnippet(s)
|
||||
}
|
||||
}
|
||||
|
||||
// SnippetWithLine specifies the line number that the [Snippet] should center
|
||||
// around and point to.
|
||||
func SnippetWithLine(line int) SnippetOption {
|
||||
return func(snippet *Snippet) {
|
||||
snippet.line = line
|
||||
}
|
||||
// WithLine specifies the line number that the [Snippet] should center around
|
||||
// and point to.
|
||||
func WithLine(line int) SnippetOption {
|
||||
return &lineOption{line: line}
|
||||
}
|
||||
|
||||
// SnippetWithColumn specifies the column number that the [Snippet] should
|
||||
// point to.
|
||||
func SnippetWithColumn(column int) SnippetOption {
|
||||
return func(snippet *Snippet) {
|
||||
snippet.column = column
|
||||
}
|
||||
type lineOption struct {
|
||||
line int
|
||||
}
|
||||
|
||||
// SnippetWithPadding specifies the number of lines to include before and after
|
||||
// the selected line in the [Snippet].
|
||||
func SnippetWithPadding(padding int) SnippetOption {
|
||||
return func(snippet *Snippet) {
|
||||
snippet.padding = padding
|
||||
}
|
||||
func (o *lineOption) ApplyToSnippet(s *Snippet) {
|
||||
s.line = o.line
|
||||
}
|
||||
|
||||
// SnippetWithNoIndicators specifies that the [Snippet] should not include line
|
||||
// or column indicators.
|
||||
func SnippetWithNoIndicators() SnippetOption {
|
||||
return func(snippet *Snippet) {
|
||||
snippet.noIndicators = true
|
||||
}
|
||||
// WithColumn specifies the column number that the [Snippet] should point to.
|
||||
func WithColumn(column int) SnippetOption {
|
||||
return &columnOption{column: column}
|
||||
}
|
||||
|
||||
type columnOption struct {
|
||||
column int
|
||||
}
|
||||
|
||||
func (o *columnOption) ApplyToSnippet(s *Snippet) {
|
||||
s.column = o.column
|
||||
}
|
||||
|
||||
// WithPadding specifies the number of lines to include before and after the
|
||||
// selected line in the [Snippet].
|
||||
func WithPadding(padding int) SnippetOption {
|
||||
return &paddingOption{padding: padding}
|
||||
}
|
||||
|
||||
type paddingOption struct {
|
||||
padding int
|
||||
}
|
||||
|
||||
func (o *paddingOption) ApplyToSnippet(s *Snippet) {
|
||||
s.padding = o.padding
|
||||
}
|
||||
|
||||
// WithNoIndicators specifies that the [Snippet] should not include line or
|
||||
// column indicators.
|
||||
func WithNoIndicators() SnippetOption {
|
||||
return &noIndicatorsOption{}
|
||||
}
|
||||
|
||||
type noIndicatorsOption struct{}
|
||||
|
||||
func (o *noIndicatorsOption) ApplyToSnippet(s *Snippet) {
|
||||
s.noIndicators = true
|
||||
}
|
||||
|
||||
func (s *Snippet) String() string {
|
||||
|
||||
@@ -31,8 +31,8 @@ func TestNewSnippet(t *testing.T) {
|
||||
name: "first line, first column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
SnippetWithColumn(1),
|
||||
WithLine(1),
|
||||
WithColumn(1),
|
||||
},
|
||||
want: &Snippet{
|
||||
linesRaw: []string{
|
||||
@@ -52,9 +52,9 @@ func TestNewSnippet(t *testing.T) {
|
||||
name: "first line, first column, padding=2",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
SnippetWithColumn(1),
|
||||
SnippetWithPadding(2),
|
||||
WithLine(1),
|
||||
WithColumn(1),
|
||||
WithPadding(2),
|
||||
},
|
||||
want: &Snippet{
|
||||
linesRaw: []string{
|
||||
@@ -96,8 +96,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "empty",
|
||||
b: []byte{},
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
SnippetWithColumn(1),
|
||||
WithLine(1),
|
||||
WithColumn(1),
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
@@ -110,7 +110,7 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "1st line, 0th column (line indicator only)",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
WithLine(1),
|
||||
},
|
||||
want: "> 1 | \x1b[33mversion\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36m3\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
@@ -118,7 +118,7 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "0th line, 1st column (column indicator only)",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithColumn(1),
|
||||
WithColumn(1),
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
@@ -126,8 +126,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "0th line, 1st column, padding=2 (column indicator only)",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithColumn(1),
|
||||
SnippetWithPadding(2),
|
||||
WithColumn(1),
|
||||
WithPadding(2),
|
||||
},
|
||||
want: " 1 | \x1b[33mversion\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36m3\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 2 | \x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -135,8 +135,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "1st line, 1st column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
SnippetWithColumn(1),
|
||||
WithLine(1),
|
||||
WithColumn(1),
|
||||
},
|
||||
want: "> 1 | \x1b[33mversion\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36m3\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -144,8 +144,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "1st line, 10th column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
SnippetWithColumn(10),
|
||||
WithLine(1),
|
||||
WithColumn(10),
|
||||
},
|
||||
want: "> 1 | \x1b[33mversion\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36m3\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -153,9 +153,9 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "1st line, 1st column, padding=2",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
SnippetWithColumn(1),
|
||||
SnippetWithPadding(2),
|
||||
WithLine(1),
|
||||
WithColumn(1),
|
||||
WithPadding(2),
|
||||
},
|
||||
want: "> 1 | \x1b[33mversion\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36m3\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^\n 2 | \x1b[1m\x1b[30m\x1b[0m\n 3 | \x1b[33mtasks\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
@@ -163,9 +163,9 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "1st line, 10th column, padding=2",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(1),
|
||||
SnippetWithColumn(10),
|
||||
SnippetWithPadding(2),
|
||||
WithLine(1),
|
||||
WithColumn(10),
|
||||
WithPadding(2),
|
||||
},
|
||||
want: "> 1 | \x1b[33mversion\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36m3\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^\n 2 | \x1b[1m\x1b[30m\x1b[0m\n 3 | \x1b[33mtasks\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
@@ -173,8 +173,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "5th line, 1st column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(5),
|
||||
SnippetWithColumn(1),
|
||||
WithLine(5),
|
||||
WithColumn(1),
|
||||
},
|
||||
want: "> 5 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mvars\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -182,8 +182,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "5th line, 5th column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(5),
|
||||
SnippetWithColumn(5),
|
||||
WithLine(5),
|
||||
WithColumn(5),
|
||||
},
|
||||
want: "> 5 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mvars\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -191,9 +191,9 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "5th line, 5th column, padding=2",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(5),
|
||||
SnippetWithColumn(5),
|
||||
SnippetWithPadding(2),
|
||||
WithLine(5),
|
||||
WithColumn(5),
|
||||
WithPadding(2),
|
||||
},
|
||||
want: " 3 | \x1b[33mtasks\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 4 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mdefault\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n> 5 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mvars\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^\n 6 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mFOO\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36mfoo\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 7 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mBAR\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36mbar\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
@@ -201,10 +201,10 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "5th line, 5th column, padding=2, no indicators",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(5),
|
||||
SnippetWithColumn(5),
|
||||
SnippetWithPadding(2),
|
||||
SnippetWithNoIndicators(),
|
||||
WithLine(5),
|
||||
WithColumn(5),
|
||||
WithPadding(2),
|
||||
WithNoIndicators(),
|
||||
},
|
||||
want: " 3 | \x1b[33mtasks\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 4 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mdefault\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 5 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mvars\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 6 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mFOO\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36mfoo\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 7 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mBAR\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36mbar\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
@@ -212,8 +212,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "10th line, 1st column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(10),
|
||||
SnippetWithColumn(1),
|
||||
WithLine(10),
|
||||
WithColumn(1),
|
||||
},
|
||||
want: "> 10 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.BAR}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -221,8 +221,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "10th line, 23rd column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(10),
|
||||
SnippetWithColumn(23),
|
||||
WithLine(10),
|
||||
WithColumn(23),
|
||||
},
|
||||
want: "> 10 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.BAR}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -230,8 +230,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "10th line, 24th column (out of bounds)",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(10),
|
||||
SnippetWithColumn(24),
|
||||
WithLine(10),
|
||||
WithColumn(24),
|
||||
},
|
||||
want: "> 10 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.BAR}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
@@ -239,9 +239,9 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "10th line, 23rd column, padding=2",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(10),
|
||||
SnippetWithColumn(23),
|
||||
SnippetWithPadding(2),
|
||||
WithLine(10),
|
||||
WithColumn(23),
|
||||
WithPadding(2),
|
||||
},
|
||||
want: " 8 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mcmds\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 9 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.FOO}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n> 10 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.BAR}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^",
|
||||
},
|
||||
@@ -249,9 +249,9 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "5th line, 5th column, padding=100",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(5),
|
||||
SnippetWithColumn(5),
|
||||
SnippetWithPadding(100),
|
||||
WithLine(5),
|
||||
WithColumn(5),
|
||||
WithPadding(100),
|
||||
},
|
||||
want: " 1 | \x1b[33mversion\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36m3\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 2 | \x1b[1m\x1b[30m\x1b[0m\n 3 | \x1b[33mtasks\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 4 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mdefault\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n> 5 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mvars\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n | ^\n 6 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mFOO\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36mfoo\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 7 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mBAR\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m \x1b[0m\x1b[36mbar\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 8 | \x1b[1m\x1b[30m \x1b[0m\x1b[33mcmds\x1b[0m\x1b[1m\x1b[30m:\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 9 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.FOO}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 10 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.BAR}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
@@ -259,8 +259,8 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "11th line (out of bounds), 1st column",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(11),
|
||||
SnippetWithColumn(1),
|
||||
WithLine(11),
|
||||
WithColumn(1),
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
@@ -268,9 +268,9 @@ func TestSnippetString(t *testing.T) {
|
||||
name: "11th line (out of bounds), 1st column, padding=2",
|
||||
b: []byte(sample),
|
||||
opts: []SnippetOption{
|
||||
SnippetWithLine(11),
|
||||
SnippetWithColumn(1),
|
||||
SnippetWithPadding(2),
|
||||
WithLine(11),
|
||||
WithColumn(1),
|
||||
WithPadding(2),
|
||||
},
|
||||
want: " 9 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.FOO}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m\n 10 | \x1b[1m\x1b[30m \x1b[0m\x1b[1m\x1b[30m- \x1b[0m\x1b[36mecho \"{{.BAR}}\"\x1b[0m\x1b[1m\x1b[30m\x1b[0m",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user