diff --git a/Razor.sln b/Razor.sln index 148df2a733..26af208252 100644 --- a/Razor.sln +++ b/Razor.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.21005.1 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Razor", "src\Microsoft.AspNet.Razor\Microsoft.AspNet.Razor.csproj", "{E75D8296-3BA6-4E67-AFEB-90FF77460B15}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{92463391-81BE-462B-AC3C-78C6C760741F}" @@ -13,16 +11,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Razor.Test EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.TestCommon", "test\Microsoft.TestCommon\Microsoft.TestCommon.csproj", "{FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Razor.net45", "src\Microsoft.AspNet.Razor\Microsoft.AspNet.Razor.net45.csproj", "{8B129FF9-0B8F-4E0C-8DFC-0137D8550FB7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Razor.k10", "src\Microsoft.AspNet.Razor\Microsoft.AspNet.Razor.k10.csproj", "{F5A44105-08E2-4602-8231-DAFDDC9A146E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E75D8296-3BA6-4E67-AFEB-90FF77460B15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E75D8296-3BA6-4E67-AFEB-90FF77460B15}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E75D8296-3BA6-4E67-AFEB-90FF77460B15}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E75D8296-3BA6-4E67-AFEB-90FF77460B15}.Release|Any CPU.Build.0 = Release|Any CPU {0BB62A1D-E6B5-49FA-9E3C-6AF679A66DFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0BB62A1D-E6B5-49FA-9E3C-6AF679A66DFE}.Debug|Any CPU.Build.0 = Debug|Any CPU {0BB62A1D-E6B5-49FA-9E3C-6AF679A66DFE}.Release|Any CPU.ActiveCfg = Debug|Any CPU @@ -31,12 +29,21 @@ Global {FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}.Release|Any CPU.ActiveCfg = Debug|Any CPU {FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}.Release|Any CPU.Build.0 = Debug|Any CPU + {8B129FF9-0B8F-4E0C-8DFC-0137D8550FB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B129FF9-0B8F-4E0C-8DFC-0137D8550FB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B129FF9-0B8F-4E0C-8DFC-0137D8550FB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B129FF9-0B8F-4E0C-8DFC-0137D8550FB7}.Release|Any CPU.Build.0 = Release|Any CPU + {F5A44105-08E2-4602-8231-DAFDDC9A146E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5A44105-08E2-4602-8231-DAFDDC9A146E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5A44105-08E2-4602-8231-DAFDDC9A146E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5A44105-08E2-4602-8231-DAFDDC9A146E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {E75D8296-3BA6-4E67-AFEB-90FF77460B15} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} + {8B129FF9-0B8F-4E0C-8DFC-0137D8550FB7} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} + {F5A44105-08E2-4602-8231-DAFDDC9A146E} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED} {0BB62A1D-E6B5-49FA-9E3C-6AF679A66DFE} = {92463391-81BE-462B-AC3C-78C6C760741F} {FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0} = {92463391-81BE-462B-AC3C-78C6C760741F} EndGlobalSection diff --git a/build/_git-clone.shade b/build/_git-clone.shade new file mode 100644 index 0000000000..32355ab5a3 --- /dev/null +++ b/build/_git-clone.shade @@ -0,0 +1,9 @@ + + + +default gitBranch='' + +var gitCommand='clone ${gitUri}' +set gitCommand='${gitCommand} --branch ${gitBranch}' if='!string.IsNullOrEmpty(gitBranch)' + +git diff --git a/build/_git-pull.shade b/build/_git-pull.shade new file mode 100644 index 0000000000..1e7971020f --- /dev/null +++ b/build/_git-pull.shade @@ -0,0 +1,8 @@ + + +default gitBranch='' + +var gitCommand='pull ${gitUri}' +set gitCommand='${gitCommand} ${gitBranch}' if='!string.IsNullOrEmpty(gitBranch)' + +git diff --git a/build/_git.shade b/build/_git.shade new file mode 100644 index 0000000000..7495a598bb --- /dev/null +++ b/build/_git.shade @@ -0,0 +1,5 @@ + +default gitFolder='' + +exec program='git' commandline='${gitCommand}' workingdir='${gitFolder}' + diff --git a/build/_k-generate-projects.shade b/build/_k-generate-projects.shade new file mode 100644 index 0000000000..01af0cd018 --- /dev/null +++ b/build/_k-generate-projects.shade @@ -0,0 +1,330 @@ +use namespace="System" +use namespace="System.Collections.Generic" +use namespace="System.IO" +use namespace="System.Linq" +use namespace="System.Reflection" +use namespace="System.Text" +use namespace="System.Web.Script.Serialization" +use namespace="System.Xml.Linq" + +use assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" + +@{/* + +k-generate-projects + Generate csproj files from project.json + +solutionPath='' + Required. Path to the solution directory + +*/} + +content var='net45' include href='net45.txt' +content var='k10' include href='k10.txt' + +@{ + ProjectGenerator.Logger = Log; + + var templates = new Dictionary { + { "net45", net45 }, + { "k10", k10 } + }; + + ProjectGenerator.MakeProjects(solutionPath, templates); +} + +functions + @{ + class ProjectGenerator + { + public static Sake.Engine.Logging.ILog Logger { get; set; } + + static void Log(string message, params object[] args) + { + Logger.Info(String.Format(message, args)); + } + + static void Warn(string message, params object[] args) + { + Logger.Warn(String.Format(message, args)); + } + + public static void MakeProjects(string solutionPath, IDictionary templates) + { + var jsonFiles = GetJsonFiles(solutionPath); + var projectMapping = GetProjectMapping(solutionPath, jsonFiles); + + Log("Found {0} projects", jsonFiles.Length); + + foreach (var p in jsonFiles) + { + Log(p); + } + + foreach (var path in jsonFiles) + { + ProduceProjectFilesForProject(path, projectMapping, templates); + } + } + + private static string[] GetJsonFiles(string solutionPath) + { + Func getFiles = dir => + { + string path = Path.Combine(solutionPath, dir); + + if (!Directory.Exists(path)) + { + return new string[0]; + } + + return Directory.GetFiles(path, "project.json", SearchOption.AllDirectories); + }; + + return getFiles("src").Concat(getFiles("samples")) + .Concat(getFiles("test")) + .ToArray(); + } + + private static IDictionary GetProjectMapping(string solutionPath, string[] jsonFiles) + { + var dict = new Dictionary(); + + foreach (var path in jsonFiles) + { + string projectDir = Path.GetDirectoryName(path); + string projectName = projectDir.Substring(Path.GetDirectoryName(projectDir).Length).Trim(Path.DirectorySeparatorChar); + + // { + // "p1" : { "net45" : "id", "k10" : "pid1", path: "src\p1" }, + // "p2" : { "net45" : "id", "k10" : "pid2", path: "src\p2" } + // } + // + + string net45Project = Path.Combine(projectDir, GetProjectFileName(projectName, "net45")); + string k10Project = Path.Combine(projectDir, GetProjectFileName(projectName, "k10")); + + var configs = new Dictionary(); + configs["net45"] = GetProjectGuidFromFileOrCreateNew(net45Project); + configs["k10"] = GetProjectGuidFromFileOrCreateNew(k10Project); + configs["path"] = Path.GetDirectoryName(path.Substring(solutionPath.Length).TrimStart(Path.DirectorySeparatorChar)); + + dict[projectName] = configs; + } + + return dict; + } + + private static string GetProjectGuidFromFileOrCreateNew(string projectPath) + { + if (!File.Exists(projectPath)) + { + return Guid.NewGuid().ToString().ToUpper(); + } + + var projectGuid = XDocument.Parse(File.ReadAllText(projectPath)) + .Descendants() + .FirstOrDefault(e => e.Name.LocalName.Equals("ProjectGuid")); + + if (projectGuid == null) + { + return Guid.NewGuid().ToString(); + } + + return projectGuid.Value.Trim((char)'{', (char)'}'); + } + + private static void ProduceProjectFilesForProject(string jsonPath, + IDictionary projectMapping, + IDictionary templates) + { + var serializer = new JavaScriptSerializer(); + + string projectDir = Path.GetDirectoryName(jsonPath); + string projectName = projectDir.Substring(Path.GetDirectoryName(projectDir).Length).Trim(Path.DirectorySeparatorChar); + + Log("Generated projects for {0}", projectName); + + var jsonText = File.ReadAllText(jsonPath); + + var d = serializer.DeserializeObject(jsonText) as IDictionary; + var configs = GetObject(d, "configurations"); + var references = GetObject(d, "dependencies") ?? new Dictionary(); + + // Get the list of files + var filesString = String.Join(Environment.NewLine, + Directory.GetFiles(projectDir, "*.cs", SearchOption.AllDirectories) + .Select(p => p.Substring(projectDir.Length).Trim(Path.DirectorySeparatorChar)) + .Where(p => !p.StartsWith("obj")) + .Select(p => String.Format( + @"", p))); + + // Add the config file if it's there + if (File.Exists(Path.Combine(projectDir, "packages.config"))) + { + filesString += ""; + } + + var packageReferences = references.Where(r => !String.IsNullOrEmpty((string)r.Value)) + .ToDictionary(k => k.Key, k => (string)k.Value); + + var projectReferences = references.Where(r => String.IsNullOrEmpty((string)r.Value)) + .Select(r => r.Key) + .ToArray(); + + + // HACK: Assume the packages folder is 2 up from the projectDir + string packagesDir = Path.GetFullPath(Path.Combine(projectDir, "..", "..", "packages")); + + foreach (var targetFramework in configs.Keys) + { + string id = (string)GetObject(projectMapping, projectName)[targetFramework]; + + var template = templates[targetFramework] + .Replace("{ProjectGuid}", id) + .Replace("{Name}", projectName) + .Replace("{Files}", filesString) + .Replace("{ProjectReferences}", BuildProjectReferences(projectReferences, targetFramework, projectMapping)) + .Replace("{References}", BuildReferences(packageReferences, packagesDir, targetFramework, GetCandidates(targetFramework))); + + if (targetFramework.StartsWith("k")) + { + template = template.Replace("{CSharpTargetsPath}", GetProjectKTargets(packagesDir)); + } + + string output = Path.Combine(projectDir, GetProjectFileName(projectName, targetFramework)); + + Log("Generated {0}", output); + + File.WriteAllText(output, template); + } + } + + private static string GetProjectKTargets(string packagesDir) + { + var projectK = Directory.GetDirectories(packagesDir, "ProjectK*") + .Select(p => new { Path = p, Build = Int32.Parse(p.Substring(p.LastIndexOf('-') + 1)) }) + .OrderByDescending(p => p.Build) + .FirstOrDefault(); + + if (projectK == null) + { + Warn("Project K targets aren't installed"); + return ""; + } + + return Path.Combine("..", "..", projectK.Path.Substring(projectK.Path.IndexOf("packages")), "Framework\\K\\v1.0\\ProjectK.CSharp.targets"); + } + + private static string GetProjectFileName(string projectName, string config) + { + return projectName + "." + config + ".csproj"; + } + + private static string BuildProjectReferences(string[] projectReferences, string config, IDictionary projectMapping) + { + if (projectReferences.Length == 0) + { + return ""; + } + + var sb = new StringBuilder(); + + foreach (var reference in projectReferences) + { + var info = GetObject(projectMapping, reference); + + if (info == null) + { + Warn("No project reference found for {0}", reference); + continue; + } + + string projectFileName = GetProjectFileName(reference, config); + string path = Path.Combine((string)info["path"], projectFileName); + + sb.AppendFormat(@" + {{{1}}} + {2} + ", path, info[config], reference); + } + + return sb.ToString(); + } + + private static string[] GetCandidates(string config) + { + if (config == "net45") + { + return new[] { "net45", "net40", "net35", "net20" }; + } + + return new[] { config }; + } + + private static string BuildReferences(IDictionary references, string packagesDir, string configName, string[] candidates) + { + if (references.Count == 0) + { + return ""; + } + + Log("Building package references for {0}", configName); + + var sb = new StringBuilder(); + + foreach (var reference in references) + { + var version = (string)reference.Value; + + string pattern = version.IndexOf("*") != -1 ? reference.Key + "*" : reference.Key + "." + reference.Value; + + var packageDir = Directory.GetDirectories(packagesDir, pattern).FirstOrDefault(); + + if (packageDir == null) + { + Warn(reference.Key + " = " + version + " ==> UNRESOLVED"); + continue; + } + + Log(reference.Key + " = " + version + " ==> " + packageDir); + + var candidate = candidates.Select(c => Path.Combine(packageDir, "lib", c)) + .FirstOrDefault(Directory.Exists); + + if (candidate == null) + { + Warn("Unable to find package reference for {0}, target framework = {1}", reference.Key, configName); + continue; + } + + var dlls = Directory.EnumerateFiles(candidate, "*.dll") + .Distinct() + .Where(File.Exists) + .ToList(); + + foreach (var dllPath in dlls) + { + sb.AppendFormat(@" + + False + ..\..\{1} + ", AssemblyName.GetAssemblyName(dllPath).FullName, dllPath.Substring(dllPath.IndexOf("packages"))); + } + } + + return sb.ToString(); + } + + private static IDictionary GetObject(IDictionary obj, string key) + { + object value; + if (obj.TryGetValue(key, out value)) + { + return value as IDictionary; + } + + return null; + } + } + } diff --git a/build/_k-standard-goals.shade b/build/_k-standard-goals.shade index 92dd803eb8..b6a38ff7dd 100644 --- a/build/_k-standard-goals.shade +++ b/build/_k-standard-goals.shade @@ -13,6 +13,7 @@ default TEST_DIR='${Path.Combine(TARGET_DIR, "test")}' #target-default target='default' k-restore + k-generate-projects solutionPath='${BASE_DIR}' #target-dir-clean target='clean' directory delete="${TARGET_DIR}" diff --git a/build/k10.txt b/build/k10.txt new file mode 100644 index 0000000000..60c669f855 --- /dev/null +++ b/build/k10.txt @@ -0,0 +1,50 @@ + + + + + Debug + AnyCPU + {{ProjectGuid}} + Library + Properties + {Name} + {Name} + v4.5 + 512 + obj/K + + + AnyCPU + true + full + false + bin\Debug\K + DEBUG;TRACE;K10 + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\K + TRACE;K10 + prompt + 4 + + + {Files} + + + + {ProjectReferences} + + + + \ No newline at end of file diff --git a/build/net45.txt b/build/net45.txt new file mode 100644 index 0000000000..8d2e271f7b --- /dev/null +++ b/build/net45.txt @@ -0,0 +1,57 @@ + + + + + Debug + AnyCPU + {{ProjectGuid}} + Library + Properties + {Name} + {Name} + v4.5 + 512 + obj/net45 + + + AnyCPU + true + full + false + bin\Debug\net45 + DEBUG;TRACE;NET45 + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\net45 + TRACE;NET45 + prompt + 4 + + + + + + + {References} + + + {Files} + + + + {ProjectReferences} + + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.csproj b/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.csproj deleted file mode 100644 index 201f80430f..0000000000 --- a/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.csproj +++ /dev/null @@ -1,210 +0,0 @@ - - - - - Debug - AnyCPU - {E75D8296-3BA6-4E67-AFEB-90FF77460B15} - Library - Properties - Microsoft.AspNet.Razor - Microsoft.AspNet.Razor - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - True - True - CommonResources.resx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - RazorResources.resx - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ResXFileCodeGenerator - CommonResources.Designer.cs - - - ResXFileCodeGenerator - RazorResources.Designer.cs - Designer - - - - - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.k10.csproj b/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.k10.csproj new file mode 100644 index 0000000000..b6e8e2fcd2 --- /dev/null +++ b/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.k10.csproj @@ -0,0 +1,194 @@ + + + + + Debug + AnyCPU + {F5A44105-08E2-4602-8231-DAFDDC9A146E} + Library + Properties + Microsoft.AspNet.Razor + Microsoft.AspNet.Razor + v4.5 + 512 + obj/K + + + AnyCPU + true + full + false + bin\Debug\K + DEBUG;TRACE;K10 + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\K + TRACE;K10 + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.net45.csproj b/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.net45.csproj new file mode 100644 index 0000000000..b852cc4e73 --- /dev/null +++ b/src/Microsoft.AspNet.Razor/Microsoft.AspNet.Razor.net45.csproj @@ -0,0 +1,201 @@ + + + + + Debug + AnyCPU + {8B129FF9-0B8F-4E0C-8DFC-0137D8550FB7} + Library + Properties + Microsoft.AspNet.Razor + Microsoft.AspNet.Razor + v4.5 + 512 + obj/net45 + + + AnyCPU + true + full + false + bin\Debug\net45 + DEBUG;TRACE;NET45 + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\net45 + TRACE;NET45 + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Razor.Test/Microsoft.AspNet.Razor.Test.csproj b/test/Microsoft.AspNet.Razor.Test/Microsoft.AspNet.Razor.Test.csproj index a04a33cb04..d72552a832 100644 --- a/test/Microsoft.AspNet.Razor.Test/Microsoft.AspNet.Razor.Test.csproj +++ b/test/Microsoft.AspNet.Razor.Test/Microsoft.AspNet.Razor.Test.csproj @@ -213,9 +213,9 @@ - - {e75d8296-3ba6-4e67-afeb-90ff77460b15} - Microsoft.AspNet.Razor + + {8b129ff9-0b8f-4e0c-8dfc-0137d8550fb7} + Microsoft.AspNet.Razor.net45 {FCCC4CB7-BAF7-4A57-9F89-E5766FE536C0}