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

     1  package cmdruntime
     2  
     3  import (
     4  	"errors"
     5  	"runtime"
     6  	"sort"
     7  
     8  	"github.com/lmorg/murex/builtins/core/open"
     9  	"github.com/lmorg/murex/builtins/events"
    10  	"github.com/lmorg/murex/config/defaults"
    11  	"github.com/lmorg/murex/config/profile"
    12  	"github.com/lmorg/murex/debug"
    13  	"github.com/lmorg/murex/lang"
    14  	"github.com/lmorg/murex/lang/parameters"
    15  	"github.com/lmorg/murex/lang/ref"
    16  	"github.com/lmorg/murex/lang/stdio"
    17  	"github.com/lmorg/murex/lang/types"
    18  	"github.com/lmorg/murex/shell/autocomplete"
    19  	"github.com/lmorg/murex/shell/hintsummary"
    20  	"github.com/lmorg/murex/utils/cache"
    21  	cdcache "github.com/lmorg/murex/utils/cd/cache"
    22  	"github.com/lmorg/murex/utils/envvars"
    23  	"github.com/lmorg/murex/utils/json"
    24  )
    25  
    26  const (
    27  	fVars               = "--variables"
    28  	fGlobals            = "--globals"
    29  	fExports            = "--exports"
    30  	fAliases            = "--aliases"
    31  	fBuiltins           = "--builtins"
    32  	fMethods            = "--methods"
    33  	fConfig             = "--config"
    34  	fNamedPipes         = "--named-pipes"
    35  	fPipes              = "--pipes"
    36  	fFunctions          = "--functions"
    37  	fPrivates           = "--privates"
    38  	fOpenAgents         = "--open-agents"
    39  	fFids               = "--fids"
    40  	fShellProc          = "--shell-proc"
    41  	fReadArrays         = "--readarray"
    42  	fReadArrayWithTypes = "--readarraywithtype"
    43  	fWriteArrays        = "--writearray"
    44  	fReadMaps           = "--readmap"
    45  	fIndexes            = "--indexes"
    46  	fNotIndexes         = "--not-indexes"
    47  	fMarshallers        = "--marshallers"
    48  	fUnmarshallers      = "--unmarshallers"
    49  	fEvents             = "--events"
    50  	fAutocomplete       = "--autocomplete"
    51  	fMemstats           = "--memstats"
    52  	fTests              = "--tests"
    53  	fTestResults        = "--test-results"
    54  	fModules            = "--modules"
    55  	fDebug              = "--debug"
    56  	fSources            = "--sources"
    57  	fSummaries          = "--summaries"
    58  	fCachedFilePaths    = "--cached-file-paths"
    59  	fCacheDump          = "--cache"
    60  	fCacheTrim          = "--trim-cache"
    61  	fCacheFlush         = "--flush-cache"
    62  	fHelp               = "--help"
    63  )
    64  
    65  var flags = map[string]string{
    66  	fVars:               types.Boolean,
    67  	fGlobals:            types.Boolean,
    68  	fExports:            types.Boolean,
    69  	fAliases:            types.Boolean,
    70  	fBuiltins:           types.Boolean,
    71  	fMethods:            types.Boolean,
    72  	fConfig:             types.Boolean,
    73  	fPipes:              types.Boolean,
    74  	fNamedPipes:         types.Boolean,
    75  	fFunctions:          types.Boolean,
    76  	fPrivates:           types.Boolean,
    77  	fOpenAgents:         types.Boolean,
    78  	fFids:               types.Boolean,
    79  	fShellProc:          types.Boolean,
    80  	fReadArrays:         types.Boolean,
    81  	fReadArrayWithTypes: types.Boolean,
    82  	fReadMaps:           types.Boolean,
    83  	fWriteArrays:        types.Boolean,
    84  	fIndexes:            types.Boolean,
    85  	fNotIndexes:         types.Boolean,
    86  	fMarshallers:        types.Boolean,
    87  	fUnmarshallers:      types.Boolean,
    88  	fEvents:             types.Boolean,
    89  	fAutocomplete:       types.Boolean,
    90  	fMemstats:           types.Boolean,
    91  	fTests:              types.Boolean,
    92  	fTestResults:        types.Boolean,
    93  	fModules:            types.Boolean,
    94  	fDebug:              types.Boolean,
    95  	fSources:            types.Boolean,
    96  	fSummaries:          types.Boolean,
    97  	fCachedFilePaths:    types.Boolean,
    98  	fCacheDump:          types.Boolean,
    99  	fCacheTrim:          types.Boolean,
   100  	fCacheFlush:         types.Boolean,
   101  	fHelp:               types.Boolean,
   102  }
   103  
   104  func init() {
   105  	lang.DefineFunction("runtime", cmdRuntime, types.Json)
   106  
   107  	defaults.AppendProfile(`
   108          autocomplete set runtime { [{
   109              "Dynamic": ({ runtime --help }),
   110              "AllowMultiple": true
   111          }] }
   112      `)
   113  }
   114  
   115  // Help returns an array of flags supported by `runtime`
   116  func Help() (s []string) {
   117  	for f := range flags {
   118  		s = append(s, f)
   119  	}
   120  
   121  	sort.Strings(s)
   122  	return
   123  }
   124  
   125  func cmdRuntime(p *lang.Process) error {
   126  	p.Stdout.SetDataType(types.Json)
   127  
   128  	f, _, err := p.Parameters.ParseFlags(
   129  		&parameters.Arguments{
   130  			Flags:           flags,
   131  			AllowAdditional: false,
   132  		},
   133  	)
   134  
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	if len(f) == 0 {
   140  		return errors.New("please include one or more parameters")
   141  	}
   142  
   143  	ret := make(map[string]interface{})
   144  	for flag := range f {
   145  		switch flag {
   146  		case fVars:
   147  			ret[fVars[2:]] = p.Scope.Variables.Dump()
   148  		case fGlobals:
   149  			ret[fGlobals[2:]] = lang.GlobalVariables.Dump()
   150  		case fExports:
   151  			m := make(map[string]interface{})
   152  			envvars.All(m)
   153  			ret[fExports[2:]] = m
   154  		case fAliases:
   155  			ret[fAliases[2:]] = lang.GlobalAliases.Dump()
   156  		case fBuiltins:
   157  			var s []string
   158  			for name := range lang.GoFunctions {
   159  				s = append(s, name)
   160  			}
   161  			sort.Strings(s)
   162  			ret[fBuiltins[2:]] = s
   163  		case fMethods:
   164  			ret[fMethods[2:]] = map[string]map[string][]string{
   165  				"in":  lang.MethodStdin.Dump(),
   166  				"out": lang.MethodStdout.Dump(),
   167  			}
   168  		case fConfig:
   169  			ret[fConfig[2:]] = lang.ShellProcess.Config.DumpRuntime()
   170  		case fNamedPipes:
   171  			ret[fNamedPipes[2:]] = lang.GlobalPipes.Dump()
   172  		case fPipes:
   173  			ret[fPipes[2:]] = stdio.DumpPipes()
   174  		case fFunctions:
   175  			ret[fFunctions[2:]] = lang.MxFunctions.Dump()
   176  		case fPrivates:
   177  			ret[fPrivates[2:]] = lang.PrivateFunctions.Dump()
   178  		case fOpenAgents:
   179  			ret[fOpenAgents[2:]] = open.OpenAgents.Dump()
   180  		case fFids:
   181  			ret[fFids[2:]] = lang.GlobalFIDs.ListAll()
   182  		case fShellProc:
   183  			ret[fShellProc[2:]] = lang.ShellProcess.Dump()
   184  		case fReadArrays:
   185  			ret[fReadArrays[2:]] = stdio.DumpReadArray()
   186  		case fReadArrayWithTypes:
   187  			ret[fReadArrays[2:]] = stdio.DumpReadArrayWithType()
   188  		case fReadMaps:
   189  			ret[fReadMaps[2:]] = stdio.DumpMap()
   190  		case fWriteArrays:
   191  			ret[fWriteArrays[2:]] = stdio.DumpWriteArray()
   192  		case fIndexes:
   193  			ret[fIndexes[2:]] = lang.DumpIndex()
   194  		case fNotIndexes:
   195  			ret[fIndexes[2:]] = lang.DumpNotIndex()
   196  		case fMarshallers:
   197  			ret[fMarshallers[2:]] = lang.DumpMarshaller()
   198  		case fUnmarshallers:
   199  			ret[fUnmarshallers[2:]] = lang.DumpUnmarshaller()
   200  		case fEvents:
   201  			ret[fEvents[2:]] = events.DumpEvents()
   202  		case fAutocomplete:
   203  			ret[fAutocomplete[2:]] = autocomplete.RuntimeDump()
   204  		case fMemstats:
   205  			var mem runtime.MemStats
   206  			runtime.ReadMemStats(&mem)
   207  			ret[fMemstats[2:]] = mem
   208  		case fTests:
   209  			ret[fTests[2:]] = p.Tests.Dump()
   210  		case fTestResults:
   211  			ret[fTestResults[2:]] = dumpTestResults(p)
   212  		case fModules:
   213  			ret[fModules[2:]] = profile.Packages
   214  		case fDebug:
   215  			ret[fDebug[2:]] = debug.Dump()
   216  		case fSources:
   217  			ret[fSources[2:]] = ref.History.Dump()
   218  		case fSummaries:
   219  			ret[fSummaries[2:]] = hintsummary.Summary.Dump()
   220  		case fCachedFilePaths:
   221  			ret[fCachedFilePaths[2:]] = cdcache.DumpCompletions()
   222  		case fCacheDump:
   223  			v, err := cache.Dump(p.Context)
   224  			if err != nil {
   225  				return err
   226  			}
   227  			ret[fCacheDump[2:]] = v
   228  		case fCacheTrim:
   229  			v, err := cache.Trim(p.Context)
   230  			if err != nil {
   231  				return err
   232  			}
   233  			ret[fCacheTrim[2:]] = v
   234  		case fCacheFlush:
   235  			v, err := cache.Flush(p.Context)
   236  			if err != nil {
   237  				return err
   238  			}
   239  			ret[fCacheFlush[2:]] = v
   240  		case fHelp:
   241  			ret[fHelp[2:]] = Help()
   242  		default:
   243  			return errors.New("unrecognized parameter: " + flag)
   244  		}
   245  	}
   246  
   247  	var b []byte
   248  	if len(ret) == 1 {
   249  		var obj interface{}
   250  		for _, obj = range ret {
   251  		}
   252  		b, err = json.Marshal(obj, p.Stdout.IsTTY())
   253  		if err != nil {
   254  			return err
   255  		}
   256  
   257  	} else {
   258  		b, err = json.Marshal(ret, p.Stdout.IsTTY())
   259  		if err != nil {
   260  			return err
   261  		}
   262  	}
   263  
   264  	_, err = p.Stdout.Write(b)
   265  	return err
   266  }
   267  
   268  func dumpTestResults(p *lang.Process) interface{} {
   269  	return map[string]interface{}{
   270  		"shell":   lang.ShellProcess.Tests.Results.Dump(),
   271  		"process": p.Tests.Results.Dump(),
   272  	}
   273  }