all repos

viye @ 87c9108

my shot at reimplementing xiki
6 files changed, 28 insertions(+), 26 deletions(-)
some refactoring again
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-08-28 20:38:02 +0300
Authored at: 2026-08-28 19:21:53 +0300
Change ID: mqskkstxmuvzpqozxzplukqxtztkxuxz
Parent: f73a949
M internal/plumbing/curl/curl.go
···
        2
        2
         

      
        3
        3
         import (

      
        4
        4
         	"context"

      
        5
        
        -	"fmt"

      
        6
        5
         	"os/exec"

      
        7
        6
         	"strings"

      
        8
        7
         

      ···
        24
        23
         

      
        25
        24
         	output, err := cmd.CombinedOutput()

      
        26
        25
         	if err != nil && ctx.Err() == context.DeadlineExceeded {

      
        27
        
        -		return "", fmt.Errorf("timeout: command exceeded %s", viye.Timeout)

      
        
        26
        +		return "", viye.ErrTimeout

      
        28
        27
         	}

      
        29
        28
         

      
        30
        29
         	out := strings.ReplaceAll(string(output), "\r", "")

      
M internal/plumbing/gobin/gobin.go
···
        1
        1
         package gobin

      
        2
        2
         

      
        3
        3
         import (

      
        
        4
        +	"context"

      
        4
        5
         	"os/exec"

      
        5
        6
         

      
        6
        7
         	"github.com/olexsmir/viye/internal/viye"

      ···
        11
        12
         - run

      
        12
        13
         - generate

      
        13
        14
         - doc

      
        14
        
        -- mod/

      
        
        15
        ++ mod/

      
        15
        16
         `

      
        16
        17
         

      
        17
        18
         const modMenu = `- tidy

      ···
        43
        44
         }

      
        44
        45
         

      
        45
        46
         func runGo(dir, subcmd string, args ...string) (string, error) {

      
        46
        
        -	cmd := exec.Command("go", append([]string{subcmd}, args...)...)

      
        
        47
        +	ctx, cancel := context.WithTimeout(context.Background(), viye.Timeout)

      
        
        48
        +	defer cancel()

      
        
        49
        +

      
        
        50
        +	cmd := exec.CommandContext(ctx, "go", append([]string{subcmd}, args...)...)

      
        47
        51
         	cmd.Dir = dir

      
        48
        
        -	out, _ := cmd.CombinedOutput()

      
        
        52
        +	out, err := cmd.CombinedOutput()

      
        
        53
        +	if err != nil && ctx.Err() == context.DeadlineExceeded {

      
        
        54
        +		return "", viye.ErrTimeout

      
        
        55
        +	}

      
        49
        56
         	return viye.FormatOutput(out), nil

      
        50
        57
         }

      
M internal/plumbing/json/json.go
···
        26
        26
         		}

      
        27
        27
         

      
        28
        28
         		key := strings.TrimSpace(before)

      
        29
        
        -		val := strings.TrimSpace(after)

      
        30
        29
         		if key != "" {

      
        31
        
        -			m[key] = val

      
        
        30
        +			m[key] = strings.TrimSpace(after)

      
        32
        31
         		}

      
        33
        32
         	}

      
        34
        33
         

      
M internal/plumbing/makefile/makefile.go
···
        3
        3
         import (

      
        4
        4
         	"bufio"

      
        5
        5
         	"bytes"

      
        
        6
        +	"context"

      
        6
        7
         	"errors"

      
        7
        8
         	"os"

      
        8
        9
         	"os/exec"

      ···
        13
        14
         	"github.com/olexsmir/viye/internal/viye"

      
        14
        15
         )

      
        15
        16
         

      
        16
        
        -var ErrMakefileNotFound = errors.New("makefile not found")

      
        17
        
        -

      
        18
        17
         type Tool struct{}

      
        19
        18
         

      
        20
        19
         func (Tool) Name() string               { return "make" }

      ···
        22
        21
         func (Tool) Execute(c *viye.Context) (string, error) {

      
        23
        22
         	fpath, found := findMakefile(c)

      
        24
        23
         	if !found {

      
        25
        
        -		return "", ErrMakefileNotFound

      
        
        24
        +		return "", errors.New("makefile not found")

      
        26
        25
         	}

      
        27
        26
         

      
        28
        27
         	contents, err := os.ReadFile(fpath)

      ···
        41
        40
         

      
        42
        41
         	case 1: // run specified task

      
        43
        42
         		if !slices.Contains(tasks, c.Args[0]) {

      
        44
        
        -			return "", ErrTaskNotFound

      
        
        43
        +			return "", errors.New("task not found")

      
        45
        44
         		}

      
        46
        
        -		cmd := exec.Command("make", c.Args[0])

      
        
        45
        +

      
        
        46
        +		ctx, cancel := context.WithTimeout(context.Background(), viye.Timeout)

      
        
        47
        +		defer cancel()

      
        
        48
        +

      
        
        49
        +		cmd := exec.CommandContext(ctx, "make", c.Args[0])

      
        47
        50
         		cmd.Dir = c.Dir

      
        48
        51
         		out, err := cmd.Output()

      
        
        52
        +		if ctx.Err() == context.DeadlineExceeded {

      
        
        53
        +			return "", viye.ErrTimeout

      
        
        54
        +		}

      
        49
        55
         		if err != nil {

      
        50
        56
         			return "", err

      
        51
        57
         		}

      ···
        55
        61
         		return "", errors.New("invalid command, make usage: make [task]")

      
        56
        62
         	}

      
        57
        63
         }

      
        58
        
        -

      
        59
        
        -var ErrTaskNotFound = errors.New("task not found")

      
        60
        64
         

      
        61
        65
         func findMakefile(c *viye.Context) (name string, found bool) {

      
        62
        66
         	for _, mfile := range []string{"makefile", "Makefile", "GNUMakefile"} {

      
M internal/plumbing/weather/weather.go
···
        14
        14
         	"github.com/olexsmir/viye/internal/viye"

      
        15
        15
         )

      
        16
        16
         

      
        17
        
        -// | Berlin

      
        18
        
        -// | Today 🌧️ 12° / ☀️ 19° / 🌤️ 15°

      
        19
        
        -// | Sat   ☁️ 16° (avg)

      
        20
        
        -// | Sun   🌧️ 14° (avg)

      
        21
        
        -

      
        22
        17
         type Tool struct{}

      
        23
        18
         

      
        24
        19
         func (Tool) Name() string               { return "weather" }

      
M internal/viye/viye.go
···
        9
        9
         	"time"

      
        10
        10
         )

      
        11
        11
         

      
        12
        
        -var ErrToolNotFound = errors.New("tool not found")

      
        13
        
        -

      
        14
        12
         const (

      
        15
        13
         	Version = "0.0.1-alpha"

      
        16
        14
         	Timeout = 5 * time.Second

      
        
        15
        +)

      
        
        16
        +

      
        
        17
        +var (

      
        
        18
        +	ErrToolNotFound = errors.New("tool not found")

      
        
        19
        +	ErrTimeout      = fmt.Errorf("timeout: command exceeded %s", Timeout)

      
        17
        20
         )

      
        18
        21
         

      
        19
        22
         type Context struct {

      ···
        79
        82
         	return err

      
        80
        83
         }

      
        81
        84
         

      
        82
        
        -// dispatch executes the path against registered tools, first-match-wins

      
        83
        85
         func (v *Viye) dispatch(ctx *Context) (string, error) {

      
        84
        86
         	if len(ctx.Path) == 0 {

      
        85
        87
         		return "", nil

      ···
        113
        115
         	return path[0], path[1:]

      
        114
        116
         }

      
        115
        117
         

      
        116
        
        -// splitArgs builds path and body from args.

      
        117
        
        -// Everything before "--" is the path (each arg is one component).

      
        118
        
        -// Everything after "--" is the body (one element per line, ": " prefix stripped).

      
        119
        
        -// If there's no "--", body is nil.

      
        120
        118
         func splitArgs(args []string) (path []string, body []string) {

      
        121
        119
         	sawSep := false

      
        122
        120
         	for _, arg := range args {