Removing support for csproj generation as part of build
* Removing 'watch' target since it's no longer useful
This commit is contained in:
parent
6ecabcf644
commit
6c6e474db1
|
|
@ -1,122 +0,0 @@
|
||||||
use namespace="System.Collections.Concurrent"
|
|
||||||
|
|
||||||
functions
|
|
||||||
@{
|
|
||||||
public class FileWatcher
|
|
||||||
{
|
|
||||||
private readonly HashSet<string> _files = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
private readonly ConcurrentDictionary<string, HashSet<string>> _directories = new ConcurrentDictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
private readonly FileSystemWatcher _watcher;
|
|
||||||
|
|
||||||
public FileWatcher(string path)
|
|
||||||
{
|
|
||||||
_watcher = new FileSystemWatcher(path);
|
|
||||||
_watcher.IncludeSubdirectories = true;
|
|
||||||
_watcher.EnableRaisingEvents = true;
|
|
||||||
|
|
||||||
_watcher.Changed += OnWatcherChanged;
|
|
||||||
_watcher.Renamed += OnRenamed;
|
|
||||||
_watcher.Deleted += OnWatcherChanged;
|
|
||||||
_watcher.Created += OnWatcherChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
public event Action<string> OnChanged;
|
|
||||||
|
|
||||||
public void WatchDirectory(string path, string extension)
|
|
||||||
{
|
|
||||||
var extensions = _directories.GetOrAdd(path, _ => new HashSet<string>(StringComparer.OrdinalIgnoreCase));
|
|
||||||
|
|
||||||
extensions.Add(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool WatchFile(string path)
|
|
||||||
{
|
|
||||||
return _files.Add(path);
|
|
||||||
}
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_watcher.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ReportChange(string newPath, WatcherChangeTypes changeType)
|
|
||||||
{
|
|
||||||
return ReportChange(oldPath: null, newPath: newPath, changeType: changeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ReportChange(string oldPath, string newPath, WatcherChangeTypes changeType)
|
|
||||||
{
|
|
||||||
if (HasChanged(oldPath, newPath, changeType))
|
|
||||||
{
|
|
||||||
if (oldPath != null)
|
|
||||||
{
|
|
||||||
Trace.TraceInformation("{0} -> {1}", oldPath, newPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Trace.TraceInformation("{0} -> {1}", changeType, newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OnChanged != null)
|
|
||||||
{
|
|
||||||
OnChanged(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnRenamed(object sender, RenamedEventArgs e)
|
|
||||||
{
|
|
||||||
ReportChange(e.OldFullPath, e.FullPath, e.ChangeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnWatcherChanged(object sender, FileSystemEventArgs e)
|
|
||||||
{
|
|
||||||
ReportChange(e.FullPath, e.ChangeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HasChanged(string oldPath, string newPath, WatcherChangeTypes changeType)
|
|
||||||
{
|
|
||||||
// File changes
|
|
||||||
if (_files.Contains(newPath) ||
|
|
||||||
(oldPath != null && _files.Contains(oldPath)))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashSet<string> extensions;
|
|
||||||
if (_directories.TryGetValue(newPath, out extensions) ||
|
|
||||||
_directories.TryGetValue(Path.GetDirectoryName(newPath), out extensions))
|
|
||||||
{
|
|
||||||
string extension = Path.GetExtension(newPath);
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(extension))
|
|
||||||
{
|
|
||||||
// Assume it's a directory
|
|
||||||
if (changeType == WatcherChangeTypes.Created ||
|
|
||||||
changeType == WatcherChangeTypes.Renamed)
|
|
||||||
{
|
|
||||||
foreach (var e in extensions)
|
|
||||||
{
|
|
||||||
WatchDirectory(newPath, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(changeType == WatcherChangeTypes.Deleted)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore anything else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return extensions.Contains(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
|
|
||||||
<Import Project="ProjectK.Common.props" />
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.Targets" />
|
|
||||||
<Import Project="ProjectK.Common.targets" />
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<!-- Currently we force these to override what's in the project file, but by the time
|
|
||||||
we ship, they should respect user settings -->
|
|
||||||
<TargetFrameworkIdentifier>.NETServer</TargetFrameworkIdentifier>
|
|
||||||
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
|
|
||||||
<TargetFrameworkProfile></TargetFrameworkProfile>
|
|
||||||
|
|
||||||
<TargetFrameworkMonikerDisplayName>.NET for Server</TargetFrameworkMonikerDisplayName>
|
|
||||||
|
|
||||||
<!-- Temporary until we are installed on the box under Reference Assemblies -->
|
|
||||||
<TargetFrameworkRootPath>$(MSBuildThisFileDirectory)</TargetFrameworkRootPath>
|
|
||||||
<FrameworkPathOverride>$(TargetFrameworkRootPath)</FrameworkPathOverride>
|
|
||||||
<_FullFrameworkReferenceAssemblyPaths>$(FrameworkPathOverride)</_FullFrameworkReferenceAssemblyPaths>
|
|
||||||
<_TargetFrameworkDirectories>$(FrameworkPathOverride)</_TargetFrameworkDirectories>
|
|
||||||
<NoStdLib>true</NoStdLib>
|
|
||||||
|
|
||||||
<!-- Automatically reference all assemblies in the target framework -->
|
|
||||||
<ImplicitlyExpandTargetFramework Condition="'$(ImplicitlyExpandTargetFramework)' == '' ">true</ImplicitlyExpandTargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<!-- Redefine AssemblySearchPaths to exclude {AssemblyFolders} and {GAC}, these represent .NET-specific locations -->
|
|
||||||
<PropertyGroup>
|
|
||||||
<AssemblySearchPaths Condition="'$(AssemblySearchPaths)' == ''">
|
|
||||||
{CandidateAssemblyFiles};
|
|
||||||
$(ReferencePath);
|
|
||||||
{HintPathFromItem};
|
|
||||||
{TargetFrameworkDirectory};
|
|
||||||
{Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
|
|
||||||
{RawFileName};
|
|
||||||
$(OutDir)
|
|
||||||
</AssemblySearchPaths>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The ImplicitlyExpandTargetFramework target will expand all
|
|
||||||
of the dll reference assemblies in the TargetFrameworkDirectory
|
|
||||||
for the project and place the items into the ReferencePath itemgroup
|
|
||||||
which contains resolved items.
|
|
||||||
-->
|
|
||||||
<PropertyGroup>
|
|
||||||
<ResolveReferencesDependsOn>
|
|
||||||
$(ResolveReferencesDependsOn);
|
|
||||||
ImplicitlyExpandTargetFramework;
|
|
||||||
</ResolveReferencesDependsOn>
|
|
||||||
|
|
||||||
<ImplicitlyExpandTargetFrameworkDependsOn>
|
|
||||||
$(ImplicitlyExpandTargetFrameworkDependsOn);
|
|
||||||
GetReferenceAssemblyPaths
|
|
||||||
</ImplicitlyExpandTargetFrameworkDependsOn>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Target Name="ImplicitlyExpandTargetFramework"
|
|
||||||
Condition="'$(ImplicitlyExpandTargetFramework)' == 'true'"
|
|
||||||
DependsOnTargets="$(ImplicitlyExpandTargetFrameworkDependsOn)"
|
|
||||||
>
|
|
||||||
<ItemGroup>
|
|
||||||
<ReferenceAssemblyPaths Include="$(_TargetFrameworkDirectories)"/>
|
|
||||||
<ReferencePath Include="%(ReferenceAssemblyPaths.Identity)*.dll">
|
|
||||||
<WinMDFile>false</WinMDFile>
|
|
||||||
<CopyLocal>false</CopyLocal>
|
|
||||||
<ReferenceGroupingDisplayName>$(TargetFrameworkMonikerDisplayName)</ReferenceGroupingDisplayName>
|
|
||||||
<ReferenceGrouping>$(TargetFrameworkIdentifier),$(TargetFrameworkVersion)</ReferenceGrouping>
|
|
||||||
<ResolvedFrom>ImplicitlyExpandTargetFramework</ResolvedFrom>
|
|
||||||
<IsSystemReference>True</IsSystemReference>
|
|
||||||
</ReferencePath>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Message Importance="Low" Text="TargetMonikerDisplayName: $(TargetFrameworkMonikerDisplayName) ReferenceAssemblyPaths: @(ReferenceAssemblyPaths)"/>
|
|
||||||
|
|
||||||
<Message Importance="Low" Text="Including @(ReferencePath)"
|
|
||||||
Condition="'%(ReferencePath.ResolvedFrom)' == 'ImplicitlyExpandTargetFramework'"/>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<_ResolveAssemblyReferenceResolvedFiles Include="@(ReferencePath)"
|
|
||||||
Condition="'%(ReferencePath.ResolvedFrom)' == 'ImplicitlyExpandTargetFramework'"/>
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,703 +0,0 @@
|
||||||
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 import="Files"
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
skipNet45='false'
|
|
||||||
Optional. Skip net45 project regeneration
|
|
||||||
|
|
||||||
*/}
|
|
||||||
|
|
||||||
content var='web' include href='web.txt'
|
|
||||||
content var='net45' include href='net45.txt'
|
|
||||||
content var='k10' include href='k10.txt'
|
|
||||||
|
|
||||||
default skipNet45='${false}'
|
|
||||||
|
|
||||||
@{
|
|
||||||
ProjectGenerator.Logger = Log;
|
|
||||||
ProjectGenerator.FilesAccessor = ()=> Files;
|
|
||||||
|
|
||||||
var templates = new Dictionary<string, string> {
|
|
||||||
{ "net45", net45 },
|
|
||||||
{ "net451", net45 },
|
|
||||||
{ "k10", k10 },
|
|
||||||
{ "web", web }
|
|
||||||
};
|
|
||||||
|
|
||||||
if(skipNet45)
|
|
||||||
{
|
|
||||||
templates.Remove("net45");
|
|
||||||
templates.Remove("net451");
|
|
||||||
}
|
|
||||||
|
|
||||||
ProjectGenerator.MakeProjects(solutionPath, templates);
|
|
||||||
}
|
|
||||||
|
|
||||||
functions
|
|
||||||
@{
|
|
||||||
class ProjectGenerator
|
|
||||||
{
|
|
||||||
public static Sake.Engine.Logging.ILog Logger { get; set; }
|
|
||||||
|
|
||||||
public static _Files Files { get { return FilesAccessor(); } }
|
|
||||||
|
|
||||||
public static Func<_Files> FilesAccessor { 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<string, string> 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<string, string[]> 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<string, object> GetProjectMapping(string solutionPath, string[] jsonFiles)
|
|
||||||
{
|
|
||||||
var solutionProjects = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
foreach (var solutionFile in Directory.GetFiles(solutionPath, "*.sln"))
|
|
||||||
{
|
|
||||||
foreach (var line in File.ReadAllLines(solutionFile))
|
|
||||||
{
|
|
||||||
if (!line.StartsWith("Project", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var eq = line.IndexOf('=');
|
|
||||||
|
|
||||||
if (eq == -1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var parts = line.Substring(eq + 1).Trim().Split((char)',')
|
|
||||||
.Select(p => p.Trim().Trim((char)'"'))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (parts.Count != 3)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
string name = parts[0];
|
|
||||||
string path = Path.Combine(solutionPath, parts[1]);
|
|
||||||
string guid = parts[2].Trim((char)'{', (char)'}');
|
|
||||||
|
|
||||||
solutionProjects[path] = guid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var dict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
foreach (var path in jsonFiles)
|
|
||||||
{
|
|
||||||
string projectDir = Path.GetDirectoryName(path);
|
|
||||||
string projectName = projectDir.Substring(Path.GetDirectoryName(projectDir).Length).Trim(Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
string net45Project = Path.Combine(projectDir, GetProjectFileName(projectName, "net45"));
|
|
||||||
string net451Project = Path.Combine(projectDir, GetProjectFileName(projectName, "net451"));
|
|
||||||
string k10Project = Path.Combine(projectDir, GetProjectFileName(projectName, "k10"));
|
|
||||||
|
|
||||||
var configs = new Dictionary<string, object>();
|
|
||||||
configs["net45"] = solutionProjects.ContainsKey(net45Project) ?
|
|
||||||
solutionProjects[net45Project] :
|
|
||||||
GetProjectGuidFromFileOrCreateNew(net45Project);
|
|
||||||
|
|
||||||
configs["net451"] = solutionProjects.ContainsKey(net451Project) ?
|
|
||||||
solutionProjects[net451Project] :
|
|
||||||
GetProjectGuidFromFileOrCreateNew(net451Project);
|
|
||||||
|
|
||||||
configs["k10"] = solutionProjects.ContainsKey(k10Project) ?
|
|
||||||
solutionProjects[k10Project] :
|
|
||||||
GetProjectGuidFromFileOrCreateNew(k10Project);
|
|
||||||
|
|
||||||
configs["path"] = Path.GetDirectoryName(path.Substring(solutionPath.Length).TrimStart(Path.DirectorySeparatorChar));
|
|
||||||
configs["jsonPath"] = path;
|
|
||||||
|
|
||||||
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<string, object> projectMapping,
|
|
||||||
IDictionary<string, string> 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<string, object>;
|
|
||||||
var configs = GetObject(d, "configurations") ?? new Dictionary<string, object>();
|
|
||||||
var dependencies = GetObject(d, "dependencies") ?? new Dictionary<string, object>();
|
|
||||||
var compilationOptions = GetObject(d, "compilationOptions") ?? new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if(configs.Count == 0)
|
|
||||||
{
|
|
||||||
// If the project doesn't specify any configurations generate both
|
|
||||||
configs["k10"] = new Dictionary<string, object>();
|
|
||||||
configs["net45"] = new Dictionary<string, object>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Templates
|
|
||||||
const string csTemplate = @"<Compile Include=""{0}"" />";
|
|
||||||
const string resxDesignerTemplate = @"<Compile Include=""{0}"">
|
|
||||||
<DependentUpon>{1}.resx</DependentUpon>
|
|
||||||
</Compile>";
|
|
||||||
const string resxTemplate = @"<EmbeddedResource Include=""{0}"">
|
|
||||||
<LogicalName>{1}.{2}.resources</LogicalName>
|
|
||||||
</EmbeddedResource>";
|
|
||||||
|
|
||||||
const string contentTemplate = @"<Content Include=""{0}"" />";
|
|
||||||
|
|
||||||
// Build the list of resx files
|
|
||||||
var resxFileNames = Files.Include(Path.Combine(projectDir, "**", "*.resx"));
|
|
||||||
var resxDesignerFiles = new HashSet<string>(resxFileNames.Select(f => Path.ChangeExtension(f, "Designer.cs")),
|
|
||||||
StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
var resxFiles
|
|
||||||
= String.Join(Environment.NewLine,
|
|
||||||
resxFileNames.Select(p => String.Format(resxTemplate, Path.Combine("..", "..", p), projectName, Path.GetFileNameWithoutExtension(p))));
|
|
||||||
|
|
||||||
var sourcePattern = Get<string>(d, "code") ?? @"**\*.cs";
|
|
||||||
var sourceExcludePattern = Get<string>(d, "exclude") ?? "";
|
|
||||||
var objPath = Path.Combine(projectDir, "obj");
|
|
||||||
var objPattern = Directory.Exists(objPath) ? Path.Combine(objPath, "**", "*.*") : projectDir;
|
|
||||||
|
|
||||||
var csFiles = String.Join(Environment.NewLine, Files.Include(sourcePattern.Split(Path.PathSeparator).Select(p => Path.Combine(projectDir, p)).ToArray())
|
|
||||||
.Exclude(Path.Combine(projectDir, sourceExcludePattern))
|
|
||||||
.Exclude(objPattern)
|
|
||||||
.Select(p => resxDesignerFiles.Contains(p)
|
|
||||||
? String.Format(resxDesignerTemplate, Path.Combine("..", "..", p), Path.GetFileNameWithoutExtension(p).Replace(".Designer", ""))
|
|
||||||
: String.Format(csTemplate, Path.Combine("..", "..", p))));
|
|
||||||
|
|
||||||
|
|
||||||
var contentFileExtensions = new [] {
|
|
||||||
"*.cshtml",
|
|
||||||
"*.css",
|
|
||||||
"*.js",
|
|
||||||
"*.html"
|
|
||||||
};
|
|
||||||
|
|
||||||
var contentFiles = String.Join(Environment.NewLine,
|
|
||||||
contentFileExtensions.SelectMany(ext => FindFilesOfType(projectDir, ext))
|
|
||||||
.Select(p => String.Format(contentTemplate, p)));
|
|
||||||
|
|
||||||
bool isSample = Path.GetDirectoryName(projectDir)
|
|
||||||
.TrimEnd(Path.DirectorySeparatorChar)
|
|
||||||
.EndsWith("samples");
|
|
||||||
|
|
||||||
bool isWebSample = isSample && projectName.EndsWith("Web", StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
Log("Processing sample project '{0}'", projectName);
|
|
||||||
|
|
||||||
var packageReferences = dependencies.Where(r => !projectMapping.ContainsKey(r.Key))
|
|
||||||
.ToDictionary(k => k.Key, k => (string)k.Value);
|
|
||||||
|
|
||||||
var projectReferences = dependencies.Where(r => projectMapping.ContainsKey(r.Key))
|
|
||||||
.Select(r => r.Key)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
|
|
||||||
var sharedFiles = GetSharedFiles(projectReferences, projectMapping);
|
|
||||||
|
|
||||||
var sharedDefines = Get<IEnumerable<object>>(compilationOptions, "define") ?? new object[0];
|
|
||||||
|
|
||||||
object unsafeValue = Get<object>(compilationOptions, "allowUnsafe");
|
|
||||||
bool sharedAllowUnsafeCode = unsafeValue == null ? false : (bool)unsafeValue;
|
|
||||||
|
|
||||||
object warningsValue = Get<object>(compilationOptions, "warningsAsErrors");
|
|
||||||
bool sharedWarningsAsErrors = warningsValue == null ? false : (bool)warningsValue;
|
|
||||||
|
|
||||||
// HACK: Assume the packages folder is 2 up from the projectDir
|
|
||||||
string packagesDir = Path.GetFullPath(Path.Combine(projectDir, "..", "..", "packages"));
|
|
||||||
|
|
||||||
string ttFileTemplate = @"<None Include=""..\..\packages\KoreBuild\Build\Resources.tt"">
|
|
||||||
<Link>Properties\Resources.tt</Link>
|
|
||||||
<Generator>TextTemplatingFileGenerator</Generator>
|
|
||||||
<CustomToolNamespace>{0}</CustomToolNamespace>
|
|
||||||
</None>";
|
|
||||||
// Link the tt file from packages dir
|
|
||||||
resxFiles += Environment.NewLine + String.Format(ttFileTemplate, projectName);
|
|
||||||
|
|
||||||
foreach (var pair in configs)
|
|
||||||
{
|
|
||||||
var targetFramework = pair.Key;
|
|
||||||
|
|
||||||
var templateKey = isWebSample ? "web" : targetFramework;
|
|
||||||
|
|
||||||
string projectTemplate;
|
|
||||||
if(!templates.TryGetValue(templateKey, out projectTemplate))
|
|
||||||
{
|
|
||||||
Warn("Skipping project generation for " + projectName + " - " + targetFramework);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var allPackageReferences = new Dictionary<string, string>(packageReferences);
|
|
||||||
|
|
||||||
var props = (IDictionary<string, object>)pair.Value;
|
|
||||||
|
|
||||||
var specificCompilationOptions = GetObject(props, "compilationOptions") ?? compilationOptions ?? new Dictionary<string, object>();
|
|
||||||
|
|
||||||
var specificDefines = Get<IEnumerable<object>>(specificCompilationOptions, "define") ?? new object[0];
|
|
||||||
|
|
||||||
object specificUnsafeValue = Get<object>(specificCompilationOptions, "allowUnsafe");
|
|
||||||
bool allowUnsafeCode = unsafeValue == null ? sharedAllowUnsafeCode : (bool)specificUnsafeValue;
|
|
||||||
string extraProperties = (allowUnsafeCode ? Environment.NewLine + "<AllowUnsafeBlocks>true</AllowUnsafeBlocks>" : "");
|
|
||||||
|
|
||||||
object specificWarningsValue = Get<object>(specificCompilationOptions, "warningsAsErrors");
|
|
||||||
bool warningsAsErrors = specificWarningsValue == null ? sharedWarningsAsErrors : (bool)specificWarningsValue;
|
|
||||||
extraProperties += (warningsAsErrors ? Environment.NewLine + "<TreatWarningsAsErrors>true</TreatWarningsAsErrors>" : "");
|
|
||||||
|
|
||||||
if (isWebSample)
|
|
||||||
{
|
|
||||||
var config = Path.Combine(projectDir, "web.config");
|
|
||||||
if(!File.Exists(config))
|
|
||||||
{
|
|
||||||
File.WriteAllText(config, @"<?xml version=""1.0""?>
|
|
||||||
<configuration>
|
|
||||||
|
|
||||||
<system.web>
|
|
||||||
<compilation debug=""true"" targetFramework=""4.5"" />
|
|
||||||
<httpRuntime targetFramework=""4.5"" />
|
|
||||||
</system.web>
|
|
||||||
|
|
||||||
</configuration>
|
|
||||||
");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isSample)
|
|
||||||
{
|
|
||||||
extraProperties += GenerateStartupAction(projectDir, projectName, packagesDir, pair.Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
string id = (string)GetObject(projectMapping, projectName)[targetFramework];
|
|
||||||
|
|
||||||
var defines = new HashSet<string>(specificDefines.Select(sd => sd.ToString()));
|
|
||||||
foreach(var def in sharedDefines)
|
|
||||||
{
|
|
||||||
defines.Add(def.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
var specificDependencies = GetObject(props, "dependencies") ?? new Dictionary<string, object>();
|
|
||||||
var gacReferences = new List<string>();
|
|
||||||
|
|
||||||
foreach(var dep in specificDependencies)
|
|
||||||
{
|
|
||||||
if (!projectMapping.ContainsKey(dep.Key))
|
|
||||||
{
|
|
||||||
var version = (string)dep.Value;
|
|
||||||
|
|
||||||
if(String.IsNullOrEmpty(version))
|
|
||||||
{
|
|
||||||
gacReferences.Add(dep.Key);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
allPackageReferences[dep.Key] = version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
projectReferences.Add(dep.Key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var template = projectTemplate
|
|
||||||
.Replace("{ProjectGuid}", id)
|
|
||||||
.Replace("{Name}", projectName)
|
|
||||||
.Replace("{Defines}", String.Join(";", defines))
|
|
||||||
.Replace("{ExtraProperties}", extraProperties)
|
|
||||||
.Replace("{Files}", String.Join(Environment.NewLine, csFiles, resxFiles, contentFiles, sharedFiles))
|
|
||||||
.Replace("{ProjectReferences}", BuildProjectReferences(projectReferences, targetFramework, projectMapping))
|
|
||||||
.Replace("{References}", BuildReferences(allPackageReferences, gacReferences, packagesDir, targetFramework, GetCandidates(targetFramework)));
|
|
||||||
|
|
||||||
if (targetFramework.StartsWith("k"))
|
|
||||||
{
|
|
||||||
template = template.Replace("{CSharpTargetsPath}", GetProjectKTargets(packagesDir));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isWebSample)
|
|
||||||
{
|
|
||||||
template = template.Replace("{Port}", (58189 + (projectName.GetHashCode() % 50)).ToString())
|
|
||||||
.Replace("{TargetFramwork}", targetFramework.ToUpper())
|
|
||||||
.Replace("{BinPath}", Path.Combine(projectDir, "bin"))
|
|
||||||
.Replace("{AspNetLoaderPath}", GetLoaderPath(packagesDir));
|
|
||||||
}
|
|
||||||
|
|
||||||
string output = Path.Combine(projectDir, GetProjectFileName(projectName, targetFramework));
|
|
||||||
string current = "";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
current = File.Exists(output) ? File.ReadAllText(output) : "";
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Warn(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current != template)
|
|
||||||
{
|
|
||||||
File.WriteAllText(output, template);
|
|
||||||
|
|
||||||
Log("Generated {0}", output);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log("No changes required for {0}", output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<string> FindFilesOfType(string projectDir, string pattern)
|
|
||||||
{
|
|
||||||
return Directory.GetFiles(projectDir, pattern, SearchOption.AllDirectories)
|
|
||||||
.Select(p => p.Substring(projectDir.Length).Trim(Path.DirectorySeparatorChar))
|
|
||||||
.Where(p => !p.StartsWith(@"obj\"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetLoaderPath(string packagesDir)
|
|
||||||
{
|
|
||||||
var interopPackage = Directory.GetDirectories(packagesDir, "Microsoft.AspNet.Loader.IIS.Interop*")
|
|
||||||
.OrderByDescending(d => d)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (interopPackage == null)
|
|
||||||
{
|
|
||||||
Warn("Unable to locate AspNet.Loader.dll");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Path.Combine(interopPackage, "tools", "AspNet.Loader.dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GenerateStartupAction(string projectRoot, string projectName, string packagesDir, string configType)
|
|
||||||
{
|
|
||||||
// packages\ProjectK.*\tools\bin\x86\klr.exe
|
|
||||||
// packages\ProjectK.*\tools\net45
|
|
||||||
|
|
||||||
Func<string, long> getVersion = version => {
|
|
||||||
var dash = version.LastIndexOf('-');
|
|
||||||
|
|
||||||
if(dash != -1)
|
|
||||||
{
|
|
||||||
var lastToken = version.Substring(dash + 1);
|
|
||||||
|
|
||||||
if(lastToken.StartsWith("t"))
|
|
||||||
{
|
|
||||||
return Int64.Parse(lastToken.Substring(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Int64.Parse(lastToken);
|
|
||||||
}
|
|
||||||
return Int64.MaxValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
var projectK = Directory.GetDirectories(packagesDir, "ProjectK*")
|
|
||||||
.Select(p => new { Path = p, Build = getVersion(p) })
|
|
||||||
.OrderByDescending(p => p.Build)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (projectK == null)
|
|
||||||
{
|
|
||||||
Warn("Unable to locate project K package");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var toolsDir = Path.Combine(projectK.Path, "tools");
|
|
||||||
var klrPath = Path.Combine(toolsDir, "bin", "x86", "klr.exe");
|
|
||||||
|
|
||||||
var klrSwitches = configType == "k10" ? "--core45" : "--net45";
|
|
||||||
klrSwitches += " --appbase " + projectRoot + " --lib " + Path.Combine(toolsDir, configType);
|
|
||||||
var args = klrSwitches + " Microsoft.Net.ApplicationHost --nobin ";
|
|
||||||
|
|
||||||
return String.Format(@"<StartAction>Program</StartAction>
|
|
||||||
<StartProgram>{0}</StartProgram>
|
|
||||||
<StartArguments>{1}</StartArguments>", klrPath, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetProjectKTargets(string packagesDir)
|
|
||||||
{
|
|
||||||
return Path.Combine(packagesDir, "KoreBuild", "build", "ProjectK.CSharp.targets");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetProjectFileName(string projectName, string config)
|
|
||||||
{
|
|
||||||
return projectName + "." + config + ".csproj";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetSharedFiles(IList<string> projectReferences, IDictionary<string, object> projectMapping)
|
|
||||||
{
|
|
||||||
if (projectReferences.Count == 0)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
for (var i = 0; i < projectReferences.Count; i++)
|
|
||||||
{
|
|
||||||
var reference = projectReferences[i];
|
|
||||||
var info = GetObject(projectMapping, reference);
|
|
||||||
|
|
||||||
if (info == null)
|
|
||||||
{
|
|
||||||
Warn("No project reference found for {0}", reference);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var serializer = new JavaScriptSerializer();
|
|
||||||
|
|
||||||
var jsonPath = (string)info["jsonPath"];
|
|
||||||
var jsonText = File.ReadAllText(jsonPath);
|
|
||||||
var path = (string)info["path"];
|
|
||||||
|
|
||||||
var d = serializer.DeserializeObject(jsonText) as IDictionary<string, object>;
|
|
||||||
|
|
||||||
// TODO: Support default compilers shared thing
|
|
||||||
var sharedFilesPattern = Get<string>(d, "shared");
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(sharedFilesPattern))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pattern = Path.Combine(Path.GetDirectoryName(jsonPath), sharedFilesPattern);
|
|
||||||
var files = Files.Include(pattern).ToList();
|
|
||||||
|
|
||||||
if (files.Count > 0)
|
|
||||||
{
|
|
||||||
Log("Found shared files in {0}", jsonPath);
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var sharedFilePath in files)
|
|
||||||
{
|
|
||||||
string fullPath = sharedFilePath;
|
|
||||||
string relativePath = sharedFilePath.Substring(path.Length).TrimStart(Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
if(relativePath.StartsWith("obj" + Path.DirectorySeparatorChar))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendFormat(@"<Compile Include=""..\..\{0}"">
|
|
||||||
<Link>{1}</Link>
|
|
||||||
</Compile>", fullPath, relativePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
projectReferences.RemoveAt(i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string BuildProjectReferences(IList<string> projectReferences, string config, IDictionary<string, object> projectMapping)
|
|
||||||
{
|
|
||||||
if (projectReferences.Count == 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(@"<ProjectReference Include=""..\..\{0}"">
|
|
||||||
<Project>{{{1}}}</Project>
|
|
||||||
<Name>{2}</Name>
|
|
||||||
</ProjectReference>", path, info[config], reference);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string[] GetCandidates(string config)
|
|
||||||
{
|
|
||||||
if (config == "net45" || config == "net451")
|
|
||||||
{
|
|
||||||
return new[] { "net45", "net40", "net35", "35", "net20" };
|
|
||||||
}
|
|
||||||
// If it's k10 then look for netcore45 as well
|
|
||||||
return new[] { "contract", config, "netcore45" };
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string BuildReferences(IDictionary<string, string> references, List<string> gacReferences, string packagesDir, string configName, string[] candidates)
|
|
||||||
{
|
|
||||||
Log("Building package references for {0}", configName);
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
foreach(var gacRef in gacReferences)
|
|
||||||
{
|
|
||||||
sb.AppendFormat(@"
|
|
||||||
<Reference Include=""{0}""></Reference>
|
|
||||||
", gacRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var reference in references)
|
|
||||||
{
|
|
||||||
var version = (string)reference.Value;
|
|
||||||
var pattern = reference.Key + "." + version;
|
|
||||||
|
|
||||||
var packageDir = Directory.GetDirectories(packagesDir, pattern).OrderByDescending(p => p).FirstOrDefault();
|
|
||||||
|
|
||||||
if (packageDir == null)
|
|
||||||
{
|
|
||||||
Warn(reference.Key + " = " + version + " ==> UNRESOLVED");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(reference.Key + " = " + version + " ==> " + packageDir);
|
|
||||||
|
|
||||||
var libPath = Path.Combine(packageDir, "lib");
|
|
||||||
|
|
||||||
if(!Directory.Exists(libPath))
|
|
||||||
{
|
|
||||||
Log(reference.Key + " = " + version + " has no lib folder");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var candidate
|
|
||||||
= candidates.Select(c => Path.Combine(libPath, c))
|
|
||||||
.FirstOrDefault(Directory.Exists)
|
|
||||||
?? candidates
|
|
||||||
.SelectMany(c => Directory.GetDirectories(libPath, "*" + c + "*"))
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
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(@"
|
|
||||||
<Reference Include=""{0}"">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\..\{1}</HintPath>
|
|
||||||
<Private>true</Private>
|
|
||||||
</Reference>", AssemblyName.GetAssemblyName(dllPath).FullName, dllPath.Substring(dllPath.IndexOf("packages")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static T Get<T>(IDictionary<string, object> obj, string key) where T : class
|
|
||||||
{
|
|
||||||
object value;
|
|
||||||
if (obj.TryGetValue(key, out value))
|
|
||||||
{
|
|
||||||
return value as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IDictionary<string, object> GetObject(IDictionary<string, object> obj, string key)
|
|
||||||
{
|
|
||||||
return Get<IDictionary<string, object>>(obj, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,7 @@ use namespace="System"
|
||||||
use namespace="System.Collections.Generic"
|
use namespace="System.Collections.Generic"
|
||||||
use namespace="System.IO"
|
use namespace="System.IO"
|
||||||
use namespace="System.Linq"
|
use namespace="System.Linq"
|
||||||
|
use namespace="System.Text"
|
||||||
use namespace="System.Xml.Linq"
|
use namespace="System.Xml.Linq"
|
||||||
|
|
||||||
default resxFile=''
|
default resxFile=''
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ use namespace="System"
|
||||||
use namespace="System.IO"
|
use namespace="System.IO"
|
||||||
use import="Files"
|
use import="Files"
|
||||||
use import="BuildEnv"
|
use import="BuildEnv"
|
||||||
use import="FileWatcher"
|
|
||||||
use import="Environment"
|
use import="Environment"
|
||||||
|
|
||||||
default BASE_DIR='${Directory.GetCurrentDirectory()}'
|
default BASE_DIR='${Directory.GetCurrentDirectory()}'
|
||||||
|
|
@ -18,7 +17,6 @@ default Configuration='Release'
|
||||||
|
|
||||||
#repo-initialize target='initialize'
|
#repo-initialize target='initialize'
|
||||||
k-restore
|
k-restore
|
||||||
k-generate-projects solutionPath='${BASE_DIR}' if='!IsMono'
|
|
||||||
|
|
||||||
#target-dir-clean target='clean'
|
#target-dir-clean target='clean'
|
||||||
directory delete="${TARGET_DIR}"
|
directory delete="${TARGET_DIR}"
|
||||||
|
|
@ -75,68 +73,12 @@ default Configuration='Release'
|
||||||
UpdateResx(file);
|
UpdateResx(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#watch
|
|
||||||
@{
|
|
||||||
var watcher = new FileWatcher(BASE_DIR);
|
|
||||||
|
|
||||||
foreach (var file in Directory.EnumerateFiles(BASE_DIR, "*.json", SearchOption.AllDirectories))
|
|
||||||
{
|
|
||||||
watcher.WatchFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var file in Directory.EnumerateFiles(BASE_DIR, "*.cs", SearchOption.AllDirectories))
|
|
||||||
{
|
|
||||||
watcher.WatchFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var file in Directory.EnumerateFiles(BASE_DIR, "*.resx", SearchOption.AllDirectories))
|
|
||||||
{
|
|
||||||
watcher.WatchFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var dir in Directory.EnumerateDirectories(BASE_DIR, "*.*", SearchOption.AllDirectories))
|
|
||||||
{
|
|
||||||
watcher.WatchDirectory(dir, ".cs");
|
|
||||||
watcher.WatchDirectory(dir, ".json");
|
|
||||||
}
|
|
||||||
|
|
||||||
watcher.OnChanged += path =>
|
|
||||||
{
|
|
||||||
Log.Info("Change detected in " + path);
|
|
||||||
bool restore = path.EndsWith("project.json");
|
|
||||||
|
|
||||||
if(path.EndsWith(".resx"))
|
|
||||||
{
|
|
||||||
UpdateResx(path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
UpdateProjects(BASE_DIR, restore);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Warn(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.Info("Waiting for changes...");
|
|
||||||
};
|
|
||||||
|
|
||||||
Log.Info("Waiting for changes...");
|
|
||||||
Console.ReadLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
functions @{
|
functions @{
|
||||||
string E(string key) { return Environment.GetEnvironmentVariable(key); }
|
string E(string key) { return Environment.GetEnvironmentVariable(key); }
|
||||||
void E(string key, string value) { Environment.SetEnvironmentVariable(key, value); }
|
void E(string key, string value) { Environment.SetEnvironmentVariable(key, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
macro name='UpdateProjects' basePath='string' restore='bool'
|
|
||||||
k command='restore' prefetch='${false}' if='restore'
|
|
||||||
k-generate-projects solutionPath='${basePath}' skipNet45='${!restore}'
|
|
||||||
|
|
||||||
macro name='Exec' program='string' commandline='string'
|
macro name='Exec' program='string' commandline='string'
|
||||||
exec
|
exec
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue