github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/management/functions.go (about)

     1  package management
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"runtime"
     7  	"strconv"
     8  
     9  	"github.com/lmorg/murex/lang"
    10  	"github.com/lmorg/murex/lang/types"
    11  	"github.com/lmorg/murex/shell/autocomplete"
    12  	"github.com/lmorg/murex/utils/cd"
    13  	"github.com/lmorg/murex/utils/home"
    14  	"github.com/lmorg/murex/utils/json"
    15  	"github.com/lmorg/murex/utils/lists"
    16  	"github.com/lmorg/murex/utils/man"
    17  	"github.com/lmorg/murex/utils/posix"
    18  )
    19  
    20  func init() {
    21  	lang.DefineFunction("exitnum", cmdExitNum, types.Integer)
    22  	lang.DefineFunction("bexists", cmdBuiltinExists, types.Json)
    23  	lang.DefineFunction("cd", cmdCd, types.Null)
    24  	lang.DefineFunction("os", cmdOs, types.String)
    25  	lang.DefineFunction("cpuarch", cmdCpuArch, types.String)
    26  	lang.DefineFunction("cpucount", cmdCpuCount, types.Integer)
    27  	lang.DefineFunction("murex-update-exe-list", cmdUpdateExeList, types.Null)
    28  	lang.DefineFunction("man-summary", cmdManSummary, types.Null)
    29  }
    30  
    31  func cmdExitNum(p *lang.Process) error {
    32  	p.Stdout.SetDataType(types.Integer)
    33  	p.Stdout.Writeln([]byte(strconv.Itoa(p.Previous.ExitNum)))
    34  	return nil
    35  }
    36  
    37  func cmdBuiltinExists(p *lang.Process) error {
    38  	p.Stdout.SetDataType(types.Json)
    39  	if p.Parameters.Len() == 0 {
    40  		return errors.New("missing parameters. Please name builtins you want to check")
    41  	}
    42  
    43  	var j struct {
    44  		Installed []string
    45  		Missing   []string
    46  	}
    47  
    48  	for _, name := range p.Parameters.StringArray() {
    49  		if lang.GoFunctions[name] != nil {
    50  			j.Installed = append(j.Installed, name)
    51  		} else {
    52  			j.Missing = append(j.Missing, name)
    53  			p.ExitNum++
    54  		}
    55  	}
    56  
    57  	b, err := json.Marshal(j, p.Stdout.IsTTY())
    58  	p.Stdout.Writeln(b)
    59  
    60  	return err
    61  }
    62  
    63  const cdErrMsg = "cannot find previous directory"
    64  
    65  func cmdCd(p *lang.Process) error {
    66  	p.Stdout.SetDataType(types.Null)
    67  	path, _ := p.Parameters.String(0)
    68  
    69  	switch path {
    70  	case "":
    71  		return cd.Chdir(p, home.MyDir)
    72  	case "-":
    73  		pwdHist, err := p.Variables.GetValue("PWDHIST")
    74  		if err != nil {
    75  			return fmt.Errorf("%s: %s", cdErrMsg, err.Error())
    76  		}
    77  		v, err := lists.GenericToString(pwdHist)
    78  		switch {
    79  		case err != nil:
    80  			return fmt.Errorf("%s: $PWDHIST doesn't appear to be a valid array: %s", cdErrMsg, err.Error())
    81  		case len(v) == 0:
    82  			return fmt.Errorf("%s: $PWDHIST is an empty array", cdErrMsg)
    83  		case len(v) == 1:
    84  			return errors.New("already at first directory in $PWDHIST")
    85  		default:
    86  			return cd.Chdir(p, v[len(v)-2])
    87  		}
    88  	default:
    89  		return cd.Chdir(p, path)
    90  	}
    91  }
    92  
    93  func cmdOs(p *lang.Process) error {
    94  	if p.Parameters.Len() == 0 {
    95  		p.Stdout.SetDataType(types.String)
    96  		_, err := p.Stdout.Write([]byte(runtime.GOOS))
    97  		return err
    98  	}
    99  
   100  	for _, os := range p.Parameters.StringArray() {
   101  		if os == runtime.GOOS || (os == "posix" && posix.IsPosix()) {
   102  			_, err := p.Stdout.Write(types.TrueByte)
   103  			return err
   104  		}
   105  	}
   106  
   107  	p.ExitNum = 1
   108  	_, err := p.Stdout.Write(types.FalseByte)
   109  	return err
   110  }
   111  
   112  func cmdCpuArch(p *lang.Process) (err error) {
   113  	p.Stdout.SetDataType(types.String)
   114  	_, err = p.Stdout.Write([]byte(runtime.GOARCH))
   115  	return
   116  }
   117  
   118  func cmdCpuCount(p *lang.Process) (err error) {
   119  	p.Stdout.SetDataType(types.Integer)
   120  	_, err = p.Stdout.Write([]byte(strconv.Itoa(runtime.NumCPU())))
   121  	return
   122  }
   123  
   124  func cmdUpdateExeList(p *lang.Process) error {
   125  	p.Stdout.SetDataType(types.Null)
   126  	autocomplete.UpdateGlobalExeList()
   127  	return nil
   128  }
   129  
   130  func cmdManSummary(p *lang.Process) (err error) {
   131  	p.Stdout.SetDataType(types.String)
   132  
   133  	if p.Parameters.Len() == 0 {
   134  		return errors.New("parameter expected - name of executable")
   135  	}
   136  
   137  	exes := p.Parameters.StringArray()
   138  
   139  	for _, exe := range exes {
   140  		paths := man.GetManPages(exe)
   141  		if len(paths) == 0 {
   142  			p.Stderr.Writeln([]byte(exe + " - no man page exists"))
   143  			continue
   144  		}
   145  
   146  		s := man.ParseSummary(paths)
   147  		if s == "" {
   148  			p.Stderr.Writeln([]byte(exe + " - unable to parse summary"))
   149  			continue
   150  		}
   151  
   152  		_, err := p.Stdout.Writeln([]byte(s))
   153  		if err != nil {
   154  			return err
   155  		}
   156  	}
   157  
   158  	return nil
   159  }