From 7e1bfa23920a9a590ae15499846c703b860f8e03 Mon Sep 17 00:00:00 2001 From: shucai Date: Wed, 16 Nov 2016 15:14:39 -0800 Subject: [PATCH] kudu support dotnet project created with preview2 and preview3 cli tools --- Kudu.Core/Deployment/DeploymentHelper.cs | 8 +-- .../Deployment/Generator/AspNetCoreBuilder.cs | 6 +- .../Generator/SiteBuilderFactory.cs | 67 ++++++++++--------- Kudu.Core/Functions/FunctionManager.cs | 3 +- Kudu.Core/Infrastructure/AspNetCoreHelper.cs | 13 +++- Kudu.Core/Infrastructure/VsHelper.cs | 8 +-- Kudu.Core/Infrastructure/VsSolutionProject.cs | 14 ++-- Kudu.Services.Web/updateNodeModules.cmd | 2 +- 8 files changed, 65 insertions(+), 56 deletions(-) diff --git a/Kudu.Core/Deployment/DeploymentHelper.cs b/Kudu.Core/Deployment/DeploymentHelper.cs index 2cb889f52..3d2f0a69c 100644 --- a/Kudu.Core/Deployment/DeploymentHelper.cs +++ b/Kudu.Core/Deployment/DeploymentHelper.cs @@ -10,7 +10,7 @@ namespace Kudu.Core.Deployment { public static class DeploymentHelper { - private static readonly string[] _projectFileExtensions = new[] { ".csproj", ".vbproj", ".fsproj" }; + private static readonly string[] _projectFileExtensions = new[] { ".csproj", ".vbproj", ".fsproj", ".xproj" }; public static readonly string[] ProjectFileLookup = _projectFileExtensions.Select(p => "*" + p).ToArray(); @@ -25,12 +25,6 @@ public static bool IsProject(string path) return _projectFileExtensions.Any(extension => path.EndsWith(extension, StringComparison.OrdinalIgnoreCase)); } - public static bool IsDeployableProject(string path) - { - return IsProject(path) && - (VsHelper.IsWap(path) || VsHelper.IsExecutableProject(path)); - } - public static bool IsDefaultWebRootContent(string webroot) { if (!FileSystemHelpers.DirectoryExists(webroot)) diff --git a/Kudu.Core/Deployment/Generator/AspNetCoreBuilder.cs b/Kudu.Core/Deployment/Generator/AspNetCoreBuilder.cs index fa4230a29..26f8485f9 100644 --- a/Kudu.Core/Deployment/Generator/AspNetCoreBuilder.cs +++ b/Kudu.Core/Deployment/Generator/AspNetCoreBuilder.cs @@ -23,11 +23,13 @@ protected override string ScriptGeneratorCommandArguments if (string.IsNullOrEmpty(_solutionPath)) { - return $"--aspNetCore \"{Path.GetDirectoryName(_projectPath)}\""; + return $"--aspNetCore \"{_projectPath}\""; + // projectfile is either project.json for preview2, ***.csproj for preview3 } else { - return $"--aspNetCore \"{Path.GetDirectoryName(_projectPath)}\" --solutionFile {_solutionPath}"; + return $"--aspNetCore \"{_projectPath}\" --solutionFile \"{_solutionPath}\""; + // if we have a solution file, projectfile is either ***.xproj for preview2, ***.csproj for preview3 } } } diff --git a/Kudu.Core/Deployment/Generator/SiteBuilderFactory.cs b/Kudu.Core/Deployment/Generator/SiteBuilderFactory.cs index c1a1d6c89..6e7adbb68 100644 --- a/Kudu.Core/Deployment/Generator/SiteBuilderFactory.cs +++ b/Kudu.Core/Deployment/Generator/SiteBuilderFactory.cs @@ -188,6 +188,13 @@ private ISiteBuilder ResolveProject(string repositoryRoot, string targetPath, ID { if (DeploymentHelper.IsProject(targetPath)) { + // needs to check for project file existence + if (!File.Exists(targetPath)) + { + throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, + Resources.Error_ProjectDoesNotExist, + targetPath)); + } return DetermineProject(repositoryRoot, targetPath, perDeploymentSettings, fileFinder); } @@ -204,7 +211,7 @@ private ISiteBuilder ResolveProject(string repositoryRoot, string targetPath, ID { return DetermineProject(repositoryRoot, projects[0], perDeploymentSettings, fileFinder); } - + // Check for ASP.NET Core project without VS solution or project string projectJson; if (AspNetCoreHelper.TryAspNetCoreWebProject(targetPath, fileFinder, out projectJson)) @@ -254,41 +261,41 @@ private ISiteBuilder ResolveProject(string repositoryRoot, string targetPath, ID private ISiteBuilder DetermineProject(string repositoryRoot, string targetPath, IDeploymentSettingsManager perDeploymentSettings, IFileFinder fileFinder) { - if (!DeploymentHelper.IsDeployableProject(targetPath)) + var solution = VsHelper.FindContainingSolution(repositoryRoot, targetPath, fileFinder); + string solutionPath = solution?.Path; + var projectTypeGuids = VsHelper.GetProjectTypeGuids(targetPath); + if (VsHelper.IsWap(projectTypeGuids)) { - throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, - Resources.Error_ProjectNotDeployable, - targetPath)); + return new WapBuilder(_environment, + perDeploymentSettings, + _propertyProvider, + repositoryRoot, + targetPath, + solutionPath); } - else if (File.Exists(targetPath)) // TODO: what is this if about? + else if (AspNetCoreHelper.IsDotnetCorePreview3(targetPath, projectTypeGuids) || targetPath.EndsWith(".xproj", StringComparison.OrdinalIgnoreCase)) { - var solution = VsHelper.FindContainingSolution(repositoryRoot, targetPath, fileFinder); - string solutionPath = solution != null ? solution.Path : null; - - if (VsHelper.IsWap(targetPath)) - { - return new WapBuilder(_environment, - perDeploymentSettings, - _propertyProvider, - repositoryRoot, - targetPath, - solutionPath); - } - else - { - // This is a console app - return new DotNetConsoleBuilder(_environment, - perDeploymentSettings, - _propertyProvider, - repositoryRoot, - targetPath, - solutionPath); - } + return new AspNetCoreBuilder(_environment, + perDeploymentSettings, + _propertyProvider, + repositoryRoot, + targetPath, + solutionPath); + } + else if (VsHelper.IsExecutableProject(targetPath)) + { + // This is a console app + return new DotNetConsoleBuilder(_environment, + perDeploymentSettings, + _propertyProvider, + repositoryRoot, + targetPath, + solutionPath); } throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, - Resources.Error_ProjectDoesNotExist, - targetPath)); + Resources.Error_ProjectNotDeployable, + targetPath)); } private static void ThrowAmbiguousSolutionsError(IList solutions) diff --git a/Kudu.Core/Functions/FunctionManager.cs b/Kudu.Core/Functions/FunctionManager.cs index ad7a54af2..04c69d7ee 100644 --- a/Kudu.Core/Functions/FunctionManager.cs +++ b/Kudu.Core/Functions/FunctionManager.cs @@ -227,8 +227,9 @@ private async Task GetKeyObjectFromFile(string name, IKeyJsonOps keyOp) } return keyOp.GenerateKeyObject(key, name); } - catch (Exception) + catch (IOException) { + // don't throw exception if the file already existed // fallback to read key files } } diff --git a/Kudu.Core/Infrastructure/AspNetCoreHelper.cs b/Kudu.Core/Infrastructure/AspNetCoreHelper.cs index 127431344..a07bf58cd 100644 --- a/Kudu.Core/Infrastructure/AspNetCoreHelper.cs +++ b/Kudu.Core/Infrastructure/AspNetCoreHelper.cs @@ -4,6 +4,7 @@ using Kudu.Core.Deployment; using Newtonsoft.Json.Linq; using Kudu.Core.SourceControl; +using System.Collections.Generic; namespace Kudu.Core.Infrastructure { @@ -12,9 +13,9 @@ internal static class AspNetCoreHelper private const string ProjectJson = "project.json"; public static readonly string[] ProjectJsonLookupList = new string[] { $"*{ProjectJson}" }; - public static bool IsWebApplicationProjectJsonFile(string projectJsonPath) + public static bool IsWebApplicationProjectFile(string projectFilePath) { - var projectDirectory = Path.GetDirectoryName(projectJsonPath); + var projectDirectory = Path.GetDirectoryName(projectFilePath); var webConfig = Path.Combine(projectDirectory, "web.config"); var wwwrootDirectory = Path.Combine(projectDirectory, "wwwroot"); @@ -27,7 +28,7 @@ public static bool TryAspNetCoreWebProject(string rootPath, IFileFinder fileFind projectJsonPath = null; var projectJsonFiles = fileFinder.ListFiles(rootPath, SearchOption.AllDirectories, ProjectJsonLookupList) .Where(path => Path.GetFileName(path).Equals(ProjectJson, StringComparison.OrdinalIgnoreCase)) - .Where(IsWebApplicationProjectJsonFile) + .Where(IsWebApplicationProjectFile) .ToList(); if (projectJsonFiles.Any()) @@ -38,5 +39,11 @@ public static bool TryAspNetCoreWebProject(string rootPath, IFileFinder fileFind return false; } + + public static bool IsDotnetCorePreview3(string projectPath, IEnumerable projectTypeGuids) + { + // we need to verify suffix is csproj, xproj will not have projectTypeGuids either + return projectPath.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) && !projectTypeGuids.Any() && IsWebApplicationProjectFile(projectPath); + } } } diff --git a/Kudu.Core/Infrastructure/VsHelper.cs b/Kudu.Core/Infrastructure/VsHelper.cs index 08affd107..55761efe7 100644 --- a/Kudu.Core/Infrastructure/VsHelper.cs +++ b/Kudu.Core/Infrastructure/VsHelper.cs @@ -65,12 +65,7 @@ public static VsSolution FindContainingSolution(string repositoryPath, string ta return solutions[0]; } - - public static bool IsWap(string projectPath) - { - return IsWap(GetProjectTypeGuids(projectPath)); - } - + public static bool IsWap(IEnumerable projectTypeGuids) { return projectTypeGuids.Contains(_wapGuid); @@ -87,7 +82,6 @@ public static IEnumerable GetProjectTypeGuids(string path) select new Guid(guid.Trim('{', '}')); return guids; } - public static bool IsExecutableProject(string projectPath) { var document = XDocument.Parse(File.ReadAllText(projectPath)); diff --git a/Kudu.Core/Infrastructure/VsSolutionProject.cs b/Kudu.Core/Infrastructure/VsSolutionProject.cs index 9cfbcdfda..a1c0b4228 100644 --- a/Kudu.Core/Infrastructure/VsSolutionProject.cs +++ b/Kudu.Core/Infrastructure/VsSolutionProject.cs @@ -150,24 +150,28 @@ private void EnsureProperties() } _absolutePath = Path.Combine(Path.GetDirectoryName(_solutionPath), relativePath); - - if (projectType == SolutionProjectType.KnownToBeMSBuildFormat && File.Exists(_absolutePath)) + // KnownToBeMSBuildFormat: C#, VB, and VJ# projects + // check project extension since Common Project System is not in KnowToBeMSBuildFormat yet + if (((projectType == SolutionProjectType.KnownToBeMSBuildFormat) || projectExtension.Equals(".csproj", StringComparison.OrdinalIgnoreCase)) && File.Exists(_absolutePath)) { - // If the project is an msbuild project then extra the project type guids + // If the project is a msbuild project then extract the project type guids _projectTypeGuids = VsHelper.GetProjectTypeGuids(_absolutePath); // Check if it's a wap _isWap = VsHelper.IsWap(_projectTypeGuids); + // FIXME, checking for projectExtension two times + _isAspNetCore = AspNetCoreHelper.IsDotnetCorePreview3(_absolutePath, _projectTypeGuids); + _isExecutable = VsHelper.IsExecutableProject(_absolutePath); } else if (projectExtension.Equals(".xproj", StringComparison.OrdinalIgnoreCase) && File.Exists(_absolutePath)) { var projectPath = Path.Combine(Path.GetDirectoryName(_absolutePath), "project.json"); - if (AspNetCoreHelper.IsWebApplicationProjectJsonFile(projectPath)) + if (AspNetCoreHelper.IsWebApplicationProjectFile(projectPath)) { _isAspNetCore = true; - _absolutePath = projectPath; + // _absolutePath = projectPath; _absolutePath is now xproj } _projectTypeGuids = Enumerable.Empty(); } diff --git a/Kudu.Services.Web/updateNodeModules.cmd b/Kudu.Services.Web/updateNodeModules.cmd index 9f39279d2..27afea986 100644 --- a/Kudu.Services.Web/updateNodeModules.cmd +++ b/Kudu.Services.Web/updateNodeModules.cmd @@ -10,7 +10,7 @@ set counter=0 set /a counter+=1 echo Attempt %counter% out of %attempts% -cmd /c npm install https://github.com/projectkudu/KuduScript/tarball/55afbed5c9d5fca443b24369fa086ef3a7d51fca +cmd /c npm install https://github.com/projectkudu/KuduScript/tarball/3bdda1b270f5e468f0de3f47a61490179288d8d9 IF %ERRORLEVEL% NEQ 0 goto error goto end