58556d7281
ADDED: * netx.IsPub * encodingx/hexx Rest are mostly small corrections and docs
2421 lines
69 KiB
Plaintext
2421 lines
69 KiB
Plaintext
= SprigX
|
|
Brent Saner <bts@square-r00t.net>
|
|
Last rendered {localdatetime}
|
|
:doctype: book
|
|
:docinfo: shared
|
|
:data-uri:
|
|
:imagesdir: images
|
|
:sectlinks:
|
|
:sectnums:
|
|
:sectnumlevels: 7
|
|
:toc: preamble
|
|
:toc2: left
|
|
:idprefix:
|
|
:toclevels: 7
|
|
:source-highlighter: rouge
|
|
:docinfo: shared
|
|
// BEGIN variable attributes
|
|
:sprig_ver: 3
|
|
:psutil_ver: 4
|
|
:git_owner: r00t2
|
|
:git_repo: go_goutils
|
|
:git_repo_full: {git_owner}/{git_repo}
|
|
:mod_me: r00t2.io/goutils
|
|
:pkg_me: tplx/sprigx
|
|
:src_root: https://git.r00t2.io
|
|
:godoc_root: https://pkg.go.dev
|
|
:sprig_web: https://masterminds.github.io/sprig
|
|
:mod_sprig: github.com/Masterminds/sprig/v{sprig_ver}
|
|
:mod_psutil: github.com/shirou/gopsutil/v{psutil_ver}
|
|
:import_sprig: {mod_sprig}
|
|
:src_base: {src_root}/{git_repo_full}
|
|
:src_git: {src_base}.git
|
|
:src_tree: {src_base}/src/branch/master
|
|
:src_raw: {src_base}/raw/branch/master
|
|
:src_dir: {src_tree}/{pkg_me}
|
|
:src_dir_raw: {src_raw}/{pkg_me}
|
|
:import_me: {mod_me}/{pkg_me}
|
|
:godoc_me: {godoc_root}/{import_me}
|
|
:godoc_sprig: {godoc_root}/{import_sprig}
|
|
:funcsig_tpl: ./_docs/includes/funcsig.adoc
|
|
// Gorram it AsciiDoc stop snarfing whitespace
|
|
////
|
|
These are only currently used by extIndent and strsxIsAsciiSpcl,
|
|
but there's no way to get rid of the blank lines/extra newlines.
|
|
|
|
If I specify it without the plus, it just renders the tabs in indnt.
|
|
If I specify it without the slash, I can't enxapsulate the newline.
|
|
If I specify the source block in the include without +post_replacements, it leaves the plus signs in.
|
|
If I specifiy it with, it double-spaces the thing.
|
|
Oh well.
|
|
TODO: File a bug for that nonsense.
|
|
////
|
|
:tab: pass:[ ]
|
|
:nl: pass:[ + \
|
|
]
|
|
:indnt: pass:a[{nl}{tab}{tab}]
|
|
// END variable attributes
|
|
|
|
[id="wat"]
|
|
== What is SprigX?
|
|
SprigX is a suite of extensions to {sprig_web}/[the `sprig` library^] ({godoc_sprig}[Go docs^]).
|
|
|
|
They provide functions that offer more enriched use cases and domain-specific data.
|
|
|
|
[TIP]
|
|
====
|
|
If you are reading this README on the Go Module Directory documentation ({godoc_me})
|
|
or the directory landing page ({src_dir}), it may not render correctly.
|
|
Anchor-links (links within this document to other sections of this document) will likely also not work.
|
|
|
|
Be sure to view it at properly via {src_dir}/README.adoc[the in-repo AsciiDoc rendering^]
|
|
or by downloading and viewing the {src_dir_raw}/README.html[HTML version^] in a browser locally
|
|
and/or <<rndr_pdf, rendering a PDF version>>.
|
|
====
|
|
|
|
[id="rndr"]
|
|
== How do I Render These Docs?
|
|
This documentation is written in https://asciidoc.org/[AsciiDoc^] (with https://asciidoctor.org/[AsciiDoctor^] extensions).
|
|
|
|
To re-render all docs (including <<rndr_pdf>>):
|
|
|
|
[source,bash, subs="attributes"]
|
|
----
|
|
git clone {src_git}
|
|
cd {git_repo}
|
|
.githooks/pre-commit/01-docgen
|
|
----
|
|
|
|
[id="rndr_html"]
|
|
=== HTML
|
|
HTML output is re-rendered and included in git {src_dir}/.githooks/pre-commit/01-docgen[on each commit^] automatically (via https://github.com/gabyx/Githooks[`github:gabyx/Githooks`^])
|
|
but can be re-rendered on-demand locally via:
|
|
|
|
[source,bash, subs="attributes"]
|
|
----
|
|
git clone {src_git}
|
|
cd {git_repo}
|
|
export orig_dir="$(pwd)"
|
|
cd {pkg_me}
|
|
asciidoctor -a ROOTDIR="${orig_dir}/" -o README.html README.adoc
|
|
----
|
|
|
|
[id="rndr_pdf"]
|
|
=== PDF
|
|
This documentation can be rendered to PDF via https://docs.asciidoctor.org/pdf-converter/latest/[`asciidoctor-pdf`^].
|
|
It is not included in git automatically because binary files that change on each commit is not a good idea for git,
|
|
especially for a repo that gets cloned as part of a library inclusion in a module/package dependency system (like `gomod`).
|
|
|
|
To render as PDF:
|
|
|
|
[source,bash,subs="attributes"]
|
|
----
|
|
git clone {src_git}
|
|
cd {git_repo}
|
|
export orig_dir="$(pwd)"
|
|
cd {pkg_me}
|
|
asciidoctor-pdf -a ROOTDIR="${orig_dir}/" -o README.pdf README.adoc
|
|
----
|
|
|
|
[id="use"]
|
|
== How do I Use SprigX?
|
|
|
|
The same way you would `sprig`!
|
|
|
|
[%collapsible]
|
|
.Like this.
|
|
====
|
|
[source,go,subs="attributes",opts=novalidate]
|
|
----
|
|
package main
|
|
|
|
import (
|
|
htmlTplLib "html/template"
|
|
txtTplLib "text/template"
|
|
|
|
"{import_me}"
|
|
)
|
|
|
|
var (
|
|
txtTpl *txtTplLib.Template = txtTplLib.
|
|
New("").
|
|
Funcs(
|
|
sprigx.TxtFuncMap(),
|
|
)
|
|
htmlTpl *htmlTplLib.Template = htmlTplLib.
|
|
New("").
|
|
Funcs(
|
|
sprigx.HtmlFuncMap(),
|
|
)
|
|
)
|
|
----
|
|
====
|
|
|
|
They can even be combined/used together,
|
|
|
|
[%collapsible]
|
|
.like this.
|
|
====
|
|
[source,go,subs="attributes",opts=novalidate]
|
|
----
|
|
package main
|
|
|
|
import (
|
|
"text/template"
|
|
|
|
"{import_sprig}"
|
|
"{import_me}"
|
|
)
|
|
|
|
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(),
|
|
)
|
|
*/
|
|
----
|
|
====
|
|
|
|
Or, as a convenience, you can simply use the <<lib_cmbtfmap, `sprigx.CombinedTxtFuncMap`>> and/or <<lib_cmbhfmap, `sprigx.CombinedHtmlFuncMap`>> functions.
|
|
|
|
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`:
|
|
|
|
[%collapsible]
|
|
.this will use `foo` from `sprigx`
|
|
====
|
|
[source,go,subs="attributes",opts=novalidate]
|
|
----
|
|
package main
|
|
|
|
import (
|
|
"text/template"
|
|
|
|
"{import_sprig}"
|
|
"{import_me}"
|
|
)
|
|
|
|
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())
|
|
)
|
|
----
|
|
====
|
|
|
|
[%collapsible]
|
|
.whereas this will use `foo` from `sprig`
|
|
====
|
|
[source,go,subs="attributes",opts=novalidate]
|
|
----
|
|
package main
|
|
|
|
import (
|
|
"text/template"
|
|
|
|
"{import_sprig}"
|
|
"{import_me}"
|
|
)
|
|
|
|
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 [[override]]overridden,
|
|
|
|
[%collapsible]
|
|
.like this.
|
|
====
|
|
This would override a function `foo` and `foo2` in `sprigx` from `foo` and `foo2` from `sprig`, but leave all other `sprig` functions untouched.
|
|
|
|
[source,go,subs="attributes",opts=novalidate]
|
|
----
|
|
package main
|
|
|
|
import (
|
|
"text/template"
|
|
|
|
"{import_sprig}"
|
|
"{import_me}"
|
|
)
|
|
|
|
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"],
|
|
},
|
|
),
|
|
)
|
|
)
|
|
----
|
|
====
|
|
|
|
[id="lib"]
|
|
== Library Functions
|
|
|
|
These are generally intended to be used *outside* the template in the actual Go code.
|
|
|
|
[id="lib_cmbfmap"]
|
|
=== `CombinedFuncMap`
|
|
:func: CombinedFuncMap
|
|
:sig: (preferSprigX bool) (fmap map[string]any)
|
|
include::{funcsig_tpl}[]
|
|
|
|
This function returns a generic function map (like <<lib_fmap>>) combined with
|
|
{godoc_sprig}#GenericFuncMap[`{import_sprig}.GenericFuncMap`^].
|
|
|
|
If `preferSprigx` is true, SprigX function names will override Sprig functions with the same name.
|
|
If false, Sprig functions will override conflicting SprigX functions with the same name.
|
|
|
|
You probably want <<lib_cmbtfmap>> or <<lib_cmbhfmap>> instead,
|
|
as they wrap this with the appropriate type.
|
|
|
|
[id="lib_cmbhfmap"]
|
|
=== `CombinedHtmlFuncMap`
|
|
:func: CombinedHtmlFuncMap
|
|
:sig: (preferSprigX bool) (fmap template.FuncMap)
|
|
include::{funcsig_tpl}[]
|
|
|
|
This function returns an {godoc_root}/html/template#FuncMap[`html/template.FuncMap`] function map (like <<lib_hfmap>>) combined with
|
|
{godoc_sprig}#HtmlFuncMap[`{import_sprig}.HtmlFuncMap`^].
|
|
|
|
If `preferSprigx` is true, SprigX function names will override Sprig functions with the same name.
|
|
If false, Sprig functions will override conflicting SprigX functions with the same name.
|
|
|
|
[id="lib_cmbtfmap"]
|
|
=== `CombinedTxtFuncMap`
|
|
:func: CombinedTxtFuncMap
|
|
:sig: (preferSprigX bool) (fmap template.FuncMap)
|
|
include::{funcsig_tpl}[]
|
|
|
|
This function returns a {godoc_root}/text/template#FuncMap[`text/template.FuncMap`] function map (like <<lib_tfmap>>) combined with
|
|
{godoc_sprig}#TxtFuncMap[`{import_sprig}.TxtFuncMap`^].
|
|
|
|
If `preferSprigx` is true, SprigX function names will override Sprig functions with the same name.
|
|
If false, Sprig functions will override conflicting SprigX functions with the same name.
|
|
|
|
[id="lib_fmap"]
|
|
=== `FuncMap`
|
|
:func: FuncMap
|
|
:sig: () (fmap map[string]any)
|
|
include::{funcsig_tpl}[]
|
|
|
|
This function returns a generic SprigX function map.
|
|
|
|
You probably want <<lib_tfmap>> or <<lib_hfmap>> instead,
|
|
as they wrap this with the appropriate type.
|
|
|
|
[id="lib_hfmap"]
|
|
=== `HtmlFuncMap`
|
|
:func: HtmlFuncMap
|
|
:sig: () (fmap template.FuncMap)
|
|
include::{funcsig_tpl}[]
|
|
|
|
This function returns a SprigX {godoc_root}/html/template#FuncMap[`html/template.FuncMap`^].
|
|
|
|
[id="lib_nop"]
|
|
=== `Nop`
|
|
:func: Nop
|
|
:sig: (obj ...any) (s string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`Nop` is a NO-OP function that one can use in an <<override, override map>> to explicitly disable
|
|
certain Sprig/SprigX functions that may be deemed "unsafe" and/or to sanitize templates from untrusted input.
|
|
|
|
It will *never* error or panic, and `s` is *always* an empty string.
|
|
|
|
[id="lib_tfmap"]
|
|
=== `TxtFuncMap`
|
|
:func: TxtFuncMap
|
|
:sig: () (fmap template.FuncMap)
|
|
include::{funcsig_tpl}[]
|
|
|
|
This function returns a SprigX {godoc_root}/text/template#FuncMap[`text/template.FuncMap`^].
|
|
|
|
[id="fn"]
|
|
== Template Functions
|
|
Expect this list to grow over time, and potentially more frequently than the `sprigx` functions.
|
|
|
|
Each function includes its *_Function Signature_* to indicate what arguments/parameters it accepts, their type(s),
|
|
what it returns, and the returned value(s) type(s).
|
|
|
|
Because Go template functions can only return either:
|
|
|
|
* a single value of any type, or
|
|
* a value of any type and an `error` (in that order)
|
|
|
|
you can easily determine whether a function can return an error or not by simply referring to the Function Signature.
|
|
|
|
[id="fn_dbg"]
|
|
=== Debugging
|
|
|
|
[id="fn_dbg_dump"]
|
|
==== `dump`
|
|
:func: dump
|
|
:sig: (a ...interface{}) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
The `dump` function directly calls {godoc_root}/davecgh/go-spew/spew#Sdump[`github.com/davecgh/go-spew/spew.Sdump`^]
|
|
for whatever object(s) is/are passed to it.
|
|
|
|
[id="fn_meta"]
|
|
=== "Meta"/Template Helpers
|
|
|
|
[id="fn_meta_isnil"]
|
|
==== `metaIsNil`
|
|
:func: metaIsNil
|
|
:sig: (obj any) (isNil bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`metaIsNil` returns `true` if `obj` is explicitly nil, otherwise it returns false.
|
|
|
|
This function fills in the gap that {godoc_root}/text/template#IsTrue[`text/template.IsTrue`^] and {godoc_root}/html/template#IsTrue[`html/template.IsTrue`^] (expressed in templates as `{{ if ... }}`) leaves, as those functions/expressions return false for e.g. `false` booleans AND nils.
|
|
|
|
[id="fn_net_all"]
|
|
=== Networking
|
|
These template functions use capabilities from:
|
|
|
|
* <<fn_net>>
|
|
* <<fn_netip>>
|
|
* <<fn_netipx>>
|
|
* <<fn_netx>>
|
|
* <<fn_dnsx>>
|
|
|
|
The function prefix is used to indicate which module/package a function is added from.
|
|
|
|
[id="fn_net"]
|
|
==== `net`
|
|
These template functions contain capabilities from {godoc_root}/net[`net`^].
|
|
|
|
[id="fn_net_cidrmask"]
|
|
===== `netCidrMask`
|
|
:func: netCidrMask
|
|
:sig: (ones, bits int) (mask net.IPMask)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netCidrMask` directly calls {godoc_root}/net#CIDRMask[`net.CIDRMask`^].
|
|
|
|
[id="fn_net_cidra"]
|
|
===== `netExtractAddr`
|
|
:func: netExtractAddr
|
|
:sig: (s string) (addr net.IP, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netExtractAddr` wraps {godoc_root}/net#ParseCIDR[`net.ParseCIDR`^] and returns the {godoc_root}/net#IP[`net.IP`^] component.
|
|
|
|
[id="fn_net_hph"]
|
|
===== `netExtractHost`
|
|
:func: netExtractHost
|
|
:sig: (hostPort string) (host string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netExtractHost` wraps {godoc_root}/net#SplitHostPort[`net.SplitHostPort`^] and returns the host component (as a string).
|
|
|
|
[id="fn_net_cidrn"]
|
|
===== `netExtractIpnet`
|
|
:func: netExtractIpnet
|
|
:sig: (s string) (ipNet *net.IPNet, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netExtractIpnet` wraps {godoc_root}/net#ParseCIDR[`net.ParseCIDR`^] and returns the {godoc_root}/net#IPNet[`net.IPNet`^] component.
|
|
|
|
[id="fn_net_hpp"]
|
|
===== `netExtractPort`
|
|
:func: netExtractPort
|
|
:sig: (hostPort string) (port uint16, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netExtractPort` wraps {godoc_root}/net#SplitHostPort[`net.SplitHostPort`^] and returns the port component (as a uint16).
|
|
|
|
[id='fn_net_ifaces']
|
|
===== `netIfaces`
|
|
:func: netIfaces
|
|
:sig: () (ifaces []net.Interface, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netIfaces` directly calls {godoc_root}/net#Interfaces[`net.Interfaces`^].
|
|
|
|
[id="fn_net_ip4mask"]
|
|
===== `netIp4Mask`
|
|
:func: netIp4Mask
|
|
:sig: (a, b, c, d any) (mask net.IPMask, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netIp4Mask` wraps {godoc_root}/net#IPv4Mask[`net.IPv4Mask`^].
|
|
|
|
It is wrapped so that `a`, `b`, `c`, and `d` may be a string:
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $mask := netIp4Mask "198" "51" "100" "10" -}}
|
|
----
|
|
|
|
or integers/other numeric:
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $mask := netIp4Mask 198 51 100 10 -}}
|
|
----
|
|
|
|
or bytes:
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $mask := netIp4Mask 0xc6 0x33 0x64 0x0a -}}
|
|
----
|
|
|
|
or even a mix:
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $mask := netIp4Mask "198" 51 "100" 0x0a -}}
|
|
----
|
|
|
|
[id="fn_net_jhp"]
|
|
===== `netJoinHostPort`
|
|
:func: netJoinHostPort
|
|
:sig: (host, port string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netJoinHostPort` directly calls {godoc_root}/net#JoinHostPort[`net.JoinHostPort`^].
|
|
|
|
[id="fn_net_parseip"]
|
|
===== `netParseIP`
|
|
:func: netParseIP
|
|
:sig: (s string) (ip net.IP)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netParseIP` directly calls {godoc_root}/net#ParseIP[`net.ParseIP`^].
|
|
|
|
[id="fn_netip"]
|
|
==== `net/netip`
|
|
These template functions contain capabilities from {godoc_root}/net/netip[`net/netip`^].
|
|
|
|
[id="fn_netip_addrport"]
|
|
===== `netipAddrPort`
|
|
:func: netipAddrPort
|
|
:sig: (ip netip.Addr, port uint16) (addrPort netip.AddrPort)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipAddrPort` directly calls {godoc_root}/net/netip#AddrPortFrom[`net/netip.AddrPortFrom`^].
|
|
|
|
[id="fn_netip_parseaddr"]
|
|
===== `netipParseAddr`
|
|
:func: netipParseAddr
|
|
:sig: (s string) (addr netip.Addr, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipParseAddr` directly calls {godoc_root}/net/netip#ParseAddr[`net/netip.ParseAddr`^].
|
|
|
|
[id="fn_netip_pap"]
|
|
===== `netipParseAddrPort`
|
|
:func: netipParseAddrPort
|
|
:sig: (s string) (addrPort netip.AddrPort, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipParseAddrPort` directly calls {godoc_root}/net/netip#ParseAddrPort[`net/netip.ParseAddrPort`^].
|
|
|
|
[id="fn_netip_parsepfx"]
|
|
===== `netipParsePrefix`
|
|
:func: netipParsePrefix
|
|
:sig: (s string) (pfx netip.Prefix, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipParsePrefix` directly calls {godoc_root}/net/netip#ParsePrefix[`net/netip.ParsePrefix`^].
|
|
|
|
[id="fn_netip_pfx"]
|
|
===== `netipPrefix`
|
|
:func: netipPrefix
|
|
:sig: (ip netip.Addr, bits int) (pfx netip.Prefix)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipPrefix` directly calls {godoc_root}/net/netip#PrefixFrom[`net/netip.PrefixFrom`^].
|
|
|
|
[id="fn_netipx"]
|
|
==== `go4.org/netipx`
|
|
These template functions contain capabilities from {godoc_root}/go4.org/netipx[`go4.org/netipx`^].
|
|
|
|
[id="fn_netipx_addripnet"]
|
|
===== `netipxAddrIpNet`
|
|
:func: netipxAddrIpNet
|
|
:sig: (addr netip.Addr) (ipNet *net.IPNet)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxAddrIpNet` directly calls {godoc_root}/go4.org/netipx#AddrIPNet[`go4.org/netipx.AddrIPNet`^].
|
|
|
|
[id="fn_netipx_cmppfx"]
|
|
===== `netipxCmpPfx`
|
|
:func: netipxCmpPfx
|
|
:sig: (a, b netip.Prefix) (cmp int)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxCmpPfx` directly calls {godoc_root}/go4.org/netipx#ComparePrefix[`go4.org/netipx.ComparePrefix`^].
|
|
|
|
[id="fn_netipx_fromstdaddr"]
|
|
===== `netipxFromStdAddr`
|
|
:func: netipxFromStdAddr
|
|
:sig: (ip net.IP, port int, zone string) (addrPort netip.AddrPort, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxFromStdAddr` wraps {godoc_root}/go4.org/netipx#FromStdAddr[`go4.org/netipx.FromStdAddr`^]. Instead of returning a boolean as the second value, it will instead be an error if the wrapped boolean is false.
|
|
|
|
[id="fn_netipx_fromip"]
|
|
===== `netipxFromIp`
|
|
:func: netipxFromIp
|
|
:sig: (ip net.IP) (addr netip.Addr, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxFromIp` wraps {godoc_root}/go4.org/netipx#FromStdIP[`go4.org/netipx.FromStdIP`^]. Instead of returning a boolean as the second value, it will instead be an error if the wrapped boolean is false.
|
|
|
|
[id="fn_netipx_fromipnet"]
|
|
===== `netipxFromIpNet`
|
|
:func: netipxFromIpNet
|
|
:sig: (ipNet *net.IPNet) (pfx netip.Prefix, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxFromIpNet` wraps {godoc_root}/go4.org/netipx#FromStdIPNet[`go4.org/netipx.FromStdIPNet`^]. Instead of returning a boolean as the second value, it will instead be an error if the wrapped boolean is false.
|
|
|
|
[id="fn_netipx_parserange"]
|
|
===== `netipxParseRange`
|
|
:func: netipxParseRange
|
|
:sig: (s string) (ipRange netipx.IPRange, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxParseRange` directly calls {godoc_root}/go4.org/netipx#ParseIPRange[`go4.org/netipx.ParseIPRange`^].
|
|
|
|
[id="fn_netipx_pfxaddr"]
|
|
===== `netipxPfxAddr`
|
|
:func: netipxPfxAddr
|
|
:sig: (s string) (addr netip.Addr, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxPfxAddr` directly calls {godoc_root}/go4.org/netipx#ParsePrefixOrAddr[`go4.org/netipx.ParsePrefixOrAddr`^].
|
|
|
|
[id="fn_netipx_pfxipnet"]
|
|
===== `netipxPfxIpNet`
|
|
:func: netipxPfxIpNet
|
|
:sig: (pfx netip.Prefix) (ipNet *net.IPNet)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxPfxIpNet` directly calls {godoc_root}/go4.org/netipx#PrefixIPNet[`go4.org/netipx.PrefixIPNet`^].
|
|
|
|
[id="fn_netipx_pfxlast"]
|
|
===== `netipxPfxLast`
|
|
:func: netipxPfxLast
|
|
:sig: (pfx netip.Prefix) (addr netip.Addr)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxPfxLast` directly calls {godoc_root}/go4.org/netipx#PrefixLastIP[`go4.org/netipx.PrefixLastIP`^].
|
|
|
|
[id="fn_netipx_pfxrange"]
|
|
===== `netipxPfxRange`
|
|
:func: netipxPfxRange
|
|
:sig: (pfx netip.Prefix) (ipRange netipx.IPRange)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxPfxRange` directly calls {godoc_root}/go4.org/netipx#RangeOfPrefix[`go4.org/netipx.RangeOfPrefix`^].
|
|
|
|
[id="fn_netipx_range"]
|
|
===== `netipxRange`
|
|
:func: netipxRange
|
|
:sig: (from, to netip.Addr) (ipRange netipx.IPRange)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netipxRange` directly calls {godoc_root}/go4.org/netipx#IPRangeFrom[`go4.org/netipx.IPRangeFrom`^].
|
|
|
|
[id="fn_netx"]
|
|
==== `r00t2.io/goutils/netx`
|
|
These template functions contain capabilities from {godoc_root}/{mod_me}/netx[`{mod_me}/netx`^].
|
|
|
|
[id="fn_netx_addrrfc"]
|
|
===== `netxAddrRfc`
|
|
:func: netxAddrRfc
|
|
:sig: (addr netip.Addr) (rfcStr string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxAddrRfc` directly calls {godoc_root}/{mod_me}/netx#AddrRfc[`{mod_me}/netx.AddrRfc`^].
|
|
|
|
[id="fn_netx_cidr4ipmask"]
|
|
===== `netxAddrRfc`
|
|
:func: netxAddrRfc
|
|
:sig: (cidr uint8) (ipMask net.IPMask, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxCidr4IpMask` directly calls {godoc_root}/{mod_me}/netx#Cidr4ToIPMask[`{mod_me}/netx.Cidr4ToIPMask`^].
|
|
|
|
[id="fn_netx_cidr4mask"]
|
|
===== `netxCidr4Mask`
|
|
:func: netxCidr4Mask
|
|
:sig: (cidr uint8) (mask uint32, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxCidr4IpMask` directly calls {godoc_root}/{mod_me}/netx#Cidr4ToMask[`{mod_me}/netx.Cidr4ToMask`^].
|
|
|
|
[id="fn_netx_cidr4str"]
|
|
===== `netxCidr4Str`
|
|
:func: netxCidr4Str
|
|
:sig: (cidr uint8) (maskStr string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxCidr4Str` directly calls {godoc_root}/{mod_me}/netx#Cidr4ToStr[`{mod_me}/netx.Cidr4ToStr`^].
|
|
|
|
[id="fn_netx_familyver"]
|
|
===== `netxFamilyVer`
|
|
:func: netxFamilyVer
|
|
:sig: (family uint16) (ipVer int)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxFamilyVer` directly calls {godoc_root}/{mod_me}/netx#FamilyToVer[`{mod_me}/netx.FamilyToVer`^].
|
|
|
|
[id="fn_netx_getaddrfam"]
|
|
===== `netxGetAddrFam`
|
|
:func: netxGetAddrFam
|
|
:sig: (addr netip.Addr) (family uint16)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxGetAddrFam` directly calls {godoc_root}/{mod_me}/netx#GetAddrFamily[`{mod_me}/netx.GetAddrFamily`^].
|
|
|
|
[id="fn_netx_getipfam"]
|
|
===== `netxGetIpFam`
|
|
:func: netxGetIpFam
|
|
:sig: (ip net.IP) (family uint16)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxGetIpFam` directly calls {godoc_root}/{mod_me}/netx#GetAddrFamily[`{mod_me}/netx.GetIpFamily`^].
|
|
|
|
[id="fn_netx_iprfc"]
|
|
===== `netxIpRfc`
|
|
:func: netxIpRfc
|
|
:sig: (ip net.IP) (rfcStr string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIpRfc` directly calls {godoc_root}/{mod_me}/netx#IpRfc[`{mod_me}/netx.IpRfc`^].
|
|
|
|
[id="fn_netx_iprfcstr"]
|
|
===== `netxIpRfcStr`
|
|
:func: netxIpRfcStr
|
|
:sig: (s string) (rfcStr string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIpRfcStr` directly calls {godoc_root}/{mod_me}/netx#IpRfcStr[`{mod_me}/netx.IpRfcStr`^].
|
|
|
|
[id="fn_netx_ipstriprfc"]
|
|
===== `netxIpStripRfc`
|
|
:func: netxIpStripRfc
|
|
:sig: (s string) (stripStr string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIpStripRfc` directly calls {godoc_root}/{mod_me}/netx#IpStripRfcStr[`{mod_me}/netx.IpStripRfcStr`^].
|
|
|
|
[id="fn_netx_ip4maskcidr"]
|
|
===== `netxIp4MaskCidr`
|
|
:func: netxIp4MaskCidr
|
|
:sig: (ipMask net.IPMask) (cidr uint8, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIp4MaskCidr` directly calls {godoc_root}/{mod_me}/netx#IPMask4ToCidr[`{mod_me}/netx.IPMask4ToCidr`^].
|
|
|
|
[id="fn_netx_ip4maskmask"]
|
|
===== `netxIp4MaskMask`
|
|
:func: netxIp4MaskMask
|
|
:sig: (ipMask net.IPMask) (mask uint32, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIp4MaskMask` directly calls {godoc_root}/{mod_me}/netx#IPMask4ToMask[`{mod_me}/netx.IPMask4ToMask`^].
|
|
|
|
[id="fn_netx_ip4maskstr"]
|
|
===== `netxIp4MaskStr`
|
|
:func: netxIp4MaskStr
|
|
:sig: (ipMask net.IPMask) (maskStr string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIp4MaskStr` directly calls {godoc_root}/{mod_me}/netx#IPMask4ToStr[`{mod_me}/netx.IPMask4ToStr`^].
|
|
|
|
[id="fn_netx_ipverstr"]
|
|
===== `netxIpVerStr`
|
|
:func: netxIpVerStr
|
|
:sig: (s string) (ipVer int)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIpVerStr` directly calls {godoc_root}/{mod_me}/netx#IpVerStr[`{mod_me}/netx.IpVerStr`^].
|
|
|
|
[id="fn_netx_isbrktd6"]
|
|
===== `netxIsBrktd6`
|
|
:func: netxIsBrktd6
|
|
:sig: (s string) (isBrktdIp bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIsBrktd6` directly calls {godoc_root}/{mod_me}/netx#IsBracketedIp6[`{mod_me}/netx.IsBracketedIp6`^].
|
|
|
|
[id="fn_netx_isip"]
|
|
===== `netxIsIp`
|
|
:func: netxIsIp
|
|
:sig: (s string) (isIp bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIsIp` directly calls {godoc_root}/{mod_me}/netx#IsIpAddr[`{mod_me}/netx.IsIpAddr`^].
|
|
|
|
[id="fn_netx_ispfx"]
|
|
===== `netxIsPfx`
|
|
:func: netxIsPfx
|
|
:sig: (s string) (isNet bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxIsPfx` directly calls {godoc_root}/{mod_me}/netx#IsPrefixNet[`{mod_me}/netx.IsPrefixNet`^].
|
|
|
|
[id="fn_netx_mask4cidr"]
|
|
===== `netxMask4Cidr`
|
|
:func: netxMask4Cidr
|
|
:sig: (mask uint32) (cidr uint8, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxMask4Cidr` directly calls {godoc_root}/{mod_me}/netx#Mask4ToCidr[`{mod_me}/netx.Mask4ToCidr`^].
|
|
|
|
[id="fn_netx_mask4Strcidr"]
|
|
===== `netxMask4StrCidr`
|
|
:func: netxMask4StrCidr
|
|
:sig: (maskStr string) (cidr uint8, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxMask4StrCidr` directly calls {godoc_root}/{mod_me}/netx#Mask4StrToCidr[`{mod_me}/netx.Mask4StrToCidr`^].
|
|
|
|
[id="fn_netx_mask4stripmask"]
|
|
===== `netxMask4StrIpMask`
|
|
:func: netxMask4StrIpMask
|
|
:sig: (maskStr string) (mask net.IPMask, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxMask4StrIpMask` directly calls {godoc_root}/{mod_me}/netx#Mask4StrToIPMask[`{mod_me}/netx.Mask4StrToIPMask`^].
|
|
|
|
[id="fn_netx_mask4strmask"]
|
|
===== `netxMask4StrMask`
|
|
:func: netxMask4StrMask
|
|
:sig: (maskStr string) (mask uint32, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxMask4StrMask` directly calls {godoc_root}/{mod_me}/netx#Mask4StrToMask[`{mod_me}/netx.Mask4StrToMask`^].
|
|
|
|
[id="fn_netx_ver2fam"]
|
|
===== `netxVerFamily`
|
|
:func: netxVerFamily
|
|
:sig: (ipVer int) (family uint16)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`netxVerFamily` directly calls {godoc_root}/{mod_me}/netx#VerToFamily[`{mod_me}/netx.VerToFamily`^].
|
|
|
|
[id="fn_dnsx"]
|
|
==== `r00t2.io/goutils/netx/dnsx`
|
|
These template functions contain capabilities from {godoc_root}/{import_me}/netx/dnsx[`{import_me}/netx/dnsx`^].
|
|
|
|
[id="fn_dnsx_ptraddr"]
|
|
===== `dnsxPtrAddr`
|
|
:func: dnsxPtrAddr
|
|
:sig: (s string) (ip netip.Addr, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxPtrAddr` directly calls {godoc_root}/{import_me}/netx/dnsx#AddrFromPtr[`{import_me}/netx/dnsx.AddrFromPtr`^].
|
|
|
|
[id="fn_dnsx_addrptr"]
|
|
===== `dnsxAddrPtr`
|
|
:func: dnsxAddrPtr
|
|
:sig: (ip netip.Addr) (s string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxAddrPtr` directly calls {godoc_root}/{import_me}/netx/dnsx#AddrToPtr[`{import_me}/netx/dnsx.AddrToPtr`^].
|
|
|
|
[id="fn_dnsx_str2wire"]
|
|
===== `dnsxStrWire`
|
|
:func: dnsxStrWire
|
|
:sig: (recordNm string) (recordNmBytes []byte, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxStrWire` directly calls {godoc_root}/{import_me}/netx/dnsx#DnsStrToWire[`{import_me}/netx/dnsx.DnsStrToWire`^].
|
|
|
|
[id="fn_dnsx_wire2str"]
|
|
===== `dnsxWireStr`
|
|
:func: dnsxWireStr
|
|
:sig: (recordNmBytes []byte) (recordNm string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxWireStr` directly calls {godoc_root}/{import_me}/netx/dnsx#DnsWireToStr[`{import_me}/netx/dnsx.DnsWireToStr`^].
|
|
|
|
[id="fn_dnsx_ptrip"]
|
|
===== `dnsxPtrIp`
|
|
:func: dnsxPtrIp
|
|
:sig: (s string) (ip net.IP, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxPtrIp` directly calls {godoc_root}/{import_me}/netx/dnsx#IpFromPtr[`{import_me}/netx/dnsx.IpFromPtr`^].
|
|
|
|
[id="fn_dnsx_ipptr"]
|
|
===== `dnsxIpPtr`
|
|
:func: dnsxIpPtr
|
|
:sig: (ip net.IP) (s string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIpPtr` directly calls {godoc_root}/{import_me}/netx/dnsx#IpToPtr[`{import_me}/netx/dnsx.IpToPtr`^].
|
|
|
|
[id="fn_dnsx_isfqdn"]
|
|
===== `dnsxIsFqdn`
|
|
:func: dnsxIsFqdn
|
|
:sig: (s string) (fqdn bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIsFqdn` directly calls {godoc_root}/{import_me}/netx/dnsx#IsFqdn[`{import_me}/netx/dnsx.IsFqdn`^].
|
|
|
|
[id="fn_dnsx_istxt"]
|
|
===== `dnsxIsTxt`
|
|
:func: dnsxIsTxt
|
|
:sig: (fqdn string) (isOk bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIsTxt` directly calls {godoc_root}/{import_me}/netx/dnsx#IsFqdnDefinedTxt[`{import_me}/netx/dnsx.IsFqdnDefinedTxt`^].
|
|
|
|
[id="fn_dnsx_isnsec3"]
|
|
===== `dnsxIsNsec3`
|
|
:func: dnsxIsNsec3
|
|
:sig: (s string) (maybeNsec3 bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIsNsec3` directly calls {godoc_root}/{import_me}/netx/dnsx#IsFqdnNsec3[`{import_me}/netx/dnsx.IsFqdnNsec3`^].
|
|
|
|
[id="fn_dnsx_issrv"]
|
|
===== `dnsxIsSrv`
|
|
:func: dnsxIsSrv
|
|
:sig: (s string) (srv bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIsSrv` directly calls {godoc_root}/{import_me}/netx/dnsx#IsFqdnSrv[`{import_me}/netx/dnsx.IsFqdnSrv`^].
|
|
|
|
[id="fn_dnsx_iswild"]
|
|
===== `dnsxIsWild`
|
|
:func: dnsxIsWild
|
|
:sig: (s string) (wildcard bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIsWild` directly calls {godoc_root}/{import_me}/netx/dnsx#IsFqdnWildcard[`{import_me}/netx/dnsx.IsFqdnWildcard`^].
|
|
|
|
[id="fn_dnsx_islbl"]
|
|
===== `dnsxIsLbl`
|
|
:func: dnsxIsLbl
|
|
:sig: (s string) (isLbl bool)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIsLbl` directly calls {godoc_root}/{import_me}/netx/dnsx#IsLabel[`{import_me}/netx/dnsx.IsLabel`^].
|
|
|
|
[id="fn_dnsx_isptr"]
|
|
===== `dnsxIsPtr`
|
|
:func: dnsxIsPtr
|
|
:sig: (s string) (isPtr bool, addr net.IP)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`dnsxIsPtr` directly calls {godoc_root}/{import_me}/netx/dnsx#IsPtr[`{import_me}/netx/dnsx.IsPtr`^].
|
|
|
|
[id="fn_num"]
|
|
=== Numbers/Math
|
|
|
|
[id="fn_num_f32s"]
|
|
==== `numFloat32Str`
|
|
:func: numFloat32Str
|
|
:sig: (f float32) (s string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`numFloat32Str` returns a *complete* non-truncated non-right-padded string representation of a `float32`.
|
|
|
|
[id="fn_num_f64"]
|
|
==== `numFloat64`
|
|
:func: numFloat64
|
|
:sig: (val any) (f float64, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`numFloat64` returns any string representation of a numeric value or any type of numeric value to a `float64`.
|
|
|
|
[id="fn_num_f64s"]
|
|
==== `numFloat64Str`
|
|
:func: numFloat64Str
|
|
:sig: (f float64) (s string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`numFloat64Str` returns a *complete* non-truncated non-right-padded string representation of a `float64`.
|
|
|
|
[id="fn_num_fs"]
|
|
==== `numFloatStr`
|
|
:func: numFloatStr
|
|
:sig: (val any) (s string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`numFloatStr` wraps <<fn_num_f32s>> and <<fn_num_f64s>>.
|
|
|
|
`val` can be a string representation of any numeric value or any type of numeric value.
|
|
|
|
[id="fn_os"]
|
|
=== Operating System
|
|
|
|
[id="fn_os_fqdn"]
|
|
==== `osFQDN`
|
|
:func: osFQDN
|
|
:sig: () (fqdn string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osFQDN` currently just directly calls {godoc_root}/os#Hostname[`os.Hostname`^].
|
|
|
|
As such, it comes with the same caveats -- namely that it isn't guaranteed to be
|
|
an FQDN, it will be precisely/exactly whatever the kernel/OS hostname is set as.
|
|
|
|
In the future, it may be extended to support a more diligent effort to determine
|
|
an actual FQDN, and return an error if it is unable to be derived.
|
|
|
|
To (relatively) predictably get the "short hostname", use <<fn_os_hst>>.
|
|
To directly/predictably use {godoc_root}/os#Hostname[`os.Hostname`^], use <<fn_os_hstnm>>.
|
|
|
|
[id="fn_os_grpid"]
|
|
==== `osGroupById`
|
|
:func: osGroupById
|
|
:sig: [T string | int](gid T) (g *user.Group, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osGroupById` returns an {godoc_root}/os/user#Group[`os/user.Group`^] from a given group ID/GID.
|
|
|
|
It more or less behaves exactly like {godoc_root}/os/user#LookupGroupId[`os/user.LookupGroupId`^],
|
|
except it will accept either a `string` *or* an `int` as the GID.
|
|
|
|
[id="fn_os_grpnm"]
|
|
==== `osGroupByName`
|
|
:func: osGroupByName
|
|
:sig: (grpNm string) (g *user.Group, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osGroupByName` returns an {godoc_root}/os/user#Group[`os/user.Group`^] from a given group name.
|
|
|
|
It behaves exactly like {godoc_root}/os/user#LookupGroup[`os/user.LookupGroup`^].
|
|
|
|
[id="fn_os_hst"]
|
|
==== `osHost`
|
|
:func: osHost
|
|
:sig: () (out string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osHost` returns the "short hostname" by calling {godoc_root}/os#Hostname[`os.Hostname`^]
|
|
and returning the first "host label" (as RFCs refer to it). This is commonly/colloquially called the "hostname" or "hostname without the domain part".
|
|
|
|
e.g.:
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $fqdn := osFQDN -}}
|
|
{{- $h := osHost -}}
|
|
{{- $cmp := index ($fqdn | splitList ".") 0 -}}
|
|
osHost {{ $h }} should be equal to first label of FQDN {{ $cmp }}.
|
|
----
|
|
|
|
[TIP]
|
|
====
|
|
The `splitList` function shown above is from the {sprig_web}/string_slice.html[`sprig` string slice functions^].
|
|
====
|
|
|
|
To (try to) get the FQDN, use <<fn_os_fqdn>>.
|
|
To directly use {godoc_root}/os#Hostname[`os.Hostname`^], use <<fn_os_hstnm>>.
|
|
|
|
[id="fn_os_hstnm"]
|
|
==== `osHostname`
|
|
:func: osHostname
|
|
:sig: () (out string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osHostname` directly calls {godoc_root}/os#Hostname[`os.Hostname`^].
|
|
|
|
[id="fn_os_idst"]
|
|
==== `osIdState`
|
|
:func: osIdState
|
|
:sig: () (idst sysutils.IDState)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osIdState` returns the current runtime process' {godoc_root}/r00t2.io/sysutils#IDState[`r00t2.io/sysutils.IDState`^].
|
|
|
|
It directly calls {godoc_root}/r00t2.io/sysutils#GetIDState[`r00t2.io/sysutils.GetIDState`^].
|
|
|
|
[WARNING]
|
|
====
|
|
This is more or less useless on Windows; it returns only a dummy struct for cross-platform compatibility.
|
|
====
|
|
|
|
[id="fn_os_usr"]
|
|
==== `osUser`
|
|
:func: osUser
|
|
:sig: () (u *user.User, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osUser` returns the current runtime process' {godoc_root}/os/user#User[`os/user.User`^].
|
|
|
|
It directly calls {godoc_root}/os/user#Current[`os/user.Current`^].
|
|
|
|
[id="fn_os_usrid"]
|
|
==== `osUserById`
|
|
:func: osUserById
|
|
:sig: [T string | int](uid T) (u *user.User, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osUserById` returns an {godoc_root}/os/user#User[`os/user.User`^] from a given user ID/UID.
|
|
|
|
It more or less behaves exactly like {godoc_root}/os/user#LookupId[`os/user.LookupId`^],
|
|
except it will accept either a `string` *or* an `int` as the UID.
|
|
|
|
[id="fn_os_usrnm"]
|
|
==== `osUserByName`
|
|
:func: osUserByName
|
|
:sig: (userNm string) (u *user.User, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osUserByName` returns an {godoc_root}/os/user#User[`os/user.User`^] from a given username.
|
|
|
|
It directly calls {godoc_root}/os/user#Lookup[`os/user.Lookup`^].
|
|
|
|
[id="fn_path"]
|
|
=== Paths
|
|
|
|
[id="fn_path_gnrc"]
|
|
==== Generic
|
|
These operate similar to {godoc_root}/path[the `path` stdlib library^] and use a fixed `/` path separator.
|
|
|
|
[id="fn_path_gnrc_pj"]
|
|
===== `pathJoin`
|
|
:func: pathJoin
|
|
:sig: (elem ...string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`pathJoin` directly calls {godoc_root}/path#Join[`path.Join`^].
|
|
|
|
[WARNING]
|
|
====
|
|
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.
|
|
====
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- pathJoin "a" "b" "c" }}
|
|
{{- pathJoin "/" "a" "b" "c" }}
|
|
{{- pathJoin "/a/b" "c" }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[source,text]
|
|
----
|
|
a/b/c
|
|
/a/b/c
|
|
/a/b/c
|
|
----
|
|
|
|
[id="fn_path_gnrc_ppj"]
|
|
===== `pathPipeJoin`
|
|
:func: pathPipeJoin
|
|
:sig: (elems ...string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`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.
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $myBase := "/a" -}}
|
|
{{- pathPipeJoin "b" "c" "a" }}
|
|
{{- pathPipeJoin "a" "b" "c" "/" }}
|
|
{{- $myBase | pathPipeJoin "b" "c" }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[source,text]
|
|
----
|
|
a/b/c
|
|
/a/b/c
|
|
/a/b/c
|
|
----
|
|
|
|
[id="fn_path_gnrc_psj"]
|
|
===== `pathSliceJoin`
|
|
:func: pathSliceJoin
|
|
:sig: (sl []string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`pathSliceJoin` joins a slice of path segment strings (`[]string`) instead of a variadic sequence of strings.
|
|
|
|
[TIP]
|
|
====
|
|
The `splitList` function shown below is from the {sprig_web}/string_slice.html[`sprig` string slice functions^].
|
|
====
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $myList := "a,b,c" | splitList "," -}}
|
|
{{- $myList | pathSliceJoin }}
|
|
{{- ("a,b,c" | splitList ",") | pathSliceJoin }}
|
|
{{- ("/,a,b,c" | splitList ",") | pathSliceJoin }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[source,text]
|
|
----
|
|
a/b/c
|
|
a/b/c
|
|
/a/b/c
|
|
----
|
|
|
|
[id="fn_path_gnrc_pspj"]
|
|
===== `pathSlicePipeJoin`
|
|
:func: pathSlicePipeJoin
|
|
:sig: (sl []string, root string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`pathSlicePipeJoin` operates like a hybrid of <<fn_path_gnrc_ppj>> and <<fn_path_gnrc_psj>>:
|
|
|
|
* Like <<fn_path_gnrc_ppj>>, it is suitable for pipeline use -- the root/base path is passed in from the pipeline
|
|
* Like <<fn_path_gnrc_psj>>, it *also* accepts a slice of path segments (`[]string`) to append to that base path
|
|
|
|
[TIP]
|
|
====
|
|
The `splitList` function shown below is from the {sprig_web}/string_slice.html[`sprig` string slice functions^].
|
|
====
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $myBase := "/a" -}}
|
|
{{- $myList := "b,c,d" | splitList "." -}}
|
|
{{- pathSlicePipeJoin $myList $myBase }}
|
|
{{- $myBase | pathSlicePipeJoin $myList }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[source,text]
|
|
----
|
|
/a/b/c
|
|
/a/b/c
|
|
----
|
|
|
|
[id="fn_path_gnrc_psubj"]
|
|
===== `pathSubJoin`
|
|
:func: pathSubJoin
|
|
:sig: (root string, elems ...string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`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>>.
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- pathSubJoin "/a/b" "c" }}
|
|
{{- pathSubJoin "/" "a" "b" "c" }}
|
|
{{- "c" | pathSubJoin "/" "a" "b" }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[source,text]
|
|
----
|
|
/a/b/c
|
|
/a/b/c
|
|
/a/b/c
|
|
----
|
|
|
|
[id="fn_path_os"]
|
|
==== OS/Platform-Tailored
|
|
These operate similar to {godoc_root}/path/filepath[the `path/filepath` stdlib library^], and use the OS-specific {godoc_root}/os#PathSeparator[`os.PathSeparator`^].
|
|
|
|
[WARNING]
|
|
====
|
|
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.
|
|
====
|
|
|
|
[id="fn_path_os_pj"]
|
|
===== `osPathJoin`
|
|
:func: osPathJoin
|
|
:sig: (elem ...string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osPathJoin` directly calls {godoc_root}/path/filepath#Join[`path/filepath.Join`^].
|
|
|
|
[WARNING]
|
|
====
|
|
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.
|
|
====
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- osPathJoin "a" "b" "c" }}
|
|
{{- osPathJoin "/" "a" "b" "c" }}
|
|
{{- osPathJoin "C:\\" "a" "b" "c" }}
|
|
{{- osPathJoin "C:" "a" "b" "c" }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[cols="^.^2,.^4a",options="header"]
|
|
|===
|
|
| OS ^| Result
|
|
|
|
| Windows | [source,text]
|
|
----
|
|
a\b\c
|
|
\a\b\c
|
|
\a\b\c
|
|
C:\a\b\c
|
|
C:a\b\c
|
|
----
|
|
| Others (e.g. Linux, macOS) | [source,text]
|
|
----
|
|
a/b/c
|
|
/a/b/c
|
|
C:\/a/b/c
|
|
C:/a/b/c
|
|
----
|
|
|===
|
|
|
|
[id="fn_path_os_ppj"]
|
|
===== `osPathPipeJoin`
|
|
:func: osPathJoin
|
|
:sig: (elems ...string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`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 argument to the next pipe function.
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $myBase := "/a" -}}
|
|
{{- osPathPipeJoin "b" "c" "a" }}
|
|
{{- osPathPipeJoin "a" "b" "c" "/" }}
|
|
{{- $myBase | osPathPipeJoin "b" "c" }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[cols="^.^2,.^4a",options="header"]
|
|
|===
|
|
| OS ^| Result
|
|
|
|
| Windows | [source,text]
|
|
----
|
|
a\b\c
|
|
\a\b\c
|
|
\a\b\c
|
|
----
|
|
| Others (e.g. Linux, macOS) | [source,text]
|
|
----
|
|
a/b/c
|
|
/a/b/c
|
|
/a/b/c
|
|
----
|
|
|===
|
|
|
|
[id="fn_path_ossep"]
|
|
===== `osPathSep`
|
|
:func: osPathSep
|
|
:sig: () (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osPathSep` returns the {godoc_root}/os#PathSeparator[`os.PathSeparator`^] for this OS.
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- osPathSep }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[cols="^.^2,.^4a",options="header"]
|
|
|===
|
|
| OS ^| Result
|
|
|
|
| Windows | [source,text]
|
|
----
|
|
\
|
|
----
|
|
| Others (e.g. Linux, macOS) | [source,text]
|
|
----
|
|
/
|
|
----
|
|
|===
|
|
|
|
[id="fn_path_os_psj"]
|
|
===== `osPathSliceJoin`
|
|
:func: osPathSliceJoin
|
|
:sig: (sl []string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osPathSliceJoin` operates like <<fn_path_gnrc_psj>> but with OS-specific path separators.
|
|
|
|
[TIP]
|
|
====
|
|
The `splitList` function shown below is from the {sprig_web}/string_slice.html[`sprig` string slice functions^].
|
|
====
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $myList := "a,b,c" | splitList "," -}}
|
|
{{- $myList | osPathSliceJoin }}
|
|
{{- ("a,b,c" | splitList ",") | osPathSliceJoin }}
|
|
{{- ("/,a,b,c" | splitList ",") | osPathSliceJoin }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[cols="^.^2,.^4a",options="header"]
|
|
|===
|
|
| OS ^| Result
|
|
|
|
| Windows | [source,text]
|
|
----
|
|
a\b\c
|
|
a\b\c
|
|
\a\b\c
|
|
----
|
|
| Others (e.g. Linux, macOS) | [source,text]
|
|
----
|
|
a/b/c
|
|
a/b/c
|
|
/a/b/c
|
|
----
|
|
|===
|
|
|
|
[id="fn_path_os_pspj"]
|
|
===== `osPathSlicePipeJoin`
|
|
:func: osPathSlicePipeJoin
|
|
:sig: (sl []string, root string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osPathSlicePipeJoin` operates like <<fn_path_gnrc_pspj>> but with OS-specific separators.
|
|
|
|
[TIP]
|
|
====
|
|
The `splitList` function shown below is from the {sprig_web}/string_slice.html[`sprig` string slice functions^].
|
|
====
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $myBase := "/a" -}}
|
|
{{- $myList := "b,c,d" | splitList "." -}}
|
|
{{- osPathSlicePipeJoin $myList $myBase }}
|
|
{{- $myBase | osPathSlicePipeJoin $myList }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[cols="^.^2,.^4a",options="header"]
|
|
|===
|
|
| OS ^| Result
|
|
|
|
| Windows | [source,text]
|
|
----
|
|
\a\b\c\d
|
|
\a\b\c\d
|
|
----
|
|
| Others (e.g. Linux, macOS) | [source,text]
|
|
----
|
|
/a/b/c/d
|
|
/a/b/c/d
|
|
----
|
|
|===
|
|
|
|
[id="fn_path_os_psubj"]
|
|
===== `osPathSubJoin`
|
|
:func: osPathSubJoin
|
|
:sig: (root string, elems ...string) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`osPathSubJoin` operates like <<fn_path_gnrc_psubj>> but with OS-specific separators.
|
|
|
|
The pipeline-friendly equivalent of this is <<fn_path_os_ppj>>.
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- osPathSubJoin "/a/b" "c" }}
|
|
{{- osPathSubJoin "/" "a" "b" "c" }}
|
|
{{- "c" | osPathSubJoin "/" "a" "b" }}
|
|
----
|
|
|
|
renders as:
|
|
|
|
[cols="^.^2,.^4a",options="header"]
|
|
|===
|
|
| OS ^| Result
|
|
|
|
| Windows | [source,text]
|
|
----
|
|
\a\b\c
|
|
\a\b\c
|
|
\a\b\c
|
|
----
|
|
| Others (e.g. Linux, macOS) | [source,text]
|
|
----
|
|
/a/b/c
|
|
/a/b/c
|
|
/a/b/c
|
|
----
|
|
|===
|
|
|
|
[id="fn_ps"]
|
|
=== PSUtil
|
|
These are functions from {godoc_root}/{mod_psutil}[`{mod_psutil}`^] packages.
|
|
|
|
[id="fn_ps_cpu"]
|
|
==== CPU/Processor
|
|
|
|
[id="fn_ps_cpu_cnts"]
|
|
===== `psCpuCnts`
|
|
:func: psCpuCnts
|
|
:sig: (logical bool) (numCpu int, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psCpuCnts` directly calls {godoc_root}/{mod_psutil}/cpu#Counts[`{mod_psutil}/cpu.Counts`^].
|
|
|
|
[id="fn_ps_cpu_info"]
|
|
===== `psCpuInfo`
|
|
:func: psCpuInfo
|
|
:sig: () (cpuInfo []cpu.Info, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psCpuInfo` directly calls {godoc_root}/{mod_psutil}/cpu#Info[`{mod_psutil}/cpu.Info`^].
|
|
|
|
[id="fn_ps_cpu_pct"]
|
|
===== `psCpuPct`
|
|
:func: psCpuPct
|
|
:sig: (interval time.Duration, percpu bool) (pcts []float64, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psCpuPct` directly calls {godoc_root}/{mod_psutil}/cpu#Percent[`{mod_psutil}/cpu.Percent`^].
|
|
|
|
[id="fn_ps_cpu_tms"]
|
|
===== `psCpuTimes`
|
|
:func: psCpuTimes
|
|
:sig: (percpu bool) (cpuTimes []cpu.TimesStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psCpuTimes` directly calls {godoc_root}/{mod_psutil}/cpu#Times[`{mod_psutil}/cpu.Times`^].
|
|
|
|
[id="fn_ps_dsk"]
|
|
==== Disk
|
|
|
|
[id="fn_ps_dsk_iocnts"]
|
|
===== `psDiskIoCnts`
|
|
:func: psDiskIoCnts
|
|
:sig: (names ...string) (stats map[string]disk.IOCountersStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psDiskIoCnts` directly calls {godoc_root}/{mod_psutil}/disk#IOCounters[`{mod_psutil}/disk.IOCounters`^].
|
|
|
|
[id="fn_ps_dsk_lbl"]
|
|
===== `psDiskLabel`
|
|
:func: psDiskLabel
|
|
:sig: (name string) (label string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psDiskLabel` directly calls {godoc_root}/{mod_psutil}/disk#Label[`{mod_psutil}/disk.Label`^].
|
|
|
|
[id="fn_ps_dsk_parts"]
|
|
===== `psDiskParts`
|
|
:func: psDiskParts
|
|
:sig: (all bool) (parts []disk.PartitionStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psDiskParts` directly calls {godoc_root}/{mod_psutil}/disk#Partitions[`{mod_psutil}/disk.Partitions`^].
|
|
|
|
[id="fn_ps_dsk_srl"]
|
|
===== `psDiskSerial`
|
|
:func: psDiskSerial
|
|
:sig: (name string) (serial string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psDiskSerial` directly calls {godoc_root}/{mod_psutil}/disk#SerialNumber[`{mod_psutil}/disk.SerialNumber`^].
|
|
|
|
[id="fn_ps_dsk_usg"]
|
|
===== `psDiskUsage`
|
|
:func: psDiskUsage
|
|
:sig: (path string) (usage *disk.UsageStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psDiskUsage` directly calls {godoc_root}/{mod_psutil}/disk#Usage[`{mod_psutil}/disk.Usage`^].
|
|
|
|
[id="fn_ps_hst"]
|
|
==== Host
|
|
|
|
[id="fn_ps_hst_boot"]
|
|
===== `psHostBoot`
|
|
:func: psHostBoot
|
|
:sig: () (bootEpoch uint64, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostBoot` directly calls {godoc_root}/{mod_psutil}/host#BootTime[`{mod_psutil}/host.BootTime`^].
|
|
|
|
[id="fn_ps_hst_id"]
|
|
===== `psHostId`
|
|
:func: psHostId
|
|
:sig: () (hostId string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostId` directly calls {godoc_root}/{mod_psutil}/host#HostID[`{mod_psutil}/host.HostID`^].
|
|
|
|
[id="fn_ps_hst_info"]
|
|
===== `psHostInfo`
|
|
:func: psHostInfo
|
|
:sig: () (info *host.InfoStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostInfo` directly calls {godoc_root}/{mod_psutil}/host#Info[`{mod_psutil}/host.Info`^].
|
|
|
|
[id="fn_ps_hst_krnarch"]
|
|
===== `psHostKernArch`
|
|
:func: psHostKernArch
|
|
:sig: () (arch string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostKernArch` directly calls {godoc_root}/{mod_psutil}/host#KernelArch[`{mod_psutil}/host.KernelArch`^].
|
|
|
|
[id="fn_ps_hst_krnver"]
|
|
===== `psHostKernVer`
|
|
:func: psHostKernVer
|
|
:sig: () (ver string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostKernVer` directly calls {godoc_root}/{mod_psutil}/host#KernelVersion[`{mod_psutil}/host.KernelVersion`^].
|
|
|
|
[id="fn_ps_hst_plat"]
|
|
===== `psHostPlatInfo`
|
|
:func: psHostPlatInfo
|
|
:sig: () (platInfo [3]string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostPlatInfo` wraps {godoc_root}/{mod_psutil}/host#PlatformInformation[`{mod_psutil}/host.PlatformInformation`^].
|
|
|
|
It is necessary to wrap because the function normally returns `(string, string, string, error)` but a template function may only return either a single value (of any type) or a single value of any type and an error, so the three `string` returns are consolidated into an ordered `[3]string`.
|
|
|
|
[id="fn_ps_hst_uptm"]
|
|
===== `psHostPlatUptime`
|
|
:func: psHostPlatUptime
|
|
:sig: () (uptimeSecs uint64, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostPlatUptime` directly calls {godoc_root}/{mod_psutil}/host#Uptime[`{mod_psutil}/host.Uptime`^].
|
|
|
|
[id="fn_ps_hst_usrs"]
|
|
===== `psHostUsers`
|
|
:func: psHostUsers
|
|
:sig: () (users []host.UserStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostUsers` directly calls {godoc_root}/{mod_psutil}/host#Users[`{mod_psutil}/host.Users`^].
|
|
|
|
[id="fn_ps_hst_virt"]
|
|
===== `psHostPlatVirt`
|
|
:func: psHostPlatVirt
|
|
:sig: () (virtInfo [2]string, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psHostPlatVirt` wraps {godoc_root}/{mod_psutil}/host#Virtualization[`{mod_psutil}/host.Virtualization`^].
|
|
|
|
It is necessary to wrap because the function normally returns `(string, string, error)` but a template function may only return either a single value (of any type) or a single value of any type and an error, so the two `string` returns are consolidated into an ordered `[2]string`.
|
|
|
|
[id="fn_ps_ld"]
|
|
==== Load
|
|
|
|
[id="fn_ps_ld_avg"]
|
|
===== `psLoadAvg`
|
|
:func: psLoadAvg
|
|
:sig: () (avg *load.AvgStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psLoadAvg` directly calls {godoc_root}/{mod_psutil}/load#Avg[`{mod_psutil}/load.Avg`^].
|
|
|
|
[id="fn_ps_ld_misc"]
|
|
===== `psLoadMisc`
|
|
:func: psLoadMisc
|
|
:sig: () (misc *load.MiscStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psLoadMisc` directly calls {godoc_root}/{mod_psutil}/load#Misc[`{mod_psutil}/load.Misc`^].
|
|
|
|
[id="fn_ps_mem"]
|
|
==== Memory
|
|
|
|
[id="fn_ps_mem_exvmem"]
|
|
===== `psMemExVMem`
|
|
:func: psMemExVMem
|
|
:sig: () (exVMem *mem.ExVirtualMemory, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
[WARNING]
|
|
====
|
|
This function is available on Windows and Linux platforms *only*.
|
|
====
|
|
|
|
[WARNING]
|
|
====
|
|
This function returns very different types depending on platform.
|
|
|
|
* Linux: {godoc_root}/{mod_psutil}/mem?GOOS=linux#ExVirtualMemory[`mem.ExVirtualMemory`^]
|
|
* Windows: {godoc_root}/{mod_psutil}/mem?GOOS=windows#ExVirtualMemory[`mem.ExVirtualMemory`^]
|
|
====
|
|
|
|
This function wraps link:{godoc_root}/{mod_psutil}/mem?GOOS=linux#NewExLinux[`{mod_psutil}/mem.NewExLinux`^].link:{godoc_root}/{mod_psutil}/mem?GOOS=linux#ExLinux.VirtualMemory[`VirtualMemory`^] on Linux and
|
|
link:{godoc_root}/{mod_psutil}/mem?GOOS=windows#NewExWindows[`{mod_psutil}/mem.NewExWindows`^].link:{godoc_root}/{mod_psutil}/mem?GOOS=windows#ExWindows.VirtualMemory[`VirtualMemory`^] on Windows.
|
|
|
|
[id="fn_ps_mem_swap"]
|
|
===== `psMemSwap`
|
|
:func: psMemSwap
|
|
:sig: () (swap *mem.SwapMemoryStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psMemSwap` directly calls {godoc_root}/{mod_psutil}/mem#SwapMemory[`{mod_psutil}/mem.SwapMemory`^].
|
|
|
|
[id="fn_ps_mem_swapdevs"]
|
|
===== `psMemSwapDevs`
|
|
:func: psMemSwapDevs
|
|
:sig: () (swapDevs []*mem.SwapDevice, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psMemSwapDevs` directly calls {godoc_root}/{mod_psutil}/mem#SwapDevices[`{mod_psutil}/mem.SwapDevices`^].
|
|
|
|
[id="fn_ps_mem_vmem"]
|
|
===== `psMemVMem`
|
|
:func: psMemVMem
|
|
:sig: () (vmem *mem.VirtualMemoryStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psMemVMem` directly calls {godoc_root}/{mod_psutil}/mem#VirtualMemory[`{mod_psutil}/mem.VirtualMemory`^].
|
|
|
|
[id="fn_ps_net"]
|
|
==== Network
|
|
|
|
[id="fn_ps_net_conns"]
|
|
===== `psNetConns`
|
|
:func: psNetConns
|
|
:sig: (kind string) (conns []net.ConnectionStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetConns` directly calls {godoc_root}/{mod_psutil}/net#Connections[`{mod_psutil}/net.Connections`^].
|
|
|
|
[id="fn_ps_net_connsmax"]
|
|
===== `psNetConnsMax`
|
|
:func: psNetConnsMax
|
|
:sig: (kind string, maxConn int) (conns []net.ConnectionStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetConnsMax` directly calls {godoc_root}/{mod_psutil}/net#ConnectionsMax[`{mod_psutil}/net.ConnectionsMax`^].
|
|
|
|
[id="fn_ps_net_connspid"]
|
|
===== `psNetConnsPid`
|
|
:func: psNetConnsPid
|
|
:sig: (kind string, pid int32) (conns []net.ConnectionStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetConnsPid` directly calls {godoc_root}/{mod_psutil}/net#ConnectionsPid[`{mod_psutil}/net.ConnectionsPid`^].
|
|
|
|
[id="fn_ps_net_connspidmax"]
|
|
===== `psNetConnsPidMax`
|
|
:func: psNetConnsPidMax
|
|
:sig: (kind string, pid int32, maxConn int) (conns []net.ConnectionStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetConnsPidMax` directly calls {godoc_root}/{mod_psutil}/net#ConnectionsPidMax[`{mod_psutil}/net.ConnectionsPidMax`^].
|
|
|
|
[id="fn_ps_net_ct"]
|
|
===== `psNetCTStats`
|
|
:func: psNetCTStats
|
|
:sig: (percCpu bool) (ctStats []net.ConntrackStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetCTStats` directly calls {godoc_root}/{mod_psutil}/net#ConntrackStats[`{mod_psutil}/net.ConntrackStats`^].
|
|
|
|
[id="fn_ps_net_ctlist"]
|
|
===== `psNetCTStatList`
|
|
:func: psNetCTStatList
|
|
:sig: () (ctStats *net.ConntrackStatList, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetCTStatList` directly calls {godoc_root}/{mod_psutil}/net#ConntrackStatList[`{mod_psutil}/net.ConntrackStatList`^].
|
|
|
|
[id="fn_ps_net_fltcnt"]
|
|
===== `psNetFilterCnts`
|
|
:func: psNetFilterCnts
|
|
:sig: () (filterCnts []net.FilterStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetFilterCnts` directly calls {godoc_root}/{mod_psutil}/net#FilterCounters[`{mod_psutil}/net.FilterCounters`^].
|
|
|
|
[id="fn_ps_net_iocnts"]
|
|
===== `psNetIoCnts`
|
|
:func: psNetIoCnts
|
|
:sig: (perNIC bool) (ioCnts []net.IOCountersStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetIoCnts` directly calls {godoc_root}/{mod_psutil}/net#IOCounters[`{mod_psutil}/net.IOCounters`^].
|
|
|
|
[id="fn_ps_net_iocntsfl"]
|
|
===== `psNetIoCntsFile`
|
|
:func: psNetIoCntsFile
|
|
:sig: (perNIC bool, filepath string) (ioCnts []net.IOCountersStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetIoCntsFile` directly calls {godoc_root}/{mod_psutil}/net#IOCountersByFile[`{mod_psutil}/net.IOCountersByFile`^].
|
|
|
|
[id="fn_ps_net_ifaces"]
|
|
===== `psNetIfaces`
|
|
:func: psNetIfaces
|
|
:sig: () (ioCnts []net.InterfaceStatList, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetIfaces` directly calls {godoc_root}/{mod_psutil}/net#Interfaces[`{mod_psutil}/net.Interfaces`^].
|
|
|
|
[id="fn_ps_net_pids"]
|
|
===== `psNetPids`
|
|
:func: psNetPids
|
|
:sig: () (pids []int32, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psNetPids` directly calls {godoc_root}/{mod_psutil}/net#Pids[`{mod_psutil}/net.Pids`^].
|
|
|
|
[id="fn_ps_net_protocnts"]
|
|
===== `psNetProtoCnt`
|
|
:func: psNetProtoCnt
|
|
:sig: (protos []string) (protoCnts []net.ProtoCountersStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
[WARNING]
|
|
====
|
|
This only works properly on Linux currently per upstream.
|
|
====
|
|
|
|
`psNetProtoCnt` directly calls {godoc_root}/{mod_psutil}/net#ProtoCounters[`{mod_psutil}/net.ProtoCounters`^].
|
|
|
|
[id="fn_ps_net_rev"]
|
|
===== `psNetRev`
|
|
:func: psNetRev
|
|
:sig: (b []byte) (out []byte)
|
|
include::{funcsig_tpl}[]
|
|
|
|
[WARNING]
|
|
====
|
|
This function only exists on Linux.
|
|
====
|
|
|
|
`psNetRev` directly calls {godoc_root}/{mod_psutil}/net?GOOS=linux#Reverse[`{mod_psutil}/net.Reverse`^].
|
|
|
|
[id="fn_ps_proc"]
|
|
==== Processes
|
|
|
|
[id="fn_ps_procs_procs"]
|
|
===== `psProcs`
|
|
:func: psProcs
|
|
:sig: (pid int32) (procs []*process.Process, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psProcs` directly calls {godoc_root}/{mod_psutil}/process#Processes[`{mod_psutil}/proc.Processes`^].
|
|
|
|
[id="fn_ps_proc_new"]
|
|
===== `psProcNew`
|
|
:func: psProcNew
|
|
:sig: (pid int32) (proc *process.Process, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psProcNew` directly calls {godoc_root}/{mod_psutil}/process#NewProcess[`{mod_psutil}/proc.NewProcess`^].
|
|
|
|
[id="fn_ps_proc_pids"]
|
|
===== `psProcPids`
|
|
:func: psProcPids
|
|
:sig: () (pids []int32, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psProcPids` directly calls {godoc_root}/{mod_psutil}/process#Pids[`{mod_psutil}/proc.Pids`^].
|
|
|
|
[id="fn_ps_proc_pidxst"]
|
|
===== `psProcPidExists`
|
|
:func: psProcPidExists
|
|
:sig: (pid int32) (exists bool, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psProcPidExists` directly calls {godoc_root}/{mod_psutil}/process#PidExists[`{mod_psutil}/proc.PidExists`^].
|
|
|
|
[id="fn_ps_sns"]
|
|
==== Sensors/Thermals
|
|
|
|
[id="fn_ps_sns_extemp"]
|
|
===== `psSensorExTemp`
|
|
:func: psSensorExTemp
|
|
:sig: () (temps []sensors.ExTemperature, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
[WARNING]
|
|
====
|
|
This function only exists on Linux.
|
|
====
|
|
|
|
`psSensorExTemp` wraps link:{godoc_root}/{mod_psutil}/sensors?GOOS=linux#NewExLinux[`{mod_psutil}/sensors.NewExLinux`^].link:{godoc_root}/{mod_psutil}/sensors?GOOS=linux#TemperatureWithContext[`{mod_psutil}/sensors.TemperatureWithContext`^].
|
|
|
|
[id="fn_ps_sns_temps"]
|
|
===== `psSensorTemps`
|
|
:func: psSensorTemps
|
|
:sig: () (temps []sensors.TemperatureStat, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`psSensorTemps` directly calls {godoc_root}/{mod_psutil}/sensors#SensorsTemperatures[`{mod_psutil}/sensors.SensorsTemperatures`^].
|
|
|
|
[id="fn_ps_winsvc"]
|
|
==== Windows Services
|
|
|
|
[WARNING]
|
|
====
|
|
All of these functions are only available on Windows.
|
|
====
|
|
|
|
[id="fn_ps_winsvc_list"]
|
|
===== `psWinsvcList`
|
|
:func: psWinsvcList
|
|
:sig: () (svcs []winservices.Service, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
[WARNING]
|
|
====
|
|
This function is only available on Windows.
|
|
====
|
|
|
|
`psWinsvcList` directly calls {godoc_root}/{mod_psutil}/winservices?GOOS=windows#ListServices[`{mod_psutil}/winservices.ListServices`^].
|
|
|
|
[id="fn_ps_winsvc_new"]
|
|
===== `psWinsvcNew`
|
|
:func: psWinsvcNew
|
|
:sig: (svcName string) (svc *winservices.Service, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
[WARNING]
|
|
====
|
|
This function is only available on Windows.
|
|
====
|
|
|
|
`psWinsvcNew` directly calls {godoc_root}/{mod_psutil}/winservices?GOOS=windows#NewService[`{mod_psutil}/winservices.NewService`^].
|
|
|
|
[id="fn_str"]
|
|
=== Strings
|
|
|
|
These template functions use capabilities from:
|
|
|
|
* <<fn_str_stnd>>
|
|
* <<fn_str_strsx>>
|
|
|
|
[id="fn_str_stnd"]
|
|
==== Standalone
|
|
|
|
These functions are standalone developed purely for this library.
|
|
For legacy reasons, these have the special prefix `ext`.
|
|
|
|
[id="fn_str_stnd_extindent"]
|
|
===== `extIndent`
|
|
:func: extIndent
|
|
:sig: ({indnt}levels int,{indnt}skipFirst, skipEmpty, skipWhitespace bool,{indnt}indentString, input string,{nl}) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`extIndent` allows for a MUCH more flexible indenter than the `sprig` `indent` function.
|
|
|
|
It works with both Windows (`\r\n`) and POSIX (`\n`) linebreaks.
|
|
|
|
[TIP]
|
|
====
|
|
If `<indentString>` is set to `\n` and `<levels>` is always set to `1`, this function can even be used to doublespace text!
|
|
====
|
|
|
|
It has quite a few arguments, however:
|
|
|
|
[cols="^.^1m,^.^1m,.^4a",options="header"]
|
|
|===
|
|
| Argument ^| Type | Description
|
|
|
|
| levels | int | 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 | bool | If true, skip indenting the first line. This is particularly handy if you like to visually align your function calls in your templates.
|
|
| skipEmpty | bool | If true, do not add an indent to *empty* lines (where an "empty line" means "only has a linebreak").
|
|
| skipWhitespace | bool | If true, do not add an indent to lines that *only* consist of whitespace (spaces, tabs, etc.) and a linebreak.
|
|
| indentString | string | The string to use as the "indent character". This can be any string, such as `"<SP>"` (https://asciiref.dev/#c32[`0x20`^]), `"\t"`, `"."`, `"\|"`, `"=="` etc.
|
|
| input | string | The text to be indented. Because it is the last argument, `extIndent` works with pipelined text as well.
|
|
|===
|
|
|
|
[id="fn_str_strsx"]
|
|
==== `r00t2.io/goutils/stringsx`
|
|
These template functions contain capabilities from {godoc_root}/{mod_me}/netx[`{mod_me}/stringsx`^].
|
|
|
|
[id="fn_str_strsx_isascii"]
|
|
===== `strsxIsAscii`
|
|
:func: strsxIsAscii
|
|
:sig: (s string, allowCtl, allowExt bool) (isAscii bool, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxIsAscii` directly calls {godoc_root}/{import_me}/stringsx#IsAscii[`{import_me}/stringsx.IsAscii`^].
|
|
|
|
[id="fn_str_strsx_isasciibuf"]
|
|
===== `strsxIsAsciiBuf`
|
|
:func: strsxIsAsciiBuf
|
|
:sig: (r io.RuneReader, allowCtl, allowExt bool) (isAscii bool, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxIsAsciiBuf` directly calls {godoc_root}/{import_me}/stringsx#IsAsciiBuf[`{import_me}/stringsx.IsAsciiBuf`^].
|
|
|
|
[id="fn_str_strsx_isasciispcl"]
|
|
===== `strsxIsAsciiSpcl`
|
|
:func: strsxIsAsciiSpcl
|
|
:sig: ({indnt}s string,{indnt}allowCtl, allowPrint, allowExt, allowWs bool,{indnt}incl, excl []byte{nl}) (isAscii bool, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxIsAsciiSpcl` directly calls {godoc_root}/{import_me}/stringsx#IsAsciiSpecial[`{import_me}/stringsx.IsAsciiSpecial`^].
|
|
|
|
[id="fn_str_strsx_isasciibufspcl"]
|
|
===== `strsxIsAsciiBufSpcl`
|
|
:func: strsxIsAsciiBufSpcl
|
|
:sig: ({indnt}r io.RuneReader,{indnt}allowCtl, allowPrint, allowExt, allowWs bool,{indnt}incl, excl []byte{nl}) (isAscii bool, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxIsAsciiBufSpcl` directly calls {godoc_root}/{import_me}/stringsx#IsAsciiSpecial[`{import_me}/stringsx.IsAsciiSpecial`^].
|
|
|
|
[id="fn_str_strsx_lenspl"]
|
|
===== `strsxLenSpl`
|
|
:func: strsxLenSpl
|
|
:sig: (s string, width uint) (out []string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxLenSpl` directly calls {godoc_root}/{import_me}/stringsx#LenSplit[`{import_me}/stringsx.LenSplit`^].
|
|
|
|
[id="fn_str_strsx_lensplstr"]
|
|
===== `strsxLenSplStr`
|
|
:func: strsxLenSplStr
|
|
:sig: (s string, width uint, winNewline bool) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxLenSplStr` directly calls {godoc_root}/{import_me}/stringsx#LenSplitStr[`{import_me}/stringsx.LenSplitStr`^].
|
|
|
|
[id="fn_str_strsx_pad"]
|
|
===== `strsxPad`
|
|
:func: strsxPad
|
|
:sig: (s []string, width uint, pad string, leftPad bool) (out []string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxPad` directly calls {godoc_root}/{import_me}/stringsx#Pad[`{import_me}/stringsx.Pad`^].
|
|
|
|
[id="fn_str_strsx_rdct"]
|
|
===== `strsxRedact`
|
|
:func: strsxRedact
|
|
:sig: (s, maskStr string, leading, trailing uint, newlines bool) (redacted string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxRedact` directly calls {godoc_root}/{import_me}/stringsx#Redact[`{import_me}/stringsx.Redact`^].
|
|
|
|
[id="fn_str_strsx_rev"]
|
|
===== `strsxRev`
|
|
:func: strsxRev
|
|
:sig: (s string) (revS string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxRev` directly calls {godoc_root}/{import_me}/stringsx#Reverse[`{import_me}/stringsx.Reverse`^].
|
|
|
|
[id="fn_str_strsx_trimlns"]
|
|
===== `strsxTrimLns`
|
|
:func: strsxTrimLns
|
|
:sig: (s string, left, right bool) (trimmed string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxTrimLns` directly calls {godoc_root}/{import_me}/stringsx#TrimLines[`{import_me}/stringsx.TrimLines`^].
|
|
|
|
[id="fn_str_strsx_trimspcl"]
|
|
===== `strsxTrimSpcLft`
|
|
:func: strsxTrimSpcLft
|
|
:sig: (s string) (trimmed string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxTrimSpcLft` directly calls {godoc_root}/{import_me}/stringsx#TrimSpaceLeft[`{import_me}/stringsx.TrimSpaceLeft`^].
|
|
|
|
[id="fn_str_strsx_trimspcr"]
|
|
===== `strsxTrimSpcRt`
|
|
:func: strsxTrimSpcRt
|
|
:sig: (s string) (trimmed string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`strsxTrimSpcRt` directly calls {godoc_root}/{import_me}/stringsx#TrimSpaceRight[`{import_me}/stringsx.TrimSpaceRight`^].
|
|
|
|
[id="fn_sys"]
|
|
=== System/Platform/Architecture
|
|
|
|
[id="fn_sys_arch"]
|
|
==== `sysArch`
|
|
:func: sysArch
|
|
:sig: () (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
Returns the {godoc_root}/runtime#GOARCH[`runtime.GOARCH`^] constant.
|
|
|
|
[id="fn_sys_numcpu"]
|
|
==== `sysNumCpu`
|
|
:func: sysNumCpu
|
|
:sig: () (cnt int)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`sysNumCpu` directly calls {godoc_root}/runtime#NumCPU[`runtime.NumCPU`^].
|
|
|
|
[id="fn_sys_os"]
|
|
==== `sysOsName`
|
|
:func: sysOsName
|
|
:sig: () (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
Returns the {godoc_root}/runtime#GOOS[`runtime.GOOS`^] constant.
|
|
|
|
[id="fn_sys_rntm"]
|
|
==== `sysRuntime`
|
|
:func: sysRuntime
|
|
:sig: () (out map[string]string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
This function returns a `map[string]string` of various information from the {godoc_root}/runtime[`runtime` stdlib library^].
|
|
|
|
Specifically, the following are returned.
|
|
|
|
[TIP]
|
|
====
|
|
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_web}/conversion.html[Sprig conversion functions^] if necessary.
|
|
====
|
|
|
|
.`sysRuntime` Values
|
|
[cols="^.^3m,^.^3",options="header"]
|
|
|===
|
|
| Key | Value Type
|
|
|
|
| compiler | {godoc_root}/runtime#Compiler[string^]
|
|
| arch | {godoc_root}/runtime#GOARCH[string^]
|
|
| os | {godoc_root}/runtime#GOOS[string^]
|
|
| maxprocs | {godoc_root}/runtime#GOMAXPROCS[int^] footnote:[For safety concerns, `sprigx` does not allow *setting* `GOMAXPROCS`, this value only contains the *current* `GOMAXPROCS` value.]
|
|
| cpu_cnt | {godoc_root}/runtime#NumCPU[int^]
|
|
| num_cgo | {godoc_root}/runtime#NumCgoCall[int^]
|
|
| num_go | {godoc_root}/runtime#NumGoroutine[int^]
|
|
| go_ver | {godoc_root}/runtime#Version[string^]
|
|
|===
|
|
|
|
As a convenience, some of these values also have their own dedicated functions as well:
|
|
|
|
* <<fn_sys_arch>>
|
|
* <<fn_sys_numcpu>>
|
|
* <<fn_sys_os>>
|
|
|
|
[id="fn_tm"]
|
|
=== Time/Dates/Timestamps
|
|
|
|
[NOTE]
|
|
====
|
|
Some of these functions duplicate Sprig functionality, but are included here for predictable API.
|
|
|
|
Care has been taken to name these functions differently from the Sprig functions where possible and sensible.
|
|
====
|
|
|
|
[id="fn_tm_date"]
|
|
==== `tmDate`
|
|
:func: tmDate
|
|
:sig: (year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) (date time.Time)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmDate` directly calls {godoc_root}/time#Date[`time.Date`^].
|
|
|
|
[id="fn_tm_fltmic"]
|
|
==== `tmFloatMicro`
|
|
:func: tmFloatMicro
|
|
:sig: (t time.Time) (f64 float64)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmFloatMicro` directly calls {godoc_root}/r00t2.io/goutils/timex#F64Microseconds[`(r00t2.io/goutils/timex).F64Microseconds`^].
|
|
|
|
[id="fn_tm_fltmill"]
|
|
==== `tmFloatMilli`
|
|
:func: tmFloatMilli
|
|
:sig: (t time.Time) (f64 float64)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmFloatMilli` directly calls {godoc_root}/r00t2.io/goutils/timex#F64Milliseconds[`(r00t2.io/goutils/timex).F64Milliseconds`^].
|
|
|
|
[id="fn_tm_fltnano"]
|
|
==== `tmFloatNano`
|
|
:func: tmFloatNano
|
|
:sig: (t time.Time) (f64 float64)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmFloatNano` directly calls {godoc_root}/r00t2.io/goutils/timex#F64Nanoseconds[`(r00t2.io/goutils/timex).F64Nanoseconds`^].
|
|
|
|
[id="fn_tm_flt"]
|
|
==== `tmFloat`
|
|
:func: tmFloat
|
|
:sig: (t time.Time) (f64 float64)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmFloat` directly calls {godoc_root}/r00t2.io/goutils/timex#F64Seconds[`(r00t2.io/goutils/timex).F64Seconds`^].
|
|
|
|
[id="fn_tm_fmt"]
|
|
==== `tmFmt`
|
|
:func: tmFmt
|
|
:sig: (fstr string, t time.Time) (out string)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmFormat` provides a more pipeline-friendly alternative to calling e.g.
|
|
|
|
[source,gotemplate]
|
|
----
|
|
{{- $t := tmNow -}}
|
|
{{ $t.Format "<some time format string>" }}
|
|
----
|
|
|
|
[id="fn_tm_now"]
|
|
==== `tmNow`
|
|
:func: tmNow
|
|
:sig: () (now time.Time)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmNow` directly calls {godoc_root}/time#Now[`time.Now`^].
|
|
|
|
[id="fn_tm_pdur8n"]
|
|
==== `tmParseDur8n`
|
|
:func: tmParseDur8n
|
|
:sig: (s string) (d time.Duration, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmParseDur8n` directly calls {godoc_root}/time#ParseDuration[`time.ParseDuration`^].
|
|
|
|
[id="fn_tm_pmnth"]
|
|
==== `tmParseMonth`
|
|
:func: tmParseMonth
|
|
:sig: (v any) (mon time.Month, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmParseMonth` attempts to first try <<fn_tm_pmnthi>> and then tries <<fn_tm_pmnths>> if `v` is not "numeric".
|
|
|
|
[id="fn_tm_pmnthi"]
|
|
==== `tmParseMonthInt`
|
|
:func: tmParseMonthInt
|
|
:sig: (n any) (mon time.Month, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmParseMonthInt` parses a number representation of month `n` to a {godoc_root}/time#Month[`time.Month`^].
|
|
`n` may be any numeric type or a string representation of a number (or a custom type derived from those).
|
|
|
|
A negative integer (or float, etc.) will be converted to a positive one (e.g. `-6` -> `6` -> `time.June`).
|
|
|
|
Floats are rounded to the nearest integer.
|
|
|
|
The integer should map directly to the {godoc_root}/time#example-Month[`time.Month` constants^] in the `time` module:
|
|
|
|
* `1`: `time.January`
|
|
* `2`: `time.February`
|
|
* `3`: `time.March`
|
|
* `4`: `time.April`
|
|
* `5`: `time.May`
|
|
* `6`: `time.June`
|
|
* `7`: `time.July`
|
|
* `8`: `time.August`
|
|
* `9`: `time.September`
|
|
* `10`: `time.October`
|
|
* `11`: `time.November`
|
|
* `12`: `time.December`
|
|
|
|
If `n` resolves to `0`, `mon` will be the current month (as determined by {godoc_root}/time#Now[`time.Now`^]).
|
|
|
|
If `n` resolves to > `12`, `err` will be `sprigx.ErrBadMonth` (though be sure to use {godoc_root}/errors#Is[`errors.Is`^]; it will be wrapped by link:{godoc_root}/text/template#ExecError[`(text/template).ExecError`]/link:{godoc_root}/html/template#ExecError[`(html/template).ExecError`].
|
|
|
|
[id="fn_tm_pmnths"]
|
|
==== `tmParseMonthStr`
|
|
:func: tmParseMonthStr
|
|
:sig: (s string) (mon time.Month, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmParseMonthStr` parses a string representation `s` of a month to a {godoc_root}/time#Month[`time.Month`^].
|
|
|
|
It normalizes `s` to lowercase and only uses the first 3 characters (the minimum length needed to determine month name
|
|
uniqueness - "June" vs. "July", "March" vs. "May").
|
|
|
|
An empty (or whitespace-only) string will use the current month (as determined by {godoc_root}/time#Now[`time.Now`^]).
|
|
|
|
[id="fn_tm_ptm"]
|
|
==== `tmParseTime`
|
|
:func: tmParseTime
|
|
:sig: (layout, value string) (t time.Time, err error)
|
|
include::{funcsig_tpl}[]
|
|
|
|
`tmParseTime` directly calls {godoc_root}/time#Parse[`time.Parse`^].
|
|
|
|
Be sure that `layout` is a properly parseable {godoc_root}/time#Layout[layout format^].
|
|
|
|
[id="todo"]
|
|
== TODO/Wishlist
|
|
|
|
[id="todo_collctns"]
|
|
=== Function Collections
|
|
Functions should be split into more granular function maps that allows a conusmer to only load a certain subset of relevant functions to reduce surface - string functions, network functions, etc.
|
|
|
|
This would ideally also allow for e.g. FuncMap "generators" that would return a FuncMap of methods bound to a struct with certain contextual settings (e.g. a root path restriction for <<todo_os>>).
|
|
|
|
[id="todo_fallible"]
|
|
=== Fallibility
|
|
Requires <<todo_collctns>> first.
|
|
|
|
Modeled after Vector's VRL concept of https://vector.dev/docs/reference/vrl/#fallibility[_Fallibility_^] (https://vector.dev/docs/reference/vrl/expressions/#function-fallibility[see also^]).
|
|
|
|
Functions should be grouped/selectable by "fallibility" - if they are guaranteed to return a *meaningful* value always, if they are guaranteed to return a value that *may be empty* but no error will be returned, or if a function *may* return an error.
|
|
|
|
[id="todo_safe"]
|
|
=== Function Scope Segregation
|
|
Requires <<todo_collctns>> first.
|
|
|
|
Modeled (slightly) after Vector's VRL concept of https://vector.dev/docs/reference/vrl/expressions/#purity[purity^].
|
|
|
|
As more functions get added (and even with the present function set), it may be desired that only functions that work only with provided data are exposed to templates.
|
|
|
|
The goal is to scope/separate functions in such a way that they are "tagged" with multiple attributes/characteristics:
|
|
|
|
* <<todo_fallible>>
|
|
* External Read (e.g. <<todo_os_fs, reading arbitrary files>>)
|
|
* Internal Modify (would potentially transform source data/data structures)
|
|
* External Modify (would affect the invoking system, e.g. <<todo_os_fs>>)
|
|
* Arbitrary Execution (e.g. `osExec` -- see <<todo_os_fs>>)
|
|
* Network Access (e.g. would involve creating network connections instead of operating on provided data locally)
|
|
|
|
A risk "score" from 1-10 should also be implemented with the above scopes/classes for further/alternative filtering by consumers.
|
|
|
|
[id="todo_os"]
|
|
=== Extend OS functions
|
|
Requires <<todo_safe>> first. (Not technically, but can provide a pretty big risk of not split out first.)
|
|
|
|
[id="todo_os_fs"]
|
|
Adding the ability to read files from the filesystem should be added. As part of this, however, a package-level variable should be implemented
|
|
(or <<todo_collctns>>) that can restrict reading to a specific prefix.
|
|
|
|
Off the top of my head:
|
|
|
|
* `osReadFile`
|
|
** Returns an `*os.File`.
|
|
** Closing the handler gets tricky, though... it can be done from within the template, but templates also have no `defer` to my knowledge. Caveat emptor.
|
|
* `osReadFileBuf`
|
|
** Will return a `*bytes.Buffer` with the contents of a file.
|
|
** A little safer than `osReadFile` as it's backed by a static set of bytes and doesn't need to be ``.Close()``'d.
|
|
* `osReadFileBytes`
|
|
** Should include an optional length limiter, so data from e.g. `/dev/urandom` can be read from.
|
|
* `osReadFileStr`
|
|
** Would return `string` instead of `[]byte`.
|
|
* `osReadDir`
|
|
** Returns a `[]fs.DirEntry` of a given path via `os.ReadDir`.
|
|
* `osStat`
|
|
** Returns an `fs.FileInfo` from an `os.Stat` or `os.LStat` (controlled by tpl function parameter)
|
|
* `osExec`
|
|
** Exactly what you'd think. Returns a command via an `os/exec.Cmd`, with params passed to `os/exec.Command` (plus ``*bytes.Buffer``s set to `<exec.Cmd>.Stdin` and `<exec.Cmd>.Stdout`).
|
|
|
|
These obviously have the potential to be *incredibly* dangerous if using untrusted template strings.
|
|
|
|
[id="todo_os_env"]
|
|
==== Environment Variables
|
|
|
|
* `osEnvGet` (`os.Getenv`)
|
|
* `osEnvs` (returns `os.Environ` result)
|
|
* `osEnvsMap` and other https://pkg.go.dev/r00t2.io/sysutils/envs[`r00t2.io/sysutils/envs`^] funcs
|
|
|
|
[id="todo_sys"]
|
|
=== System Functions
|
|
This would be... particularly tricky.
|
|
|
|
I essentially want to expose a large amount of functionality from https://pkg.go.dev/golang.org/x/sys/unix[`golang.org/x/sys/unix`^] and https://pkg.go.dev/golang.org/x/sys@v0.46.0/windows[`golang.org/x/sys/windows`^]
|
|
(and its https://pkg.go.dev/golang.org/x/sys@v0.46.0/windows#section-directories[subpackages^]).
|
|
|
|
At the least I should have a way to (attempt to) convert/coerce an `fs.FileInfo.Sys()` into the platform-appropriate definite object
|
|
(e.g. a https://pkg.go.dev/golang.org/x/sys/unix#Stat_t[`golang.org/x/sys/unix.Stat_t`^] and/or
|
|
https://pkg.go.dev/golang.org/x/sys/unix#Statx_t[`golang.org/x/sys/unix.Statx_t`^],
|
|
or a https://pkg.go.dev/golang.org/x/sys/windows#Win32FileAttributeData[`golang.org/x/sys/windows.Win32FileAttributeData`^]).
|
|
|
|
[id="todo_encode"]
|
|
=== Encoding Functions
|
|
Should require <<todo_collctns>> first (at least for grouping).
|
|
|
|
* `hex*` functions ({godoc_root}/encoding/hex[`encoding/hex`^])
|
|
** Technically hex is "base16"
|
|
* `hexx*` functions ({godoc_root}/r00t2.io/goutils/encodingx/hexx[`r00t2.io/goutils/encodingx/hexx`^])
|
|
* `b64*` functions ({godoc_root}/encoding/base64[`encoding/base64`^])
|
|
|
|
[id="todo_uuid"]
|
|
=== UUID Functions
|
|
Should require <<todo_collctns>> first (at least for grouping).
|
|
|
|
* `uuid*` functions for {godoc_root}/github.com/google/uuid[`github.com/google/uuid`^]
|
|
* `uuidx*` functions for {godoc_root}/r00t2.io/goutils/uuidx[`r00t2.io/goutils/uuidx`^]
|
|
|
|
[id="todo_url"]
|
|
=== URL Functions
|
|
Expose {godoc_root}net/url/[`net/url`^] functions to derive URLs.
|
|
|
|
[id="todo_net"]
|
|
=== Live Networking Functions
|
|
Requires <<todo_safe>> first.
|
|
|
|
Sometimes networking data lookup is needed at time of render/contextual to render.
|
|
|
|
* `dns*` (DNS lookup options from {godoc_root}/[`net`^])
|
|
** With the ability to use a custom resolver (would need <<todo_collctns>>)
|
|
* `http*` functions
|
|
** `httpReq` for a {godoc_root}/net/http#Request[`net/http.Request`^]
|
|
** `http<Method>` for a shorthand/one-shot version of `httpReq` above
|
|
** `resty*` functions for {godoc_root}/resty.dev/v3[`resty.dev/v3`^]?
|
|
*** Maybe via a configured <<todo_collctns>> instead
|