dotnet-script 0.27.0 is out – with a ton of features!

It's that time again, the new dotnet-script release, version 0.27.0 is out. It's been 2+ months since the last release so this one is fully packed with great features.

You can get it by running dotnet tool install dotnet-script -g (if you don't have it installed yet) or dotnet tool update dotnet-script -g (if you just need an update).

Let me quickly walk you through some of them.

Script startup performance improvements

One of the most common feedbacks we have been hearing was the startup performance of the scripts. Scripts start up slower than regular DLLs on the .NET Core platform. In a way this is understandable – since the script is compiled on demand and only then executed in memory. When it actually runs there is really no performance difference between a "regular" .NET Core program, but nevertheless, the startup performance can be annoying.

In recent releases we offered some ways to alleviate the pain, for example the ability to compile ("cache") a script to a DLL, and then running from that DLL. This however, doesn't really reflect very well the scripting nature of the whole project, since it's kind of a step back into the "compile and run" world, so we were not the biggest fans of this approach.

In this release we went a step further – every script that you execute, will be cached behind the scenes into a hidden DLL (think of it as implementation detail though). This means that every subsequent execution will be lightning fast, because we will just run the cached DLL version. No Nuget-restore, no copying of .NET Core runtime assemblies, no dynamic compilation anymore – since it's all not needed anymore, just blazing fast speed.

This cache is based on a hash of abstract syntax trees your script consists of. This means, as soon as you change anything, including changing NuGet dependencies or a #loaded file, the cache will be automatically invalid and upon the next execution the script will recompile cache will be recreated.

You can always choose to bypass cache by running dotnet script {your_script.csx} –no-cache. Hopefully this feature will provide a lot of performance benefits.

Support for native assets on non-Windows platforms

So far we supported loading native dependencies (for example System.Data.SqlClient or System.IO.Compression) from script files only on Windows. Since this release, native dependencies are also supported on MacOS and Linux!

Support Nuget.config correctly

We have supported Nuget.config for a while, however only if that file was located next to the script you want to execute. We didn't support the full semantics of traversing up the folder tree to find the closest applicable config file. We also didn't support Nuget.config as part of the "publish to DLL/EXE" experience.

All that is now fully supported, allowing you much easier access to i.e. local or custom package feeds.

Improved Nuget package versioning support

Instead of a simple #r "nuget: PackageName, 1.0.0" syntax, we now support the full Nuget versioning syntax, including ranges. For example, all of the following are now valid:

  • #r "nuget: PackageName – always downloads the latest package (note: this option prevents you from benefiting from cache, as we never know when the package will become stale)
  • #r "nuget: PackageName, [2.0.1, 3.0)" – mixed inclusive minimum and exclusive maximum version
  • #r "nuget: PackageName, (,1.0)" – maximum version, exclusive

And so on. Hopefully this helps in being able to flexibly manage your dependencies. Note that this feature applies to script packages ("#load "nuget: …") too.

Library improvements

If you are consuming Dotnet.Script.Core, then I am sure you will be delighted to know that all of the dotnet script CLI operations have been moved into the library in 1-to-1 format. You can now do everything the CLI does using same set of argument as the CLI expects from the library level. The CLI is simply forwarding everything to the Core library, without containing any logic.

This allows, for example, the entire caching feature to be used from the library level. You can find all the commands here.

Improved version check and update suggestion

When you run dotnet script –info (which prints the usual useful environment information, install location and so on), we will now check for the latest available version and inform you if you need to update.

Other fixes & improvements

There are plenty of other small bug fixes and improvements. Some of the ones worth mentioning:

  • there is now a help option for each command
  • parsing of #load directives is now case insensitive
  • parsing of Nuget package names is now case insensitive

We tried not to break anything, but if we did, please make sure to report problems on Github.

Thanks

This release was really possible because of the tireless work of Bernhard. I would also like to thank Atif, Tom and Frédéric for their excellent contributions.