Updating files as well as assemblies in an upgrade

Oct 17, 2011 at 5:53 PM

Naked Objects is now using NuGet in a reasonably sophisticated way.  (See http://nakedobjects.codeplex.com ) We’ve encountered a lot of pain points, and have managed to find workarounds in most cases, but we’re stuck on this one…

When we upgrade the NakedObjects.Mvc package (which you install from scratch into an Empty Mvc project) we are potentially upgrading not only the referenced assemblies, but any of the following types of files that were installed the first time:

-          Views, Controllers, Scripts, Config, and Code (such as the asax.cs, or the RunWeb class in App_Start)

Of these, NuGet only really seems to support updating the Config (allowing replacements for sections within config).  In all other cases, if NuGet finds such a file already there it just skips over it. We therefore have to resort to PowerShell, which is ugly enough in its own right, but made far worse by the fact that NuGet currently only allows us to run PowerShell after the rest of the install has completed. 

One solution might be to version all our file names, so that new versions are automatically installed alongside the old  -  as JQuery does.  But then you still need to make changes to other files that reference them so you're back to the same problem. And it won’t work for code files such as controllers.

N.B. We note that Microsoft is not yet using NuGet to install MVC 3, even though the latter is open source. If it were, they'd be hitting exactly equivalent issues, as Naked Objects MVC is just a slightly specialised version of an MVC project.

As a first step, a huge improvement would be to allow running separate PowerShell scripts before and after the install.  That way we could simply delete all the files that are ‘ours’ and had not been changed since the last install.  Or delete all the files that are ours, and warn developers that if they have made changes to them then they’ll need to merge back in their own changes using source control. Then the new versions would install automatically.

A nicer solution would be to provide more native support in NuGet for replacing and/or merging content within files in general, in a manner similar to what is allowed for configs only.

Any help, or reassurance of better things to come would be welcome ;-) 


Richard Pawson, Naked Objects Group

Oct 17, 2011 at 6:09 PM

NuGet actually supports updating web files (Views, Controllers, etc). But it can only do that if the files have not been modified. The way it checks this is by comparing the installed files with the files in the current nupkg file. Are you seeing cases where files that have not been modified are been skipped over? If so, this may be a bug that we need to investigate.

As for files that have been modified, NuGet skips them over to avoid data loss. Ideally, it would do some fancy merge, and maybe at some point we'll get there. This bug tracks a similar case.

I think I recall the idea of having both Pre and Post installs scripts coming up before, and it would probably make sense to support that. Others may be able to comment further on this.

As for MVC 3, note that the MVC project template is in fact using NuGet to install various things. But it does start from a Project Template and not from NuGet itself. NuGet is not really designed to replace Project Templates, as it doesn't have the ability to create projects. But NuGet is good at filling up existing projects with things :)

Oct 17, 2011 at 8:04 PM

Thanks for the response, David.  No, we've not seen any bugs in the updating of installed files.  Just to clarify my original posting, the main issue we face is updating files that the developer has changed.  The second situation, which you could argue is just a specialised case of the first, is where the file hasn't been altered by the developer, but where that file pre-exists the first NuGet install.  An example is if the user created the Mvc project, not as an Empty project but as, say, an Mvc Intranet project, so has default views in it, and then adds a NuGet package (such as our own NakedObjects.Mvc package) that has its own version of those files.

It also seems to me that the simplest solution would be just what you get when you copy files via Windows Explorer onto an existing location:  a warning that you are about to over-write an existing file, with the option to over-write, or rename, and also the option to take the same action for all conflicts.  Then rely on source control to identity and merge changes.

Oct 17, 2011 at 9:17 PM

Indeed, pre-existing vs modified from previous package are pretty similar. Well, if we were to attempt a diffing solution, then they would be different because in the modified case we could use 3-way merge mechanisms, whereas in pre-existing that would not work.

Giving the user the option to override might be a good solution that applies to both cases. This could come in two forms:

  1. A switch that allows overwriting for the whole operation
  2. A prompt for each individual file. The prompt would need to have 'Yes To All'/'No To All' options or it could get pretty painful

One potential issue with #2 is that it doesn't work so well when installing from the PowerShell Console, and I don't think we ever pop up prompts from there.

Could you please open a bug to track this?

Oct 18, 2011 at 1:33 AM

For the console, we do have the option to show text prompts (similar to the prompt in cmd.exe).