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 1c724d6  support prerequisites - test to fix
1c724d6 is described below

commit 1c724d6c92003a966b94446b979920d458aeacf5
Author: Michele Sciabarra <[email protected]>
AuthorDate: Thu Jul 25 19:25:52 2024 +0200

    support prerequisites - test to fix
---
 Taskfile.yml                |   8 +-
 _patches/patch-task.sh      |  13 ++-
 _patches/task               | Bin 17159510 -> 17159510 bytes
 cli.code-workspace          |   8 --
 common.go                   |   1 +
 go.mod                      |   2 +-
 go.sum                      |   2 +
 main_test.go                |   5 +-
 nuv.go                      |   3 +
 prereq.go                   | 191 ++++++++++++++++++++++++++++++++++++++++++++
 prereq_test.go              | 100 +++++++++++++++++++++++
 tests/prereq.bats           |  31 +++++++
 tests/prereq/prereq.yml     |  27 +++++++
 tests/prereq/sub/prereq.yml |  27 +++++++
 tests/scan.bats             |  73 -----------------
 15 files changed, 401 insertions(+), 90 deletions(-)

diff --git a/Taskfile.yml b/Taskfile.yml
index 68786d5..4c7559f 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -94,12 +94,16 @@ tasks:
     - test -d bats
 
   itest:
-    desc: integration tests nuv
+    desc: integration tests for nuv (T=<test-name> without .bats, empty all)
     dir: tests
     cmds:
       - task: bats
       - rm -Rf ~/.nuv/olaris
-      - bats/bin/bats .
+      - |
+        if test -z "{{.T}}"
+        then bats/bin/bats .
+        else bats/bin/bats {{.T}}.bats
+        fi
 
   clean:
     - rm ops || true
diff --git a/_patches/patch-task.sh b/_patches/patch-task.sh
index 4cd3fdf..66718f2 100644
--- a/_patches/patch-task.sh
+++ b/_patches/patch-task.sh
@@ -4,7 +4,7 @@ cd "$(dirname $0)"
 HERE=$PWD
 SHVER=$(git ls-remote https://github.com/sciabarracom/sh | awk 
'/refs\/heads\/openserverless/{print $1}')
 STAG="v3.38.0"
-DTAG="v3.38.6"
+DTAG="v3.38.7"
 cd taskfile
 go clean -cache -modcache
 git checkout "$STAG" -B openserverless
@@ -16,9 +16,14 @@ cat cmd/task/task.go \
 sed -i -e 's/func init/func FlagInit/' internal/flags/flags.go
 cat   <<EOF >>cmd/taskmain/task.go
 
+var todoFlagInit = true
+
 func Task(_args []string) (int, error) {
-   os.Args = _args
-   flags.FlagInit()
+       os.Args = _args
+       if todoFlagInit {
+               flags.FlagInit()
+               todoFlagInit = false
+       }
        if err := run(); err != nil {
                l := &logger.Logger{
                        Stdout:  os.Stdout,
@@ -54,8 +59,8 @@ sed -i -e '/mvdan.cc/g' go.mod
 go get github.com/sciabarracom/sh/v3@$SHVER
 go mod tidy
 git commit -m "patching sh for ops" -a
-git tag $DTAG
 go build
+git tag $DTAG
 git push origin-auth openserverless -f --tags
 VER=$(git rev-parse HEAD)
 GOBIN=$HERE go install github.com/sciabarracom/task/v3/cmd/task@$VER
diff --git a/_patches/task b/_patches/task
index bbd6523..c5c1815 100755
Binary files a/_patches/task and b/_patches/task differ
diff --git a/cli.code-workspace b/cli.code-workspace
index e5e2b0b..68e91f6 100644
--- a/cli.code-workspace
+++ b/cli.code-workspace
@@ -3,14 +3,6 @@
     {
       "name": "ops",
       "path": "."
-    },
-    {
-      "name": "task",
-      "path": "tools/task"
-    },
-    {
-      "name": "sh",
-      "path": "tools/sh"
     }
   ],
   "settings": {
diff --git a/common.go b/common.go
index c565229..bdfd470 100644
--- a/common.go
+++ b/common.go
@@ -31,6 +31,7 @@ const NUVFILE = "nuvfile.yml"
 const NUVROOT = "nuvroot.json"
 const NUVOPTS = "nuvopts.txt"
 const CONFIGFILE = "config.json"
+const PREREQ = "prereq.yml"
 
 // repo where download tasks
 const NUVREPO = "http://github.com/apache/openserverless-task";
diff --git a/go.mod b/go.mod
index 70ba5d3..f670934 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,7 @@ require (
        github.com/nuvolaris/jj v0.0.0-20231020143327-10b90948a5d2
        github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
        github.com/sciabarracom/openwhisk-cli v1.2.1
-       github.com/sciabarracom/task/v3 v3.38.6
+       github.com/sciabarracom/task/v3 v3.38.7
        github.com/stretchr/testify v1.9.0
        github.com/zalando/go-keyring v0.2.5
        golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
diff --git a/go.sum b/go.sum
index d4d6af7..2eb29ca 100644
--- a/go.sum
+++ b/go.sum
@@ -349,6 +349,8 @@ github.com/sciabarracom/task/v3 v3.38.5 
h1:n3MoGltcwTtuG3R4tlPX9V0DmFYa55ESDItNi
 github.com/sciabarracom/task/v3 v3.38.5/go.mod 
h1:KOSMNSJm4CBpVzAXUlkgEPgbDp9kQoL9nNm/B6DvcW0=
 github.com/sciabarracom/task/v3 v3.38.6 
h1:vNVqq/EUDkCbt4TUvk4LWtpD4wE0G4mveWMBb8QUieU=
 github.com/sciabarracom/task/v3 v3.38.6/go.mod 
h1:KOSMNSJm4CBpVzAXUlkgEPgbDp9kQoL9nNm/B6DvcW0=
+github.com/sciabarracom/task/v3 v3.38.7 
h1:cWN+wE5zDW/U5VLoj/D9PFNHqgGodM+5XtY8av5hZso=
+github.com/sciabarracom/task/v3 v3.38.7/go.mod 
h1:KOSMNSJm4CBpVzAXUlkgEPgbDp9kQoL9nNm/B6DvcW0=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod 
h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 
h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod 
h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
diff --git a/main_test.go b/main_test.go
index aa1f0c2..6b5e4d5 100644
--- a/main_test.go
+++ b/main_test.go
@@ -54,12 +54,13 @@ func nhpath(dir string) string {
 }
 
 func TestMain(m *testing.M) {
+       //debugging = true
+       //tracing = true
        wd, _ := os.Getwd()
        workDir, _ = filepath.Abs(wd)
        homeDir, _ = homedir.Dir()
        taskDryRun = true
-       //debugging = true
-       //tracing = true
+       ensurePrereq()
        os.Exit(m.Run())
 }
 
diff --git a/nuv.go b/nuv.go
index 43d7486..0efc60b 100644
--- a/nuv.go
+++ b/nuv.go
@@ -173,6 +173,8 @@ func Nuv(base string, args []string) error {
        rest := args
 
        isSubCmd := false
+
+       ensurePrereq()
        for _, task := range args {
                trace("task name", task)
 
@@ -192,6 +194,7 @@ func Nuv(base string, args []string) error {
                        if err := os.Chdir(taskName); err != nil {
                                return err
                        }
+                       ensurePrereq()
                        //remove it from the args
                        rest = rest[1:]
                        isSubCmd = true
diff --git a/prereq.go b/prereq.go
new file mode 100644
index 0000000..bb87a4d
--- /dev/null
+++ b/prereq.go
@@ -0,0 +1,191 @@
+package openserverless
+
+import (
+       "fmt"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "strings"
+
+       "github.com/mitchellh/go-homedir"
+       "gopkg.in/yaml.v3"
+)
+
+var PrereqSeenMap = map[string]string{}
+
+// Define the Go structs
+type Prereq struct {
+       Version int                   `yaml:"version"`
+       Tasks   map[string]PrereqTask `yaml:"tasks"`
+}
+
+type PrereqTask struct {
+       Description *string           `yaml:"description,omitempty"` // Make 
description optional
+       Vars        map[string]string `yaml:"vars,omitempty"`
+}
+
+// execute prereq task
+func execPrereqTask(bindir string, name string) error {
+       me, err := os.Executable()
+       if err != nil {
+               return err
+       }
+       args := []string{
+               "-task",
+               "-d", bindir,
+               "-t", PREREQ,
+               name,
+       }
+       if taskDryRun {
+               fmt.Printf("invoking prereq for %s\n", name)
+               return nil
+       }
+       trace("Exec:", me, args)
+       err = exec.Command(me, args...).Run()
+       if err != nil {
+               return err
+       }
+       return nil
+}
+
+// load prerequisites in current dir
+func loadPrereq() (Prereq, error) {
+       var prereq Prereq = Prereq{}
+       dir, err := os.Getwd()
+       if err != nil {
+               return prereq, err
+       }
+
+       if !exists(dir, PREREQ) {
+               return prereq, fmt.Errorf("not found %s", dir)
+       }
+       trace("found prereq.yml in ", dir)
+
+       dat, err := os.ReadFile(joinpath(dir, PREREQ))
+       if err != nil {
+               return prereq, err
+       }
+
+       err = yaml.Unmarshal(dat, &prereq)
+       if err != nil {
+               return prereq, err
+       }
+
+       return prereq, err
+}
+
+// ensure there is a bindir for downloading prerequisites
+func ensureBindir() (string, error) {
+       bindir, err := homedir.Expand("~/.nuv/bin")
+       if err != nil {
+               return "", err
+       }
+       err = os.MkdirAll(bindir, 0755)
+       if err != nil {
+               return "", err
+       }
+       trace("bindir", bindir)
+       return bindir, nil
+}
+
+func touch(dir string, name string) error {
+       tgt := filepath.Join(dir, name)
+       trace("touch", tgt)
+       f, err := os.Create(tgt)
+       if err != nil {
+               return err
+       }
+       f.Close()
+       return nil
+}
+
+// create a mark of current version touching <name>-<version> and remove all 
the other files starting with <name>-
+func touchAndClean(dir string, name string, version string) error {
+
+       // Walk through the directory
+       err := filepath.Walk(dir, func(path string, info os.FileInfo, err 
error) error {
+               if err != nil {
+                       return err
+               }
+
+               // Check if the file starts with the prefix
+               if !info.IsDir() && strings.HasPrefix(info.Name(), name+"-") {
+                       trace("Removing file:", path)
+                       err := os.Remove(path)
+                       if err != nil {
+                               return err
+                       }
+               }
+               return nil
+       })
+
+       if err != nil {
+               return err
+       }
+       err = touch(dir, name+"-"+version)
+       if err != nil {
+               return err
+       }
+       return nil
+
+}
+
+// download a prerequisite
+func downloadPrereq(name string, task PrereqTask) error {
+       version, ok := task.Vars["VERSION"]
+       if !ok {
+               return nil
+       }
+
+       bindir, err := ensureBindir()
+       if err != nil {
+               return err
+       }
+
+       // check if file and version exists
+       vname := name + "-" + version
+       trace("checking", vname, version)
+       if exists(bindir, name) {
+               // check if there is an inconsistency in the versions
+               if exists(bindir, vname) {
+                       trace("already downloaded", vname)
+                       return nil
+               }
+               oldver, seen := PrereqSeenMap[name]
+               if seen {
+                       if oldver == version {
+                               trace("same version again", vname)
+                               return nil
+                       }
+                       return fmt.Errorf("WARNING: %s prerequisite found twice 
with different versions!\nPrevious version: %s, ignoring %s", name, oldver, 
version)
+               }
+       }
+
+       if taskDryRun {
+               fmt.Printf("downloading %s %s\n", name, version)
+               touch(bindir, name)
+               touchAndClean(bindir, name, version)
+       } else {
+               execPrereqTask(bindir, name)
+               // check if file and version exists
+               if !exists(bindir, name) {
+                       return fmt.Errorf("failed to download %s %s", name, 
version)
+               }
+       }
+
+       PrereqSeenMap[name] = version
+       return touchAndClean(bindir, name, version)
+}
+
+// ensure prereq are satified looking at the prereq.yml
+func ensurePrereq() error {
+       trace("ensurePrereq")
+       prereq, err := loadPrereq()
+       for task := range prereq.Tasks {
+               err = downloadPrereq(task, prereq.Tasks[task])
+               if err != nil {
+                       fmt.Printf("error in prereq %s: %v\n", task, err)
+               }
+       }
+       return nil
+}
diff --git a/prereq_test.go b/prereq_test.go
new file mode 100644
index 0000000..bd9f756
--- /dev/null
+++ b/prereq_test.go
@@ -0,0 +1,100 @@
+package openserverless
+
+import (
+       "fmt"
+       "os"
+
+       "github.com/mitchellh/go-homedir"
+)
+
+func Example_execPrereqTask() {
+       fmt.Println(execPrereqTask("bin", "bun"))
+       // Output:
+       // executing: ops [-task -d bin -t prereq.yml bun]
+       // <nil>
+}
+
+func Example_loadPrereq() {
+       //downloadPrereq("")
+       os.Chdir(workDir)
+       os.Chdir("tests")
+       _, err := loadPrereq()
+       fmt.Println(npath(err.Error()))
+       os.Chdir("prereq")
+       prq, err := loadPrereq()
+       //fmt.Println(prq)
+       fmt.Println(err, *prq.Tasks["bun"].Description, 
prq.Tasks["bun"].Vars["VERSION"])
+       // Output:
+       // not found /work/tests
+       // <nil> bun v1.11.20
+}
+
+func Example_ensureBindir() {
+       bindir, _ := homedir.Expand("~/.nuv/bin")
+       os.RemoveAll(bindir)
+       _, err1 := os.Stat(bindir)
+       bindir1, _ := ensureBindir()
+       _, err2 := os.Stat(bindir)
+       fmt.Printf("no dir: %s\ncreated: %t\nyes dir: %v\n", 
nhpath(err1.Error()), bindir1 == bindir, err2)
+       // Output:
+       // no dir: stat /home/.nuv/bin: no such file or directory
+       // created: true
+       // yes dir: <nil>
+}
+
+func Example_touchAndClean() {
+       bindir, _ := ensureBindir()
+       os.RemoveAll(bindir)
+       bindir, _ = ensureBindir()
+       touch(bindir, "hello")
+       err := touchAndClean(bindir, "hello", "1.2.3")
+       fmt.Println(err, exists(bindir, "hello"), exists(bindir, 
"hello-1.2.3"), exists(bindir, "hello-1.2.4"))
+       err = touchAndClean(bindir, "hello", "1.2.4")
+       fmt.Println(err, exists(bindir, "hello"), exists(bindir, 
"hello-1.2.3"), exists(bindir, "hello-1.2.4"))
+       // Output:
+       // <nil> true true false
+       // <nil> true false true
+}
+
+func Example_downloadPrereq() {
+       bindir, _ := homedir.Expand("~/.nuv/bin")
+       os.RemoveAll(bindir)
+       os.Chdir(workDir)
+       os.Chdir("tests")
+       os.Chdir("prereq")
+
+       prq, _ := loadPrereq()
+       fmt.Println("1", downloadPrereq("bun", prq.Tasks["bun"]))
+       fmt.Println("2", downloadPrereq("bun", prq.Tasks["bun"]))
+
+       os.Chdir("other")
+       prq, _ = loadPrereq()
+       //fmt.Println(prq)
+       //fmt.Println(PrereqSeenMap)
+       fmt.Println("3", downloadPrereq("bun", prq.Tasks["bun"]))
+       // Output:
+       // downloading bun v1.11.20
+       // 1 <nil>
+       // 2 <nil>
+       // 3 WARNING: bun prerequisite found twice with different versions!
+       // Previous version: v1.11.20, ignoring v1.11.21
+}
+
+func Example_ensurePrereq() {
+       bindir, _ := homedir.Expand("~/.nuv/bin")
+       os.RemoveAll(bindir)
+       os.Chdir(workDir)
+       os.Chdir("tests")
+       os.Chdir("prereq")
+       fmt.Println(ensurePrereq())
+       os.Chdir("sub")
+       fmt.Println(ensurePrereq())
+       // Output:
+       // downloading bun v1.11.20
+       // downloading coreutils 0.0.27
+       // <nil>
+       // <nil>
+       // error in prereq bun: WARNING: bun prerequisite found twice with 
different versions!
+       // Previous version: v1.11.20, ignoring v1.11.21
+       // <nil>
+}
diff --git a/tests/prereq.bats b/tests/prereq.bats
new file mode 100644
index 0000000..11eade6
--- /dev/null
+++ b/tests/prereq.bats
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+setup() {
+    load 'test_helper/bats-support/load'
+    load 'test_helper/bats-assert/load'
+    export NO_COLOR=1
+    export NUV_BRANCH="0.3.0"
+  
+}
+
+@test "ops prereq" {
+    rm -Rvf ~/.nuv/bin
+    TRACE=1 ops
+
+
+}
diff --git a/tests/prereq/prereq.yml b/tests/prereq/prereq.yml
new file mode 100644
index 0000000..3d51ce1
--- /dev/null
+++ b/tests/prereq/prereq.yml
@@ -0,0 +1,27 @@
+version: 3
+
+tasks:
+
+  _coreutils: 
+    cmds:
+    - touch coreutils
+
+  _bun:
+   cmds:
+   - touch bun
+
+  bun:
+    description: bun
+    vars:
+      VERSION: "v1.11.20"
+    cmds:
+    - task: _bun
+
+
+  coreutils:
+    description: coreutils
+    vars:
+       VERSION: "0.0.27"
+    cmds:
+    - task: _coreutils
+
diff --git a/tests/prereq/sub/prereq.yml b/tests/prereq/sub/prereq.yml
new file mode 100644
index 0000000..cef0736
--- /dev/null
+++ b/tests/prereq/sub/prereq.yml
@@ -0,0 +1,27 @@
+version: 3
+
+tasks:
+
+  _coreutils: 
+    cmds:
+    - touch coreutils
+
+  _bun:
+   cmds:
+   - touch bun
+
+  bun:
+    description: bun
+    vars:
+      VERSION: "v1.11.21"
+    cmds:
+    - task: _bun
+
+
+  coreutils:
+    description: coreutils
+    vars:
+       VERSION: "0.0.27"
+    cmds:
+    - task: _coreutils
+
diff --git a/tests/scan.bats b/tests/scan.bats
deleted file mode 100644
index 42c1478..0000000
--- a/tests/scan.bats
+++ /dev/null
@@ -1,73 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# setup() {
-#     load 'test_helper/bats-support/load'
-#     load 'test_helper/bats-assert/load'
-#     export NO_COLOR=1
-# }
-
-# @test "-scan help msg" {
-#     run nuv -scan --help
-#     assert_line --partial "Usage:"
-
-#     run nuv -scan
-#     assert_line --partial "Usage:"
-#     assert_failure
-# }
-
-# @test "-scan stops if actions folder not present" {
-#     NUV_PWD="./olaris" run nuv -scan nuv -js
-#     assert_line --partial "actions folder not found"
-#     assert_failure
-# }
-
-# @test "-scan -js argv.js without -g" {
-#     NUV_PWD="./testdata" run nuv -scan nuv -js testdata/js_test_argv.js
-#     WD=$(pwd)
-#     assert_line --partial 
"goja,testdata/js_test_argv.js,$WD/testdata/actions"
-#     assert_line --partial 
"goja,testdata/js_test_argv.js,$WD/testdata/actions/subfolder"
-#     assert_line --partial 
"goja,testdata/js_test_argv.js,$WD/testdata/actions/subfolder/subsub"
-#     assert_success
-# }
-
-# @test "-scan -js argv.js with -g *" {
-#     NUV_PWD="./testdata" run nuv -scan -glob "*" nuv -js 
testdata/js_test_argv.js
-#     WD=$(pwd)
-#     assert_line --partial 
"goja,testdata/js_test_argv.js,$WD/testdata/actions"
-#     assert_line --partial 
"goja,testdata/js_test_argv.js,$WD/testdata/actions/subfolder"
-#     assert_line --partial 
"goja,testdata/js_test_argv.js,$WD/testdata/actions/subfolder/subsub,hello.js,hello.py"
-#     assert_success
-# }
-
-# @test "-scan --dry-run" {
-#     NUV_PWD="./testdata" run nuv -scan -glob "*" --dry-run nuv -scan -js 
testdata/js_test_argv.js
-#     WD=$(pwd)
-#     assert_line --partial "nuv -scan -js testdata/js_test_argv.js 
$WD/testdata/actions"
-#     assert_line --partial "nuv -scan -js testdata/js_test_argv.js 
$WD/testdata/actions/subfolder"
-#     assert_line --partial "nuv -scan -js testdata/js_test_argv.js 
$WD/testdata/actions/subfolder/subsub hello.js hello.py"
-#     assert_success
-# }
-
-# @test "-scan glob pattern" {
-#     NUV_PWD="./testdata" run nuv -scan --dry-run -glob "*.js" nuv -js 
testdata/js_test_argv.js
-#     WD=$(pwd)
-#     assert_line --partial "nuv -js testdata/js_test_argv.js 
$WD/testdata/actions"
-#     assert_line --partial "nuv -js testdata/js_test_argv.js 
$WD/testdata/actions/subfolder"
-#     assert_line --partial "nuv -js testdata/js_test_argv.js 
$WD/testdata/actions/subfolder/subsub hello.js"
-#     assert_success
-# }

Reply via email to