public GetCloneFromInternetDialog(GetCloneFromInternetModel model)
        {
            _model = model;
            //#if !MONO
            Font = SystemFonts.MessageBoxFont;
            //#endif
            InitializeComponent();

            Font = SystemFonts.MessageBoxFont;

            _backgroundWorker = new BackgroundWorker();
            _backgroundWorker.WorkerSupportsCancellation = true;
            _backgroundWorker.RunWorkerCompleted += _backgroundWorker_RunWorkerCompleted;
            _backgroundWorker.DoWork += _backgroundWorker_DoWork;

            _logBox.ShowCopyToClipboardMenuItem = true;
            _logBox.ShowDetailsMenuItem = true;
            _logBox.ShowDiagnosticsMenuItem = true;
            _logBox.ShowFontMenuItem = true;

            _model.AddProgress(_statusProgress);
            _statusProgress.Text = "";
            _statusProgress.Visible = false;
            _model.AddMessageProgress(_logBox);
            _model.ProgressIndicator = _progressBar;
            _model.UIContext = SynchronizationContext.Current;

            _serverSettingsControl = new ServerSettingsControl(){Model=_model};
            _serverSettingsControl.TabIndex = 0;
            _serverSettingsControl.Anchor = (AnchorStyles.Top | AnchorStyles.Left);
            Controls.Add(_serverSettingsControl);

            _targetFolderControl = new TargetFolderControl(_model);
            _targetFolderControl.Anchor = (AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
            _targetFolderControl._downloadButton.Click+=OnDownloadClick;
            _targetFolderControl.Location = new Point(0, _serverSettingsControl.Height +10);
            MinimumSize = new Size(_targetFolderControl.MinimumSize.Width+20, _targetFolderControl.Bottom +20);
            if (_targetFolderControl.Bottom +30> Bottom)
            {
                this.Size = new Size(this.Width,_targetFolderControl.Bottom + 30);
            }
            _targetFolderControl.TabIndex = 1;
            this.Controls.Add(_targetFolderControl);
            _okButton.TabIndex = 90;
            _cancelButton.TabIndex = 91;

            _fixSettingsButton.Left = _cancelButton.Left;
             _targetFolderControl._downloadButton.Top = _okButton.Top-_targetFolderControl.Top	;
             _targetFolderControl._downloadButton.Left = _okButton.Left - 15;

            _logBox.GetDiagnosticsMethod = (progress) =>
                                           	{
                                                var hg = new HgRepository(PathToNewlyClonedFolder, progress);
                                                hg.GetDiagnosticInformationForRemoteProject(progress, ThreadSafeUrl);
                                           	};
        }
 public void URL_AfterConstruction_GoodDefault()
 {
     using (var testFolder = new TemporaryFolder("clonetest"))
     {
         var model = new GetCloneFromInternetModel(testFolder.Path);
         model.AccountName = "account";
         model.Password = "******";
         model.ProjectId = "id";
         Assert.AreEqual("http://*****:*****@resumable.languagedepot.org/id", model.URL.ToLower());
     }
 }
 public void InitFromUri_GivenCompleteUri_AllPropertiesCorrect()
 {
     using (var testFolder = new TemporaryFolder("clonetest"))
     {
         var model = new GetCloneFromInternetModel(testFolder.Path);
         model.InitFromUri("http://*****:*****@hg-languagedepot.org/tpi?localFolder=tokPisin");
         Assert.AreEqual("tokPisin", model.LocalFolderName);
         Assert.IsTrue(model.ReadyToDownload);
         Assert.AreEqual("http://*****:*****@hg-languagedepot.org/tpi",model.URL);
     }
 }
 public void UpdateDisplay_BadModelDoesNotThrow()
 {
     using (var testFolder = new TemporaryFolder("clonetest"))
     {
         var model = new GetCloneFromInternetModel(testFolder.Path);
         model.AccountName = "account";
         model.Password = "******";
         model.ProjectId = "id";
         model.LocalFolderName = "Some<Folder";
         var ctrl = new TargetFolderControl(model);
         Assert.DoesNotThrow(() => { ctrl._localFolderName.Text = "Some<Folders"; });
     }
 }
        public void CleanUpAfterErrorOrCancel_DirectoryDeleted()
        {
            using (var testFolder = new TemporaryFolder("clonetest"))
            {
                var model = new GetCloneFromInternetModel(testFolder.Path);
                model.LocalFolderName = "SomeFolder";
                // Ideally would call model to start the clone - but that's in the dialog for now so fake it instead.
                Directory.CreateDirectory(model.TargetDestination);
                Assert.That(Directory.Exists(model.TargetDestination), Is.True);

                model.CleanUpAfterErrorOrCancel();
                Assert.That(Directory.Exists(model.TargetDestination), Is.False);
            }
        }
Example #6
0
        /// <summary>
        /// Get a teammate's shared project from the specified source.
        /// </summary>
        /// <param name="parent">Window that will be parent of progress window</param>
        /// <param name="projectFilter">Function taking a directory path and telling whether it contains the right sort of repo</param>
        /// <param name="hubQuery">String on which to build a URL query to ChorusHub to accomplish the purpose of 'projectFilter'
        /// in the ChorusHub environment</param>
        /// <example>FLExBridge sends "fileExtension=.lift|._custom_properties" to get both LIFT and FLExBridge repos, but not Bloom ones,
        /// for instance. The server looks in the project's .hg/store/data folder for a file ending in .lift.i or ._custom_properties.i</example>
        /// <param name="baseProjectDirForNewClone">The base folder for the new clone, if created.</param>
        /// <param name="baseProjectDirInWhichToSearchForRepositories">The directory which contains projects we already have, and where the result should go</param>
        /// <param name="lowerLevelRepoPath">Optionally specifies another place to look for existing repos: look in this subfolder of each folder in baseProjectDirInWhichToSearchForRepositories.
        /// This is used in FLEx (passing "OtherRepositories") so existing LIFT repos linked to FW projects can be found. Pass null if not used.</param>
        /// <param name="preferredClonedFolderName"></param>
        /// <param name="howToSendReceiveMessageText">This string is appended to the message we build when we have received a repo and can't keep it, because
        /// it has the same hash as an existing project. We think it is likely the user actually intended to Send/Receive that project rather than obtaining
        /// a duplicate. This message thus typically tells him how to do so, in the particular client program. May also be empty.</param>
        /// <returns>
        /// A CloneResult that provides the clone results (e.g., success or failure) and the actual clone location (null if not created).
        /// </returns>
        public CloneResult GetSharedProjectUsing(Form parent, string baseProjectDirForNewClone, string preferredClonedFolderName,
                                                 Func <string, bool> projectFilter, string hubQuery, string baseProjectDirInWhichToSearchForRepositories, string lowerLevelRepoPath,
                                                 string howToSendReceiveMessageText)
        {
            Guard.AgainstNull(parent, "parent");
            Guard.AgainstNullOrEmptyString(baseProjectDirForNewClone, "baseProjectDirForNewClone");
            Guard.AgainstNullOrEmptyString(baseProjectDirInWhichToSearchForRepositories, "baseProjectDirInWhichToSearchForRepositories");
            if (preferredClonedFolderName == string.Empty)
            {
                preferredClonedFolderName = null;
            }

            Dictionary <string, string> existingRepositories;

            try
            {
                existingRepositories = ExtantRepoIdentifiers(baseProjectDirInWhichToSearchForRepositories, lowerLevelRepoPath);
            }
            catch (ApplicationException e)
            {
                // FLEx issue LT-14301: one reason we may throw is that we can't get the identifier of some project because we don't have
                // sufficient permissions.

                // We think this will be very rare...try to get an automatic notification if it happens.
                UsageReporter.SendEvent("UnusualProblems", "Chorus", "ExtantRepoIdentifiersFailed", null, 0);

                MessageBox.Show(
                    string.Format(LocalizationManager.GetString("Messages.CantGetInfo",
                                                                "You can't get a project from a colleague at present, because some required information about the projects you already have is unavailable. "
                                                                + "This may be because you don't have permission to access a file in one of the projects in {0}.\n\n"
                                                                + "You will probably need technical support to resolve this problem. The following information may be helpful to tech support:") + "\n\n{1}",
                                  baseProjectDirInWhichToSearchForRepositories, e.Message),
                    LocalizationManager.GetString("Messages.CantGetProject", "Cannot get project"));
                return(new CloneResult(null, CloneStatus.NotCreated));
            }
            var existingProjectNames = new HashSet <string>(from dir in Directory.GetDirectories(baseProjectDirInWhichToSearchForRepositories) select Path.GetFileName(dir));

            // "existingRepositoryIdentifiers" is currently not used, but the expectation is that the various models/views could use it how they see fit.
            // "Seeing fit' may mean to warn the user they already have some repository, or as a filter to not show ones that already exist.
            // What to do with the list of extant repos is left up to a view+model pair.

            // Select basic source type.
            using (var getSharedProjectDlg = new GetSharedProjectDlg())
            {
                getSharedProjectDlg.InitFromModel(this);
                getSharedProjectDlg.ShowDialog(parent);
                if (getSharedProjectDlg.DialogResult != DialogResult.OK)
                {
                    return(new CloneResult(null, CloneStatus.NotCreated));
                }
            }

            // Make clone from some source.
            string actualCloneLocation = null;
            var    cloneStatus         = CloneStatus.NotCreated;

            switch (RepositorySource)
            {
            case ExtantRepoSource.Internet:
                var cloneFromInternetModel = new GetCloneFromInternetModel(baseProjectDirForNewClone)
                {
                    LocalFolderName = preferredClonedFolderName
                };
                using (var cloneFromInternetDialog = new GetCloneFromInternetDialog(cloneFromInternetModel))
                {
                    switch (cloneFromInternetDialog.ShowDialog(parent))
                    {
                    default:
                        cloneStatus = CloneStatus.NotCreated;
                        break;

                    case DialogResult.Cancel:
                        cloneStatus = CloneStatus.Cancelled;
                        break;

                    case DialogResult.OK:
                        actualCloneLocation = cloneFromInternetDialog.PathToNewlyClonedFolder;
                        cloneStatus         = CloneStatus.Created;
                        break;
                    }
                }
                break;

            case ExtantRepoSource.ChorusHub:
                var getCloneFromChorusHubModel = new GetCloneFromChorusHubModel(baseProjectDirForNewClone)
                {
                    ProjectFilter    = hubQuery,
                    ExistingProjects = existingProjectNames,
                    ExistingRepositoryIdentifiers = existingRepositories
                };

                using (var getCloneFromChorusHubDialog = new GetCloneFromChorusHubDialog(getCloneFromChorusHubModel))
                {
                    switch (getCloneFromChorusHubDialog.ShowDialog(parent))
                    {
                    default:
                        cloneStatus = CloneStatus.NotCreated;
                        break;

                    case DialogResult.Cancel:
                        cloneStatus = CloneStatus.Cancelled;
                        break;

                    case DialogResult.OK:
                        if (getCloneFromChorusHubModel.CloneSucceeded)
                        {
                            actualCloneLocation = getCloneFromChorusHubDialog.PathToNewlyClonedFolder;
                            cloneStatus         = CloneStatus.Created;
                        }
                        else
                        {
                            cloneStatus = CloneStatus.NotCreated;
                        }
                        break;
                    }
                }
                break;

            case ExtantRepoSource.Usb:
                using (var cloneFromUsbDialog = new GetCloneFromUsbDialog(baseProjectDirForNewClone))
                {
                    cloneFromUsbDialog.Model.ProjectFilter    = projectFilter ?? DefaultProjectFilter;
                    cloneFromUsbDialog.Model.ReposInUse       = existingRepositories;
                    cloneFromUsbDialog.Model.ExistingProjects = existingProjectNames;
                    switch (cloneFromUsbDialog.ShowDialog(parent))
                    {
                    default:
                        cloneStatus = CloneStatus.NotCreated;
                        break;

                    case DialogResult.Cancel:
                        cloneStatus = CloneStatus.Cancelled;
                        break;

                    case DialogResult.OK:
                        actualCloneLocation = cloneFromUsbDialog.PathToNewlyClonedFolder;
                        cloneStatus         = CloneStatus.Created;
                        break;
                    }
                }
                break;
            }
            // Warn the user if they already have this by another name.
            // Not currently needed for USB, since those have already been checked.
            if (RepositorySource != ExtantRepoSource.Usb && cloneStatus == CloneStatus.Created)
            {
                var    repo = new HgRepository(actualCloneLocation, new NullProgress());
                string projectWithExistingRepo;
                if (repo.Identifier != null && existingRepositories.TryGetValue(repo.Identifier, out projectWithExistingRepo))
                {
                    using (var warningDlg = new DuplicateProjectWarningDialog())
                        warningDlg.Run(projectWithExistingRepo, howToSendReceiveMessageText);
                    Directory.Delete(actualCloneLocation, true);
                    actualCloneLocation = null;
                    cloneStatus         = CloneStatus.Cancelled;
                }
            }
            return(new CloneResult(actualCloneLocation, cloneStatus));
        }
Example #7
0
 public TargetFolderControl(GetCloneFromInternetModel model)
 {
     _model = model;
     InitializeComponent();
 }
 public TargetFolderControl(GetCloneFromInternetModel model)
 {
     _model = model;
     InitializeComponent();
 }
 private void LaunchCustomUrl(string url)
 {
     using (var targetComputer = new TemporaryFolder("clonetest-targetComputer"))
     {
         var model = new GetCloneFromInternetModel(targetComputer.Path);
         model.InitFromUri(url);
         using (var dlg = new GetCloneFromInternetDialog(model))
         {
             if (DialogResult.OK != dlg.ShowDialog())
                 return;
         }
     }
 }
Example #10
0
        public GetCloneFromInternetDialog(GetCloneFromInternetModel model)
        {
            _model = model;
            Font   = SystemFonts.MessageBoxFont;
            InitializeComponent();

            Font = SystemFonts.MessageBoxFont;

            _backgroundWorker = new BackgroundWorker();
            _backgroundWorker.WorkerSupportsCancellation = true;
            _backgroundWorker.RunWorkerCompleted        += _backgroundWorker_RunWorkerCompleted;
            _backgroundWorker.DoWork += _backgroundWorker_DoWork;

            _logBox.ShowCopyToClipboardMenuItem = true;
            _logBox.ShowDetailsMenuItem         = true;
            _logBox.ShowDiagnosticsMenuItem     = true;
            _logBox.ShowFontMenuItem            = true;


            _model.AddProgress(_statusProgress);
            _statusProgress.Text    = "";
            _statusProgress.Visible = false;
            _model.AddMessageProgress(_logBox);
            _model.ProgressIndicator = _progressBar;
            _model.UIContext         = SynchronizationContext.Current;

            _serverSettingsControl = new ServerSettingsControl()
            {
                Model = _model
            };
            _serverSettingsControl.TabIndex = 0;
            _serverSettingsControl.Anchor   = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
            Controls.Add(_serverSettingsControl);

            _targetFolderControl        = new TargetFolderControl(_model);
            _targetFolderControl.Anchor = (AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
            _targetFolderControl._downloadButton.Click += OnDownloadClick;
            _targetFolderControl.Location = new Point(0, _serverSettingsControl.Height + 10);
            var minimumWidth = Math.Max(_serverSettingsControl.MinimumSize.Width, _targetFolderControl.MinimumSize.Width) + 20;

            MinimumSize = new Size(minimumWidth, _targetFolderControl.Bottom + 20);
            // On Linux, we have to set the dialog width, then set the control width back to what it had been. TODO: different order
            var sscWidth = _serverSettingsControl.Width;

            Width = sscWidth + 30;
            _serverSettingsControl.Width = sscWidth;
            if (_targetFolderControl.Bottom + 30 > Bottom)
            {
                this.Size = new Size(this.Width, _targetFolderControl.Bottom + 30);
            }
            _targetFolderControl.TabIndex = 1;
            this.Controls.Add(_targetFolderControl);
            _okButton.TabIndex     = 90;
            _cancelButton.TabIndex = 91;

            _fixSettingsButton.Left = _cancelButton.Left;
            var fixBtnWidth = _fixSettingsButton.Width;

            _fixSettingsButton.AutoSize = true;
            if (_fixSettingsButton.Width > fixBtnWidth)
            {
                // The button was too small before autosizing, but now it may extend off the dialog...
                var diff = _fixSettingsButton.Width - fixBtnWidth;
                if (diff < _cancelButton.Left)
                {
                    _fixSettingsButton.Left = _cancelButton.Left - diff;
                }
            }
            _targetFolderControl._downloadButton.Top  = _okButton.Top - _targetFolderControl.Top;
            _targetFolderControl._downloadButton.Left = _okButton.Left - 15;

            _logBox.GetDiagnosticsMethod = (progress) =>
            {
                var hg = new HgRepository(PathToNewlyClonedFolder, progress);
                hg.GetDiagnosticInformationForRemoteProject(progress, ThreadSafeUrl);
            };
        }
        /// <summary>
        /// Get a teammate's shared project from the specified source.
        /// </summary>
        /// <param name="parent">Window that will be parent of progress window</param>
        /// <param name="projectFilter">Function taking a directory path and telling whether it contains the right sort of repo</param>
        /// <param name="hubQuery">String on which to build a URL query to ChorusHub to accomplish the purpose of 'projectFilter'
        /// in the ChorusHub environment</param>
        /// <example>FLExBridge sends "fileExtension=.lift|._custom_properties" to get both LIFT and FLExBridge repos, but not Bloom ones,
        /// for instance. The server looks in the project's .hg/store/data folder for a file ending in .lift.i or ._custom_properties.i</example>
        /// <param name="baseProjectDirForNewClone">The base folder for the new clone, if created.</param>
        /// <param name="baseProjectDirInWhichToSearchForRepositories">The directory which contains projects we already have, and where the result should go</param>
        /// <param name="lowerLevelRepoPath">Optionally specifies another place to look for existing repos: look in this subfolder of each folder in baseProjectDirInWhichToSearchForRepositories.
        /// This is used in FLEx (passing "OtherRepositories") so existing LIFT repos linked to FW projects can be found. Pass null if not used.</param>
        /// <param name="preferredClonedFolderName"></param>
        /// <param name="howToSendReceiveMessageText">This string is appended to the message we build when we have received a repo and can't keep it, because
        /// it has the same hash as an existing project. We think it is likely the user actually intended to Send/Receive that project rather than obtaining
        /// a duplicate. This message thus typically tells him how to do so, in the particular client program. May also be empty.</param>
        /// <returns>
        /// A CloneResult that provides the clone results (e.g., success or failure) and the actual clone location (null if not created).
        /// </returns>
        public CloneResult GetSharedProjectUsing(Form parent, string baseProjectDirForNewClone, string preferredClonedFolderName,
			Func<string, bool> projectFilter, string hubQuery, string baseProjectDirInWhichToSearchForRepositories, string lowerLevelRepoPath,
			string howToSendReceiveMessageText)
        {
            Guard.AgainstNull(parent, "parent");
            Guard.AgainstNullOrEmptyString(baseProjectDirForNewClone, "baseProjectDirForNewClone");
            Guard.AgainstNullOrEmptyString(baseProjectDirInWhichToSearchForRepositories, "baseProjectDirInWhichToSearchForRepositories");
            if (preferredClonedFolderName == string.Empty)
                preferredClonedFolderName = null;

            Dictionary<string, string> existingRepositories;
            try
            {
                existingRepositories = ExtantRepoIdentifiers(baseProjectDirInWhichToSearchForRepositories, lowerLevelRepoPath);
            }
            catch (ApplicationException e)
            {
                // FLEx issue LT-14301: one reason we may throw is that we can't get the identifier of some project because we don't have
                // sufficient permissions.

                // We think this will be very rare...try to get an automatic notification if it happens.
                UsageReporter.SendEvent("UnusualProblems", "Chorus", "ExtantRepoIdentifiersFailed", null, 0);

                MessageBox.Show(
                    string.Format(LocalizationManager.GetString("Messages.CantGetInfo",
                        "You can't get a project from a colleague at present, because some required information about the projects you already have is unavailable. "
                + "This may be because you don't have permission to access a file in one of the projects in {0}.\n\n"
                + "You will probably need technical support to resolve this problem. The following information may be helpful to tech support:") + "\n\n{1}",
                        baseProjectDirInWhichToSearchForRepositories, e.Message),
                        LocalizationManager.GetString("Messages.CantGetProject", "Cannot get project"));
                return new CloneResult(null, CloneStatus.NotCreated);
            }
            var existingProjectNames = new HashSet<string>(from dir in Directory.GetDirectories(baseProjectDirInWhichToSearchForRepositories) select Path.GetFileName(dir));

            // "existingRepositoryIdentifiers" is currently not used, but the expectation is that the various models/views could use it how they see fit.
            // "Seeing fit' may mean to warn the user they already have some repository, or as a filter to not show ones that already exist.
            // Waht to do with the list of extant repos is left up to a view+model pair.

            // Select basic source type.
            using (var getSharedProjectDlg = new GetSharedProjectDlg())
            {
                getSharedProjectDlg.InitFromModel(this);
                getSharedProjectDlg.ShowDialog(parent);
                if (getSharedProjectDlg.DialogResult != DialogResult.OK)
                {
                    return new CloneResult(null, CloneStatus.NotCreated);
                }
            }

            // Make clone from some source.
            string actualCloneLocation = null;
            var cloneStatus = CloneStatus.NotCreated;
            switch (RepositorySource)
            {
                case ExtantRepoSource.Internet:
                    var cloneFromInternetModel = new GetCloneFromInternetModel(baseProjectDirForNewClone)
                        {
                            LocalFolderName = preferredClonedFolderName
                        };
                    using (var cloneFromInternetDialog = new GetCloneFromInternetDialog(cloneFromInternetModel))
                    {
                        switch (cloneFromInternetDialog.ShowDialog(parent))
                        {
                            default:
                                cloneStatus = CloneStatus.NotCreated;
                                break;
                            case DialogResult.Cancel:
                                cloneStatus = CloneStatus.Cancelled;
                                break;
                            case DialogResult.OK:
                                actualCloneLocation = cloneFromInternetDialog.PathToNewlyClonedFolder;
                                cloneStatus = CloneStatus.Created;
                                break;
                        }
                    }
                    break;

                case ExtantRepoSource.ChorusHub:
                    var getCloneFromChorusHubModel = new GetCloneFromChorusHubModel(baseProjectDirForNewClone)
                    {
                        ProjectFilter = hubQuery,
                        ExistingProjects = existingProjectNames,
                        ExistingRepositoryIdentifiers = existingRepositories
                    };

                    using (var getCloneFromChorusHubDialog = new GetCloneFromChorusHubDialog(getCloneFromChorusHubModel))
                    {
                        switch (getCloneFromChorusHubDialog.ShowDialog(parent))
                        {
                            default:
                                cloneStatus = CloneStatus.NotCreated;
                                break;
                            case DialogResult.Cancel:
                                cloneStatus = CloneStatus.Cancelled;
                                break;
                            case DialogResult.OK:
                                if (getCloneFromChorusHubModel.CloneSucceeded)
                                {
                                    actualCloneLocation = getCloneFromChorusHubDialog.PathToNewlyClonedFolder;
                                    cloneStatus = CloneStatus.Created;
                                }
                                else
                                {
                                    cloneStatus = CloneStatus.NotCreated;
                                }
                                break;
                        }
                    }
                    break;

                case ExtantRepoSource.Usb:
                    using (var cloneFromUsbDialog = new GetCloneFromUsbDialog(baseProjectDirForNewClone))
                    {
                        cloneFromUsbDialog.Model.ProjectFilter = projectFilter ?? DefaultProjectFilter;
                        cloneFromUsbDialog.Model.ReposInUse = existingRepositories;
                        cloneFromUsbDialog.Model.ExistingProjects = existingProjectNames;
                        switch (cloneFromUsbDialog.ShowDialog(parent))
                        {
                            default:
                                cloneStatus = CloneStatus.NotCreated;
                                break;
                            case DialogResult.Cancel:
                                cloneStatus = CloneStatus.Cancelled;
                                break;
                            case DialogResult.OK:
                                actualCloneLocation = cloneFromUsbDialog.PathToNewlyClonedFolder;
                                cloneStatus = CloneStatus.Created;
                                break;
                        }
                    }
                    break;

            }
            // Warn the user if they already have this by another name.
            // Not currently needed for USB, since those have already been checked.
            if (RepositorySource != ExtantRepoSource.Usb && cloneStatus == CloneStatus.Created)
            {
                var repo = new HgRepository(actualCloneLocation, new NullProgress());
                string projectWithExistingRepo;
                if (repo.Identifier != null && existingRepositories.TryGetValue(repo.Identifier, out projectWithExistingRepo))
                {
                    using (var warningDlg = new DuplicateProjectWarningDialog())
                        warningDlg.Run(projectWithExistingRepo, howToSendReceiveMessageText);
                    Directory.Delete(actualCloneLocation, true);
                    actualCloneLocation = null;
                    cloneStatus = CloneStatus.Cancelled;
                }

            }
            return new CloneResult(actualCloneLocation, cloneStatus);
        }