// force update given or all registered clones // @handled @logs public static void UpdateAllClones(GitInstallerCredentials credentials) { logger.Debug("Updating all pyRevit clones"); foreach (var clone in GetRegisteredClones()) { Update(clone, credentials); } }
// force update all extensions // @handled @logs public static void UpdateAllInstalledExtensions(GitInstallerCredentials credentials = null) { logger.Debug("Updating all installed extensions."); // update all installed extensions foreach (var ext in GetInstalledExtensions()) { UpdateExtension(ext, credentials); } }
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."); } }
UpdateExtension(bool all, string extName, GitInstallerCredentials credentials) { if (all) { PyRevitExtensions.UpdateAllInstalledExtensions(credentials); } else if (extName != null) { PyRevitExtensions.UpdateExtension(extName, credentials); } }
// force update extension // @handled @logs public static void UpdateExtension(PyRevitExtension ext, GitInstallerCredentials credentials = null) { logger.Debug("Updating extension \"{0}\"", ext.Name); logger.Debug("Updating extension repo at \"{0}\"", ext.InstallPath); var res = GitInstaller.ForcedUpdate(ext.InstallPath, credentials); if (res <= UpdateStatus.Conflicts) { throw new PyRevitException( string.Format("Error updating extension \"{0}\" installed at \"{1}\"", ext.Name, ext.InstallPath) ); } }
// force update given or all registered clones // @handled @logs public static void Update(PyRevitClone clone, GitInstallerCredentials credentials) { // current user config logger.Debug("Updating pyRevit clone \"{0}\"", clone.Name); if (clone.IsRepoDeploy) { var res = GitInstaller.ForcedUpdate(clone.ClonePath, credentials); if (res <= UpdateStatus.Conflicts) { throw new PyRevitException(string.Format("Error updating clone \"{0}\"", clone.Name)); } } else { // re-deploying is how the no-git clones get updated ReDeployClone(clone, credentials); } }
private static void ReDeployClone(PyRevitClone clone, GitInstallerCredentials credentials) { // grab clone arguments from inside of clone var cloneName = clone.Name; var clonePath = clone.ClonePath; var cloneDeployArgs = clone.DeploymentArgs; logger.Debug("Clone Name=\"{0}\", Path=\"{1}\" Args=> {2}", cloneName, clonePath, cloneDeployArgs); // delete existing clone Delete(clone); // re-deploy DeployFromImage( cloneName: cloneName, deploymentName: cloneDeployArgs.DeploymentName, branchName: cloneDeployArgs.BranchName, imagePath: cloneDeployArgs.Url, destPath: clonePath ); }
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 ); } } }
// install pyRevit by cloning from git repo // @handled @logs public static void DeployFromRepo(string cloneName, string deploymentName = null, string branchName = null, string repoUrl = null, string destPath = null, GitInstallerCredentials credentials = null) { string repoSourcePath = repoUrl ?? PyRevitLabsConsts.OriginalRepoGitPath; string repoBranch = branchName != null ? branchName : PyRevitLabsConsts.TragetBranch; logger.Debug("Repo source determined as \"{0}:{1}\"", repoSourcePath, repoBranch); // determine destination path if not provided if (destPath is null) { destPath = Path.Combine(PyRevitLabsConsts.PyRevitPath, PyRevitConsts.DefaultCloneInstallName); } logger.Debug("Destination path determined as \"{0}\"", destPath); // make sure destPath exists CommonUtils.EnsurePath(destPath); // check existing destination path if (CommonUtils.VerifyPath(destPath)) { logger.Debug("Destination path already exists {0}", destPath); destPath = Path.Combine(destPath, cloneName); logger.Debug("Using subpath {0}", destPath); if (CommonUtils.VerifyPath(destPath)) { throw new PyRevitException(string.Format("Destination path already exists \"{0}\"", destPath)); } } // start the clone process LibGit2Sharp.Repository repo = null; if (deploymentName != null) { // TODO: Add core checkout option. Figure out how to checkout certain folders in libgit2sharp throw new NotImplementedException("Deployment with git clones not implemented yet."); } else { repo = GitInstaller.Clone(repoSourcePath, repoBranch, destPath, credentials); } // Check installation if (repo != null) { // make sure to delete the repo if error occured after cloning var clonedPath = repo.Info.WorkingDirectory; try { PyRevitClone.VerifyCloneValidity(clonedPath); logger.Debug("Clone successful \"{0}\"", clonedPath); RegisterClone(cloneName, clonedPath); } catch (Exception ex) { logger.Debug(string.Format("Exception occured after clone complete. Deleting clone \"{0}\" | {1}", clonedPath, ex.Message)); try { CommonUtils.DeleteDirectory(clonedPath); } catch (Exception delEx) { logger.Error(string.Format("Error post-install cleanup on \"{0}\" | {1}", clonedPath, delEx.Message)); } // cleanup completed, now baloon up the exception throw ex; } } else { throw new PyRevitException(string.Format("Error installing pyRevit. Null repo error on \"{0}\"", repoUrl)); } }
public static void UpdateExtension(string extName, GitInstallerCredentials credentials = null) { var ext = GetInstalledExtension(extName); UpdateExtension(ext, credentials); }
// installs extension from repo url // @handled @logs public static void InstallExtension(string extensionName, PyRevitExtensionTypes extensionType, string repoPath, string destPath = null, string branchName = null, GitInstallerCredentials credentials = null) { // make sure extension is not installed already try { var existExt = GetInstalledExtension(extensionName); if (existExt != null) { throw new PyRevitException(string.Format("Extension \"{0}\" is already installed under \"{1}\"", existExt.Name, existExt.InstallPath)); } } catch { // extension is not installed so everything is fine } // determine repo folder name // Name.extension for UI Extensions // Name.lib for Library Extensions string extDestDirName = PyRevitExtension.MakeConfigName(extensionName, extensionType); // determine destination destPath = destPath ?? PyRevitConsts.DefaultExtensionsPath; string finalExtRepoPath = Path.Combine(destPath, extDestDirName).NormalizeAsPath(); // determine branch name branchName = branchName ?? PyRevitConsts.DefaultExtensionRepoDefaultBranch; logger.Debug("Extension branch name determined as \"{0}\"", branchName); logger.Debug("Installing extension into \"{0}\"", finalExtRepoPath); // start the clone process var repo = GitInstaller.Clone(repoPath, branchName, finalExtRepoPath, credentials); // Check installation if (repo != null) { // make sure to delete the repo if error occured after cloning var clonedPath = repo.Info.WorkingDirectory; if (GitInstaller.IsValidRepo(clonedPath)) { logger.Debug("Clone successful \"{0}\"", clonedPath); RegisterExtensionSearchPath(destPath.NormalizeAsPath()); } else { logger.Debug("Invalid repo after cloning. Deleting clone \"{0}\"", repoPath); try { CommonUtils.DeleteDirectory(repoPath); } catch (Exception delEx) { logger.Error(string.Format("Error post-install cleanup on \"{0}\" | {1}", repoPath, delEx.Message)); } } } else { throw new PyRevitException(string.Format("Error installing extension. Null repo error on \"{0}\"", repoPath)); } }
Extend(bool ui, bool lib, string extName, string destPath, string repoUrl, string branchName, GitInstallerCredentials credentials) { PyRevitExtensionTypes extType = PyRevitExtensionTypes.Unknown; if (ui) { extType = PyRevitExtensionTypes.UIExtension; } else if (lib) { extType = PyRevitExtensionTypes.LibraryExtension; } PyRevitExtensions.InstallExtension(extName, extType, repoUrl, destPath, branchName, credentials); }