Adding OpenWrap to an existing project (Part 1)

I’m continuing writing up teaser posts on how to use OpenWrap. Building a new office has taken away my Sunday, so the server is still not up, and the code unfinished. A few more days and we’ll be there.

In the meantime, assuming you have OpenWrap installed, here’s how to convert an existing asp.net site (here an OpenRasta site running on top of asp.net) to OpenWrap.

From a default project…

Here’s the layout of my project.

PS C:\src\caff\git\openwrap-server> tree
Folder PATH listing for volume BOOTCAMP
Volume serial number is 60DA-D801
C:.
└───src
    └───OpenWrap.Server
        ├───App_Data
        ├───Handlers
        ├───Properties
        ├───Resources
        └───Views

First step is to add a wrap descriptor file and a version file that will be used to build the package.

PS C:\src\caff\git\openwrap-server> "Description: an openwrap server implementation based on OpenRasta." | ac openwrap-server.wrapdesc
PS C:\src\caff\git\openwrap-server> "1.0.0" | ac version

And finally, we want to create a project repository in which openwrap packages will be stored so OpenWrap can know where to put those. We can do this by creating a wraps folder.

PS C:\src\caff\git\openwrap-server> md wraps | out-null; tree
Folder PATH listing for volume BOOTCAMP
Volume serial number is 60DA-D801
C:.
├───src
│   └───OpenWrap.Server
│       ├───App_Data
│       ├───Handlers
│       ├───Properties
│       ├───Resources
│       └───Views
└───wraps

Adding OpenWrap to the project

Time to add OpenWrap to our project, which will add the necessary instruction to our wrap descriptor and all needed files.

PS C:\src\caff\git\openwrap-server> o add-wrap openwrap
# OpenWrap v1.0.0.0 ['C:\Users\sebastien.lambla\AppData\Local\OpenWrap\wraps\_cache\openwrap-1.0.0.13979169']
No wrap descriptor found, installing locally.
Project repository found.
Dependency added to descriptor.
Copying 'openwrap-1.0.0.13979169' to 'Project repository'
Expanding packages to cache...
PS C:\src\caff\git\openwrap-server> tree
Folder PATH listing for volume BOOTCAMP
Volume serial number is 60DA-D801
C:.
├───src
│   └───OpenWrap.Server
│       ├───App_Data
│       ├───Handlers
│       ├───Properties
│       ├───Resources
│       └───Views
└───wraps
    ├───openwrap
    │   ├───bin-net35
    │   ├───build
    │   └───commands
    └───_cache
        └───openwrap-1.0.0.13979169
            ├───bin-net35
            ├───build
            └───commands

Couple of interesting notes. First, you can see that the o.exe tool redirects all calls to the last version of the OpenWrap pacakge on the system.

Secondly, the wrap decriptor now contains the line depends: openwrap.

A folder structure…

Let’s examine what files are actually in this wraps folder that now exists:

 

└───wraps
    │   openwrap-1.0.0.13979169.wrap
    │
    ├───openwrap
    │   │   openwrap-1.0.0.13979169.wrapdesc
    │   │   version
    │   │
    │   ├───bin-net35
    │   │       ICSharpCode.SharpZipLib.dll
    │   │       OpenFileSystem.dll
    │   │       OpenRasta.Client.dll
    │   │       OpenWrap.dll
    │   │
    │   ├───build
    │   │       OpenWrap.Build.Tasks.dll
    │   │       OpenWrap.CSharp.targets
    │   │       OpenWrap.Resharper.dll
    │   │       OpenWrap.tasks
    │   │
    │   └───commands
    │           OpenWrap.Commands.dll
    │
    └───_cache
        └───openwrap-1.0.0.13979169
            │   openwrap-1.0.0.13979169.wrapdesc
            │   version
            │
            ├───bin-net35
            │       ICSharpCode.SharpZipLib.dll
            │       OpenFileSystem.dll
            │       OpenRasta.Client.dll
            │       OpenWrap.dll
            │
            ├───build
            │       OpenWrap.Build.Tasks.dll
            │       OpenWrap.CSharp.targets
            │       OpenWrap.Resharper.dll
            │       OpenWrap.tasks
            │
            └───commands
                    OpenWrap.Commands.dll

There are a couple of interesting things happening. First, the wrap package itself got copied over in the wraps folder. The goal here is for you to always commit those dependencies as part of your project in source-control. Second, you’ll notice that the content of this file is uncompressed in the _cache folder. This one should always be part of your ignores, as you really don’t want to be committing the zip file *and* the content.

Finally,you’ll notice there’s also an openwrap folder that has the same content as the _cache/openwrap-1.0.0.13979169 folder. Lets look more closely.

PS C:\src\caff\git\openwrap-server> ls wraps

Mode           LastWriteTime       Length Name
----           -------------       ------ ----
d----    02/08/2010    01:23   <JUNCTION> openwrap [C:\src\caff\git\openwrap-server\wraps\_cache\openwrap-1.0.0.13979169]

Indeed, this folder is not a real folder but a junction to the latest version. This linking is only done for pacakges that are anchored. So why do we have this?

In an ideal world, everything would use OpenWrap for finding stuff, and the latest version for a project would always be selected. But we live in a world full of dragons and daemons that require a bit more of a stable path. As OpenWrap hooks in MSBuild (we’ll see how in the next post), it’s important that the msbuild files are in a reasonably stable location. It’s also important that OpenWrap is available the first time you checkout your files, so a build can happen instantly.

Folder structure

You may notice that packages contain multiple folders (which are called an export in OpenWrap). The bin-Xxx are the ones in which assemblies needed for referencing in a project are contained. Each .net framework profile has its own identifiers, and the resolution algorithm uses those identifiers to decide what assembly to load. If you’re on .net 3.5, the probing will go bin-net35, bin-net30, and bin-net20, and will fail when it cannot resolve assemblies.

There are a couple more exports in the package: commands contain all the commands you can execute from the command-line (or from any host that can execute those commands, currently only the command line), and build contains all msbuild-related extensibility points (which I really hope to manage to import automatically further down the road).

Conclusion

So, there you have it, in a few seconds we installed OpenWrap in the solution. Next up, we’ll hook-up our project by changing a line in an MSBuild file.

Ads

The initial OpenWrap installation

Going down OpenWrap’s rabbit hole, the first thing you do is retrieve a fresh copy of o.exe, the Command shell. At a whopping 32k (for the debug build), you could get the initial file in 234 text messages. Lets open the file straight from the web site, and we’re greeted by installation options.

The OpenWrap shell is not installed on this machine. Do you want to:
(i) install the shell and make it available on the path?
(c) use the current executable location and make it available on the path?
(n) do nothing?

I think the options are quite self-explanatory, but let’s recap:

  • (i) will copy o.exe to ~/AppData/Local/OpenWrap/ and add this path to your PATH environment variable for the current user
  • (c) will simply add an o.exe.link file in ~/AppData/Local/OpenWrap/ and add this path to your PATH
  • (n) will do nothing this time around and run o.exe as normal.

Let’s choose the first option

OpenWrap packages not found. Attempting download.
Downloading http://wraps.openwrap.org/bootstrap [....................]
Downloading http://wraps.openwrap.org/wraps/openwrap-1.0.0.13979169.wrap [.............]
Expanding pacakge...
# OpenWrap v1.0.0.0 ['C:\Users\sebastien.lambla\AppData\Local\OpenWrap\wraps\_cache\openwrap-1.0.0.13979169']
Command was not understood. Type 'help' to get a list of supported commands.

I do hope that this is also quite self-explanatory, but just in case… When the shell tries to execute the first time, it will not find the OpenWrap packages anywhere. At that stage, it will go to the openwrap web-site and download the bootstrap packages to the correct location, which is just a list of URIs to download in a text file.

Once all this is done (and notice the wonderful typo in the output, you can check on github that this is all live code), the shell can now delegate to the openwrap code itself to parse the command. And as there was no command (remember, we started the application from a web browser), the system tells us that the command was not understood.

I tried to make it more complicated but I just didn’t have the time.

Ads

The future of OpenRasta

You may have noticed that development on OpenRasta has slowed down quite a bit recently. It’s a double-edge sword: the codebase is stable enough for most people, which has helped adoption of the 2.0 branch quite a bit, but at the same time there are new features that I want to see implemented.

As you probably know, I’m putting most of my energy on OpenWrap until we have a fully functioning first beta release, because I want the next version of OpenRasta to be completely built on top of it. So what is the future of OpenRasta?

OpenRasta 2.0 RTM coming to a shop near you soon

The current branch on github is going to be enhanced slightly by the addition of a few fixes / features that will close the loop for a 2.0 release:

  • Http header processing will special-case our friend Set-Cookie, which will solve a bunch of issues people have been reported when trying to use those evil babies.
  • The diagnostics output is going to be made a bit nicer by actually showing the log on the web page itself rather than the dreaded “There was an error in a contributor”.
  • I’ll pull in the fixes requested by those that want to use the binder to do constructor value injection.
  • We’ll put the nice logo we’ve had and not used for so long.

That’s it. This should happen in the next week or so.

OpenRasta 3.0

I’ve decided to rename 2.1 in 3.0, for the simple reason that I’m going to move stuff around quite a bit, all driven by my need for better componentisation of the codebase, most of it driven by OpenWrap. I’m not ready to discuss the feature-set yet, but August will be the big development push on the first iteration. Expect a lot of splitting of code, of re-evaluation of some features that are not as much in use as I’d like, and hopefully a lot of bug fixes in the process.

In the meantime…

In the meantime, you may as well get yourself acquainted with OpenWrap, because it will be mandatory for OpenRasta 3.0.

I’d also like to thank Hadi and the codebetter guys, as our bug tracking has now moved to youtrack on codebetter.com, at http://youtrack.codebetter.com/issues/OR. Let me know what you think of the new system.

Ads