Skip to content

Commit f2d4f80

Browse files
committed
modules: prepare modules list
Find possible modules by manifest.yaml or main executable. Closes #1014
1 parent db292f8 commit f2d4f80

File tree

1 file changed

+61
-36
lines changed

1 file changed

+61
-36
lines changed

cli/modules/modules.go

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ import (
77
"path/filepath"
88
"strings"
99

10+
"github.com/apex/log"
1011
"github.com/spf13/cobra"
1112
"github.com/tarantool/tt/cli/cmdcontext"
1213
"github.com/tarantool/tt/cli/config"
14+
"github.com/tarantool/tt/cli/util"
1315
)
1416

1517
const (
16-
helpModuleName = "help"
18+
manifestFileName = "manifest"
19+
mainEntryPoint = "main"
1720
)
1821

1922
// ModuleInfo stores information about Tarantool CLI module.
@@ -27,6 +30,19 @@ type ModuleInfo struct {
2730
// ModulesInfo stores information about all CLI modules.
2831
type ModulesInfo map[string]*ModuleInfo
2932

33+
// modulesEntries keeps detected entry points while scan modules.
34+
type modulesEntries struct {
35+
// Modules location path.
36+
Directory string
37+
// Path to manifest.yaml file.
38+
Manifest string
39+
// Path to `main` executable file.
40+
Main string
41+
}
42+
43+
// posibleModules map module name with found its entry points.
44+
type posibleModules map[string]modulesEntries
45+
3046
// fillSubCommandsInfo collects information about subcommands.
3147
func fillSubCommandsInfo(cmd *cobra.Command, modulesInfo *ModulesInfo) {
3248
for _, subCmd := range cmd.Commands() {
@@ -57,21 +73,23 @@ func GetModulesInfo(cmdCtx *cmdcontext.CmdCtx, rootCmd *cobra.Command,
5773
}
5874
modulesDirs = append(modulesDirs, modulesEnvDirs...)
5975

60-
externalModules, err := getExternalModules(modulesDirs)
76+
// FIXME: working with modules list at https://github.com/tarantool/tt/issues/1016
77+
/* externalModules */
78+
_, err = getExternalModules(modulesDirs)
6179
if err != nil {
6280
return nil, fmt.Errorf(
6381
"failed to get available external modules information: %s", err)
6482
}
6583

6684
// External modules have a higher priority than internal.
6785
modulesInfo := ModulesInfo{}
68-
for name, path := range externalModules {
69-
commandPath := rootCmd.Name() + " " + name
70-
modulesInfo[commandPath] = &ModuleInfo{
71-
IsInternal: false,
72-
ExternalPath: path,
73-
}
74-
}
86+
// for name, path := range externalModules {
87+
// commandPath := rootCmd.Name() + " " + name
88+
// modulesInfo[commandPath] = &ModuleInfo{
89+
// IsInternal: false,
90+
// ExternalPath: path,
91+
// }
92+
// }
7593

7694
fillSubCommandsInfo(rootCmd, &modulesInfo)
7795

@@ -132,38 +150,45 @@ func getEnvironmentModulesDirs() ([]string, error) {
132150
return collectDirectoriesList(paths)
133151
}
134152

135-
// getExternalModules returns map of available modules by
136-
// parsing the contents of the path folder.
137-
func getExternalModules(paths []string) (map[string]string, error) {
138-
modules := make(map[string]string)
139-
if len(paths) == 0 {
140-
return modules, nil
153+
// isPossibleModule checks is exists any manifest or executable `main` file inside dir.
154+
func isPossibleModule(dir string) (modulesEntries, bool) {
155+
is_module := false
156+
entries := modulesEntries{Directory: dir}
157+
manifest, _ := util.GetYamlFileName(filepath.Join(dir, manifestFileName), false)
158+
if manifest != "" {
159+
entries.Manifest = manifest
160+
is_module = true
141161
}
142-
// FIXME: Work with list at https://github.com/tarantool/tt/issues/1014
143-
path := paths[0]
162+
if main, err := exec.LookPath(filepath.Join(dir, mainEntryPoint)); err == nil {
163+
entries.Main = main
164+
is_module = true
165+
}
166+
return entries, is_module
167+
}
144168

145-
// If the directory doesn't exist, it is not an error.
146-
// TODO: Add warning in next patches, discussion
147-
// what if the file exists, but access is denied, etc.
148-
if _, err := os.Stat(path); err != nil {
149-
if !os.IsNotExist(err) {
169+
// getExternalModules returns map[name] = directory of available modules by
170+
// parsing the contents of the list folders.
171+
func getExternalModules(paths []string) (posibleModules, error) {
172+
modules := posibleModules{}
173+
for _, path := range paths {
174+
entries, err := os.ReadDir(path)
175+
if err != nil {
150176
return nil, fmt.Errorf(`failed to read "%s" directory: %s`, path, err)
151177
}
152-
153-
return nil, nil
154-
}
155-
156-
files, err := os.ReadDir(path)
157-
if err != nil {
158-
return nil, fmt.Errorf(`failed to read "%s" directory: %s`, path, err)
159-
}
160-
161-
for _, f := range files {
162-
// Ignore non executable files.
163-
if path, err := exec.LookPath(filepath.Join(path, f.Name())); err == nil {
164-
modules[strings.Split(f.Name(), ".")[0]] = path
178+
cnt_modules := 0
179+
for _, e := range entries {
180+
mod_path := filepath.Join(path, e.Name())
181+
if !e.IsDir() {
182+
continue
183+
}
184+
if mod_entry, is_module := isPossibleModule(mod_path); is_module {
185+
modules[e.Name()] = mod_entry
186+
cnt_modules += 1
187+
}
188+
}
189+
if cnt_modules == 0 {
190+
log.Warnf("Directory %q does not have any module", path)
165191
}
166192
}
167-
168193
return modules, nil
169194
}

0 commit comments

Comments
 (0)