Skip to content

Commit 7473207

Browse files
committed
(WIP) Add output of draft release and split out VCS Provider
1 parent 8987ebd commit 7473207

20 files changed

+646
-155
lines changed

src/GitReleaseManager.Cli/GitReleaseManager.Cli.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<LangVersion>8.0</LangVersion>
44
<OutputType>Exe</OutputType>

src/GitReleaseManager.Cli/Program.cs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ private static void RegisterServices(BaseSubOptions options)
110110
RegisterVcsProvider(vcsOptions, serviceCollection);
111111
}
112112

113+
if (options is CreateSubOptions createOptions && !string.IsNullOrEmpty(createOptions.OutputPath))
114+
{
115+
configuration.Create.AllowUpdateToPublishedRelease = false;
116+
}
117+
113118
serviceCollection = serviceCollection
114119
.AddTransient((services) => new TemplateFactory(services.GetRequiredService<IFileSystem>(), services.GetRequiredService<Config>(), TemplateKind.Create));
115120

@@ -197,21 +202,53 @@ private static Task<int> ExecuteCommand<TOptions>(TOptions options)
197202
private static void LogOptions(BaseSubOptions options)
198203
=> Log.Debug("{@Options}", options);
199204

205+
private static void RegisterKeyedVcsProvider<TVcsImplementation>(object provider, IServiceCollection serviceCollection)
206+
where TVcsImplementation : class, IVcsProvider
207+
{
208+
static IVcsProvider ResolveService(IServiceProvider service, object key) => service.GetRequiredKeyedService<IVcsProvider>(key);
209+
210+
provider ??= "null";
211+
212+
Log.Debug("Registering {Type} with Service Key {Key}", typeof(IVcsProvider), provider);
213+
214+
if (typeof(TVcsImplementation) != typeof(NullReleasesProvider))
215+
{
216+
serviceCollection.AddKeyedSingleton<IVcsProvider, TVcsImplementation>(provider);
217+
}
218+
219+
serviceCollection
220+
.AddKeyedTransient<IAssetsProvider>(provider, ResolveService)
221+
.AddKeyedTransient<ICommitsProvider>(provider, ResolveService)
222+
.AddKeyedTransient<IIssuesProvider>(provider, ResolveService)
223+
.AddKeyedTransient<IMilestonesProvider>(provider, ResolveService)
224+
.AddKeyedTransient<IReleasesProvider>(provider, ResolveService);
225+
}
226+
200227
private static void RegisterVcsProvider(BaseVcsOptions vcsOptions, IServiceCollection serviceCollection)
201228
{
202229
Log.Information("Using {Provider} as VCS Provider", vcsOptions.Provider);
203-
if (vcsOptions.Provider == VcsProvider.GitLab)
230+
231+
serviceCollection.AddKeyedSingleton<IVcsProvider>("null", (service, _) => new NullReleasesProvider(vcsOptions.Provider.ToString(), service.GetRequiredService<ILogger>()));
232+
RegisterKeyedVcsProvider<NullReleasesProvider>(null, serviceCollection);
233+
RegisterKeyedVcsProvider<GitHubProvider>(VcsProvider.GitHub, serviceCollection);
234+
235+
serviceCollection
236+
.AddSingleton<IGitLabClient>((_) => new GitLabClient("https://gitlab.com", vcsOptions.Token));
237+
238+
serviceCollection
239+
.AddSingleton<IGitHubClient>((_) => new GitHubClient(new ProductHeaderValue("GitReleaseManager")) { Credentials = new Credentials(vcsOptions.Token) });
240+
241+
serviceCollection.AddTransient((service) => service.GetKeyedService<IVcsProvider>(vcsOptions.Provider) ?? service.GetRequiredKeyedService<IVcsProvider>("null"));
242+
243+
if (vcsOptions is CreateSubOptions createOptions && !string.IsNullOrEmpty(createOptions.OutputPath))
204244
{
205-
serviceCollection
206-
.AddSingleton<IGitLabClient>((_) => new GitLabClient("https://gitlab.com", vcsOptions.Token))
207-
.AddSingleton<IVcsProvider, GitLabProvider>();
245+
serviceCollection.AddSingleton<IReleasesProvider>((service) => new LocalProvider(
246+
service.GetRequiredService<IFileSystem>(),
247+
createOptions.OutputPath));
208248
}
209249
else
210250
{
211-
// default to Github
212-
serviceCollection
213-
.AddSingleton<IGitHubClient>((_) => new GitHubClient(new ProductHeaderValue("GitReleaseManager")) { Credentials = new Credentials(vcsOptions.Token) })
214-
.AddSingleton<IVcsProvider, GitHubProvider>();
251+
serviceCollection.AddTransient((service) => service.GetKeyedService<IReleasesProvider>(vcsOptions.Provider) ?? service.GetRequiredKeyedService<IReleasesProvider>("null"));
215252
}
216253
}
217254
}

src/GitReleaseManager.Core.Tests/VcsServiceTests.cs

Lines changed: 65 additions & 63 deletions
Large diffs are not rendered by default.

src/GitReleaseManager.Core/GitReleaseManager.Core.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\TextTemplating\Microsoft.TextTemplating.targets" Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\TextTemplating\Microsoft.TextTemplating.targets')" />
55
<PropertyGroup>
66
<LangVersion>8.0</LangVersion>
7+
<!-- Uncomment the below property when langversion is updated to 9.0 or higher (optimally 11.0). -->
8+
<!--<DefineConstants>$(DefineConstants);USE_GENERATED_REGEX</DefineConstants>-->
79
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
810
<Title>GitReleaseManager.Core</Title>
911
<Description>Create release notes in markdown given a milestone</Description>

src/GitReleaseManager.Core/Helpers/FileSystem.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,21 @@ public void Copy(string @source, string destination, bool overwrite)
1919
File.Copy(@source, destination, overwrite);
2020
}
2121

22+
public void CreateDirectory(string path)
23+
{
24+
// It is safe to call CreateDirectory, if the directory
25+
// already exists these are no-op.
26+
27+
if (string.IsNullOrEmpty(path))
28+
{
29+
Directory.CreateDirectory(Environment.CurrentDirectory);
30+
}
31+
else
32+
{
33+
Directory.CreateDirectory(path);
34+
}
35+
}
36+
2237
public void Move(string @source, string destination)
2338
{
2439
File.Move(@source, destination);
@@ -59,9 +74,19 @@ public IEnumerable<string> DirectoryGetFiles(string directory, string searchPatt
5974
return Directory.GetFiles(directory, searchPattern, searchOption);
6075
}
6176

77+
public Stream OpenRead(string path)
78+
{
79+
return File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
80+
}
81+
6282
public Stream OpenWrite(string path)
6383
{
64-
return File.OpenWrite(path);
84+
return OpenWrite(path, overwrite: false);
85+
}
86+
87+
public Stream OpenWrite(string path, bool overwrite)
88+
{
89+
return File.Open(path, overwrite ? FileMode.Create : FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
6590
}
6691
}
6792
}

src/GitReleaseManager.Core/Helpers/IFileSystem.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ public interface IFileSystem
77
{
88
void Copy(string source, string destination, bool overwrite);
99

10+
void CreateDirectory(string path);
11+
1012
void Move(string source, string destination);
1113

1214
bool Exists(string file);
@@ -21,6 +23,9 @@ public interface IFileSystem
2123

2224
IEnumerable<string> DirectoryGetFiles(string directory, string searchPattern, SearchOption searchOption);
2325

26+
Stream OpenRead(string path);
27+
2428
Stream OpenWrite(string path);
29+
Stream OpenWrite(string path, bool overwrite);
2530
}
2631
}

src/GitReleaseManager.Core/Options/CreateSubOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@ public class CreateSubOptions : BaseVcsOptions
2929

3030
[Option("allowEmpty", Required = false, HelpText = "Allow the creation of an empty set of release notes. In this mode, milestone and input file path will be ignored.")]
3131
public bool AllowEmpty { get; set; }
32+
33+
[Option("output", Required = false, HelpText = "The path to a local file location where the release notes will be created, instead of creating in remotely on the specified provider.")]
34+
public string OutputPath { get; set; }
3235
}
3336
}

src/GitReleaseManager.Core/Provider/GitHubProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public GitHubProvider(IGitHubClient gitHubClient, IMapper mapper)
3535
_mapper = mapper;
3636
}
3737

38+
public string Name => "GitHub";
39+
3840
public Task DeleteAssetAsync(string owner, string repository, ReleaseAsset asset)
3941
{
4042
return ExecuteAsync(async () =>

src/GitReleaseManager.Core/Provider/GitLabProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public GitLabProvider(IGitLabClient gitLabClient, IMapper mapper, ILogger logger
4343
_logger = logger;
4444
}
4545

46+
public string Name => "GitLab";
47+
4648
public Task DeleteAssetAsync(string owner, string repository, ReleaseAsset asset)
4749
{
4850
// TODO: This is a discussion here:
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace GitReleaseManager.Core.Provider
2+
{
3+
using System.Threading.Tasks;
4+
using GitReleaseManager.Core.Model;
5+
6+
public interface IAssetsProvider
7+
{
8+
bool SupportsAssets { get; }
9+
10+
Task DeleteAssetAsync(string owner, string repository, ReleaseAsset asset);
11+
12+
Task UploadAssetAsync(Release release, ReleaseAssetUpload releaseAssetUpload);
13+
}
14+
}

0 commit comments

Comments
 (0)