Skip to content

Commit

Permalink
Refactoring the File Watcher and working on the JSON schema generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Baudin999 committed Dec 22, 2019
1 parent 17978c1 commit 6c2ae5c
Show file tree
Hide file tree
Showing 35 changed files with 843 additions and 272 deletions.
45 changes: 45 additions & 0 deletions APIStrategy.archimate
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<archimate:model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:archimate="http://www.archimatetool.com/archimate" name="API strategy" id="38eabdc1-6ecd-4ba4-9b00-c1173a6bdd62" version="4.4.0">
<folder name="Strategy" id="17dae3a5-4154-4319-8ce2-0ac956494390" type="strategy"/>
<folder name="Business" id="cb946f1d-cd8a-4219-ba9b-e9e99a66826e" type="business">
<element xsi:type="archimate:BusinessProcess" name="Becoming A Customer" id="a6b974d6-fb7c-4c5a-8b10-81c7b39fad4e"/>
<element xsi:type="archimate:BusinessFunction" name="Address Check" id="97404917-d4d4-45e6-9903-20b3f68874b6"/>
</folder>
<folder name="Application" id="0f4f34f7-6335-49ad-906b-27a214b41ce5" type="application">
<element xsi:type="archimate:ApplicationComponent" name="API GW" id="3a901134-f659-4f8e-a9d8-693b6aa982ff"/>
<element xsi:type="archimate:ApplicationInterface" name="Check Address" id="611b4c06-bb25-42df-bacb-275397df6bb3"/>
</folder>
<folder name="Technology &amp; Physical" id="b1feab1d-49d9-46a3-8148-ec80da4f84d3" type="technology"/>
<folder name="Motivation" id="dea929da-2fa7-47dc-b841-0a5c4a2249ad" type="motivation"/>
<folder name="Implementation &amp; Migration" id="f9e3269b-981c-4ad3-8498-d4d075bf6317" type="implementation_migration"/>
<folder name="Other" id="8ab3a69d-8a47-4526-b80a-709ef0be63c2" type="other"/>
<folder name="Relations" id="548b4beb-3584-46f4-8387-fe556540cf09" type="relations">
<element xsi:type="archimate:CompositionRelationship" id="de10f773-c76e-4608-800e-42ae2d340ce2" source="a6b974d6-fb7c-4c5a-8b10-81c7b39fad4e" target="97404917-d4d4-45e6-9903-20b3f68874b6"/>
<element xsi:type="archimate:CompositionRelationship" id="ee6aa360-4e84-4bea-82c5-40bd74738014" source="3a901134-f659-4f8e-a9d8-693b6aa982ff" target="611b4c06-bb25-42df-bacb-275397df6bb3"/>
<element xsi:type="archimate:ServingRelationship" id="a37b9142-5698-422e-afaf-6a7c9f9d5543" source="611b4c06-bb25-42df-bacb-275397df6bb3" target="97404917-d4d4-45e6-9903-20b3f68874b6"/>
</folder>
<folder name="Views" id="125d407d-d7e7-47d9-b543-807983ae59b8" type="diagrams">
<element xsi:type="archimate:ArchimateDiagramModel" name="Default View" id="f47bba11-12f6-4c66-8d67-d929f80ab2f5">
<child xsi:type="archimate:DiagramObject" id="6dc6bb97-efe9-470d-952f-d37bee471a68" archimateElement="a6b974d6-fb7c-4c5a-8b10-81c7b39fad4e">
<bounds x="372" y="132" width="445" height="121"/>
<sourceConnection xsi:type="archimate:Connection" id="414f5fa8-a11f-4559-befd-6cdd50dd4a84" source="6dc6bb97-efe9-470d-952f-d37bee471a68" target="81796d8c-fc3f-4720-a603-fd10e1b64aba" archimateRelationship="de10f773-c76e-4608-800e-42ae2d340ce2"/>
<child xsi:type="archimate:DiagramObject" id="81796d8c-fc3f-4720-a603-fd10e1b64aba" targetConnections="414f5fa8-a11f-4559-befd-6cdd50dd4a84 d20bb575-44c1-488e-8abc-843fd77dbbf2" archimateElement="97404917-d4d4-45e6-9903-20b3f68874b6">
<bounds x="72" y="36" width="120" height="55"/>
</child>
</child>
<child xsi:type="archimate:DiagramObject" id="cabf64fc-2154-486b-aab6-afcef0f34ad8" archimateElement="3a901134-f659-4f8e-a9d8-693b6aa982ff">
<bounds x="372" y="468" width="445" height="97"/>
<sourceConnection xsi:type="archimate:Connection" id="b1f0ba96-6ffe-408a-a1e8-cbb8fb46bd9f" source="cabf64fc-2154-486b-aab6-afcef0f34ad8" target="b5dce208-9790-459a-a99f-a71d21e143be" archimateRelationship="ee6aa360-4e84-4bea-82c5-40bd74738014"/>
<child xsi:type="archimate:DiagramObject" id="b5dce208-9790-459a-a99f-a71d21e143be" targetConnections="b1f0ba96-6ffe-408a-a1e8-cbb8fb46bd9f 57bcf25c-17cd-4dc8-9264-bac521d22468" archimateElement="611b4c06-bb25-42df-bacb-275397df6bb3">
<bounds x="60" y="24" width="120" height="55"/>
<sourceConnection xsi:type="archimate:Connection" id="d20bb575-44c1-488e-8abc-843fd77dbbf2" source="b5dce208-9790-459a-a99f-a71d21e143be" target="81796d8c-fc3f-4720-a603-fd10e1b64aba" archimateRelationship="a37b9142-5698-422e-afaf-6a7c9f9d5543"/>
</child>
</child>
<child xsi:type="archimate:Note" id="555f14b6-ec21-4187-ba7f-99470726ed4c" textAlignment="1">
<bounds x="192" y="372" width="185" height="80"/>
<sourceConnection id="57bcf25c-17cd-4dc8-9264-bac521d22468" source="555f14b6-ec21-4187-ba7f-99470726ed4c" target="b5dce208-9790-459a-a99f-a71d21e143be"/>
<content>Dit is de API/EndPoint waar wij een beschrijving va nodig hebben.</content>
</child>
</element>
</folder>
</archimate:model>
12 changes: 11 additions & 1 deletion ApplicationTests/CreateModuleInProject.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.IO;
using CLI;
using Xunit;
Expand All @@ -11,6 +12,15 @@ public class CreateModuleInProject: IDisposable
readonly Project project;
public CreateModuleInProject()
{
try
{
Directory.Delete(dir, true);
}
catch (Exception)
{
Debug.WriteLine("Delete Directory failed in unit test.");
}
Directory.CreateDirectory(dir);
project = new Project(dir);
}

Expand All @@ -33,7 +43,7 @@ public void CreateModule()
public void Dispose()
{
project.Dispose();
Directory.Delete(dir, true);
//Directory.Delete(dir, true);
}

private string path(string add)
Expand Down
42 changes: 42 additions & 0 deletions ApplicationTests/ModuleStream_tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Threading.Tasks;
using CLI;
using Xunit;

namespace ApplicationTests
{

public class ModuleStream_tests : IDisposable
{
ModuleStream moduleStream;

public ModuleStream_tests()
{
moduleStream = new ModuleStream();
}

[Fact]
public Task CreateModuleStream()
{
var tcs = new TaskCompletionSource<bool>();
moduleStream.Subscribe("Logger", message =>
{
Assert.NotNull(message);
Assert.Equal("First Message", message.ModuleName);
Assert.Equal("Path", message.FileFullPath);
Assert.Equal(MessageType.ModuleChanged, message.MessageType);

tcs.TrySetResult(true);
});

moduleStream.Publish(new ModuleStreamMessage("First Message", "Path", MessageType.ModuleChanged));

return tcs.Task;
}

public void Dispose()
{
moduleStream.Dispose();
}
}
}
1 change: 1 addition & 0 deletions ApplicationTests/ProjectFileWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public ProjectFileWatcher(ITestOutputHelper output)
} catch (Exception) {
Debug.WriteLine("Delete Directory failed in unit test.");
}
Directory.CreateDirectory(dir);

this.output = output;
project = new Project(dir);
Expand Down
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions CLI/CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<PackageReference Include="System.IO.FileSystem.Watcher" Version="4.3.0" />
<PackageReference Include="Bogus" Version="28.4.4" />
<PackageReference Include="LiteDB" Version="4.1.4" />
<PackageReference Include="System.Reactive" Version="4.3.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="Assets\" />
Expand All @@ -35,6 +36,8 @@
</ItemGroup>
<ItemGroup>
<None Remove="Assets\style.css" />
<None Remove="Assets\mermaid.min.js" />
<None Remove="Assets\mermaid.min.js.map" />
</ItemGroup>
<ItemGroup>
<None Update="wwwroot\*">
Expand All @@ -44,4 +47,8 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Assets\mermaid.min.js" />
<EmbeddedResource Include="Assets\mermaid.min.js.map" />
</ItemGroup>
</Project>
3 changes: 3 additions & 0 deletions CLI/Commands/Commands.Watch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ To quit the application press 'q'

project.Watch();

while (Console.ReadKey().Key != ConsoleKey.Q) { }
Console.WriteLine();

SignalSingleton.ExitSignal.Dispatch();
return 0;
});
Expand Down
2 changes: 1 addition & 1 deletion CLI/Controllers/ModuleController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public IActionResult GetModuleText(string module)
var m = Project.Current?.FindModule(module);
if (m is null) return NotFound();

return Ok(m.Generator.Code);
return Ok(m.Code);
}

[HttpPost("/api/module/{module}")]
Expand Down
58 changes: 45 additions & 13 deletions CLI/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace CLI
public class Module : IDisposable
{
public string Name { get; }
public string Path { get; }
public string FilePath { get; }
public string BasePath { get; }
public string OutPath { get; }
public Project Project { get; }
Expand All @@ -21,9 +21,23 @@ public class Module : IDisposable
public ASTGenerator Generator { get; private set; }
public DateTime LastParsed { get; private set; }

public string Code
{
get
{
if (Generator.Code == String.Empty)
{
return ReadModuleText();
} else
{
return Generator.Code;
}
}
}

public Module(string path, string basePath, Project project)
{
this.Path = path;
this.FilePath = path;
this.BasePath = basePath;
this.Name = CreateModuleName();
this.OutPath = System.IO.Path.GetFullPath($"out/{Name}", basePath);
Expand All @@ -45,7 +59,7 @@ public void Parse()

public void SaveModuleOutput(bool decend = true, bool suppressMessage = false)
{
this.Transpiler.StartTranspilation(this.Name, Project.CarConfig?.ErdConfig ?? new ErdConfig());
this.Transpiler.StartTranspilation(this.Name);
if (!suppressMessage)
{
Console.WriteLine($"Perfectly parsed: {Name}");
Expand All @@ -58,13 +72,14 @@ public void SaveModuleOutput(bool decend = true, bool suppressMessage = false)
SaveResult(key, value);
}

// Trickery to no regenerate infinately...
// Trickery to not parse infinately...
// TODO: replace with propper topological order...
if (decend)
{
// We would now also want to resolve the other modules
// which depend upon this module so that they are automatically
// regenerated and their output changed.
// TODO: notice circular dependencies, remove diamond of death...
this.Project
.Modules
.ToList()
Expand All @@ -76,6 +91,17 @@ public void SaveModuleOutput(bool decend = true, bool suppressMessage = false)
});
}
}
public void Clean()
{
try
{
System.IO.Directory.Delete(OutPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

public IEnumerable<Descriptor> GetDescriptions()
{
Expand All @@ -89,7 +115,7 @@ public bool SaveCode(string source)
try
{

System.IO.File.WriteAllText(this.Path, source);
System.IO.File.WriteAllText(this.FilePath, source);
return true;
}
catch (Exception ex)
Expand All @@ -103,7 +129,7 @@ private string ReadModuleText()
{
try
{
using (var fs = new FileStream(this.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var fs = new FileStream(this.FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
Expand All @@ -128,25 +154,31 @@ private void SaveResult(string fileName, string source)

private string CreateModuleName()
{
var p = Path.Replace(BasePath, "").Replace("/", ".").Replace("\\", ".").Replace(".car", "");
if (p.StartsWith(".", StringComparison.Ordinal))
{
p = p.Substring(1);
}
return p;
return Module.FromPathToName(this.FilePath, this.BasePath);
}

public override string ToString()
{
return $@"
Module: {Name}
Path: {Path}
Path: {FilePath}
Dir: {BasePath}
LastParsed: {LastParsed}
";
}

public void Dispose(){}

public static string FromPathToName(string path, string basePath)
{
var p = path.Replace(basePath, "").Replace("/", ".").Replace("\\", ".").Replace(".car", "");
if (p.StartsWith(".", StringComparison.Ordinal))
{
p = p.Substring(1);
}
return p;
}

}

public static class DictionaryHelpers
Expand Down
81 changes: 81 additions & 0 deletions CLI/ModuleStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Reactive.Subjects;

namespace CLI
{
public class ModuleStream : IDisposable
{

private Subject<ModuleStreamMessage> moduleMessageSubject;
private IDictionary<string, IDisposable> subscribers;

public ModuleStream()
{
moduleMessageSubject = new Subject<ModuleStreamMessage>();
subscribers = new Dictionary<string, IDisposable>();
}

public void Dispose()
{
if (moduleMessageSubject != null)
{
moduleMessageSubject.Dispose();
}

foreach (var subscriber in subscribers)
{
subscriber.Value.Dispose();
}
}


/// <summary>
/// Publish a ModuleStreamMessage, triggering the subscriptions.
/// </summary>
/// <param name="moduleMessage"></param>
public void Publish(ModuleStreamMessage moduleMessage)
{
moduleMessageSubject.OnNext(moduleMessage);
}


/// <summary>
/// Subscribe to all publications of a ModuleStreamMessage
/// </summary>
/// <param name="subscriberName"></param>
/// <param name="action"></param>
public void Subscribe(string subscriberName, Action<ModuleStreamMessage> action)
{
if (!subscribers.ContainsKey(subscriberName))
{
subscribers.Add(subscriberName, moduleMessageSubject.Subscribe(action));
}
}


/// <summary>
/// Only subscribe to messages with a certain message type. This way you
/// can filter out those messages which will be handled by other systems.
/// </summary>
/// <param name="subscriberName">Simple unique name of the subscriber</param>
/// <param name="messageType">The message type you would like to subscribe to</param>
/// <param name="action">The action which you'd want to take one a valid message is published.</param>
public void Subscribe(string subscriberName, MessageType messageType, Action<ModuleStreamMessage> action)
{
if (!subscribers.ContainsKey(subscriberName))
{
subscribers.Add(
subscriberName,
moduleMessageSubject
.Where(msm => msm.MessageType == messageType)
.Subscribe(action)
);
}
}


}

}
Loading

0 comments on commit 6c2ae5c

Please sign in to comment.