Restoring DNX packages using a Task Runner – ASP.NET Core

Reason

DNX packages aren’t restored automatically when building a project based on the ASP.NET 5 preview templates shipped with Visual Studio 2015, preventing the projects from compiling when first used. This means it’s sometimes necessary to open a PowerShell console and run package restoration manually using the DNX utility, depending on whether or not all the project dependencies are available in the local DNX package cache or not.

The following is an example of a Gulp task which calls dnu restore before each build, which restores all required DNX packages automatically. It should be trivial to port the functionality to other task runners.

Note: In case there’s a simpler way to enable DNX package restoration, please leave a comment and point me in the right direction. My Google skills haven’t been up to the task of finding any useful documentation regarding such a feature/build step/magic button.

Code

If you haven’t done so yet, add a package.json file to your project to include e.g. Gulp, Grunt or whatever your favorite node.js task runner might be, along with a corresponding build file (e.g. gulpfile.js, gruntfile.js).

Project structure screenshot

package.json

{
  "version": "1.0.0",
  "name": "MyAspNet5Project",
  "private": true,
  "devDependencies": {
    "gulp": "^3.9.0"
  }
}

gulpfile.js

The task named “restore-dnx-packages” executes PowerShell.exe dnu restore via a helper object before each build.

/// <binding BeforeBuild='restore-dnx-packages' />
var gulp = require("gulp"),
    fs = require("fs"),
    path = require("path"),
    // Change this path to match the location of "global.json" in relation to the location of "gulpfile.js".
    globalConfig = require("../../global.json");


gulp.task("restore-dnx-packages", function () {
    // Whether or not it's necessary to set the PowerShell execution policy depends on your local settings.
    childProcess.run("PowerShell.exe", "Set-ExecutionPolicy -Scope Currentuser Unrestricted");
    // Read the SDK version from "global.json" and run DNU restore using that framework version.
    childProcess.run("PowerShell.exe", "dnvm exec " + globalConfig.sdk.version + " dnu restore");
});

var childProcess = {
    run: function (executable, args) {
        console.log("Running \"%s %s\".", executable, args);

        var spawn = require("child_process").spawn;
        var child = spawn(executable, [args]);
        var hasError = false;
        var error = "";

        child.stdout.on("data", function (data) {
            console.log(data.toString());
        });

        child.stderr.on("data", function (data) {
            hasError = true;
            error += data.toString();
        });

        child.on("exit", function (code, signal) {
            if (hasError) {
                throw (error);
            }
            console.log("Done running \"%s %s\". Child process terminated with code %d.", executable, args, code);
        });

        child.stdin.end();
    }
};

Note the first line of the build file shown above; it contains a comment which instructs Visual Studio to run the task named “restore-dnx-packages” before each build, which is reflected in the Task Runner Explorer:

Task Runner Explorer screenshot

Since DNX caches packages locally running the task before each build doesn’t incur a noticable increase in build time.

Example

Missing packages should now be fetched automatically each time you build:

Using gulpfile D:\Projects\ReasonCodeExample\src\ReasonCodeExample\Gulpfile.js
Starting 'restore-dnx-packages'...
Running "PowerShell.exe dnu restore".
Finished 'restore-dnx-packages' after 4.11 μs
Microsoft .NET Development Utility CLR-x86-1.0.0-beta7-15532
  CACHE https://www.nuget.org/api/v2/
Restoring packages for D:ProjectsReasonCodeExamplesrcReasonCodeExampleproject.json
  GET https://www.nuget.org/api/v2/FindPackagesById()?id='Microsoft.AspNet.Server.IIS'
  GET https://www.nuget.org/api/v2/FindPackagesById()?id='Microsoft.AspNet.Server.WebListener'
  OK https://www.nuget.org/api/v2/FindPackagesById()?id='Microsoft.AspNet.Server.IIS' 947ms
  CACHE https://www.nuget.org/api/v2/package/Microsoft.AspNet.Server.IIS/1.0.0-beta7

[…]

Installing Microsoft.AspNet.Server.WebListener.1.0.0-beta7
Installing Microsoft.Net.Http.Headers.1.0.0-beta7
Installing Microsoft.Net.Http.Server.1.0.0-beta7

[…]

Restore complete, 19288ms elapsed
NuGet Config files used:
  C:\Users\Uli\AppData\Roaming\NuGet\NuGet.Config
Feeds used:
  https://www.nuget.org/api/v2/
Installed:
  125 package(s) to C:\Users\Uli\.dnx\packages
Done running "PowerShell.exe dnu restore". Child process terminated with code 0.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s