-
Notifications
You must be signed in to change notification settings - Fork 2
/
MxLint.cs
135 lines (120 loc) · 4.17 KB
/
MxLint.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System.Diagnostics;
using Mendix.StudioPro.ExtensionsAPI.Model;
using System.Net.Http;
using Mendix.StudioPro.ExtensionsAPI.Services;
using System.IO.Compression;
namespace com.cinaq.MxLintExtension;
public class MxLint
{
IModel Model;
string ExecutablePath;
string LintResultsPath;
string CachePath;
string RulesPath;
string CLIBaseURL;
string RulesBaseURL;
private readonly ILogService _logService;
private const string CLIVersion = "v3.1.0";
private const string RulesVersion = "v3.1.0";
public MxLint(IModel model, ILogService logService)
{
Model = model;
_logService = logService;
CachePath = Path.Combine(Model.Root.DirectoryPath, ".mendix-cache");
ExecutablePath = Path.Combine(CachePath, "mxlint-local.exe");
LintResultsPath = Path.Combine(CachePath, "lint-results.json");
RulesPath = Path.Combine(CachePath, "rules");
CLIBaseURL = "https://github.com/mxlint/mxlint-cli/releases/download/" + CLIVersion + "/";
RulesBaseURL = "https://github.com/mxlint/mxlint-rules/releases/download/" + RulesVersion + "/";
}
public async Task Lint()
{
try
{
await EnsureCLI();
await EnsurePolicies();
await ExportModel();
await LintModel();
}
catch (Exception ex)
{
_logService.Error($"Error during linting process: {ex.Message}");
}
}
public async Task ExportModel()
{
await RunProcess("export-model", "Exporting model");
}
public async Task LintModel()
{
await RunProcess($"lint -j {LintResultsPath} -r {RulesPath}", "Linting model");
}
private async Task RunProcess(string arguments, string operationName)
{
var startInfo = new ProcessStartInfo
{
FileName = ExecutablePath,
Arguments = arguments,
WorkingDirectory = Model.Root.DirectoryPath,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
using var process = new Process { StartInfo = startInfo };
process.OutputDataReceived += (sender, e) => { if (e.Data != null) _logService.Info(e.Data); };
process.ErrorDataReceived += (sender, e) => { if (e.Data != null) _logService.Error(e.Data); };
try
{
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
await process.WaitForExitAsync();
_logService.Info($"Finished {operationName}");
}
catch (Exception ex)
{
_logService.Error($"Error during {operationName}: {ex.Message}");
}
}
private async Task EnsureCLI()
{
if (File.Exists(ExecutablePath))
{
_logService.Info("CLI already exists");
return;
}
using (var client = new HttpClient())
{
string DownloadURL = CLIBaseURL + "mxlint-" + CLIVersion + "-windows-amd64.exe";
_logService.Info("Downloading CLI from " + DownloadURL);
var response = await client.GetAsync(DownloadURL);
using (var fs = new FileStream(ExecutablePath, FileMode.CreateNew))
{
await response.Content.CopyToAsync(fs);
}
}
}
private async Task EnsurePolicies()
{
if (Directory.Exists(RulesPath))
{
_logService.Info("Rules already exists");
return;
}
using (var client = new HttpClient())
{
string DownloadURL = RulesBaseURL + "rules-" + RulesVersion + ".zip";
string tempZip = Path.Combine(CachePath, "rules.zip");
_logService.Info("Downloading rules from " + DownloadURL);
var response = await client.GetAsync(DownloadURL);
using (var fs = new FileStream(tempZip, FileMode.CreateNew))
{
await response.Content.CopyToAsync(fs);
}
// unzip
ZipFile.ExtractToDirectory(tempZip, CachePath);
File.Delete(tempZip);
}
}
}