Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/Core/RemoteRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,25 @@ public override string ToString() =>

public static bool TryParse(string value, [NotNullWhen(true)] out RemoteRef? remote)
{
Match GetMatch(string input)
// Convenience case for some common URL formats pasted from browser
if (Uri.TryCreate(value, UriKind.Absolute, out var uri))
{
var path = uri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (uri.Host == "github.com" && path is [var ghOwner, var ghRepo, "blob", var ghReference, ..])
{
value = $"{uri.Host}/{ghOwner}/{ghRepo}@{ghReference}:{string.Join('/', path[4..])}";
}
else if (uri.Host == "gist.github.com" && path is [var gistOwner, var gistId, ..])
{
value = $"{uri.Host}/{gistOwner}/{gistId}";
}
else if (uri.Host == "gitlab.com" && path is [var glOwner, var glRepo, "-", "blob", var glReference, ..])
{
value = $"{uri.Host}/{glOwner}/{glRepo}@{glReference}:{string.Join('/', path[5..])}";
}
}

static Match GetMatch(string input)
{
// Try Azure DevOps first since it is more specific
var match = ParseAzureDevOpsExp().Match(input);
Expand Down
27 changes: 27 additions & 0 deletions src/Tests/DownloadTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@ namespace Devlooped.Tests;

public class DownloadTests
{
[Theory]
[InlineData("https://gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381")]
[InlineData("https://github.com/kzu/runfile/blob/main/run.cs")]
[InlineData("https://gitlab.com/kzu/runcs/-/blob/main/program.cs?ref_type=heads")]
public async Task DownloadPublicUnchanged(string value)
{
Assert.True(RemoteRef.TryParse(value, out var location));

var provider = DownloadProvider.Create(location);
var contents = await provider.GetAsync(location);

Assert.True(contents.IsSuccessStatusCode);

var etag = contents.Headers.ETag?.ToString();

location = location with
{
ETag = etag,
ResolvedUri = contents.OriginalUri
};

var refresh = await provider.GetAsync(location);

Assert.Equal(HttpStatusCode.NotModified, refresh.StatusCode);
}

[LocalTheory]
// Requires being authenticated with private kzu's GH repo
[InlineData("github.com/kzu/runfile")]
Expand All @@ -13,6 +39,7 @@ public class DownloadTests
[InlineData("github.com/kzu/runfile@211de7614")]
[InlineData("github.com/kzu/runfile@211de761455")]
// Requires running the CLI app once against this private repo and saving a PAT
[InlineData("https://gitlab.com/kzu/runfile/-/blob/main/program.cs?ref_type=heads")]
[InlineData("gitlab.com/kzu/runfile")]
[InlineData("gitlab.com/kzu/runfile@v0.1.0")]
[InlineData("gitlab.com/kzu/runfile@dev")]
Expand Down
57 changes: 57 additions & 0 deletions src/Tests/Tests.cs → src/Tests/RemoteRefTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -475,4 +475,61 @@ public void TryParse_WithInvalidOwnerRepoCharacters_ReturnsFalse(string input)
Assert.False(success);
Assert.Null(result);
}

[Theory]
[InlineData("https://github.com/owner/repo/blob/main/file.txt", "github.com", "owner", "repo", "main", "file.txt")]
[InlineData("https://github.com/microsoft/vscode/blob/main/src/vs/workbench/workbench.main.ts", "github.com", "microsoft", "vscode", "main", "src/vs/workbench/workbench.main.ts")]
[InlineData("https://github.com/octocat/Hello-World/blob/master/README", "github.com", "octocat", "Hello-World", "master", "README")]
[InlineData("https://github.com/owner/repo/blob/develop/path/to/file.cs", "github.com", "owner", "repo", "develop", "path/to/file.cs")]
[InlineData("https://github.com/dotnet/runtime/blob/v8.0.0/src/libraries/System.Console/src/System/Console.cs", "github.com", "dotnet", "runtime", "v8.0.0", "src/libraries/System.Console/src/System/Console.cs")]
public void TryParse_GitHubBlobUrls_WorksCorrectly(string input, string expectedHost, string expectedOwner, string expectedRepo, string expectedRef, string expectedPath)
{
var success = RemoteRef.TryParse(input, out var result);

Assert.True(success);
Assert.NotNull(result);
Assert.Equal(expectedHost, result.Host);
Assert.Equal(expectedOwner, result.Owner);
Assert.Equal(expectedRepo, result.Repo);
Assert.Equal(expectedRef, result.Ref);
Assert.Equal(expectedPath, result.Path);
Assert.NotEmpty(result.TempPath);
}

[Theory]
[InlineData("https://gist.github.com/username/123456789", "gist.github.com", "username", "123456789", null, null)]
[InlineData("https://gist.github.com/octocat/6cad326836d38bd6", "gist.github.com", "octocat", "6cad326836d38bd6", null, null)]
[InlineData("https://gist.github.com/devlooped/abc123def", "gist.github.com", "devlooped", "abc123def", null, null)]
public void TryParse_GistUrls_WorksCorrectly(string input, string expectedHost, string expectedOwner, string expectedRepo, string? expectedRef, string? expectedPath)
{
var success = RemoteRef.TryParse(input, out var result);

Assert.True(success);
Assert.NotNull(result);
Assert.Equal(expectedHost, result.Host);
Assert.Equal(expectedOwner, result.Owner);
Assert.Equal(expectedRepo, result.Repo);
Assert.Equal(expectedRef, result.Ref);
Assert.Equal(expectedPath, result.Path);
Assert.NotEmpty(result.TempPath);
}

[Theory]
[InlineData("https://gitlab.com/owner/repo/-/blob/main/file.txt", "gitlab.com", "owner", "repo", "main", "file.txt")]
[InlineData("https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/main.js", "gitlab.com", "gitlab-org", "gitlab", "master", "app/assets/javascripts/main.js")]
[InlineData("https://gitlab.com/inkscape/inkscape/-/blob/1.3.x/src/ui/widget/color-scales.cpp", "gitlab.com", "inkscape", "inkscape", "1.3.x", "src/ui/widget/color-scales.cpp")]
[InlineData("https://gitlab.com/fdroid/fdroidclient/-/blob/master/app/src/main/java/org/fdroid/fdroid/installer/Installer.java", "gitlab.com", "fdroid", "fdroidclient", "master", "app/src/main/java/org/fdroid/fdroid/installer/Installer.java")]
public void TryParse_GitLabBlobUrls_WorksCorrectly(string input, string expectedHost, string expectedOwner, string expectedRepo, string expectedRef, string expectedPath)
{
var success = RemoteRef.TryParse(input, out var result);

Assert.True(success);
Assert.NotNull(result);
Assert.Equal(expectedHost, result.Host);
Assert.Equal(expectedOwner, result.Owner);
Assert.Equal(expectedRepo, result.Repo);
Assert.Equal(expectedRef, result.Ref);
Assert.Equal(expectedPath, result.Path);
Assert.NotEmpty(result.TempPath);
}
}
7 changes: 6 additions & 1 deletion src/gist/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@
if (alias != null)
args = [.. parsed.UnmatchedTokens];

if (args.Length == 0 || !RemoteRef.TryParse("gist.github.com/" + args[0], out var location))
RemoteRef? location = default;
var validRef = args.Length > 0 &&
(RemoteRef.TryParse("gist.github.com/" + args[0], out location) ||
RemoteRef.TryParse(args[0], out location));

if (args.Length == 0 || !validRef || location is null)
{
AnsiConsole.MarkupLine(
$"""
Expand Down
4 changes: 4 additions & 0 deletions src/gist/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"gist": {
"commandName": "Project",
"commandLineArgs": "kzu/0ac826dc7de666546aaedd38e5965381"
},
"gist url": {
"commandName": "Project",
"commandLineArgs": "https://gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381"
}
}
}
2 changes: 2 additions & 0 deletions src/gist/gist.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>

<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="https://www.schemastore.org/loobin-1.0.json" /></VisualStudio></ProjectExtensions>

</Project>
8 changes: 8 additions & 0 deletions src/runfile/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@
"commandName": "Project",
"commandLineArgs": "clean",
"workingDirectory": "C:\\Code\\WhatsApp"
},
"damian": {
"commandName": "Project",
"commandLineArgs": "https://github.com/DamianEdwards/runfile/blob/main/flat/filepath.cs"
},
"gitlab url": {
"commandName": "Project",
"commandLineArgs": "https://gitlab.com/kzu/runfile/-/blob/main/program.cs?ref_type=heads"
}
}
}