Skip to content

Commit fdcca96

Browse files
committed
Migration from private Git to GitHub
for Nuget release
1 parent ab8928b commit fdcca96

6 files changed

Lines changed: 1269 additions & 0 deletions

File tree

GithubUpdateCheck.sln

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.29509.3
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GithubUpdateCheck", "GithubUpdateCheck\GithubUpdateCheck.csproj", "{85FCC2DF-BCF3-447A-9675-39765B9AA1F9}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GithubUpdateCheckTest", "GithubUpdateCheckTest\GithubUpdateCheckTest.csproj", "{40867AEC-2913-4B04-99E8-A48E7FEB2058}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{85FCC2DF-BCF3-447A-9675-39765B9AA1F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{85FCC2DF-BCF3-447A-9675-39765B9AA1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{85FCC2DF-BCF3-447A-9675-39765B9AA1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{85FCC2DF-BCF3-447A-9675-39765B9AA1F9}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{40867AEC-2913-4B04-99E8-A48E7FEB2058}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{40867AEC-2913-4B04-99E8-A48E7FEB2058}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{40867AEC-2913-4B04-99E8-A48E7FEB2058}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{40867AEC-2913-4B04-99E8-A48E7FEB2058}.Release|Any CPU.Build.0 = Release|Any CPU
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {04FA09DC-A6AD-413C-BD9C-BB7B422CF44C}
30+
EndGlobalSection
31+
EndGlobal
Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
using System;
2+
using System.Net;
3+
using System.Threading.Tasks;
4+
5+
using System.Text.RegularExpressions;
6+
7+
namespace Mayerch1.GithubUpdateCheck
8+
{
9+
/// <summary>
10+
/// Enumeration of version steps (Major, Minor,...)
11+
/// </summary>
12+
public enum VersionChange
13+
{
14+
/// <summary>
15+
/// Major software update (X.0.0.0)
16+
/// </summary>
17+
Major = 1,
18+
19+
/// <summary>
20+
/// Minor software update (0.X.0.0)
21+
/// </summary>
22+
Minor = 2,
23+
24+
/// <summary>
25+
/// Build change (0.0.X.0)
26+
/// </summary>
27+
Build = 3,
28+
29+
/// <summary>
30+
/// Revision changed (0.0.0.X)
31+
/// </summary>
32+
Revision = 4
33+
}
34+
35+
/// <summary>
36+
/// The exception that is thrown if the version argument does not match the required pattern
37+
/// </summary>
38+
public class InvalidVersionException : ArgumentException {
39+
/// <summary>
40+
/// Initializes a new instance of the <see cref="InvalidVersionException"/> class with a specified error message
41+
/// </summary>
42+
public InvalidVersionException(String message): base(message)
43+
{
44+
}
45+
};
46+
47+
48+
/// <summary>
49+
/// Checks if your github repo is on a newer version or not
50+
/// </summary>
51+
public class GithubUpdateCheck
52+
{
53+
private const string githubUrl = "https://github.com/";
54+
private const string latestVersionString = "/releases/latest";
55+
56+
private string Username;
57+
private string Repository;
58+
59+
/// <summary>
60+
/// Assumes version numbering with the pattern 1.2.3.4
61+
/// </summary>
62+
/// <param name="Username">Username of Repository owner</param>
63+
/// <param name="Repository">Name of Github Repository</param>
64+
public GithubUpdateCheck(string Username, string Repository)
65+
{
66+
this.Username = Username;
67+
this.Repository = Repository;
68+
}
69+
70+
71+
/// <summary>
72+
/// Tests if inputted version is valid based on the allowed/specified patterns
73+
/// </summary>
74+
/// <param name="version">Current software version, is compared against the github version</param>
75+
/// <returns></returns>
76+
private bool isValidInput(string version)
77+
{
78+
// currently accepeted pattern:
79+
// 1.0.0.0
80+
// 1.0.0
81+
// v.1.0.0
82+
// v1.0.0
83+
// and any combination of those
84+
string pattern = @"^([^0-9]\.{0,1}){0,1}\d+\.\d+\.\d+(\.\d+){0,1}$";
85+
Match match = Regex.Match(version, pattern);
86+
87+
return match.Success;
88+
}
89+
90+
91+
/// <summary>
92+
/// Removes leading v. and v from the string
93+
/// </summary>
94+
/// <param name="version">string which is compliant to the allowed pattern(s)</param>
95+
/// <returns>normalized string</returns>
96+
private string normalizeVersionString(string version)
97+
{
98+
// leading (v. or v ) are allowed
99+
// therefore remove those from the version number
100+
string pattern = @"\d+\.\d+\.\d+(\.\d+){0,1}$";
101+
Match match = Regex.Match(version, pattern);
102+
103+
return match.Value;
104+
}
105+
106+
107+
108+
/// <summary>
109+
/// <para>Compares the current software version to the latest release on github. Asynchronous web request</para>
110+
/// If the webservice is not available this function will assume no updates available
111+
/// </summary>
112+
/// <param name="CurrentVersion">The version of the software wich is compared to the github version</param>
113+
/// <param name="VersionChange">The granularity of the comparison. Any version change smaller than this will be ignored. (e.g. Minor will check for a change in the first 2 digits groups)</param>
114+
/// <exception cref="InvalidVersionException">Is thrown if the supplied version does not match the allowed version pattern</exception>
115+
/// <returns>bool - true if a newer version is available, false - if no newer version is available or if no connection to github is available</returns>
116+
public async Task<bool> IsUpdateAvailableAsync(string CurrentVersion, VersionChange VersionChange = VersionChange.Minor)
117+
{
118+
if (!isValidInput(CurrentVersion))
119+
{
120+
throw new InvalidVersionException(CurrentVersion + " does not follow the specified version pattern [CurrentVersion]");
121+
}
122+
string resolved = await getResponseUrlAsync(githubUrl + Username + "/" + Repository + latestVersionString);
123+
124+
if (resolved != null)
125+
return compareVersions(normalizeVersionString(CurrentVersion), resolved, VersionChange);
126+
else
127+
return false;
128+
129+
130+
}
131+
132+
/// <summary>
133+
/// <para>Compares the current software version to the latest release on github. Synchronous (blocking) web request</para>
134+
/// If the webservice is not available this function will assume no updates available
135+
/// </summary>
136+
/// <param name="CurrentVersion">The version of the software wich is compared to the github version</param>
137+
/// <param name="VersionChange">The granularity of the comparison. Any version change smaller than this will be ignored. (e.g. Minor will check for a change in the first 2 digits groups)</param>
138+
/// <exception cref="InvalidVersionException">Is thrown if the supplied version does not match the allowed version pattern</exception>
139+
/// <returns>bool - true if a newer version is available, false - if no newer version is available or if no connection to github is available</returns>
140+
public bool IsUpdateAvailable(string CurrentVersion, VersionChange VersionChange = VersionChange.Minor)
141+
{
142+
if (!isValidInput(CurrentVersion))
143+
{
144+
throw new InvalidVersionException(CurrentVersion + " does not follow the specified version pattern [CurrentVersion]");
145+
}
146+
147+
148+
string resolved = getResponseUrl(githubUrl + Username + "/" + Repository + latestVersionString);
149+
150+
if (resolved != null)
151+
return compareVersions(normalizeVersionString(CurrentVersion), resolved, VersionChange);
152+
else
153+
return false;
154+
}
155+
156+
157+
158+
/// <summary>
159+
/// Compares two version numbers. Extract version number of github release url
160+
/// "Current" must comply with pattern, aswell as github version
161+
/// </summary>
162+
/// <param name="current">Local software version, must be checket for complinance with the allowed pattern(s)</param>
163+
/// <param name="github">Url of the latest github release</param>
164+
/// <param name="changeLevel">The level for comparison</param>
165+
/// /// <exception cref="InvalidVersionException">Is thrown if the supplied version does not match the allowed version pattern</exception>
166+
/// <returns></returns>
167+
private bool compareVersions(string current, string github, VersionChange changeLevel)
168+
{
169+
//no releases yet
170+
if (!github.Contains("/tag/"))
171+
return false;
172+
173+
//get everything after last /tag/
174+
github = github.Substring(github.LastIndexOf("/tag/") + "/tag/".Length);
175+
176+
177+
if (!isValidInput(github))
178+
{
179+
throw new InvalidVersionException(github + " the github version number does not follow the specified version pattern [Remote error]");
180+
}
181+
182+
github = normalizeVersionString(github);
183+
184+
// separate version into VersionChange
185+
// input is tested for numbers only between the seperators ('.')
186+
Int64[] currentArr = Array.ConvertAll(current.Split('.'), s => Int64.Parse(s));
187+
Int64[] gitArr = Array.ConvertAll(github.Split('.'), s => Int64.Parse(s));
188+
189+
190+
// set the comparison depth
191+
// take the minimum depth, in case one specified number is smaller than another one
192+
int cmpDepth = (int)changeLevel;
193+
cmpDepth = Math.Min(currentArr.Length, cmpDepth);
194+
cmpDepth = Math.Min(gitArr.Length, cmpDepth);
195+
196+
197+
/* comparison of version numbers as follows
198+
199+
localMajor <> gitMajor
200+
[smalle] [equals] [greater]
201+
true | false
202+
V
203+
localMinor <> gitMinor
204+
[smalle] [equals] [greater]
205+
true | false
206+
V
207+
localBuild <> gitBuild
208+
[smalle] [equals] [greater]
209+
true | false
210+
V
211+
localRev. <> gitRev.
212+
[smalle] [equals] [greater]
213+
true false false
214+
215+
// if cmpDepth is reached at any time
216+
// the return is false aswell
217+
218+
219+
*/
220+
221+
// implicitie cmpDepth == 1
222+
// 1. major is checked on every version
223+
// 2. input is guaranteed to have cmpDepth >= 1
224+
225+
//===============MAJOR==================
226+
if (currentArr[0] < gitArr[0])
227+
{
228+
return true;
229+
}
230+
else if (currentArr[0] > gitArr[0])
231+
{
232+
return false;
233+
}
234+
//===============MAJOR==================
235+
else
236+
{
237+
// first check if Depth was reached
238+
if(cmpDepth <= 1)
239+
{
240+
return false;
241+
}
242+
//===============MINOR==================
243+
// repeat same procedure for minor
244+
if (currentArr[1] < gitArr[1])
245+
{
246+
return true;
247+
}
248+
else if (currentArr[1] > gitArr[1])
249+
{
250+
return false;
251+
}
252+
//===============MINOR==================
253+
else
254+
{
255+
// check if Depth was reached
256+
if (cmpDepth <= 2)
257+
{
258+
return false;
259+
}
260+
//===============BUILD==================
261+
// repeat same procedure for build
262+
if (currentArr[2] < gitArr[2])
263+
{
264+
return true;
265+
}
266+
else if (currentArr[2] > gitArr[2])
267+
{
268+
return false;
269+
}
270+
//===============BUILD==================
271+
else
272+
{
273+
// check if Depth was reached
274+
if (cmpDepth <= 3)
275+
{
276+
return false;
277+
}
278+
279+
//===============REVSIION==================
280+
// repeat same procedure for Revision
281+
if (currentArr[3] < gitArr[3])
282+
{
283+
return true;
284+
}
285+
// no smaller compare possible
286+
else
287+
{
288+
return false;
289+
}
290+
//===============REVISION==================
291+
}
292+
}
293+
294+
295+
}
296+
}
297+
298+
private string getResponseUrl(string request)
299+
{
300+
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(request);
301+
WebResponse wResp;
302+
try
303+
{
304+
wResp = req.GetResponse();
305+
}
306+
catch
307+
{
308+
//if not available
309+
return null;
310+
}
311+
312+
return wResp.ResponseUri.ToString();
313+
}
314+
315+
private async Task<string> getResponseUrlAsync(string request)
316+
{
317+
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(request);
318+
WebResponse wResp;
319+
try
320+
{
321+
wResp = await req.GetResponseAsync();
322+
}
323+
catch
324+
{
325+
return null;
326+
//if not available
327+
}
328+
329+
return wResp.ResponseUri.ToString();
330+
}
331+
}
332+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<AssemblyName>Mayerch1.GithubUpdateCheck</AssemblyName>
6+
<RootNamespace>Mayerch1.GithubUpdateCheck</RootNamespace>
7+
</PropertyGroup>
8+
9+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
10+
<DocumentationFile>bin\Debug\netstandard2.0\GithubVersionChecker.xml</DocumentationFile>
11+
</PropertyGroup>
12+
13+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
14+
<DocumentationFile>bin\Release\netstandard2.0\GithubVersionChecker.xml</DocumentationFile>
15+
</PropertyGroup>
16+
17+
</Project>

0 commit comments

Comments
 (0)