Skip to content

Commit 5364a41

Browse files
committed
refactor update
1 parent 198f7f9 commit 5364a41

File tree

2 files changed

+90
-54
lines changed

2 files changed

+90
-54
lines changed

Compiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ static async Task Main(string[] args)
1515

1616
if (config.Update)
1717
{
18-
await GithubUpdater.UpdateFromGithub(config);
18+
await GithubUpdater.UpdateFromGithubAsync(config);
1919
}
2020

2121
if (args.Length > 0)

GithubUpdater.cs

Lines changed: 89 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,67 +9,103 @@ namespace Compiler
99
{
1010
public class GithubUpdater
1111
{
12-
public static async Task UpdateFromGithub(Config config)
12+
private static readonly string ApiURL = "https://api.github.com/repos/johnoclockdk/CssCompiler/releases/latest";
13+
private static readonly HttpClient httpClient = new HttpClient();
14+
15+
static GithubUpdater()
1316
{
14-
string apiURL = $"https://api.github.com/repos/johnoclockdk/CssCompiler/releases/latest";
15-
string tempFilePath = Path.Combine(Path.GetTempPath(), "newExecutable.exe");
16-
string currentExecutablePath = Process.GetCurrentProcess().MainModule!.FileName;
17-
string batchScriptPath = Path.Combine(Path.GetTempPath(), "updateScript.bat");
17+
httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("request");
18+
}
1819

19-
using (var httpClient = new HttpClient())
20+
public static async Task UpdateFromGithubAsync(Config config)
21+
{
22+
try
2023
{
21-
httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd("request");
24+
var latestRelease = await GetLatestReleaseAsync();
25+
var latestVersion = new Version(latestRelease["tag_name"]!.ToString());
2226

23-
try
27+
if (IsUpdateRequired(config, latestVersion))
2428
{
25-
var response = await httpClient.GetStringAsync(apiURL);
26-
var latestRelease = JObject.Parse(response);
27-
28-
string latestVersion = latestRelease["tag_name"]!.ToString();
29-
30-
Version latestVer = new Version(latestVersion);
31-
Version currentVer = new Version(config.Version);
32-
33-
if (latestVer > currentVer)
34-
{
35-
Console.WriteLine("Downloading Latest Version: " + latestVersion);
36-
37-
string downloadUrl = latestRelease["assets"]![0]!["browser_download_url"]!.ToString();
38-
39-
var downloadResponse = await httpClient.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
40-
using (var fs = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
41-
{
42-
await downloadResponse.Content.CopyToAsync(fs);
43-
}
44-
45-
config.Version = latestVersion;
46-
ConfigurationManager.SaveConfig(config);
47-
48-
// Create a batch script for updating
49-
using (StreamWriter sw = new StreamWriter(batchScriptPath))
50-
{
51-
sw.WriteLine("@echo off");
52-
//sw.WriteLine("TIMEOUT /T 2 /NOBREAK");
53-
sw.WriteLine($"COPY /Y \"{tempFilePath}\" \"{currentExecutablePath}\"");
54-
sw.WriteLine($"DEL \"{tempFilePath}\"");
55-
sw.WriteLine($"START \"\" \"{currentExecutablePath}\"");
56-
sw.WriteLine($"DEL \"%~f0\"");
57-
}
58-
59-
// Start the batch script and exit the application
60-
Process.Start(batchScriptPath);
61-
Environment.Exit(0);
62-
}
63-
else
64-
{
65-
Console.WriteLine("No update required. Running the latest version.");
66-
}
29+
var tempFilePath = Path.GetTempFileName();
30+
await DownloadLatestVersionAsync(latestRelease, tempFilePath);
31+
32+
config.Version = latestVersion.ToString();
33+
ConfigurationManager.SaveConfig(config);
34+
35+
await ApplyUpdateAsync(tempFilePath);
6736
}
68-
catch (Exception ex)
37+
else
6938
{
70-
Console.WriteLine("Error: " + ex.Message);
39+
Console.WriteLine("No update required. Running the latest version.");
7140
}
7241
}
42+
catch (Exception ex)
43+
{
44+
Console.WriteLine("Error updating: " + ex.Message);
45+
}
46+
}
47+
48+
private static bool IsUpdateRequired(Config config, Version latestVersion)
49+
{
50+
return latestVersion > new Version(config.Version);
51+
}
52+
53+
private static async Task<JObject> GetLatestReleaseAsync()
54+
{
55+
var response = await httpClient.GetStringAsync(ApiURL);
56+
return JObject.Parse(response);
57+
}
58+
59+
private static async Task DownloadLatestVersionAsync(JObject latestRelease, string tempFilePath)
60+
{
61+
string downloadUrl = latestRelease["assets"]![0]!["browser_download_url"]!.ToString();
62+
63+
Console.WriteLine("Downloading Latest Version...");
64+
using var downloadResponse = await httpClient.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead);
65+
using var fs = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
66+
67+
await CopyContentToStream(downloadResponse.Content, fs);
68+
}
69+
70+
private static async Task CopyContentToStream(HttpContent content, FileStream fileStream)
71+
{
72+
var totalBytes = content.Headers.ContentLength ?? 0;
73+
var buffer = new byte[8192];
74+
var totalRead = 0L;
75+
using var stream = await content.ReadAsStreamAsync();
76+
77+
int read;
78+
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
79+
{
80+
await fileStream.WriteAsync(buffer, 0, read);
81+
totalRead += read;
82+
Console.Write($"\rDownload progress: {totalRead * 100 / totalBytes}%");
83+
}
84+
Console.WriteLine("\nDownload Complete.");
85+
}
86+
87+
private static async Task ApplyUpdateAsync(string tempFilePath)
88+
{
89+
string currentExecutablePath = Process.GetCurrentProcess().MainModule!.FileName;
90+
string backupExecutablePath = currentExecutablePath + ".bak";
91+
92+
// Rename current executable as a backup
93+
File.Move(currentExecutablePath, backupExecutablePath);
94+
95+
// Move new executable to application path
96+
File.Move(tempFilePath, currentExecutablePath);
97+
98+
// Restart application
99+
ProcessStartInfo startInfo = new ProcessStartInfo(currentExecutablePath)
100+
{
101+
Arguments = "restart",
102+
UseShellExecute = false
103+
};
104+
105+
Process.Start(startInfo);
106+
107+
// Exit current application
108+
Environment.Exit(0);
73109
}
74110
}
75-
}
111+
}

0 commit comments

Comments
 (0)