public void FinishCloning(Dictionary <string, string> commandLineArgs, string cloneLocation, string expectedPathToClonedRepository) { // "obtain" // 'cloneLocation' will be a new folder at the $fwroot main project location, such as $fwroot\foo. // Move the lift repo down into $fwroot\foo\OtherRepositories\foo_LIFT folder // Check for Lift version compatibility. cloneLocation = RemoveAppendedLiftIfNeeded(cloneLocation); var otherReposDir = Path.Combine(cloneLocation, Utilities.OtherRepositories); if (!Directory.Exists(otherReposDir)) { Directory.CreateDirectory(otherReposDir); } _liftFolder = Utilities.LiftOffset(cloneLocation); var actualCloneResult = new ActualCloneResult { // Be a bit pessimistic at first. CloneResult = null, ActualCloneFolder = null, FinalCloneResult = FinalCloneResult.ExistingCloneTargetFolder }; // Move the repo from its temp home in cloneLocation into new home. // The original location, may not be on the same device, so it may be a copy+delete, rather than a formal move. // At the end of the day, cloneLocation and its parent temp folder need to be deleted. MakeLocalCloneAndRemoveSourceParentFolder aims to do all of it. MakeLocalClone(cloneLocation, _liftFolder); actualCloneResult.ActualCloneFolder = _liftFolder; actualCloneResult.FinalCloneResult = FinalCloneResult.Cloned; // Update to the head of the desired branch, if possible. UpdateToTheCorrectBranchHeadIfPossible(_liftFolder, "LIFT" + commandLineArgs["-liftmodel"], actualCloneResult); switch (actualCloneResult.FinalCloneResult) { case FinalCloneResult.ExistingCloneTargetFolder: MessageBox.Show(CommonResources.kFlexProjectExists, CommonResources.kObtainProject, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Directory.Delete(cloneLocation, true); _liftFolder = null; break; case FinalCloneResult.FlexVersionIsTooOld: MessageBox.Show(CommonResources.kFlexUpdateRequired, CommonResources.kObtainProject, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Directory.Delete(cloneLocation, true); _liftFolder = null; break; } // Delete all old repo folders and files from 'cloneLocation'. foreach (var dir in Directory.GetDirectories(cloneLocation).Where(directory => !directory.Contains(Utilities.OtherRepositories))) { Directory.Delete(dir, true); } foreach (var file in Directory.GetFiles(cloneLocation)) { File.Delete(file); } }
public void FinishCloning(Dictionary <string, string> commandLineArgs, string cloneLocation, string expectedPathToClonedRepository) { var actualCloneResult = new ActualCloneResult { // Be a bit pessimistic at first. CloneResult = null, ActualCloneFolder = null, FinalCloneResult = FinalCloneResult.ExistingCloneTargetFolder }; _newProjectFilename = Path.GetFileName(cloneLocation) + Utilities.FwXmlExtension; _newFwProjectPathname = Path.Combine(cloneLocation, _newProjectFilename); // Check the actual FW model number in the '-fwmodel' of 'commandLineArgs' parm. // Update to the head of the desired branch, if possible. UpdateToTheCorrectBranchHeadIfPossible(commandLineArgs, actualCloneResult, cloneLocation); _gotClone = false; switch (actualCloneResult.FinalCloneResult) { case FinalCloneResult.ExistingCloneTargetFolder: MessageBox.Show(CommonResources.kFlexProjectExists, CommonResources.kObtainProject, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Directory.Delete(cloneLocation, true); _newFwProjectPathname = null; return; case FinalCloneResult.FlexVersionIsTooOld: MessageBox.Show(actualCloneResult.Message, CommonResources.kObtainProject, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Directory.Delete(cloneLocation, true); _newFwProjectPathname = null; return; case FinalCloneResult.Cloned: _gotClone = true; break; } FLExProjectUnifier.PutHumptyTogetherAgain(new NullProgress(), false, _newFwProjectPathname); }
private void FinishCloning(Dictionary <string, string> commandLineArgs, string cloneLocation, string expectedPathToClonedRepository) { // "obtain_lift" // 'cloneLocation' wants to be a new folder at the $fwroot\foo\OtherRepositories\foo_LIFT folder, // but Chorus may put it in $fwroot\foo\OtherRepositories\bar. // So, it might need to be moved or the containing folder renamed, // as we have no real control over the actual folder of 'cloneLocation' from Chorus. // 'expectedPathToClonedRepository' is where it is supposed to be. // It may not be in the right, fixed folder, so rename/move, as needed var actualCloneResult = new ActualCloneResult { // Be a bit pessimistic at first. CloneResult = null, ActualCloneFolder = null, FinalCloneResult = FinalCloneResult.ExistingCloneTargetFolder }; // Update to the head of the desired branch, if possible. ObtainProjectStrategyLift.UpdateToTheCorrectBranchHeadIfPossible(cloneLocation, "LIFT" + commandLineArgs["-liftmodel"], actualCloneResult); switch (actualCloneResult.FinalCloneResult) { case FinalCloneResult.ExistingCloneTargetFolder: MessageBox.Show(CommonResources.kFlexProjectExists, CommonResources.kObtainProject, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Directory.Delete(cloneLocation, true); _liftFolder = null; return; case FinalCloneResult.FlexVersionIsTooOld: MessageBox.Show(CommonResources.kFlexUpdateRequired, CommonResources.kObtainProject, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Directory.Delete(cloneLocation, true); _liftFolder = null; return; case FinalCloneResult.Cloned: _gotClone = true; break; } if (cloneLocation == expectedPathToClonedRepository) { _liftFolder = cloneLocation; return; } if (!Directory.Exists(expectedPathToClonedRepository) || Utilities.FolderIsEmpty(expectedPathToClonedRepository)) { if (Directory.Exists(expectedPathToClonedRepository)) { Directory.Delete(expectedPathToClonedRepository); } DirectoryUtilities.MoveDirectorySafely(cloneLocation, expectedPathToClonedRepository); actualCloneResult.ActualCloneFolder = expectedPathToClonedRepository; actualCloneResult.FinalCloneResult = FinalCloneResult.Cloned; _liftFolder = expectedPathToClonedRepository; } else { // Not good at all. if (Directory.Exists(cloneLocation)) { Directory.Delete(cloneLocation, true); } if (Directory.Exists(expectedPathToClonedRepository)) { Directory.Delete(expectedPathToClonedRepository, true); } _liftFolder = null; } }
internal static void UpdateToTheCorrectBranchHeadIfPossible(string cloneLocation, string desiredBranchName, ActualCloneResult cloneResult) { var repo = new HgRepository(cloneLocation, new NullProgress()); Dictionary <string, Revision> allHeads = Utilities.CollectAllBranchHeads(cloneLocation); var desiredModelVersion = float.Parse(desiredBranchName.Replace("LIFT", null)); Revision desiredRevision; if (!allHeads.TryGetValue(desiredBranchName, out desiredRevision)) { // Remove any that are too high. var gonerKeys = new HashSet <string>(); foreach (var headKvp in allHeads) { float currentVersion; if (headKvp.Key == Default) { repo.Update(headKvp.Value.Number.LocalRevisionNumber); currentVersion = GetLiftVersionNumber(cloneLocation); } else { currentVersion = float.Parse(headKvp.Value.Branch); } if (currentVersion > desiredModelVersion) { gonerKeys.Add((headKvp.Key == Default) ? Default : headKvp.Key); } } foreach (var goner in gonerKeys) { allHeads.Remove(goner); } // Replace 'default' with its real model number. if (allHeads.ContainsKey(Default)) { repo.Update(allHeads[Default].Number.LocalRevisionNumber); var modelVersion = GetLiftVersionNumber(cloneLocation); var fullModelVersion = "LIFT" + modelVersion; if (allHeads.ContainsKey(fullModelVersion)) { // Pick the highest revision of the two. var defaultHead = allHeads[Default]; var otherHead = allHeads[fullModelVersion]; var defaultRevisionNumber = int.Parse(defaultHead.Number.LocalRevisionNumber); var otherRevisionNumber = int.Parse(otherHead.Number.LocalRevisionNumber); allHeads[fullModelVersion] = defaultRevisionNumber > otherRevisionNumber ? defaultHead : otherHead; } else { allHeads.Add(fullModelVersion, allHeads[Default]); } allHeads.Remove(Default); } // 'default' is no longer present in 'allHeads'. // If all of them are higher, then it is a no go. if (allHeads.Count == 0) { // No useable model version, so bailout with a message to the user telling them they are 'toast'. cloneResult.FinalCloneResult = FinalCloneResult.FlexVersionIsTooOld; cloneResult.Message = CommonResources.kFlexUpdateRequired; Directory.Delete(cloneLocation, true); return; } // Now. get to the real work. var sortedRevisions = new SortedList <float, Revision>(); foreach (var kvp in allHeads) { sortedRevisions.Add(float.Parse(kvp.Key.Replace("LIFT", null)), kvp.Value); } desiredRevision = sortedRevisions.Values[sortedRevisions.Count - 1]; } repo.Update(desiredRevision.Number.LocalRevisionNumber); cloneResult.ActualCloneFolder = cloneLocation; cloneResult.FinalCloneResult = FinalCloneResult.Cloned; }
/// <summary> /// Start doing whatever is needed for the supported type of action. /// </summary> public void StartWorking(Dictionary <string, string> commandLineArgs) { _baseLiftDir = Utilities.LiftOffset(Path.GetDirectoryName(commandLineArgs["-p"])); var fwLangProjGuid = commandLineArgs["-g"]; var basePathForOldLiftRepos = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "LiftBridge"); if (!Directory.Exists(basePathForOldLiftRepos)) { return; } if (Directory.GetDirectories(basePathForOldLiftRepos).Length == 0) { Directory.Delete(basePathForOldLiftRepos, true); return; } var mappingDocPathname = Path.Combine(basePathForOldLiftRepos, MappingFilename); if (!File.Exists(mappingDocPathname)) { return; } var mappingDoc = XDocument.Load(mappingDocPathname); if (!mappingDoc.Root.HasElements) { Directory.Delete(basePathForOldLiftRepos, true); return; } var removedElements = mappingDoc.Root.Elements(MappingTag) .Where(mapElement => mapElement.Attribute(ProjectguidAttrTag) == null || mapElement.Attribute(RepositoryidentifierAttrTag) == null).ToList(); foreach (var goner in removedElements) { goner.Remove(); } if (removedElements.Count > 0) { removedElements.Clear(); mappingDoc.Save(mappingDocPathname); } string oldLiftFolder = null; foreach (var mapElement in mappingDoc.Root.Elements(MappingTag).ToList()) { if (mapElement.Attribute(ProjectguidAttrTag).Value.ToLowerInvariant() != fwLangProjGuid.ToLowerInvariant()) { continue; } var repoId = mapElement.Attribute(RepositoryidentifierAttrTag).Value; foreach (var directory in Directory.GetDirectories(basePathForOldLiftRepos).Where(directory => Directory.Exists(Path.Combine(directory, Utilities.hg)))) { var repo = new HgRepository(directory, new NullProgress()); if (repo.Identifier != repoId) { continue; } oldLiftFolder = directory; break; } if (oldLiftFolder == null) { continue; } RemoveElementAndSaveDoc(mappingDoc, mapElement, mappingDocPathname); break; } if (oldLiftFolder == null) { return; } var actualCloneResult = new ActualCloneResult(); ObtainProjectStrategyLift.MakeLocalClone(oldLiftFolder, _baseLiftDir); actualCloneResult.ActualCloneFolder = _baseLiftDir; actualCloneResult.FinalCloneResult = FinalCloneResult.Cloned; // Update to the head of the desired branch, if possible. ObtainProjectStrategyLift.UpdateToTheCorrectBranchHeadIfPossible(_baseLiftDir, "LIFT" + commandLineArgs["-liftmodel"], actualCloneResult); if (actualCloneResult.FinalCloneResult != FinalCloneResult.Cloned) { MessageBox.Show(actualCloneResult.Message, LocalizationManager.GetString("LiftBridge_MoveFailed_Title", "Failed to update LiftBridge project.", "Title of error message shown when moving a LiftBridge repo to the FlexBridge location fails.")); // The clone and update did not go smoothly. return; } var folderToZap = mappingDoc.Root.HasElements || Directory.GetDirectories(basePathForOldLiftRepos).Length > 1 ? oldLiftFolder : basePathForOldLiftRepos; Directory.Delete(folderToZap, true); var otherRepoDir = Directory.GetParent(_baseLiftDir).FullName; if (!Directory.Exists(_baseLiftDir) && Directory.GetDirectories(_baseLiftDir).Length == 0) { Directory.Delete(otherRepoDir); } }
private static void UpdateToTheCorrectBranchHeadIfPossible(Dictionary <string, string> commandLineArgs, ActualCloneResult cloneResult, string cloneLocation) { var repo = new HgRepository(cloneLocation, new NullProgress()); Dictionary <string, Revision> allHeads = Utilities.CollectAllBranchHeads(cloneLocation); var desiredBranchName = commandLineArgs["-fwmodel"]; var desiredModelVersion = uint.Parse(desiredBranchName); Revision desiredRevision; if (!allHeads.TryGetValue(desiredBranchName, out desiredRevision)) { // Remove any that are too high. var gonerKeys = new HashSet <string>(); foreach (var headKvp in allHeads) { uint currentVersion; if (headKvp.Key == Default) { repo.Update(headKvp.Value.Number.LocalRevisionNumber); var modelVersion = FLExProjectUnifier.GetModelVersion(cloneLocation); currentVersion = (modelVersion == null) ? uint.MaxValue // Get rid of the initial default commit by making it max for uint. It had no model version file. : uint.Parse(modelVersion); } else { currentVersion = uint.Parse(headKvp.Value.Branch); } if (currentVersion > desiredModelVersion) { gonerKeys.Add((headKvp.Key == Default) ? Default : headKvp.Key); } } foreach (var goner in gonerKeys) { allHeads.Remove(goner); } // Replace 'default' with its real model number. if (allHeads.ContainsKey(Default)) { repo.Update(allHeads[Default].Number.LocalRevisionNumber); var modelVersion = FLExProjectUnifier.GetModelVersion(cloneLocation); if (modelVersion != null) { if (allHeads.ContainsKey(modelVersion)) { // Pick the highest revision of the two. var defaultHead = allHeads[Default]; var otherHead = allHeads[modelVersion]; var defaultRevisionNumber = int.Parse(defaultHead.Number.LocalRevisionNumber); var otherRevisionNumber = int.Parse(otherHead.Number.LocalRevisionNumber); allHeads[modelVersion] = defaultRevisionNumber > otherRevisionNumber ? defaultHead : otherHead; } else { allHeads.Add(modelVersion, allHeads[Default]); } } allHeads.Remove(Default); } // 'default' is no longer present in 'allHeads'. // If all of them are higher, then it is a no go. if (allHeads.Count == 0) { // No useable model version, so bailout with a message to the user telling them they are 'toast'. cloneResult.FinalCloneResult = FinalCloneResult.FlexVersionIsTooOld; cloneResult.Message = CommonResources.kFlexUpdateRequired; Directory.Delete(cloneLocation, true); return; } // Now. get to the real work. var sortedRevisions = new SortedList <uint, Revision>(); foreach (var kvp in allHeads) { sortedRevisions.Add(uint.Parse(kvp.Key), kvp.Value); } desiredRevision = sortedRevisions.Values[sortedRevisions.Count - 1]; } repo.Update(desiredRevision.Number.LocalRevisionNumber); cloneResult.ActualCloneFolder = cloneLocation; cloneResult.FinalCloneResult = FinalCloneResult.Cloned; }