ADDED:
* Much more functions to tplx/sprigx
This commit is contained in:
brent saner
2026-01-29 19:02:21 -05:00
parent 64a7648fbc
commit 1bd6e1256c
18 changed files with 3036 additions and 1489 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,699 +0,0 @@
# What is SprigX?
SprigX are extensions to [the `sprig`
library](https://masterminds.github.io/sprig/) ([Go
docs](https://pkg.go.dev/github.com/Masterminds/sprig/v3)).
They provide functions that offer more enriched use cases and
domain-specific data.
If you are reading this README on the Go Module Directory documentation
(<https://pkg.go.dev/r00t2.io/goutils/tplx/sprigx>) or the directory
landing page
(<https://git.r00t2.io/r00t2/go_goutils/src/branch/master/tplx/sprigx>),
it may not render correctly.
Be sure to view it at properly via [the AsciiDoc
rendering](https://git.r00t2.io/r00t2/go_goutils/src/branch/master/tplx/sprigx/README.adoc)
or by downloading and viewing the [HTML
version](https://git.r00t2.io/r00t2/go_goutils/raw/branch/master/tplx/sprigx/README.html).
# How do I Use SprigX?
The same way you would `sprig`!
package main
import (
htmlTplLib "html/template"
txtTplLib "text/template"
"r00t2.io/goutils/tplx/sprigx"
)
var (
txtTpl *txtTplLib.Template = txtTplLib.
New("").
Funcs(
sprigx.TxtFuncMap(),
)
htmlTpl *htmlTplLib.Template = htmlTplLib.
New("").
Funcs(
sprigx.HtmlFuncMap(),
)
)
They can even be combined/used together.
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
var txtTpl *template.Template = template.
New("").
Funcs(
sprigx.TxtFuncMap(),
).
Funcs(
sprig.TxtFuncMap(),
)
// Or:
/*
var txtTpl *template.Template = template.
New("").
Funcs(
sprig.TxtFuncMap(),
).
Funcs(
sprigx.TxtFuncMap(),
)
*/
If a `<template>.FuncMap` is added via `.Funcs()` **after** template
parsing, it will override any functions of the same name of a
`<template>.FuncMap` **before** parsing.
For example, if both `sprig` and `sprigx` provide a function `foo`:
this will use `foo` from `sprigx`
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
const (
myTpl string = `{{ "This is an example template string." | foo }}`
)
var (
tpl *template.Template = template.Must(
template.
New("").
Funcs(sprig.TxtFuncMap()).
Parse(myTpl),
).
Funcs(sprigx.TxtFuncMap())
)
whereas this will use `foo` from `sprig`
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
const (
myTpl string = `{{ "This is an example template string." | foo }}`
)
var (
tpl *template.Template = template.Must(
template.
New("").
Funcs(sprigx.TxtFuncMap()).
Parse(myTpl),
).
Funcs(sprig.TxtFuncMap())
)
and a function can even be explicitly overridden.
This would override a function `foo` and `foo2` in `sprigx` from `foo`
and `foo2` from `sprig`, but leave all other `sprig` functions
untouched.
package main
import (
"text/template"
"github.com/Masterminds/sprig/v3"
"r00t2.io/goutils/tplx/sprigx"
)
const (
myTpl string = `{{ "This is an example template string." | foo }}`
)
var (
overrideFuncs template.FuncMap = sprig.TxtFuncMap()
tpl *template.Template = template.Must(
template.
New("").
Funcs(sprigx.TxtFuncMap()).
Parse(myTpl),
).
Funcs(
template.FuncMap(
map[string]any{
"foo": overrideFuncs["foo"],
"foo2": overrideFuncs["foo2"],
},
),
)
)
# Functions
Expect this list to grow over time, and potentially more frequently than
the `sprigx` functions.
## Operating System
### `osHostname`
`osHostname` simply wraps and returns the result of calling
[`os.Hostname`](https://pkg.go.dev/os#Hostname).
As such, it comes with the same caveats - its possible for it to error,
and it isnt guaranteed to be an FQDNit will be precisely/exactly
whatever the kernels hostname is set as.
## System/Platform/Architecture
### `sysArch`
Returns the [`runtime.GOARCH`](https://pkg.go.dev/runtime#GOARCH)
constant.
### `sysNumCpu`
Returns the value from
[`runtime.NumCPU`](https://pkg.go.dev/runtime#NumCPU).
### `sysOsName`
Returns the [`runtime.GOOS`](https://pkg.go.dev/runtime#GOOS) constant.
### `sysRuntime`
This function returns a `map[string]string` of various information from
the [`runtime` stdlib library](https://pkg.go.dev/runtime).
Specifically, the following are returned.
The value type is a direct link to the `runtime` documentation providing
more detail about the associated value.
Because all values are mapped as strings, they can be converted back to
their native type via e.g. the [Sprig conversion
functions](https://masterminds.github.io/sprig/conversion.html) if
necessary.
<table>
<caption><code>sysRuntime</code> Values</caption>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr>
<th style="text-align: center;">Key</th>
<th style="text-align: center;">Value Type</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><p><code>compiler</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#Compiler">string</a></p></td>
</tr>
<tr>
<td style="text-align: center;"><p><code>arch</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#GOARCH">string</a></p></td>
</tr>
<tr>
<td style="text-align: center;"><p><code>os</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#GOOS">string</a></p></td>
</tr>
<tr>
<td style="text-align: center;"><p><code>maxprocs</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#GOMAXPROCS">int</a> <a href="#fn1"
class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a></p></td>
</tr>
<tr>
<td style="text-align: center;"><p><code>cpu_cnt</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#NumCPU">int</a></p></td>
</tr>
<tr>
<td style="text-align: center;"><p><code>num_cgo</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#NumCgoCall">int</a></p></td>
</tr>
<tr>
<td style="text-align: center;"><p><code>num_go</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#NumGoroutine">int</a></p></td>
</tr>
<tr>
<td style="text-align: center;"><p><code>go_ver</code></p></td>
<td style="text-align: center;"><p><a
href="https://pkg.go.dev/runtime#Version">string</a></p></td>
</tr>
</tbody>
</table>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>For safety concerns, <code>sprigx</code> does not allow
<strong>setting</strong> <code>GOMAXPROCS</code>, this value only
contains the <strong>current</strong> <code>GOMAXPROCS</code> value.<a
href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
As a convenience, some of these values also have their own dedicated
functions as well:
- [](#fn_sys_arch)
- [](#fn_sys_numcpu)
- [](#fn_sys_os)
## Paths
### Generic
These operate similar to [the `path` stdlib
library](https://pkg.go.dev/path) and use a fixed `/` path separator.
#### `pathJoin`
`pathJoin` operates **exactly** like
[`path.Join`](https://pkg.go.dev/path#Join) in stdlib.
If you are joining paths in a pipeline, you almost assuredly want
[](#fn_path_gnrc_ppj) or [](#fn_path_gnrc_pspj) instead unless you are
explicitly **appending** a pipeline result to a path.
{{- pathJoin "a" "b" "c" }}
{{- pathJoin "/" "a" "b" "c" }}
{{- pathJoin "/a/b" "c" }}
renders as:
a/b/c
/a/b/c
/a/b/c
#### `pathPipeJoin`
`pathPipeJoin` operates like [](#fn_path_gnrc_pj) with one deviation:
the root/base path is expected to be **last** in the arguments.
This makes it much more suitable for use in template pipelines, as the
previous value in a pipeline is passed in as the last element to the
next pipe function.
{{- $myBase := "/a" -}}
{{- pathPipeJoin "b" "c" "a" }}
{{- pathPipeJoin "a" "b" "c" "/" }}
{{- $myBase | pathPipeJoin "b" "c" }}
renders as:
a/b/c
/a/b/c
/a/b/c
#### `pathSliceJoin`
`pathSliceJoin` joins a slice of path segment strings (`[]string`)
instead of a variadic sequence of strings.
The `splitList` function shown below is from the [`sprig` string slice
functions](https://masterminds.github.io/sprig/string_slice.html).
{{- $myList := "a,b,c" | splitList "," -}}
{{- $myList | pathSliceJoin }}
{{- ("a,b,c" | splitList ",") | pathSliceJoin }}
{{- ("/,a,b,c" | splitList ",") | pathSliceJoin }}
renders as:
a/b/c
a/b/c
/a/b/c
#### `pathSlicePipeJoin`
`pathSlicePipeJoin` operates like [](#fn_path_gnrc_ppj) in that it is
suitable for pipeline use in which the root/base path is passed in from
the pipeline, but it is like [](#fn_path_gnrc_psj) in that it then also
accepts a slice of path segments (`[]string`) to append to that base
path.
The `splitList` function shown below is from the [`sprig` string slice
functions](https://masterminds.github.io/sprig/string_slice.html).
{{- $myBase := "/a" -}}
{{- $myList := "b,c,d" | splitList "." -}}
{{- pathSlicePipeJoin $myList $myBase }}
{{- $myBase | pathSlicePipeJoin $myList }}
renders as:
/a/b/c
/a/b/c
#### `pathSubJoin`
`pathSubJoin` operates like [](#fn_path_gnrc_pj) but it expects an
explicit root/base path.
The pipeline-friendly equivalent of this is [](#fn_path_gnrc_ppj).
{{- pathSubJoin "/a/b" "c" }}
{{- pathSubJoin "/" "a" "b" "c" }}
{{- "c" | pathSubJoin "/" "a" "b" }}
renders as:
/a/b/c
/a/b/c
/a/b/c
### OS/Platform-Tailored
These operate similar to [the `path/filepath` stdlib
library](https://pkg.go.dev/path/filepath), and use the OS-specific
[`os.PathSeparator`](https://pkg.go.dev/os#PathSeparator).
Take special note of the oddness around specifying Windows paths and
drive letters in e.g. [](#fn_path_os_pj)!
It is recommended to make use of [](#fn_sys_os) to conditionally format
path bases/roots if needed.
#### `osPathJoin`
`osPathJoin` operates **exactly** like
[`path/filepath.Join`](https://pkg.go.dev/path/filepath#Join) in stdlib.
If you are joining paths in a pipeline, you almost assuredly want
[](#fn_path_os_ppj) or [](#fn_path_os_pspj) instead unless you are
explicitly **appending** a pipeline result to a path.
{{- osPathJoin "a" "b" "c" }}
{{- osPathJoin "/" "a" "b" "c" }}
{{- osPathJoin "C:\\" "a" "b" "c" }}
{{- osPathJoin "C:" "a" "b" "c" }}
renders as:
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 66%" />
</colgroup>
<thead>
<tr>
<th style="text-align: center;">OS</th>
<th style="text-align: center;">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><p>Windows</p></td>
<td style="text-align: left;"><pre class="text"><code>a\b\c
\a\b\c
\a\b\c
C:\a\b\c
C:a\b\c</code></pre></td>
</tr>
<tr>
<td style="text-align: center;"><p>Others (e.g. Linux, macOS)</p></td>
<td style="text-align: left;"><pre class="text"><code>a/b/c
/a/b/c
C:\/a/b/c
C:/a/b/c</code></pre></td>
</tr>
</tbody>
</table>
#### `osPathPipeJoin`
`osPathPipeJoin` operates like [](#fn_path_gnrc_ppj) (except using
OS-specific path separators).
This makes it much more suitable for use in template pipelines, as the
previous value in a pipeline is passed in as the last element to the
next pipe function.
{{- $myBase := "/a" -}}
{{- osPathPipeJoin "b" "c" "a" }}
{{- osPathPipeJoin "a" "b" "c" "/" }}
{{- $myBase | osPathPipeJoin "b" "c" }}
renders as:
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 66%" />
</colgroup>
<thead>
<tr>
<th style="text-align: center;">OS</th>
<th style="text-align: center;">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><p>Windows</p></td>
<td style="text-align: left;"><pre class="text"><code>a\b\c
\a\b\c
\a\b\c</code></pre></td>
</tr>
<tr>
<td style="text-align: center;"><p>Others (e.g. Linux, macOS)</p></td>
<td style="text-align: left;"><pre class="text"><code>a/b/c
/a/b/c
/a/b/c</code></pre></td>
</tr>
</tbody>
</table>
#### `osPathSep`
`osPathSep` returns the
[`os.PathSeparator`](https://pkg.go.dev/os#PathSeparator) for this OS.
{{- osPathSep }}
renders as:
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 66%" />
</colgroup>
<thead>
<tr>
<th style="text-align: center;">OS</th>
<th style="text-align: center;">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><p>Windows</p></td>
<td style="text-align: left;"><pre class="text"><code>\</code></pre></td>
</tr>
<tr>
<td style="text-align: center;"><p>Others (e.g. Linux, macOS)</p></td>
<td style="text-align: left;"><pre class="text"><code>/</code></pre></td>
</tr>
</tbody>
</table>
#### `osPathSliceJoin`
`osPathSliceJoin` operates like [](#fn_path_gnrc_psj) but with
OS-specific path separators.
The `splitList` function shown below is from the [`sprig` string slice
functions](https://masterminds.github.io/sprig/string_slice.html).
{{- $myList := "a,b,c" | splitList "," -}}
{{- $myList | osPathSliceJoin }}
{{- ("a,b,c" | splitList ",") | osPathSliceJoin }}
{{- ("/,a,b,c" | splitList ",") | osPathSliceJoin }}
renders as:
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 66%" />
</colgroup>
<thead>
<tr>
<th style="text-align: center;">OS</th>
<th style="text-align: center;">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><p>Windows</p></td>
<td style="text-align: left;"><pre class="text"><code>a\b\c
a\b\c
\a\b\c</code></pre></td>
</tr>
<tr>
<td style="text-align: center;"><p>Others (e.g. Linux, macOS)</p></td>
<td style="text-align: left;"><pre class="text"><code>a/b/c
a/b/c
/a/b/c</code></pre></td>
</tr>
</tbody>
</table>
#### `osPathSlicePipeJoin`
`osPathSlicePipeJoin` operates like [](#fn_path_gnrc_pspj) but with
OS-specific separators.
The `splitList` function shown below is from the [`sprig` string slice
functions](https://masterminds.github.io/sprig/string_slice.html).
{{- $myBase := "/a" -}}
{{- $myList := "b,c,d" | splitList "." -}}
{{- osPathSlicePipeJoin $myList $myBase }}
{{- $myBase | osPathSlicePipeJoin $myList }}
renders as:
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 66%" />
</colgroup>
<thead>
<tr>
<th style="text-align: center;">OS</th>
<th style="text-align: center;">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><p>Windows</p></td>
<td style="text-align: left;"><pre class="text"><code>\a\b\c\d
\a\b\c\d</code></pre></td>
</tr>
<tr>
<td style="text-align: center;"><p>Others (e.g. Linux, macOS)</p></td>
<td style="text-align: left;"><pre class="text"><code>/a/b/c/d
/a/b/c/d</code></pre></td>
</tr>
</tbody>
</table>
#### `osPathSubJoin`
`osPathSubJoin` operates like [](#fn_path_gnrc_psubj) but with
OS-specific separators.
The pipeline-friendly equivalent of this is [](#fn_path_os_ppj).
{{- osPathSubJoin "/a/b" "c" }}
{{- osPathSubJoin "/" "a" "b" "c" }}
{{- "c" | osPathSubJoin "/" "a" "b" }}
renders as:
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 66%" />
</colgroup>
<thead>
<tr>
<th style="text-align: center;">OS</th>
<th style="text-align: center;">Result</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><p>Windows</p></td>
<td style="text-align: left;"><pre class="text"><code>\a\b\c
\a\b\c
\a\b\c</code></pre></td>
</tr>
<tr>
<td style="text-align: center;"><p>Others (e.g. Linux, macOS)</p></td>
<td style="text-align: left;"><pre class="text"><code>/a/b/c
/a/b/c
/a/b/c</code></pre></td>
</tr>
</tbody>
</table>
## Strings
### `extIndent`
`extIndent` allows for a MUCH more flexible indenter than the `sprig`
`indent` function.
It works with both Windows (`\r\n`) and POSIX (`\n`) linebreaks.
If `<indentString>` is set to `\n` and `<levels>` is always set to `1`,
this function can even be used to doubelspace text!
It has quite a few arguments, however:
{{ extIndent <levels> <skipFirst> <skipEmpty> <skipWhitespace> <indentString> <input> }}
Where:
- `<levels>`: The level of indentation for the text. If less than or
equal to `0`, `extIndent` just returns `<input>` as-is and NO-OPs
otherwise.
- `<skipFirst>`: If true, skip indenting the first line. This is
particularly handy if you like to visually align your function calls
in your templates.
- `<skipEmpty>`: If true, do not add an indent to **empty** lines
(where an "empty line" means "only has a linebreak").
- `<skipWhitespace>`: If true, do not add an indent to lines that
**only** consist of whitespace (spaces, tabs, etc.) and a linebreak.
- `<indentString>`: The string to use as the "indent character". This
can be any string, such as `" "`, `"\t"`, `"."`, `"|"`, `"=="` etc.
- `<input>`: The text to be indented. Because it is the last argument,
`extIndent` works with pipelined text as well.
## Debugging
### `dump`
The `dump` function calls [the `Sdump`
function](https://pkg.go.dev/github.com/davecgh/go-spew/spew#Sdump) from
[`go-spew`](https://github.com/davecgh/go-spew)
([`github.com/davecgh/go-spew/spew`](https://pkg.go.dev/github.com/davecgh/go-spew/spew))
for whatever object(s) is/are passed to it.

View File

@@ -1,22 +1,48 @@
package sprigx
import (
"path"
"path/filepath"
`os`
`os/user`
`path`
`path/filepath`
`runtime`
`github.com/davecgh/go-spew/spew`
`github.com/shirou/gopsutil/v4/cpu`
`github.com/shirou/gopsutil/v4/disk`
`github.com/shirou/gopsutil/v4/host`
`github.com/shirou/gopsutil/v4/load`
`github.com/shirou/gopsutil/v4/mem`
psnet `github.com/shirou/gopsutil/v4/net`
`github.com/shirou/gopsutil/v4/process`
`github.com/shirou/gopsutil/v4/sensors`
`r00t2.io/sysutils`
)
var (
// genericMap holds functions usable/intended for use in either an [html/template.FuncMap] or [text/template.FuncMap].
genericMap map[string]any = map[string]any{
// Debugging
"dump": dump,
// Strings
"extIndent": extIndent, // PR in: https://github.com/Masterminds/sprig/pull/468
// OS/System
"sysArch": sysArch,
"sysNumCpu": sysNumCpu,
"sysOsName": sysOsNm,
"sysRuntime": sysRuntime,
"dump": spew.Sdump,
/*
"Meta"/Template-Helpers
*/
"metaIsNil": metaIsNil,
/*
OS
*/
"osFQDN": osFQDN,
"osGroupById": osGroupById,
"osGroupByName": user.LookupGroup,
"osHost": osHost,
"osHostname": os.Hostname,
"osIdState": sysutils.GetIDState,
"osUser": user.Current,
"osUserById": osUserById,
"osUserByName": user.Lookup,
/*
Paths
*/
// Paths: Generic
"pathJoin": path.Join,
"pathPipeJoin": pathPipeJoin,
@@ -30,6 +56,70 @@ var (
"osPathSliceJoin": osPathSliceJoin,
"osPathSlicePipeJoin": osPathSlicePipeJoin,
"osPathSubJoin": osPathSubJoin,
/*
PSUtil
(https://pkg.go.dev/github.com/shirou/gopsutil/v4)
*/
// .../cpu
"psCpuCnts": cpu.Counts,
"psCpuInfo": cpu.Info,
"psCpuPct": cpu.Percent,
"psCpuTimes": cpu.Times,
// .../disk
"psDiskIoCnts": disk.IOCounters,
"psDiskLabel": disk.Label,
"psDiskParts": disk.Partitions,
"psDiskSerial": disk.SerialNumber,
"psDiskUsage": disk.Usage,
// .../host
"psHostBoot": host.BootTime,
"psHostId": host.HostID,
"psHostInfo": host.Info,
"psHostKernArch": host.KernelArch,
"psHostKernVer": host.KernelVersion,
"psHostPlatInfo": psHostPlatInfo,
"psHostUptime": host.Uptime,
"psHostUsers": host.Users,
"psHostVirt": psHostVirt,
// .../load
"psLoadAvg": load.Avg,
"psLoadMisc": load.Misc,
// .../mem
"psMemSwap": mem.SwapMemory,
"psMemSwapDevs": mem.SwapDevices,
"psMemVMem": mem.VirtualMemory,
// .../net
"psNetConns": psnet.Connections,
"psNetConnsMax": psnet.ConnectionsMax,
"psNetConnsPid": psnet.ConnectionsPid,
"psNetConnsPidMax": psnet.ConnectionsPidMax,
"psNetCTStats": psnet.ConntrackStats,
"psNetCTStatList": psnet.NewConntrackStatList,
"psNetFilterCnts": psnet.FilterCounters,
"psNetIoCnts": psnet.IOCounters,
"psNetIoCntsFile": psnet.IOCountersByFile,
"psNetIfaces": psnet.Interfaces,
"psNetPids": psnet.Pids,
"psNetProtoCnt": psnet.ProtoCounters,
// .../process
"psProcs": process.Processes,
"psProcNew": process.NewProcess,
"psProcPids": process.Pids,
"psProcPidExists": process.PidExists,
// .../sensors
"psSensorTemps": sensors.SensorsTemperatures,
/*
Strings
*/
"extIndent": extIndent, // PR in: https://github.com/Masterminds/sprig/pull/468
/*
System/Platform
*/
"sysArch": sysArch,
"sysNumCpu": runtime.NumCPU,
"sysOsName": sysOsNm,
"sysRuntime": sysRuntime,
}
// htmlMap holds functions usable/intended for use in only an [html/template.FuncMap].

View File

@@ -0,0 +1,9 @@
//go:build darwin
package sprigx
var (
osGenericMap map[string]any = map[string]any{}
osHtmlMap map[string]any = map[string]any{}
osTxtMap map[string]any = map[string]any{}
)

View File

@@ -0,0 +1,25 @@
//go:build linux
package sprigx
import (
`github.com/shirou/gopsutil/v4/mem`
psnet `github.com/shirou/gopsutil/v4/net`
)
var (
osGenericMap map[string]any = map[string]any{
/*
PSUtil
(https://pkg.go.dev/github.com/shirou/gopsutil/v4)
*/
// .../mem
"psMemExVMem": mem.NewExLinux().VirtualMemory,
// .../net
"psNetRev": psnet.Reverse,
// .../sensors
"psSensorExTemp": psSensorExTemp,
}
osHtmlMap map[string]any = map[string]any{}
osTxtMap map[string]any = map[string]any{}
)

View File

@@ -0,0 +1,9 @@
//go:build !(linux || windows || darwin)
package sprigx
var (
osGenericMap map[string]any = map[string]any{}
osHtmlMap map[string]any = map[string]any{}
osTxtMap map[string]any = map[string]any{}
)

View File

@@ -0,0 +1,24 @@
//go:build windows
package sprigx
import (
`github.com/shirou/gopsutil/v4/mem`
`github.com/shirou/gopsutil/v4/winservices`
)
var (
osGenericMap map[string]any = map[string]any{
/*
PSUtil
(https://pkg.go.dev/github.com/shirou/gopsutil/v4)
*/
// .../mem
"psMemExVMem": mem.NewExWindows().VirtualMemory,
// .../winservices
"psWinsvcList": winservices.ListServices,
"psWinsvcNew": winservices.NewService,
}
osHtmlMap map[string]any = map[string]any{}
osTxtMap map[string]any = map[string]any{}
)

View File

@@ -25,6 +25,11 @@ func FuncMap() (fmap map[string]any) {
for fn, f = range genericMap {
fmap[fn] = f
}
if osGenericMap != nil && len(osGenericMap) > 0 {
for fn, f = range osGenericMap {
fmap[fn] = f
}
}
return
}
@@ -43,6 +48,12 @@ func HtmlFuncMap() (fmap htpl.FuncMap) {
}
}
if osHtmlMap != nil && len(osHtmlMap) > 0 {
for fn, f = range osHtmlMap {
fmap[fn] = f
}
}
return
}
@@ -60,5 +71,11 @@ func TxtFuncMap() (fmap ttpl.FuncMap) {
}
}
if osTxtMap != nil && len(osTxtMap) > 0 {
for fn, f = range osTxtMap {
fmap[fn] = f
}
}
return
}

View File

@@ -1,17 +0,0 @@
package sprigx
import (
`github.com/davecgh/go-spew/spew`
)
/*
dump calls [spew.Sdump] on obj.
[spew.Sdump]: https://pkg.go.dev/github.com/davecgh/go-spew/spew
*/
func dump(obj any) (out string) {
out = spew.Sdump(obj)
return
}

View File

@@ -0,0 +1,14 @@
package sprigx
// Nop explicitly performs a NO-OP and returns an empty string, allowing one to override "unsafe" functions.
func Nop(obj ...any) (s string) {
return
}
// metaIsNil returns true if obj is explicitly nil.
func metaIsNil(obj any) (isNil bool) {
isNil = obj == nil
return
}

View File

@@ -1,13 +1,73 @@
package sprigx
import (
"os"
`os`
`os/user`
`strconv`
`strings`
)
// osHostname returns os.Hostname()
func osHostname() (out string, err error) {
// osGroupById returns os/user.LookupGroupId. Can accept either an integer or a string.
func osGroupById[T string | int](gid T) (g *user.Group, err error) {
out, err = os.Hostname()
var gidStr string
switch t := any(gid).(type) {
case string:
gidStr = t
case int:
gidStr = strconv.Itoa(t)
}
g, err = user.LookupGroupId(gidStr)
return
}
/*
osFQDN (tries to) return the FQDN of this host.
Currently it just calls os.Hostname() but may be extended to "try harder" in the future.
*/
func osFQDN() (fqdn string, err error) {
fqdn, err = os.Hostname()
return
}
/*
osHost returns the system's "host shortname".
Currently it just calls os.Hostname() and takes the first
"host label" (as RFCs refer to it), but it may be extended
in the future.
*/
func osHost() (hostNm string, err error) {
hostNm, err = os.Hostname()
if hostNm == "" {
return
}
hostNm = strings.Split(hostNm, ".")[0]
return
}
// osUserById returns an os/user.LookupId. Can accept either an integer or a string.
func osUserById[T string | int](uid T) (u *user.User, err error) {
var uidStr string
switch t := any(uid).(type) {
case string:
uidStr = t
case int:
uidStr = strconv.Itoa(t)
}
u, err = user.LookupId(uidStr)
return
}

View File

@@ -0,0 +1,43 @@
package sprigx
import (
`github.com/shirou/gopsutil/v4/host`
)
/*
psHostPlatInfo returns a "squashed" github.com/shirou/gopsutil/v4/host.PlatformInformation;
normally it returns a (string, string, string, error)
but you can only have a (any) or (any, error) return in Golang templates.
*/
func psHostPlatInfo() (platInfo [3]string, err error) {
var s1 string
var s2 string
var s3 string
if s1, s2, s3, err = host.PlatformInformation(); err != nil {
return
}
platInfo = [3]string{s1, s2, s3}
return
}
/*
psHostVirt returns a "squared" github.com/shirou/gopsutil/v4/host.Virtualization;
normally it returns a (string, string, error) but Go templates etc.
*/
func psHostVirt() (virtInfo [2]string, err error) {
var s1 string
var s2 string
if s1, s2, err = host.Virtualization(); err != nil {
return
}
virtInfo = [2]string{s1, s2}
return
}

View File

@@ -0,0 +1,15 @@
package sprigx
import (
`context`
`github.com/shirou/gopsutil/v4/sensors`
)
// psSensorExTemp wraps github.com/shirou/gopsutil/v4/sensors.NewExLinux().TemperatureWithContext() to not require a context.
func psSensorExTemp() (exTemps []sensors.ExTemperature, err error) {
exTemps, err = sensors.NewExLinux().TemperatureWithContext(context.Background())
return
}

View File

@@ -5,6 +5,22 @@ import (
`runtime`
)
// sysArch returns [runtime.GOARCH].
func sysArch() (out string) {
out = runtime.GOARCH
return
}
// sysOsNm returns [runtime.GOOS].
func sysOsNm() (out string) {
out = runtime.GOOS
return
}
// sysRuntime returns various information from [runtime].
func sysRuntime() (out map[string]string) {
@@ -21,27 +37,3 @@ func sysRuntime() (out map[string]string) {
return
}
// sysArch returns [runtime.GOARCH].
func sysArch() (out string) {
out = runtime.GOARCH
return
}
// sysNumCpu returns the reuslt from [runtime.NumCPU].
func sysNumCpu() (out string) {
out = fmt.Sprintf("%d", runtime.NumCPU())
return
}
// sysOsNm returns [runtime.GOOS].
func sysOsNm() (out string) {
out = runtime.GOOS
return
}