I vowed not to come out too early with loud propaganda on what OpenWrap is, but many have told me that they want to see it happen now rather than together with a beta, and I’ve been coding away for long enough that the code may be of interest to some. So, without further do, I announce my latest venture in world OSS domination called OpenWrap.
OpenWrap is currently classified as a package management system. In reality, it’s an export management system. The reason for OpenWrap existing is to deliver stuff to whatever environment is needing it, be it at development time within Visual Studio, at deployment time when pushing an OpenRasta or MVC web-site, or at run-time for a rich client.
An application is usually made of a bunch of stuff. Some are components, some are static files, some are executable tools, and some may be an energy pattern that needs to go from point A to point B.
OpenWrap is a simple packaging format that deals with separating those stuff things into exports. An export is whatever you want, and only the consumer of an export need to know and understand a certain kind of export.
An example of exports: assembly references and build files
One of the many exports that everyone is focusing on at the moment is binary assembly distribution. You want to easily add a component built by someone else, without the hassle of having to download binaries and all their dependency hell yourself. I hear you! While projects like horn have attempted to take away some of the pain by automating cross-trunk version building, the lack of binary distribution and versioning has made using the tool a hit-or-miss, because of the nature of how open-source software is built more than because of what horn is.
So, in OpenWrap, you can use the OpenWrap shell, called o.exe, to issue a bunch of commands. So if you want a reference to nhibernate, you’d do
o add-wrap nhibernate
OpenWrap will try and find the package called nhiberante, and all the packages it depends on, and install them in your system repository. At build time, each package you depend on will automatically get its references added to your project. There’s even a ReSharper plug-in to make it real-time.
In your package, which happens to be a simple zip file, each dll present in the /bin-netXXX folder will be automatically resolved. Why the XXX? Because in OpenWrap, the binary exports are dependent on the version of .net you’re running under. That means that if you run under .net 2.0, you’ll get all the DLLs present in /bin-net20, but if you’re under .net 3.5, you’ll get the ones in /bin-net35.
Want to provide architecture-dependent code? Just put the same dll and the same API in both /bin-x86-net20 and /bin-x64-net20, and OpenWrap will figure out which of the versions to use.
Another example of exports: commands
In OpenWrap, commands are also a type of export, that live in /commands. Want to provide command-line commands to execute as part of your project? As long as your package is present in a solution, all of the commands you create will be available from the command-line. XCopy command-line extensibility is the feature used by openwrap itself to execute its own commands, so you have the guarantee that only the version of OpenWrap (and other packages) you have in your project repository will be the ones executed when you are running the shell.
The sky is the limit
Of course, package exports are extensible, so if you want for your project a custom export, or if you feel (like me) that web applications should share a same export for things like jQuery, then you can integrate yourself with that and make it your own.
There’s a few repositories in OpenWrap. The System repository is the one living in your /Users/UserName/AppData/Local/OpenWrap/wraps folder. Anytime you execute an OpenWrap command anywhere that’s not an OpenWrap folder, it will come from your system repository.
As you may have guessed by now, each of your projects will also have its own repository. You can consider that an equivalent to your vendors folder in Rails. In each of your projects, all exports (commands, assemblies etc) come from your project repository first.
And of course, multiple repositories can exist. The repository at http://wraps.openwrap.org is maintained by myself, and you should be able to upload your own packages there very soon. If you want to add your own repository, the openwrap-server will provide you with a full-fledged repository you can install locally. You then only need to issue a o add-remote myRepository http://myRepository.com command to add your own.
Whenever you execute the o add-wrap xxx command in a project, a line will be added to your descriptor file. This file is the description of what your application does, what other packages it depends on and what versions it needs to execute. The end-result in your file would add a line. Here’s a typical package descriptor, to give you a sense of what things look like. (note the syntax is slightly different than what is on the wiki, those changes are coming up on github in the next few days as we ramp up for release).
Depends: nhibernate >= 2.0.0 and < 3.0
Depends: openfilesystem = 1.0.0
Description: A wiki system based on the textile language and using GIT as a repository.
Versions are very simple, you decide what your package is compatible for. When it comes to dependencies, only [Major[.Minor[.Build]]] are taken into account. If you add the fourth number, the revision, openwrap will always update the package to the latest revision.
Of course, you can update all packages in one go automatically by doing o update-wrap. This will update the project repository to the latest compatible version of packages, as described in your wrap descriptor file.
One of the things I don’t want to address just yet is building packages. There’s an MSBuild task that makes building the zip files easier, but I don’t want to go down the route Horn got and turn a dependency manager into dependency hell. So for now, people are expected to build their own zip files. It’s only temporary however, as I do expect in the next few versions for OpenWrap to not be built from a build script anymore, which may end up being the default convention. Who knows? For now, OpenWrap integrates itself in your existing projects by replacing the target import by openwrap’s one.
I’ve not put up binary releases just yet, but when they are made available (or if you build it yourself), the shell is able to automatically install itself and retrieve the latest version of packages that it needs to run. That means that the installer is 35kb. You shouldn’t have much difficulty downloading o.exe and running with it very quickly.
There’s a lot more to OpenWrap so far, from anchoring to the build system, but this is enough of an intro to give you a taste of what I’ve been up to for a few months.
Bar one piece of functionality on the client, which I’m in the middle of changing around (anchoring, a blog post at some point will explain what that is), we’re nearly ready for a first beta release.
Want to contribute? The site is at http://github.com/openrasta/openwrap. While it’s under the OpenRasta brand, the project is stand-alone, and I will be managing OpenWrap as an independent tool. I will however base any further OpenRasta developments on it.
I know there has been recently a lot of noise from many parties in the package management space. The only thing I can tell you is that I’m fully committed to bringing OpenWrap in the hands of developers as quickly as possible. It’s a different approach to a complicated problem, and I think it’s hitting a damn nice spot even if I may say so myself. I’ll post in a few days the first binaries (when the server is up) so you can start playing with it, open accounts and start publishing your own wraps. After that, there’s a lot of work to do to enable testing, documentation and many other scenarios.
One last word
If I was to request one last thing from you, reader, it would be the following. Package management is going to be the next Vietnam war on .net, and many people will come up with different solutions. It’s all for the best, and most projects, as they have done many times before, will die off on their own. This is to be expected. As such, I implore the .net world to let enough time for each of those projects to compete purely on the quality and functionality they provide, and let the best one eliminate naturally the other ones. Don’t succumb to the belief that standardizing early will help, or that popularity would be a distinctive factor. If we fuck-up the package management story on .net, we may never recover, so give it a bit of time and be circumspect in your analysis.
And don’t forget, my project got a cooler name anyway.