Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 067be61

Browse files
committed
Merge pull request #97 from github/shana/repository-tests
Add repository model tests
2 parents a960664 + ef0a40e commit 067be61

File tree

14 files changed

+312
-128
lines changed

14 files changed

+312
-128
lines changed

src/DesignTimeStyleHelper/MainWindow.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using GitHub.SampleData;
44
using GitHub.Services;
55
using GitHub.UI;
6-
using GitHub.VisualStudio;
6+
using GitHub.Extensions;
77
using GitHub.Models;
88

99
namespace DesignTimeStyleHelper

src/GitHub.App/Services/RepositoryPublishService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace GitHub.Services
1313
public class RepositoryPublishService : IRepositoryPublishService
1414
{
1515
readonly IGitClient gitClient;
16-
readonly Repository activeRepository;
16+
readonly IRepository activeRepository;
1717

1818
[ImportingConstructor]
1919
public RepositoryPublishService(IGitClient gitClient, IVSServices services)

src/GitHub.Exports/Extensions/SimpleRepositoryModelExtensions.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
using GitHub.Models;
2-
using System;
1+
using System;
32
using System.Linq;
43
using System.IO;
4+
using GitHub.Models;
55
using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility;
66

77
namespace GitHub.Extensions
@@ -13,14 +13,12 @@ public static class SimpleRepositoryModelExtensions
1313
/// </summary>
1414
public static ISimpleRepositoryModel ToModel(this IGitRepositoryInfo repo)
1515
{
16-
if (repo == null)
17-
return null;
18-
return SimpleRepositoryModel.Create(repo.RepositoryPath);
16+
return repo == null ? null : new SimpleRepositoryModel(repo.RepositoryPath);
1917
}
2018

2119
public static bool HasCommits(this ISimpleRepositoryModel repository)
2220
{
23-
var repo = GitHelpers.GetRepoFromPath(repository.LocalPath);
21+
var repo = VisualStudio.Services.IGitService.GetRepo(repository.LocalPath);
2422
return repo?.Commits.Any() ?? false;
2523
}
2624

src/GitHub.Exports/Extensions/VSExtensions.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
using GitHub.Services;
2-
using Microsoft.TeamFoundation.Controls;
3-
using System;
1+
using System;
42
using System.Diagnostics;
3+
using GitHub.Services;
4+
using Microsoft.TeamFoundation.Controls;
55

66
namespace GitHub.Extensions
77
{
@@ -36,6 +36,14 @@ public static T GetService<T>(this IServiceProvider serviceProvider)
3636
return (T)serviceProvider.GetService(typeof(T));
3737
}
3838

39+
public static T GetExportedValue<T>(this IServiceProvider serviceProvider)
40+
{
41+
var ui = serviceProvider as IUIProvider;
42+
return ui != null
43+
? ui.GetService<T>()
44+
: VisualStudio.Services.ComponentModel.DefaultExportProvider.GetExportedValue<T>();
45+
}
46+
3947
public static ITeamExplorerSection GetSection(this IServiceProvider serviceProvider, Guid section)
4048
{
4149
return serviceProvider?.GetService<ITeamExplorerPage>()?.GetSection(section);

src/GitHub.Exports/GitHub.Exports.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@
111111
<Compile Include="Models\SimpleRepositoryModel.cs" />
112112
<Compile Include="Helpers\NotificationAwareObject.cs" />
113113
<Compile Include="Services\Connection.cs" />
114+
<Compile Include="Services\GitService.cs" />
115+
<Compile Include="Services\IGitService.cs" />
114116
<Compile Include="Services\ITeamExplorerServiceHolder.cs" />
115117
<Compile Include="Services\Logger.cs" />
116118
<Compile Include="Services\Services.cs" />

src/GitHub.Exports/Models/SimpleRepositoryModel.cs

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
using GitHub.Extensions;
2-
using GitHub.Primitives;
3-
using GitHub.UI;
4-
using GitHub.VisualStudio;
5-
using GitHub.VisualStudio.Helpers;
6-
using System;
1+
using System;
72
using System.Diagnostics;
83
using System.Globalization;
94
using System.IO;
5+
using GitHub.Primitives;
6+
using GitHub.UI;
7+
using GitHub.VisualStudio.Helpers;
108

119
namespace GitHub.Models
1210
{
@@ -28,25 +26,14 @@ public SimpleRepositoryModel(string path)
2826
var dir = new DirectoryInfo(path);
2927
if (!dir.Exists)
3028
throw new ArgumentException("Path does not exist", nameof(path));
31-
var uri = GitHelpers.GetRepoFromPath(path)?.GetUri();
32-
var name = uri?.NameWithOwner;
33-
if (name == null)
34-
name = dir.Name;
29+
var uri = VisualStudio.Services.IGitService.GetUri(path);
30+
var name = uri?.NameWithOwner ?? dir.Name;
3531
Name = name;
3632
LocalPath = path;
3733
CloneUrl = uri;
3834
Icon = Octicon.repo;
3935
}
4036

41-
public static ISimpleRepositoryModel Create(string path)
42-
{
43-
if (path == null)
44-
return null;
45-
if (!Directory.Exists(path))
46-
return null;
47-
return new SimpleRepositoryModel(path);
48-
}
49-
5037
public void SetIcon(bool isPrivate, bool isFork)
5138
{
5239
Icon = isPrivate
@@ -60,15 +47,15 @@ public void Refresh()
6047
{
6148
if (LocalPath == null)
6249
return;
63-
var uri = GitHelpers.GetRepoFromPath(LocalPath)?.GetUri();
50+
var uri = VisualStudio.Services.IGitService.GetUri(LocalPath);
6451
if (CloneUrl != uri)
6552
CloneUrl = uri;
6653
}
6754

68-
public string Name { get; private set; }
55+
public string Name { get; }
6956
UriString cloneUrl;
7057
public UriString CloneUrl { get { return cloneUrl; } set { cloneUrl = value; this.RaisePropertyChange(); } }
71-
public string LocalPath { get; private set; }
58+
public string LocalPath { get; }
7259
Octicon icon;
7360
public Octicon Icon { get { return icon; } set { icon = value; this.RaisePropertyChange(); } }
7461

@@ -97,13 +84,12 @@ bool IEquatable<SimpleRepositoryModel>.Equals(SimpleRepositoryModel other)
9784
return other != null && String.Equals(Name, other.Name) && String.Equals(CloneUrl, other.CloneUrl) && String.Equals(LocalPath?.TrimEnd('\\'), other.LocalPath?.TrimEnd('\\'), StringComparison.CurrentCultureIgnoreCase);
9885
}
9986

100-
internal string DebuggerDisplay
101-
{
102-
get
103-
{
104-
return String.Format(CultureInfo.InvariantCulture,
105-
"{3}\tName: {0} CloneUrl: {1} LocalPath: {2}", Name, CloneUrl, LocalPath, GetHashCode());
106-
}
107-
}
87+
internal string DebuggerDisplay => String.Format(
88+
CultureInfo.InvariantCulture,
89+
"{3}\tName: {0} CloneUrl: {1} LocalPath: {2}",
90+
Name,
91+
CloneUrl,
92+
LocalPath,
93+
GetHashCode());
10894
}
10995
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using System;
2+
using System.ComponentModel.Composition;
3+
using System.Linq;
4+
using GitHub.Primitives;
5+
using LibGit2Sharp;
6+
using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility;
7+
8+
namespace GitHub.Services
9+
{
10+
[Export(typeof(IVSServices))]
11+
[PartCreationPolicy(CreationPolicy.Shared)]
12+
public class GitService : IGitService
13+
{
14+
/// <summary>
15+
/// Returns the URL of the remote named "origin" for the specified <see cref="repository"/>. If the repository
16+
/// is null or no remote named origin exists, this method returns null
17+
/// </summary>
18+
/// <param name="repository">The repository to look at for the remote.</param>
19+
/// <returns>A <see cref="UriString"/> representing the origin or null if none found.</returns>
20+
public UriString GetUri(IRepository repository)
21+
{
22+
return UriString.ToUriString(GetUriFromRepository(repository)?.ToRepositoryUrl());
23+
}
24+
25+
/// <summary>
26+
/// Probes for a git repository and if one is found, returns a <see cref="UriString"/> for the repository's
27+
/// remote named "origin" if one is found
28+
/// </summary>
29+
/// <remarks>
30+
/// The lookup checks to see if the specified <paramref name="path"/> is a repository. If it's not, it then
31+
/// walks up the parent directories until it either finds a repository, or reaches the root disk.
32+
/// </remarks>
33+
/// <param name="path">The path to start probing</param>
34+
/// <returns>A <see cref="UriString"/> representing the origin or null if none found.</returns>
35+
public UriString GetUri(string path)
36+
{
37+
return GetUri(GetRepo(path));
38+
}
39+
40+
/// <summary>
41+
/// Probes for a git repository and if one is found, returns a <see cref="UriString"/> for the repository's
42+
/// remote named "origin" if one is found
43+
/// </summary>
44+
/// <remarks>
45+
/// The lookup checks to see if the path specified by the RepositoryPath property of the specified
46+
/// <see cref="repoInfo"/> is a repository. If it's not, it then walks up the parent directories until it
47+
/// either finds a repository, or reaches the root disk.
48+
/// </remarks>
49+
/// <param name="repoInfo">The repository information containing the path to start probing</param>
50+
/// <returns>A <see cref="UriString"/> representing the origin or null if none found.</returns>
51+
public UriString GetUri(IGitRepositoryInfo repoInfo)
52+
{
53+
return GetUri(GetRepo(repoInfo));
54+
}
55+
56+
/// <summary>
57+
/// Probes for a git repository and if one is found, returns a <see cref="IRepository"/> instance for the
58+
/// repository.
59+
/// </summary>
60+
/// <remarks>
61+
/// The lookup checks to see if the path specified by the RepositoryPath property of the specified
62+
/// <see cref="repoInfo"/> is a repository. If it's not, it then walks up the parent directories until it
63+
/// either finds a repository, or reaches the root disk.
64+
/// </remarks>
65+
/// <param name="repoInfo">The repository information containing the path to start probing</param>
66+
/// <returns>An instance of <see cref="IRepository"/> or null</returns>
67+
68+
public IRepository GetRepo(IGitRepositoryInfo repoInfo)
69+
{
70+
return GetRepo(repoInfo?.RepositoryPath);
71+
}
72+
73+
/// <summary>
74+
/// Probes for a git repository and if one is found, returns a <see cref="IRepository"/> instance for the
75+
/// repository.
76+
/// </summary>
77+
/// <remarks>
78+
/// The lookup checks to see if the specified <paramref name="path"/> is a repository. If it's not, it then
79+
/// walks up the parent directories until it either finds a repository, or reaches the root disk.
80+
/// </remarks>
81+
/// <param name="path">The path to start probing</param>
82+
/// <returns>An instance of <see cref="IRepository"/> or null</returns>
83+
public IRepository GetRepo(string path)
84+
{
85+
var repoPath = Repository.Discover(path);
86+
return repoPath == null ? null : new Repository(repoPath);
87+
}
88+
89+
internal static UriString GetUriFromRepository(IRepository repo)
90+
{
91+
return repo
92+
?.Network
93+
.Remotes
94+
.FirstOrDefault(x => x.Name.Equals("origin", StringComparison.Ordinal))
95+
?.Url;
96+
}
97+
}
98+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using GitHub.Primitives;
2+
using LibGit2Sharp;
3+
using Microsoft.VisualStudio.TeamFoundation.Git.Extensibility;
4+
5+
namespace GitHub.Services
6+
{
7+
public interface IGitService
8+
{
9+
/// <summary>
10+
/// Returns the URL of the remote named "origin" for the specified <see cref="repository"/>. If the repository
11+
/// is null or no remote named origin exists, this method returns null
12+
/// </summary>
13+
/// <param name="repository">The repository to look at for the remote.</param>
14+
/// <returns>A <see cref="UriString"/> representing the origin or null if none found.</returns>
15+
UriString GetUri(IRepository repository);
16+
17+
/// <summary>
18+
/// Probes for a git repository and if one is found, returns a <see cref="UriString"/> for the repository's
19+
/// remote named "origin" if one is found
20+
/// </summary>
21+
/// <remarks>
22+
/// The lookup checks to see if the specified <paramref name="path"/> is a repository. If it's not, it then
23+
/// walks up the parent directories until it either finds a repository, or reaches the root disk.
24+
/// </remarks>
25+
/// <param name="path">The path to start probing</param>
26+
/// <returns>A <see cref="UriString"/> representing the origin or null if none found.</returns>
27+
UriString GetUri(string path);
28+
29+
/// <summary>
30+
/// Probes for a git repository and if one is found, returns a <see cref="UriString"/> for the repository's
31+
/// remote named "origin" if one is found
32+
/// </summary>
33+
/// <remarks>
34+
/// The lookup checks to see if the path specified by the RepositoryPath property of the specified
35+
/// <see cref="repoInfo"/> is a repository. If it's not, it then walks up the parent directories until it
36+
/// either finds a repository, or reaches the root disk.
37+
/// </remarks>
38+
/// <param name="repoInfo">The repository information containing the path to start probing</param>
39+
/// <returns>A <see cref="UriString"/> representing the origin or null if none found.</returns>
40+
UriString GetUri(IGitRepositoryInfo repoInfo);
41+
42+
/// <summary>
43+
/// Probes for a git repository and if one is found, returns a <see cref="IRepository"/> instance for the
44+
/// repository.
45+
/// </summary>
46+
/// <remarks>
47+
/// The lookup checks to see if the path specified by the RepositoryPath property of the specified
48+
/// <see cref="repoInfo"/> is a repository. If it's not, it then walks up the parent directories until it
49+
/// either finds a repository, or reaches the root disk.
50+
/// </remarks>
51+
/// <param name="repoInfo">The repository information containing the path to start probing</param>
52+
/// <returns>An instance of <see cref="IRepository"/> or null</returns>
53+
54+
IRepository GetRepo(IGitRepositoryInfo repoInfo);
55+
56+
/// <summary>
57+
/// Probes for a git repository and if one is found, returns a <see cref="IRepository"/> instance for the
58+
/// repository.
59+
/// </summary>
60+
/// <remarks>
61+
/// The lookup checks to see if the specified <paramref name="path"/> is a repository. If it's not, it then
62+
/// walks up the parent directories until it either finds a repository, or reaches the root disk.
63+
/// </remarks>
64+
/// <param name="path">The path to start probing</param>
65+
/// <returns>An instance of <see cref="IRepository"/> or null</returns>
66+
IRepository GetRepo(string path);
67+
}
68+
}

0 commit comments

Comments
 (0)