public CommandResult <int> Batch(
            CommandEvaluationContext context,
            [Parameter(0, "path of the batch file (attempt a text file, starting or not by #orbsh!)")] FilePath path
            )
        {
            int r = (int)ReturnCode.OK;

            if (path.CheckExists(context))
            {
                context.CommandLineProcessor.CommandBatchProcessor.RunBatch(context, path.FileSystemInfo.FullName);
            }
            return(new CommandResult <int>(r));
        }
Example #2
0
        public CommandResult <(int retCode, string output)> Exec(
            CommandEvaluationContext context,
            [Parameter(0, "executable file path")] FilePath path,
            [Parameter(1, "arguments", true)] string args
            )
        {
            int    ret    = (int)ReturnCode.Error;
            string output = null;

            if (path.CheckExists(context))
            {
                ret = context
                      .CommandLineProcessor
                      .ShellExec(
                    context,
                    path.FullName,
                    args,
                    out output
                    );
            }
            return(new CommandResult <(int retCode, string output)>((ret, output)));
        }
        public CommandResult <List <string> > FileEol(
            CommandEvaluationContext context,
            [Parameter("file path")] FilePath file)
        {
            var r = new List <string>();

            if (file.CheckExists(context))
            {
                var(_, eolCounts, _) = GetEOLCounts(File.ReadAllText(file.FullName));
                foreach (var eol in eolCounts)
                {
                    var s = $"{eol.eol}={eol.count}";
                    r.Add(s);
                    context.Out.Echoln(s);
                }
                return(new CommandResult <List <string> >(r));
            }
            else
            {
                return(new CommandResult <List <string> >(r, ReturnCode.Error));
            }
        }
Example #4
0
        public CommandVoidResult NewModule(
            CommandEvaluationContext context,
            [Parameter(0, "module ID")] string id,
            [Parameter(1, "module project repository url (if not set do net set project repository properties, thus the project repo is not connected to any remote repository)", true)] string repoUrl = null,
            [Option("o", "out", "output path", true, true)] DirectoryPath output = null,
            [Option("i", "in", "take parameters from json input file", true, true)] string inputFile = defaultSettingsFileName,
            [Option("f", "force", "delete target if already exists")] bool force                   = false,
            [Option("s", "skip-errors", "skip ant error if possible")] bool skipErrors             = false,
            [Option(null, "no-push", "don't perform an initial push of project repo")] bool noPush = false,
            [Option("project template url", "modproj-tpl-url", "module project template url", true, true)] string url = moduleProjectTemplateRepositoryUrl,
            [Option(null, "preserve-curdir", "preserve current dir")] bool preserveCurrentDir = false
            )
        {
            var o = context.Out;
            var c = context.ShellEnv.Colors;

            output ??= new DirectoryPath(Environment.CurrentDirectory);
            output = new DirectoryPath(Path.Combine(output.FullName, id));
            var input = new FilePath(inputFile);
            var ectx  = new EchoEvaluationContext(context);

            ectx.Options.LineBreak = true;
            CommandVoidResult result = CommandVoidResult.Instance;

            o.Echo(_title("shell module dotnet project generator"));

            #region download_pattern_project

            if (force && output.CheckExists())
            {
                Directory.Delete(output.FullName, true);
            }

            o.Echoln(_subTitle("cloning module project repository", url));
            o.Echo(_("into: ")); output.Echo(ectx); o.Echoln("(br)");

            if (!ShellExec(context, skipErrors, "git", $"clone {url} {output.FullName}", out result))
            {
                return(result);
            }

            #endregion

            #region setup project template properties

            if (!input.CheckExists(context))
            {
                return(new CommandVoidResult(ReturnCode.Error));
            }
            o.Echoln(_subTitle($"set project template properties", $"'{id}'"));

            string packageId = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileNameWithoutExtension(repoUrl) : null;
            string repoOwner = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileName(Path.GetDirectoryName(repoUrl)) : null;

            var settingsText = File.ReadAllText(input.FullName);
            var settings     = JsonConvert
                               .DeserializeObject <ModuleSettings>(settingsText)
                               .AutoFill(id, packageId);
            settings.ModuleRepositoryUrl   = repoUrl;
            settings.ModuleRepositoryOwner = repoOwner;

            o.Echoln(_subTitle("using settings", input.FullName));
            settings.Echo(ectx); o.Echoln("(br)");

            var items = fs.FindItems(
                context,
                output.FullName,
                "*",
                false,
                true,
                false,
                true,
                false,
                null,
                false,
                new FindCounts(),
                false);

            var fields = typeof(ModuleSettings).GetFields();
            foreach (var item in items)
            {
                var path = item.FullName;
                if (item.IsFile && fs.IsTextFile(path))
                {
                    var tpl = path;
                    _templateReplace(fields, settings, ref tpl);

                    var txt = File.ReadAllText(path);

                    if (tpl != path)
                    {
                        File.Delete(path);
                        path = tpl;
                    }

                    tpl = txt + "";
                    _templateReplace(fields, settings, ref tpl);
                    if (tpl != txt)
                    {
                        File.WriteAllText(path, tpl);
                    }
                }
            }

            void _deleteIfExists(string n)
            {
                if (File.Exists(n))
                {
                    File.Delete(n);
                }
            }

            _deleteIfExists(Path.Combine(output.FullName, "templateInfo.txt"));
            _deleteIfExists(Path.Combine(output.FullName, "./module-settings.json"));

            #endregion

            #region setup project repository

            o.Echoln(_subTitle("setup project repository", url)); o.Echoln();

            var curDir = Environment.CurrentDirectory;
            Environment.CurrentDirectory = output.FullName;

            if (!ShellExec(context, skipErrors, "git", "remote remove origin", out result))
            {
                return(result);
            }

            if (!string.IsNullOrWhiteSpace(settings.ModuleRepositoryUrl))
            {
                if (!ShellExec(context, skipErrors, "git", $"remote add origin {settings.ModuleRepositoryUrl}", out result))
                {
                    return(result);
                }
                // check this
                if (!noPush && !ShellExec(context, skipErrors, "git", "push --set-upstream origin main", out result))
                {
                    return(result);
                }
            }

            #endregion

            #region restore & build project

            o.Echoln(_subTitle("restore & build module project", "")); o.Echoln();

            if (!ShellExec(context, skipErrors, "dotnet", "build", out result))
            {
                return(result);
            }

            #endregion

            if (preserveCurrentDir)
            {
                Environment.CurrentDirectory = curDir;
            }

            o.Echoln(_subTitle($"module project has been generated", id));

            return(result ?? CommandVoidResult.Instance);
        }
Example #5
0
        public CommandResult <List <CommandsModule> > Module(
            CommandEvaluationContext context,
            [Option("l", "load a module from the given path", true, true)] FilePath loadModulePath        = null,
            [Option("u", "unload the module having the given name ", true, true)] string unloadModuleName = null
            )
        {
            var f = ColorSettings.Default.ToString();

            if (loadModulePath == null && unloadModuleName == null)
            {
                var col1length = context.CommandLineProcessor.Modules.Values.Select(x => x.Name.Length).Max() + 1;
                foreach (var kvp in context.CommandLineProcessor.Modules)
                {
                    context.Out.Echoln($"{Darkcyan}{kvp.Value.Name.PadRight(col1length, ' ')}{f}{kvp.Value.Description} [types count={Cyan}{kvp.Value.TypesCount}{f} commands count={Cyan}{kvp.Value.CommandsCount}{f}]");
                    context.Out.Echoln($"{"".PadRight(col1length, ' ')}{ColorSettings.Label}assembly:{ColorSettings.HalfDark}{kvp.Value.Assembly.FullName}");
                    context.Out.Echoln($"{"".PadRight(col1length, ' ')}{ColorSettings.Label}path:    {ColorSettings.HalfDark}{kvp.Value.Assembly.Location}");
                }
                return(new CommandResult <List <CommandsModule> >(context.CommandLineProcessor.Modules.Values.ToList()));
            }
            if (loadModulePath != null)
            {
                if (loadModulePath.CheckExists())
                {
                    var a = Assembly.LoadFrom(loadModulePath.FileSystemInfo.FullName);
                    var(typesCount, commandsCount) = context.CommandLineProcessor.RegisterCommandsAssembly(context, a);
                    if (commandsCount == 0)
                    {
                        Errorln("no commands have been loaded");
                        return(new CommandResult <List <CommandsModule> >(ReturnCode.Error));
                    }
                    else
                    {
                        context.Out.Echoln($"loaded {ColorSettings.Numeric}{Plur("command", commandsCount, f)} in {ColorSettings.Numeric}{Plur("type", typesCount, f)}");
                    }
                }
                else
                {
                    return(new CommandResult <List <CommandsModule> >(ReturnCode.Error));
                }
            }
            if (unloadModuleName != null)
            {
                if (context.CommandLineProcessor.Modules.Values.Any(x => x.Name == unloadModuleName))
                {
                    var(typesCount, commandsCount) = context.CommandLineProcessor.UnregisterCommandsAssembly(context, unloadModuleName);
                    if (commandsCount == 0)
                    {
                        Errorln("no commands have been unloaded");
                        return(new CommandResult <List <CommandsModule> >(ReturnCode.Error));
                    }
                    else
                    {
                        context.Out.Echoln($"unloaded {ColorSettings.Numeric}{Plur("command", commandsCount, f)} in {ColorSettings.Numeric}{Plur("type", typesCount, f)}");
                    }
                }
                else
                {
                    Errorln($"commands module '{unloadModuleName}' not registered");
                    return(new CommandResult <List <CommandsModule> >(ReturnCode.Error));
                }
            }
            return(new CommandResult <List <CommandsModule> >());
        }
        public CommandResult <string> NugetPush(
            CommandEvaluationContext context,
            [Parameter(0, "package (.nuget) file path")] FilePath pkgFile,
            [Parameter(1, "target server api key")] string apiKey,
            [Option("u", "push-url", "nuget server api push service url", true, true)] string url = PushUrl,
            [Option("p", "protocol-version", "nuget thir party client protocol version", true, true)] string protocolVersion = ProtocolVersion
            )
        {
            var @return = "";

            if (pkgFile.CheckExists(context))
            {
                var ext   = Path.GetExtension(pkgFile.FullName);
                var atExt = ".nupkg";
                if (ext.ToLower() != atExt)
                {
                    context.Errorln($"bad file extension: '{ext}', should be '{atExt}'");
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(apiKey))
                    {
                        context.Errorln($"api key is required and can't be empty");
                    }
                    else
                    {
                        using var httpClient = new HttpClient();
                        using var request    = new HttpRequestMessage(new HttpMethod("PUT"), url);

                        request.Headers.Add("X-NuGet-ApiKey", apiKey);
                        request.Headers.AcceptEncoding.ParseAdd("gzip,deflate");
                        request.Headers.Add("X-NuGet-Protocol-Version", protocolVersion);
                        //request.Headers.Add("X-NuGet-Client-Version", "5.8.1");
                        //request.Headers.Add("user-agent", "NuGet Command Line / 5.8.1 (Microsoft Windows NT 10.0.19042.0)");

                        var content = new MultipartFormDataContent();

                        var fileContent = new ByteArrayContent(File.ReadAllBytes(pkgFile.FullName));

                        fileContent.Headers.ContentDisposition =
                            new ContentDispositionHeaderValue(
                                "form-data"
                                )
                        {
                            FileName = "package.nupkg"
                        };

                        fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

                        content.Add(fileContent);
                        request.Content = content;


                        context.Out.Echo(context.ShellEnv.Colors.Log + $"PUT {PushUrl} ... ");

                        var tsk = httpClient.SendAsync(request);

                        var result = tsk.Result;
                        if (result.IsSuccessStatusCode)
                        {
                            var res = result.Content.ReadAsStringAsync().Result;

                            context.Out.Echoln(" Done(rdc)");
                            context.Out.Echo(ANSI.RSTXTA + ANSI.CPL(1) + ANSI.EL(ANSI.ELParameter.p2));     // TODO: add as ANSI combo

                            @return = res;

                            if (res != null)
                            {
                                if (!string.IsNullOrWhiteSpace(res))
                                {
                                    context.Out.Echoln(res);
                                }
                            }
                            else
                            {
                                context.Warningln("quey result is empty");
                            }
                            context.Warningln("quey result is empty");

                            if (result.StatusCode == HttpStatusCode.Created ||
                                result.StatusCode == HttpStatusCode.Accepted)
                            {
                                context.Out.Echoln($"package '{Path.GetFileName(pkgFile.FullName)}' has been successfully pushed");
                            }
                        }
                        else
                        {
                            context.Errorln($"can't get response content: {(int)result.StatusCode} {result.ReasonPhrase}");
                        }
                    }
                }
            }
            return(new CommandResult <string>(@return));
        }
Example #7
0
        public CommandVoidResult NewModule(
            CommandEvaluationContext context,
            [Parameter(0, "module ID")] string id,
            [Parameter(1, "module project repository url (if not set do net set project repository properties, thus the project repo is not connected to any remote repository)", true)] string repoUrl = null,
            [Option("o", "out", "output path", true, true)] DirectoryPath output = null,
            [Option("i", "in", "take parameters from json input file", true, true)] string inputFile = defaultSettingsFileName,
            [Option("f", "force", "delete target if already exists")] bool force       = false,
            [Option("s", "skip-errors", "skip ant error if possible")] bool skipErrors = false,
            [Option(null, "no-git-init", "don't perform an initial init of the git repository - do not init the project as a git repository")] bool noInitRemote = false,
            [Option("project template url", "modproj-tpl-url", "module project template url", true, true)] string url             = moduleProjectTemplateRepositoryUrl,
            [Option("project archive url", "modproj-arch-url", "module project archive template url", true, true)] string archUrl = moduleProjectTemplateArchiveUrl,
            [Option(null, "preserve-curdir", "preserve current dir")] bool preserveCurrentDir = false
            )
        {
            var  o      = context.Out;
            var  c      = context.ShellEnv.Colors;
            bool noRepo = repoUrl == null;

            noInitRemote |= noRepo;
            string packageId = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileNameWithoutExtension(repoUrl) : null;
            string repoOwner = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileName(Path.GetDirectoryName(repoUrl)) : null;

            output ??= new DirectoryPath(Environment.CurrentDirectory);
            output = new DirectoryPath(Path.Combine(output.FullName, packageId ?? id));
            var targetId = packageId ?? id;
            var input    = new FilePath(inputFile);
            var ectx     = new EchoEvaluationContext(context);

            ectx.Options.LineBreak = true;
            CommandVoidResult result = CommandVoidResult.Instance;

            o.Echo(_title("shell module dotnet project generator"));

            #region download_pattern_project

            try
            {
                if (force && output.CheckExists())
                {
                    Directory.Delete(output.FullName, true);
                }
            } catch (Exception ex)
            {
                o.Errorln(ex.Message);
                if (!skipErrors)
                {
                    throw;
                }
            }

            o.Echoln(_subTitle("cloning module project repository", url));
            o.Echo(_("into: ")); output.Echo(ectx); o.Echoln("(br)");

            if (!noInitRemote)
            {
                // checkout repo
                if (!ShellExec(context, skipErrors, "git", $"clone {url} {output.FullName}", out result) && !skipErrors)
                {
                    return(result);
                }
            }
            else
            {
                // download & unpack as an archive
                o.Echoln(_subTitle("download project template archive", ""));
                var downloadArchRes = context.CommandLineProcessor.Eval(context, @$ "get " "{archUrl}" " -q -b");
                var archFile        = "tpl.zip";
                var res             = downloadArchRes.GetResult <HttpContentBody>();

                File.WriteAllBytes(
                    archFile,
                    (byte[])res.Content);

                if (File.Exists(archFile))
                {
                    _try(() =>
                    {
                        var arc  = ZipFile.OpenRead(archFile);
                        var root = arc.Entries.First();
                        arc.Dispose();
                        var rootName = root.FullName.Replace("/", "");
                        ZipFile.ExtractToDirectory(archFile, ".", true);
                        Directory.Move(rootName, targetId);
                        File.Delete(archFile);
                    });
                }
            }
            #endregion

            #region setup project template properties

            if (!input.CheckExists(context))
            {
                return(new CommandVoidResult(ReturnCode.Error));
            }
            o.Echoln(_subTitle($"set project template properties", $"'{id}'"));

            var settings = new ModuleSettings();

            _try(() =>
            {
                var settingsText = File.ReadAllText(input.FullName);
                var settings     = JsonConvert
                                   .DeserializeObject <ModuleSettings>(settingsText)
                                   .AutoFill(id, packageId);

                if (!noInitRemote)
                {
                    settings.ModuleRepositoryUrl   = repoUrl;
                    settings.ModuleRepositoryOwner = repoOwner;
                }

                o.Echoln(_subTitle("using settings", input.FullName));
                settings.Echo(ectx);
                o.Echoln("(br)");

                var items = fs.FindItems(
                    context,
                    output.FullName,
                    "*",
                    false,
                    true,
                    false,
                    true,
                    false,
                    null,
                    false,
                    new FindCounts(),
                    false);

                var fields = typeof(ModuleSettings).GetFields();
                foreach (var item in items)
                {
                    var path = item.FullName;
                    if (item.IsFile && FilePath.IsTextFile(path))
                    {
                        var tpl = path;
                        _templateReplace(fields, settings, ref tpl);

                        var txt = File.ReadAllText(path);

                        if (tpl != path)
                        {
                            _try(() => File.Delete(path));
                            path = tpl;
                        }

                        tpl = txt + "";
                        _templateReplace(fields, settings, ref tpl);
                        if (tpl != txt)
                        {
                            _try(() => File.WriteAllText(path, tpl));
                        }
                    }
                }
            });

            void _deleteIfExists(string n)
            {
                if (File.Exists(n))
                {
                    File.Delete(n);
                }
            }

            void _try(Action a)
            {
                try
                {
                    a();
                }
                catch (Exception ex)
                {
                    context.Error(ex.Message);
                    if (!skipErrors)
                    {
                        throw;
                    }
                }
            }

            _try(() =>
            {
                _deleteIfExists(Path.Combine(output.FullName, "templateInfo.txt"));
                _deleteIfExists(Path.Combine(output.FullName, "module-settings.json"));
            });

            #endregion

            #region setup project repository

            o.Echoln(_subTitle("setup project repository", url)); o.Echoln();

            var curDir = Environment.CurrentDirectory;
            _try(() => Environment.CurrentDirectory = output.FullName);

            if (!noInitRemote && !ShellExec(context, skipErrors, "git", "remote remove origin", out result) && !skipErrors)
            {
                return(result);
            }

            if (!string.IsNullOrWhiteSpace(settings.ModuleRepositoryUrl) && !noInitRemote)
            {
                if (!ShellExec(context, skipErrors, "git", $"remote add origin {settings.ModuleRepositoryUrl}", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "fetch", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "branch --set-upstream-to=origin/main main", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "pull --allow-unrelated-histories", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "add .", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "commit -a -m \"initial commit\"", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "push", out result) && !skipErrors)
                {
                    return(result);
                }
            }

            #endregion

            #region restore & build project

            o.Echoln(_subTitle("restore & build module project", "")); o.Echoln();

            if (!ShellExec(context, skipErrors, "dotnet", "build", out result) && !skipErrors)
            {
                return(result);
            }

            #endregion

            if (preserveCurrentDir)
            {
                _try(() => Environment.CurrentDirectory = curDir);
            }

            o.Echoln(_subTitle($"module project has been generated", id));

            return(result ?? CommandVoidResult.Instance);
        }
Example #8
0
        public CommandResult <List <ModuleSpecification> > Module(
            CommandEvaluationContext context,
            [Option("l", "load", "load a module from the given path", true, true)] FilePath loadModulePath                         = null,
            [Option("n", "unload", "unload the module having the given name ", true, true)] string unloadModuleName                = null,
            [Option("i", "install", "install a module from the nuget source", true, true)] string installModuleName                = null,
            [Option("r", "remove", "uninstall a module and remove the module files", true, true)] string uninstallModuleName       = null,
            [Option("u", "update", "try to update an installed module from the nuget source", true, true)] string updateModuleName = null,
            [Option("f", "fetch-list", "fetch list of modules from modules repositories", true)] bool fetchList                    = false,
            [Option("o", "fetch-info", "query modules repositories about a module name, if found fetch the module and output informations about it. the module is not installed", true, true)] string fetchInfoName = null,
            [Option("v", "version", "module version if applyable", true, true)] string version = null,
            [Option("s", "short", "output less informations", true)] bool @short = false,
            [Option(null, "force", "perform the requested operation even if already done, in case of it is meaningfull (example: -i --force constraint the command to reinstall a module)")] bool force = false
            )
        {
            ModuleSpecification moduleSpecification = null;
            var  f         = context.ShellEnv.Colors.Default.ToString();
            bool fetchInfo = fetchInfoName != null;
            var  clog      = context.ShellEnv.Colors.Log;
            var  o         = context.Out;

            if (loadModulePath == null && unloadModuleName == null && updateModuleName == null && installModuleName == null && uninstallModuleName == null &&
                !fetchList && !fetchInfo)
            {
                // output reports on loaded modules

                var col1length = context.CommandLineProcessor.ModuleManager.Modules.Values.Select(x => x.Name.Length).Max() + 1;
                int n          = 1;
                foreach (var kvp in context.CommandLineProcessor.ModuleManager.Modules)
                {
                    var ver      = kvp.Value.Assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>()?.InformationalVersion;
                    var af       = new FileInfo(kvp.Value.Assembly.Location);
                    var dat      = af.CreationTimeUtc.ToString() + " UTC";
                    var comp     = kvp.Value.Assembly.GetCustomAttribute <AssemblyCompanyAttribute>()?.Company;
                    var aut_attr = kvp.Value.Assembly.GetCustomAttribute <ModuleAuthorsAttribute>();
                    var aut      = (aut_attr == null) ? "" : string.Join(",", aut_attr.Auhors);
                    var target   = kvp.Value.Assembly.GetCustomAttribute <ModuleTargetPlateformAttribute>()?.TargetPlateform;
                    target ??= TargetPlatform.Unspecified;
                    var deps_attr = kvp.Value.Assembly.GetCustomAttributes <ModuleDependencyAttribute>();
                    var deps      = (deps_attr.Count() == 0) ? "" : string.Join(",", deps_attr.Select(x => x.ModuleName + " " + x.ModuleMinVersion));
                    var sminv     = kvp.Value.Assembly.GetCustomAttribute <ModuleShellMinVersionAttribute>()?.ShellMinVersion;

                    o.Echoln($"{Darkcyan}{kvp.Value.Name.PadRight(col1length, ' ')}{f}{kvp.Value.Description}");

                    if (!@short)
                    {
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}assembly     : (rdc){kvp.Value.Assembly.FullName}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}path         : (rdc){kvp.Value.Assembly.Location}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}version      : (rdc){ver}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}date         : (rdc){dat}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}target       : (rdc){target}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}dependencies : (rdc){deps}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}shell min ver: (rdc){sminv}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}company      : (rdc){comp}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}authors      : (rdc){aut}");
                        o.Echoln($"{"".PadRight(col1length, ' ')}{kvp.Value.Info.GetDescriptor(context)}");
                    }
                    else
                    {
                        o.Echoln($"{"".PadRight(col1length, ' ')}{context.ShellEnv.Colors.Label}version : {context.ShellEnv.Colors.HalfDark}{ver} (target {((target == null) ? "" : target + ", ")}created {dat}) {context.ShellEnv.Colors.Label}Company : (rdc){comp} ({aut}) ");
                    }
                    if (n < context.CommandLineProcessor.ModuleManager.Modules.Count)
                    {
                        o.Echoln();
                    }
                    n++;
                }
                return(new CommandResult <List <ModuleSpecification> >(context.CommandLineProcessor.ModuleManager.Modules.Values.ToList()));
            }

            if (!fetchList && !fetchInfo)
            {
                // install module

                if (installModuleName != null)
                {
                    var lastVer = string.IsNullOrWhiteSpace(version);

                    var queryMethod = typeof(NuGetServerApiCommands).GetMethod("NugetQuery");
                    var r0          = context.CommandLineProcessor.Eval(context, queryMethod, $"{installModuleName} -t 1", 0);
                    if (r0.EvalResultCode != (int)ReturnCode.OK)
                    {
                        return(_ModuleErr(context, r0.ErrorReason));
                    }
                    var queryRes = r0.Result as QueryResultRoot;
                    if (queryRes == null)
                    {
                        return(_ModuleErr(context, "nuget query return a null result"));
                    }
                    if (queryRes.Data.Length == 0)
                    {
                        return(_ModuleErr(context, "module id unknown"));
                    }

                    var packageId = queryRes.Data[0].Id;
                    o.Echoln();

                    var getVersMethod = typeof(NuGetServerApiCommands).GetMethod("NugetVer");
                    var r             = context.CommandLineProcessor.Eval(context, getVersMethod, $"{installModuleName}", 0);
                    if (r.EvalResultCode == (int)ReturnCode.OK)
                    {
                        var vers = (PackageVersions)r.Result;

                        if (!lastVer && !vers.Versions.Contains(version))
                        {
                            return(_ModuleErr(context, $"module version '{version}' not found"));
                        }

                        if (lastVer)
                        {
                            version = vers.Versions.Last();
                            o.Echoln($"{clog}select the last version of package: {version}(rdc)");
                        }
                        var dwnMethod         = typeof(NuGetServerApiCommands).GetMethod("NugetDownload");
                        var output            = context.CommandLineProcessor.Settings.ModulesFolderPath;
                        var folderName        = packageId.ToLower();
                        var lowerVersion      = version.ToLower();
                        var moduleLowerFullId = $"{folderName}.{lowerVersion}";  // == module lower id

                        if (context.CommandLineProcessor.ModuleManager.IsModuleInstalled(
                                context, folderName, version
                                ) && !force)
                        {
                            // error already installed, !force
                            return(_ModuleErr(context, $"module '{moduleLowerFullId}' is already installed (may try --force)"));
                        }

                        var moduleFolder = Path.Combine(output, folderName);
                        if (!Directory.Exists(moduleFolder))
                        {
                            Directory.CreateDirectory(moduleFolder);
                        }

                        moduleFolder = FileSystemPath.UnescapePathSeparators(moduleFolder);
                        var rd = context.CommandLineProcessor.Eval(context, dwnMethod, $"{installModuleName} {version} -o {moduleFolder}", 0);
                        if (rd.EvalResultCode == (int)ReturnCode.OK)
                        {
                            o.Echo(clog + "extracting package... ");

                            var versionFolder = Path.Combine(moduleFolder, lowerVersion);
                            if (!Directory.Exists(versionFolder))
                            {
                                Directory.CreateDirectory(versionFolder);
                            }

                            var nupkgFileName = (string)rd.Result;
                            ZipFile.ExtractToDirectory(Path.Combine(moduleFolder, nupkgFileName), versionFolder, true);

                            o.Echoln(" Done(rdc)");
                            o.Echo(ANSI.RSTXTA + ANSI.CPL(1) + ANSI.EL(ANSI.ELParameter.p2));     // TODO: add as ANSI combo

                            // find modules dlls : find {folderName}/{lowerVersion}/lib -p *.dll
                            var findMethod = typeof(FileSystemCommands).GetMethod("Find");
                            var find       = context.CommandLineProcessor.Eval(context, findMethod, $"{folderName}/{lowerVersion}/lib -p *.dll", 0);
                            var nodllmess  = "the module doesn't contain any dll in /lib";
                            if (find.EvalResultCode != (int)ReturnCode.OK)
                            {
                                return(_ModuleErr(context, nodllmess));
                            }

                            var findResult = ((List <FileSystemPath>, FindCounts))find.Result;
                            foreach (var dll in findResult.Item1)
                            {
                                if (!context.CommandLineProcessor.ModuleManager.IsAssemblyLoaded(dll.FullName))
                                {
                                    // candidate assembly
                                    o.Echoln(clog + $"importing dll: '{dll.Name}'");
                                }
                            }

                            o.Echoln("module installed");
                        }
                        else
                        {
                            return(_ModuleErr(context, rd.ErrorReason));
                        }
                    }
                    else
                    {
                        return(_ModuleErr(context, "module id is required"));
                    }
                }

                // load/init module

                if (loadModulePath != null)
                {
                    if (loadModulePath.CheckExists(context))
                    {
                        var a = Assembly.LoadFrom(loadModulePath.FileSystemInfo.FullName);
                        moduleSpecification = context.CommandLineProcessor.ModuleManager.RegisterModule(context, a);
                        if (moduleSpecification != null && moduleSpecification.Info != null)
                        {
                            o.Echoln($" Done : {moduleSpecification.Info.GetDescriptor(context)}");
                        }
                    }
                    else
                    {
                        return(_ModuleErr(null, null));
                    }
                }

                // unload module

                if (unloadModuleName != null)
                {
                    if (context.CommandLineProcessor.ModuleManager.Modules.Values.Any(x => x.Name == unloadModuleName))
                    {
                        moduleSpecification = context.CommandLineProcessor.ModuleManager.UnregisterModule(context, unloadModuleName);
                        if (moduleSpecification != null && moduleSpecification.Info != null)
                        {
                            o.Echoln($"unloaded: {moduleSpecification.Info.GetDescriptor(context)}");
                        }
                    }
                    else
                    {
                        return(_ModuleErr(context, $"module '{unloadModuleName}' is not registered"));
                    }
                }
            }
            else
            {
                // fetch mod repos
                if (_GetModuleListFromRepositories(context, out var modRefs))
                {
                    o.Echo(ANSI.CPL(1) + ANSI.EL(ANSI.ELParameter.p2));     // TODO: add as ANSI combo

                    if (modRefs.Count > 0)
                    {
                        // fetch module info

                        if (fetchInfo)
                        {
                            var modRef = modRefs.Where(x => x.Name == fetchInfoName).FirstOrDefault();
                            if (modRef != null)
                            {
                                // try to fetch the module : name[,version]->nuget
                            }
                            else
                            {
                                o.Errorln("no module having name '{fetchInfoName}' can be found in repostories");
                            }
                        }

                        if (fetchList)
                        {
                            // get list

                            var tb = new Table(
                                ("name", typeof(string)),
                                ("version", typeof(ModuleVersion)),
                                ("description", typeof(string))
                                );
                            foreach (var modref in modRefs)
                            {
                                tb.AddRow(modref.Name, modref.Version, modref.Description);
                            }

                            tb.Echo(new EchoEvaluationContext(
                                        o,
                                        context,
                                        new TableFormattingOptions(
                                            context.ShellEnv.GetValue <TableFormattingOptions>(
                                                ShellEnvironmentVar.display_tableFormattingOptions))
                            {
                            }));
                        }
                    }
                    else
                    {
                        o.Errorln("module repository list doesn't contains any module reference");
                    }
                }
            }

            if (moduleSpecification != null)
            {
                return(new CommandResult <List <ModuleSpecification> >(new List <ModuleSpecification> {
                    moduleSpecification
                }));
            }
            else
            {
                return(new CommandResult <List <ModuleSpecification> >(new List <ModuleSpecification> {
                }));
            }
        }