diff --git a/README.md b/README.md
index e73078e3..5d621cd0 100644
--- a/README.md
+++ b/README.md
@@ -264,6 +264,15 @@ In order to execute a script it needs to be compiled first and since that is a C
> You can override this automatic caching by passing **--no-cache** flag, which will bypass both caches and cause dependency resolution and script compilation to happen every time we execute the script.
+#### Cache Location
+
+The temporary location used for caches is a sub-directory named `dotnet-script` under (in order of priority):
+
+1. The path specified for the value of the environment variable named `DOTNET_SCRIPT_CACHE_LOCATION`, if defined and value is not empty.
+2. Linux distributions only: `$XDG_CACHE_HOME` if defined otherwise `$HOME/.cache`
+3. macOS only: `~/Library/Caches`
+4. The value returned by [`Path.GetTempPath`](https://docs.microsoft.com/en-us/dotnet/api/system.io.path.gettemppath) for the platform.
+
###
### Debugging
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 9f219345..6e47aa6e 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -25,6 +25,9 @@ jobs:
- bash: "curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -version 2.1.402"
displayName: "Install 2.1.402"
+ - bash: "curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -version 5.0.100"
+ displayName: " 5.0.100"
+
- bash: |
export PATH=/home/vsts/.dotnet:$PATH
curl -L https://github.com/filipw/dotnet-script/releases/download/0.28.0/dotnet-script.0.28.0.zip > dotnet-script.zip
@@ -44,9 +47,12 @@ jobs:
steps:
- bash: |
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -version 3.1.102
-
displayName: "Install 3.0.100"
+ - bash: |
+ curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin -version 5.0.100
+ displayName: "Install 5.0.100"
+
- bash: |
curl -L https://github.com/filipw/dotnet-script/releases/download/0.28.0/dotnet-script.0.28.0.zip > dotnet-script.zip
unzip -o dotnet-script.zip -d ./
@@ -73,6 +79,12 @@ jobs:
displayName: "Install 2.1.402 SDK"
+ - powershell: |
+ iwr https://raw.githubusercontent.com/dotnet/cli/release/2.1.3xx/scripts/obtain/dotnet-install.ps1 -outfile dotnet-install.ps1
+ .\dotnet-install.ps1 -Version 5.0.100
+
+ displayName: "Install 5.0.100"
+
# NuGet Tool Installer
# Acquires a specific version of NuGet from the internet or the tools cache and adds it to the PATH. Use this task to change the version of NuGet used in the NuGet tasks.
- task: NuGetToolInstaller@0
diff --git a/build/Dockerfile b/build/Dockerfile
index f055c974..44e5014e 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/core/sdk:3.0
+FROM mcr.microsoft.com/dotnet/core/sdk:3.1
# https://www.nuget.org/packages/dotnet-script/
RUN dotnet tool install dotnet-script --tool-path /usr/bin
diff --git a/global.json b/global.json
new file mode 100644
index 00000000..94eb6594
--- /dev/null
+++ b/global.json
@@ -0,0 +1,6 @@
+{
+ "sdk": {
+ "version": "5.0.100",
+ "rollForward": "latestFeature"
+ }
+}
diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json
index 6f31e44e..99987c10 100644
--- a/src/.vscode/settings.json
+++ b/src/.vscode/settings.json
@@ -1,3 +1,4 @@
{
- "coverage-gutters.lcovname": "coverage.info"
-}
\ No newline at end of file
+ "coverage-gutters.lcovname": "coverage.info",
+ "dotnetCoreExplorer.searchpatterns": "**/bin/Debug/net5.0/Dotnet.Script.Tests.dll"
+}
diff --git a/src/Dotnet.Script.Core/Commands/ExecuteScriptCommand.cs b/src/Dotnet.Script.Core/Commands/ExecuteScriptCommand.cs
index 8bc28fae..6bf3809c 100644
--- a/src/Dotnet.Script.Core/Commands/ExecuteScriptCommand.cs
+++ b/src/Dotnet.Script.Core/Commands/ExecuteScriptCommand.cs
@@ -49,28 +49,21 @@ private string GetLibrary(ExecuteScriptCommandOptions executeOptions)
var executionCacheFolder = Path.Combine(projectFolder, "execution-cache");
var pathToLibrary = Path.Combine(executionCacheFolder, "script.dll");
- if (!TryCreateHash(executeOptions, out var hash) || !TryGetHash(executionCacheFolder, out var cachedHash))
+ if (TryCreateHash(executeOptions, out var hash)
+ && TryGetHash(executionCacheFolder, out var cachedHash)
+ && string.Equals(hash, cachedHash))
{
- return CreateLibrary();
+ _logger.Debug($"Using cached compilation: " + pathToLibrary);
+ return pathToLibrary;
}
- if (!string.Equals(hash, cachedHash))
+ var options = new PublishCommandOptions(executeOptions.File, executionCacheFolder, "script", PublishType.Library, executeOptions.OptimizationLevel, executeOptions.PackageSources, null, executeOptions.NoCache);
+ new PublishCommand(_scriptConsole, _logFactory).Execute(options);
+ if (hash != null)
{
- return CreateLibrary();
- }
-
- return pathToLibrary;
-
- string CreateLibrary()
- {
- var options = new PublishCommandOptions(executeOptions.File, executionCacheFolder, "script", PublishType.Library, executeOptions.OptimizationLevel, executeOptions.PackageSources, null, executeOptions.NoCache);
- new PublishCommand(_scriptConsole, _logFactory).Execute(options);
- if (hash != null)
- {
- File.WriteAllText(Path.Combine(executionCacheFolder, "script.sha256"), hash);
- }
- return Path.Combine(executionCacheFolder, "script.dll");
+ File.WriteAllText(Path.Combine(executionCacheFolder, "script.sha256"), hash);
}
+ return Path.Combine(executionCacheFolder, "script.dll");
}
public bool TryCreateHash(ExecuteScriptCommandOptions options, out string hash)
diff --git a/src/Dotnet.Script.Core/Dotnet.Script.Core.csproj b/src/Dotnet.Script.Core/Dotnet.Script.Core.csproj
index 19a03477..305e0b72 100644
--- a/src/Dotnet.Script.Core/Dotnet.Script.Core.csproj
+++ b/src/Dotnet.Script.Core/Dotnet.Script.Core.csproj
@@ -2,7 +2,7 @@
A cross platform library allowing you to run C# (CSX) scripts with support for debugging and inline NuGet packages. Based on Roslyn.
- 0.53.0
+ 1.0.0
filipw
netstandard2.0
Dotnet.Script.Core
@@ -21,7 +21,7 @@
-
+
@@ -31,7 +31,7 @@
We need to figure out why we can't load these via the dependency context.
-->
-
+
diff --git a/src/Dotnet.Script.Core/ScriptDownloader.cs b/src/Dotnet.Script.Core/ScriptDownloader.cs
old mode 100644
new mode 100755
index 0bf5fc02..f22741a0
--- a/src/Dotnet.Script.Core/ScriptDownloader.cs
+++ b/src/Dotnet.Script.Core/ScriptDownloader.cs
@@ -1,7 +1,8 @@
using System;
using System.IO;
+using System.IO.Compression;
+using System.Net;
using System.Net.Http;
-using System.Net.Mime;
using System.Threading.Tasks;
namespace Dotnet.Script.Core
@@ -10,23 +11,35 @@ public class ScriptDownloader
{
public async Task Download(string uri)
{
- const string plainTextMediaType = "text/plain";
- using (HttpClient client = new HttpClient())
+ using (HttpClient client = new HttpClient(new HttpClientHandler
{
- using (HttpResponseMessage response = await client.GetAsync(uri))
+ // Avoid Deflate due to bugs. For more info, see:
+ // https://github.com/weblinq/WebLinq/issues/132
+ AutomaticDecompression = DecompressionMethods.GZip
+ }))
+ {
+ using (HttpResponseMessage response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
using (HttpContent content = response.Content)
{
- string mediaType = content.Headers.ContentType.MediaType;
-
- if (string.IsNullOrWhiteSpace(mediaType) || mediaType.Equals(plainTextMediaType, StringComparison.InvariantCultureIgnoreCase))
+ var mediaType = content.Headers.ContentType?.MediaType?.ToLowerInvariant().Trim();
+ switch (mediaType)
{
- return await content.ReadAsStringAsync();
+ case null:
+ case "":
+ case "text/plain":
+ return await content.ReadAsStringAsync();
+ case "application/gzip":
+ case "application/x-gzip":
+ using (var stream = await content.ReadAsStreamAsync())
+ using (var gzip = new GZipStream(stream, CompressionMode.Decompress))
+ using (var reader = new StreamReader(gzip))
+ return await reader.ReadToEndAsync();
+ default:
+ throw new NotSupportedException($"The media type '{mediaType}' is not supported when executing a script over http/https");
}
-
- throw new NotSupportedException($"The media type '{mediaType}' is not supported when executing a script over http/https");
}
}
}
diff --git a/src/Dotnet.Script.Core/ScriptEmitter.cs b/src/Dotnet.Script.Core/ScriptEmitter.cs
index bdc88488..8f8e133d 100644
--- a/src/Dotnet.Script.Core/ScriptEmitter.cs
+++ b/src/Dotnet.Script.Core/ScriptEmitter.cs
@@ -18,7 +18,7 @@ public ScriptEmitter(ScriptConsole scriptConsole, ScriptCompiler scriptCompiler)
_scriptCompiler = scriptCompiler;
}
- public virtual ScriptEmitResult Emit(ScriptContext context)
+ public virtual ScriptEmitResult Emit(ScriptContext context, string assemblyName)
{
var compilationContext = _scriptCompiler.CreateCompilationContext(context);
foreach (var warning in compilationContext.Warnings)
@@ -37,13 +37,17 @@ public virtual ScriptEmitResult Emit(ScriptContext context)
}
var compilation = compilationContext.Script.GetCompilation();
+ compilation = compilation.WithAssemblyName(assemblyName);
var peStream = new MemoryStream();
EmitOptions emitOptions = null;
+
if (context.OptimizationLevel == Microsoft.CodeAnalysis.OptimizationLevel.Debug)
{
emitOptions = new EmitOptions()
.WithDebugInformationFormat(DebugInformationFormat.Embedded);
+
+
}
var result = compilation.Emit(peStream, options: emitOptions);
diff --git a/src/Dotnet.Script.Core/ScriptPublisher.cs b/src/Dotnet.Script.Core/ScriptPublisher.cs
index cf8aa00e..6f14aa5a 100644
--- a/src/Dotnet.Script.Core/ScriptPublisher.cs
+++ b/src/Dotnet.Script.Core/ScriptPublisher.cs
@@ -13,7 +13,7 @@ namespace Dotnet.Script.Core
{
public class ScriptPublisher
{
- private const string ScriptingVersion = "2.8.2";
+ private const string ScriptingVersion = "3.7.0";
private readonly ScriptProjectProvider _scriptProjectProvider;
private readonly ScriptEmitter _scriptEmitter;
@@ -73,8 +73,8 @@ public void CreateExecutable(ScriptContext context, LogFactory l
executableFileName = executableFileName ?? Path.GetFileNameWithoutExtension(context.FilePath);
const string AssemblyName = "scriptAssembly";
- var tempProjectPath = ScriptProjectProvider.GetPathToProjectFile(Path.GetDirectoryName(context.FilePath), ScriptEnvironment.Default.TargetFramework);
- var renamedProjectPath = ScriptProjectProvider.GetPathToProjectFile(Path.GetDirectoryName(context.FilePath), ScriptEnvironment.Default.TargetFramework, executableFileName);
+ var tempProjectPath = ScriptProjectProvider.GetPathToProjectFile(Path.GetDirectoryName(context.FilePath), _scriptEnvironment.TargetFramework);
+ var renamedProjectPath = ScriptProjectProvider.GetPathToProjectFile(Path.GetDirectoryName(context.FilePath), _scriptEnvironment.TargetFramework, executableFileName);
var tempProjectDirectory = Path.GetDirectoryName(tempProjectPath);
var scriptAssemblyPath = CreateScriptAssembly(context, tempProjectDirectory, AssemblyName);
@@ -88,7 +88,10 @@ public void CreateExecutable(ScriptContext context, LogFactory l
var commandRunner = new CommandRunner(logFactory);
// todo: may want to add ability to return dotnet.exe errors
- var exitcode = commandRunner.Execute("dotnet", $"publish \"{renamedProjectPath}\" -c Release -r {runtimeIdentifier} -o \"{context.WorkingDirectory}\" {(ScriptEnvironment.Default.NetCoreVersion.Major >= 3 ? "/p:PublishSingleFile=true" : string.Empty)} /p:DebugType=Embedded");
+ var publishSingleFileArgument = ScriptEnvironment.Default.NetCoreVersion.Major >= 3 ? "/p:PublishSingleFile=true" : string.Empty;
+ var includeNativeLibrariesForSelfExtract = ScriptEnvironment.Default.NetCoreVersion.Major >= 5 ? "/p:IncludeNativeLibrariesForSelfExtract=true" : string.Empty;
+
+ var exitcode = commandRunner.Execute("dotnet", $"publish \"{renamedProjectPath}\" -c Release -r {runtimeIdentifier} -o \"{context.WorkingDirectory}\" {publishSingleFileArgument} {includeNativeLibrariesForSelfExtract} /p:DebugType=Embedded");
if (exitcode != 0)
{
@@ -100,7 +103,7 @@ public void CreateExecutable(ScriptContext context, LogFactory l
private string CreateScriptAssembly(ScriptContext context, string outputDirectory, string assemblyFileName)
{
- var emitResult = _scriptEmitter.Emit(context);
+ var emitResult = _scriptEmitter.Emit(context, assemblyFileName);
var assemblyPath = Path.Combine(outputDirectory, $"{assemblyFileName}.dll");
using (var peFileStream = new FileStream(assemblyPath, FileMode.Create))
using (emitResult.PeStream)
diff --git a/src/Dotnet.Script.Core/Templates/program.publish.template b/src/Dotnet.Script.Core/Templates/program.publish.template
index ba79887a..2b269482 100644
--- a/src/Dotnet.Script.Core/Templates/program.publish.template
+++ b/src/Dotnet.Script.Core/Templates/program.publish.template
@@ -1,6 +1,7 @@
using System;
using Microsoft.CodeAnalysis.CSharp.Scripting.Hosting;
using Microsoft.CodeAnalysis.Scripting.Hosting;
+using System.Runtime.Loader;
using System.Threading.Tasks;
using static System.Console;
using System.Reflection;
@@ -18,15 +19,14 @@ namespace dotnetPublishCode
foreach (var arg in args)
globals.Args.Add(arg);
- var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
- var assembly = Assembly.LoadFrom(Path.Combine(path, "scriptAssembly.dll"));
+ var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("scriptAssembly"));
var type = assembly.GetType("Submission#0");
var factoryMethod = type.GetMethod("");
if (factoryMethod == null) throw new Exception("couldn't find factory method to initiate script");
var invokeTask = factoryMethod.Invoke(null, new object[] { new object[] { globals, null } }) as Task;
var invokeResult = await invokeTask;
- if (invokeResult != 0)
+ if (invokeResult != 0)
{
WritePrettyError($"Error result: '{invokeResult}'");
return 0x1;
diff --git a/src/Dotnet.Script.DependencyModel.Nuget/Dotnet.Script.DependencyModel.NuGet.csproj b/src/Dotnet.Script.DependencyModel.Nuget/Dotnet.Script.DependencyModel.NuGet.csproj
index 7db8473f..148a6ea0 100644
--- a/src/Dotnet.Script.DependencyModel.Nuget/Dotnet.Script.DependencyModel.NuGet.csproj
+++ b/src/Dotnet.Script.DependencyModel.Nuget/Dotnet.Script.DependencyModel.NuGet.csproj
@@ -8,7 +8,7 @@
https://github.com/filipw/dotnet-script.git
git
script;csx;csharp;roslyn;nuget
- 0.53.0
+ 1.0.0
A MetadataReferenceResolver that allows inline nuget references to be specified in script(csx) files.
dotnet-script
dotnet-script
@@ -19,6 +19,6 @@
-
+
diff --git a/src/Dotnet.Script.DependencyModel/Context/DotnetRestorer.cs b/src/Dotnet.Script.DependencyModel/Context/DotnetRestorer.cs
index 3ae1cedc..8b8a9f4a 100644
--- a/src/Dotnet.Script.DependencyModel/Context/DotnetRestorer.cs
+++ b/src/Dotnet.Script.DependencyModel/Context/DotnetRestorer.cs
@@ -3,6 +3,7 @@
using Dotnet.Script.DependencyModel.Process;
using Dotnet.Script.DependencyModel.ProjectSystem;
using System;
+using System.IO;
using System.Linq;
namespace Dotnet.Script.DependencyModel.Context
@@ -25,13 +26,18 @@ public void Restore(ProjectFileInfo projectFileInfo, string[] packageSources)
var packageSourcesArgument = CreatePackageSourcesArguments();
var configFileArgument = CreateConfigFileArgument();
var runtimeIdentifier = _scriptEnvironment.RuntimeIdentifier;
+ var workingDirectory = Path.GetFullPath(Path.GetDirectoryName(projectFileInfo.Path));
+
_logger.Debug($"Restoring {projectFileInfo.Path} using the dotnet cli. RuntimeIdentifier : {runtimeIdentifier} NugetConfigFile: {projectFileInfo.NuGetConfigFile}");
- var exitcode = _commandRunner.Execute("dotnet", $"restore \"{projectFileInfo.Path}\" -r {runtimeIdentifier} {packageSourcesArgument} {configFileArgument}");
- if (exitcode != 0)
+
+ var commandPath = "dotnet";
+ var commandArguments = $"restore \"{projectFileInfo.Path}\" -r {runtimeIdentifier} {packageSourcesArgument} {configFileArgument}";
+ var commandResult = _commandRunner.Capture(commandPath, commandArguments, workingDirectory);
+ if (commandResult.ExitCode != 0)
{
// We must throw here, otherwise we may incorrectly run with the old 'project.assets.json'
- throw new Exception($"Unable to restore packages from '{projectFileInfo.Path}'. Make sure that all script files contains valid NuGet references");
+ throw new Exception($"Unable to restore packages from '{projectFileInfo.Path}'{System.Environment.NewLine}Make sure that all script files contains valid NuGet references{System.Environment.NewLine}{System.Environment.NewLine}Details:{System.Environment.NewLine}{workingDirectory} : {commandPath} {commandArguments}{System.Environment.NewLine}{commandResult.StandardOut}");
}
string CreatePackageSourcesArguments()
diff --git a/src/Dotnet.Script.DependencyModel/Dotnet.Script.DependencyModel.csproj b/src/Dotnet.Script.DependencyModel/Dotnet.Script.DependencyModel.csproj
index d0198e04..ad38b324 100644
--- a/src/Dotnet.Script.DependencyModel/Dotnet.Script.DependencyModel.csproj
+++ b/src/Dotnet.Script.DependencyModel/Dotnet.Script.DependencyModel.csproj
@@ -11,7 +11,7 @@
https://github.com/filipw/dotnet-script.git
git
script;csx;csharp;roslyn;omnisharp
- 0.53.0
+ 1.0.0
latest
@@ -31,7 +31,7 @@
-
+
diff --git a/src/Dotnet.Script.DependencyModel/Environment/ScriptEnvironment.cs b/src/Dotnet.Script.DependencyModel/Environment/ScriptEnvironment.cs
index 18c3e7e8..afb6591e 100644
--- a/src/Dotnet.Script.DependencyModel/Environment/ScriptEnvironment.cs
+++ b/src/Dotnet.Script.DependencyModel/Environment/ScriptEnvironment.cs
@@ -74,6 +74,7 @@ private static string GetPlatformIdentifier()
private static DotnetVersion GetNetCoreAppVersion()
{
+ GetNetCoreVersion();
// https://github.com/dotnet/BenchmarkDotNet/blob/94863ab4d024eca04d061423e5aad498feff386b/src/BenchmarkDotNet/Portability/RuntimeInformation.cs#L156
var codeBase = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.CodeBase;
var pattern = @"^.*Microsoft\.NETCore\.App\/(\d+\.\d+)(.*?)\/";
@@ -88,6 +89,16 @@ private static DotnetVersion GetNetCoreAppVersion()
return new DotnetVersion(version, $"netcoreapp{tfm}");
}
+ public static string GetNetCoreVersion()
+ {
+ var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
+ var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
+ int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
+ if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
+ return assemblyPath[netCoreAppIndex + 1];
+ return null;
+ }
+
private static string GetInstallLocation()
{
return Path.GetDirectoryName(new Uri(typeof(ScriptEnvironment).GetTypeInfo().Assembly.CodeBase).LocalPath);
@@ -145,6 +156,10 @@ public DotnetVersion(string version, string tfm)
Major = int.Parse(versionMatch.Groups[1].Value);
if (versionMatch.Success && versionMatch.Groups[2].Success)
Minor = int.Parse(versionMatch.Groups[2].Value);
+ if (Major >= 5)
+ {
+ Tfm = $"net{Major}.{Minor}";
+ }
}
public string Version { get; }
diff --git a/src/Dotnet.Script.Desktop.Tests/Dotnet.Script.Desktop.Tests.csproj b/src/Dotnet.Script.Desktop.Tests/Dotnet.Script.Desktop.Tests.csproj
index 3a744f6a..fd6ac52f 100644
--- a/src/Dotnet.Script.Desktop.Tests/Dotnet.Script.Desktop.Tests.csproj
+++ b/src/Dotnet.Script.Desktop.Tests/Dotnet.Script.Desktop.Tests.csproj
@@ -4,9 +4,9 @@
net472
-
+
-
+
all
runtime; build; native; contentfiles; analyzers
diff --git a/src/Dotnet.Script.Extras/Dotnet.Script.Extras.csproj b/src/Dotnet.Script.Extras/Dotnet.Script.Extras.csproj
index ed6546d5..84c07d06 100644
--- a/src/Dotnet.Script.Extras/Dotnet.Script.Extras.csproj
+++ b/src/Dotnet.Script.Extras/Dotnet.Script.Extras.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/src/Dotnet.Script.Tests/Dotnet.Script.Tests.csproj b/src/Dotnet.Script.Tests/Dotnet.Script.Tests.csproj
index fbcb0e64..b08a3b76 100644
--- a/src/Dotnet.Script.Tests/Dotnet.Script.Tests.csproj
+++ b/src/Dotnet.Script.Tests/Dotnet.Script.Tests.csproj
@@ -1,6 +1,6 @@
- netcoreapp2.1;netcoreapp3.1
+ net5.0
false
@@ -8,14 +8,14 @@
runtime; build; native; contentfiles; analyzers
all
-
+
-
+
all
runtime; build; native; contentfiles; analyzers
-
+
diff --git a/src/Dotnet.Script.Tests/DotnetRestorerTests.cs b/src/Dotnet.Script.Tests/DotnetRestorerTests.cs
new file mode 100644
index 00000000..c954d6cc
--- /dev/null
+++ b/src/Dotnet.Script.Tests/DotnetRestorerTests.cs
@@ -0,0 +1,80 @@
+using Dotnet.Script.DependencyModel.Context;
+using Dotnet.Script.DependencyModel.Process;
+using Dotnet.Script.DependencyModel.ProjectSystem;
+using Dotnet.Script.Shared.Tests;
+using System;
+using System.IO;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Dotnet.Script.Tests
+{
+ public class DotnetRestorerTests
+ {
+ private PackageReference ValidPackageReferenceA => new PackageReference("Newtonsoft.Json", "12.0.3");
+ private PackageReference ValidPackageReferenceB => new PackageReference("Moq", "4.14.5");
+
+ private PackageReference InvalidPackageReferenceA => new PackageReference("7c63e1f5-2248-ed31-9480-e4cb5ac322fe", "1.0.0");
+
+ public DotnetRestorerTests(ITestOutputHelper testOutputHelper)
+ {
+ testOutputHelper.Capture();
+ }
+
+ [Fact]
+ public void ShouldRestoreProjectPackageReferences()
+ {
+ using (var projectFolder = new DisposableFolder())
+ {
+ var pathToProjectFile = Path.Combine(projectFolder.Path, "script.csproj");
+
+ var projectFile = new ProjectFile();
+ projectFile.PackageReferences.Add(ValidPackageReferenceA);
+ projectFile.PackageReferences.Add(ValidPackageReferenceB);
+ projectFile.Save(pathToProjectFile);
+
+ var projectFileInfo = new ProjectFileInfo(pathToProjectFile, string.Empty);
+
+ var logFactory = TestOutputHelper.CreateTestLogFactory();
+ var commandRunner = new CommandRunner(logFactory);
+ var restorer = new DotnetRestorer(commandRunner, logFactory);
+
+ var pathToProjectObjDirectory = Path.Combine(projectFolder.Path, "obj");
+
+ Assert.False(Directory.Exists(pathToProjectObjDirectory));
+
+ restorer.Restore(projectFileInfo, Array.Empty());
+
+ Assert.True(Directory.Exists(pathToProjectObjDirectory));
+ }
+ }
+
+ [Fact]
+ public void ShouldThrowExceptionOnRestoreError()
+ {
+ using (var projectFolder = new DisposableFolder())
+ {
+ var pathToProjectFile = Path.Combine(projectFolder.Path, "script.csproj");
+
+ var projectFile = new ProjectFile();
+ projectFile.PackageReferences.Add(ValidPackageReferenceA);
+ projectFile.PackageReferences.Add(InvalidPackageReferenceA);
+ projectFile.PackageReferences.Add(ValidPackageReferenceB);
+ projectFile.Save(pathToProjectFile);
+
+ var projectFileInfo = new ProjectFileInfo(pathToProjectFile, string.Empty);
+
+ var logFactory = TestOutputHelper.CreateTestLogFactory();
+ var commandRunner = new CommandRunner(logFactory);
+ var restorer = new DotnetRestorer(commandRunner, logFactory);
+
+ var exception = Assert.Throws(() =>
+ {
+ restorer.Restore(projectFileInfo, Array.Empty());
+ });
+
+ Assert.Contains("NU1101", exception.Message); // unable to find package
+ }
+ }
+ }
+}
diff --git a/src/Dotnet.Script.Tests/ScriptExecutionTests.cs b/src/Dotnet.Script.Tests/ScriptExecutionTests.cs
index 4ed9efae..2c41ceaf 100644
--- a/src/Dotnet.Script.Tests/ScriptExecutionTests.cs
+++ b/src/Dotnet.Script.Tests/ScriptExecutionTests.cs
@@ -241,12 +241,15 @@ public void ShouldSupportInlineNugetReferencesWithTrailingSemicoloninEvaluatedCo
Assert.Contains("AutoMapper.MapperConfiguration", result.output);
}
- [Fact]
- public void ShouldExecuteRemoteScript()
+ [Theory]
+ [InlineData("https://gist.githubusercontent.com/seesharper/5d6859509ea8364a1fdf66bbf5b7923d/raw/0a32bac2c3ea807f9379a38e251d93e39c8131cb/HelloWorld.csx",
+ "Hello World")]
+ [InlineData("https://github.com/filipw/dotnet-script/files/5035247/hello.csx.gz",
+ "Hello, world!")]
+ public void ShouldExecuteRemoteScript(string url, string output)
{
- var url = "https://gist.githubusercontent.com/seesharper/5d6859509ea8364a1fdf66bbf5b7923d/raw/0a32bac2c3ea807f9379a38e251d93e39c8131cb/HelloWorld.csx";
var result = ScriptTestRunner.Default.Execute(url);
- Assert.Contains("Hello World", result.output);
+ Assert.Contains(output, result.output);
}
[Fact]
@@ -453,6 +456,15 @@ public void ShouldHandleScriptWithTargetFrameworkInShebang()
Assert.Contains("Hello world!", result.output);
}
+ [Fact]
+ public void ShouldIgnoreGlobalJsonInScriptFolder()
+ {
+ var fixture = "InvalidGlobalJson";
+ var workingDirectory = Path.GetDirectoryName(TestPathUtils.GetPathToTestFixture(fixture));
+ var result = ScriptTestRunner.Default.ExecuteFixture("InvalidGlobalJson", $"--no-cache", workingDirectory);
+ Assert.Contains("Hello world!", result.output);
+ }
+
private static string CreateTestScript(string scriptFolder)
{
@@ -467,7 +479,7 @@ private static string CreateTestScript(string scriptFolder)
private static void CreateTestPackage(string packageLibraryFolder)
{
- ProcessHelper.RunAndCaptureOutput("dotnet", "new classlib -n NuGetConfigTestLibrary", packageLibraryFolder);
+ ProcessHelper.RunAndCaptureOutput("dotnet", "new classlib -n NuGetConfigTestLibrary -f netstandard2.0", packageLibraryFolder);
var projectFolder = Path.Combine(packageLibraryFolder, "NuGetConfigTestLibrary");
ProcessHelper.RunAndCaptureOutput("dotnet", $"pack -o \"{Path.Combine(packageLibraryFolder, "packagePath")}\"", projectFolder);
CreateNuGetConfig(packageLibraryFolder);
diff --git a/src/Dotnet.Script.Tests/ScriptPackagesTests.cs b/src/Dotnet.Script.Tests/ScriptPackagesTests.cs
index 043cfa64..aeb3bebd 100644
--- a/src/Dotnet.Script.Tests/ScriptPackagesTests.cs
+++ b/src/Dotnet.Script.Tests/ScriptPackagesTests.cs
@@ -25,11 +25,12 @@ public ScriptPackagesTests(ITestOutputHelper testOutputHelper)
[Fact]
public void ShouldHandleScriptPackageWithMainCsx()
{
- var result = Execute("WithMainCsx/WithMainCsx.csx");
- Assert.StartsWith("Hello from netstandard2.0", result);
+ var (output, exitcode) = ScriptTestRunner.Default.ExecuteWithScriptPackage("WithMainCsx", "--no-cache");
+ Assert.Equal(0, exitcode);
+ Assert.StartsWith("Hello from netstandard2.0", output);
}
- [Fact]
+ //[Fact]
public void ShouldThrowMeaningfulExceptionWhenScriptPackageIsMissing()
{
using (var scriptFolder = new DisposableFolder())
@@ -60,37 +61,42 @@ public void ShouldThrowMeaningfulExceptionWhenScriptPackageIsMissing()
[Fact]
public void ShouldHandleScriptWithAnyTargetFramework()
{
- var result = Execute("WithAnyTargetFramework/WithAnyTargetFramework.csx");
- Assert.StartsWith("Hello from any target framework", result);
+ var (output, exitcode) = ScriptTestRunner.Default.ExecuteWithScriptPackage("WithAnyTargetFramework", "--no-cache");
+ Assert.Equal(0, exitcode);
+ Assert.StartsWith("Hello from any target framework", output);
}
[Fact]
public void ShouldHandleScriptPackageWithNoEntryPointFile()
{
- var result = Execute("WithNoEntryPointFile/WithNoEntryPointFile.csx");
- Assert.Contains("Hello from Foo.csx", result);
- Assert.Contains("Hello from Bar.csx", result);
+ var (output, exitcode) = ScriptTestRunner.Default.ExecuteWithScriptPackage("WithNoEntryPointFile", "--no-cache");
+ Assert.Equal(0, exitcode);
+ Assert.Contains("Hello from Foo.csx", output);
+ Assert.Contains("Hello from Bar.csx", output);
}
[Fact]
public void ShouldHandleScriptPackageWithScriptPackageDependency()
{
- var result = Execute("WithScriptPackageDependency/WithScriptPackageDependency.csx");
- Assert.StartsWith("Hello from netstandard2.0", result);
+ var (output, exitcode) = ScriptTestRunner.Default.ExecuteWithScriptPackage("WithScriptPackageDependency", "--no-cache");
+ Assert.Equal(0, exitcode);
+ Assert.StartsWith("Hello from netstandard2.0", output);
}
[Fact]
public void ShouldThrowExceptionWhenReferencingUnknownPackage()
{
- var result = Execute("WithInvalidPackageReference/WithInvalidPackageReference.csx");
- Assert.StartsWith("Unable to restore packages from", result);
+ var (output, exitcode) = ScriptTestRunner.Default.ExecuteWithScriptPackage("WithInvalidPackageReference", "--no-cache");
+ Assert.NotEqual(0, exitcode);
+ Assert.StartsWith("Unable to restore packages from", output);
}
[Fact]
public void ShouldHandleScriptPackageWithSubFolder()
{
- var result = Execute("WithSubFolder/WithSubFolder.csx");
- Assert.StartsWith("Hello from Bar.csx", result);
+ var (output, exitcode) = ScriptTestRunner.Default.ExecuteWithScriptPackage("WithSubFolder", "--no-cache");
+ Assert.Equal(0, exitcode);
+ Assert.StartsWith("Hello from Bar.csx", output);
}
[Fact]
diff --git a/src/Dotnet.Script.Tests/ScriptTestRunner.cs b/src/Dotnet.Script.Tests/ScriptTestRunner.cs
index 45f6fe76..ebb1d0d7 100644
--- a/src/Dotnet.Script.Tests/ScriptTestRunner.cs
+++ b/src/Dotnet.Script.Tests/ScriptTestRunner.cs
@@ -35,13 +35,20 @@ public int ExecuteInProcess(string arguments = null)
return Program.Main(arguments?.Split(" ") ?? Array.Empty());
}
- public (string output, int exitCode) ExecuteFixture(string fixture, string arguments = null)
+ public (string output, int exitCode) ExecuteFixture(string fixture, string arguments = null, string workingDirectory = null)
{
var pathToFixture = TestPathUtils.GetPathToTestFixture(fixture);
- var result = ProcessHelper.RunAndCaptureOutput("dotnet", GetDotnetScriptArguments($"{pathToFixture} {arguments}"));
+ var result = ProcessHelper.RunAndCaptureOutput("dotnet", GetDotnetScriptArguments($"{pathToFixture} {arguments}"), workingDirectory);
return result;
}
+ public (string output, int exitcode) ExecuteWithScriptPackage(string fixture, string arguments = null, string workingDirectory = null)
+ {
+ var pathToScriptPackageFixtures = TestPathUtils.GetPathToTestFixtureFolder("ScriptPackage");
+ var pathToFixture = Path.Combine(pathToScriptPackageFixtures, fixture, $"{fixture}.csx");
+ return ProcessHelper.RunAndCaptureOutput("dotnet", GetDotnetScriptArguments($"{pathToFixture} {arguments}"), workingDirectory);
+ }
+
public int ExecuteFixtureInProcess(string fixture, string arguments = null)
{
var pathToFixture = TestPathUtils.GetPathToTestFixture(fixture);
@@ -80,6 +87,7 @@ private string GetDotnetScriptArguments(string arguments)
#else
configuration = "Release";
#endif
+
var allArgs = $"exec {Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "Dotnet.Script", "bin", configuration, _scriptEnvironment.TargetFramework, "dotnet-script.dll")} {arguments}";
return allArgs;
diff --git a/src/Dotnet.Script.Tests/TestFixtures/InvalidGlobalJson/InvalidGlobalJson.csx b/src/Dotnet.Script.Tests/TestFixtures/InvalidGlobalJson/InvalidGlobalJson.csx
new file mode 100644
index 00000000..8c7603a8
--- /dev/null
+++ b/src/Dotnet.Script.Tests/TestFixtures/InvalidGlobalJson/InvalidGlobalJson.csx
@@ -0,0 +1 @@
+Console.WriteLine("Hello world!");
\ No newline at end of file
diff --git a/src/Dotnet.Script.Tests/TestFixtures/InvalidGlobalJson/global.json b/src/Dotnet.Script.Tests/TestFixtures/InvalidGlobalJson/global.json
new file mode 100644
index 00000000..79422f0c
--- /dev/null
+++ b/src/Dotnet.Script.Tests/TestFixtures/InvalidGlobalJson/global.json
@@ -0,0 +1,5 @@
+{
+ "sdk": {
+ "version": "3.0.100"
+ }
+}
diff --git a/src/Dotnet.Script/Dotnet.Script.csproj b/src/Dotnet.Script/Dotnet.Script.csproj
index 24a16769..ccde00a5 100644
--- a/src/Dotnet.Script/Dotnet.Script.csproj
+++ b/src/Dotnet.Script/Dotnet.Script.csproj
@@ -1,10 +1,10 @@
Dotnet CLI tool allowing you to run C# (CSX) scripts.
- 0.53.0
+ 1.0.0
filipw
Dotnet.Script
- netcoreapp2.1;netcoreapp3.1
+ net5.0;netcoreapp2.1;netcoreapp3.1
portable
dotnet-script
Exe
@@ -22,9 +22,9 @@
latest
-
+
-
+
diff --git a/src/Dotnet.Script/Program.cs b/src/Dotnet.Script/Program.cs
index 809fa63c..54b2c196 100644
--- a/src/Dotnet.Script/Program.cs
+++ b/src/Dotnet.Script/Program.cs
@@ -83,13 +83,22 @@ private static int Wain(string[] args)
c.HelpOption(helpOptionTemplate);
c.OnExecute(async () =>
{
- if (string.IsNullOrWhiteSpace(code.Value))
+ var source = code.Value;
+ if (string.IsNullOrWhiteSpace(source))
{
- c.ShowHelp();
- return 0;
+ if (Console.IsInputRedirected)
+ {
+ source = await Console.In.ReadToEndAsync();
+ }
+ else
+ {
+ c.ShowHelp();
+ return 0;
+ }
}
+
var logFactory = CreateLogFactory(verbosity.Value(), debugMode.HasValue());
- var options = new ExecuteCodeCommandOptions(code.Value,cwd.Value(), app.RemainingArguments.Concat(argsAfterDoubleHyphen).ToArray(),configuration.ValueEquals("release", StringComparison.OrdinalIgnoreCase) ? OptimizationLevel.Release : OptimizationLevel.Debug, nocache.HasValue(),packageSources.Values?.ToArray());
+ var options = new ExecuteCodeCommandOptions(source, cwd.Value(), app.RemainingArguments.Concat(argsAfterDoubleHyphen).ToArray(),configuration.ValueEquals("release", StringComparison.OrdinalIgnoreCase) ? OptimizationLevel.Release : OptimizationLevel.Debug, nocache.HasValue(),packageSources.Values?.ToArray());
return await new ExecuteCodeCommand(ScriptConsole.Default, logFactory).Execute(options);
});
});