This is an automated email from the ASF dual-hosted git repository. sciabarracom pushed a commit to branch 0.9.0 in repository https://gitbox.apache.org/repos/asf/openserverless-cli.git
commit 572e29c50fd730581056d3e81d1ead53a137630d Author: Michele Sciabarra <[email protected]> AuthorDate: Thu Sep 3 15:23:34 2026 +0200 from olaris to oplugins --- README.md | 20 +++++++------ common.go | 11 +++++++ main.go | 22 +++++++------- plugin.go | 89 +++++++++++++++++++++++++++++++++---------------------- prepare.go | 62 +++++++++++++++++++++++++------------- prepare_test.go | 2 +- tests/info.bats | 2 +- tests/plugin.bats | 4 +-- updates_check.go | 29 +++++++++--------- 9 files changed, 146 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index 62a6275..4c0688d 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,8 @@ See below for details When you run `ops [<args>...]` it will first look for its `ops` root. -The `olaris` root is a folder with two files inside: `opsfile.yml` (a yaml taskfile) and `opsroot.json` (a json file -with release information). +The `ops` root is a folder with two files inside: `opsfile.yml` (a yaml taskfile) and `opsroot.json` (a json file +with release information). It is named `oplugins` (the legacy name `olaris` is still accepted). The first step is to locate the root folder. The algorithm to find the tools is the following. @@ -85,9 +85,10 @@ The first step is to locate the root folder. The algorithm to find the tools is 2. Then it will look in the current folder if there is a `opsfile.yml`. If there is, it will also look for `opsroot.json`. If it is not there, it will go up one level looking for a directory with `opsfile.yml` and `opstools.json`, and selects it as the `ops` root. -3. If there is not a `opsfile.yml` it will look for a folder called `olaris` with both a `opsfile.yml` - and `opstools.json` in it and will select it as the `ops` root. -4. Then it will look in `~/.ops` if there is an `olaris` folder with `opsfile.yml` and `opsroot.json`. +3. If there is not a `opsfile.yml` it will look for a folder called `oplugins` (or the legacy `olaris`) with both a + `opsfile.yml` and `opstools.json` in it and will select it as the `ops` root. +4. Then it will look in `~/.ops` if there is an `oplugins` (or the legacy `olaris`) folder with `opsfile.yml` + and `opsroot.json`. ### Download Tasks @@ -103,8 +104,8 @@ to `https://github.com/apache/openserverless-task` The branch to use is defined at build time. It is noramlly named as the base version of the CLI. It can be overriden with the enviroment variable `OPS_BRANCH`. -When you run `ops -update`, if there is not a `~/.ops/<branch>/olaris` it will clone the current branch, otherwise it -will update it. +When you run `ops -update`, if there is not a `~/.ops/<branch>/oplugins` nor a `~/.ops/<branch>/olaris` it will clone +the current branch into `~/.ops/<branch>/oplugins`, otherwise it will update the existing one. ## How `ops` execute tasks @@ -203,7 +204,8 @@ The following environment variables are always set and you **can override** them usually the base version (without the patch level). Check `branch.txt` for the current value - `OPS_ROOT` is the folder where `ops` looks for its tasks. If not defined, if will follow the algorithm described before to finding it locally. Otherwise download it from GitHub, git clones or git updates the `$OPS_REPO` in - the `$OPS_BRANCH` and store it is `$OPS_HOME/$OPS_BRANCH/olaris`. + the `$OPS_BRANCH` and store it is `$OPS_HOME/$OPS_BRANCH/oplugins` (an existing legacy + `$OPS_HOME/$OPS_BRANCH/olaris` is used and updated instead, if present). - `OPS_BIN` is the folder where `ops` looks for binaries (external command line tools). If not defined, it defaults to `~/.ops/{{.OS}}-{{.ARCH}}/bin`. All the prerequisites are downloaded in this directory. It is automatically added to the PATH at the beginning when executing opsfiles. @@ -218,7 +220,7 @@ The following environment variables are always set and you **can override** them where `ops` is located. - `OPS_PORT` is the port where `ops` will run embedded web server for the configurator. If not defined, it defaults to `9678`. -- `OPS_OLARIS` holds the head commit hash of the used olaris repo. If it is a local version its value is `<local>`. You +- `OPS_TASKS` holds the head commit hash of the used tasks repo. If it is a local version its value is `<local>`. You can see the hash with `ops -info`. ## Special purpose environment variables diff --git a/common.go b/common.go index 75630da..8c20bcf 100644 --- a/common.go +++ b/common.go @@ -41,6 +41,17 @@ const CONFIGFILE = "config.json" // repo where download tasks const OPSREPO = "http://github.com/apache/openserverless-task" +// names of the folders holding the tasks, in lookup order +// the legacy "olaris" name is still accepted for existing checkouts +var TASKS_DIRS = []string{"oplugins", "olaris"} + +// name of the folder used when downloading the tasks +const TASKS_DIR = "oplugins" + +// prefixes of the plugin folders, in lookup order +// the legacy "olaris-" prefix is still accepted for existing plugins +var PLUGIN_PREFIXES = []string{"oplugins-", "olaris-"} + // branch where download tasks // defaults to test - will be changed in compilation diff --git a/main.go b/main.go index 50c1a3d..95a3fe9 100644 --- a/main.go +++ b/main.go @@ -100,7 +100,7 @@ func info() { fmt.Println("OPS_ROOT:", os.Getenv("OPS_ROOT")) fmt.Println("OPS_REPO:", os.Getenv("OPS_REPO")) fmt.Println("OPS_PWD:", os.Getenv("OPS_PWD")) - fmt.Println("OPS_OLARIS:", os.Getenv("OPS_OLARIS")) + fmt.Println("OPS_TASKS:", os.Getenv("OPS_TASKS")) fmt.Println("OPS_ROOT_PLUGIN:", os.Getenv("OPS_ROOT_PLUGIN")) //fmt.Println("OPS_TOOLS:", os.Getenv("OPS_TOOLS")) //fmt.Println("OPS_COREUTILS:", os.Getenv("OPS_COREUTILS")) @@ -203,7 +203,7 @@ func executeTools(args []string, opsHome string) int { log.Fatalf("error: %v", err) } if err := setOpsOlarisHash(dir); err != nil { - log.Fatal("unable to set OPS_OLARIS...", err.Error()) + log.Fatal("unable to set OPS_TASKS...", err.Error()) } return 0 @@ -370,13 +370,13 @@ func Main() { // OPS_REPO && OPS_ROOT_PLUGIN getOpsRepo() setOpsRootPluginEnv() - // Check if olaris exists. If not, download tasks - olarisDir, err := getOpsRoot() + // Check if the tasks folder exists. If not, download tasks + tasksDir, err := getOpsRoot() if err != nil { - olarisDir := joinpath(joinpath(opsHome, getOpsBranch()), "olaris") - if !isDir(olarisDir) { + opsBranchDir := joinpath(opsHome, getOpsBranch()) + if findTasksDir(opsBranchDir) == "" { log.Println("Welcome to ops! Setting up...") - olarisDir, err = pullTasks(true, true) + tasksDir, err = pullTasks(true, true) if err != nil { log.Fatalf("cannot locate or download OPS_ROOT: %s", err.Error()) } @@ -385,12 +385,12 @@ func Main() { os.Exit(0) } } else { - // check if olaris was recently updated + // check if the tasks were recently updated checkUpdated(opsHome, 24*time.Hour) } } - if err = setOpsOlarisHash(olarisDir); err != nil { - os.Setenv("OPS_OLARIS", "<local>") + if err = setOpsOlarisHash(tasksDir); err != nil { + os.Setenv("OPS_TASKS", "<local>") } // set the enviroment variables from the config @@ -448,7 +448,7 @@ func parseInvokeArgs(rest []string) []string { return args } -// getRootDirOrExit returns the olaris dir or exits (Fatal) if not found +// getRootDirOrExit returns the tasks dir or exits (Fatal) if not found func getRootDirOrExit() string { dir, err := getOpsRoot() if err != nil { diff --git a/plugin.go b/plugin.go index 4ece835..bf05ff5 100644 --- a/plugin.go +++ b/plugin.go @@ -60,13 +60,13 @@ func printPluginUsage() { fmt.Println(`Usage: ops -plugin <repo-url> Install/update plugins from a remote repository. -The name of the repository must start with 'olaris-'.`) +The name of the repository must start with 'oplugins-' (or the legacy 'olaris-').`) } func downloadPluginTasksFromRepo(repo string) error { isNameValid, repoName := checkGitRepo(repo) if !isNameValid { - return fmt.Errorf("plugin repository must be a https url and plugin must start with 'olaris-'") + return fmt.Errorf("plugin repository must be a https url and plugin must start with 'oplugins-' or 'olaris-'") } pluginDir, err := homedir.Expand("~/.ops/" + repoName) @@ -128,9 +128,10 @@ func checkGitRepo(url string) (bool, string) { parts := strings.Split(url, "/") repoName := parts[len(parts)-1] - // Check if the repository name matches the pattern "https://...olaris-*" + // Check if the repository name matches the pattern "https://...oplugins-*" + // or the legacy "https://...olaris-*" matchProtocol, _ := regexp.MatchString(`^https://.*$`, url) - matchName, _ := regexp.MatchString(`^olaris-.*$`, repoName) + matchName := hasPluginPrefix(repoName) if matchName && matchProtocol { return true, repoName @@ -147,7 +148,7 @@ func printPluginsHelp() error { return nil } -// GetOpsRootPlugins returns the map with all the olaris-*/opsroot.json files +// GetOpsRootPlugins returns the map with all the olaris-*/oplugins-*/opsroot.json files // in the local and ~/.ops folders, pointed by their plugin names. // If the same plugin is found in both folders, the one in the local folder // is used. @@ -188,16 +189,14 @@ func findTaskInPlugins(plg string) (string, error) { // check that plg is the suffix of a folder name in plgs.local for _, path := range plgs.local { - folder := filepath.Base(path) - if strings.TrimPrefix(folder, "olaris-") == plg { + if getPluginName(path) == plg { return path, nil } } // check that plg is the suffix of a folder name in plgs.ops for _, path := range plgs.ops { - folder := filepath.Base(path) - if strings.TrimPrefix(folder, "olaris-") == plg { + if getPluginName(path) == plg { return path, nil } } @@ -205,7 +204,7 @@ func findTaskInPlugins(plg string) (string, error) { return "", &TaskNotFoundErr{input: plg} } -// plugins struct holds the list of local and ~/.ops olaris-* folders +// plugins struct holds the list of local and ~/.ops olaris-*/oplugins-* folders type plugins struct { local []string ops []string @@ -213,47 +212,60 @@ type plugins struct { func newPlugins() (*plugins, error) { localDir := os.Getenv("OPS_ROOT_PLUGIN") - localOlarisFolders := make([]string, 0) - opsOlarisFolders := make([]string, 0) - // Search in directory (localDir/olaris-*) - dir := filepath.Join(localDir, "olaris-*") - olarisFolders, err := filepath.Glob(dir) + // Search in directory (localDir/olaris-*, localDir/oplugins-*) + localPluginFolders, err := globPluginFolders(localDir) if err != nil { return nil, err } - // filter all folders that are do not contain opsfile.yaml - for _, folder := range olarisFolders { - if !isDir(folder) || !exists(folder, OPSFILE) { - continue - } - localOlarisFolders = append(localOlarisFolders, folder) - } - - // Search in ~/.ops/olaris-* + // Search in ~/.ops/olaris-*, ~/.ops/oplugins-* opsHome, err := homedir.Expand("~/.ops") if err != nil { return nil, err } - olarisOpsFolders, err := filepath.Glob(filepath.Join(opsHome, "olaris-*")) + opsPluginFolders, err := globPluginFolders(opsHome) if err != nil { return nil, err } - for _, folder := range olarisOpsFolders { - if !isDir(folder) || !exists(folder, OPSFILE) { - continue - } - opsOlarisFolders = append(opsOlarisFolders, folder) - } return &plugins{ - local: localOlarisFolders, - ops: opsOlarisFolders, + local: localPluginFolders, + ops: opsPluginFolders, }, nil } +// globPluginFolders returns the folders in base matching any of the plugin +// prefixes and containing an opsfile +func globPluginFolders(base string) ([]string, error) { + result := make([]string, 0) + for _, prefix := range PLUGIN_PREFIXES { + folders, err := filepath.Glob(filepath.Join(base, prefix+"*")) + if err != nil { + return nil, err + } + // filter all folders that do not contain opsfile.yaml + for _, folder := range folders { + if !isDir(folder) || !exists(folder, OPSFILE) { + continue + } + result = append(result, folder) + } + } + return result, nil +} + +// hasPluginPrefix tells whether name starts with one of the plugin prefixes +func hasPluginPrefix(name string) bool { + for _, prefix := range PLUGIN_PREFIXES { + if strings.HasPrefix(name, prefix) { + return true + } + } + return false +} + func (p *plugins) print() { if len(p.local) == 0 && len(p.ops) == 0 { debug("No plugins installed") @@ -278,10 +290,15 @@ func (p *plugins) print() { } // getPluginName returns the plugin name from the plugin path, removing the -// olaris- prefix +// olaris- or oplugins- prefix func getPluginName(plg string) string { - // remove olaris- prefix - plgName := strings.TrimPrefix(filepath.Base(plg), "olaris-") + // remove the plugin prefix + plgName := filepath.Base(plg) + for _, prefix := range PLUGIN_PREFIXES { + if strings.HasPrefix(plgName, prefix) { + return strings.TrimPrefix(plgName, prefix) + } + } return plgName } diff --git a/prepare.go b/prepare.go index 489e74a..b0f9b3c 100644 --- a/prepare.go +++ b/prepare.go @@ -43,15 +43,20 @@ func downloadTasksFromGitHub(force bool, silent bool) (string, error) { } opsBranchDir := joinpath(opsDir, branch) - localDir, err := homedir.Expand(joinpath(opsBranchDir, "olaris")) + tasksDir := findTasksDir(opsBranchDir) + alreadyCloned := tasksDir != "" + if !alreadyCloned { + tasksDir = TASKS_DIR + } + localDir, err := homedir.Expand(joinpath(opsBranchDir, tasksDir)) if err != nil { return "", err } debug("localDir", localDir) // Updating existing tools - if exists(opsBranchDir, "olaris") { - trace("Updating olaris in", opsBranchDir) + if alreadyCloned { + trace("Updating", tasksDir, "in", opsBranchDir) fmt.Println("Updating tasks...") r, err := git.PlainOpen(localDir) if err != nil { @@ -96,7 +101,7 @@ func downloadTasksFromGitHub(force bool, silent bool) (string, error) { _, err = git.PlainClone(localDir, false, cloneOpts) if err != nil { os.RemoveAll(opsBranchDir) - warn(fmt.Sprintf("failed to clone olaris on branch '%s'", branch)) + warn(fmt.Sprintf("failed to clone %s on branch '%s'", tasksDir, branch)) return "", err } @@ -176,19 +181,23 @@ func locateOpsRoot(cur string) (string, error) { return search, nil } - // is there olaris folder? - olaris := joinpath(cur, "olaris") - if exists(cur, "olaris") && exists(olaris, OPSFILE) && exists(olaris, OPSROOT) { - trace("found sub olaris:", olaris) - return olaris, nil + // is there a tasks folder (olaris or oplugins)? + for _, name := range TASKS_DIRS { + tasks := joinpath(cur, name) + if exists(cur, name) && exists(tasks, OPSFILE) && exists(tasks, OPSROOT) { + trace("found sub tasks:", tasks) + return tasks, nil + } } - // is there an olaris folder in ~/.ops ? - opsOlarisDir := fmt.Sprintf("~/.ops/%s/olaris", getOpsBranch()) - olaris, err = homedir.Expand(opsOlarisDir) - if err == nil && exists(olaris, OPSFILE) && exists(olaris, OPSROOT) { - trace("found sub", opsOlarisDir, ":", olaris) - return olaris, nil + // is there a tasks folder in ~/.ops ? + for _, name := range TASKS_DIRS { + opsTasksDir := fmt.Sprintf("~/.ops/%s/%s", getOpsBranch(), name) + tasks, err := homedir.Expand(opsTasksDir) + if err == nil && exists(tasks, OPSFILE) && exists(tasks, OPSROOT) { + trace("found sub", opsTasksDir, ":", tasks) + return tasks, nil + } } return "", fmt.Errorf("cannot find opsfiles, download them with ops -update") @@ -231,9 +240,9 @@ func checkOperatorVersion(opsRootConfig map[string]interface{}) error { return cmd.Run() } -func setOpsOlarisHash(olarisDir string) error { - trace("setOpsOlarisHash", olarisDir) - r, err := git.PlainOpen(olarisDir) +func setOpsOlarisHash(tasksDir string) error { + trace("setOpsOlarisHash", tasksDir) + r, err := git.PlainOpen(tasksDir) if err != nil { return err } @@ -241,8 +250,19 @@ func setOpsOlarisHash(olarisDir string) error { if err != nil { return err } - debug("olaris hash", h.Hash().String()) - os.Setenv("OPS_OLARIS", h.Hash().String()) - trace("OPS_OLARIS", os.Getenv("OPS_OLARIS")) + debug("tasks hash", h.Hash().String()) + os.Setenv("OPS_TASKS", h.Hash().String()) + trace("OPS_TASKS", os.Getenv("OPS_TASKS")) return nil } + +// findTasksDir returns the name of the tasks folder (olaris or oplugins) +// existing under base, or "" if none is found +func findTasksDir(base string) string { + for _, name := range TASKS_DIRS { + if isDir(joinpath(base, name)) { + return name + } + } + return "" +} diff --git a/prepare_test.go b/prepare_test.go index 96bccf9..a33cd66 100644 --- a/prepare_test.go +++ b/prepare_test.go @@ -83,5 +83,5 @@ func Test_setOpsOlarisHash(t *testing.T) { dir, _ := downloadTasksFromGitHub(true, true) err := setOpsOlarisHash(dir) require.NoError(t, err) - require.NotEmpty(t, os.Getenv("OPS_OLARIS")) + require.NotEmpty(t, os.Getenv("OPS_TASKS")) } diff --git a/tests/info.bats b/tests/info.bats index 56013dd..264ed16 100644 --- a/tests/info.bats +++ b/tests/info.bats @@ -37,6 +37,6 @@ setup() { assert_line "OPS_PWD: $WD" assert_line "OPS_ROOT: $WD/olaris" assert_line "OPS_TMP: $HOME/.ops/tmp" - assert_line --partial "OPS_OLARIS: " + assert_line --partial "OPS_TASKS: " assert_success } \ No newline at end of file diff --git a/tests/plugin.bats b/tests/plugin.bats index 779ebf3..a4e56ad 100644 --- a/tests/plugin.bats +++ b/tests/plugin.bats @@ -92,11 +92,11 @@ setup() { @test "ops -plugin with wrong name" { run ops -plugin https://github.com/giusdp/olari - assert_line "error: plugin repository must be a https url and plugin must start with 'olaris-'" + assert_line "error: plugin repository must be a https url and plugin must start with 'oplugins-' or 'olaris-'" assert_failure run ops -plugin olaris-test - assert_line "error: plugin repository must be a https url and plugin must start with 'olaris-'" + assert_line "error: plugin repository must be a https url and plugin must start with 'oplugins-' or 'olaris-'" assert_failure } diff --git a/updates_check.go b/updates_check.go index f92cf15..9fddea4 100644 --- a/updates_check.go +++ b/updates_check.go @@ -31,14 +31,15 @@ const LATESTCHECK = ".latestcheck" func checkUpdated(base string, timeInterval time.Duration) { trace("checkUpdated", base) - olaris_base := joinpath(base, getOpsBranch()) - latest_check_path := joinpath(olaris_base, LATESTCHECK) - olaris_path := joinpath(olaris_base, "olaris") + tasks_base := joinpath(base, getOpsBranch()) + latest_check_path := joinpath(tasks_base, LATESTCHECK) - // if no olaris dir, no update check - if !isDir(olaris_path) { + // if no tasks dir (olaris or oplugins), no update check + tasks_dir := findTasksDir(tasks_base) + if tasks_dir == "" { return } + tasks_path := joinpath(tasks_base, tasks_dir) // get info on latest_check file file, ok := checkLatestFile(latest_check_path) @@ -55,8 +56,8 @@ func checkUpdated(base string, timeInterval time.Duration) { // touch latest_check file ONLY if enough time has passed touchLatestCheckFile(latest_check_path) - // check if remote olaris is newer - if checkRemoteOlarisNewer(olaris_path) { + // check if remote tasks are newer + if checkRemoteOlarisNewer(tasks_path) { fmt.Print("New tasks available! Use 'ops -update' to update.\n\n") } else { fmt.Print("Tasks up to date!\n\n") @@ -94,29 +95,29 @@ func touchLatestCheckFile(latest_check_path string) { } } -func checkRemoteOlarisNewer(olaris_path string) bool { - trace("checkRemoteOlarisNewer", olaris_path) - repo, err := git.PlainOpen(olaris_path) +func checkRemoteOlarisNewer(tasks_path string) bool { + trace("checkRemoteOlarisNewer", tasks_path) + repo, err := git.PlainOpen(tasks_path) if err != nil { - warn("failed to check olaris folder", err) + warn("failed to check tasks folder", err) return false } localRef, err := repo.Head() if err != nil { - warn("failed to check olaris folder", err) + warn("failed to check tasks folder", err) return false } remote, err := repo.Remote("origin") if err != nil { - warn("failed to check remote olaris", err) + warn("failed to check remote tasks", err) return false } _ = remote.Fetch(&git.FetchOptions{}) remoteRefs, err := remote.List(&git.ListOptions{}) if err != nil { - warn("failed to check remote olaris", err) + warn("failed to check remote tasks", err) return false }
