checking in before refactoring interpolation

This commit is contained in:
brent saner
2024-04-11 12:46:13 -04:00
parent 187ad868db
commit eed9c34ebf
17 changed files with 2014 additions and 48 deletions

34
exec_extra/consts.go Normal file
View File

@@ -0,0 +1,34 @@
package exec_extra
var (
StructTagCmdArgs string = "cmdarg"
)
var (
/*
CmdArgsOptPreferShort, if specified, prefers the "short" argument over "long" if both are specified.
The default is to prefer long.
Can be specified per-field via the `prefer_short` option (no value/value ignored).
*/
CmdArgsOptPreferShort cmdArgOpt = func(opts *cmdArgsOpts) (err error) {
opts.preferShort = true
return
}
/*
CmdArgsOptShortEquals, if specified, renders short flags *with* an equals sign
(if using POSIX args).
Has no effect if using Windows traditional syntax or if there is no value for the field.
*/
CmdArgsOptShortEquals cmdArgOpt = func(opts *cmdArgsOpts) (err error) {
opts.preferShort = true
return
}
CmdArgsOptLongNoEquals cmdArgOpt = func(opts *cmdArgsOpts) (err error) {
opts.preferShort = true
return
}
)

View File

@@ -0,0 +1,45 @@
package exec_extra
var (
/*
CmdArgsOptForcePosix forces the resulting command string to use "POSIX-style" flag notation.
Traditionally, Windows used flags like `/f` instead of POSIX `-f`, `/c:value` instead of `-c value`
or `-c=value`, etc.
If this option is passed, either to GetCmdFromStruct() or for a specific field via the
tag defined by StructTagCmdArgs (option `force_posix`, no value/value ignored), then the
POSIX-style flag syntax will be used instead.
Note that on Windows runtime, the default is to use the traditional slash-based syntax.
If you are generating command strings for Powershell or third-party software, you probably
want to use this option.
See also the inverse of this option, CmdArgsOptForceNoPosix.
*/
CmdArgsOptForcePosix cmdArgOpt = func(opts *cmdArgsOpts) (err error) {
opts.forcePosix = true
return
}
/*
CmdArgsOptForceNoPosix forces the resulting command string to use "traditional Windows" flag notation.
Traditionally, Windows used flags like `/f` instead of POSIX `-f`, `/c:value` instead of `-c value`
or `-c=value`, etc.
If this option is passed, either to GetCmdFromStruct() or for a specific field via the
tag defined by StructTagCmdArgs (option `force_no_posix`, no value/value ignored), then the
Windows-style flag syntax will be used instead.
Note that on Windows runtime, the default is to use the traditional slash-based syntax.
If you are generating command strings for Powershell or third-party software, you probably
want to use CmdArgsOptForcePosix instead.
See also the inverse of this option, CmdArgsOptForcePosix.
*/
CmdArgsOptForceNoPosix cmdArgOpt = func(opts *cmdArgsOpts) (err error) {
opts.forcePosix = false
return
}
)

View File

@@ -1,31 +0,0 @@
/*
SysUtils - a library to assist with various system-related functions
Copyright (C) 2020 Brent Saner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package exec_extra
import (
"os/exec"
)
func ExecCmdReturn(cmd *exec.Cmd) (exitStatus int, err error) {
// https://stackoverflow.com/a/55055100/733214
err = cmd.Run()
exitErr, _ := err.(*exec.ExitError)
exitStatus = exitErr.ExitCode()
return
}

86
exec_extra/funcs.go Normal file
View File

@@ -0,0 +1,86 @@
/*
SysUtils - a library to assist with various system-related functions
Copyright (C) 2020 Brent Saner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package exec_extra
import (
"os/exec"
)
func ExecCmdReturn(cmd *exec.Cmd) (exitStatus int, err error) {
// https://stackoverflow.com/a/55055100/733214
err = cmd.Run()
exitErr, _ := err.(*exec.ExitError)
exitStatus = exitErr.ExitCode()
return
}
/*
GetCmdFromStruct takes (a pointer to) a struct and returns a slice of
strings compatible with os/exec.Cmd.
The tag name used can be changed by setting the StructTagCmdArgs variable in this module;
the default is `cmdarg`.
If the tag value is "-", the field will be skipped. Any other tag value(s) are ignored.
Tag value format:
<tag>:"<option>=<value>[,<option>[=<value>],<option>[=<value>]...]"
e.g.
cmdarg:"short=l,long=list"
cmdarg:"short=l"
cmdarg:"long=list"
If the tag value is "-", or <VAR NAME> is not provided, the field will be explicitly skipped.
(This is the default behavior for struct fields not tagged with `cmdarg`.)
If a cmdarg tag is specified but has no `short` or `long` option value, the field will be skipped entirely.
If a field's value is nil, it will be skipped.
Otherwise if a field's value is the zero-value, it will be skipped.
Recognized options:
* short - A short flag for the argument
e.g.:
struct{
// If this is an empty string, it will be replaced with the value of $CWD.
CurrentDir string `envpop:"CWD"`
// This would only populate with $USER if the pointer is nil.
UserName *string `envpop:"USER"`
// This will *always* replace the field's value with the value of $DISPLAY,
// even if not an empty string.
// Note the `force` option.
Display string `envpop:"DISPLAY,force"`
// Likewise, even if not nil, this field's value would be replaced with the value of $SHELL.
Shell *string `envpop:"SHELL,force"`
// This field will be untouched if non-nil, otherwise it will be a pointer to an empty string
// if FOOBAR is undefined.
NonExistentVar *string `envpop:"FOOBAR,allow_empty"`
}
If s is nil, nothing will be done and err will be errs.ErrNilPtr.
If s is not a pointer to a struct, nothing will be done and err will be errs.ErrBadType.
*/
func GetCmdFromStruct[T any](s T, opts ...cmdArgOpt) (cmdSlice []string, err error) {
// TODO
return
}

9
exec_extra/types.go Normal file
View File

@@ -0,0 +1,9 @@
package exec_extra
type cmdArgsOpts struct {
preferShort bool
forcePosix bool
cmd *string
}
type cmdArgOpt func(*cmdArgsOpts) (err error)

33
exec_extra/utils.go Normal file
View File

@@ -0,0 +1,33 @@
package exec_extra
import (
`r00t2.io/sysutils/paths`
)
/*
CmdArgsWithBin returns a cmdArgsOpt that specifies program/executable/binary path `bin`,
ensuring that the resulting cmdSlice from GetCmdFromStruct() will return a ready-to-use slice.
(Otherwise the executable would need to be prepended to the resulting slice.)
Path normalization/canonziation can be enabled/disabled via normalizePath.
*/
func CmdArgsWithBin(bin string, normalizePath bool) (opt cmdArgOpt, err error) {
if normalizePath {
if err = paths.RealPath(&bin); err != nil {
return
}
}
opt = func(opts *cmdArgsOpts) (err error) {
/*
if opts.cmd == nil {
opts.cmd = new(string)
}
*/
*opts.cmd = bin
return
}
return
}