From 41e7c287eb1ed6ad4cc74e682a5b343c272d9551 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Tue, 15 Sep 2015 12:47:40 +0200 Subject: [PATCH 1/7] Use ISimpleRepositoryModel instead of IGitRepositoryInfo IGitRepositoryInfo is a VS type that doesn't cache url information. Switch to our ISimpleRepositoryModel which caches the local and remote information and that we can control. --- .../Services/ITeamExplorerServiceHolder.cs | 7 ++++--- .../Base/TeamExplorerGitRepoInfo.cs | 7 ++++--- .../Base/TeamExplorerItemBase.cs | 3 ++- .../Base/TeamExplorerNavigationItemBase.cs | 3 ++- .../Base/TeamExplorerSectionBase.cs | 2 +- .../Base/TeamExplorerServiceHolder.cs | 21 ++++++++++--------- .../Connect/GitHubConnectSection.cs | 4 ++-- 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs b/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs index 7356dc1b7f..26801d4c54 100644 --- a/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs +++ b/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs @@ -1,6 +1,7 @@ using System; using GitHub.Primitives; using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility; +using GitHub.Models; namespace GitHub.Services { @@ -28,13 +29,13 @@ public interface ITeamExplorerServiceHolder /// /// A IGitRepositoryInfo representing the currently active repository /// - IGitRepositoryInfo ActiveRepo { get; } + ISimpleRepositoryModel ActiveRepo { get; } /// /// Subscribe to be notified when the active repository is set and Notify is called. /// /// The instance that is interested in being called (or a unique key/object for that instance) /// The handler to call when ActiveRepo is set - void Subscribe(object who, Action handler); + void Subscribe(object who, Action handler); /// /// Unsubscribe from notifications /// @@ -46,7 +47,7 @@ public interface ITeamExplorerServiceHolder public interface IGitAwareItem { - IGitRepositoryInfo ActiveRepo { get; } + ISimpleRepositoryModel ActiveRepo { get; } /// /// Represents the web URL of the repository on GitHub.com, even if the origin is an SSH address. diff --git a/src/GitHub.VisualStudio/Base/TeamExplorerGitRepoInfo.cs b/src/GitHub.VisualStudio/Base/TeamExplorerGitRepoInfo.cs index 9a75cb4efa..2bc47af60c 100644 --- a/src/GitHub.VisualStudio/Base/TeamExplorerGitRepoInfo.cs +++ b/src/GitHub.VisualStudio/Base/TeamExplorerGitRepoInfo.cs @@ -1,4 +1,5 @@ -using GitHub.Primitives; +using GitHub.Models; +using GitHub.Primitives; using GitHub.Services; using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility; using NullGuard; @@ -12,9 +13,9 @@ public TeamExplorerGitRepoInfo() ActiveRepo = null; } - IGitRepositoryInfo activeRepo; + ISimpleRepositoryModel activeRepo; [AllowNull] - public IGitRepositoryInfo ActiveRepo + public ISimpleRepositoryModel ActiveRepo { [return: AllowNull] get { return activeRepo; } diff --git a/src/GitHub.VisualStudio/Base/TeamExplorerItemBase.cs b/src/GitHub.VisualStudio/Base/TeamExplorerItemBase.cs index 7ef7fc1887..b181f9ea0e 100644 --- a/src/GitHub.VisualStudio/Base/TeamExplorerItemBase.cs +++ b/src/GitHub.VisualStudio/Base/TeamExplorerItemBase.cs @@ -7,6 +7,7 @@ using GitHub.VisualStudio.Helpers; using NullGuard; using Octokit; +using GitHub.Extensions; namespace GitHub.VisualStudio.Base { @@ -49,7 +50,7 @@ protected virtual void RepoChanged() var repo = ActiveRepo; if (repo != null) { - var uri = repo.GetUriFromRepository(); + var uri = repo.CloneUrl; if (uri?.RepositoryName != null) { ActiveRepoUri = uri; diff --git a/src/GitHub.VisualStudio/Base/TeamExplorerNavigationItemBase.cs b/src/GitHub.VisualStudio/Base/TeamExplorerNavigationItemBase.cs index dd3abd0aad..e60fc892f0 100644 --- a/src/GitHub.VisualStudio/Base/TeamExplorerNavigationItemBase.cs +++ b/src/GitHub.VisualStudio/Base/TeamExplorerNavigationItemBase.cs @@ -10,6 +10,7 @@ using Microsoft.VisualStudio.PlatformUI; using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility; using NullGuard; +using GitHub.Models; namespace GitHub.VisualStudio.Base { @@ -56,7 +57,7 @@ void OnThemeChanged() } } - void UpdateRepo(IGitRepositoryInfo repo) + void UpdateRepo(ISimpleRepositoryModel repo) { ActiveRepo = repo; RepoChanged(); diff --git a/src/GitHub.VisualStudio/Base/TeamExplorerSectionBase.cs b/src/GitHub.VisualStudio/Base/TeamExplorerSectionBase.cs index 7f6b0833d5..6b234ba36c 100644 --- a/src/GitHub.VisualStudio/Base/TeamExplorerSectionBase.cs +++ b/src/GitHub.VisualStudio/Base/TeamExplorerSectionBase.cs @@ -100,7 +100,7 @@ public virtual void SaveContext(object sender, SectionSaveContextEventArgs e) void SubscribeToRepoChanges() { - holder.Subscribe(this, (IGitRepositoryInfo repo) => + holder.Subscribe(this, (ISimpleRepositoryModel repo) => { ActiveRepo = repo; RepoChanged(); diff --git a/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs b/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs index 931494e2d3..85283fa266 100644 --- a/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs +++ b/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Globalization; +using GitHub.Models; namespace GitHub.VisualStudio.Base { @@ -18,8 +19,8 @@ namespace GitHub.VisualStudio.Base [PartCreationPolicy(CreationPolicy.Shared)] public class TeamExplorerServiceHolder : ITeamExplorerServiceHolder { - readonly Dictionary> activeRepoHandlers = new Dictionary>(); - IGitRepositoryInfo activeRepo; + readonly Dictionary> activeRepoHandlers = new Dictionary>(); + ISimpleRepositoryModel activeRepo; bool activeRepoNotified = false; IServiceProvider serviceProvider; @@ -48,24 +49,24 @@ public IServiceProvider ServiceProvider if (serviceProvider == null) return; GitUIContext = GitUIContext ?? UIContext.FromUIContextGuid(new Guid("11B8E6D7-C08B-4385-B321-321078CDD1F8")); - UIContextChanged(GitUIContext?.IsActive ?? false); + UIContextChanged(GitUIContext?.IsActive ?? false, false); } } [AllowNull] - public IGitRepositoryInfo ActiveRepo + public ISimpleRepositoryModel ActiveRepo { [return: AllowNull] get { return activeRepo; } private set { - if (activeRepo.Compare(value)) + if (Equals(activeRepo, value)) return; activeRepo = value; NotifyActiveRepo(); } } - public void Subscribe(object who, Action handler) + public void Subscribe(object who, Action handler) { lock(activeRepoHandlers) { @@ -140,7 +141,7 @@ async void UIContextChanged(bool active) if (repos == null) VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error 2002: ActiveRepositories is null. GitService: '{0}'", GitService)); } - return repos?.FirstOrDefault(); + return repos?.FirstOrDefault()?.ToModel(); }); } else @@ -156,11 +157,11 @@ void CheckAndUpdate(object sender, System.ComponentModel.PropertyChangedEventArg if (service == null) return; - var repo = service.ActiveRepositories.FirstOrDefault(); + var repo = service.ActiveRepositories.FirstOrDefault()?.ToModel(); // this comparison is safe, the extension method supports null instances - if (!repo.Compare(ActiveRepo)) + if (!repo.Equals(ActiveRepo)) // so annoying that this is on the wrong thread - syncContext.Post(r => ActiveRepo = r as IGitRepositoryInfo, repo); + syncContext.Post(r => ActiveRepo = r as ISimpleRepositoryModel, repo); } public IGitAwareItem HomeSection diff --git a/src/GitHub.VisualStudio/TeamExplorer/Connect/GitHubConnectSection.cs b/src/GitHub.VisualStudio/TeamExplorer/Connect/GitHubConnectSection.cs index 59ba33e00a..95982b14df 100644 --- a/src/GitHub.VisualStudio/TeamExplorer/Connect/GitHubConnectSection.cs +++ b/src/GitHub.VisualStudio/TeamExplorer/Connect/GitHubConnectSection.cs @@ -209,7 +209,7 @@ async void UpdateRepositoryList(object sender, NotifyCollectionChangedEventArgs .Cast() .ForEach(async r => { - if (String.Equals(Holder.ActiveRepo?.RepositoryPath, r.LocalPath, StringComparison.CurrentCultureIgnoreCase)) + if (Equals(Holder.ActiveRepo, r)) SelectedRepository = r; var repo = await ApiFactory.Create(r.CloneUrl).GetRepository(); r.SetIcon(repo.Private, repo.Fork); @@ -298,7 +298,7 @@ public void Login() public bool OpenRepository() { - var old = Repositories.FirstOrDefault(x => String.Equals(Holder.ActiveRepo?.RepositoryPath, x.LocalPath, StringComparison.CurrentCultureIgnoreCase)); + var old = Repositories.FirstOrDefault(x => x.Equals(Holder.ActiveRepo)); // open the solution selection dialog when the user wants to switch to a different repo // since there's no other way of changing the source control context in VS if (!Equals(SelectedRepository, old)) From 197c7f1a827ccdd4ab97c1d1b774aa731a404cd5 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Tue, 15 Sep 2015 18:38:54 +0200 Subject: [PATCH 2/7] Add more functionality to SimpleRepositoryModel Now that ActiveRepo is a SimpleRepositoryModel, we need a way to update the url, for when a user adds or removes the origin remote manually inside Visual Studio (in the git repo settings), or via the command line. This is required so that the UI updates properly and rechecks whether the repo is ours or not. --- .../Extensions/RepositoryModelExtensions.cs | 4 +- src/GitHub.App/SampleData/SampleViewModels.cs | 4 +- .../Models/ISimpleRepositoryModel.cs | 9 +++- .../Models/SimpleRepositoryModel.cs | 48 +++++++++++++++++-- src/GitHub.Exports/Services/VSServices.cs | 10 +--- 5 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/GitHub.App/Extensions/RepositoryModelExtensions.cs b/src/GitHub.App/Extensions/RepositoryModelExtensions.cs index 50d3a428e2..252e5e5532 100644 --- a/src/GitHub.App/Extensions/RepositoryModelExtensions.cs +++ b/src/GitHub.App/Extensions/RepositoryModelExtensions.cs @@ -15,9 +15,7 @@ public static ISimpleRepositoryModel ToModel([AllowNull] this IGitRepositoryInfo { if (repo == null) return null; - var uri = repo.GetUriFromRepository(); - var name = uri?.NameWithOwner; - return name != null ? new SimpleRepositoryModel(name, uri, repo.RepositoryPath) : null; + return SimpleRepositoryModel.Create(repo.RepositoryPath); } } } diff --git a/src/GitHub.App/SampleData/SampleViewModels.cs b/src/GitHub.App/SampleData/SampleViewModels.cs index 161a5767e2..c93d26acd2 100644 --- a/src/GitHub.App/SampleData/SampleViewModels.cs +++ b/src/GitHub.App/SampleData/SampleViewModels.cs @@ -388,7 +388,7 @@ public long PrivateReposInPlan } [ExcludeFromCodeCoverage] - public class RepositoryModelDesigner : IRepositoryModel + public class RepositoryModelDesigner : NotificationAwareObject, IRepositoryModel { public RepositoryModelDesigner() : this("repo") { @@ -416,6 +416,8 @@ public void SetIcon(bool isPrivate, bool isFork) public Octicon Icon { get; set; } public IAccount Owner { get; set; } + + public void Refresh() { } } public class RepositoryCloneViewModelDesigner : BaseViewModelDesigner, IRepositoryCloneViewModel diff --git a/src/GitHub.Exports/Models/ISimpleRepositoryModel.cs b/src/GitHub.Exports/Models/ISimpleRepositoryModel.cs index 5b15b3d179..197a09378f 100644 --- a/src/GitHub.Exports/Models/ISimpleRepositoryModel.cs +++ b/src/GitHub.Exports/Models/ISimpleRepositoryModel.cs @@ -1,9 +1,10 @@ using GitHub.Primitives; using GitHub.UI; +using System.ComponentModel; namespace GitHub.Models { - public interface ISimpleRepositoryModel + public interface ISimpleRepositoryModel : INotifyPropertyChanged { string Name { get; } UriString CloneUrl { get; } @@ -11,5 +12,11 @@ public interface ISimpleRepositoryModel Octicon Icon { get; } void SetIcon(bool isPrivate, bool isFork); + + + /// + /// Updates the url information based on the local path + /// + void Refresh(); } } diff --git a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs index 7ca976a1d1..0b345002ce 100644 --- a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs +++ b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs @@ -1,9 +1,11 @@ -using GitHub.Primitives; +using GitHub.Extensions; +using GitHub.Primitives; using GitHub.UI; using GitHub.VisualStudio.Helpers; using System; using System.Diagnostics; using System.Globalization; +using System.IO; namespace GitHub.Models { @@ -18,6 +20,31 @@ public SimpleRepositoryModel(string name, UriString cloneUrl, string localPath = Icon = Octicon.repo; } + public SimpleRepositoryModel(string path) + { + if (path == null) + throw new ArgumentNullException("path"); + if (!Directory.Exists(path)) + throw new ArgumentException("Path does not exist", path); + var uri = GitHelpers.GetRepoFromPath(path)?.GetUri(); + var name = uri?.NameWithOwner; + if (name == null) + name = Path.GetDirectoryName(name); + Name = name; + LocalPath = path; + CloneUrl = uri; + Icon = Octicon.repo; + } + + public static ISimpleRepositoryModel Create(string path) + { + if (path == null) + return null; + if (!Directory.Exists(path)) + return null; + return new SimpleRepositoryModel(path); + } + public void SetIcon(bool isPrivate, bool isFork) { Icon = isPrivate @@ -27,15 +54,30 @@ public void SetIcon(bool isPrivate, bool isFork) : Octicon.repo; } + public void Refresh() + { + if (LocalPath == null) + return; + var uri = GitHelpers.GetRepoFromPath(LocalPath)?.GetUri(); + if (CloneUrl != uri) + CloneUrl = uri; + } + public string Name { get; private set; } - public UriString CloneUrl { get; private set; } + UriString cloneUrl; + public UriString CloneUrl { get { return cloneUrl; } set { cloneUrl = value; this.RaisePropertyChange(); } } public string LocalPath { get; private set; } Octicon icon; public Octicon Icon { get { return icon; } set { icon = value; this.RaisePropertyChange(); } } + /// + /// Note: We don't consider CloneUrl a part of the hash code because it can change during the lifetime + /// of a repository. Equals takes care of any hash collisions because of this + /// + /// public override int GetHashCode() { - return (Name?.GetHashCode() ?? 0) ^ (CloneUrl?.GetHashCode() ?? 0) ^ (LocalPath?.TrimEnd('\\').ToUpperInvariant().GetHashCode() ?? 0); + return (Name?.GetHashCode() ?? 0) ^ (LocalPath?.TrimEnd('\\').ToUpperInvariant().GetHashCode() ?? 0); } public override bool Equals(object obj) diff --git a/src/GitHub.Exports/Services/VSServices.cs b/src/GitHub.Exports/Services/VSServices.cs index e851a48d3d..ce830e15ec 100644 --- a/src/GitHub.Exports/Services/VSServices.cs +++ b/src/GitHub.Exports/Services/VSServices.cs @@ -117,16 +117,8 @@ static IEnumerable PokeTheRegistryForRepositoryList() { using (var subkey = key.OpenSubKey(x)) { - var path = subkey?.GetValue("Path") as string; - if (path != null) - { - var uri = VisualStudio.Services.GetRepoFromPath(path)?.GetUri(); - var name = uri?.NameWithOwner; - if (name != null) - return new SimpleRepositoryModel(name, uri, path); - } + return SimpleRepositoryModel.Create(subkey?.GetValue("Path") as string); } - return null; }) .Where(x => x != null) .ToList(); From 788e726a30cd55a9875aa54bde97de1769b531fb Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Tue, 15 Sep 2015 18:39:51 +0200 Subject: [PATCH 3/7] CloneUrl can be null now, so check that --- src/GitHub.VisualStudio/Services/ConnectionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitHub.VisualStudio/Services/ConnectionManager.cs b/src/GitHub.VisualStudio/Services/ConnectionManager.cs index 9cbfd6598e..41cc18c7d2 100644 --- a/src/GitHub.VisualStudio/Services/ConnectionManager.cs +++ b/src/GitHub.VisualStudio/Services/ConnectionManager.cs @@ -129,7 +129,7 @@ public void RequestLogout(IConnection connection) public void RefreshRepositories() { var list = vsServices.GetKnownRepositories(); - list.GroupBy(r => Connections.FirstOrDefault(c => c.HostAddress.Equals(HostAddress.Create(r.CloneUrl)))) + list.GroupBy(r => Connections.FirstOrDefault(c => r.CloneUrl != null && c.HostAddress.Equals(HostAddress.Create(r.CloneUrl)))) .Where(g => g.Key != null) .ForEach(g => { From 1aaea466c079637df9cc15935c4c41866eaf32c8 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Tue, 15 Sep 2015 18:52:22 +0200 Subject: [PATCH 4/7] Make sure the ActiveRepo data is always up to date If the origin remote url changes, update ActiveRepo that as soon as possible. --- .../Services/ITeamExplorerServiceHolder.cs | 5 +++ .../Base/TeamExplorerServiceHolder.cs | 44 +++++++++++++++---- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs b/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs index 26801d4c54..eab5345aef 100644 --- a/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs +++ b/src/GitHub.Exports/Services/ITeamExplorerServiceHolder.cs @@ -43,6 +43,11 @@ public interface ITeamExplorerServiceHolder void Unsubscribe(object who); IGitAwareItem HomeSection { get; } + + /// + /// Refresh the information on the active repo (in case of remote url changes or other such things) + /// + void Refresh(); } public interface IGitAwareItem diff --git a/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs b/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs index 85283fa266..046b0171a7 100644 --- a/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs +++ b/src/GitHub.VisualStudio/Base/TeamExplorerServiceHolder.cs @@ -59,25 +59,40 @@ public ISimpleRepositoryModel ActiveRepo [return: AllowNull] get { return activeRepo; } private set { - if (Equals(activeRepo, value)) + if (activeRepo == value) return; + if (activeRepo != null) + activeRepo.PropertyChanged -= ActiveRepoPropertyChanged; activeRepo = value; + if (activeRepo != null) + activeRepo.PropertyChanged += ActiveRepoPropertyChanged; NotifyActiveRepo(); } } public void Subscribe(object who, Action handler) { + bool notificationsExist; + ISimpleRepositoryModel repo; lock(activeRepoHandlers) { - var repo = ActiveRepo; + repo = ActiveRepo; + notificationsExist = activeRepoNotified; if (!activeRepoHandlers.ContainsKey(who)) activeRepoHandlers.Add(who, handler); else activeRepoHandlers[who] = handler; - if (activeRepoNotified) - handler(repo); } + + // the repo url might have changed and we don't get notifications + // for that, so this is a good place to refresh it in case that happened + repo?.Refresh(); + + // if the active repo hasn't changed and there's notifications queued up, + // notify the subscriber. If the repo has changed, the set above will trigger + // notifications so we don't have to do it here. + if (repo == ActiveRepo && notificationsExist) + handler(repo); } public void Unsubscribe(object who) @@ -101,6 +116,12 @@ public void ClearServiceProvider(IServiceProvider provider) ServiceProvider = null; } + public void Refresh() + { + GitUIContext = GitUIContext ?? UIContext.FromUIContextGuid(new Guid("11B8E6D7-C08B-4385-B321-321078CDD1F8")); + UIContextChanged(GitUIContext?.IsActive ?? false, true); + } + void NotifyActiveRepo() { lock (activeRepoHandlers) @@ -114,10 +135,10 @@ void NotifyActiveRepo() void UIContextChanged(object sender, UIContextChangedEventArgs e) { ActiveRepo = null; - UIContextChanged(e.Activated); + UIContextChanged(e.Activated, false); } - async void UIContextChanged(bool active) + async void UIContextChanged(bool active, bool refresh) { Debug.Assert(ServiceProvider != null, "UIContextChanged called before service provider is set"); if (ServiceProvider == null) @@ -126,7 +147,7 @@ async void UIContextChanged(bool active) if (active) { GitService = GitService ?? ServiceProvider.GetService(); - if (ActiveRepo == null) + if (ActiveRepo == null || refresh) ActiveRepo = await System.Threading.Tasks.Task.Run(() => { var repos = GitService?.ActiveRepositories; @@ -158,12 +179,17 @@ void CheckAndUpdate(object sender, System.ComponentModel.PropertyChangedEventArg return; var repo = service.ActiveRepositories.FirstOrDefault()?.ToModel(); - // this comparison is safe, the extension method supports null instances - if (!repo.Equals(ActiveRepo)) + if (repo != ActiveRepo) // so annoying that this is on the wrong thread syncContext.Post(r => ActiveRepo = r as ISimpleRepositoryModel, repo); } + void ActiveRepoPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == "CloneUrl") + ActiveRepo = sender as ISimpleRepositoryModel; + } + public IGitAwareItem HomeSection { [return:AllowNull] From 7dd53df88a1d223a88fc92d1bac15ea54091b083 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Wed, 16 Sep 2015 14:14:06 +0200 Subject: [PATCH 5/7] Fix the build, the extension changes are on a separate branch --- src/GitHub.Exports/Models/SimpleRepositoryModel.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs index 0b345002ce..80694c9226 100644 --- a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs +++ b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs @@ -1,6 +1,7 @@ using GitHub.Extensions; using GitHub.Primitives; using GitHub.UI; +using GitHub.VisualStudio; using GitHub.VisualStudio.Helpers; using System; using System.Diagnostics; @@ -26,7 +27,7 @@ public SimpleRepositoryModel(string path) throw new ArgumentNullException("path"); if (!Directory.Exists(path)) throw new ArgumentException("Path does not exist", path); - var uri = GitHelpers.GetRepoFromPath(path)?.GetUri(); + var uri = VisualStudio.Services.GetRepoFromPath(path)?.GetUri(); var name = uri?.NameWithOwner; if (name == null) name = Path.GetDirectoryName(name); @@ -58,7 +59,7 @@ public void Refresh() { if (LocalPath == null) return; - var uri = GitHelpers.GetRepoFromPath(LocalPath)?.GetUri(); + var uri = VisualStudio.Services.GetRepoFromPath(LocalPath)?.GetUri(); if (CloneUrl != uri) CloneUrl = uri; } From fa9ba8c196eb34e4cbdc1cfd7a2cb388aae6a8c6 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 18 Sep 2015 16:14:34 +0200 Subject: [PATCH 6/7] Fix setting the name from the path --- src/GitHub.Exports/Models/SimpleRepositoryModel.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs index 80694c9226..518a74876a 100644 --- a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs +++ b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs @@ -25,12 +25,13 @@ public SimpleRepositoryModel(string path) { if (path == null) throw new ArgumentNullException("path"); - if (!Directory.Exists(path)) + var dir = new DirectoryInfo(path); + if (!dir.Exists) throw new ArgumentException("Path does not exist", path); var uri = VisualStudio.Services.GetRepoFromPath(path)?.GetUri(); var name = uri?.NameWithOwner; if (name == null) - name = Path.GetDirectoryName(name); + name = dir.Name; Name = name; LocalPath = path; CloneUrl = uri; From 70a9090cc6c99f0979fae99953a37471fe25dc59 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 18 Sep 2015 16:45:47 +0200 Subject: [PATCH 7/7] Yay C# 6! --- src/GitHub.Exports/Models/SimpleRepositoryModel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs index 0b5492fe82..4ec5ddbe83 100644 --- a/src/GitHub.Exports/Models/SimpleRepositoryModel.cs +++ b/src/GitHub.Exports/Models/SimpleRepositoryModel.cs @@ -24,10 +24,10 @@ public SimpleRepositoryModel(string name, UriString cloneUrl, string localPath = public SimpleRepositoryModel(string path) { if (path == null) - throw new ArgumentNullException("path"); + throw new ArgumentNullException(nameof(path)); var dir = new DirectoryInfo(path); if (!dir.Exists) - throw new ArgumentException("Path does not exist", path); + throw new ArgumentException("Path does not exist", nameof(path)); var uri = GitHelpers.GetRepoFromPath(path)?.GetUri(); var name = uri?.NameWithOwner; if (name == null)