Skip to content

Commit 52b49d6

Browse files
committed
Raw prototype version
1 parent 54157b7 commit 52b49d6

File tree

12 files changed

+297
-16
lines changed

12 files changed

+297
-16
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ Library/bin
55
Library/obj
66
Tests/bin
77
Tests/obj
8+
Temp
9+
GitChat/.cache

GitChat/Program.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,37 @@
11
using System;
2+
using GitChat.Library;
23

34
namespace GitChat {
45
class Program {
56
static void Main(string[] args) {
6-
Console.WriteLine("Hello World!");
7+
var storagePath = ".cache";
8+
Console.WriteLine("Your repository URL:");
9+
var originUrl = Console.ReadLine();
10+
var service = new ChatService(originUrl);
11+
while ( true ) {
12+
Console.Clear();
13+
Console.WriteLine(originUrl);
14+
var messages = service.ReadMessages();
15+
foreach ( var msg in messages ) {
16+
WriteWithColor(msg.Author, msg.IsCurrentUser ? ConsoleColor.Green : ConsoleColor.Yellow);
17+
Console.Write(": ");
18+
Console.Write(msg.Content);
19+
Console.WriteLine();
20+
}
21+
Console.WriteLine("Your reply (empty for exit):");
22+
var message = Console.ReadLine();
23+
if ( string.IsNullOrEmpty(message) ) {
24+
return;
25+
}
26+
service.SendMessage(message);
27+
}
28+
}
29+
30+
static void WriteWithColor(string message, ConsoleColor color) {
31+
var oldColor = Console.ForegroundColor;
32+
Console.ForegroundColor = color;
33+
Console.Write(message);
34+
Console.ForegroundColor = oldColor;
735
}
836
}
937
}

Library/CacheStorage.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.IO;
2+
3+
namespace GitChat.Library {
4+
public sealed class CacheStorage {
5+
public readonly string RootPath;
6+
7+
public CacheStorage(string rootPath) {
8+
RootPath = rootPath;
9+
EnsureRootAccess();
10+
}
11+
12+
void EnsureRootAccess() {
13+
if ( Directory.Exists(RootPath) ) {
14+
return;
15+
}
16+
Directory.CreateDirectory(RootPath);
17+
}
18+
19+
public void Clear() {
20+
if ( Directory.Exists(RootPath) ) {
21+
Directory.Delete(RootPath, true);
22+
}
23+
}
24+
}
25+
}

Library/ChatService.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System.Linq;
2+
3+
namespace GitChat.Library {
4+
public sealed class ChatService {
5+
readonly CacheStorage _storage;
6+
readonly GitRunner _git;
7+
readonly string _userName;
8+
9+
public ChatService(string originUrl) {
10+
_storage = new CacheStorage(".cache");
11+
_git = new GitRunner(_storage, originUrl);
12+
_userName = _git.GetUserName().Trim();
13+
}
14+
15+
public void SendMessage(string message) {
16+
_git.SendMessage(message);
17+
}
18+
19+
public Message[] ReadMessages() {
20+
var rawMessages = _git.ReadMessages();
21+
return rawMessages
22+
.Select(ConvertStringToMessage)
23+
.Where(m => (m != null))
24+
.Reverse()
25+
.ToArray();
26+
}
27+
28+
Message ConvertStringToMessage(string str) {
29+
var parts = str.Split(':');
30+
if ( parts.Length < 2 ) {
31+
return null;
32+
}
33+
var author = parts[0];
34+
var message = parts[1].Substring(1);
35+
var isCurrentUser = (author == _userName);
36+
return new Message(author, message, isCurrentUser);
37+
}
38+
}
39+
}

Library/Class1.cs

Lines changed: 0 additions & 5 deletions
This file was deleted.

Library/GitRunner.cs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using System.Diagnostics;
2+
using System.IO;
3+
4+
namespace GitChat.Library {
5+
public sealed class GitRunner {
6+
public readonly string WorkingDirectory;
7+
8+
readonly CacheStorage _storage;
9+
readonly string _originUrl;
10+
11+
public GitRunner(CacheStorage storage, string originUrl) {
12+
_storage = storage;
13+
_originUrl = originUrl;
14+
15+
var lastSlashIndex = _originUrl.LastIndexOf('/');
16+
var repoName = _originUrl.Substring(lastSlashIndex + 1);
17+
WorkingDirectory = Path.Combine(_storage.RootPath, repoName);
18+
19+
TryClone();
20+
}
21+
22+
void TryClone() {
23+
if ( Directory.Exists(WorkingDirectory) ) {
24+
return;
25+
}
26+
var startInfo = new ProcessStartInfo {
27+
FileName = "git",
28+
Arguments = "clone " + _originUrl,
29+
WorkingDirectory = _storage.RootPath
30+
};
31+
Process.Start(startInfo).WaitForExit();
32+
}
33+
34+
public void SendMessage(string message) {
35+
Commit(message);
36+
Push();
37+
}
38+
39+
public string[] ReadMessages() {
40+
Pull();
41+
return Log();
42+
}
43+
44+
public string GetUserName() {
45+
var startInfo = new ProcessStartInfo {
46+
FileName = "git",
47+
Arguments = $"config user.name",
48+
WorkingDirectory = WorkingDirectory,
49+
RedirectStandardOutput = true
50+
};
51+
var proc = Process.Start(startInfo);
52+
proc.WaitForExit();
53+
var output = proc.StandardOutput.ReadToEnd();
54+
return output;
55+
}
56+
57+
void Commit(string message) {
58+
var startInfo = new ProcessStartInfo {
59+
FileName = "git",
60+
Arguments = $"commit -m \"{message}\" --allow-empty",
61+
WorkingDirectory = WorkingDirectory
62+
};
63+
Process.Start(startInfo).WaitForExit();
64+
}
65+
66+
void Push() {
67+
var startInfo = new ProcessStartInfo {
68+
FileName = "git",
69+
Arguments = $"push",
70+
WorkingDirectory = WorkingDirectory
71+
};
72+
Process.Start(startInfo).WaitForExit();
73+
}
74+
75+
void Pull() {
76+
var startInfo = new ProcessStartInfo {
77+
FileName = "git",
78+
Arguments = $"pull",
79+
WorkingDirectory = WorkingDirectory
80+
};
81+
Process.Start(startInfo).WaitForExit();
82+
}
83+
84+
string[] Log() {
85+
var startInfo = new ProcessStartInfo {
86+
FileName = "git",
87+
Arguments = $"log --format=\"%an: %s\"",
88+
WorkingDirectory = WorkingDirectory,
89+
RedirectStandardOutput = true
90+
};
91+
var proc = Process.Start(startInfo);
92+
proc.WaitForExit();
93+
var output = proc.StandardOutput.ReadToEnd();
94+
return output.Split('\n');
95+
}
96+
}
97+
}

Library/Library.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

33
<PropertyGroup>
44
<TargetFramework>netcoreapp2.2</TargetFramework>

Library/Message.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace GitChat.Library {
2+
public sealed class Message {
3+
public readonly string Author;
4+
public readonly string Content;
5+
public readonly bool IsCurrentUser;
6+
7+
public Message(string author, string content, bool isCurrentUser) {
8+
Author = author;
9+
Content = content;
10+
IsCurrentUser = isCurrentUser;
11+
}
12+
}
13+
}

Tests/CacheStorageTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.IO;
3+
using GitChat.Library;
4+
using Xunit;
5+
6+
namespace GitChat.Tests {
7+
public sealed class CacheStorageTests : IDisposable {
8+
readonly string _tempDir;
9+
10+
public CacheStorageTests() {
11+
_tempDir = "." + GetHashCode().ToString();
12+
}
13+
14+
public void Dispose() {
15+
if ( Directory.Exists(_tempDir) ) {
16+
Directory.Delete(_tempDir);
17+
}
18+
}
19+
20+
[Fact]
21+
public void IsRootDirCreatedOnInit() {
22+
var unused = new CacheStorage(_tempDir);
23+
24+
Assert.True(Directory.Exists(_tempDir));
25+
}
26+
27+
[Fact]
28+
public void IsRootDirRemovedOnClear() {
29+
var storage = new CacheStorage(_tempDir);
30+
storage.Clear();
31+
32+
Assert.False(Directory.Exists(_tempDir));
33+
}
34+
}
35+
}

Tests/Env.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace GitChat.Tests {
2+
static class Env {
3+
public const string RepoUrl = "https://github.com/KonH/GitChatTestRepo";
4+
5+
public static string GetTempDir(object context) {
6+
return "." + context.GetHashCode().ToString();
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)