Angel \”Java\” Lopez on Blog

October 11, 2010

Dissecting NuPack (Part 2) The Package Feed

Filed under: .NET, NuPack, Package Management — ajlopez @ 6:19 pm

In the previous post of this serie, I introduced NuPack package manager:

Dissecting NuPack (Part 1) Introduction

I would like to explore NuPack internal process. First, to run using the source code, I installed:

Visual Studio 2010 SDK
PowerShell 2.0

Then, this is the current solution (October 11th):

NuPack.Server project is a web server, written using ASP.NET MVC:

First, note the MVC mapping in global.asax.cs:

            // Map a feed route at the root
            routes.MapRoute("feed",
                            "feed",
                            new { controller = "Packages", action = "Feed" }
            );

The Package controller is in charge of producing the list of package to expose in the server. Its address is /feed. The output:

The source code of Package controller is in Controllers\PackageController.cs. The Feed action will be deprecated in NuPack CPT 2:

        //TODO: This method is deprecated. Need to keep it around till we release NuPack CTP 2.
        public ActionResult Feed() {
            // Add the response header
            Response.AddHeader(PackageUtility.FeedVersionHeader, PackageUtility.AtomFeedVersion);
            if (Request.Headers[PackageUtility.FeedVersionHeader] != null) {
                return new HttpStatusCodeResult(304);
            }
            // Get the last modified of the package directory
            DateTime lastModified = Directory.GetLastWriteTimeUtc(PackageUtility.PackagePhysicalPath);
            return ConditionalGet(lastModified, () => {
                SyndicationFeed packageFeed = PackageSyndicationFeed.Create(
                    PackageUtility.PackagePhysicalPath,
                    package => PackageUtility.GetPackageUrl(package.Id, package.Version.ToString(), Request.Url));
                packageFeed.Title = new TextSyndicationContent("Demo Feed");
                packageFeed.Description = new TextSyndicationContent("Demo package feed");
                SyndicationPerson sp = new SyndicationPerson("person@demofeed.com", "Demo", "http://www.demofeed.com");
                packageFeed.Authors.Add(sp);
                packageFeed.Copyright = new TextSyndicationContent("Copyright " + DateTime.Now.Year);
                packageFeed.Description = new TextSyndicationContent("ASP.NET package feed");
                packageFeed.Language = "en-us";
                packageFeed.LastUpdatedTime = lastModified;
                return new SyndicationFeedResult(packageFeed,
                                                 feed => new Atom10FeedFormatter(feed));
            });
        }

The packages are retrieved from PackageUtility.PackagePhysicalPath:

    public class PackageUtility {
        internal static string PackagePhysicalPath = HostingEnvironment.MapPath("~/Packages");
        internal static string AtomFeedVersion = "1.0";
        internal static string ODataFeedVersion = "2.0";
        internal static string FeedVersionHeader = "NuPackVersion";

I copied NuPack packages files (with .nupkg extension) from package directory (included in the download) (In previous versions, the Server contained a complete list of .nupkg files, but now, we should add the package to the /Packages INSIDE web server).

There is a new OData service, in /DataServices/Packages.svc. The initialization code:

        protected override void OnStartProcessingRequest(ProcessRequestArgs args) {
            base.OnStartProcessingRequest(args);
            // HACK: Exceptions for control flow yay! Only way to stop the request from completing
            // right now
            HttpRequestBase request = new HttpRequestWrapper(HttpContext.Current.Request);
            DateTime lastModified = Directory.GetLastWriteTimeUtc(PackageUtility.PackagePhysicalPath);
            if (request.IsUnmodified(lastModified)) {
                throw new DataServiceException(304, null);
            }
            // Stick the version header in the response
            args.OperationContext.ResponseHeaders[PackageUtility.FeedVersionHeader] = PackageUtility.ODataFeedVersion;
            // Try to determine if this is a request for the feed version
            if(args.OperationContext.RequestHeaders[PackageUtility.FeedVersionHeader] != null) {
                throw new DataServiceException(200, null);
            }
            HttpCachePolicy cachePolicy = HttpContext.Current.Response.Cache;
            cachePolicy.SetCacheability(HttpCacheability.Public);
            cachePolicy.SetLastModified(Directory.GetLastWriteTimeUtc(PackageUtility.PackagePhysicalPath));
        }

The PackageContext is the key class to get an IQueryable over existing packages:

namespace NuPack.Server.DataServices {
    public class PackageContext {
        private IPackageRepository _repository;
        public PackageContext(IPackageRepository repository) {
            _repository = repository;
        }
        public IQueryable<Package> Packages {
            get {
                return from package in _repository.GetPackages()
                       select new Package(package);
            }
        }
    }
}

More about WCF DataServices and OData:

http://msdn.microsoft.com/en-us/data/ee720180.aspx

http://www.odata.org/developers/protocols/uri-conventions

You can obtain the list of packages entering /DataServices/Packages.svc/Packages in browser:

I should explore the NuPack.Core, the way a package is created and installed.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

October 8, 2010

Dissecting NuPack (Part 1) Introduction

Filed under: .NET, NuPack, Package Management — ajlopez @ 3:00 pm

These days, Microsoft has released an open source package manager, for .NET with Visual Studio integration:

http://nupack.codeplex.com/

NuPack has a console program, a Visual Studio extension, and a server to host your packages (Microsoft has an online server online, but you can run your own). Interesting, the code was written with open source developers, that are involved in Nu project, another open source package manager. And the project now is open to accept collaboration from the developer community. Notably, hours after the public launch (the project was under development for months) external devs updated the source to be compile in Mono, the multiplatform .NET implementation.

NuPack doesn’t compile the source code of the packages. It exposes the binaries or source code, to be downloaded and integrated in our current solution in Visual Studio. It manages the dependencies between packages, but it is up to developers and authors to keep the health of dependencies. Then, the project is less ambitious than others, like Horn, that got the source code from open source repositories and compiled it.

I would like to learn how NuPack implements its features, what is its internal structure, how it manages feeds and downloads, its integration with Visual Studio and PowerShell, the way the team covered the code with tests, etc… This is only a brief post, with links about NuPack, an introduction to the project “dissection” 😉

There are some interesting post about the history of NuPack and its relation with Nu project and alikes:

Unicorns, Triple Rainbows, Package Management and Lasers by @bsimser one of the authors of previous Nu project
The Evolution of Package Management for .NET

There is another project with the source code of published packages:

http://nupackpackages.codeplex.com/

Video at Channel 9

Web Camps TV #8 – NuPack with Phil Haack | Web Camps TV | Channel 9

Many developers are preparing their software to be packaged with NuPack, examples:

Using Solution Factory + NuPack to create Opinionated Visual Studio Solutions
forks/jglozano/turbineserver: log

The .NET community received the new project with divided opinions. A lot of excitement and interests was distilled in Twitter and forums, and some skepticism, too. This is a thread in the semi-defunct Horn project:

Microsoft NuPack

My NuPack links:

http://delicious.com/ajlopez/nupack

Keep tuned!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Blog at WordPress.com.