public ActionResult Submit(string githubUrl) { // If someone navigates to submit directly, just send 'em back to index if (string.IsNullOrWhiteSpace(githubUrl)) { return View("Index"); } var retriever = new GitHubRetriever(githubUrl); if (!retriever.IsValidUrl()) { ViewBag.Error = "Make sure that the provided path points to a valid GitHub repository."; return View("Index"); } // Check if this repo already exists if (!BrowserRepository.TryLockRepository(retriever.UserName, retriever.RepoName)) { // Repo exists. Redirect the user to that repository. return Redirect("/Browse/" + retriever.UserName + "/" + retriever.RepoName); } // We have locked the repository and marked it as processing. // Whenever we return or exit on an exception, we need to unlock this repository bool processingSuccessful = false; try { string repoRootPath = string.Empty; try { repoRootPath = retriever.RetrieveProject(); } catch (Exception ex) { ViewBag.Error = "There was an error downloading this repository."; return View("Index"); } // Generate the source browser files for this solution var solutionPaths = GetSolutionPaths(repoRootPath); if (solutionPaths.Length == 0) { ViewBag.Error = "No C# solution was found. Ensure that a valid .sln file exists within your repository."; return View("Index"); } var organizationPath = System.Web.Hosting.HostingEnvironment.MapPath("~/") + "SB_Files\\" + retriever.UserName; var repoPath = Path.Combine(organizationPath, retriever.RepoName); // TODO: Use parallel for. // TODO: Process all solutions. // For now, we're assuming the shallowest and shortest .sln file is the one we're interested in foreach (var solutionPath in solutionPaths.OrderBy(n => n.Length).Take(1)) { try { var workspaceModel = UploadRepository.ProcessSolution(solutionPath, repoRootPath); //One pass to lookup all declarations var typeTransformer = new TokenLookupTransformer(); typeTransformer.Visit(workspaceModel); var tokenLookup = typeTransformer.TokenLookup; //Another pass to generate HTMLs var htmlTransformer = new HtmlTransformer(tokenLookup, repoPath); htmlTransformer.Visit(workspaceModel); var searchTransformer = new SearchIndexTransformer(retriever.UserName, retriever.RepoName); searchTransformer.Visit(workspaceModel); // Generate HTML of the tree view var treeViewTransformer = new TreeViewTransformer(repoPath, retriever.UserName, retriever.RepoName); treeViewTransformer.Visit(workspaceModel); } catch (Exception ex) { // TODO: Log this ViewBag.Error = "There was an error processing solution " + Path.GetFileName(solutionPath); return View("Index"); } } try { UploadRepository.SaveReadme(repoPath, retriever.ProvideParsedReadme()); } catch (Exception ex) { // TODO: Log and swallow - readme is not essential. } processingSuccessful = true; return Redirect("/Browse/" + retriever.UserName + "/" + retriever.RepoName); } finally { if (processingSuccessful) { BrowserRepository.UnlockRepository(retriever.UserName, retriever.RepoName); } else { BrowserRepository.RemoveRepository(retriever.UserName, retriever.RepoName); } } }
static void Main(string[] args) { // Combined with, or replaced by, provided paths to create absolute paths string userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); // For developers that set test variables in code: string solutionPath = @""; string saveDirectory = @""; string username = ""; string repository = ""; // For developers that provide test variables in arguments: if (args.Length == 4) { solutionPath = args[0]; saveDirectory = args[1]; username = args[2]; repository = args[3]; } // Combine user's root with relative solution paths, or use absolute paths. // (Path.Combine returns just second argument if it is an absolute path) string absoluteSolutionPath = Path.Combine(userProfilePath, solutionPath); string absoluteSaveDirectory = Path.Combine(userProfilePath, saveDirectory); // Open and analyze the solution. try { Console.Write("Opening " + absoluteSolutionPath); Console.WriteLine("..."); var solutionAnalyzer = new SolutionAnalayzer(absoluteSolutionPath); Console.Write("Analyzing and saving into " + absoluteSaveDirectory); Console.WriteLine("..."); //NOTE: The rootPath is not always the parent directory of the solution. //The root path should be the longest path within which all documents are contained. var rootPath = Directory.GetParent(solutionPath).FullName; var workspaceModel = solutionAnalyzer.BuildWorkspaceModel(rootPath); var typeTransformer = new TokenLookupTransformer(); typeTransformer.Visit(workspaceModel); var tokenLookup = typeTransformer.TokenLookup; var htmlTransformer = new HtmlTransformer(tokenLookup, absoluteSaveDirectory); htmlTransformer.Visit(workspaceModel); var searchTransformer = new SearchIndexTransformer(username, repository); searchTransformer.Visit(workspaceModel); var treeViewTransformer = new TreeViewTransformer(absoluteSaveDirectory, username, repository); treeViewTransformer.Visit(workspaceModel); Console.WriteLine("Job successful!"); } catch (Exception ex) { Console.WriteLine("Error:"); Console.WriteLine(ex.ToString()); Console.ReadLine(); } }