GetSetCloneBranch(string cloneName, string branchName)
 {
     if (cloneName != null)
     {
         var clone = PyRevitClones.GetRegisteredClone(cloneName);
         if (clone != null)
         {
             if (clone.IsRepoDeploy)
             {
                 if (branchName != null)
                 {
                     clone.SetBranch(branchName);
                 }
                 else
                 {
                     Console.WriteLine(string.Format("Clone \"{0}\" is on branch \"{1}\"",
                                                     clone.Name, clone.Branch));
                 }
             }
             else
             {
                 PyRevitCLIAppCmds.ReportCloneAsNoGit(clone);
             }
         }
     }
 }
        ProcessExtensionOpenCommand(string cloneName, string extName)
        {
            if (extName != null)
            {
                PyRevitClone clone = null;
                if (cloneName != null)
                {
                    clone = PyRevitClones.GetRegisteredClone(cloneName);
                }

                PyRevitExtension ext;
                if (clone != null)
                {
                    ext = PyRevitExtensions.GetShippedExtension(clone, extName);
                }
                else
                {
                    ext = PyRevitExtensions.GetInstalledExtension(extName);
                }

                if (ext != null)
                {
                    CommonUtils.OpenInExplorer(ext.InstallPath);
                }
            }
        }
Beispiel #3
0
        ListAvailableCommands()
        {
            foreach (PyRevitClone clone in PyRevitClones.GetRegisteredClones())
            {
                PyRevitCLIAppCmds.PrintHeader($"Commands in Clone \"{clone.Name}\"");
                foreach (PyRevitExtension ext in clone.GetExtensions())
                {
                    if (ext.Type == PyRevitExtensionTypes.UIExtension)
                    {
                        foreach (PyRevitRunnerCommand cmd in ext.GetCommands())
                        {
                            Console.WriteLine(cmd);
                        }
                    }
                }
            }

            foreach (PyRevitExtension ext in PyRevitExtensions.GetInstalledExtensions())
            {
                if (ext.Type == PyRevitExtensionTypes.UIExtension)
                {
                    PyRevitCLIAppCmds.PrintHeader($"Commands in Extension \"{ext.Name}\"");
                    foreach (PyRevitRunnerCommand cmd in ext.GetCommands())
                    {
                        Console.WriteLine(cmd);
                    }
                }
            }
        }
 GetSetCloneTag(string cloneName, string tagName)
 {
     if (cloneName != null)
     {
         var clone = PyRevitClones.GetRegisteredClone(cloneName);
         // get version for git clones
         if (clone.IsRepoDeploy)
         {
             if (tagName != null)
             {
                 clone.SetTag(tagName);
             }
             else
             {
                 logger.Error("Version finder not yet implemented for git clones.");
                 // TODO: grab version from repo (last tag?)
             }
         }
         // get version for other clones
         else
         {
             if (tagName != null)
             {
                 logger.Error("Version setter not yet implemented for clones.");
                 // TODO: set version for archive clones?
             }
             else
             {
                 Console.WriteLine(clone.ModuleVersion);
             }
         }
     }
 }
 GetSetCloneOrigin(string cloneName, string originUrl, bool reset)
 {
     if (cloneName != null)
     {
         var clone = PyRevitClones.GetRegisteredClone(cloneName);
         if (clone.IsRepoDeploy)
         {
             if (originUrl != null || reset)
             {
                 string newUrl =
                     reset ? PyRevitLabsConsts.OriginalRepoGitPath : originUrl;
                 clone.SetOrigin(newUrl);
             }
             else
             {
                 Console.WriteLine(string.Format("Clone \"{0}\" origin is at \"{1}\"",
                                                 clone.Name, clone.Origin));
             }
         }
         else
         {
             PyRevitCLIAppCmds.ReportCloneAsNoGit(clone);
         }
     }
 }
Beispiel #6
0
 CreateClone(string cloneName, string deployName, string branchName, string repoUrl, string imagePath, string destPath, string username, string password)
 {
     // FIXME: implement image
     if (cloneName != null)
     {
         // if deployment requested or image path is provided
         if (imagePath != null || deployName != null)
         {
             PyRevitClones.DeployFromImage(
                 cloneName,
                 deploymentName: deployName,
                 branchName: branchName,
                 imagePath: imagePath,
                 destPath: destPath
                 );
         }
         // otherwise clone the full repo
         else
         {
             PyRevitClones.DeployFromRepo(
                 cloneName,
                 deploymentName: deployName,
                 branchName: branchName,
                 repoUrl: repoUrl,
                 destPath: destPath,
                 username: username,
                 password: password
                 );
         }
     }
 }
        SwitchAttachment(string cloneName, string revitYear)
        {
            var clone = PyRevitClones.GetRegisteredClone(cloneName);

            if (revitYear != null)
            {
                int revitYearNumber = 0;
                if (int.TryParse(revitYear, out revitYearNumber))
                {
                    var attachment = PyRevitAttachments.GetAttached(revitYearNumber);
                    if (attachment != null)
                    {
                        if (attachment.Engine != null)
                        {
                            PyRevitAttachments.Attach(attachment.Product.ProductYear,
                                                      clone,
                                                      engineVer: attachment.Engine.Version,
                                                      allUsers: attachment.AllUsers);
                        }
                        else
                        {
                            throw new PyRevitException(
                                      string.Format("Can not determine attachment engine for Revit \"{0}\"",
                                                    revitYear)
                                      );
                        }
                    }
                    else
                    {
                        throw new PyRevitException(
                                  string.Format("Can not determine existing attachment for Revit \"{0}\"",
                                                revitYear)
                                  );
                    }
                }
                else
                {
                    throw new PyRevitException(string.Format("Invalid Revit year \"{0}\"", revitYear));
                }
            }
            else
            {
                // read current attachments and reattach using the same config with the new clone
                foreach (var attachment in PyRevitAttachments.GetAttachments())
                {
                    if (attachment.Engine != null)
                    {
                        PyRevitAttachments.Attach(
                            attachment.Product.ProductYear,
                            clone,
                            engineVer: attachment.Engine.Version,
                            allUsers: attachment.AllUsers);
                    }
                    else
                    {
                        throw new PyRevitException("Can not determine attachment engine.");
                    }
                }
            }
        }
        ToggleExtension(bool enable, string cloneName, string extName)
        {
            if (extName != null)
            {
                PyRevitClone clone = null;
                if (cloneName != null)
                {
                    clone = PyRevitClones.GetRegisteredClone(cloneName);
                }

                if (enable)
                {
                    if (clone != null)
                    {
                        PyRevitExtensions.EnableShippedExtension(clone, extName);
                    }
                    else
                    {
                        PyRevitExtensions.EnableInstalledExtension(extName);
                    }
                }
                else
                {
                    if (clone != null)
                    {
                        PyRevitExtensions.DisableShippedExtension(clone, extName);
                    }
                    else
                    {
                        PyRevitExtensions.DisableInstalledExtension(extName);
                    }
                }
            }
        }
 RenameClone(string cloneName, string cloneNewName)
 {
     if (cloneNewName != null)
     {
         PyRevitClones.RenameClone(cloneName, cloneNewName);
     }
 }
 CreateClone(string cloneName, string deployName, string branchName, string repoUrl, string imagePath, string destPath, GitInstallerCredentials credentials)
 {
     // FIXME: implement image
     if (cloneName != null)
     {
         // if deployment requested or image path is provided
         if (imagePath != null || deployName != null)
         {
             PyRevitClones.DeployFromImage(
                 cloneName,
                 deploymentName: deployName,
                 branchName: branchName,
                 imagePath: imagePath,
                 destPath: destPath
                 );
         }
         // otherwise clone the full repo
         else
         {
             PyRevitClones.DeployFromRepo(
                 cloneName,
                 deploymentName: deployName,
                 branchName: branchName,
                 repoUrl: repoUrl,
                 destPath: destPath,
                 credentials: credentials
                 );
         }
     }
 }
 RegisterClone(string cloneName, string clonePath, bool force)
 {
     if (clonePath != null)
     {
         PyRevitClones.RegisterClone(cloneName, clonePath, forceUpdate: force);
     }
 }
Beispiel #12
0
        CreateEnvJson()
        {
            // collecet search paths
            var searchPaths = new List <string>()
            {
                PyRevitConsts.DefaultExtensionsPath
            };

            searchPaths.AddRange(PyRevitExtensions.GetRegisteredExtensionSearchPaths());

            // collect list of lookup sources
            var lookupSrc = new List <string>()
            {
                PyRevitExtensions.GetDefaultExtensionLookupSource()
            };

            lookupSrc.AddRange(PyRevitExtensions.GetRegisteredExtensionLookupSources());

            // create json data object
            var jsonData = new Dictionary <string, object>()
            {
                { "meta", new Dictionary <string, object>()
                  {
                      { "version", "0.1.0" }
                  } },
                { "clones", PyRevitClones.GetRegisteredClones() },
                { "attachments", PyRevitAttachments.GetAttachments() },
                { "extensions", PyRevitExtensions.GetInstalledExtensions() },
                { "searchPaths", searchPaths },
                { "lookupSources", lookupSrc },
                { "installed", RevitProduct.ListInstalledProducts() },
                { "running", RevitController.ListRunningRevits() },
                { "pyrevitDataDir", PyRevitLabsConsts.PyRevitPath },
                { "userEnv", new Dictionary <string, object>()
                  {
                      { "osVersion", UserEnv.GetWindowsVersion() },
                      { "execUser", string.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName) },
                      { "activeUser", UserEnv.GetLoggedInUserName() },
                      { "isAdmin", UserEnv.IsRunAsAdmin() },
                      { "userAppdata", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) },
                      { "latestFramework", UserEnv.GetInstalledDotNetVersion() },
                      { "targetPacks", UserEnv.GetInstalledDotnetTargetPacks() },
                      { "targetPacksCore", UserEnv.GetInstalledDotnetCoreTargetPacks() },
                      { "cliVersion", PyRevitCLI.CLIVersion },
                  } },
            };

            var jsonExportCfg = new JsonSerializerSettings {
                Error = delegate(object sender, pyRevitLabs.Json.Serialization.ErrorEventArgs args) {
                    args.ErrorContext.Handled = true;
                },
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };

            jsonExportCfg.Converters.Add(new JsonVersionConverter());

            return(JsonConvert.SerializeObject(jsonData, jsonExportCfg));
        }
        UpdateClone(bool allClones, string cloneName, GitInstallerCredentials credentials)
        {
            // TODO: ask for closing running Revits

            // prepare a list of clones to be updated
            var targetClones = new List <PyRevitClone>();
            // separate the clone that this process might be running from
            // this is used to update this clone from outside since the dlls will be locked
            PyRevitClone myClone = null;

            // all clones
            if (allClones)
            {
                foreach (var clone in PyRevitClones.GetRegisteredClones())
                {
                    if (PyRevitCLIAppCmds.IsRunningInsideClone(clone))
                    {
                        myClone = clone;
                    }
                    else
                    {
                        targetClones.Add(clone);
                    }
                }
            }
            // or single clone
            else
            {
                if (cloneName != null)
                {
                    var clone = PyRevitClones.GetRegisteredClone(cloneName);
                    if (PyRevitCLIAppCmds.IsRunningInsideClone(clone))
                    {
                        myClone = clone;
                    }
                    else
                    {
                        targetClones.Add(clone);
                    }
                }
            }

            // update clones that do not include this process
            foreach (var clone in targetClones)
            {
                logger.Debug("Updating clone \"{0}\"", clone.Name);
                PyRevitClones.Update(clone, credentials);
            }

            // now update myClone if any, as last step
            if (myClone != null)
            {
                throw new PyRevitException("Can not update clone that contains this command line utility. "
                                           + "Use installer to update.");
            }
        }
Beispiel #14
0
        AttachClone(string cloneName,
                    bool latest, bool dynamoSafe, string engineVersion,
                    string revitYear, bool installed, bool attached,
                    bool allUsers)
        {
            var clone = PyRevitClones.GetRegisteredClone(cloneName);

            // grab engine version
            int engineVer = 0;

            int.TryParse(engineVersion, out engineVer);

            if (latest)
            {
                logger.Debug("Attaching on latest engine...");
                var latestCloneEngine =
                    clone.GetEngines().Where(x => x.Runtime).OrderByDescending(x => x.Version).First();
                logger.Debug(string.Format("Latest engine: {0}", latestCloneEngine));
                if (latestCloneEngine != null)
                {
                    engineVer = latestCloneEngine.Version;
                }
                else
                {
                    throw new PyRevitException("Can not determine latest runtime engine for this clone.");
                }
            }
            else if (dynamoSafe)
            {
                logger.Debug("Attaching on dynamo-safe engine");
                engineVer = PyRevitConsts.ConfigsDynamoCompatibleEnginerVer;
            }

            // decide targets revits to attach to
            int revitYearNumber = 0;

            if (installed)
            {
                foreach (var revit in RevitProduct.ListInstalledProducts())
                {
                    PyRevitAttachments.Attach(revit.ProductYear, clone, engineVer: engineVer, allUsers: allUsers);
                }
            }
            else if (attached)
            {
                foreach (var attachment in PyRevitAttachments.GetAttachments())
                {
                    PyRevitAttachments.Attach(attachment.Product.ProductYear, clone, engineVer: engineVer, allUsers: allUsers);
                }
            }
            else if (int.TryParse(revitYear, out revitYearNumber))
            {
                PyRevitAttachments.Attach(revitYearNumber, clone, engineVer: engineVer, allUsers: allUsers);
            }
        }
 PrintCloneEngines(string cloneName)
 {
     if (cloneName != null)
     {
         var clone = PyRevitClones.GetRegisteredClone(cloneName);
         PyRevitCLIAppCmds.PrintHeader(string.Format("Deployments for \"{0}\"", clone.Name));
         foreach (var engine in clone.GetConfiguredEngines())
         {
             Console.WriteLine(engine);
         }
     }
 }
 ForgetClone(bool allClones, string cloneName)
 {
     if (allClones)
     {
         PyRevitClones.UnregisterAllClones();
     }
     else
     {
         PyRevitClones.UnregisterClone(
             PyRevitClones.GetRegisteredClone(cloneName)
             );
     }
 }
Beispiel #17
0
 DeleteClone(bool allClones, string cloneName, bool clearConfigs)
 {
     if (allClones)
     {
         PyRevitClones.DeleteAllClones(clearConfigs: clearConfigs);
     }
     else
     {
         if (cloneName != null)
         {
             PyRevitClones.Delete(PyRevitClones.GetRegisteredClone(cloneName), clearConfigs: clearConfigs);
         }
     }
 }
        PrintClones()
        {
            PyRevitCLIAppCmds.PrintHeader("Registered Clones (full git repos)");
            var clones = PyRevitClones.GetRegisteredClones().OrderBy(x => x.Name);

            foreach (var clone in clones.Where(c => c.IsRepoDeploy))
            {
                Console.WriteLine(clone);
            }

            PyRevitCLIAppCmds.PrintHeader("Registered Clones (deployed from archive/image)");
            foreach (var clone in clones.Where(c => !c.IsRepoDeploy))
            {
                Console.WriteLine(clone);
            }
        }
 PrintCloneDeployments(string cloneName)
 {
     if (cloneName != null)
     {
         var clone = PyRevitClones.GetRegisteredClone(cloneName);
         PyRevitCLIAppCmds.PrintHeader(string.Format("Deployments for \"{0}\"", clone.Name));
         foreach (var dep in clone.GetConfiguredDeployments())
         {
             Console.WriteLine(string.Format("\"{0}\" deploys:", dep.Name));
             foreach (var path in dep.Paths)
             {
                 Console.WriteLine("    " + path);
             }
             Console.WriteLine();
         }
     }
 }
        public void DeployFromRepo_Deployment_Test()
        {
            var testCloneDeployment = "core";
            var testCloneBranch     = PyRevitLabsConsts.TragetBranch;

            try {
                PyRevitClones.DeployFromRepo(
                    cloneName: testCloneName,
                    deploymentName: testCloneDeployment,
                    branchName: testCloneBranch,
                    repoUrl: null,
                    destPath: TempPath
                    );
            }
            catch (Exception ex) {
                Assert.Fail(ex.Message);
            }
        }
        public void DeployFromImage_Full_Test()
        {
            var testCloneBranch = PyRevitLabsConsts.TragetBranch;

            PyRevitClones.DeployFromImage(
                cloneName: testCloneName,
                deploymentName: null,
                branchName: null,
                imagePath: null,
                destPath: TempPath
                );

            var clone = PyRevitClones.GetRegisteredClone(testCloneName);

            PyRevitClones.UnregisterClone(clone);

            Assert.AreEqual(testCloneBranch, clone.Branch, string.Format("{0} != {1}", testCloneBranch, clone.Branch));
        }
        public void DeployFromRepo_Develop_Test()
        {
            var testCloneBranch = PyRevitLabsConsts.TragetBranch;

            PyRevitClones.DeployFromRepo(
                cloneName: testCloneName,
                deploymentName: null,
                branchName: testCloneBranch,
                repoUrl: null,
                destPath: TempPath
                );

            var clone = PyRevitClones.GetRegisteredClone(testCloneName);

            PyRevitClones.UnregisterClone(clone);

            Assert.IsTrue(clone.IsRepoDeploy);
            Assert.AreEqual(testCloneBranch, clone.Branch);
        }
        DeleteClone(bool allClones, string cloneName, bool clearConfigs)
        {
            if (allClones)
            {
                PyRevitClones.DeleteAllClones(clearConfigs: clearConfigs);
            }
            else if (cloneName != null)
            {
                // lets detach the clone if there is any attachments to it
                var clone = PyRevitClones.GetRegisteredClone(cloneName);
                foreach (var attachment in PyRevitAttachments.GetAttachments())
                {
                    if (attachment.Clone.Equals(clone))
                    {
                        logger.Debug($"Detaching existing attachment: {attachment}");
                        PyRevitAttachments.Detach(attachment.Product.ProductYear, attachment.AllUsers);
                    }
                }

                PyRevitClones.Delete(clone, clearConfigs: clearConfigs);
            }
        }
Beispiel #24
0
        CreateClone(string cloneName, string deployName, string branchName, string repoUrl, string imagePath, string destPath, string username, string password)
        {
            // FIXME: implement image
            if (cloneName != null)
            {
                // report progress
                GlobalConfigs.ReportProgress = true;
                Console.CursorVisible        = false;

                // if deployment requested or image path is provided
                if (imagePath != null || deployName != null)
                {
                    PyRevitClones.DeployFromImage(
                        cloneName,
                        deploymentName: deployName,
                        branchName: branchName,
                        imagePath: imagePath,
                        destPath: destPath
                        );
                }
                // otherwise clone the full repo
                else
                {
                    PyRevitClones.DeployFromRepo(
                        cloneName,
                        deploymentName: deployName,
                        branchName: branchName,
                        repoUrl: repoUrl,
                        destPath: destPath,
                        username: username,
                        password: password
                        );
                }

                GlobalConfigs.ReportProgress = false;
                Console.CursorVisible        = true;
            }
        }
 GetSetCloneCommit(string cloneName, string commitHash)
 {
     if (cloneName != null)
     {
         var clone = PyRevitClones.GetRegisteredClone(cloneName);
         if (clone.IsRepoDeploy)
         {
             if (commitHash != null)
             {
                 clone.SetCommit(commitHash);
             }
             else
             {
                 Console.WriteLine(string.Format("Clone \"{0}\" is on commit \"{1}\"",
                                                 clone.Name, clone.Commit));
             }
         }
         else
         {
             PyRevitCLIAppCmds.ReportCloneAsNoGit(clone);
         }
     }
 }
Beispiel #26
0
        // cli argument processor
        private static void ProcessArguments()
        {
            if (IsHelpUsagePatternMode)
            {
                Console.WriteLine(UsagePatterns.Replace("\t", "    "));
            }

            else if (IsVersionMode)
            {
                PyRevitCLIAppCmds.PrintVersion(checkUpdates: true);
            }

            else if (all("wiki"))
            {
                CommonUtils.OpenUrl(PyRevitLabsConsts.WikiUrl);
            }

            else if (all("blog"))
            {
                CommonUtils.OpenUrl(PyRevitLabsConsts.BlogsUrl);
            }

            else if (all("docs"))
            {
                CommonUtils.OpenUrl(PyRevitLabsConsts.DocsUrl);
            }

            else if (all("source"))
            {
                CommonUtils.OpenUrl(PyRevitLabsConsts.SourceRepoUrl);
            }

            else if (all("youtube"))
            {
                CommonUtils.OpenUrl(PyRevitLabsConsts.YoutubeUrl);
            }

            else if (all("support"))
            {
                CommonUtils.OpenUrl(PyRevitLabsConsts.SupportUrl);
            }

            else if (all("env"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Env);
                }
                else
                {
                    PyRevitCLIAppCmds.MakeEnvReport(json: arguments["--json"].IsTrue);
                }
            }

            else if (all("update") && !any("clones", "extensions"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Update);
                }
                else
                {
                    PyRevitCLIAppCmds.UpdateRemoteDataSources();
                }
            }

            else if (all("clone"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Clone);
                }
                else
                {
                    PyRevitCLICloneCmds.CreateClone(
                        cloneName: TryGetValue("<clone_name>"),
                        deployName: TryGetValue("<deployment_name>"),
                        branchName: TryGetValue("--branch"),
                        repoUrl: TryGetValue("--source"),
                        imagePath: TryGetValue("--image"),
                        destPath: TryGetValue("--dest"),
                        credentials: TryGetCredentials()
                        );
                }
            }

            else if (all("clones"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Clones);
                }

                else if (all("info"))
                {
                    PyRevitCLICloneCmds.PrintCloneInfo(TryGetValue("<clone_name>"));
                }

                else if (all("open"))
                {
                    PyRevitCLICloneCmds.OpenClone(TryGetValue("<clone_name>"));
                }

                else if (all("add"))
                {
                    if (all("this"))
                    {
                        PyRevitCLICloneCmds.RegisterClone(
                            TryGetValue("<clone_name>"),
                            Path.GetDirectoryName(CLIPath),
                            force: arguments["--force"].IsTrue
                            );
                    }
                    else
                    {
                        PyRevitCLICloneCmds.RegisterClone(
                            TryGetValue("<clone_name>"),
                            TryGetValue("<clone_path>"),
                            force: arguments["--force"].IsTrue
                            );
                    }
                }

                else if (all("forget"))
                {
                    PyRevitCLICloneCmds.ForgetClone(
                        allClones: arguments["--all"].IsTrue,
                        cloneName: TryGetValue("<clone_name>")
                        );
                }

                else if (all("rename"))
                {
                    PyRevitCLICloneCmds.RenameClone(
                        cloneName: TryGetValue("<clone_name>"),
                        cloneNewName: TryGetValue("<clone_new_name>")
                        );
                }

                else if (all("delete"))
                {
                    PyRevitCLICloneCmds.DeleteClone(
                        allClones: arguments["--all"].IsTrue,
                        cloneName: TryGetValue("<clone_name>"),
                        clearConfigs: arguments["--clearconfigs"].IsTrue
                        );
                }

                else if (all("branch"))
                {
                    PyRevitCLICloneCmds.GetSetCloneBranch(
                        cloneName: TryGetValue("<clone_name>"),
                        branchName: TryGetValue("<branch_name>")
                        );
                }

                else if (all("version"))
                {
                    PyRevitCLICloneCmds.GetSetCloneTag(
                        cloneName: TryGetValue("<clone_name>"),
                        tagName: TryGetValue("<tag_name>")
                        );
                }

                else if (all("commit"))
                {
                    PyRevitCLICloneCmds.GetSetCloneCommit(
                        cloneName: TryGetValue("<clone_name>"),
                        commitHash: TryGetValue("<commit_hash>")
                        );
                }

                else if (all("origin"))
                {
                    PyRevitCLICloneCmds.GetSetCloneOrigin(
                        cloneName: TryGetValue("<clone_name>"),
                        originUrl: TryGetValue("<origin_url>"),
                        reset: arguments["--reset"].IsTrue
                        );
                }

                else if (all("deployments"))
                {
                    PyRevitCLICloneCmds.PrintCloneDeployments(TryGetValue("<clone_name>"));
                }

                else if (all("engines"))
                {
                    PyRevitCLICloneCmds.PrintCloneEngines(TryGetValue("<clone_name>"));
                }

                else if (all("update"))
                {
                    PyRevitCLICloneCmds.UpdateClone(
                        allClones: arguments["--all"].IsTrue,
                        cloneName: TryGetValue("<clone_name>"),
                        credentials: TryGetCredentials()
                        );
                }

                else
                {
                    PyRevitCLICloneCmds.PrintClones();
                }
            }

            else if (all("attach"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Attach);
                }
                else
                {
                    // get clone
                    var clone = PyRevitClones.GetRegisteredClone(TryGetValue("<clone_name>"));

                    // determine version
                    var engStrVer = TryGetValue("<engine_version>");
                    PyRevitEngineVersion engineVersion = null;
                    if (arguments["default"].IsTrue)
                    {
                        engineVersion = PyRevitEngineVersion.Default;
                    }
                    else
                    {
                        // try parse the engine version as an integer e.g. 277 for 2.7.7
                        if (int.TryParse(engStrVer, out var engIntVer))
                        {
                            engineVersion = (PyRevitEngineVersion)engIntVer;
                        }
                    }

                    if (engineVersion is null)
                    {
                        // then engine must be an engine id
                        PyRevitCLICloneCmds.AttachClone(
                            clone: clone,
                            engineId: engStrVer,
                            revitYear: TryGetValue("<revit_year>"),
                            installed: arguments["--installed"].IsTrue,
                            attached: arguments["--attached"].IsTrue,
                            allUsers: arguments["--allusers"].IsTrue
                            );
                    }
                    else
                    {
                        PyRevitCLICloneCmds.AttachClone(
                            clone: clone,
                            engineVersion: engineVersion,
                            revitYear: TryGetValue("<revit_year>"),
                            installed: arguments["--installed"].IsTrue,
                            attached: arguments["--attached"].IsTrue,
                            allUsers: arguments["--allusers"].IsTrue
                            );
                    }
                }
            }

            else if (all("detach"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Detach);
                }
                else
                {
                    PyRevitCLICloneCmds.DetachClone(
                        revitYear: TryGetValue("<revit_year>"),
                        all: arguments["--all"].IsTrue,
                        currentAndAllUsers: true
                        );
                }
            }

            else if (all("attached"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Attached);
                }
                else
                {
                    PyRevitCLICloneCmds.ListAttachments(revitYear: TryGetValue("<revit_year>"));
                }
            }

            else if (all("switch"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Switch);
                }
                else
                {
                    PyRevitCLICloneCmds.SwitchAttachment(
                        cloneName: TryGetValue("<clone_name>"),
                        revitYear: TryGetValue("<revit_year>")
                        );
                }
            }

            else if (all("extend"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Extend);
                }

                else if (any("ui", "lib"))
                {
                    PyRevitCLIExtensionCmds.Extend(
                        ui: arguments["ui"].IsTrue,
                        lib: arguments["lib"].IsTrue,
                        extName: TryGetValue("<extension_name>"),
                        destPath: TryGetValue("--dest"),
                        repoUrl: TryGetValue("<repo_url>"),
                        branchName: TryGetValue("--branch"),
                        credentials: TryGetCredentials()
                        );
                }

                else
                {
                    PyRevitCLIExtensionCmds.Extend(
                        extName: TryGetValue("<extension_name>"),
                        destPath: TryGetValue("--dest"),
                        branchName: TryGetValue("--branch")
                        );
                }
            }

            else if (all("extensions"))
            {
                if (all("search"))
                {
                    PyRevitCLIExtensionCmds.PrintExtensionDefinitions(
                        searchPattern: TryGetValue("<search_pattern>"),
                        headerPrefix: "Matched"
                        );
                }

                else if (any("info", "help"))
                {
                    PyRevitCLIExtensionCmds.ProcessExtensionInfoCommands(
                        extName: TryGetValue("<extension_name>"),
                        info: arguments["info"].IsTrue,
                        help: arguments["help"].IsTrue
                        );
                }

                else if (all("open"))
                {
                    PyRevitCLIExtensionCmds.ProcessExtensionOpenCommand(
                        cloneName: TryGetValue("<clone_name>"),
                        extName: TryGetValue("<extension_name>")
                        );
                }

                else if (all("delete"))
                {
                    PyRevitCLIExtensionCmds.DeleteExtension(TryGetValue("<extension_name>"));
                }

                else if (all("origin"))
                {
                    PyRevitCLIExtensionCmds.GetSetExtensionOrigin(
                        extName: TryGetValue("<extension_name>"),
                        originUrl: TryGetValue("<origin_url>"),
                        reset: arguments["--reset"].IsTrue
                        );
                }

                else if (all("paths"))
                {
                    if (IsHelpMode)
                    {
                        PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.ExtensionsPaths);
                    }

                    else if (all("add"))
                    {
                        PyRevitCLIExtensionCmds.AddExtensionPath(
                            searchPath: TryGetValue("<extensions_path>")
                            );
                    }

                    else if (all("forget"))
                    {
                        PyRevitCLIExtensionCmds.ForgetAllExtensionPaths(
                            all: arguments["--all"].IsTrue,
                            searchPath: TryGetValue("<extensions_path>")
                            );
                    }

                    else
                    {
                        PyRevitCLIExtensionCmds.PrintExtensionSearchPaths();
                    }
                }

                else if (any("enable", "disable"))
                {
                    PyRevitCLIExtensionCmds.ToggleExtension(
                        enable: arguments["enable"].IsTrue,
                        cloneName: TryGetValue("<clone_name>"),
                        extName: TryGetValue("<extension_name>")
                        );
                }

                else if (all("sources"))
                {
                    if (IsHelpMode)
                    {
                        PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.ExtensionsSources);
                    }

                    else if (all("add"))
                    {
                        PyRevitCLIExtensionCmds.AddExtensionLookupSource(
                            lookupPath: TryGetValue("<source_json_or_url>")
                            );
                    }

                    else if (all("forget"))
                    {
                        PyRevitCLIExtensionCmds.ForgetExtensionLookupSources(
                            all: arguments["--all"].IsTrue,
                            lookupPath: TryGetValue("<source_json_or_url>")
                            );
                    }

                    else
                    {
                        PyRevitCLIExtensionCmds.PrintExtensionLookupSources();
                    }
                }

                else if (all("update"))
                {
                    PyRevitCLIExtensionCmds.UpdateExtension(
                        all: arguments["--all"].IsTrue,
                        extName: TryGetValue("<extension_name>"),
                        credentials: TryGetCredentials()
                        );
                }

                else if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Extensions);
                }

                else
                {
                    PyRevitCLIExtensionCmds.PrintExtensions();
                }
            }

            else if (all("releases"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Releases);
                }

                else if (all("open"))
                {
                    PyRevitCLIReleaseCmds.OpenReleasePage(
                        searchPattern: TryGetValue("<search_pattern>"),
                        latest: arguments["latest"].IsTrue,
                        listPreReleases: arguments["--pre"].IsTrue
                        );
                }

                else if (all("download"))
                {
                    PyRevitCLIReleaseCmds.DownloadReleaseAsset(
                        arguments["archive"].IsTrue ? GithubReleaseAssetType.Archive : GithubReleaseAssetType.Installer,
                        destPath: TryGetValue("--dest"),
                        searchPattern: TryGetValue("<search_pattern>"),
                        latest: arguments["latest"].IsTrue,
                        listPreReleases: arguments["--pre"].IsTrue
                        );
                }

                else
                {
                    PyRevitCLIReleaseCmds.PrintReleases(
                        searchPattern: TryGetValue("<search_pattern>"),
                        latest: arguments["latest"].IsTrue,
                        printReleaseNotes: arguments["--notes"].IsTrue,
                        listPreReleases: arguments["--pre"].IsTrue
                        );
                }
            }

            else if (all("revits"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Revits);
                }

                else if (all("killall"))
                {
                    PyRevitCLIRevitCmds.KillAllRevits(
                        revitYear: TryGetValue("<revit_year>")
                        );
                }

                else if (all("fileinfo"))
                {
                    PyRevitCLIRevitCmds.ProcessFileInfo(
                        targetPath: TryGetValue("<file_or_dir_path>"),
                        outputCSV: TryGetValue("--csv"),
                        IncludeRVT: arguments["--rvt"].IsTrue,
                        includeRTE: arguments["--rte"].IsTrue,
                        includeRFA: arguments["--rfa"].IsTrue,
                        includeRFT: arguments["--rft"].IsTrue
                        );
                }

                else if (arguments["--supported"].IsTrue)
                {
                    PyRevitCLIRevitCmds.ProcessBuildInfo(
                        outputCSV: TryGetValue("--csv")
                        );
                }

                else
                {
                    PyRevitCLIRevitCmds.PrintLocalRevits(running: arguments["--installed"].IsFalse);
                }
            }

            else if (all("run"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Run);
                }
                else if (all("commands"))
                {
                    PyRevitCLIRevitCmds.ListAvailableCommands();
                }
                else
                {
                    var modelList = TryGetValue("--models");
                    if (modelList != null)
                    {
                        PyRevitCLIRevitCmds.RunExtensionCommand(
                            commandName: TryGetValue("<script_or_command_name>"),
                            targetFile: modelList,
                            revitYear: TryGetValue("--revit"),
                            runOptions: new PyRevitRunnerOptions()
                        {
                            PurgeTempFiles = arguments["--purge"].IsTrue,
                            ImportPath     = TryGetValue("--import", null)
                        },
                            targetIsFileList: true
                            );
                    }
                    else
                    {
                        PyRevitCLIRevitCmds.RunExtensionCommand(
                            commandName: TryGetValue("<script_or_command_name>"),
                            targetFile: TryGetValue("<model_file>"),
                            revitYear: TryGetValue("--revit"),
                            runOptions: new PyRevitRunnerOptions()
                        {
                            PurgeTempFiles = arguments["--purge"].IsTrue,
                            ImportPath     = TryGetValue("--import", null)
                        }
                            );
                    }
                }
            }

            else if (all("caches"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Caches);
                }

                else if (all("bim360", "clear"))
                {
                    PyRevitCLIAppCmds.ClearCaches(
                        allCaches: arguments["--all"].IsTrue,
                        revitYear: TryGetValue("<revit_year>"),
                        cachetype: TargetCacheType.BIM360Cache
                        );
                }

                else if (all("clear"))
                {
                    PyRevitCLIAppCmds.ClearCaches(
                        allCaches: arguments["--all"].IsTrue,
                        revitYear: TryGetValue("<revit_year>"),
                        cachetype: TargetCacheType.PyRevitCache
                        );
                }
            }

            else if (all("config"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Config);
                }
                else
                {
                    PyRevitCLIConfigCmds.SeedConfigs(
                        templateConfigFilePath: TryGetValue("--from")
                        );
                }
            }

            else if (all("configs"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Configs);
                }

                else if (all("bincache"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetBinaryCaches(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Binary cache is {0}",
                                                        PyRevitConfigs.GetBinaryCaches() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("checkupdates"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetCheckUpdates(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Check Updates is {0}",
                                                        PyRevitConfigs.GetCheckUpdates() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("autoupdate"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetAutoUpdate(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Auto Update is {0}",
                                                        PyRevitConfigs.GetAutoUpdate() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("rocketmode"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetRocketMode(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Rocket Mode is {0}",
                                                        PyRevitConfigs.GetRocketMode() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("logs"))
                {
                    if (all("none"))
                    {
                        PyRevitConfigs.SetLoggingLevel(PyRevitLogLevels.Quiet);
                    }

                    else if (all("verbose"))
                    {
                        PyRevitConfigs.SetLoggingLevel(PyRevitLogLevels.Verbose);
                    }

                    else if (all("debug"))
                    {
                        PyRevitConfigs.SetLoggingLevel(PyRevitLogLevels.Debug);
                    }

                    else
                    {
                        Console.WriteLine(string.Format("Logging Level is {0}", PyRevitConfigs.GetLoggingLevel().ToString()));
                    }
                }

                else if (all("filelogging"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetFileLogging(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("File Logging is {0}",
                                                        PyRevitConfigs.GetFileLogging() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("startuptimeout"))
                {
                    if (arguments["<timeout>"] is null)
                    {
                        Console.WriteLine(string.Format("Startup log timeout is set to: {0}",
                                                        PyRevitConfigs.GetStartupLogTimeout()));
                    }
                    else
                    {
                        PyRevitConfigs.SetStartupLogTimeout(int.Parse(TryGetValue("<timeout>")));
                    }
                }

                else if (all("loadbeta"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetLoadBetaTools(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Load Beta is {0}",
                                                        PyRevitConfigs.GetLoadBetaTools() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("cpyversion"))
                {
                    if (arguments["<cpy_version>"] is null)
                    {
                        Console.WriteLine(string.Format("CPython version is set to: {0}",
                                                        PyRevitConfigs.GetCpythonEngineVersion()));
                    }
                    else
                    {
                        PyRevitConfigs.SetCpythonEngineVersion(int.Parse(TryGetValue("<cpy_version>")));
                    }
                }

                else if (all("usercanupdate"))
                {
                    if (any("yes", "no"))
                    {
                        PyRevitConfigs.SetUserCanUpdate(arguments["yes"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("User {0} update",
                                                        PyRevitConfigs.GetUserCanUpdate() ? "CAN" : "CAN NOT"));
                    }
                }

                else if (all("usercanextend"))
                {
                    if (any("yes", "no"))
                    {
                        PyRevitConfigs.SetUserCanExtend(arguments["yes"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("User {0} extend",
                                                        PyRevitConfigs.GetUserCanExtend() ? "CAN" : "CAN NOT"));
                    }
                }

                else if (all("usercanconfig"))
                {
                    if (any("yes", "no"))
                    {
                        PyRevitConfigs.SetUserCanConfig(arguments["yes"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("User {0} config",
                                                        PyRevitConfigs.GetUserCanConfig() ? "CAN" : "CAN NOT"));
                    }
                }

                else if (all("colordocs"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetColorizeDocs(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Doc Colorizer is {0}",
                                                        PyRevitConfigs.GetColorizeDocs() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("tooltipdebuginfo"))
                {
                    if (any("enable", "disable"))
                    {
                        PyRevitConfigs.SetAppendTooltipEx(arguments["enable"].IsTrue);
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Doc Colorizer is {0}",
                                                        PyRevitConfigs.GetAppendTooltipEx() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("routes"))
                {
                    if (all("port"))
                    {
                        var portNumber = TryGetValue("<port_number>");
                        if (portNumber is null)
                        {
                            Console.WriteLine(string.Format("Routes Port: {0}", PyRevitConfigs.GetRoutesServerPort()));
                        }
                        else
                        {
                            PyRevitConfigs.SetRoutesServerPort(int.Parse(portNumber));
                        }
                    }

                    else if (all("coreapi"))
                    {
                        if (all("enable"))
                        {
                            PyRevitConfigs.SetRoutesLoadCoreAPIStatus(true);
                        }
                        else if (all("disable"))
                        {
                            PyRevitConfigs.SetRoutesLoadCoreAPIStatus(false);
                        }
                        else
                        {
                            Console.WriteLine(string.Format("Routes Core API is {0}",
                                                            PyRevitConfigs.GetRoutesLoadCoreAPIStatus() ? "Enabled" : "Disabled"));
                        }
                    }

                    else if (all("enable"))
                    {
                        PyRevitConfigs.EnableRoutesServer();
                    }

                    else if (all("disable"))
                    {
                        PyRevitConfigs.DisableRoutesServer();
                    }

                    else
                    {
                        Console.WriteLine(string.Format("Routes Server is {0}",
                                                        PyRevitConfigs.GetRoutesServerStatus() ? "Enabled" : "Disabled"));
                    }
                }

                else if (all("telemetry"))
                {
                    if (all("utc"))
                    {
                        if (any("yes", "no"))
                        {
                            PyRevitConfigs.SetUTCStamps(arguments["yes"].IsTrue);
                        }
                        else
                        {
                            Console.WriteLine(PyRevitConfigs.GetUTCStamps() ? "Using UTC timestamps" : "Using Local timestamps");
                        }
                    }

                    else if (all("file"))
                    {
                        var destPath = TryGetValue("<dest_path>");
                        if (destPath is null)
                        {
                            Console.WriteLine(string.Format("Telemetry File Path: {0}", PyRevitConfigs.GetAppTelemetryFlags()));
                        }
                        else
                        {
                            PyRevitConfigs.EnableTelemetry(telemetryFileDir: destPath);
                        }
                    }

                    else if (all("server"))
                    {
                        var serverUrl = TryGetValue("<dest_path>");
                        if (serverUrl is null)
                        {
                            Console.WriteLine(string.Format("Telemetry Server Url: {0}", PyRevitConfigs.GetAppTelemetryFlags()));
                        }
                        else
                        {
                            PyRevitConfigs.EnableTelemetry(telemetryServerUrl: serverUrl);
                        }
                    }

                    else if (all("hooks"))
                    {
                        if (any("yes", "no"))
                        {
                            PyRevitConfigs.SetTelemetryIncludeHooks(arguments["yes"].IsTrue);
                        }
                        else
                        {
                            Console.WriteLine(PyRevitConfigs.GetTelemetryIncludeHooks() ? "Sending telemetry for hooks" : "Not sending telemetry for hooks");
                        }
                    }

                    else if (all("enable"))
                    {
                        PyRevitConfigs.EnableTelemetry();
                    }

                    else if (all("disable"))
                    {
                        PyRevitConfigs.DisableTelemetry();
                    }

                    else
                    {
                        Console.WriteLine(string.Format("Telemetry is {0}",
                                                        PyRevitConfigs.GetTelemetryStatus() ? "Enabled" : "Disabled"));
                        Console.WriteLine(string.Format("File Path: {0}", PyRevitConfigs.GetTelemetryFilePath()));
                        Console.WriteLine(string.Format("Server Url: {0}", PyRevitConfigs.GetTelemetryServerUrl()));
                    }
                }

                else if (all("apptelemetry"))
                {
                    if (all("flags"))
                    {
                        var flagsValue = TryGetValue("<flags>");
                        if (flagsValue is null)
                        {
                            Console.WriteLine(string.Format("App Telemetry Flags: {0}", PyRevitConfigs.GetAppTelemetryFlags()));
                        }
                        else
                        {
                            PyRevitConfigs.SetAppTelemetryFlags(flags: flagsValue);
                        }
                    }

                    else if (all("server"))
                    {
                        var serverPath = TryGetValue("<server_path>");
                        if (serverPath is null)
                        {
                            Console.WriteLine(string.Format("App Telemetry Server: {0}", PyRevitConfigs.GetAppTelemetryServerUrl()));
                        }
                        else
                        {
                            PyRevitConfigs.EnableAppTelemetry(apptelemetryServerUrl: serverPath);
                        }
                    }

                    else if (all("enable"))
                    {
                        PyRevitConfigs.EnableAppTelemetry();
                    }

                    else if (all("disable"))
                    {
                        PyRevitConfigs.DisableAppTelemetry();
                    }

                    else
                    {
                        Console.WriteLine(string.Format("App Telemetry is {0}",
                                                        PyRevitConfigs.GetAppTelemetryStatus() ? "Enabled" : "Disabled"));
                        Console.WriteLine(string.Format("Server Url: {0}", PyRevitConfigs.GetAppTelemetryServerUrl()));
                        Console.WriteLine(string.Format("App Telemetry flag is {0}",
                                                        PyRevitConfigs.GetAppTelemetryFlags()));
                    }
                }

                else if (all("outputcss"))
                {
                    if (arguments["<css_path>"] is null)
                    {
                        Console.WriteLine(string.Format("Output Style Sheet is set to: {0}",
                                                        PyRevitConfigs.GetOutputStyleSheet()));
                    }
                    else
                    {
                        PyRevitConfigs.SetOutputStyleSheet(TryGetValue("<css_path>"));
                    }
                }

                else if (all("seed"))
                {
                    PyRevitConfigs.SeedConfig(makeCurrentUserAsOwner: arguments["--lock"].IsTrue);
                }

                else if (any("enable", "disable"))
                {
                    if (arguments["<option_path>"] != null)
                    {
                        // extract section and option names
                        string orignalOptionValue = TryGetValue("<option_path>");
                        if (orignalOptionValue.Split(':').Count() == 2)
                        {
                            string configSection = orignalOptionValue.Split(':')[0];
                            string configOption  = orignalOptionValue.Split(':')[1];

                            var cfg = PyRevitConfigs.GetConfigFile();
                            cfg.SetValue(configSection, configOption, arguments["enable"].IsTrue);
                        }
                        else
                        {
                            PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Main);
                        }
                    }
                }

                else
                {
                    if (arguments["<option_path>"] != null)
                    {
                        // extract section and option names
                        string orignalOptionValue = TryGetValue("<option_path>");
                        if (orignalOptionValue.Split(':').Count() == 2)
                        {
                            string configSection = orignalOptionValue.Split(':')[0];
                            string configOption  = orignalOptionValue.Split(':')[1];

                            var cfg = PyRevitConfigs.GetConfigFile();

                            // if no value provided, read the value
                            var optValue = TryGetValue("<option_value>");
                            if (optValue != null)
                            {
                                cfg.SetValue(configSection, configOption, optValue);
                            }
                            else if (optValue is null)
                            {
                                var existingVal = cfg.GetValue(configSection, configOption);
                                if (existingVal != null)
                                {
                                    Console.WriteLine(string.Format("{0} = {1}", configOption, existingVal));
                                }
                                else
                                {
                                    Console.WriteLine(string.Format("Configuration key \"{0}\" is not set", configOption));
                                }
                            }
                        }
                        else
                        {
                            PyRevitCLIAppHelps.PrintHelp(PyRevitCLICommandType.Main);
                        }
                    }
                }
            }

            else if (all("doctor"))
            {
                if (IsHelpMode)
                {
                    PyRevitCLIAppCmds.RunDoctor("--wrappedhelp");
                }

                else if (TryGetValue("<doctor_command>") is var doctorCommand && doctorCommand != null)
                {
                    PyRevitCLIAppCmds.RunDoctor(doctorCommand, dryRun: arguments["--dryrun"].IsTrue);
                }

                else if (all("doctor", "--list"))
                {
                    PyRevitCLIAppCmds.RunDoctor("--list");
                }

                else
                {
                    PyRevitCLIAppCmds.RunDoctor("");
                }
            }
 OpenClone(string cloneName)
 {
     CommonUtils.OpenInExplorer(PyRevitClones.GetRegisteredClone(cloneName).ClonePath);
 }
 PrintCloneInfo(string cloneName)
 {
     PyRevitCLIAppCmds.PrintHeader("Clone info");
     Console.WriteLine(PyRevitClones.GetRegisteredClone(cloneName));
 }