This is an automated email from the ASF dual-hosted git repository.
msciabarra pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/openserverless-cli.git
The following commit(s) were added to refs/heads/main by this push:
new 65957c4 cleanup and fix tests
65957c4 is described below
commit 65957c492f5a2f145791d5bc80c1cf8479a22501
Author: Michele Sciabarra <[email protected]>
AuthorDate: Mon Jul 29 12:06:02 2024 +0200
cleanup and fix tests
---
README.md | 25 ++++++-----
Taskfile.yml | 11 ++---
docs/OPS.md | 32 ++++++++++++++
main.go | 119 ++++++++++++++++++++++++++++----------------------
prepare.go | 10 -----
prereq.go | 2 +-
tests/auto_setup.bats | 1 +
tests/folders.bats | 2 +-
version.txt | 2 +-
9 files changed, 122 insertions(+), 82 deletions(-)
diff --git a/README.md b/README.md
index 556b12c..f0c5647 100644
--- a/README.md
+++ b/README.md
@@ -49,23 +49,26 @@ Note that to avoid an egg and chicken problem, `ops` itself
is built with his an
The following environment variables allows to ovverride certain defaults.
-- `DEBUG` and `TRACE` when set gives debugging and tracing informations,
`EXTRA` appends extra arguments to the task invocation - useful when you need
to set extra variables with a nuvopts active.
-- `NUV_ROOT` is the folder where `nuv` looks for its tasks. If not defined, it
follows the algorithm below to find it.
-- `OPS_BIN` is the folder where `nuv` looks for binaries (external command
line tools). If not defined, it defaults to `~/.nuv/bin`
+- `DEBUG` if set enable debugging messages
+- `TRACE` when set gives mode detailes tracing informations, also enable
DEBUG=1
+- `EXTRA` appends extra arguments to the task invocation - useful when you
need to set extra variables with a nuvopts active.
+- `OPS_HOME` is the home dir, defaults to `~/.nuv` if not defined
+- `NUV_ROOT` is the folder where `ops` looks for its tasks. If not defined, if
will first look in current directory for an `olaris` folder otherwise download
it from githut fron the `NUV_REPO` with a git clone
+- `OPS_BIN` is the folder where `ops` looks for binaries (external command
line tools). If not defined, it defaults to `~/.nuv/<os>-<arch>/bin`. All the
prerequisites are downloaded in this directory
- `OPS_CMD` is the actual command executed - defaults to the absolute path of
the target of the symbolic link but it can be overriden.
-- `NUV_REPO` is the github repo where `nuv` downloads its tasks. If not
defined, it defaults to `https://github.com/nuvolaris/olaris`.
-- `NUV_BRANCH` is the branch where `nuv` looks for its tasks. The branch to
use is defined at build time and it is the base version (without the patch
level). For example, if `nuv` is `0.3.0-morpheus` the branch to use will be
`0.3-morpheus`.
-- `NUV_VERSION` can be defined to set nuv's version value. It is useful to
override version validations when updating tasks (and you know what you are
doing).
-- `NUV_TMP` is a temporary folder where you can store temp files - defaults to
`~/.nuv/tmp`
+- `NUV_REPO` is the github repo where `ops` downloads its tasks. If not
defined, it defaults to `https://github.com/apache/openserverless-task`.
+- `NUV_BRANCH` is the branch where `nuv` looks for its tasks. The branch to
use is defined at build time and it is the base version (without the patch
level). Chech branch.txt for the current value
+- `NUV_VERSION` can be defined to set nuv's version value. It is useful to
override version validations when updating tasks (and you know what you are
doing). Current value is in version.txt
+- `NUV_TMP` is a temporary folder where you can store temp files - defaults to
`~/.nuv/tmp`
- `NUV_APIHOST` is the host for `nuv -login`. It is used in place of the first
argument of `nuv -login`. If empty, the command will expect the first argument
to be the apihost.
- `NUV_USER`: set the username for `nuv -login`. The default is `nuvolaris`.
It can be overriden by passing the username as an argument to `nuv -login` or
by setting the environment variable.
- `NUV_PASSWORD`: set the password for `nuv -login`. If not set, `nuv -login`
will prompt for the password. It is useful for tests and non-interactive
environments.
-- `NUV_PWD` is the folder where `nuv` is executed (the current working
directory). It is used to preserve the original working directory when `nuv` is
used again in tasks (e.g. nuv -realpath to retrieve the correct path). Change
it only if you know what you are doing!
-- `NUV_ROOT_PLUGIN` is the folder where `nuv` looks for plugins. If not
defined, it defaults to the same directory where `nuv` is located.
+- `NUV_PWD` is the folder where `ops` is executed (the current working
directory). It is used to preserve the original working directory when `ops` is
used again in tasks (e.g. nuv -realpath to retrieve the correct path). Change
it only if you know what you are doing!
+- `NUV_ROOT_PLUGIN` is the folder where `nuv` looks for plugins. If not
defined, it defaults to the same directory where `ops` is located.
- `NUV_OLARIS` holds the head commit hash of the used olaris repo. You can see
the hash with `nuv -info`.
-- `NUV_PORT` is the port where `nuv` will run embedde web server for the
configurator. If not defined, it defaults to `9678`.
+- `NUV_PORT` is the port where `ops` will run embedde web server for the
configurator. If not defined, it defaults to `9678`.
- `NUV_NO_NUVOPTS` can be defined to disable nuvopts parsing. Useful to test
hidden tasks. When this is enabled it also shows all the tasks instead of just
those with a description.
-- `OPS_NO_PREREQ` disable downloading of prerequisites - you have to ensure at
least coreutils is in the path...
+- `OPS_NO_PREREQ` disable downloading of prerequisites - you have to ensure at
least coreutils is in the path to make things work
## Where `nuv` looks for binaries
diff --git a/Taskfile.yml b/Taskfile.yml
index 109e5c7..37e03c7 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -80,12 +80,13 @@ tasks:
- task: itest
utest:
- desc: unit test nuv
+ desc: unit test (use F=-v to verbose)
cmds:
- - rm -Rf ~/.nuv/olaris
- - go test -v github.com/apache/openserverless-cli
- - go test -v github.com/apache/openserverless-cli/config
- - go test -v github.com/apache/openserverless-cli/tools
+ - rm -Rf ~/.nuv
+ - go clean -testcache
+ - go test {{.F}} github.com/apache/openserverless-cli
+ - go test {{.F}} github.com/apache/openserverless-cli/config
+ - go test {{.F}} github.com/apache/openserverless-cli/tools
- echo TODO go test github.com/apache/openserverless-cli/auth
diff --git a/docs/OPS.md b/docs/OPS.md
new file mode 100644
index 0000000..59be03a
--- /dev/null
+++ b/docs/OPS.md
@@ -0,0 +1,32 @@
+# Ops
+
+Ops is the OpenServerless cli tool.
+
+It embeds [Task](https://taskfile.dev) and [OpenWhisk
wsk](https://github.com/apache/openwhisk-cli). Note that Task actually embeds
a [shell interpreter](https://github.com/mvdan/sh) so most of the tasks are
actully implemented as shell scripts embedded in taskfiles (YAML).
+
+Most of its capabilites are implemented as a hiearchy of taskfiles, managed as
described below. There is a preprocessing done on the command line allowing to
find the correct taskfile, and parameters of each task are described using
[docpts](http://docopt.org/)
+
+To be able to develop ops you need either to know [posix shell
scripting](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html),
[taskfile definition](https://taskfile.dev/usage/) and
[docpts](http://docopt.org/).
+
+The shell is modified to be able to test some commands in a special way to
simplify writing the scripts in the taskfiles.
+
+In particular, all the commonly used Unix utilites are delegated to an utility
that embeds all of then called `coreutils`. So in a task all the commands
listed as `coreutils` like `rm`, `ls` are actually translated in an invocation
of `coreutils rm`, `coreutils ls` and so all. All the commands delegated to
coreutils can be seen with `nuv -help`. We are using
[uutils](https://github.com/uutils/coreutils) a rust portable rewrite of core
unix coreutils.
+
+Furthrmore some commands are implemented in `ops` itself. For example it
embeds an `awk` intepreter (actually [gowak](https://github.com/benhoyt/goawk)
and a JQ intepreter (actually [gojq](https://github.com/itchyny/gojq)). The
shell is modified to be able to use those tooks `awk` and `jq` directly.
+
+Some commands are actually external so there is support for automatically
downloading prequisite binaries.
+
+All the CLI commands are a hierarchy of taskfiles downloaded automatically
from
[https://github.com/apache/openserverless-task](https://github.com/apache/openserverless-task)
+
+It then parse the command line to locate the correct taskfile and execute it.
+
+Before executing each command, there is a prerequisite management system that
is executed before actually running the commands, so the correct version of the
utils are downloaded
+
+# Ops command line
+
+TODO describe the command line
+
+# Ops Preqrequisites
+
+TODO describe prereq.yaml
+
diff --git a/main.go b/main.go
index 6932455..ab0cff7 100644
--- a/main.go
+++ b/main.go
@@ -83,17 +83,26 @@ func setupBinPath() error {
return err
}
+func setNuvRootPluginEnv() {
+ if os.Getenv("NUV_ROOT_PLUGIN") == "" {
+ //nolint:errcheck
+ os.Setenv("NUV_ROOT_PLUGIN", os.Getenv("NUV_PWD"))
+ }
+ trace("set NUV_ROOT_PLUGIN", os.Getenv("NUV_ROOT_PLUGIN"))
+}
+
func info() {
- fmt.Println("NUV_VERSION:", NuvVersion)
- fmt.Println("NUV_BRANCH:", getNuvBranch())
- fmt.Println("OPS_CMD:", tools.GetNuvCmd())
+ fmt.Println("NUV_VERSION:", os.Getenv("NUV_VERSION"))
+ fmt.Println("NUV_BRANCH:", os.Getenv("NUV_BRANCH"))
+ fmt.Println("OPS_CMD:", os.Getenv("OPS_CMD"))
fmt.Println("OPS_BIN:", os.Getenv("OPS_BIN"))
- fmt.Println("NUV_REPO:", getNuvRepo())
fmt.Println("NUV_TMP:", os.Getenv("NUV_TMP"))
- root, _ := getNuvRoot()
- fmt.Println("NUV_ROOT:", root)
+ fmt.Println("OPS_HOME:", os.Getenv("OPS_HOME"))
+ fmt.Println("NUV_ROOT:", os.Getenv("NUV_ROOT"))
+ fmt.Println("NUV_REPO:", os.Getenv("NUV_REPO"))
fmt.Println("NUV_PWD:", os.Getenv("NUV_PWD"))
fmt.Println("NUV_OLARIS:", os.Getenv("NUV_OLARIS"))
+ fmt.Println("NUV_ROOT_PLUGIN:", os.Getenv("NUV_ROOT_PLUGIN"))
}
// execute the embedded tools
@@ -201,6 +210,7 @@ func executeEmbeddedToolsAndExit(cmd string, args []string,
nuvHome string) int
func Main() {
var err error
+ args := os.Args
// disable log prefix
log.SetFlags(0)
@@ -216,10 +226,11 @@ func Main() {
NuvVersion = os.Getenv("NUV_VERSION")
} else {
NuvVersion = strings.TrimSpace(NuvVersion)
+ os.Setenv("NUV_VERSION", NuvVersion)
}
- // setup NUV_CMD
- me := os.Args[0]
+ // setup OPS_CMD
+ me := args[0]
if strings.Contains("ops ops.exe nuv nuv.exe", filepath.Base(me)) {
tools.NuvCmd, err = setupCmd(me)
if err != nil {
@@ -228,12 +239,16 @@ func Main() {
}
// setup home
- nuvHome, err := homedir.Expand("~/.nuv")
+ nuvHome := os.Getenv("OPS_HOME")
+ if nuvHome == "" {
+ nuvHome, err = homedir.Expand("~/.nuv")
+ }
if err != nil {
log.Fatalf("cannot setup home: %s", err.Error())
}
+ os.Setenv("OPS_HOME", nuvHome)
- // add ~/.nuv/bin to the path at the beginng
+ // add ~/.nuv/<os>-<arch>/bin to the path at the beginning
err = setupBinPath()
if err != nil {
log.Fatalf("cannot setup PATH: %s", err.Error())
@@ -251,10 +266,34 @@ func Main() {
log.Fatalf("cannot setup NUV_PWD: %s", err.Error())
}
- // set the rootdir for plugins
+ // NUV_REPO && NUV_ROOT_PLUGIN
+ getNuvRepo()
setNuvRootPluginEnv()
- // set the environemnt variables from the config
+ // Check if olaris exists. If not, download tasks
+ olarisDir, err := getNuvRoot()
+ if err != nil {
+ olarisDir := joinpath(joinpath(nuvHome, getNuvBranch()),
"olaris")
+ if !isDir(olarisDir) {
+ log.Println("Welcome to nuv! Setting up...")
+ olarisDir, err = pullTasks(true, true)
+ if err != nil {
+ log.Fatalf("cannot locate or download NUV_ROOT:
%s", err.Error())
+ }
+ // just updated, do not repeat
+ if len(args) == 2 && args[1] == "-update" {
+ os.Exit(0)
+ }
+ } else {
+ // check if olaris was recently updated
+ checkUpdated(nuvHome, 24*time.Hour)
+ }
+ }
+ if err = setNuvOlarisHash(olarisDir); err != nil {
+ os.Setenv("NUV_OLARIS", "<local>")
+ }
+
+ // set the enviroment variables from the config
nuvRootDir := getRootDirOrExit()
debug("nuvRootDir", nuvRootDir)
err = setAllConfigEnvVars(nuvRootDir, nuvHome)
@@ -262,19 +301,7 @@ func Main() {
log.Fatalf("cannot apply env vars from configs: %s",
err.Error())
}
- // first argument with prefix "-" is considered an embedded tool
- // using "-" or "--" or "-task" invokes the embedded task
- args := os.Args
- if len(args) > 1 && len(args[1]) > 0 && args[1][0] == '-' {
- cmd := args[1][1:]
- trace("executing embedded tool", cmd, args)
- // execute the embeded tool and exit
- exitCode := executeEmbeddedToolsAndExit(cmd, args, nuvHome)
- os.Exit(exitCode)
- }
-
- // in case args[1] is a wsk wrapper command
- // invoke it and exit
+ // in case args[1] is a wsk wrapper command invoke it and exit
if len(args) > 1 {
if cmd, ok := IsWskWrapperCommand(args[1]); ok {
trace("wsk wrapper command")
@@ -290,35 +317,29 @@ func Main() {
if err := tools.Wsk(cmd, rest...); err != nil {
log.Fatalf("error: %s", err.Error())
}
- return //(skip runNuv)
+ os.Exit(0)
}
}
- // preflight checks
- if err := preflightChecks(); err != nil {
- log.Fatalf("[PREFLIGHT CHECK] error: %s", err.Error())
+ // first argument with prefix "-" is considered an embedded tool
+ // using "-" or "--" or "-task" invokes the embedded task
+ if len(args) > 1 && len(args[1]) > 0 && args[1][0] == '-' {
+ cmd := args[1][1:]
+ trace("executing embedded tool", cmd, args)
+ // execute the embeded tool and exit
+ exitCode := executeEmbeddedToolsAndExit(cmd, args, nuvHome)
+ os.Exit(exitCode)
}
- // ***************
+ // *************** executing tasks
- // Check if olaris exists. If not, pull tasks to auto setup
- olarisDir := joinpath(joinpath(nuvHome, getNuvBranch()), "olaris")
- if !isDir(olarisDir) {
- log.Println("Welcome to nuv! Setting up...")
- _, err = pullTasks(true, true)
- if err != nil {
- log.Fatalf("error: %v", err)
- }
- if err := setNuvOlarisHash(olarisDir); err != nil {
- warn("unable to set NUV_OLARIS...", err.Error())
- }
+ // preflight checks - we need at least ssh and curl to proceed
+ if err := preflightChecks(); err != nil {
+ log.Fatalf("failed preflight check: %s", err.Error())
}
- // check if olaris was recently updated
- checkUpdated(nuvHome, 24*time.Hour)
-
if err := runNuv(nuvRootDir, args); err != nil {
- log.Fatalf("error: %s", err.Error())
+ log.Fatalf("task execution error: %s", err.Error())
}
}
@@ -404,14 +425,6 @@ func runNuv(baseDir string, args []string) error {
return err
}
-func setNuvRootPluginEnv() {
- if os.Getenv("NUV_ROOT_PLUGIN") == "" {
- //nolint:errcheck
- os.Setenv("NUV_ROOT_PLUGIN", os.Getenv("NUV_PWD"))
- }
- trace("set NUV_ROOT_PLUGIN", os.Getenv("NUV_ROOT_PLUGIN"))
-}
-
func setNuvPwdEnv() error {
if os.Getenv("NUV_PWD") == "" {
dir, err := os.Getwd()
diff --git a/prepare.go b/prepare.go
index 21e7424..7c7413d 100644
--- a/prepare.go
+++ b/prepare.go
@@ -186,16 +186,6 @@ func locateNuvRoot(cur string) (string, error) {
return olaris, nil
}
- // is there an olaris folder in NUV_BIN?
- nuvBin := os.Getenv("NUV_BIN")
- if nuvBin != "" {
- olaris = joinpath(nuvBin, "olaris")
- if exists(olaris, NUVFILE) && exists(olaris, NUVROOT) {
- trace("found sub NUV_BIN olaris:", olaris)
- return olaris, nil
- }
- }
-
return "", fmt.Errorf("we cannot find nuvfiles, download them with nuv
-update")
}
diff --git a/prereq.go b/prereq.go
index 65b5b19..b120c28 100644
--- a/prereq.go
+++ b/prereq.go
@@ -84,7 +84,7 @@ func EnsureBindir() (string, error) {
bindir := os.Getenv("OPS_BIN")
if bindir == "" {
bindir, err = homedir.Expand(fmt.Sprintf("~/.nuv/%s-%s/bin",
runtime.GOOS, runtime.GOARCH))
- os.Setenv("OP_BIN", bindir)
+ os.Setenv("OPS_BIN", bindir)
}
if err != nil {
return "", err
diff --git a/tests/auto_setup.bats b/tests/auto_setup.bats
index b30e795..9982025 100644
--- a/tests/auto_setup.bats
+++ b/tests/auto_setup.bats
@@ -19,6 +19,7 @@ setup() {
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
export NO_COLOR=1
+ cd testdata
}
@test "first run auto setups" {
diff --git a/tests/folders.bats b/tests/folders.bats
index ead4866..3e1a0c9 100644
--- a/tests/folders.bats
+++ b/tests/folders.bats
@@ -55,6 +55,6 @@ setup() {
@test "sub command not found" {
run nuv sub notfound
- assert_line "error: no command named notfound found"
+ assert_line "task execution error: no command named notfound found"
assert_failure
}
\ No newline at end of file
diff --git a/version.txt b/version.txt
index f2c21b4..ab6e780 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-0.1.0-testing.2407281938
+0.1.0-testing.2407291118