diff --git a/.gitattributes b/.gitattributes
index bdaa5ba982..c2f0f84273 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -48,3 +48,5 @@
*.fsproj text=auto
*.dbproj text=auto
*.sln text=auto eol=crlf
+
+*.sh eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index ac82da7568..10779cb569 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,5 @@ nuget.exe
*.ipch
*.sln.ide
project.lock.json
+.testPublish/
+.build/
diff --git a/.travis.yml b/.travis.yml
index 2019384e19..e8f77f0f14 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,14 +10,11 @@ addons:
- libssl-dev
- libunwind8
- zlib1g
-before_install:
- - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install icu4c; fi
-env:
- - KOREBUILD_DNU_RESTORE_CORECLR=true MONO_THREADS_PER_CPU=2000
mono:
- 4.0.5
os:
- linux
- osx
+osx_image: xcode7.1
script:
- - ./build.sh --quiet verify
+ - ./build.sh --quiet verify
\ No newline at end of file
diff --git a/NuGet.config b/NuGet.config
index 03704957e8..52bf414192 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -1,7 +1,7 @@
-
+
-
\ No newline at end of file
+
diff --git a/build.cmd b/build.cmd
index 553e3929a0..65fb3e3353 100644
--- a/build.cmd
+++ b/build.cmd
@@ -1,40 +1,40 @@
-@echo off
-cd %~dp0
-
+@ECHO off
SETLOCAL
+
+SET REPO_FOLDER=%~dp0
+CD "%REPO_FOLDER%"
+
+SET BUILD_FOLDER=.build
+SET KOREBUILD_FOLDER=%BUILD_FOLDER%\KoreBuild-dotnet
+SET KOREBUILD_VERSION=
+
+SET NUGET_PATH=%BUILD_FOLDER%\NuGet.exe
SET NUGET_VERSION=latest
SET CACHED_NUGET=%LocalAppData%\NuGet\nuget.%NUGET_VERSION%.exe
-SET BUILDCMD_KOREBUILD_VERSION=
-SET BUILDCMD_DNX_VERSION=
-IF EXIST %CACHED_NUGET% goto copynuget
-echo Downloading latest version of NuGet.exe...
-IF NOT EXIST %LocalAppData%\NuGet md %LocalAppData%\NuGet
-@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'"
-
-:copynuget
-IF EXIST .nuget\nuget.exe goto restore
-md .nuget
-copy %CACHED_NUGET% .nuget\nuget.exe > nul
-
-:restore
-IF EXIST packages\Sake goto getdnx
-IF "%BUILDCMD_KOREBUILD_VERSION%"=="" (
- .nuget\nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre
-) ELSE (
- .nuget\nuget.exe install KoreBuild -version %BUILDCMD_KOREBUILD_VERSION% -ExcludeVersion -o packages -nocache -pre
-)
-.nuget\NuGet.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages
-
-:getdnx
-IF "%BUILDCMD_DNX_VERSION%"=="" (
- SET BUILDCMD_DNX_VERSION=latest
-)
-IF "%SKIP_DNX_INSTALL%"=="" (
- CALL packages\KoreBuild\build\dnvm install %BUILDCMD_DNX_VERSION% -runtime CoreCLR -arch x86 -alias default
- CALL packages\KoreBuild\build\dnvm install default -runtime CLR -arch x86 -alias default
-) ELSE (
- CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86
+IF NOT EXIST %BUILD_FOLDER% (
+ md %BUILD_FOLDER%
)
-packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %*
+IF NOT EXIST %NUGET_PATH% (
+ IF NOT EXIST %CACHED_NUGET% (
+ echo Downloading latest version of NuGet.exe...
+ IF NOT EXIST %LocalAppData%\NuGet (
+ md %LocalAppData%\NuGet
+ )
+ @powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/%NUGET_VERSION%/nuget.exe' -OutFile '%CACHED_NUGET%'"
+ )
+
+ copy %CACHED_NUGET% %NUGET_PATH% > nul
+)
+
+IF NOT EXIST %KOREBUILD_FOLDER% (
+ SET KOREBUILD_DOWNLOAD_ARGS=
+ IF NOT "%KOREBUILD_VERSION%"=="" (
+ SET KOREBUILD_DOWNLOAD_ARGS=-version %KOREBUILD_VERSION%
+ )
+
+ %BUILD_FOLDER%\nuget.exe install KoreBuild-dotnet -ExcludeVersion -o %BUILD_FOLDER% -nocache -pre %KOREBUILD_DOWNLOAD_ARGS%
+)
+
+"%KOREBUILD_FOLDER%\build\KoreBuild.cmd" %*
diff --git a/build.sh b/build.sh
index da4e3fcd1c..263fb667a8 100755
--- a/build.sh
+++ b/build.sh
@@ -1,5 +1,10 @@
#!/usr/bin/env bash
+buildFolder=.build
+koreBuildFolder=$buildFolder/KoreBuild-dotnet
+
+nugetPath=$buildFolder/nuget.exe
+
if test `uname` = Darwin; then
cachedir=~/Library/Caches/KBuild
else
@@ -11,33 +16,30 @@ else
fi
mkdir -p $cachedir
nugetVersion=latest
-cachePath=$cachedir/nuget.$nugetVersion.exe
+cacheNuget=$cachedir/nuget.$nugetVersion.exe
-url=https://dist.nuget.org/win-x86-commandline/$nugetVersion/nuget.exe
+nugetUrl=https://dist.nuget.org/win-x86-commandline/$nugetVersion/nuget.exe
-if test ! -f $cachePath; then
- wget -O $cachePath $url 2>/dev/null || curl -o $cachePath --location $url /dev/null
+if test ! -d $buildFolder; then
+ mkdir $buildFolder
fi
-if test ! -e .nuget; then
- mkdir .nuget
- cp $cachePath .nuget/nuget.exe
+if test ! -f $nugetPath; then
+ if test ! -f $cacheNuget; then
+ wget -O $cacheNuget $nugetUrl 2>/dev/null || curl -o $cacheNuget --location $nugetUrl /dev/null
+ fi
+
+ cp $cacheNuget $nugetPath
fi
-if test ! -d packages/Sake; then
- mono .nuget/nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre
- mono .nuget/nuget.exe install Sake -ExcludeVersion -Source https://www.nuget.org/api/v2/ -Out packages
+if test ! -d $koreBuildFolder; then
+ mono $nugetPath install KoreBuild-dotnet -ExcludeVersion -o $buildFolder -nocache -pre
+ chmod +x $koreBuildFolder/build/KoreBuild.sh
fi
-if ! type dnvm > /dev/null 2>&1; then
- source packages/KoreBuild/build/dnvm.sh
+makeFile=makefile.shade
+if [ ! -e $makeFile ]; then
+ makeFile=$koreBuildFolder/build/makefile.shade
fi
-if ! type dnx > /dev/null 2>&1 || [ -z "$SKIP_DNX_INSTALL" ]; then
- dnvm install latest -runtime coreclr -alias default
- dnvm install default -runtime mono -alias default
-else
- dnvm use default -runtime mono
-fi
-
-mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@"
+./$koreBuildFolder/build/KoreBuild.sh -n $nugetPath -m $makeFile "$@"
diff --git a/dnx-watch.sln b/dotnet-watch.sln
similarity index 64%
rename from dnx-watch.sln
rename to dotnet-watch.sln
index 6b01701d71..3c8e1e6bbb 100644
--- a/dnx-watch.sln
+++ b/dotnet-watch.sln
@@ -5,9 +5,9 @@ VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{66517987-2A5A-4330-B130-207039378FD4}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Dnx.Watcher", "src\Microsoft.Dnx.Watcher\Microsoft.Dnx.Watcher.xproj", "{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-watch", "src\dotnet-watch\dotnet-watch.xproj", "{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Dnx.Watcher.Core", "src\Microsoft.Dnx.Watcher.Core\Microsoft.Dnx.Watcher.Core.xproj", "{D3DA3BBB-E206-404F-AEE6-17FB9B6F1221}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Watcher.Core", "src\Microsoft.DotNet.Watcher.Core\Microsoft.DotNet.Watcher.Core.xproj", "{D3DA3BBB-E206-404F-AEE6-17FB9B6F1221}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8321E0D1-9A47-4D2F-AED8-3AE636D44E35}"
ProjectSection(SolutionItems) = preProject
@@ -15,10 +15,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
NuGet.Config = NuGet.Config
EndProjectSection
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{442A6A17-4C5A-4E11-B547-A554063FD338}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Dnx.Watcher.Tests", "test\Microsoft.Dnx.Watcher.Tests\Microsoft.Dnx.Watcher.Tests.xproj", "{640D190B-26DB-4DDE-88EE-55814C86C43E}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,10 +29,6 @@ Global
{D3DA3BBB-E206-404F-AEE6-17FB9B6F1221}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3DA3BBB-E206-404F-AEE6-17FB9B6F1221}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3DA3BBB-E206-404F-AEE6-17FB9B6F1221}.Release|Any CPU.Build.0 = Release|Any CPU
- {640D190B-26DB-4DDE-88EE-55814C86C43E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {640D190B-26DB-4DDE-88EE-55814C86C43E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {640D190B-26DB-4DDE-88EE-55814C86C43E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {640D190B-26DB-4DDE-88EE-55814C86C43E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -44,6 +36,5 @@ Global
GlobalSection(NestedProjects) = preSolution
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46} = {66517987-2A5A-4330-B130-207039378FD4}
{D3DA3BBB-E206-404F-AEE6-17FB9B6F1221} = {66517987-2A5A-4330-B130-207039378FD4}
- {640D190B-26DB-4DDE-88EE-55814C86C43E} = {442A6A17-4C5A-4E11-B547-A554063FD338}
EndGlobalSection
EndGlobal
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/Constants.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/Constants.cs
deleted file mode 100644
index 9c2e502b02..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/Constants.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-
-namespace Microsoft.Dnx.Runtime
-{
- internal static class Constants
- {
- public const string BootstrapperExeName = "dnx";
- public const string BootstrapperFullName = "Microsoft .NET Execution environment";
- public const string DefaultLocalRuntimeHomeDir = ".dnx";
- public const string RuntimeShortName = "dnx";
- public const string RuntimeLongName = "Microsoft DNX";
- public const string RuntimeNamePrefix = RuntimeShortName + "-";
- public const string WebConfigRuntimeVersion = RuntimeNamePrefix + "version";
- public const string WebConfigRuntimeFlavor = RuntimeNamePrefix + "clr";
- public const string WebConfigRuntimeAppBase = RuntimeNamePrefix + "app-base";
- public const string WebConfigBootstrapperVersion = "bootstrapper-version";
- public const string WebConfigRuntimePath = "runtime-path";
- public const string BootstrapperHostName = RuntimeShortName + ".host";
- public const string BootstrapperClrName = RuntimeShortName + ".clr";
-
- public const int LockFileVersion = 2;
-
- public static readonly TimeSpan RegexMatchTimeout = TimeSpan.FromSeconds(10);
- public static readonly string AppConfigurationFileName = "app.config";
-
- public static readonly Version Version35 = new Version(3, 5);
- public static readonly Version Version40 = new Version(4, 0);
- public static readonly Version Version50 = new Version(5, 0);
- public static readonly Version Version10_0 = new Version(10, 0);
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/FileFormatException.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/FileFormatException.cs
deleted file mode 100644
index 0efa1871d1..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/FileFormatException.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using Microsoft.Extensions.JsonParser.Sources;
-
-namespace Microsoft.Dnx.Runtime
-{
- internal sealed class FileFormatException : Exception
- {
- private FileFormatException(string message) :
- base(message)
- {
- }
-
- private FileFormatException(string message, Exception innerException) :
- base(message, innerException)
- {
- }
-
- public string Path { get; private set; }
- public int Line { get; private set; }
- public int Column { get; private set; }
-
- public override string ToString()
- {
- return $"{Path}({Line},{Column}): Error: {base.ToString()}";
- }
-
- internal static FileFormatException Create(Exception exception, string filePath)
- {
- if (exception is JsonDeserializerException)
- {
- return new FileFormatException(exception.Message, exception)
- .WithFilePath(filePath)
- .WithLineInfo((JsonDeserializerException)exception);
- }
- else
- {
- return new FileFormatException(exception.Message, exception)
- .WithFilePath(filePath);
- }
- }
-
- internal static FileFormatException Create(Exception exception, JsonValue jsonValue, string filePath)
- {
- var result = Create(exception, jsonValue)
- .WithFilePath(filePath);
-
- return result;
- }
-
- internal static FileFormatException Create(Exception exception, JsonValue jsonValue)
- {
- var result = new FileFormatException(exception.Message, exception)
- .WithLineInfo(jsonValue);
-
- return result;
- }
-
- internal static FileFormatException Create(string message, JsonValue jsonValue, string filePath)
- {
- var result = Create(message, jsonValue)
- .WithFilePath(filePath);
-
- return result;
- }
-
- internal static FileFormatException Create(string message, string filePath)
- {
- var result = new FileFormatException(message)
- .WithFilePath(filePath);
-
- return result;
- }
-
- internal static FileFormatException Create(string message, JsonValue jsonValue)
- {
- var result = new FileFormatException(message)
- .WithLineInfo(jsonValue);
-
- return result;
- }
-
- internal FileFormatException WithFilePath(string path)
- {
- if (path == null)
- {
- throw new ArgumentNullException(nameof(path));
- }
-
- Path = path;
-
- return this;
- }
-
- private FileFormatException WithLineInfo(JsonValue value)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- Line = value.Line;
- Column = value.Column;
-
- return this;
- }
-
- private FileFormatException WithLineInfo(JsonDeserializerException exception)
- {
- if (exception == null)
- {
- throw new ArgumentNullException(nameof(exception));
- }
-
- Line = exception.Line;
- Column = exception.Column;
-
- return this;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFile.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFile.cs
deleted file mode 100644
index 8f07a5f54c..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFile.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Microsoft.Dnx.Runtime
-{
- public class LockFile
- {
- public int Version { get; set; }
-
- public IList ProjectLibraries { get; set; } = new List();
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFileProjectLibrary.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFileProjectLibrary.cs
deleted file mode 100644
index a131fa32ce..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFileProjectLibrary.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-namespace Microsoft.Dnx.Runtime
-{
- public class LockFileProjectLibrary
- {
- public string Name { get; set; }
-
- public string Path { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFileReader.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFileReader.cs
deleted file mode 100644
index 5cc3821fd9..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/LockFileReader.cs
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading;
-using Microsoft.Extensions.JsonParser.Sources;
-using NuGet;
-
-namespace Microsoft.Dnx.Runtime
-{
- internal class LockFileReader
- {
- public const string LockFileName = "project.lock.json";
-
- public LockFile Read(string filePath)
- {
- using (var stream = OpenFileStream(filePath))
- {
- try
- {
- return Read(stream);
- }
- catch (FileFormatException ex)
- {
- throw ex.WithFilePath(filePath);
- }
- catch (Exception ex)
- {
- throw FileFormatException.Create(ex, filePath);
- }
- }
- }
-
- private static FileStream OpenFileStream(string filePath)
- {
- // Retry 3 times before re-throw the exception.
- // It mitigates the race condition when DTH read lock file while VS is restoring projects.
-
- int retry = 3;
- while (true)
- {
- try
- {
- return new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
- }
- catch (Exception)
- {
- if (retry > 0)
- {
- retry--;
- Thread.Sleep(100);
- }
- else
- {
- throw;
- }
- }
- }
-
- }
-
- internal LockFile Read(Stream stream)
- {
- try
- {
- var reader = new StreamReader(stream);
- var jobject = JsonDeserializer.Deserialize(reader) as JsonObject;
-
- if (jobject != null)
- {
- return ReadLockFile(jobject);
- }
- else
- {
- throw new InvalidDataException();
- }
- }
- catch
- {
- // Ran into parsing errors, mark it as unlocked and out-of-date
- return new LockFile
- {
- Version = int.MinValue
- };
- }
- }
-
- private LockFile ReadLockFile(JsonObject cursor)
- {
- var lockFile = new LockFile();
- lockFile.Version = ReadInt(cursor, "version", defaultValue: int.MinValue);
- ReadLibrary(cursor.ValueAsJsonObject("libraries"), lockFile);
-
- return lockFile;
- }
-
- private void ReadLibrary(JsonObject json, LockFile lockFile)
- {
- if (json == null)
- {
- return;
- }
-
- foreach (var key in json.Keys)
- {
- var value = json.ValueAsJsonObject(key);
- if (value == null)
- {
- throw FileFormatException.Create("The value type is not object.", json.Value(key));
- }
-
- var parts = key.Split(new[] { '/' }, 2);
- var name = parts[0];
- var version = parts.Length == 2 ? SemanticVersion.Parse(parts[1]) : null;
-
- var type = value.ValueAsString("type")?.Value;
-
- if (type == "project")
- {
- lockFile.ProjectLibraries.Add(new LockFileProjectLibrary
- {
- Name = name,
- Path = ReadString(value.Value("path"))
- });
- }
- }
- }
-
- private string ReadFrameworkAssemblyReference(JsonValue json)
- {
- return ReadString(json);
- }
-
- private IList ReadArray(JsonValue json, Func readItem)
- {
- if (json == null)
- {
- return new List();
- }
-
- var jarray = json as JsonArray;
- if (jarray == null)
- {
- throw FileFormatException.Create("The value type is not array.", json);
- }
-
- var items = new List();
- for (int i = 0; i < jarray.Length; ++i)
- {
- items.Add(readItem(jarray[i]));
- }
- return items;
- }
-
- private IList ReadObject(JsonObject json, Func readItem)
- {
- if (json == null)
- {
- return new List();
- }
- var items = new List();
- foreach (var childKey in json.Keys)
- {
- items.Add(readItem(childKey, json.Value(childKey)));
- }
- return items;
- }
-
- private bool ReadBool(JsonObject cursor, string property, bool defaultValue)
- {
- var valueToken = cursor.Value(property) as JsonBoolean;
- if (valueToken == null)
- {
- return defaultValue;
- }
-
- return valueToken.Value;
- }
-
- private int ReadInt(JsonObject cursor, string property, int defaultValue)
- {
- var number = cursor.Value(property) as JsonNumber;
- if (number == null)
- {
- return defaultValue;
- }
-
- try
- {
- var resultInInt = Convert.ToInt32(number.Raw);
- return resultInInt;
- }
- catch (Exception ex)
- {
- // FormatException or OverflowException
- throw FileFormatException.Create(ex, cursor);
- }
- }
-
- private string ReadString(JsonValue json)
- {
- if (json is JsonString)
- {
- return (json as JsonString).Value;
- }
- else if (json is JsonNull)
- {
- return null;
- }
- else
- {
- throw FileFormatException.Create("The value type is not string.", json);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/NamedResourceReader.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/NamedResourceReader.cs
deleted file mode 100644
index 54bfed296b..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/NamedResourceReader.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.IO;
-using Microsoft.Extensions.JsonParser.Sources;
-
-namespace Microsoft.Dnx.Runtime
-{
- internal static class NamedResourceReader
- {
- public static IDictionary ReadNamedResources(JsonObject rawProject, string projectFilePath)
- {
- if (!rawProject.Keys.Contains("namedResource"))
- {
- return new Dictionary();
- }
-
- var namedResourceToken = rawProject.ValueAsJsonObject("namedResource");
- if (namedResourceToken == null)
- {
- throw FileFormatException.Create("Value must be object.", rawProject.Value("namedResource"), projectFilePath);
- }
-
- var namedResources = new Dictionary();
-
- foreach (var namedResourceKey in namedResourceToken.Keys)
- {
- var resourcePath = namedResourceToken.ValueAsString(namedResourceKey);
- if (resourcePath == null)
- {
- throw FileFormatException.Create("Value must be string.", namedResourceToken.Value(namedResourceKey), projectFilePath);
- }
-
- if (resourcePath.Value.Contains("*"))
- {
- throw FileFormatException.Create("Value cannot contain wildcards.", resourcePath, projectFilePath);
- }
-
- var resourceFileFullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectFilePath), resourcePath));
-
- if (namedResources.ContainsKey(namedResourceKey))
- {
- throw FileFormatException.Create(
- string.Format("The named resource {0} already exists.", namedResourceKey),
- resourcePath,
- projectFilePath);
- }
-
- namedResources.Add(
- namedResourceKey,
- resourceFileFullPath);
- }
-
- return namedResources;
- }
-
- public static void ApplyNamedResources(IDictionary namedResources, IDictionary resources)
- {
- foreach (var namedResource in namedResources)
- {
- // The named resources dictionary is like the project file
- // key = name, value = path to resource
- if (resources.ContainsKey(namedResource.Value))
- {
- resources[namedResource.Value] = namedResource.Key;
- }
- else
- {
- resources.Add(namedResource.Value, namedResource.Key);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PackIncludeEntry.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PackIncludeEntry.cs
deleted file mode 100644
index 8ba9c19515..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PackIncludeEntry.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Linq;
-using Microsoft.Extensions.JsonParser.Sources;
-
-namespace Microsoft.Dnx.Runtime
-{
- public class PackIncludeEntry
- {
- public string Target { get; }
- public string[] SourceGlobs { get; }
- public int Line { get; }
- public int Column { get; }
-
- internal PackIncludeEntry(string target, JsonValue json)
- : this(target, ExtractValues(json), json.Line, json.Column)
- {
- }
-
- public PackIncludeEntry(string target, string[] sourceGlobs, int line, int column)
- {
- Target = target;
- SourceGlobs = sourceGlobs;
- Line = line;
- Column = column;
- }
-
- private static string[] ExtractValues(JsonValue json)
- {
- var valueAsString = json as JsonString;
- if (valueAsString != null)
- {
- return new string[] { valueAsString.Value };
- }
-
- var valueAsArray = json as JsonArray;
- if(valueAsArray != null)
- {
- return valueAsArray.Values.Select(v => v.ToString()).ToArray();
- }
- return new string[0];
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PathUtility.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PathUtility.cs
deleted file mode 100644
index 9546881690..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PathUtility.cs
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.IO;
-
-namespace NuGet
-{
- internal static class PathUtility
- {
- public static bool IsChildOfDirectory(string dir, string candidate)
- {
- if (dir == null)
- {
- throw new ArgumentNullException(nameof(dir));
- }
- if (candidate == null)
- {
- throw new ArgumentNullException(nameof(candidate));
- }
- dir = Path.GetFullPath(dir);
- dir = EnsureTrailingSlash(dir);
- candidate = Path.GetFullPath(candidate);
- return candidate.StartsWith(dir, StringComparison.OrdinalIgnoreCase);
- }
-
- public static string EnsureTrailingSlash(string path)
- {
- return EnsureTrailingCharacter(path, Path.DirectorySeparatorChar);
- }
-
- public static string EnsureTrailingForwardSlash(string path)
- {
- return EnsureTrailingCharacter(path, '/');
- }
-
- private static string EnsureTrailingCharacter(string path, char trailingCharacter)
- {
- if (path == null)
- {
- throw new ArgumentNullException(nameof(path));
- }
-
- // if the path is empty, we want to return the original string instead of a single trailing character.
- if (path.Length == 0 || path[path.Length - 1] == trailingCharacter)
- {
- return path;
- }
-
- return path + trailingCharacter;
- }
-
- public static void EnsureParentDirectory(string filePath)
- {
- string directory = Path.GetDirectoryName(filePath);
- if (!Directory.Exists(directory))
- {
- Directory.CreateDirectory(directory);
- }
- }
-
- ///
- /// Returns path2 relative to path1, with Path.DirectorySeparatorChar as separator
- ///
- public static string GetRelativePath(string path1, string path2)
- {
- return GetRelativePath(path1, path2, Path.DirectorySeparatorChar);
- }
-
- ///
- /// Returns path2 relative to path1, with given path separator
- ///
- public static string GetRelativePath(string path1, string path2, char separator)
- {
- if (string.IsNullOrEmpty(path1))
- {
- throw new ArgumentException("Path must have a value", nameof(path1));
- }
-
- if (string.IsNullOrEmpty(path2))
- {
- throw new ArgumentException("Path must have a value", nameof(path2));
- }
-
- StringComparison compare;
- if (Microsoft.Dnx.Runtime.RuntimeEnvironmentHelper.IsWindows)
- {
- compare = StringComparison.OrdinalIgnoreCase;
- // check if paths are on the same volume
- if (!string.Equals(Path.GetPathRoot(path1), Path.GetPathRoot(path2)))
- {
- // on different volumes, "relative" path is just path2
- return path2;
- }
- }
- else
- {
- compare = StringComparison.Ordinal;
- }
-
- var index = 0;
- var path1Segments = path1.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
- var path2Segments = path2.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
- // if path1 does not end with / it is assumed the end is not a directory
- // we will assume that is isn't a directory by ignoring the last split
- var len1 = path1Segments.Length - 1;
- var len2 = path2Segments.Length;
-
- // find largest common absolute path between both paths
- var min = Math.Min(len1, len2);
- while (min > index)
- {
- if (!string.Equals(path1Segments[index], path2Segments[index], compare))
- {
- break;
- }
- // Handle scenarios where folder and file have same name (only if os supports same name for file and directory)
- // e.g. /file/name /file/name/app
- else if ((len1 == index && len2 > index + 1) || (len1 > index && len2 == index + 1))
- {
- break;
- }
- ++index;
- }
-
- var path = "";
-
- // check if path2 ends with a non-directory separator and if path1 has the same non-directory at the end
- if (len1 + 1 == len2 && !string.IsNullOrEmpty(path1Segments[index]) &&
- string.Equals(path1Segments[index], path2Segments[index], compare))
- {
- return path;
- }
-
- for (var i = index; len1 > i; ++i)
- {
- path += ".." + separator;
- }
- for (var i = index; len2 - 1 > i; ++i)
- {
- path += path2Segments[i] + separator;
- }
- // if path2 doesn't end with an empty string it means it ended with a non-directory name, so we add it back
- if (!string.IsNullOrEmpty(path2Segments[len2 - 1]))
- {
- path += path2Segments[len2 - 1];
- }
-
- return path;
- }
-
- public static string GetAbsolutePath(string basePath, string relativePath)
- {
- if (basePath == null)
- {
- throw new ArgumentNullException(nameof(basePath));
- }
-
- if (relativePath == null)
- {
- throw new ArgumentNullException(nameof(relativePath));
- }
-
- Uri resultUri = new Uri(new Uri(basePath), new Uri(relativePath, UriKind.Relative));
- return resultUri.LocalPath;
- }
-
- public static string GetDirectoryName(string path)
- {
- path = path.TrimEnd(Path.DirectorySeparatorChar);
- return path.Substring(Path.GetDirectoryName(path).Length).Trim(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
- }
-
- public static string GetPathWithForwardSlashes(string path)
- {
- return path.Replace('\\', '/');
- }
-
- public static string GetPathWithBackSlashes(string path)
- {
- return path.Replace('/', '\\');
- }
-
- public static string GetPathWithDirectorySeparator(string path)
- {
- if (Path.DirectorySeparatorChar == '/')
- {
- return GetPathWithForwardSlashes(path);
- }
- else
- {
- return GetPathWithBackSlashes(path);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PatternGroup.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PatternGroup.cs
deleted file mode 100644
index b7abecd809..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PatternGroup.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Microsoft.Extensions.CompilationAbstractions;
-using Microsoft.Extensions.FileSystemGlobbing;
-using Microsoft.Extensions.JsonParser.Sources;
-
-namespace Microsoft.Dnx.Runtime
-{
- public class PatternGroup
- {
- private readonly List _excludeGroups = new List();
- private readonly Matcher _matcher = new Matcher();
-
- internal PatternGroup(IEnumerable includePatterns)
- {
- IncludeLiterals = Enumerable.Empty();
- IncludePatterns = includePatterns;
- ExcludePatterns = Enumerable.Empty();
- _matcher.AddIncludePatterns(IncludePatterns);
- }
-
- internal PatternGroup(IEnumerable includePatterns, IEnumerable excludePatterns, IEnumerable includeLiterals)
- {
- IncludeLiterals = includeLiterals;
- IncludePatterns = includePatterns;
- ExcludePatterns = excludePatterns;
-
- _matcher.AddIncludePatterns(IncludePatterns);
- _matcher.AddExcludePatterns(ExcludePatterns);
- }
-
- internal static PatternGroup Build(
- JsonObject rawProject,
- string projectDirectory,
- string projectFilePath,
- string name,
- IEnumerable fallbackIncluding = null,
- IEnumerable additionalIncluding = null,
- IEnumerable additionalExcluding = null,
- bool includePatternsOnly = false,
- ICollection warnings = null)
- {
- string includePropertyName = name;
- additionalIncluding = additionalIncluding ?? Enumerable.Empty();
- var includePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, includePropertyName, defaultPatterns: fallbackIncluding)
- .Concat(additionalIncluding)
- .Distinct();
-
- if (includePatternsOnly)
- {
- return new PatternGroup(includePatterns);
- }
-
- additionalExcluding = additionalExcluding ?? Enumerable.Empty();
- var excludePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, propertyName: name + "Exclude")
- .Concat(additionalExcluding)
- .Distinct();
-
- var includeLiterals = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, propertyName: name + "Files", literalPath: true)
- .Distinct();
-
- return new PatternGroup(includePatterns, excludePatterns, includeLiterals);
- }
-
- public IEnumerable IncludeLiterals { get; }
-
- public IEnumerable IncludePatterns { get; }
-
- public IEnumerable ExcludePatterns { get; }
-
- public IEnumerable ExcludePatternsGroup { get { return _excludeGroups; } }
-
- public PatternGroup ExcludeGroup(PatternGroup group)
- {
- _excludeGroups.Add(group);
-
- return this;
- }
-
- public IEnumerable SearchFiles(string rootPath)
- {
- // literal included files are added at the last, but the search happens early
- // so as to make the process fail early in case there is missing file. fail early
- // helps to avoid unnecessary globing for performance optimization
- var literalIncludedFiles = new List();
- foreach (var literalRelativePath in IncludeLiterals)
- {
- var fullPath = Path.GetFullPath(Path.Combine(rootPath, literalRelativePath));
-
- if (!File.Exists(fullPath))
- {
- throw new InvalidOperationException(string.Format("Can't find file {0}", literalRelativePath));
- }
-
- // TODO: extract utility like NuGet.PathUtility.GetPathWithForwardSlashes()
- literalIncludedFiles.Add(fullPath.Replace('\\', '/'));
- }
-
- // globing files
- var globbingResults = _matcher.GetResultsInFullPath(rootPath);
-
- // if there is no results generated in globing, skip excluding other groups
- // for performance optimization.
- if (globbingResults.Any())
- {
- foreach (var group in _excludeGroups)
- {
- globbingResults = globbingResults.Except(group.SearchFiles(rootPath));
- }
- }
-
- return globbingResults.Concat(literalIncludedFiles).Distinct();
- }
-
- public override string ToString()
- {
- return string.Format("Pattern group: Literals [{0}] Includes [{1}] Excludes [{2}]", string.Join(", ", IncludeLiterals), string.Join(", ", IncludePatterns), string.Join(", ", ExcludePatterns));
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PatternsCollectionHelper.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PatternsCollectionHelper.cs
deleted file mode 100644
index ed3bb607b3..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/PatternsCollectionHelper.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Microsoft.Extensions.JsonParser.Sources;
-
-namespace Microsoft.Dnx.Runtime
-{
- internal static class PatternsCollectionHelper
- {
- private static readonly char[] PatternSeparator = new[] { ';' };
-
- public static IEnumerable GetPatternsCollection(
- JsonObject rawProject,
- string projectDirectory,
- string projectFilePath,
- string propertyName,
- IEnumerable defaultPatterns = null,
- bool literalPath = false)
- {
- defaultPatterns = defaultPatterns ?? Enumerable.Empty();
-
- try
- {
- if (!rawProject.Keys.Contains(propertyName))
- {
- return CreateCollection(projectDirectory, propertyName, defaultPatterns, literalPath);
- }
-
- var valueInString = rawProject.ValueAsString(propertyName);
- if (valueInString != null)
- {
- return CreateCollection(projectDirectory, propertyName, new string[] { valueInString }, literalPath);
- }
-
- var valuesInArray = rawProject.ValueAsStringArray(propertyName);
- if (valuesInArray != null)
- {
- return CreateCollection(projectDirectory, propertyName, valuesInArray.Select(s => s.ToString()), literalPath);
- }
- }
- catch (Exception ex)
- {
- throw FileFormatException.Create(ex, rawProject.Value(propertyName), projectFilePath);
- }
-
- throw FileFormatException.Create("Value must be either string or array.", rawProject.Value(propertyName), projectFilePath);
- }
-
- private static IEnumerable CreateCollection(string projectDirectory, string propertyName, IEnumerable patternsStrings, bool literalPath)
- {
- var patterns = patternsStrings.SelectMany(patternsString => GetSourcesSplit(patternsString))
- .Select(patternString => patternString.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar));
-
- foreach (var pattern in patterns)
- {
- if (Path.IsPathRooted(pattern))
- {
- throw new InvalidOperationException($"The '{propertyName}' property cannot be a rooted path.");
- }
-
- if (literalPath && pattern.Contains('*'))
- {
- throw new InvalidOperationException($"The '{propertyName}' property cannot contain wildcard characters.");
- }
- }
-
- return new List(patterns.Select(pattern => FolderToPattern(pattern, projectDirectory)));
- }
-
- private static IEnumerable GetSourcesSplit(string sourceDescription)
- {
- if (string.IsNullOrEmpty(sourceDescription))
- {
- return Enumerable.Empty();
- }
-
- return sourceDescription.Split(PatternSeparator, StringSplitOptions.RemoveEmptyEntries);
- }
-
- private static string FolderToPattern(string candidate, string projectDir)
- {
- // This conversion is needed to support current template
-
- // If it's already a pattern, no change is needed
- if (candidate.Contains('*'))
- {
- return candidate;
- }
-
- // If the given string ends with a path separator, or it is an existing directory
- // we convert this folder name to a pattern matching all files in the folder
- if (candidate.EndsWith(@"\") ||
- candidate.EndsWith("/") ||
- Directory.Exists(Path.Combine(projectDir, candidate)))
- {
- return Path.Combine(candidate, "**", "*");
- }
-
- // Otherwise, it represents a single file
- return candidate;
- }
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/Project.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/Project.cs
deleted file mode 100644
index 1b8ddd07d5..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/Project.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Microsoft.Extensions.CompilationAbstractions;
-using NuGet;
-
-namespace Microsoft.Dnx.Runtime
-{
- public class Project
- {
- public const string ProjectFileName = "project.json";
-
- public Project()
- {
- }
-
- public string ProjectFilePath { get; set; }
-
- public string ProjectDirectory
- {
- get
- {
- return Path.GetDirectoryName(ProjectFilePath);
- }
- }
-
- public string Name { get; set; }
-
- public string Title { get; set; }
-
- public string Description { get; set; }
-
- public string Copyright { get; set; }
-
- public string Summary { get; set; }
-
- public string Language { get; set; }
-
- public string ReleaseNotes { get; set; }
-
- public string[] Authors { get; set; }
-
- public string[] Owners { get; set; }
-
- public bool EmbedInteropTypes { get; set; }
-
- public Version AssemblyFileVersion { get; set; }
- public string WebRoot { get; set; }
-
- public string EntryPoint { get; set; }
-
- public string ProjectUrl { get; set; }
-
- public string LicenseUrl { get; set; }
-
- public string IconUrl { get; set; }
-
- public bool RequireLicenseAcceptance { get; set; }
-
- public string[] Tags { get; set; }
-
- public bool IsLoadable { get; set; }
-
- public ProjectFilesCollection Files { get; set; }
-
- public IDictionary Commands { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- public IDictionary> Scripts { get; } = new Dictionary>(StringComparer.OrdinalIgnoreCase);
-
- public static bool HasProjectFile(string path)
- {
- string projectPath = Path.Combine(path, ProjectFileName);
-
- return File.Exists(projectPath);
- }
-
- public static bool TryGetProject(string path, out Project project, ICollection diagnostics = null)
- {
- project = null;
-
- string projectPath = null;
-
- if (string.Equals(Path.GetFileName(path), ProjectFileName, StringComparison.OrdinalIgnoreCase))
- {
- projectPath = path;
- path = Path.GetDirectoryName(path);
- }
- else if (!HasProjectFile(path))
- {
- return false;
- }
- else
- {
- projectPath = Path.Combine(path, ProjectFileName);
- }
-
- // Assume the directory name is the project name if none was specified
- var projectName = PathUtility.GetDirectoryName(path);
- projectPath = Path.GetFullPath(projectPath);
-
- if (!File.Exists(projectPath))
- {
- return false;
- }
-
- try
- {
- using (var stream = File.OpenRead(projectPath))
- {
- var reader = new ProjectReader();
- project = reader.ReadProject(stream, projectName, projectPath, diagnostics);
- }
- }
- catch (Exception ex)
- {
- throw FileFormatException.Create(ex, projectPath);
- }
-
- return true;
- }
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/ProjectFilesCollection.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/ProjectFilesCollection.cs
deleted file mode 100644
index 2fe99407b3..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/ProjectFilesCollection.cs
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.Extensions.JsonParser.Sources;
-
-namespace Microsoft.Dnx.Runtime
-{
- public class ProjectFilesCollection
- {
- public static readonly string[] DefaultCompileBuiltInPatterns = new[] { @"**/*.cs" };
- public static readonly string[] DefaultPublishExcludePatterns = new[] { @"obj/**/*.*", @"bin/**/*.*", @"**/.*/**", @"**/global.json" };
- public static readonly string[] DefaultPreprocessPatterns = new[] { @"compiler/preprocess/**/*.cs" };
- public static readonly string[] DefaultSharedPatterns = new[] { @"compiler/shared/**/*.cs" };
- public static readonly string[] DefaultResourcesBuiltInPatterns = new[] { @"compiler/resources/**/*", "**/*.resx" };
- public static readonly string[] DefaultContentsBuiltInPatterns = new[] { @"**/*" };
-
- public static readonly string[] DefaultBuiltInExcludePatterns = new[] { "bin/**", "obj/**", "**/*.xproj" };
-
- public static readonly string PackIncludePropertyName = "packInclude";
-
- private PatternGroup _sharedPatternsGroup;
- private PatternGroup _resourcePatternsGroup;
- private PatternGroup _preprocessPatternsGroup;
- private PatternGroup _compilePatternsGroup;
- private PatternGroup _contentPatternsGroup;
- private IDictionary _namedResources;
- private IEnumerable _publishExcludePatterns;
- private IEnumerable _packInclude;
-
- private readonly string _projectDirectory;
- private readonly string _projectFilePath;
-
- private JsonObject _rawProject;
- private bool _initialized;
-
- internal ProjectFilesCollection(JsonObject rawProject, string projectDirectory, string projectFilePath)
- {
- _projectDirectory = projectDirectory;
- _projectFilePath = projectFilePath;
- _rawProject = rawProject;
- }
-
- internal void EnsureInitialized()
- {
- if (_initialized)
- {
- return;
- }
-
- var excludeBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "excludeBuiltIn", DefaultBuiltInExcludePatterns);
- var excludePatterns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "exclude")
- .Concat(excludeBuiltIns);
- var contentBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "contentBuiltIn", DefaultContentsBuiltInPatterns);
- var compileBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "compileBuiltIn", DefaultCompileBuiltInPatterns);
- var resourceBuiltIns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "resourceBuiltIn", DefaultResourcesBuiltInPatterns);
-
- _publishExcludePatterns = PatternsCollectionHelper.GetPatternsCollection(_rawProject, _projectDirectory, _projectFilePath, "publishExclude", DefaultPublishExcludePatterns);
-
- _sharedPatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "shared", fallbackIncluding: DefaultSharedPatterns, additionalExcluding: excludePatterns);
-
- _resourcePatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "resource", additionalIncluding: resourceBuiltIns, additionalExcluding: excludePatterns);
-
- _preprocessPatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "preprocess", fallbackIncluding: DefaultPreprocessPatterns, additionalExcluding: excludePatterns)
- .ExcludeGroup(_sharedPatternsGroup)
- .ExcludeGroup(_resourcePatternsGroup);
-
- _compilePatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "compile", additionalIncluding: compileBuiltIns, additionalExcluding: excludePatterns)
- .ExcludeGroup(_sharedPatternsGroup)
- .ExcludeGroup(_preprocessPatternsGroup)
- .ExcludeGroup(_resourcePatternsGroup);
-
- _contentPatternsGroup = PatternGroup.Build(_rawProject, _projectDirectory, _projectFilePath, "content", additionalIncluding: contentBuiltIns, additionalExcluding: excludePatterns.Concat(_publishExcludePatterns))
- .ExcludeGroup(_compilePatternsGroup)
- .ExcludeGroup(_preprocessPatternsGroup)
- .ExcludeGroup(_sharedPatternsGroup)
- .ExcludeGroup(_resourcePatternsGroup);
-
- _namedResources = NamedResourceReader.ReadNamedResources(_rawProject, _projectFilePath);
-
- // Files to be packed along with the project
- var packIncludeJson = _rawProject.ValueAsJsonObject(PackIncludePropertyName);
- if (packIncludeJson != null)
- {
- _packInclude = packIncludeJson
- .Keys
- .Select(k => new PackIncludeEntry(k, packIncludeJson.Value(k)))
- .ToList();
- }
- else
- {
- _packInclude = new List();
- }
-
- _initialized = true;
- _rawProject = null;
- }
-
- public IEnumerable PackInclude
- {
- get
- {
- EnsureInitialized();
- return _packInclude;
- }
- }
-
- public IEnumerable SourceFiles
- {
- get { return CompilePatternsGroup.SearchFiles(_projectDirectory).Distinct(); }
- }
-
- public IEnumerable PreprocessSourceFiles
- {
- get { return PreprocessPatternsGroup.SearchFiles(_projectDirectory).Distinct(); }
- }
-
- public IDictionary ResourceFiles
- {
- get
- {
- var resources = ResourcePatternsGroup
- .SearchFiles(_projectDirectory)
- .Distinct()
- .ToDictionary(res => res, res => (string)null);
-
- NamedResourceReader.ApplyNamedResources(_namedResources, resources);
-
- return resources;
- }
- }
-
- public IEnumerable SharedFiles
- {
- get { return SharedPatternsGroup.SearchFiles(_projectDirectory).Distinct(); }
- }
-
- public IEnumerable GetFilesForBundling(bool includeSource, IEnumerable additionalExcludePatterns)
- {
- var patternGroup = new PatternGroup(ContentPatternsGroup.IncludePatterns,
- ContentPatternsGroup.ExcludePatterns.Concat(additionalExcludePatterns),
- ContentPatternsGroup.IncludeLiterals);
- if (!includeSource)
- {
- foreach (var excludedGroup in ContentPatternsGroup.ExcludePatternsGroup)
- {
- patternGroup.ExcludeGroup(excludedGroup);
- }
- }
-
- return patternGroup.SearchFiles(_projectDirectory);
- }
-
- internal PatternGroup CompilePatternsGroup
- {
- get
- {
- EnsureInitialized();
- return _compilePatternsGroup;
- }
- }
-
- internal PatternGroup SharedPatternsGroup
- {
- get
- {
- EnsureInitialized();
- return _sharedPatternsGroup;
- }
- }
-
- internal PatternGroup ResourcePatternsGroup
- {
- get
- {
- EnsureInitialized();
- return _resourcePatternsGroup;
- }
- }
-
- internal PatternGroup PreprocessPatternsGroup
- {
- get
- {
- EnsureInitialized();
- return _preprocessPatternsGroup;
- }
- }
-
- internal PatternGroup ContentPatternsGroup
- {
- get
- {
- EnsureInitialized();
- return _contentPatternsGroup;
- }
- }
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/ProjectReader.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/ProjectReader.cs
deleted file mode 100644
index 1eafcc90a9..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/ProjectReader.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Microsoft.Extensions.CompilationAbstractions;
-using Microsoft.Extensions.JsonParser.Sources;
-using NuGet;
-
-namespace Microsoft.Dnx.Runtime
-{
- public class ProjectReader
- {
- public Project ReadProject(Stream stream, string projectName, string projectPath, ICollection diagnostics)
- {
- var project = new Project();
-
- var reader = new StreamReader(stream);
- var rawProject = JsonDeserializer.Deserialize(reader) as JsonObject;
- if (rawProject == null)
- {
- throw FileFormatException.Create(
- "The JSON file can't be deserialized to a JSON object.",
- projectPath);
- }
-
- // Meta-data properties
- project.Name = projectName;
- project.ProjectFilePath = Path.GetFullPath(projectPath);
-
- var version = rawProject.Value("version") as JsonString;
-
- project.Description = rawProject.ValueAsString("description");
- project.Summary = rawProject.ValueAsString("summary");
- project.Copyright = rawProject.ValueAsString("copyright");
- project.Title = rawProject.ValueAsString("title");
- project.WebRoot = rawProject.ValueAsString("webroot");
- project.EntryPoint = rawProject.ValueAsString("entryPoint");
- project.ProjectUrl = rawProject.ValueAsString("projectUrl");
- project.LicenseUrl = rawProject.ValueAsString("licenseUrl");
- project.IconUrl = rawProject.ValueAsString("iconUrl");
-
- project.Authors = rawProject.ValueAsStringArray("authors") ?? new string[] { };
- project.Owners = rawProject.ValueAsStringArray("owners") ?? new string[] { };
- project.Tags = rawProject.ValueAsStringArray("tags") ?? new string[] { };
-
- project.Language = rawProject.ValueAsString("language");
- project.ReleaseNotes = rawProject.ValueAsString("releaseNotes");
-
- project.RequireLicenseAcceptance = rawProject.ValueAsBoolean("requireLicenseAcceptance", defaultValue: false);
- project.IsLoadable = rawProject.ValueAsBoolean("loadable", defaultValue: true);
- // TODO: Move this to the dependencies node
- project.EmbedInteropTypes = rawProject.ValueAsBoolean("embedInteropTypes", defaultValue: false);
-
- // Project files
- project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath);
-
- var commands = rawProject.Value("commands") as JsonObject;
- if (commands != null)
- {
- foreach (var key in commands.Keys)
- {
- var value = commands.ValueAsString(key);
- if (value != null)
- {
- project.Commands[key] = value;
- }
- }
- }
-
- var scripts = rawProject.Value("scripts") as JsonObject;
- if (scripts != null)
- {
- foreach (var key in scripts.Keys)
- {
- var stringValue = scripts.ValueAsString(key);
- if (stringValue != null)
- {
- project.Scripts[key] = new string[] { stringValue };
- continue;
- }
-
- var arrayValue = scripts.ValueAsStringArray(key);
- if (arrayValue != null)
- {
- project.Scripts[key] = arrayValue;
- continue;
- }
-
- throw FileFormatException.Create(
- string.Format("The value of a script in {0} can only be a string or an array of strings", Project.ProjectFileName),
- scripts.Value(key),
- project.ProjectFilePath);
- }
- }
-
- return project;
- }
-
- private static SemanticVersion SpecifySnapshot(string version, string snapshotValue)
- {
- if (version.EndsWith("-*"))
- {
- if (string.IsNullOrEmpty(snapshotValue))
- {
- version = version.Substring(0, version.Length - 2);
- }
- else
- {
- version = version.Substring(0, version.Length - 1) + snapshotValue;
- }
- }
-
- return new SemanticVersion(version);
- }
-
- private static bool TryGetStringEnumerable(JsonObject parent, string property, out IEnumerable result)
- {
- var collection = new List();
- var valueInString = parent.ValueAsString(property);
- if (valueInString != null)
- {
- collection.Add(valueInString);
- }
- else
- {
- var valueInArray = parent.ValueAsStringArray(property);
- if (valueInArray != null)
- {
- collection.AddRange(valueInArray);
- }
- else
- {
- result = null;
- return false;
- }
- }
-
- result = collection.SelectMany(value => value.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries));
- return true;
- }
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/RuntimeEnvironmentHelper.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/RuntimeEnvironmentHelper.cs
deleted file mode 100644
index 27ea21b458..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/RuntimeEnvironmentHelper.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using Microsoft.Extensions.PlatformAbstractions;
-
-namespace Microsoft.Dnx.Runtime
-{
- internal static class RuntimeEnvironmentHelper
- {
- private static Lazy _isMono = new Lazy(() =>
- _runtimeEnv.Value.RuntimeType == "Mono");
-
- private static Lazy _isWindows = new Lazy(() =>
- _runtimeEnv.Value.OperatingSystem == "Windows");
-
- private static Lazy _runtimeEnv = new Lazy(() =>
- GetRuntimeEnvironment());
-
- private static IRuntimeEnvironment GetRuntimeEnvironment()
- {
- var environment = PlatformServices.Default.Runtime;
-
- if (environment == null)
- {
- throw new InvalidOperationException("Failed to resolve IRuntimeEnvironment");
- }
-
- return environment;
- }
-
- public static IRuntimeEnvironment RuntimeEnvironment
- {
- get
- {
- return _runtimeEnv.Value;
- }
- }
-
- public static bool IsWindows
- {
- get { return _isWindows.Value; }
- }
-
- public static bool IsMono
- {
- get { return _isMono.Value; }
- }
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/SemanticVersion.cs b/src/Microsoft.Dnx.Watcher.Core/External/Runtime/SemanticVersion.cs
deleted file mode 100644
index 59846a2cf9..0000000000
--- a/src/Microsoft.Dnx.Watcher.Core/External/Runtime/SemanticVersion.cs
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Text;
-
-namespace NuGet
-{
- ///
- /// A hybrid implementation of SemVer that supports semantic versioning as described at http://semver.org while not strictly enforcing it to
- /// allow older 4-digit versioning schemes to continue working.
- ///
- internal sealed class SemanticVersion : IComparable, IComparable, IEquatable
- {
- private string _normalizedVersionString;
-
- public SemanticVersion(string version)
- : this(Parse(version))
- {
- }
-
- public SemanticVersion(int major, int minor, int build, int revision)
- : this(new Version(major, minor, build, revision))
- {
- }
-
- public SemanticVersion(int major, int minor, int build, string specialVersion)
- : this(new Version(major, minor, build), specialVersion)
- {
- }
-
- public SemanticVersion(Version version)
- : this(version, string.Empty)
- {
- }
-
- public SemanticVersion(Version version, string specialVersion)
- {
- if (version == null)
- {
- throw new ArgumentNullException(nameof(version));
- }
- Version = NormalizeVersionValue(version);
- SpecialVersion = specialVersion ?? string.Empty;
- }
-
- internal SemanticVersion(SemanticVersion semVer)
- {
- Version = semVer.Version;
- SpecialVersion = semVer.SpecialVersion;
- }
-
- ///
- /// Gets the normalized version portion.
- ///
- public Version Version
- {
- get;
- private set;
- }
-
- ///
- /// Gets the optional special version.
- ///
- public string SpecialVersion
- {
- get;
- private set;
- }
-
- private static string[] SplitAndPadVersionString(string version)
- {
- string[] a = version.Split('.');
- if (a.Length == 4)
- {
- return a;
- }
- else
- {
- // if 'a' has less than 4 elements, we pad the '0' at the end
- // to make it 4.
- var b = new string[4] { "0", "0", "0", "0" };
- Array.Copy(a, 0, b, 0, a.Length);
- return b;
- }
- }
-
- ///
- /// Parses a version string using loose semantic versioning rules that allows 2-4 version components followed by an optional special version.
- ///
- public static SemanticVersion Parse(string version)
- {
- if (string.IsNullOrEmpty(version))
- {
- throw new ArgumentNullException(nameof(version));
- }
-
- SemanticVersion semVer;
- if (!TryParse(version, out semVer))
- {
- throw new ArgumentException(nameof(version));
- }
- return semVer;
- }
-
- ///
- /// Parses a version string using loose semantic versioning rules that allows 2-4 version components followed by an optional special version.
- ///
- public static bool TryParse(string version, out SemanticVersion value)
- {
- return TryParseInternal(version, strict: false, semVer: out value);
- }
-
- ///
- /// Parses a version string using strict semantic versioning rules that allows exactly 3 components and an optional special version.
- ///
- public static bool TryParseStrict(string version, out SemanticVersion value)
- {
- return TryParseInternal(version, strict: true, semVer: out value);
- }
-
- private static bool TryParseInternal(string version, bool strict, out SemanticVersion semVer)
- {
- semVer = null;
- if (string.IsNullOrEmpty(version))
- {
- return false;
- }
-
- version = version.Trim();
- var versionPart = version;
-
- string specialVersion = string.Empty;
- if (version.IndexOf('-') != -1)
- {
- var parts = version.Split(new char[] { '-' }, 2, StringSplitOptions.RemoveEmptyEntries);
- if (parts.Length != 2)
- {
- return false;
- }
-
- versionPart = parts[0];
- specialVersion = parts[1];
- }
-
- Version versionValue;
- if (!Version.TryParse(versionPart, out versionValue))
- {
- return false;
- }
-
- if (strict)
- {
- // Must have major, minor and build only.
- if (versionValue.Major == -1 ||
- versionValue.Minor == -1 ||
- versionValue.Build == -1 ||
- versionValue.Revision != -1)
- {
- return false;
- }
- }
-
- semVer = new SemanticVersion(NormalizeVersionValue(versionValue), specialVersion);
- return true;
- }
-
- ///
- /// Attempts to parse the version token as a SemanticVersion.
- ///
- /// An instance of SemanticVersion if it parses correctly, null otherwise.
- public static SemanticVersion ParseOptionalVersion(string version)
- {
- SemanticVersion semVer;
- TryParse(version, out semVer);
- return semVer;
- }
-
- private static Version NormalizeVersionValue(Version version)
- {
- return new Version(version.Major,
- version.Minor,
- Math.Max(version.Build, 0),
- Math.Max(version.Revision, 0));
- }
-
- public int CompareTo(object obj)
- {
- if (Object.ReferenceEquals(obj, null))
- {
- return 1;
- }
- SemanticVersion other = obj as SemanticVersion;
- if (other == null)
- {
- throw new ArgumentException(nameof(obj));
- }
- return CompareTo(other);
- }
-
- public int CompareTo(SemanticVersion other)
- {
- if (Object.ReferenceEquals(other, null))
- {
- return 1;
- }
-
- int result = Version.CompareTo(other.Version);
-
- if (result != 0)
- {
- return result;
- }
-
- bool empty = string.IsNullOrEmpty(SpecialVersion);
- bool otherEmpty = string.IsNullOrEmpty(other.SpecialVersion);
- if (empty && otherEmpty)
- {
- return 0;
- }
- else if (empty)
- {
- return 1;
- }
- else if (otherEmpty)
- {
- return -1;
- }
- return StringComparer.OrdinalIgnoreCase.Compare(SpecialVersion, other.SpecialVersion);
- }
-
- public static bool operator ==(SemanticVersion version1, SemanticVersion version2)
- {
- if (Object.ReferenceEquals(version1, null))
- {
- return Object.ReferenceEquals(version2, null);
- }
- return version1.Equals(version2);
- }
-
- public static bool operator !=(SemanticVersion version1, SemanticVersion version2)
- {
- return !(version1 == version2);
- }
-
- public static bool operator <(SemanticVersion version1, SemanticVersion version2)
- {
- if (version1 == null)
- {
- throw new ArgumentNullException(nameof(version1));
- }
- return version1.CompareTo(version2) < 0;
- }
-
- public static bool operator <=(SemanticVersion version1, SemanticVersion version2)
- {
- return (version1 == version2) || (version1 < version2);
- }
-
- public static bool operator >(SemanticVersion version1, SemanticVersion version2)
- {
- if (version1 == null)
- {
- throw new ArgumentNullException(nameof(version1));
- }
- return version2 < version1;
- }
-
- public static bool operator >=(SemanticVersion version1, SemanticVersion version2)
- {
- return (version1 == version2) || (version1 > version2);
- }
-
- public override string ToString()
- {
- if (_normalizedVersionString == null)
- {
- var builder = new StringBuilder();
- builder
- .Append(Version.Major)
- .Append('.')
- .Append(Version.Minor)
- .Append('.')
- .Append(Math.Max(0, Version.Build));
-
- if (Version.Revision > 0)
- {
- builder
- .Append('.')
- .Append(Version.Revision);
- }
-
- if (!string.IsNullOrEmpty(SpecialVersion))
- {
- builder
- .Append('-')
- .Append(SpecialVersion);
- }
-
- _normalizedVersionString = builder.ToString();
- }
-
- return _normalizedVersionString;
- }
-
- public bool Equals(SemanticVersion other)
- {
- return !Object.ReferenceEquals(null, other) &&
- Version.Equals(other.Version) &&
- SpecialVersion.Equals(other.SpecialVersion, StringComparison.OrdinalIgnoreCase);
- }
-
- public override bool Equals(object obj)
- {
- SemanticVersion semVer = obj as SemanticVersion;
- return !Object.ReferenceEquals(null, semVer) && Equals(semVer);
- }
-
- public override int GetHashCode()
- {
- int hashCode = Version.GetHashCode();
- if (SpecialVersion != null)
- {
- hashCode = hashCode * 4567 + SpecialVersion.GetHashCode();
- }
-
- return hashCode;
- }
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher/Program.cs b/src/Microsoft.Dnx.Watcher/Program.cs
deleted file mode 100644
index f2b2d9c104..0000000000
--- a/src/Microsoft.Dnx.Watcher/Program.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.CommandLineUtils;
-using Microsoft.Extensions.PlatformAbstractions;
-using Microsoft.Dnx.Watcher.Core;
-using Microsoft.Extensions.Logging;
-
-namespace Microsoft.Dnx.Watcher
-{
- public class Program
- {
- private const string DnxWatchArgumentSeparator = "--dnx-args";
-
- private readonly ILoggerFactory _loggerFactory;
-
- public Program()
- {
- _loggerFactory = new LoggerFactory();
-
- var commandProvider = new CommandOutputProvider(PlatformServices.Default.Runtime);
- _loggerFactory.AddProvider(commandProvider);
- }
-
- public static int Main(string[] args)
- {
- using (CancellationTokenSource ctrlCTokenSource = new CancellationTokenSource())
- {
- Console.CancelKeyPress += (sender, ev) =>
- {
- ctrlCTokenSource.Cancel();
- ev.Cancel = false;
- };
-
- string[] watchArgs, dnxArgs;
- SeparateWatchArguments(args, out watchArgs, out dnxArgs);
-
- return new Program().MainInternal(watchArgs, dnxArgs, ctrlCTokenSource.Token);
- }
- }
-
- internal static void SeparateWatchArguments(string[] args, out string[] watchArgs, out string[] dnxArgs)
- {
- int argsIndex = -1;
- watchArgs = args.TakeWhile((arg, idx) =>
- {
- argsIndex = idx;
- return !string.Equals(arg, DnxWatchArgumentSeparator, StringComparison.OrdinalIgnoreCase);
- }).ToArray();
-
- dnxArgs = args.Skip(argsIndex + 1).ToArray();
-
- if (dnxArgs.Length == 0)
- {
- // If no explicit dnx arguments then all arguments get passed to dnx
- dnxArgs = watchArgs;
- watchArgs = new string[0];
- }
- }
-
- private int MainInternal(string[] watchArgs, string[] dnxArgs, CancellationToken cancellationToken)
- {
- var app = new CommandLineApplication();
- app.Name = "dnx-watch";
- app.FullName = "Microsoft .NET DNX File Watcher";
-
- app.HelpOption("-?|-h|--help");
-
- var projectArg = app.Option(
- "--project ",
- "Path to the project.json file or the application folder. Defaults to the current folder if not provided. Will be passed to DNX.",
- CommandOptionType.SingleValue);
-
- var workingDirArg = app.Option(
- "--working-dir ",
- "The working directory for DNX. Defaults to the current directory.",
- CommandOptionType.SingleValue);
-
- var exitOnChangeArg = app.Option(
- "--exit-on-change",
- "The watcher will exit when a file change is detected instead of restarting the process.",
- CommandOptionType.NoValue);
-
- // This option is here just to be displayed in help
- // it will not be parsed because it is removed before the code is executed
- app.Option(
- $"{DnxWatchArgumentSeparator} ",
- "Marks the arguments that will be passed to DNX. Anything following this option is passed. If not specified, all the arguments are passed to DNX.",
- CommandOptionType.SingleValue);
-
- app.OnExecute(() =>
- {
- var projectToRun = projectArg.HasValue() ?
- projectArg.Value() :
- Directory.GetCurrentDirectory();
-
- if (!projectToRun.EndsWith("project.json", StringComparison.Ordinal))
- {
- projectToRun = Path.Combine(projectToRun, "project.json");
- }
-
- var workingDir = workingDirArg.HasValue() ?
- workingDirArg.Value() :
- Directory.GetCurrentDirectory();
-
- var watcher = DnxWatcher.CreateDefault(_loggerFactory);
- watcher.ExitOnChange = exitOnChangeArg.HasValue();
-
- try
- {
- watcher.WatchAsync(projectToRun, dnxArgs, workingDir, cancellationToken).Wait();
- }
- catch (AggregateException ex)
- {
- if (ex.InnerExceptions.Count != 1 || !(ex.InnerException is TaskCanceledException))
- {
- throw;
- }
- }
-
-
- return 1;
- });
-
- return app.Execute(watchArgs);
- }
- }
-}
diff --git a/src/Microsoft.Dnx.Watcher/Properties/AssemblyInfo.cs b/src/Microsoft.Dnx.Watcher/Properties/AssemblyInfo.cs
deleted file mode 100644
index 64dbfc69d0..0000000000
--- a/src/Microsoft.Dnx.Watcher/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Reflection;
-using System.Resources;
-using System.Runtime.CompilerServices;
-
-[assembly:InternalsVisibleTo("Microsoft.Dnx.Watcher.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
-[assembly: AssemblyMetadata("Serviceable", "True")]
-[assembly: NeutralResourcesLanguage("en-US")]
diff --git a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IFileWatcher.cs b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IFileWatcher.cs
similarity index 91%
rename from src/Microsoft.Dnx.Watcher.Core/Abstractions/IFileWatcher.cs
rename to src/Microsoft.DotNet.Watcher.Core/Abstractions/IFileWatcher.cs
index 8dfd44f1e5..c5f01a6399 100644
--- a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IFileWatcher.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IFileWatcher.cs
@@ -3,7 +3,7 @@
using System;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
public interface IFileWatcher : IDisposable
{
diff --git a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IProcessWatcher.cs b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IProcessWatcher.cs
similarity index 88%
rename from src/Microsoft.Dnx.Watcher.Core/Abstractions/IProcessWatcher.cs
rename to src/Microsoft.DotNet.Watcher.Core/Abstractions/IProcessWatcher.cs
index d075bd519a..ad975f3a12 100644
--- a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IProcessWatcher.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IProcessWatcher.cs
@@ -1,10 +1,11 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using System.Threading;
using System.Threading.Tasks;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
public interface IProcessWatcher
{
diff --git a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IProject.cs b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IProject.cs
similarity index 90%
rename from src/Microsoft.Dnx.Watcher.Core/Abstractions/IProject.cs
rename to src/Microsoft.DotNet.Watcher.Core/Abstractions/IProject.cs
index cad54e0997..fc4556c570 100644
--- a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IProject.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IProject.cs
@@ -3,7 +3,7 @@
using System.Collections.Generic;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
public interface IProject
{
diff --git a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IProjectProvider.cs b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IProjectProvider.cs
similarity index 88%
rename from src/Microsoft.Dnx.Watcher.Core/Abstractions/IProjectProvider.cs
rename to src/Microsoft.DotNet.Watcher.Core/Abstractions/IProjectProvider.cs
index 77abc7bbb1..44e46cd91e 100644
--- a/src/Microsoft.Dnx.Watcher.Core/Abstractions/IProjectProvider.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/Abstractions/IProjectProvider.cs
@@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
public interface IProjectProvider
{
diff --git a/src/Microsoft.Dnx.Watcher.Core/DictionaryExtensions.cs b/src/Microsoft.DotNet.Watcher.Core/DictionaryExtensions.cs
similarity index 100%
rename from src/Microsoft.Dnx.Watcher.Core/DictionaryExtensions.cs
rename to src/Microsoft.DotNet.Watcher.Core/DictionaryExtensions.cs
diff --git a/src/Microsoft.Dnx.Watcher.Core/DnxWatcher.cs b/src/Microsoft.DotNet.Watcher.Core/DotNetWatcher.cs
similarity index 71%
rename from src/Microsoft.Dnx.Watcher.Core/DnxWatcher.cs
rename to src/Microsoft.DotNet.Watcher.Core/DotNetWatcher.cs
index b4a27a9afb..f105727329 100644
--- a/src/Microsoft.Dnx.Watcher.Core/DnxWatcher.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/DotNetWatcher.cs
@@ -8,9 +8,9 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
- public class DnxWatcher
+ public class DotNetWatcher
{
private readonly Func _fileWatcherFactory;
private readonly Func _processWatcherFactory;
@@ -21,7 +21,7 @@ namespace Microsoft.Dnx.Watcher.Core
public bool ExitOnChange { get; set; }
- public DnxWatcher(
+ public DotNetWatcher(
Func fileWatcherFactory,
Func processWatcherFactory,
IProjectProvider projectProvider,
@@ -32,12 +32,44 @@ namespace Microsoft.Dnx.Watcher.Core
_projectProvider = projectProvider;
_loggerFactory = loggerFactory;
- _logger = _loggerFactory.CreateLogger(nameof(DnxWatcher));
+ _logger = _loggerFactory.CreateLogger(nameof(DotNetWatcher));
}
- public async Task WatchAsync(string projectFile, string[] dnxArguments, string workingDir, CancellationToken cancellationToken)
+
+ public async Task WatchAsync(string projectFile, string command, string[] dotnetArguments, string workingDir, CancellationToken cancellationToken)
{
- dnxArguments = new string[] { "--project", projectFile }
- .Concat(dnxArguments)
+ if (string.IsNullOrEmpty(projectFile))
+ {
+ throw new ArgumentNullException(nameof(projectFile));
+ }
+ if (string.IsNullOrEmpty(command))
+ {
+ throw new ArgumentNullException(nameof(command));
+ }
+ if (dotnetArguments == null)
+ {
+ throw new ArgumentNullException(nameof(dotnetArguments));
+ }
+ if (string.IsNullOrEmpty(workingDir))
+ {
+ throw new ArgumentNullException(nameof(workingDir));
+ }
+ if (cancellationToken == null)
+ {
+ throw new ArgumentNullException(nameof(cancellationToken));
+ }
+
+ if (dotnetArguments.Length > 0)
+ {
+ dotnetArguments = new string[] { command, "--" }
+ .Concat(dotnetArguments)
+ .ToArray();
+ }
+ else
+ {
+ dotnetArguments = new string[] { command };
+ }
+
+ dotnetArguments = dotnetArguments
.Select(arg =>
{
// If the argument has spaces, make sure we quote it
@@ -50,7 +82,7 @@ namespace Microsoft.Dnx.Watcher.Core
})
.ToArray();
- var dnxArgumentsAsString = string.Join(" ", dnxArguments);
+ var dotnetArgumentsAsString = string.Join(" ", dotnetArguments);
while (true)
{
@@ -63,14 +95,14 @@ namespace Microsoft.Dnx.Watcher.Core
currentRunCancellationSource.Token))
{
var fileWatchingTask = WaitForProjectFileToChangeAsync(project, combinedCancellationSource.Token);
- var dnxTask = WaitForDnxToExitAsync(dnxArgumentsAsString, workingDir, combinedCancellationSource.Token);
+ var dotnetTask = WaitForDotnetToExitAsync(dotnetArgumentsAsString, workingDir, combinedCancellationSource.Token);
- var tasksToWait = new Task[] { dnxTask, fileWatchingTask };
+ var tasksToWait = new Task[] { dotnetTask, fileWatchingTask };
int finishedTaskIndex = Task.WaitAny(tasksToWait, cancellationToken);
// Regardless of the outcome, make sure everything is cancelled
- // and wait for dnx to exit. We don't want orphan processes
+ // and wait for dotnet to exit. We don't want orphan processes
currentRunCancellationSource.Cancel();
Task.WaitAll(tasksToWait);
@@ -78,16 +110,16 @@ namespace Microsoft.Dnx.Watcher.Core
if (finishedTaskIndex == 0)
{
- // This is the dnx task
- var dnxExitCode = dnxTask.Result;
+ // This is the dotnet task
+ var dotnetExitCode = dotnetTask.Result;
- if (dnxExitCode == 0)
+ if (dotnetExitCode == 0)
{
- _logger.LogInformation($"dnx exit code: {dnxExitCode}");
+ _logger.LogInformation($"dotnet exit code: {dotnetExitCode}");
}
else
{
- _logger.LogError($"dnx exit code: {dnxExitCode}");
+ _logger.LogError($"dotnet exit code: {dotnetExitCode}");
}
if (ExitOnChange)
@@ -95,8 +127,8 @@ namespace Microsoft.Dnx.Watcher.Core
break;
}
- _logger.LogInformation("Waiting for a file to change before restarting dnx...");
- // Now wait for a file to change before restarting dnx
+ _logger.LogInformation("Waiting for a file to change before restarting dotnet...");
+ // Now wait for a file to change before restarting dotnet
await WaitForProjectFileToChangeAsync(project, cancellationToken);
}
else
@@ -123,15 +155,15 @@ namespace Microsoft.Dnx.Watcher.Core
}
}
- private Task WaitForDnxToExitAsync(string dnxArguments, string workingDir, CancellationToken cancellationToken)
+ private Task WaitForDotnetToExitAsync(string dotnetArguments, string workingDir, CancellationToken cancellationToken)
{
- _logger.LogInformation($"Running dnx with the following arguments: {dnxArguments}");
+ _logger.LogInformation($"Running dotnet with the following arguments: {dotnetArguments}");
- var dnxWatcher = _processWatcherFactory();
- int dnxProcessId = dnxWatcher.Start("dnx", dnxArguments, workingDir);
- _logger.LogInformation($"dnx process id: {dnxProcessId}");
+ var dotnetWatcher = _processWatcherFactory();
+ int dotnetProcessId = dotnetWatcher.Start("dotnet", dotnetArguments, workingDir);
+ _logger.LogInformation($"dotnet run process id: {dotnetProcessId}");
- return dnxWatcher.WaitForExitAsync(cancellationToken);
+ return dotnetWatcher.WaitForExitAsync(cancellationToken);
}
private async Task WaitForValidProjectJsonAsync(string projectFile, CancellationToken cancellationToken)
@@ -219,9 +251,9 @@ namespace Microsoft.Dnx.Watcher.Core
return changedPath;
}
- public static DnxWatcher CreateDefault(ILoggerFactory loggerFactory)
+ public static DotNetWatcher CreateDefault(ILoggerFactory loggerFactory)
{
- return new DnxWatcher(
+ return new DotNetWatcher(
fileWatcherFactory: root => new FileWatcher(root),
processWatcherFactory: () => new ProcessWatcher(),
projectProvider: new ProjectProvider(),
diff --git a/src/Microsoft.Dnx.Watcher.Core/FileSystem/FileSystemWatcherRoot.cs b/src/Microsoft.DotNet.Watcher.Core/FileSystem/FileSystemWatcherRoot.cs
similarity index 93%
rename from src/Microsoft.Dnx.Watcher.Core/FileSystem/FileSystemWatcherRoot.cs
rename to src/Microsoft.DotNet.Watcher.Core/FileSystem/FileSystemWatcherRoot.cs
index 3c4fb517c1..ff8534bc37 100644
--- a/src/Microsoft.Dnx.Watcher.Core/FileSystem/FileSystemWatcherRoot.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/FileSystem/FileSystemWatcherRoot.cs
@@ -3,7 +3,7 @@
using System.IO;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
internal class FileSystemWatcherRoot : IWatcherRoot
{
diff --git a/src/Microsoft.Dnx.Watcher.Core/FileSystem/FileWatcher.cs b/src/Microsoft.DotNet.Watcher.Core/FileSystem/FileWatcher.cs
similarity index 99%
rename from src/Microsoft.Dnx.Watcher.Core/FileSystem/FileWatcher.cs
rename to src/Microsoft.DotNet.Watcher.Core/FileSystem/FileWatcher.cs
index fe9921336e..e3d3abd442 100644
--- a/src/Microsoft.Dnx.Watcher.Core/FileSystem/FileWatcher.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/FileSystem/FileWatcher.cs
@@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.IO;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
public class FileWatcher : IFileWatcher
{
diff --git a/src/Microsoft.Dnx.Watcher.Core/FileSystem/IWatcherRoot.cs b/src/Microsoft.DotNet.Watcher.Core/FileSystem/IWatcherRoot.cs
similarity index 87%
rename from src/Microsoft.Dnx.Watcher.Core/FileSystem/IWatcherRoot.cs
rename to src/Microsoft.DotNet.Watcher.Core/FileSystem/IWatcherRoot.cs
index ffc7a86f6b..eaf0e66bd0 100644
--- a/src/Microsoft.Dnx.Watcher.Core/FileSystem/IWatcherRoot.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/FileSystem/IWatcherRoot.cs
@@ -3,7 +3,7 @@
using System;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
internal interface IWatcherRoot : IDisposable
{
diff --git a/src/Microsoft.Dnx.Watcher.Core/Impl/ProcessWatcher.cs b/src/Microsoft.DotNet.Watcher.Core/Impl/ProcessWatcher.cs
similarity index 55%
rename from src/Microsoft.Dnx.Watcher.Core/Impl/ProcessWatcher.cs
rename to src/Microsoft.DotNet.Watcher.Core/Impl/ProcessWatcher.cs
index 153979d659..91e7d72653 100644
--- a/src/Microsoft.Dnx.Watcher.Core/Impl/ProcessWatcher.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/Impl/ProcessWatcher.cs
@@ -3,14 +3,16 @@
using System;
using System.Diagnostics;
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.Extensions.PlatformAbstractions;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
public class ProcessWatcher : IProcessWatcher
{
+ private static readonly bool _isWindows = PlatformServices.Default.Runtime.OperatingSystem.Equals("Windows", StringComparison.OrdinalIgnoreCase);
+
private Process _runningProcess;
public int Start(string executable, string arguments, string workingDir)
@@ -30,8 +32,6 @@ namespace Microsoft.Dnx.Watcher.Core
WorkingDirectory = workingDir
};
- RemoveCompilationPortEnvironmentVariable(_runningProcess.StartInfo);
-
_runningProcess.Start();
return _runningProcess.Id;
@@ -39,9 +39,9 @@ namespace Microsoft.Dnx.Watcher.Core
public Task WaitForExitAsync(CancellationToken cancellationToken)
{
- cancellationToken.Register(() => _runningProcess?.Kill());
-
- return Task.Run(() =>
+ cancellationToken.Register(() => KillProcess(_runningProcess?.Id));
+
+ return Task.Run(() =>
{
_runningProcess.WaitForExit();
@@ -52,32 +52,33 @@ namespace Microsoft.Dnx.Watcher.Core
});
}
- private static void RemoveCompilationPortEnvironmentVariable(ProcessStartInfo procStartInfo)
+ private void KillProcess(int? processId)
{
- string[] _environmentVariablesToRemove = new string[]
+ if (processId == null)
{
- "DNX_COMPILATION_SERVER_PORT",
- };
-
-#if DNX451
- var environmentVariables = procStartInfo.EnvironmentVariables.Keys.Cast();
-#else
- var environmentVariables = procStartInfo.Environment.Keys;
-#endif
-
- var envVarsToRemove = environmentVariables
- .Where(envVar => _environmentVariablesToRemove.Contains(envVar, StringComparer.OrdinalIgnoreCase))
- .ToArray();
-
- // Workaround for the DNX start issue (it passes some environment variables that it shouldn't)
- foreach (var envVar in envVarsToRemove)
- {
-#if DNX451
- procStartInfo.EnvironmentVariables.Remove(envVar);
-#else
- procStartInfo.Environment.Remove(envVar);
-#endif
+ return;
}
+
+ ProcessStartInfo startInfo;
+
+ if (_isWindows)
+ {
+ startInfo = new ProcessStartInfo()
+ {
+ FileName = "taskkill",
+ Arguments = $"/T /F /PID {processId}",
+ };
+ }
+ else
+ {
+ startInfo = new ProcessStartInfo()
+ {
+ FileName = "pkill",
+ Arguments = $"-TERM -P {processId}",
+ };
+ }
+ var killProcess = Process.Start(startInfo);
+ killProcess.WaitForExit();
}
}
}
\ No newline at end of file
diff --git a/src/Microsoft.Dnx.Watcher.Core/Impl/Project.cs b/src/Microsoft.DotNet.Watcher.Core/Impl/Project.cs
similarity index 82%
rename from src/Microsoft.Dnx.Watcher.Core/Impl/Project.cs
rename to src/Microsoft.DotNet.Watcher.Core/Impl/Project.cs
index 04d667c95a..a4e2423206 100644
--- a/src/Microsoft.Dnx.Watcher.Core/Impl/Project.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/Impl/Project.cs
@@ -4,14 +4,13 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using Microsoft.Dnx.Runtime;
-using Microsoft.Extensions.CompilationAbstractions;
+using Microsoft.DotNet.ProjectModel.Graph;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
internal class Project : IProject
{
- public Project(Runtime.Project runtimeProject)
+ public Project(ProjectModel.Project runtimeProject)
{
ProjectFile = runtimeProject.ProjectFilePath;
ProjectDirectory = runtimeProject.ProjectDirectory;
@@ -23,12 +22,11 @@ namespace Microsoft.Dnx.Watcher.Core
new string[] { runtimeProject.ProjectFilePath })
.ToList();
- var projectLockJsonPath = Path.Combine(runtimeProject.ProjectDirectory, LockFileReader.LockFileName);
- var lockFileReader = new LockFileReader();
-
+ var projectLockJsonPath = Path.Combine(runtimeProject.ProjectDirectory, "project.lock.json");
+
if (File.Exists(projectLockJsonPath))
{
- var lockFile = lockFileReader.Read(projectLockJsonPath);
+ var lockFile = LockFileReader.Read(projectLockJsonPath);
ProjectDependencies = lockFile.ProjectLibraries.Select(dep => GetProjectRelativeFullPath(dep.Path)).ToList();
}
else
diff --git a/src/Microsoft.Dnx.Watcher.Core/Impl/ProjectProvider.cs b/src/Microsoft.DotNet.Watcher.Core/Impl/ProjectProvider.cs
similarity index 87%
rename from src/Microsoft.Dnx.Watcher.Core/Impl/ProjectProvider.cs
rename to src/Microsoft.DotNet.Watcher.Core/Impl/ProjectProvider.cs
index 73005c5d15..1336f50829 100644
--- a/src/Microsoft.Dnx.Watcher.Core/Impl/ProjectProvider.cs
+++ b/src/Microsoft.DotNet.Watcher.Core/Impl/ProjectProvider.cs
@@ -5,9 +5,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
-using Microsoft.Extensions.CompilationAbstractions;
+using Microsoft.DotNet.ProjectModel;
-namespace Microsoft.Dnx.Watcher.Core
+namespace Microsoft.DotNet.Watcher.Core
{
public class ProjectProvider : IProjectProvider
{
@@ -16,7 +16,7 @@ namespace Microsoft.Dnx.Watcher.Core
errors = null;
project = null;
- Runtime.Project runtimeProject;
+ ProjectModel.Project runtimeProject;
if (!TryGetProject(projectFile, out runtimeProject, out errors))
{
return false;
@@ -36,12 +36,12 @@ namespace Microsoft.Dnx.Watcher.Core
}
// Same as TryGetProject but it doesn't throw
- private bool TryGetProject(string projectFile, out Runtime.Project project, out string errorMessage)
+ private bool TryGetProject(string projectFile, out ProjectModel.Project project, out string errorMessage)
{
try
{
var errors = new List();
- if (!Runtime.Project.TryGetProject(projectFile, out project, errors))
+ if (!ProjectReader.TryGetProject(projectFile, out project, errors))
{
errorMessage = string.Join(Environment.NewLine, errors.Select(e => e.ToString()));
}
diff --git a/src/Microsoft.Dnx.Watcher.Core/Microsoft.Dnx.Watcher.Core.xproj b/src/Microsoft.DotNet.Watcher.Core/Microsoft.DotNet.Watcher.Core.xproj
similarity index 100%
rename from src/Microsoft.Dnx.Watcher.Core/Microsoft.Dnx.Watcher.Core.xproj
rename to src/Microsoft.DotNet.Watcher.Core/Microsoft.DotNet.Watcher.Core.xproj
diff --git a/src/Microsoft.Dnx.Watcher.Core/Properties/AssemblyInfo.cs b/src/Microsoft.DotNet.Watcher.Core/Properties/AssemblyInfo.cs
similarity index 100%
rename from src/Microsoft.Dnx.Watcher.Core/Properties/AssemblyInfo.cs
rename to src/Microsoft.DotNet.Watcher.Core/Properties/AssemblyInfo.cs
diff --git a/src/Microsoft.Dnx.Watcher.Core/project.json b/src/Microsoft.DotNet.Watcher.Core/project.json
similarity index 71%
rename from src/Microsoft.Dnx.Watcher.Core/project.json
rename to src/Microsoft.DotNet.Watcher.Core/project.json
index b0b659a01b..cb07bfea11 100644
--- a/src/Microsoft.Dnx.Watcher.Core/project.json
+++ b/src/Microsoft.DotNet.Watcher.Core/project.json
@@ -5,6 +5,7 @@
"keyFile": "../../tools/Key.snk"
},
"dependencies": {
+ "Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.Extensions.FileProviders.Abstractions": "1.0.0-*",
"Microsoft.Extensions.FileProviders.Physical": "1.0.0-*",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-*",
@@ -18,18 +19,8 @@
"Microsoft.NETCore.Platforms": "1.0.1-*"
},
"frameworks": {
- "dnx451": {
- "frameworkAssemblies": {
- "System.Collections": "",
- "System.Runtime": ""
- }
- },
"dnxcore50": {
- "dependencies": {
- "System.Diagnostics.Process": "4.1.0-*",
- "System.Linq": "4.0.2-*",
- "System.Threading.Thread": "4.0.0-*"
- }
+ "imports": "portable-net451+win8"
}
}
}
diff --git a/src/Microsoft.Dnx.Watcher/CommandOutputLogger.cs b/src/dotnet-watch/CommandOutputLogger.cs
similarity index 98%
rename from src/Microsoft.Dnx.Watcher/CommandOutputLogger.cs
rename to src/dotnet-watch/CommandOutputLogger.cs
index 59b329d0d1..673f7ee8d8 100644
--- a/src/Microsoft.Dnx.Watcher/CommandOutputLogger.cs
+++ b/src/dotnet-watch/CommandOutputLogger.cs
@@ -5,7 +5,7 @@ using System;
using Microsoft.Extensions.CommandLineUtils;
using Microsoft.Extensions.Logging;
-namespace Microsoft.Dnx.Watcher
+namespace Microsoft.DotNet.Watcher
{
///
/// Logger to print formatted command output.
diff --git a/src/Microsoft.Dnx.Watcher/CommandOutputProvider.cs b/src/dotnet-watch/CommandOutputProvider.cs
similarity index 95%
rename from src/Microsoft.Dnx.Watcher/CommandOutputProvider.cs
rename to src/dotnet-watch/CommandOutputProvider.cs
index ea8fec48dd..fd4945a078 100644
--- a/src/Microsoft.Dnx.Watcher/CommandOutputProvider.cs
+++ b/src/dotnet-watch/CommandOutputProvider.cs
@@ -5,7 +5,7 @@ using System;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.Logging;
-namespace Microsoft.Dnx.Watcher
+namespace Microsoft.DotNet.Watcher
{
public class CommandOutputProvider : ILoggerProvider
{
diff --git a/src/dotnet-watch/Program.cs b/src/dotnet-watch/Program.cs
new file mode 100644
index 0000000000..7f5c0ac257
--- /dev/null
+++ b/src/dotnet-watch/Program.cs
@@ -0,0 +1,139 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.CommandLineUtils;
+using Microsoft.Extensions.PlatformAbstractions;
+using Microsoft.DotNet.Watcher.Core;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.DotNet.Watcher
+{
+ public class Program
+ {
+ private const string AppArgumentSeparator = "--";
+
+ private readonly ILoggerFactory _loggerFactory;
+
+ public Program()
+ {
+ _loggerFactory = new LoggerFactory();
+
+ var commandProvider = new CommandOutputProvider(PlatformServices.Default.Runtime);
+ _loggerFactory.AddProvider(commandProvider);
+ }
+
+ public static int Main(string[] args)
+ {
+ using (CancellationTokenSource ctrlCTokenSource = new CancellationTokenSource())
+ {
+ Console.CancelKeyPress += (sender, ev) =>
+ {
+ ctrlCTokenSource.Cancel();
+ ev.Cancel = false;
+ };
+
+ string[] watchArgs, appArgs;
+ SeparateWatchArguments(args, out watchArgs, out appArgs);
+
+ return new Program().MainInternal(watchArgs, appArgs, ctrlCTokenSource.Token);
+ }
+ }
+
+ // The argument separation rules are: if no "--" is encountered, all arguments are passed to the app being watched.
+ // Unless, the argument is "--help", in which case the help for the watcher is being invoked and everything else is discarded.
+ // To pass arguments to both the watcher and the app use "--" as separator.
+ // To pass "--help" to the app being watched, you must use "--": dotnet watch -- --help
+ internal static void SeparateWatchArguments(string[] args, out string[] watchArgs, out string[] appArgs)
+ {
+ // Special case "--help"
+ if (args.Length > 0 && (
+ args[0].Equals("--help", StringComparison.OrdinalIgnoreCase) ||
+ args[0].Equals("-h", StringComparison.OrdinalIgnoreCase) ||
+ args[0].Equals("-?", StringComparison.OrdinalIgnoreCase)))
+ {
+ watchArgs = new string[] { args[0] };
+ appArgs = new string[0];
+ return;
+ }
+
+ int argsIndex = -1;
+ watchArgs = args.TakeWhile((arg, idx) =>
+ {
+ argsIndex = idx;
+ return !string.Equals(arg, AppArgumentSeparator, StringComparison.OrdinalIgnoreCase);
+ }).ToArray();
+
+ appArgs = args.Skip(argsIndex + 1).ToArray();
+
+ if (appArgs.Length == 0)
+ {
+ // If no explicit watcher arguments then all arguments get passed to the app being watched
+ appArgs = watchArgs;
+ watchArgs = new string[0];
+ }
+ }
+
+ private int MainInternal(string[] watchArgs, string[] appArgs, CancellationToken cancellationToken)
+ {
+ var app = new CommandLineApplication();
+ app.Name = "dotnet-watch";
+ app.FullName = "Microsoft dotnet File Watcher";
+
+ app.HelpOption("-?|-h|--help");
+
+ var commandArg = app.Option(
+ "--command ",
+ "Optional. The dotnet command to run. Default: 'run'.",
+ CommandOptionType.SingleValue);
+
+ var workingDirArg = app.Option(
+ "--working-dir ",
+ "Optional. The working directory. Default: project's directory.",
+ CommandOptionType.SingleValue);
+
+ var exitOnChangeArg = app.Option(
+ "--exit-on-change",
+ "Optional. The watcher will exit when a file change is detected instead of restarting the process. Default: not set.",
+ CommandOptionType.NoValue);
+
+
+ app.OnExecute(() =>
+ {
+ var projectToWatch = Path.Combine(Directory.GetCurrentDirectory(), ProjectModel.Project.FileName);
+
+ var workingDir = workingDirArg.HasValue() ?
+ workingDirArg.Value() :
+ Path.GetDirectoryName(projectToWatch);
+
+ var command = commandArg.HasValue() ?
+ commandArg.Value() :
+ "run";
+
+ var watcher = DotNetWatcher.CreateDefault(_loggerFactory);
+ watcher.ExitOnChange = exitOnChangeArg.HasValue();
+
+ try
+ {
+ watcher.WatchAsync(projectToWatch, command, appArgs, workingDir, cancellationToken).Wait();
+ }
+ catch (AggregateException ex)
+ {
+ if (ex.InnerExceptions.Count != 1 || !(ex.InnerException is TaskCanceledException))
+ {
+ throw;
+ }
+ }
+
+
+ return 1;
+ });
+
+ return app.Execute(watchArgs);
+ }
+ }
+}
diff --git a/src/dotnet-watch/Properties/AssemblyInfo.cs b/src/dotnet-watch/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..a78f66dc06
--- /dev/null
+++ b/src/dotnet-watch/Properties/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+
+[assembly:InternalsVisibleTo("dotnet-watch.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
+[assembly: AssemblyMetadata("Serviceable", "True")]
+[assembly: NeutralResourcesLanguage("en-US")]
diff --git a/src/Microsoft.Dnx.Watcher/Microsoft.Dnx.Watcher.xproj b/src/dotnet-watch/dotnet-watch.xproj
similarity index 100%
rename from src/Microsoft.Dnx.Watcher/Microsoft.Dnx.Watcher.xproj
rename to src/dotnet-watch/dotnet-watch.xproj
diff --git a/src/Microsoft.Dnx.Watcher/project.json b/src/dotnet-watch/project.json
similarity index 66%
rename from src/Microsoft.Dnx.Watcher/project.json
rename to src/dotnet-watch/project.json
index c8fc4080ac..dbe7a7ec35 100644
--- a/src/Microsoft.Dnx.Watcher/project.json
+++ b/src/dotnet-watch/project.json
@@ -6,23 +6,15 @@
"keyFile": "../../tools/Key.snk"
},
"dependencies": {
- "Microsoft.Dnx.Watcher.Core": "1.0.0-*",
+ "Microsoft.DotNet.Watcher.Core": "1.0.0-*",
"Microsoft.Extensions.CommandLineUtils": "1.0.0-*",
"Microsoft.Extensions.Logging": "1.0.0-*",
"Microsoft.Extensions.Logging.Console": "1.0.0-*",
"Microsoft.NETCore.Platforms": "1.0.1-*"
},
"frameworks": {
- "dnx451": { },
- "dnxcore50": { }
- },
-
- "commands": {
- "dnx-watch": "Microsoft.Dnx.Watcher"
- },
-
- "scripts": {
- "postbuild": [
- ]
+ "dnxcore50": {
+ "imports": "portable-net451+win8"
+ }
}
}
diff --git a/test/Microsoft.Dnx.Watcher.Tests/CommandLineParsingTests.cs b/test/Microsoft.Dnx.Watcher.Tests/CommandLineParsingTests.cs
deleted file mode 100644
index c4ac14008b..0000000000
--- a/test/Microsoft.Dnx.Watcher.Tests/CommandLineParsingTests.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using Xunit;
-
-namespace Microsoft.Dnx.Watcher.Tests
-{
- // This project can output the Class library as a NuGet Package.
- // To enable this option, right-click on the project and select the Properties menu item. In the Build tab select "Produce outputs on build".
- public class CommandLineParsingTests
- {
- [Fact]
- public void NoWatcherArgs()
- {
- var args = "--arg1 v1 --arg2 v2".Split(' ');
-
- string[] watcherArgs, dnxArgs;
- Program.SeparateWatchArguments(args, out watcherArgs, out dnxArgs);
-
- Assert.Empty(watcherArgs);
- Assert.Equal(args, dnxArgs);
- }
-
- [Fact]
- public void ArgsForBothDnxAndWatcher()
- {
- var args = "--arg1 v1 --arg2 v2 --dnx-args --arg3 --arg4 v4".Split(' ');
-
- string[] watcherArgs, dnxArgs;
- Program.SeparateWatchArguments(args, out watcherArgs, out dnxArgs);
-
- Assert.Equal(new string[] {"--arg1", "v1", "--arg2", "v2" }, watcherArgs);
- Assert.Equal(new string[] { "--arg3", "--arg4", "v4" }, dnxArgs);
- }
-
- [Fact]
- public void MultipleSeparators()
- {
- var args = "--arg1 v1 --arg2 v2 --dnx-args --arg3 --dnxArgs --arg4 v4".Split(' ');
-
- string[] watcherArgs, dnxArgs;
- Program.SeparateWatchArguments(args, out watcherArgs, out dnxArgs);
-
- Assert.Equal(new string[] { "--arg1", "v1", "--arg2", "v2" }, watcherArgs);
- Assert.Equal(new string[] { "--arg3", "--dnxArgs", "--arg4", "v4" }, dnxArgs);
- }
- }
-}
diff --git a/test/Microsoft.Dnx.Watcher.Tests/Microsoft.Dnx.Watcher.Tests.xproj b/test/Microsoft.Dnx.Watcher.Tests/Microsoft.Dnx.Watcher.Tests.xproj
deleted file mode 100644
index 7c8ac87ba2..0000000000
--- a/test/Microsoft.Dnx.Watcher.Tests/Microsoft.Dnx.Watcher.Tests.xproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- 640d190b-26db-4dde-88ee-55814c86c43e
- Microsoft.Dnx.Watcher.Tests
- ..\artifacts\obj\$(MSBuildProjectName)
- ..\artifacts\bin\$(MSBuildProjectName)\
-
-
- 2.0
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/Microsoft.Dnx.Watcher.Tests/project.json b/test/Microsoft.Dnx.Watcher.Tests/project.json
deleted file mode 100644
index f613c1cefc..0000000000
--- a/test/Microsoft.Dnx.Watcher.Tests/project.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "compilationOptions": {
- "warningsAsErrors": true,
- "keyFile": "../../tools/Key.snk"
- },
- "dependencies": {
- "Microsoft.Extensions.PlatformAbstractions": "1.0.0-*",
- "Microsoft.Dnx.Watcher": "1.0.0-*",
- "Microsoft.NETCore.Platforms": "1.0.1-*",
- "xunit.runner.aspnet": "2.0.0-aspnet-*"
- },
- "frameworks": {
- "dnx451": { },
- "dnxcore50": { }
- },
- "commands": {
- "test": "xunit.runner.aspnet"
- }
-}
-