merge my spike on compile/publish/run and switch from PS1 to C#
This commit is contained in:
commit
43873a37b5
43 changed files with 4298 additions and 117 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -49,4 +49,4 @@
|
||||||
*.vbproj text=auto
|
*.vbproj text=auto
|
||||||
*.fsproj text=auto
|
*.fsproj text=auto
|
||||||
*.dbproj text=auto
|
*.dbproj text=auto
|
||||||
*.sln text=auto eol=crlf
|
*.sln text=auto eol=crlf
|
|
@ -3,7 +3,8 @@
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
|
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
|
||||||
<clear />
|
<clear />
|
||||||
<add key="www.myget.org" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
|
<add key="AspNetCIDev" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
|
||||||
|
<add key="dotnet-core" value="https://www.myget.org/F/dotnet-core/api/v3/index.json" />
|
||||||
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
|
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
44
dotnet-cli.sln
Normal file
44
dotnet-cli.sln
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.23107.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1F391100-F011-4630-8C25-D1A5355E4F19}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5AB144A3-3D0A-4DC7-9EE8-19FDD2DF8735}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
dotnet-compile.cmd = dotnet-compile.cmd
|
||||||
|
dotnet-run.cmd = dotnet-run.cmd
|
||||||
|
global.json = global.json
|
||||||
|
NuGet.Config = NuGet.Config
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{47858134-8A8D-4D5C-ABD5-E6630A66DA05}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestApp", "test\TestApp\TestApp.xproj", "{58808BBC-371E-47D6-A3D0-4902145EDA4E}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DotNet.Tools.DependencyResolver", "src\DotNet.Tools.DependencyResolver\DotNet.Tools.DependencyResolver.xproj", "{A5D41198-209A-461B-A191-F48B9DBECD67}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A5D41198-209A-461B-A191-F48B9DBECD67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A5D41198-209A-461B-A191-F48B9DBECD67}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A5D41198-209A-461B-A191-F48B9DBECD67}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A5D41198-209A-461B-A191-F48B9DBECD67}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{58808BBC-371E-47D6-A3D0-4902145EDA4E} = {47858134-8A8D-4D5C-ABD5-E6630A66DA05}
|
||||||
|
{A5D41198-209A-461B-A191-F48B9DBECD67} = {1F391100-F011-4630-8C25-D1A5355E4F19}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
30
dotnet-compile.ps1
Normal file
30
dotnet-compile.ps1
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
$OutputName = Split-Path -Leaf (Get-Location)
|
||||||
|
$OutputPath = Join-Path (Get-Location) "bin"
|
||||||
|
|
||||||
|
if(!(Test-Path $OutputPath)) {
|
||||||
|
mkdir $OutputPath | Out-Null
|
||||||
|
}
|
||||||
|
$OutputPath = (Convert-Path $OutputPath)
|
||||||
|
|
||||||
|
|
||||||
|
# Resolve compilation dependencies
|
||||||
|
Write-Host "Resolving dependencies..."
|
||||||
|
$refs = dnx -p "$PSScriptRoot\src\DotNet.Tools.DependencyResolver" run --packages "$env:USERPROFILE\.dnx\packages" --target "DNXCore,Version=v5.0" --assets compile
|
||||||
|
|
||||||
|
# Resolve source files
|
||||||
|
Write-Host "Finding source files..."
|
||||||
|
$srcs = dnx -p "$PSScriptRoot\src\DotNet.Tools.SourceResolver" run
|
||||||
|
|
||||||
|
# Build csc response file
|
||||||
|
$resp = @($refs | foreach { "/r:$_" })
|
||||||
|
$resp += @($srcs | foreach { $_ })
|
||||||
|
$resp += @(
|
||||||
|
"/out:$OutputPath\$OutputName.dll"
|
||||||
|
"/nostdlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "Compiling..."
|
||||||
|
$resp > "$OutputPath\csc.rsp"
|
||||||
|
csc "@$OutputPath\csc.rsp"
|
||||||
|
|
||||||
|
Write-Host " $OutputName -> $OutputPath\$OutputName.dll"
|
31
dotnet-publish.ps1
Normal file
31
dotnet-publish.ps1
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
$OutputName = Split-Path -Leaf (Get-Location)
|
||||||
|
$OutputPath = Join-Path (Join-Path (Get-Location) "bin") "publish"
|
||||||
|
|
||||||
|
& $PSScriptRoot\dotnet-compile.ps1
|
||||||
|
|
||||||
|
if(Test-Path $OutputPath) {
|
||||||
|
del -Recurse -Force $OutputPath
|
||||||
|
}
|
||||||
|
mkdir $OutputPath | Out-Null
|
||||||
|
$OutputPath = (Convert-Path $OutputPath)
|
||||||
|
|
||||||
|
# Resolve runtime and native dependencies
|
||||||
|
Write-Host "Resolving dependencies..."
|
||||||
|
$refs = dnx -p "$PSScriptRoot\src\DotNet.Tools.DependencyResolver" run --packages "$env:USERPROFILE\.dnx\packages" --target "DNXCore,Version=v5.0/win7-x64" --assets runtime --assets native
|
||||||
|
|
||||||
|
# Copy everything to one directory
|
||||||
|
$refs | foreach {
|
||||||
|
Write-Host "Publishing $_ ..."
|
||||||
|
cp $_ $OutputPath
|
||||||
|
}
|
||||||
|
|
||||||
|
$ProjectBinary = (Join-Path (Get-Location) "bin\$OutputName.dll")
|
||||||
|
Write-Host "Publishing $ProjectBinary ..."
|
||||||
|
cp $ProjectBinary $OutputPath
|
||||||
|
|
||||||
|
# CoreConsole should have come along for the ride
|
||||||
|
$CoreConsolePath = Join-Path $OutputPath "CoreConsole.exe"
|
||||||
|
if(!(Test-Path $CoreConsolePath)) {
|
||||||
|
throw "Unable to locate CoreConsole.exe. You must have a dependency on Microsoft.NETCore.ConsoleHost (for now ;))"
|
||||||
|
}
|
||||||
|
mv $CoreConsolePath (Join-Path $OutputPath "$OutputName.exe")
|
|
@ -1 +1,17 @@
|
||||||
exec "dnu" "build" "$@"
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
|
# work around restore timeouts on Mono
|
||||||
|
[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50
|
||||||
|
|
||||||
|
# Makes development easier
|
||||||
|
export PATH=$PATH:$DIR
|
||||||
|
|
||||||
|
exec "dnx" -p "$DIR/../src/Microsoft.DotNet.Tools.Compiler" run "$@"
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
SETLOCAL
|
SETLOCAL
|
||||||
SET ERRORLEVEL=
|
SET ERRORLEVEL=
|
||||||
|
|
||||||
dnu build %*
|
REM makes testing easier for now
|
||||||
|
set PATH=%PATH%;%~dp0
|
||||||
|
|
||||||
|
dnx %DOTNET_OPTIONS% -p %~dp0..\src\Microsoft.DotNet.Tools.Compiler run %*
|
||||||
|
|
||||||
exit /b %ERRORLEVEL%
|
exit /b %ERRORLEVEL%
|
||||||
ENDLOCAL
|
ENDLOCAL
|
||||||
|
|
17
scripts/dotnet-publish
Normal file
17
scripts/dotnet-publish
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
|
# work around restore timeouts on Mono
|
||||||
|
[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50
|
||||||
|
|
||||||
|
# Makes development easier
|
||||||
|
export PATH=$PATH:$DIR
|
||||||
|
|
||||||
|
exec "dnx" -p "$DIR/../src/Microsoft.DotNet.Tools.Publish" run "$@"
|
11
scripts/dotnet-publish.cmd
Normal file
11
scripts/dotnet-publish.cmd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
@Echo OFF
|
||||||
|
SETLOCAL
|
||||||
|
SET ERRORLEVEL=
|
||||||
|
|
||||||
|
REM makes testing easier for now
|
||||||
|
set PATH=%PATH%;%~dp0
|
||||||
|
|
||||||
|
dnx %DOTNET_OPTIONS% -p %~dp0..\src\Microsoft.DotNet.Tools.Publish run %*
|
||||||
|
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
|
ENDLOCAL
|
17
scripts/dotnet-resolve-references
Normal file
17
scripts/dotnet-resolve-references
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
|
# work around restore timeouts on Mono
|
||||||
|
[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50
|
||||||
|
|
||||||
|
# Makes development easier
|
||||||
|
export PATH=$PATH:$DIR
|
||||||
|
|
||||||
|
exec "dnx" -p "$DIR/../src/Microsoft.DotNet.Tools.DependencyResolver" run "$@"
|
11
scripts/dotnet-resolve-references.cmd
Normal file
11
scripts/dotnet-resolve-references.cmd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
@Echo OFF
|
||||||
|
SETLOCAL
|
||||||
|
SET ERRORLEVEL=
|
||||||
|
|
||||||
|
REM makes testing easier for now
|
||||||
|
set PATH=%PATH%;%~dp0
|
||||||
|
|
||||||
|
dnx %DOTNET_OPTIONS% -p %~dp0..\src\Microsoft.DotNet.Tools.DependencyResolver run %*
|
||||||
|
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
|
ENDLOCAL
|
17
scripts/dotnet-resolve-sources
Normal file
17
scripts/dotnet-resolve-sources
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
|
# work around restore timeouts on Mono
|
||||||
|
[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50
|
||||||
|
|
||||||
|
# Makes development easier
|
||||||
|
export PATH=$PATH:$DIR
|
||||||
|
|
||||||
|
exec "dnx" -p "$DIR/../src/Microsoft.DotNet.Tools.SourceResolver" run "$@"
|
11
scripts/dotnet-resolve-sources.cmd
Normal file
11
scripts/dotnet-resolve-sources.cmd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
@Echo OFF
|
||||||
|
SETLOCAL
|
||||||
|
SET ERRORLEVEL=
|
||||||
|
|
||||||
|
REM makes testing easier for now
|
||||||
|
set PATH=%PATH%;%~dp0
|
||||||
|
|
||||||
|
dnx %DOTNET_OPTIONS% -p %~dp0..\src\Microsoft.DotNet.Tools.SourceResolver run %*
|
||||||
|
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
|
ENDLOCAL
|
17
scripts/dotnet-run
Normal file
17
scripts/dotnet-run
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SOURCE="${BASH_SOURCE[0]}"
|
||||||
|
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
SOURCE="$(readlink "$SOURCE")"
|
||||||
|
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||||
|
done
|
||||||
|
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
|
|
||||||
|
# work around restore timeouts on Mono
|
||||||
|
[ -z "$MONO_THREADS_PER_CPU" ] && export MONO_THREADS_PER_CPU=50
|
||||||
|
|
||||||
|
# Makes development easier
|
||||||
|
export PATH=$PATH:$DIR
|
||||||
|
|
||||||
|
exec "dnx" -p "$DIR/../src/Microsoft.DotNet.Tools.Run" run "$@"
|
11
scripts/dotnet-run.cmd
Normal file
11
scripts/dotnet-run.cmd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
@Echo OFF
|
||||||
|
SETLOCAL
|
||||||
|
SET ERRORLEVEL=
|
||||||
|
|
||||||
|
REM makes testing easier for now
|
||||||
|
set PATH=%PATH%;%~dp0
|
||||||
|
|
||||||
|
dnx %DOTNET_OPTIONS% -p %~dp0..\src\Microsoft.DotNet.Tools.Run run %*
|
||||||
|
|
||||||
|
exit /b %ERRORLEVEL%
|
||||||
|
ENDLOCAL
|
187
src/Microsoft.DotNet.Cli.Utils/Command.cs
Normal file
187
src/Microsoft.DotNet.Cli.Utils/Command.cs
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Cli.Utils
|
||||||
|
{
|
||||||
|
public class Command
|
||||||
|
{
|
||||||
|
private TaskCompletionSource<int> _processTcs;
|
||||||
|
private Process _process;
|
||||||
|
|
||||||
|
private StringWriter _stdOutCapture;
|
||||||
|
private StringWriter _stdErrCapture;
|
||||||
|
|
||||||
|
private TextWriter _stdOutForward;
|
||||||
|
private TextWriter _stdErrForward;
|
||||||
|
|
||||||
|
private Action<string> _stdOutHandler;
|
||||||
|
private Action<string> _stdErrHandler;
|
||||||
|
|
||||||
|
private bool _running = false;
|
||||||
|
|
||||||
|
private Command(string executable, string args)
|
||||||
|
{
|
||||||
|
// Set the things we need
|
||||||
|
var psi = new ProcessStartInfo()
|
||||||
|
{
|
||||||
|
FileName = executable,
|
||||||
|
Arguments = args,
|
||||||
|
RedirectStandardError = true,
|
||||||
|
RedirectStandardOutput = true
|
||||||
|
};
|
||||||
|
|
||||||
|
_processTcs = new TaskCompletionSource<int>();
|
||||||
|
|
||||||
|
_process = new Process()
|
||||||
|
{
|
||||||
|
StartInfo = psi
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Command Create(string executable, IEnumerable<string> args)
|
||||||
|
{
|
||||||
|
return Create(executable, args.Any() ? string.Join(" ", args) : string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Command Create(string executable, string args)
|
||||||
|
{
|
||||||
|
var comSpec = Environment.GetEnvironmentVariable("ComSpec");
|
||||||
|
if (!string.IsNullOrEmpty(comSpec))
|
||||||
|
{
|
||||||
|
// cmd doesn't like "foo.exe ", so we need to ensure that if
|
||||||
|
// args is empty, we just run "foo.exe"
|
||||||
|
if (!string.IsNullOrEmpty(args))
|
||||||
|
{
|
||||||
|
args = " " + args;
|
||||||
|
}
|
||||||
|
args = $"/C \"{executable}{args}\"";
|
||||||
|
executable = comSpec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Temporary, we're doing this so that redirecting the output works
|
||||||
|
args = $"bash -c \"{executable} {args.Replace("\"", "\\\"")}\"";
|
||||||
|
executable = "/usr/bin/env";
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Command(executable, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CommandResult> RunAsync()
|
||||||
|
{
|
||||||
|
ThrowIfRunning();
|
||||||
|
_running = true;
|
||||||
|
|
||||||
|
_process.OutputDataReceived += (sender, args) =>
|
||||||
|
ProcessData(args.Data, _stdOutCapture, _stdOutForward, _stdOutHandler);
|
||||||
|
|
||||||
|
_process.ErrorDataReceived += (sender, args) =>
|
||||||
|
ProcessData(args.Data, _stdErrCapture, _stdErrForward, _stdErrHandler);
|
||||||
|
|
||||||
|
_process.EnableRaisingEvents = true;
|
||||||
|
|
||||||
|
_process.Exited += (sender, _) =>
|
||||||
|
_processTcs.SetResult(_process.ExitCode);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
Console.WriteLine($"> {_process.StartInfo.FileName} {_process.StartInfo.Arguments}");
|
||||||
|
#endif
|
||||||
|
_process.Start();
|
||||||
|
_process.BeginOutputReadLine();
|
||||||
|
_process.BeginErrorReadLine();
|
||||||
|
|
||||||
|
var exitCode = await _processTcs.Task;
|
||||||
|
|
||||||
|
return new CommandResult(
|
||||||
|
exitCode,
|
||||||
|
_stdOutCapture?.GetStringBuilder()?.ToString(),
|
||||||
|
_stdErrCapture?.GetStringBuilder()?.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command CaptureStdOut()
|
||||||
|
{
|
||||||
|
ThrowIfRunning();
|
||||||
|
_stdOutCapture = new StringWriter();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command CaptureStdErr()
|
||||||
|
{
|
||||||
|
ThrowIfRunning();
|
||||||
|
_stdErrCapture = new StringWriter();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command ForwardStdOut(TextWriter to = null)
|
||||||
|
{
|
||||||
|
ThrowIfRunning();
|
||||||
|
_stdOutForward = to ?? Console.Out;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command ForwardStdErr(TextWriter to = null)
|
||||||
|
{
|
||||||
|
ThrowIfRunning();
|
||||||
|
_stdErrForward = to ?? Console.Error;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command OnOutputLine(Action<string> handler)
|
||||||
|
{
|
||||||
|
ThrowIfRunning();
|
||||||
|
if (_stdOutHandler != null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Already handling stdout!");
|
||||||
|
}
|
||||||
|
_stdOutHandler = handler;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command OnErrorLine(Action<string> handler)
|
||||||
|
{
|
||||||
|
ThrowIfRunning();
|
||||||
|
if (_stdErrHandler != null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Already handling stderr!");
|
||||||
|
}
|
||||||
|
_stdErrHandler = handler;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThrowIfRunning([CallerMemberName] string memberName = null)
|
||||||
|
{
|
||||||
|
if (_running)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Unable to invoke {memberName} after the command has been run");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessData(string data, StringWriter capture, TextWriter forward, Action<string> handler)
|
||||||
|
{
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capture != null)
|
||||||
|
{
|
||||||
|
capture.WriteLine(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forward != null)
|
||||||
|
{
|
||||||
|
forward.WriteLine(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
src/Microsoft.DotNet.Cli.Utils/CommandResult.cs
Normal file
18
src/Microsoft.DotNet.Cli.Utils/CommandResult.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Cli.Utils
|
||||||
|
{
|
||||||
|
public struct CommandResult
|
||||||
|
{
|
||||||
|
public int ExitCode { get; }
|
||||||
|
public string StdOut { get; }
|
||||||
|
public string StdErr { get; }
|
||||||
|
|
||||||
|
public CommandResult(int exitCode, string stdOut, string stdErr)
|
||||||
|
{
|
||||||
|
ExitCode = exitCode;
|
||||||
|
StdOut = stdOut;
|
||||||
|
StdErr = stdErr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/Microsoft.DotNet.Cli.Utils/Constants.cs
Normal file
14
src/Microsoft.DotNet.Cli.Utils/Constants.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Cli.Utils
|
||||||
|
{
|
||||||
|
internal static class Constants
|
||||||
|
{
|
||||||
|
// TODO: On Unix, exe suffix is empty string...
|
||||||
|
public static readonly string ExeSuffix = ".exe";
|
||||||
|
public static readonly string CoreConsoleName = "coreconsole" + ExeSuffix;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>61b7c351-c77d-43f7-b56f-bb1440178e10</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.DotNet.Cli.Utils</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
13
src/Microsoft.DotNet.Cli.Utils/project.json
Normal file
13
src/Microsoft.DotNet.Cli.Utils/project.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"shared": "**/*.cs",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"System.Console": "4.0.0-*",
|
||||||
|
"System.Diagnostics.Process": "4.1.0-*"
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli
|
namespace Microsoft.DotNet.Cli
|
||||||
{
|
{
|
||||||
|
@ -10,117 +8,19 @@ namespace Microsoft.DotNet.Cli
|
||||||
{
|
{
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
{
|
{
|
||||||
var app = new CommandLineApplication();
|
if (args.Length < 1)
|
||||||
app.Name = "dotnet";
|
|
||||||
app.Description = "The .NET CLI";
|
|
||||||
|
|
||||||
// Most commonly used commands
|
|
||||||
app.Command("init", c =>
|
|
||||||
{
|
{
|
||||||
c.Description = "Scaffold a basic .NET application";
|
// Handle missing args
|
||||||
|
Console.Error.WriteLine("TODO: Help");
|
||||||
c.OnExecute(() => Exec("dotnet-init", c.RemainingArguments));
|
return 1;
|
||||||
});
|
|
||||||
|
|
||||||
app.Command("compile", c =>
|
|
||||||
{
|
|
||||||
c.Description = "Produce assemblies for the project in given directory";
|
|
||||||
|
|
||||||
c.OnExecute(() => Exec("dotnet-compile", c.RemainingArguments));
|
|
||||||
});
|
|
||||||
|
|
||||||
app.Command("restore", c =>
|
|
||||||
{
|
|
||||||
c.Description = "Restore packages";
|
|
||||||
|
|
||||||
c.OnExecute(() => Exec("dotnet-restore", c.RemainingArguments));
|
|
||||||
});
|
|
||||||
|
|
||||||
app.Command("pack", c =>
|
|
||||||
{
|
|
||||||
c.Description = "Produce a NuGet package";
|
|
||||||
|
|
||||||
c.OnExecute(() => Exec("dotnet-pack", c.RemainingArguments));
|
|
||||||
});
|
|
||||||
|
|
||||||
app.Command("publish", c =>
|
|
||||||
{
|
|
||||||
c.Description = "Produce deployable assets";
|
|
||||||
|
|
||||||
c.OnExecute(() => Exec("dotnet-publish", c.RemainingArguments));
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: Handle unknown commands
|
|
||||||
|
|
||||||
app.OnExecute(() =>
|
|
||||||
{
|
|
||||||
app.ShowHelp();
|
|
||||||
return 2;
|
|
||||||
});
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return app.Execute(args);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Exec(string executable, IList<string> args)
|
|
||||||
{
|
|
||||||
var comSpec = Environment.GetEnvironmentVariable("ComSpec");
|
|
||||||
if (!string.IsNullOrEmpty(comSpec))
|
|
||||||
{
|
|
||||||
args =
|
|
||||||
new[] { "/C", "\"", executable }
|
|
||||||
.Concat(args)
|
|
||||||
.Concat(new[] { "\"" })
|
|
||||||
.ToArray();
|
|
||||||
executable = comSpec;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Temporary, we're doing this so that redirecting the output works
|
|
||||||
args = new[] { "bash", "-c", "\"", executable }
|
|
||||||
.Concat(args.Select(argument => argument.Replace("\"", "\\\"")))
|
|
||||||
.Concat(new[] { "\"" })
|
|
||||||
.ToArray();
|
|
||||||
executable = "/usr/bin/env";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var psi = new ProcessStartInfo
|
return Command.Create("dotnet-" + args[0], args.Skip(1))
|
||||||
{
|
.ForwardStdErr(Console.Error)
|
||||||
FileName = executable,
|
.ForwardStdOut(Console.Out)
|
||||||
Arguments = string.Join(" ", args),
|
.RunAsync()
|
||||||
UseShellExecute = false,
|
.Result
|
||||||
CreateNoWindow = true,
|
.ExitCode;
|
||||||
RedirectStandardError = true,
|
|
||||||
RedirectStandardOutput = true
|
|
||||||
};
|
|
||||||
|
|
||||||
var process = Process.Start(psi);
|
|
||||||
process.ErrorDataReceived += OnProcessErrorDataReceived;
|
|
||||||
process.OutputDataReceived += OnProcessOutputDataReceived;
|
|
||||||
|
|
||||||
process.BeginErrorReadLine();
|
|
||||||
process.BeginOutputReadLine();
|
|
||||||
|
|
||||||
process.WaitForExit();
|
|
||||||
|
|
||||||
return process.ExitCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnProcessOutputDataReceived(object sender, DataReceivedEventArgs e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnProcessErrorDataReceived(object sender, DataReceivedEventArgs e)
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine(e.Data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
"System.Collections": "4.0.11-*",
|
"System.Collections": "4.0.11-*",
|
||||||
"System.Linq": "4.0.1-*",
|
"System.Linq": "4.0.1-*",
|
||||||
"System.Diagnostics.Process": "4.1.0-*",
|
"System.Diagnostics.Process": "4.1.0-*",
|
||||||
"Microsoft.Framework.CommandLineUtils.Sources": {
|
"Microsoft.DotNet.Cli.Utils": {
|
||||||
"type": "build",
|
"type": "build",
|
||||||
"version": "1.0.0-*"
|
"version": "1.0.0-*"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>0a309227-a9d8-4ddf-88dd-326b57b04378</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.DotNet.Tools.Compiler</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
134
src/Microsoft.DotNet.Tools.Compiler/Program.cs
Normal file
134
src/Microsoft.DotNet.Tools.Compiler/Program.cs
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandLineApplication();
|
||||||
|
app.Name = "dotnet compile";
|
||||||
|
app.FullName = ".NET Compiler";
|
||||||
|
app.Description = "Compiler for the .NET Platform";
|
||||||
|
app.HelpOption("-h|--help");
|
||||||
|
|
||||||
|
var output = app.Option("-o|--output <OUTPUT_DIR>", "Directory in which to place outputs", CommandOptionType.SingleValue);
|
||||||
|
var framework = app.Option("-f|--framework <FRAMEWORK>", "Target framework to compile for", CommandOptionType.SingleValue);
|
||||||
|
var project = app.Argument("<PROJECT>", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory");
|
||||||
|
|
||||||
|
app.OnExecute(() =>
|
||||||
|
{
|
||||||
|
// Validate arguments
|
||||||
|
CheckArg(framework, "--framework");
|
||||||
|
|
||||||
|
// Locate the project and get the name and full path
|
||||||
|
var path = project.Value;
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
path = Directory.GetCurrentDirectory();
|
||||||
|
}
|
||||||
|
if (!string.Equals(Path.GetFileName(path), "project.json", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
path = Path.Combine(path, "project.json");
|
||||||
|
}
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Could not find project: {path}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
var dir = new FileInfo(path).Directory;
|
||||||
|
|
||||||
|
return Compile(path, framework.Value(), dir, output.Value());
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return app.Execute(args);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException ex)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine(ex.Message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckArg(CommandOption argument, string name)
|
||||||
|
{
|
||||||
|
if (!argument.HasValue())
|
||||||
|
{
|
||||||
|
// TODO: GROOOOOOSS
|
||||||
|
throw new OperationCanceledException($"Missing required argument: {name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int Compile(string path, string framework, DirectoryInfo projectDir, string outputPath)
|
||||||
|
{
|
||||||
|
// Make output directory
|
||||||
|
// TODO(anurse): per-framework and per-configuration output dir
|
||||||
|
// TODO(anurse): configurable base output dir? (maybe dotnet compile doesn't support that?)
|
||||||
|
if (string.IsNullOrEmpty(outputPath))
|
||||||
|
{
|
||||||
|
outputPath = Path.Combine(projectDir.FullName, "bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(outputPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve compilation references
|
||||||
|
var result = Command.Create("dotnet-resolve-references", $"--framework {framework} --assets compile {path}")
|
||||||
|
.CaptureStdOut()
|
||||||
|
.ForwardStdErr(Console.Error)
|
||||||
|
.RunAsync()
|
||||||
|
.Result;
|
||||||
|
if(result.ExitCode != 0)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Failed to resolve references");
|
||||||
|
return result.ExitCode;
|
||||||
|
}
|
||||||
|
var references = result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
// Resolve source files
|
||||||
|
result = Command.Create("dotnet-resolve-sources", $"{path}")
|
||||||
|
.CaptureStdOut()
|
||||||
|
.ForwardStdErr(Console.Error)
|
||||||
|
.RunAsync()
|
||||||
|
.Result;
|
||||||
|
if(result.ExitCode != 0)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Failed to resolve sources");
|
||||||
|
return result.ExitCode;
|
||||||
|
}
|
||||||
|
var sources = result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
// Build csc args
|
||||||
|
var cscArgs = new[]
|
||||||
|
{
|
||||||
|
"/nostdlib",
|
||||||
|
$"/out:{Path.Combine(outputPath, projectDir.Name + ".dll")}"
|
||||||
|
}
|
||||||
|
.Concat(references.Select(r => $"/r:{r}"))
|
||||||
|
.Concat(sources);
|
||||||
|
var rsp = Path.Combine(outputPath, "csc.rsp");
|
||||||
|
if(File.Exists(rsp))
|
||||||
|
{
|
||||||
|
File.Delete(rsp);
|
||||||
|
}
|
||||||
|
File.WriteAllLines(rsp, cscArgs);
|
||||||
|
|
||||||
|
// Run csc
|
||||||
|
return Command.Create("csc", $"@{rsp}")
|
||||||
|
.ForwardStdErr(Console.Error)
|
||||||
|
.ForwardStdOut(Console.Out)
|
||||||
|
.RunAsync()
|
||||||
|
.Result
|
||||||
|
.ExitCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/Microsoft.DotNet.Tools.Compiler/project.json
Normal file
27
src/Microsoft.DotNet.Tools.Compiler/project.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"compilationOptions": {
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"dotnet-compile": "Microsoft.DotNet.Cli"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"System.Console": "4.0.0-*",
|
||||||
|
"System.Collections": "4.0.11-*",
|
||||||
|
"System.Linq": "4.0.1-*",
|
||||||
|
"System.Diagnostics.Process": "4.1.0-*",
|
||||||
|
"System.IO.FileSystem": "4.0.1-*",
|
||||||
|
"Microsoft.DotNet.Cli.Utils": {
|
||||||
|
"type": "build",
|
||||||
|
"version": "1.0.0-*"
|
||||||
|
},
|
||||||
|
"Microsoft.Framework.CommandLineUtils.Sources": {
|
||||||
|
"type": "build",
|
||||||
|
"version": "1.0.0-*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>4298df4a-e04c-4ed9-95f8-fbb7cb32721f</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.DotNet.Tools.DependencyResolver</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
100
src/Microsoft.DotNet.Tools.DependencyResolver/Program.cs
Normal file
100
src/Microsoft.DotNet.Tools.DependencyResolver/Program.cs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||||
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
|
namespace DotNet.Tools.DependencyResolver
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public void Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandLineApplication();
|
||||||
|
app.HelpOption("-h|--help");
|
||||||
|
app.Description = "Resolves the absolute path of all dependencies for a project";
|
||||||
|
|
||||||
|
var packages = app.Option("-p|--packages <PACKAGES_DIRECTORY>", "Path to the directories containing packages to resolve.", CommandOptionType.MultipleValue);
|
||||||
|
var framework = app.Option("-f|--framework <FRAMEWORK_NAME>", "The framework to resolve dependencies for.", CommandOptionType.SingleValue);
|
||||||
|
var runtime = app.Option("-r|--runtime <RUNTIME_IDENTIFIER>", "The runtime to resolve dependencies for.", CommandOptionType.SingleValue);
|
||||||
|
var output = app.Option("-o|--output <OUTPUT_FILE>", "The path in which to write the output file (formatted as text with one line per dependency)", CommandOptionType.SingleValue);
|
||||||
|
var assetType = app.Option("-a|--assets <ASSET_TYPE>", "The type of assets to resolve (common values include: compile, runtime, native)", CommandOptionType.MultipleValue);
|
||||||
|
var project = app.Argument("PROJECT", "The project to resolve. A directory or a path to a project.lock.json may be used. Defaults to the current directory");
|
||||||
|
|
||||||
|
app.OnExecute(() =>
|
||||||
|
{
|
||||||
|
// Check required args
|
||||||
|
if (!framework.HasValue())
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Missing required argument: --framework");
|
||||||
|
app.ShowHelp();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!assetType.HasValue())
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Missing required argument: --assets");
|
||||||
|
app.ShowHelp();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build target name
|
||||||
|
var fx = NuGetFramework.Parse(framework.Value());
|
||||||
|
var target = fx.DotNetFrameworkName;
|
||||||
|
if (runtime.HasValue())
|
||||||
|
{
|
||||||
|
target += "/" + runtime.Value();
|
||||||
|
}
|
||||||
|
Console.Error.WriteLine($"Using lock file target: {target}");
|
||||||
|
|
||||||
|
// Determine packages folder
|
||||||
|
var packagesDirs = packages.Values;
|
||||||
|
if (!packagesDirs.Any())
|
||||||
|
{
|
||||||
|
var defaultDir = GetDefaultPackagesFolder();
|
||||||
|
if (string.IsNullOrEmpty(defaultDir))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Unable to locate packages directory! Try using --packages to specify it manually.");
|
||||||
|
app.ShowHelp();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
packagesDirs.Add(defaultDir);
|
||||||
|
}
|
||||||
|
foreach (var packagesDir in packagesDirs)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Using packages directory: {packagesDir}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = project.Value ?? Directory.GetCurrentDirectory();
|
||||||
|
if (path.EndsWith("project.json"))
|
||||||
|
{
|
||||||
|
path = Path.Combine(Path.GetDirectoryName(path), "project.lock.json");
|
||||||
|
}
|
||||||
|
else if (!path.EndsWith("project.lock.json"))
|
||||||
|
{
|
||||||
|
path = Path.Combine(path, "project.lock.json");
|
||||||
|
}
|
||||||
|
return Resolver.Execute(packagesDirs, target, output.Value(), assetType.Values, path);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Execute(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDefaultPackagesFolder()
|
||||||
|
{
|
||||||
|
// TODO: Read DNX_PACKAGES (or equivalent)?
|
||||||
|
// TODO: Read global.json
|
||||||
|
string userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
|
if (string.IsNullOrEmpty(userProfile))
|
||||||
|
{
|
||||||
|
userProfile = Environment.GetEnvironmentVariable("HOME");
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(userProfile))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use NuGet folder, and AppData on Windows.
|
||||||
|
return Path.Combine(userProfile, ".dnx", "packages");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
src/Microsoft.DotNet.Tools.DependencyResolver/Resolver.cs
Normal file
84
src/Microsoft.DotNet.Tools.DependencyResolver/Resolver.cs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace DotNet.Tools.DependencyResolver
|
||||||
|
{
|
||||||
|
public static class Resolver
|
||||||
|
{
|
||||||
|
public static int Execute(IEnumerable<string> packageDirectories, string targetName, string output, IEnumerable<string> assetTypes, string lockFilePath)
|
||||||
|
{
|
||||||
|
// Open the lock file
|
||||||
|
var lockFile = JObject.Parse(File.ReadAllText(lockFilePath));
|
||||||
|
|
||||||
|
// Locate the target
|
||||||
|
var target = lockFile["targets"][targetName] as JObject;
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Could not find target in lock file: {target}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over each package and prepare the dependency data
|
||||||
|
bool success = true;
|
||||||
|
List<string> files = new List<string>();
|
||||||
|
foreach (var dependency in target)
|
||||||
|
{
|
||||||
|
// Parse the input string
|
||||||
|
var splat = dependency.Key.Split('/');
|
||||||
|
var id = splat[0];
|
||||||
|
var version = splat[1];
|
||||||
|
|
||||||
|
string packageRoot = null;
|
||||||
|
foreach (var dir in packageDirectories)
|
||||||
|
{
|
||||||
|
var candidate = Path.Combine(dir, id, version);
|
||||||
|
if (Directory.Exists(candidate))
|
||||||
|
{
|
||||||
|
packageRoot = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packageRoot == null)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"WARNING: Unable to locate {id} {version}");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locate all the assets
|
||||||
|
foreach (var assetType in assetTypes)
|
||||||
|
{
|
||||||
|
var assetList = dependency.Value[assetType] as JObject;
|
||||||
|
if (assetList != null)
|
||||||
|
{
|
||||||
|
foreach (var asset in assetList)
|
||||||
|
{
|
||||||
|
var pathified = Path.Combine(asset.Key.Split('/'));
|
||||||
|
if (!Path.GetFileName(pathified).Equals("_._", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
var file = Path.Combine(packageRoot, pathified);
|
||||||
|
if (!File.Exists(file))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"WARNING: Missing asset: {file}");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
files.Add(file);
|
||||||
|
Console.WriteLine(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(output))
|
||||||
|
{
|
||||||
|
File.WriteAllLines(output, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
src/Microsoft.DotNet.Tools.DependencyResolver/project.json
Normal file
26
src/Microsoft.DotNet.Tools.DependencyResolver/project.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.0.10-beta-*",
|
||||||
|
"System.Console": "4.0.0-beta-*",
|
||||||
|
"System.Linq": "4.0.0-beta-*",
|
||||||
|
"System.Threading": "4.0.10-beta-*",
|
||||||
|
"System.IO.FileSystem": "4.0.1-beta-*",
|
||||||
|
|
||||||
|
"Microsoft.CSharp": "4.0.0-beta-23109",
|
||||||
|
"Microsoft.Framework.CommandLineUtils.Sources": "1.0.0-*",
|
||||||
|
|
||||||
|
"NuGet.Frameworks": "3.2.0",
|
||||||
|
|
||||||
|
"Newtonsoft.Json": "7.0.1"
|
||||||
|
},
|
||||||
|
|
||||||
|
"commands": {
|
||||||
|
"dotnet-resolve-dependencies": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>391d6ad6-0fd5-4e1e-a4c8-6b5439d197b5</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.DotNet.Tools.Publish</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
136
src/Microsoft.DotNet.Tools.Publish/Program.cs
Normal file
136
src/Microsoft.DotNet.Tools.Publish/Program.cs
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandLineApplication();
|
||||||
|
app.Name = "dotnet publish";
|
||||||
|
app.FullName = ".NET Publisher";
|
||||||
|
app.Description = "Publisher for the .NET Platform";
|
||||||
|
app.HelpOption("-h|--help");
|
||||||
|
|
||||||
|
var verbose = app.Option("-v|--verbose", "Be more verbose", CommandOptionType.NoValue);
|
||||||
|
var framework = app.Option("-f|--framework <FRAMEWORK>", "Target framework to compile for", CommandOptionType.SingleValue);
|
||||||
|
var runtime = app.Option("-r|--runtime <RUNTIME_IDENTIFIER>", "Target runtime to publish for", CommandOptionType.SingleValue);
|
||||||
|
var output = app.Option("-o|--output <OUTPUT_PATH>", "Path in which to publish the app", CommandOptionType.SingleValue);
|
||||||
|
var project = app.Argument("<PROJECT>", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory");
|
||||||
|
|
||||||
|
app.OnExecute(() =>
|
||||||
|
{
|
||||||
|
// Validate arguments
|
||||||
|
CheckArg(framework, "--framework");
|
||||||
|
CheckArg(runtime, "--runtime");
|
||||||
|
|
||||||
|
// Locate the project and get the name and full path
|
||||||
|
var path = project.Value;
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
path = Directory.GetCurrentDirectory();
|
||||||
|
}
|
||||||
|
if (!string.Equals(Path.GetFileName(path), "project.json", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
path = Path.Combine(path, "project.json");
|
||||||
|
}
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Could not find project: {path}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
var dir = new FileInfo(path).Directory;
|
||||||
|
|
||||||
|
return Publish(path, framework.Value(), runtime.Value(), dir, output.Value());
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return app.Execute(args);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException ex)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine(ex.Message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckArg(CommandOption argument, string name)
|
||||||
|
{
|
||||||
|
if (!argument.HasValue())
|
||||||
|
{
|
||||||
|
// TODO: GROOOOOOSS
|
||||||
|
throw new OperationCanceledException($"Missing required argument: {name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int Publish(string path, string framework, string runtime, DirectoryInfo projectDir, string outputPath)
|
||||||
|
{
|
||||||
|
// Make output directory
|
||||||
|
// TODO(anurse): per-framework and per-configuration output dir
|
||||||
|
// TODO(anurse): configurable base output dir? (maybe dotnet compile doesn't support that?)
|
||||||
|
if (string.IsNullOrEmpty(outputPath))
|
||||||
|
{
|
||||||
|
outputPath = Path.Combine(projectDir.FullName, "bin", "publish");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(outputPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile the project
|
||||||
|
var result = Command.Create("dotnet-compile", $"--framework {framework} --output {outputPath} {path}")
|
||||||
|
.ForwardStdErr()
|
||||||
|
.ForwardStdOut()
|
||||||
|
.RunAsync()
|
||||||
|
.Result;
|
||||||
|
if (result.ExitCode != 0)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Compilation failed!");
|
||||||
|
return result.ExitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect the things needed to publish
|
||||||
|
result = Command.Create("dotnet-resolve-references", $"--framework {framework} --runtime {runtime} --assets runtime --assets native {path}")
|
||||||
|
.CaptureStdOut()
|
||||||
|
.ForwardStdErr(Console.Error)
|
||||||
|
.RunAsync()
|
||||||
|
.Result;
|
||||||
|
if (result.ExitCode != 0)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Failed to resolve references");
|
||||||
|
return result.ExitCode;
|
||||||
|
}
|
||||||
|
var references = result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
// Copy everything to the output
|
||||||
|
foreach (var reference in references)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Publishing {reference} ...");
|
||||||
|
File.Copy(reference, Path.Combine(outputPath, Path.GetFileName(reference)), overwrite: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoreConsole should be there...
|
||||||
|
var coreConsole = Path.Combine(outputPath, Constants.CoreConsoleName);
|
||||||
|
if (!File.Exists(coreConsole))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Unable to find {Constants.CoreConsoleName} at {coreConsole}. You must have an explicit dependency on Microsoft.NETCore.ConsoleHost (for now ;))");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
var outputExe = Path.Combine(outputPath, projectDir.Name + Constants.ExeSuffix);
|
||||||
|
if (File.Exists(outputExe))
|
||||||
|
{
|
||||||
|
File.Delete(outputExe);
|
||||||
|
}
|
||||||
|
File.Move(coreConsole, outputExe);
|
||||||
|
Console.Error.WriteLine($"Published to {outputExe}");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/Microsoft.DotNet.Tools.Publish/project.json
Normal file
27
src/Microsoft.DotNet.Tools.Publish/project.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"compilationOptions": {
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"dotnet-compile": "Microsoft.DotNet.Cli"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"System.Console": "4.0.0-*",
|
||||||
|
"System.Collections": "4.0.11-*",
|
||||||
|
"System.Linq": "4.0.1-*",
|
||||||
|
"System.Diagnostics.Process": "4.1.0-*",
|
||||||
|
"System.IO.FileSystem": "4.0.1-*",
|
||||||
|
"Microsoft.DotNet.Cli.Utils": {
|
||||||
|
"type": "build",
|
||||||
|
"version": "1.0.0-*"
|
||||||
|
},
|
||||||
|
"Microsoft.Framework.CommandLineUtils.Sources": {
|
||||||
|
"type": "build",
|
||||||
|
"version": "1.0.0-*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>8b23b5ec-6740-447c-92d9-1f10692f232d</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.DotNet.Tools.Run</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
114
src/Microsoft.DotNet.Tools.Run/Program.cs
Normal file
114
src/Microsoft.DotNet.Tools.Run/Program.cs
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||||
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandLineApplication(throwOnUnexpectedArg: false);
|
||||||
|
app.Name = "dotnet run";
|
||||||
|
app.FullName = ".NET Executer";
|
||||||
|
app.Description = "Executer for the .NET Platform";
|
||||||
|
app.HelpOption("-h|--help");
|
||||||
|
|
||||||
|
var framework = app.Option("-f|--framework <FRAMEWORK>", "Target framework to compile for", CommandOptionType.SingleValue);
|
||||||
|
var runtime = app.Option("-r|--runtime <RUNTIME_IDENTIFIER>", "Target runtime on which to run", CommandOptionType.SingleValue);
|
||||||
|
var output = app.Option("-o|--output <OUTPUT_DIR>", "Directory in which to compile the application", CommandOptionType.SingleValue);
|
||||||
|
var project = app.Argument("<PROJECT>", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory");
|
||||||
|
|
||||||
|
app.OnExecute(() =>
|
||||||
|
{
|
||||||
|
// Validate arguments
|
||||||
|
CheckArg(framework, "--framework");
|
||||||
|
CheckArg(runtime, "--runtime");
|
||||||
|
|
||||||
|
// Locate the project and get the name and full path
|
||||||
|
var path = project.Value;
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
path = Directory.GetCurrentDirectory();
|
||||||
|
}
|
||||||
|
if (!string.Equals(Path.GetFileName(path), "project.json", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
path = Path.Combine(path, "project.json");
|
||||||
|
}
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Could not find project: {path}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
var dir = new FileInfo(path).Directory;
|
||||||
|
|
||||||
|
return Run(path, framework.Value(), runtime.Value(), dir, output.Value(), app.RemainingArguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return app.Execute(args);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException ex)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine(ex.Message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CheckArg(CommandOption argument, string name)
|
||||||
|
{
|
||||||
|
if (!argument.HasValue())
|
||||||
|
{
|
||||||
|
// TODO: GROOOOOOSS
|
||||||
|
throw new OperationCanceledException($"Missing required argument: {name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int Run(string path, string framework, string runtime, DirectoryInfo projectDir, string outputPath, IEnumerable<string> remainingArgs)
|
||||||
|
{
|
||||||
|
// Make output directory
|
||||||
|
// TODO(anurse): per-framework and per-configuration output dir
|
||||||
|
// TODO(anurse): configurable base output dir? (maybe dotnet compile doesn't support that?)
|
||||||
|
if (string.IsNullOrEmpty(outputPath))
|
||||||
|
{
|
||||||
|
outputPath = Path.Combine(projectDir.FullName, "bin", "publish");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(outputPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish the app
|
||||||
|
var result = Command.Create("dotnet-publish", $"--framework {framework} --runtime {runtime} --output {outputPath} {path}")
|
||||||
|
.ForwardStdErr()
|
||||||
|
.ForwardStdOut()
|
||||||
|
.RunAsync()
|
||||||
|
.Result;
|
||||||
|
if(result.ExitCode != 0)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("Error publishing app");
|
||||||
|
return result.ExitCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the output!
|
||||||
|
var output = Path.Combine(outputPath, projectDir.Name + Constants.ExeSuffix);
|
||||||
|
if(!File.Exists(output))
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"Could not find output: {output}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return Command.Create(output, remainingArgs)
|
||||||
|
.ForwardStdErr()
|
||||||
|
.ForwardStdOut()
|
||||||
|
.RunAsync()
|
||||||
|
.Result
|
||||||
|
.ExitCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/Microsoft.DotNet.Tools.Run/project.json
Normal file
27
src/Microsoft.DotNet.Tools.Run/project.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"compilationOptions": {
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"dotnet-compile": "Microsoft.DotNet.Cli"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"System.Console": "4.0.0-*",
|
||||||
|
"System.Collections": "4.0.11-*",
|
||||||
|
"System.Linq": "4.0.1-*",
|
||||||
|
"System.Diagnostics.Process": "4.1.0-*",
|
||||||
|
"System.IO.FileSystem": "4.0.1-*",
|
||||||
|
"Microsoft.DotNet.Cli.Utils": {
|
||||||
|
"type": "build",
|
||||||
|
"version": "1.0.0-*"
|
||||||
|
},
|
||||||
|
"Microsoft.Framework.CommandLineUtils.Sources": {
|
||||||
|
"type": "build",
|
||||||
|
"version": "1.0.0-*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>7108e4fb-e2f1-4682-8464-1dd6efb17035</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.DotNet.Tools.SourceResolver</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
31
src/Microsoft.DotNet.Tools.SourceResolver/Program.cs
Normal file
31
src/Microsoft.DotNet.Tools.SourceResolver/Program.cs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
||||||
|
|
||||||
|
namespace DotNet.Tools.DependencyResolver
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public void Main(string[] args)
|
||||||
|
{
|
||||||
|
var app = new CommandLineApplication();
|
||||||
|
app.HelpOption("-h|--help");
|
||||||
|
app.Description = "Resolves the absolute path of all source files used by a project";
|
||||||
|
|
||||||
|
var output = app.Option("-o|--output <OUTPUT_FILE>", "The path in which to write the output file (formatted as text with one line per dependency)", CommandOptionType.SingleValue);
|
||||||
|
var project = app.Argument("PROJECT", "The project to resolve. A directory or a path to a project.json may be used. Defaults to the current directory");
|
||||||
|
|
||||||
|
app.OnExecute(() =>
|
||||||
|
{
|
||||||
|
var path = project.Value ?? Directory.GetCurrentDirectory();
|
||||||
|
if (!path.EndsWith("project.json"))
|
||||||
|
{
|
||||||
|
path = Path.Combine(path, "project.json");
|
||||||
|
}
|
||||||
|
return Resolver.Execute(path, output.Value());
|
||||||
|
});
|
||||||
|
|
||||||
|
app.Execute(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
src/Microsoft.DotNet.Tools.SourceResolver/Resolver.cs
Normal file
55
src/Microsoft.DotNet.Tools.SourceResolver/Resolver.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Dnx.Runtime;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace DotNet.Tools.DependencyResolver
|
||||||
|
{
|
||||||
|
public static class Resolver
|
||||||
|
{
|
||||||
|
public static int Execute(string projectPath, string output)
|
||||||
|
{
|
||||||
|
var projectFile = new FileInfo(projectPath);
|
||||||
|
var reader = new ProjectReader();
|
||||||
|
var diagnostics = new List<DiagnosticMessage>();
|
||||||
|
Project project;
|
||||||
|
using (var stream = File.OpenRead(projectPath))
|
||||||
|
{
|
||||||
|
project = reader.ReadProject(
|
||||||
|
stream,
|
||||||
|
projectFile.Directory.Name,
|
||||||
|
projectFile.FullName,
|
||||||
|
diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var diagnostic in diagnostics)
|
||||||
|
{
|
||||||
|
WriteDiagnostic(diagnostic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diagnostics.HasErrors())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var file in project.Files.SourceFiles)
|
||||||
|
{
|
||||||
|
Console.WriteLine(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(output))
|
||||||
|
{
|
||||||
|
File.WriteAllLines(output, project.Files.SourceFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteDiagnostic(DiagnosticMessage diagnostic)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"{diagnostic.Severity}: {diagnostic.FormattedMessage}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/Microsoft.DotNet.Tools.SourceResolver/project.json
Normal file
25
src/Microsoft.DotNet.Tools.SourceResolver/project.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"System.Collections": "4.0.10-beta-*",
|
||||||
|
"System.Console": "4.0.0-beta-*",
|
||||||
|
"System.Linq": "4.0.0-beta-*",
|
||||||
|
"System.Threading": "4.0.10-beta-*",
|
||||||
|
"System.IO.FileSystem": "4.0.1-beta-*",
|
||||||
|
|
||||||
|
"Microsoft.CSharp": "4.0.0-beta-23109",
|
||||||
|
"Microsoft.Framework.CommandLineUtils.Sources": "1.0.0-*",
|
||||||
|
"Microsoft.Dnx.Runtime": "1.0.0-*",
|
||||||
|
|
||||||
|
"Newtonsoft.Json": "7.0.1"
|
||||||
|
},
|
||||||
|
|
||||||
|
"commands": {
|
||||||
|
"dotnet-resolve-dependencies": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
12
test/TestApp/Program.cs
Normal file
12
test/TestApp/Program.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("This is a test app");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
test/TestApp/TestApp.xproj
Normal file
20
test/TestApp/TestApp.xproj
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>58808bbc-371e-47d6-a3d0-4902145eda4e</ProjectGuid>
|
||||||
|
<RootNamespace>TestApp</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
13
test/TestApp/project.json
Normal file
13
test/TestApp/project.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.ConsoleHost": "1.0.0-*",
|
||||||
|
"Microsoft.NETCore.Runtime": "1.0.0-*",
|
||||||
|
"System.Console": "4.0.0-beta-23109"
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": { }
|
||||||
|
}
|
||||||
|
}
|
2865
test/TestApp/project.lock.json
Normal file
2865
test/TestApp/project.lock.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue