-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from mbican/development
release 0.1.0
- Loading branch information
Showing
19 changed files
with
550 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp3.0</TargetFramework> | ||
<LangVersion>8.0</LangVersion> | ||
<NullableContextOptions>enable</NullableContextOptions> | ||
<Version>0.1.0</Version> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Autofac" Version="4.8.1" /> | ||
<PackageReference Include="commandlineparser" Version="2.4.3" /> | ||
<PackageReference Include="EfautValueObject" Version="0.5.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\CronHosts.Domain\CronHosts.Domain.csproj" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
using CommandLine; | ||
using CronHosts.Domain; | ||
using Efaut; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
|
||
namespace CronHosts.ConsoleApp | ||
{ | ||
public class CronHostsProgram: IProgram | ||
{ | ||
#region Dependencies | ||
|
||
#nullable disable | ||
|
||
public Lazy<Parser> ParserLazy { get; set; } | ||
protected Parser Parser => ParserLazy?.Value; | ||
|
||
public Lazy<Random> RandomLazy { get; set; } | ||
protected Random Random => RandomLazy?.Value; | ||
|
||
public Lazy<IDomain> DomainLazy { get; set; } | ||
protected IDomain Domain => DomainLazy?.Value; | ||
|
||
public Lazy<IDateTimeService> DateTimeServiceLazy { get; set; } | ||
protected IDateTimeService DateTimeService => DateTimeServiceLazy?.Value; | ||
|
||
#nullable restore | ||
|
||
#endregion Dependencies | ||
|
||
public sealed class Arguments: ValueObject | ||
{ | ||
[Value(0)] | ||
public string? File { get; } | ||
|
||
public Arguments(string? file) | ||
{ | ||
File = file; | ||
} | ||
} | ||
|
||
public enum ExitCode: int | ||
{ | ||
Success = 0, | ||
ArgumentError = 1, | ||
UnknownError = 1000, | ||
} | ||
|
||
public async Task<int> Run(string[] args) | ||
{ | ||
var parserResult = Parser.ParseArguments<Arguments>(args); | ||
if (parserResult is Parsed<Arguments> parsed) | ||
{ | ||
var arguments = parsed.Value; | ||
await DoRun(arguments); | ||
return (int)ExitCode.Success; | ||
} | ||
else if (parserResult is NotParsed<Arguments> notParsed) | ||
{ | ||
var errors = notParsed.Errors; | ||
return (int)ExitCode.ArgumentError; | ||
} | ||
else | ||
{ | ||
return (int)ExitCode.UnknownError; | ||
} | ||
} | ||
|
||
protected async Task DoRun(Arguments arguments) | ||
{ | ||
// if file name has been provided | ||
if (arguments.File == null) | ||
{ // use standard input | ||
using (var input = Console.OpenStandardInput()) | ||
using (var reader = new StreamReader(input)) | ||
using (var output = Console.OpenStandardOutput()) | ||
using (var writer = new StreamWriter(output)) | ||
await Domain.Execute(reader, writer, DateTimeService.GetUtcNow()); | ||
} | ||
else | ||
{ // use file | ||
var existingFile = arguments.File; | ||
// create name for a temp file | ||
var random = Random.Next(); | ||
var tempFile = $"{existingFile}_{random:x8}.tmp"; | ||
// create name for a backup file | ||
var bakFile = $"{existingFile}_{random:x8}.bak"; | ||
try | ||
{ | ||
// copy existingFile to tempFile so it has original metadata | ||
File.Copy(existingFile, tempFile); | ||
// open existing file for reading | ||
using (var reader = new StreamReader(existingFile, true)) | ||
// open temp file for writing | ||
using (var writer = new StreamWriter(tempFile)) | ||
// execute cronhosts processes existing file into temp file | ||
await Domain.Execute(reader, writer, DateTimeService.GetUtcNow()); | ||
// swap completed temp file for existing file while renaming existing file to bakFile in case of something goes wrong | ||
File.Replace(tempFile, existingFile, bakFile); | ||
// after successful swap delete the original file renamed to bakFile | ||
File.Delete(bakFile); | ||
} | ||
catch | ||
{ // in case of an error | ||
// try restore original file from back up | ||
try { File.Move(bakFile, existingFile); } catch { } | ||
try | ||
{ | ||
// if original file exists | ||
if (File.Exists(existingFile)) | ||
// delete temp file | ||
File.Delete(tempFile); | ||
else | ||
// otherwise rename tempFile to original file | ||
File.Move(tempFile, existingFile); | ||
} | ||
catch { } | ||
throw; | ||
} | ||
} | ||
} | ||
|
||
public static IReadOnlyDictionary<ExitCode, string> ErrorMessages = new Dictionary<ExitCode, string> | ||
{ | ||
[ExitCode.Success] = "Success", | ||
[ExitCode.ArgumentError] = "ArgumentError", | ||
[ExitCode.UnknownError] = "UnknownError", | ||
}; | ||
|
||
public class CronHostsFatalException: ApplicationException | ||
{ | ||
public ExitCode ExitCode { get; protected set; } | ||
|
||
public CronHostsFatalException(ExitCode exitCode) : base(ErrorMessages[exitCode]) | ||
{ | ||
ExitCode = exitCode; | ||
} | ||
|
||
public CronHostsFatalException(ExitCode exitCode, string message) : base(message) | ||
{ | ||
ExitCode = exitCode; | ||
} | ||
|
||
public CronHostsFatalException(ExitCode exitCode, Exception innerExcpetion) : base(ErrorMessages[exitCode], innerExcpetion) | ||
{ | ||
ExitCode = exitCode; | ||
} | ||
|
||
public CronHostsFatalException(ExitCode exitCode, string message, Exception innerExcpetion) : base(message, innerExcpetion) | ||
{ | ||
ExitCode = exitCode; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace CronHosts.ConsoleApp | ||
{ | ||
public class DateTimeService: IDateTimeService | ||
{ | ||
public DateTime GetUtcNow() | ||
{ | ||
return DateTime.UtcNow; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace CronHosts.ConsoleApp | ||
{ | ||
public interface IDateTimeService | ||
{ | ||
DateTime GetUtcNow(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace CronHosts.ConsoleApp | ||
{ | ||
public interface IProgram | ||
{ | ||
Task<int> Run(string[] args); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using Autofac; | ||
using System.Threading.Tasks; | ||
|
||
namespace CronHosts.ConsoleApp | ||
{ | ||
public static class Program | ||
{ | ||
private static IContainer Container { get; set; } | ||
|
||
public static async Task<int> Main(string[] args) | ||
{ | ||
using (Container = Startup.Build()) | ||
using (var scope = Container.BeginLifetimeScope("program")) | ||
return await scope.Resolve<IProgram>().Run(args); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Autofac; | ||
using CommandLine; | ||
using CronHosts.Domain; | ||
|
||
namespace CronHosts.ConsoleApp | ||
{ | ||
public static partial class Startup | ||
{ | ||
public static void ConfigureAutofac(ContainerBuilder builder) | ||
{ | ||
Domain.Startup.ConfigureAutofac(builder); | ||
|
||
builder.RegisterType<CronHostsProgram>().As<IProgram>().PropertiesAutowired().InstancePerLifetimeScope(); | ||
|
||
builder.RegisterType<DateTimeService>().As<IDateTimeService>().PropertiesAutowired().InstancePerLifetimeScope(); | ||
|
||
builder.RegisterType<Random>().AsSelf().InstancePerLifetimeScope(); | ||
builder.Register(a => new Parser(ConfigureParser)).AsSelf().InstancePerLifetimeScope(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using CommandLine; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace CronHosts.ConsoleApp | ||
{ | ||
public static partial class Startup | ||
{ | ||
public static void ConfigureParser(ParserSettings settings) | ||
{ | ||
settings.HelpWriter = Console.Error; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Library</OutputType> | ||
<TargetFramework>netcoreapp3.0</TargetFramework> | ||
<LangVersion>8.0</LangVersion> | ||
<NullableContextOptions>enable</NullableContextOptions> | ||
<ApplicationIcon /> | ||
<StartupObject /> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Autofac" Version="4.8.1" /> | ||
<PackageReference Include="Shuttle.Core.Cron" Version="10.0.6" /> | ||
</ItemGroup> | ||
</Project> |
Oops, something went wrong.