1

I've just written the first version of a workflow activity that will run Resharper's Code Issues on the projects and parse the output to display the issues as build warnings and errors.

At first, I was going to just call Resharper's command line and parse the resulting xml manually. After fiddling with the dlls in Resharper's SDK (through disassembly mostly), I found a way to parse the results using it's own public classes, which I figured was a much more elegant and safe way to do this.

The first problem I have is that that nuget package is absolutely huge. There is 140mb of files in there, which to me is absurd for a single, unpartitioned package. There seems to be such heavy coupling between them that by using just a few model classes and the parser class, I have to drag a dozen or so of those dlls along, some of them which seemingly have nothing to do with the main dlls I need. This is not a show stopper though, I'm struggling with something else now:

In the end, I managed to track down the dependencies I needed to 41 assemblies (which is, again, insane, but alas). Initially, I tried removing everything and adding the missing references one by one, but this turned out to be unreliable, still missing some indirect references, even after compiling successfully. Then, I decided to code a small console application to find all referenced assemblies in the main Resharper assemblies I used, which gave me the 41 references I mentioned. This is the code I used to find every dependency.

Since these are custom activities we are talking about, I decided to create a unit test project to validate them. Using these 41 references only, everything works correctly.

When I added the activity to the build workflow though, and pointed the build controller to the source control folder containing the required assemblies, every time I schedule a build, the process fails stating that I need one extra dll from Resharper's SDK. For example, this is the first one it asks:

Could not load file or assembly 'AsyncBridge.Net35, PublicKeyToken=b3b1c0202c0d6a87' or one of its dependencies. The system cannot find the file specified. (type FileNotFoundException)

When I add this specific assembly to the TFS folder, I get another similar error for another dll, and this keeps going on and on.

What I wanted to know is how can I know exactly which assemblies a workflow XAML will need in order to run correctly? My custom activity dll has two specific CodeActivities and a XAML only activity that uses these two. This XAML acticity is what I'm directly using in the modified workflow template.

I see that besides the references in my project, the XAML activity also contains a TextExpression.ReferencesForImplementation section, with some assembly names. I've run my dependency finder program on those dependencies too, and the results are the same 41 assemblies already at the TFS folder.

Meanwhile I'll go with having the whole SDK into the custom assemblies folder, but I would really like to avoid this in the future since it has such an enormous amount of unneeded and big dlls in there.

Community
  • 1
  • 1
julealgon
  • 7,072
  • 3
  • 32
  • 77

2 Answers2

2

First, we have request for our command line tool to support workflow activity and we decided to implement just plain MsBuild task which is universal and works in TFS too. Task and targets files are included in ReSharper CLT 8.2.

Second, if you still want to implement workflow activity it's pretty easy to do with new API in CLT, designed specially for custom processing of found issues - http://confluence.jetbrains.com/display/NETCOM/Custom+InspectCode+Issue+Logger.

And last, but not least, you do not need to put in VCS binaries of ReSharper SDK package. Use NuGet's restore package functionality.

If you have any other questions I'll be glad to answer them.

derigel
  • 3,218
  • 2
  • 19
  • 31
  • Oh my god... I can't believe I missed the .Targets there. This is actually a better solution, but I figured you guys would never implement it that way since the integration in TeamCity is a defining feature. I still fail to see how I'll distribute this to the team though, since the command line tools is just a zip without installation. If there is no seamless integration on developers' machines it is still a bad solution. Perhaps another specific nuget package would be ideal? Or at least include this .Targets file on the existing package. – julealgon Apr 22 '14 at 13:35
  • As I said before, I can't use package restore for what I'm currently implementing (custom Workflow activities). There is no hook in the build process to let it download packages and stuff. Remember that this runs much earlier than msbuild itself. – julealgon Apr 22 '14 at 13:37
1

A custom activity is being load and run by .NET CLR like any other .NET program. If the stack trace reports a missing file, then it's required by the CLR and you can't change this fact without refactoring your code.

Having an entire SDK references in the custom assembly folder doesn't make sense. I would prefer GAC deployment over huge binaries folder in the source control. Or maybe consider having these activities running an pre\post build scripts in MSBuild or PowerShell.

KMoraz
  • 14,004
  • 3
  • 49
  • 82
  • Why does it work under unit testing though? Also, why doesn't `GetReferencedAssemblies` find these dependencies? Shouldn't it? And lastly, the SDK is a nuget package, there is no MSI installer. To put these dlls on the GAC would take ages I assume, since I would have to use the command line to register each of them (I can be very wrong on this one, never done it). – julealgon Apr 17 '14 at 15:14
  • Ok, I'm dumb. There is a msi installer [here](http://www.jetbrains.com/resharper/download/). Hmm, this may be useful. I'll install it on the build server and it should work fine without those dlls in TFS. I figure I'll still need the nuget package since I don't want to force every developer to install the SDK. – julealgon Apr 17 '14 at 15:17
  • If the SDK is a nuget package, you should be using [nuget package restore](https://docs.nuget.org/docs/reference/package-restore-with-team-build). I assume `GetReferencedAssemblies` only finds direct references. – KMoraz Apr 17 '14 at 15:18
  • This is the build workflow we are talking about, using package restore in something that is not even a msbuild project makes no sense (unfortunately). We are already using package restore for all projects, but the build process workflow cannot work that way, it requires that either the assemblies are registered in the GAC on the machine or that you point the controller to a TFS folder with the required assemblies. Also, if `GetReferencedAssemblies` only found direct references, it would return 4 or 5 assemblies in my case, instead of 41. – julealgon Apr 17 '14 at 15:21
  • I meant use package restore in MSBuild script, not in build activity. – KMoraz Apr 17 '14 at 15:29
  • In order for the build to load the xaml, it needs the references at that moment. I can't put the package restore process anywhere in between so that it would be able to load the xaml before the dependencies are already present. I think it is absolutely impossible to use package restore in my scenario, unless I'm really missing something. – julealgon Apr 17 '14 at 15:31
  • 1
    I probably missing the background for what you're trying to accomplish, but it sounds to me that design-wise, you shouldn't use a xaml activity at all. I'd rather use a script for that. Take a look at [this](http://blog.nwcadence.com/whats-new-in-tfs-2013-team-builds-are-able-to-run-in-powershell/) – KMoraz Apr 17 '14 at 15:46
  • The requirement here is actually very simple: I want to report code issues from resharper to the build process. The fact that I can code this as an activity and share it with other teams is very cool. I really wonder why you think that I shouldn't be using custom activities here, perhaps you could elaborate? I thought the support for scripts was supposed to be for generic stuff, but I need information from the running build to analyze the solutions. – julealgon Apr 17 '14 at 15:57
  • While a xaml activity is most elegant, it designed for simple, single-action tasks. If the activity hides too many 3rp-party dependencies, then you rather run the native command. I haven't tried it myself - how about calling [ReSharper command line tools](http://www.jetbrains.com/resharper/features/command-line.html) and capturing the results to the build? – KMoraz Apr 17 '14 at 16:57