/// <inheritdoc/> public PlatformDetectorResult Detect(DetectorContext context) { var projectFile = this.projectFileProvider.GetRelativePathToProjectFile(context); if (string.IsNullOrEmpty(projectFile)) { return(null); } var sourceRepo = context.SourceRepo; var appDirectory = Path.GetDirectoryName(projectFile); var installAOTWorkloads = false; var projectFileDoc = XDocument.Load(new StringReader(sourceRepo.ReadFile(projectFile))); var targetFrameworkElement = projectFileDoc.XPathSelectElement( DotNetCoreConstants.TargetFrameworkElementXPathExpression); var targetFramework = targetFrameworkElement?.Value; if (string.IsNullOrEmpty(targetFramework)) { this.logger.LogDebug( $"Could not find 'TargetFramework' element in the project file."); return(null); } var outputTypeElement = projectFileDoc.XPathSelectElement( DotNetCoreConstants.OutputTypeXPathExpression); var outputType = GetOutputType(outputTypeElement); var version = this.GetVersion(targetFramework); // Any Blazor WebAssembly app on .NET 6 should have the workload installed. // https://github.com/microsoft/Oryx/issues/1026 if (ProjectFileHelpers.IsBlazorWebAssemblyProject(projectFileDoc) && !string.IsNullOrEmpty(version) && version.StartsWith("6")) { installAOTWorkloads = true; } return(new DotNetCorePlatformDetectorResult { Platform = DotNetCoreConstants.PlatformName, PlatformVersion = version, ProjectFile = projectFile, AppDirectory = appDirectory, OutputType = outputType, InstallAOTWorkloads = installAOTWorkloads, }); }
public string GetRelativePathToProjectFile(DetectorContext context) { var sourceRepo = context.SourceRepo; string projectFile = null; // search for .csproj files var projectFiles = GetAllProjectFilesInRepo( sourceRepo, DotNetCoreConstants.CSharpProjectFileExtension); if (!projectFiles.Any()) { _logger.LogDebug( "Could not find any files with extension " + $"'{DotNetCoreConstants.CSharpProjectFileExtension}' in repo."); // search for .fsproj files projectFiles = GetAllProjectFilesInRepo( sourceRepo, DotNetCoreConstants.FSharpProjectFileExtension); if (!projectFiles.Any()) { _logger.LogDebug( "Could not find any files with extension " + $"'{DotNetCoreConstants.FSharpProjectFileExtension}' in repo."); return(null); } } var webAppProjects = new List <string>(); var azureFunctionsProjects = new List <string>(); var azureBlazorWasmProjects = new List <string>(); var allProjects = new List <string>(); bool functionProjectExists = false; bool webAppProjectExists = false; bool blazorWasmProjectExists = false; foreach (var file in projectFiles) { allProjects.Add(file); if (ProjectFileHelpers.IsAzureBlazorWebAssemblyProject(sourceRepo, file)) { azureBlazorWasmProjects.Add(file); blazorWasmProjectExists = true; } else if (ProjectFileHelpers.IsAzureFunctionsProject(sourceRepo, file)) { azureFunctionsProjects.Add(file); functionProjectExists = true; } else if (ProjectFileHelpers.IsAspNetCoreWebApplicationProject(sourceRepo, file)) { webAppProjects.Add(file); webAppProjectExists = true; } } // Assumption: some build option "--apptype" will be passed to oryx // which will indicate if the app is an azure function type or static type app // If there are multiple projects, we will look for --appty to detect corresponding project. // for example azurefunction and blazor both projects can reside // at the same repo, so more than 2 csprojs will be found. Now we will // look for --apptype value to determine which project needs to be built if (!string.IsNullOrEmpty(_options.AppType)) { _logger.LogInformation($"{nameof(_options.AppType)} is set to {_options.AppType}"); if (functionProjectExists && _options.AppType.ToLower().Contains(Constants.FunctionApplications)) { projectFile = GetProject(azureFunctionsProjects); } else if (blazorWasmProjectExists && _options.AppType.ToLower().Contains(Constants.StaticSiteApplications)) { projectFile = GetProject(azureBlazorWasmProjects); } else { _logger.LogDebug( $"Invalid value '{_options.AppType}' for '{nameof(_options.AppType)}'. " + $"Currently, supported values are 'functions', 'blazor-wasm', 'static-sites'"); } } else { // If multiple project exists, and appType is not passed // we detect them in following order if (projectFile == null && webAppProjectExists) { projectFile = GetProject(webAppProjects); } else if (projectFile == null && blazorWasmProjectExists) { projectFile = GetProject(azureBlazorWasmProjects); } else if (projectFile == null && functionProjectExists) { projectFile = GetProject(azureFunctionsProjects); } } // After scanning all the project types we stil didn't find any files (e.g. csproj if (projectFile == null) { _logger.LogDebug("Could not find a .NET Core project file to build."); return(null); } _projectFileRelativePath = ProjectFileHelpers.GetRelativePathToRoot(projectFile, sourceRepo.RootPath); return(_projectFileRelativePath); }
public string GetRelativePathToProjectFile(DetectorContext context) { var sourceRepo = context.SourceRepo; string projectFile = null; // search for .csproj files var projectFiles = this.GetAllProjectFilesInRepo( sourceRepo, DotNetCoreConstants.CSharpProjectFileExtension); if (!projectFiles.Any()) { this.logger.LogDebug( "Could not find any files with extension " + $"'{DotNetCoreConstants.CSharpProjectFileExtension}' in repo."); // search for .fsproj files projectFiles = this.GetAllProjectFilesInRepo( sourceRepo, DotNetCoreConstants.FSharpProjectFileExtension); if (!projectFiles.Any()) { this.logger.LogDebug( "Could not find any files with extension " + $"'{DotNetCoreConstants.FSharpProjectFileExtension}' in repo."); return(null); } } var webAppProjects = new List <string>(); var azureFunctionsProjects = new List <string>(); var blazorWasmProjects = new List <string>(); var allProjects = new List <string>(); foreach (var file in projectFiles) { allProjects.Add(file); if (ProjectFileHelpers.IsAzureBlazorWebAssemblyProject(sourceRepo, file)) { blazorWasmProjects.Add(file); } else if (ProjectFileHelpers.IsAzureFunctionsProject(sourceRepo, file)) { azureFunctionsProjects.Add(file); } else if (ProjectFileHelpers.IsAspNetCoreWebApplicationProject(sourceRepo, file)) { webAppProjects.Add(file); } } // Assumption: some build option "--apptype" will be passed to oryx // which will indicate if the app is an azure function type or static type app // If there are multiple projects, we will look for --apptype to detect corresponding project. // for example azurefunction and blazor both projects can reside // at the same repo, so more than 2 csprojs will be found. Now we will // look for --apptype value to determine which project needs to be built if (!string.IsNullOrEmpty(this.options.AppType)) { this.logger.LogInformation($"{nameof(this.options.AppType)} is set to {this.options.AppType}"); var appType = this.options.AppType.ToLower(); if (appType.Contains(Constants.FunctionApplications)) { if (azureFunctionsProjects.Count == 0) { return(null); } projectFile = GetProject(azureFunctionsProjects); } else if (appType.Contains(Constants.StaticSiteApplications)) { if (blazorWasmProjects.Count == 0) { return(null); } projectFile = GetProject(blazorWasmProjects); } else if (appType.Contains(Constants.WebApplications)) { if (webAppProjects.Count == 0) { return(null); } projectFile = GetProject(webAppProjects); } else { this.logger.LogDebug($"Unrecognized app type {appType}'."); } } else { this.logger.LogInformation($"AppType is not provided. Selecting projects based on "); // If multiple project exists, and appType is not passed // we detect them in following order if (webAppProjects.Count > 0) { projectFile = GetProject(webAppProjects); } else if (blazorWasmProjects.Count > 0) { projectFile = GetProject(blazorWasmProjects); } else if (azureFunctionsProjects.Count > 0) { projectFile = GetProject(azureFunctionsProjects); } } // After scanning all the project types we still didn't find any files (e.g. csproj if (projectFile == null) { this.logger.LogDebug("Could not find a .NET Core project file to build."); return(null); } this.projectFileRelativePath = ProjectFileHelpers.GetRelativePathToRoot(projectFile, sourceRepo.RootPath); return(this.projectFileRelativePath); }
public string GetRelativePathToProjectFile(DetectorContext context) { if (_probedForProjectFile) { return(_projectFileRelativePath); } var sourceRepo = context.SourceRepo; string projectFile = null; // Check if any of the sub-directories has a .csproj or .fsproj file and if that file has references // to websdk or azure functions // search for .csproj files var projectFiles = GetAllProjectFilesInRepo( sourceRepo, DotNetCoreConstants.CSharpProjectFileExtension); if (!projectFiles.Any()) { _logger.LogDebug( "Could not find any files with extension " + $"'{DotNetCoreConstants.CSharpProjectFileExtension}' in repo."); // search for .fsproj files projectFiles = GetAllProjectFilesInRepo( sourceRepo, DotNetCoreConstants.FSharpProjectFileExtension); if (!projectFiles.Any()) { _logger.LogDebug( "Could not find any files with extension " + $"'{DotNetCoreConstants.FSharpProjectFileExtension}' in repo."); return(null); } } var webAppProjects = new List <string>(); var azureFunctionsProjects = new List <string>(); var allProjects = new List <string>(); foreach (var file in projectFiles) { allProjects.Add(file); if (ProjectFileHelpers.IsAspNetCoreWebApplicationProject(sourceRepo, file)) { webAppProjects.Add(file); } else if (ProjectFileHelpers.IsAzureFunctionsProject(sourceRepo, file)) { azureFunctionsProjects.Add(file); } } projectFile = GetProject(webAppProjects); if (projectFile == null) { projectFile = GetProject(azureFunctionsProjects); } if (projectFile == null) { _logger.LogDebug("Could not find a .NET Core project file to build."); return(null); } // Cache the results _probedForProjectFile = true; _projectFileRelativePath = ProjectFileHelpers.GetRelativePathToRoot(projectFile, sourceRepo.RootPath); return(_projectFileRelativePath); }