static public ProcessWithLog <string, Result <string, (TreeWithStringPath tree, LoadCompositionOrigin origin)> > LoadFromPathResolvingNetworkDependencies(string sourcePath) { var asProcess = AsProcessWithStringLog(sourcePath); if (LoadFromGitHubOrGitLab.ParseUrl(sourcePath) != null) { return (asProcess .WithLogEntryAdded("This path looks like a URL into a remote git repository. Trying to load from there...") .MapResult(LoadFromGitHubOrGitLab.LoadFromUrl) .ResultAddLogEntriesIfOk(LogEntriesForLoadFromGitSuccess) .ResultMap(loadFromGitOk => (loadFromGitOk.tree, new LoadCompositionOrigin(FromGit: loadFromGitOk)))); } if (LoadFromElmEditor.ParseUrl(sourcePath) != null) { return (asProcess .WithLogEntryAdded("This path looks like a URL into a code editor. Trying to load from there...") .MapResult(LoadFromElmEditor.LoadFromUrl) .ResultMap(loadFromEditorOk => (loadFromEditorOk.tree, new LoadCompositionOrigin(FromEditor: loadFromEditorOk.parsedUrl)))); } return (asProcess .WithLogEntryAdded("Trying to load from local file system...") .MapResult(sourcePath => { try { var treeComponentFromSource = LoadFromLocalFilesystem.LoadSortedTreeFromPath(sourcePath); if (treeComponentFromSource == null) { return new Result <string, TreeWithStringPath> { Err = "I did not find a file or directory at '" + sourcePath + "'.", } } ; return new Result <string, TreeWithStringPath>(Ok: treeComponentFromSource); } catch (Exception e) { return Result <string, TreeWithStringPath> .err("Failed to load from local file system: " + e?.ToString()); } }) .ResultMap(tree => (tree, new LoadCompositionOrigin(FromLocalFileSystem: new object())))); }
static public Task Run( IReadOnlyList <string> urls, IReadOnlyList <string> gitCloneUrlPrefixes, string fileCacheDirectory) { var builder = WebApplication.CreateBuilder(); var app = builder.Build(); app.Urls.Clear(); urls.ToList().ForEach(app.Urls.Add); var fileCache = new CacheByFileName ( CacheDirectory: Path.Combine(fileCacheDirectory, ZipArchivePathPrefix.TrimStart('/')) ); /* * https://docs.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0 * */ app.MapGet(ZipArchivePathPrefix + "{commitId}", (string commitId, HttpRequest httpRequest) => { using var bodyReader = new StreamReader(httpRequest.Body); var bodyString = bodyReader.ReadToEndAsync().Result; var cloneUrls = bodyString.Split(new[] { '\n', '\r' }, System.StringSplitOptions.RemoveEmptyEntries); var supportedCloneUrls = cloneUrls .Where(c => gitCloneUrlPrefixes.Any(prefix => c.ToLowerInvariant().StartsWith(prefix.ToLowerInvariant()))) .ToImmutableList(); if (!cloneUrls.Any()) { return(Results.BadRequest("Missing clone URL. Use one line in the request body for each clone URL.")); } if (!supportedCloneUrls.Any()) { return(Results.BadRequest( "None of the given clone URLs is enabled here. Only URLs with the following " + gitCloneUrlPrefixes.Count + " prefixes are supported: " + string.Join(", ", gitCloneUrlPrefixes))); } byte[] loadWithFreshClone() { var files = LoadFromGitHubOrGitLab.GetRepositoryFilesPartialForCommitViaEnvironmentGitCheckout( cloneUrl: supportedCloneUrls[0], commit: commitId); var zipArchive = ZipArchive.ZipArchiveFromEntries(files); System.Console.WriteLine( "Cloned for commit " + commitId + ": Got " + files.Count + " files. Size of zip archive: " + zipArchive.Length + " bytes."); return(zipArchive); } return(Results.Bytes( contents: fileCache.GetOrUpdate(commitId, loadWithFreshClone), contentType: "application/zip", fileDownloadName: "git-partial-for-commit-" + commitId + ".zip")); }); return(app.RunAsync()); }