« CLR and DLR and BCL, oh my! - Whirlwind ... | Main | C# 4 and the dynamic keyword - Whirlwind... »

image I really advocate folks reading as much source as they can because you become a better writer by reading as much as writing. That's the whole point of the Weekly Source Code - reading code to be a better developer.

Reading code in Open Source projects is a good way to learn, especially if the project has been around a while and been successful, or if you already respect the team of people working on it. Less reliably, you can find snippets of code by searching and sharing code.

Tree Trim == CleanSources++

Many years ago, Omar Shahine wrote a great little app called Clean Sources. It added a right-click menu to the Windows Explorer that would delete your bin, obj and setup folders.

Later, Jeff wrote Clean Sources Plus. It added a "Clean and Zip" option as well as support for removing source control bindings.

Now, Steve Dunn has extended these to create Tree Trim, a command-line tool to do all this and more. He's extended it to include a plugin model that creates a little pipeline of plugins. You can chain them together and extend the command-line with your own plugins, and MEF (Managed Extensibility Framework) is at its core.

Tree Trim is convenient for build servers where you want to, for example, make a working copy, delete source control bindings, zip stuff up, email it, etc.

Each command line argument is a "task" and each command line arg (moniker) maps to a object.

treetrim.console.exe c:\dev\myproject -workingCopy -deleteFromDisk -zip -email

It's significant that order of arguments matter, so the args cause the plugins to run in order, like "make working copy, delete bin/obj, zip up, email."

Make your own Plugin and be MEFy

He's got an IPlugin interface:

public interface IPlugin
{
string Moniker { get ; }
string WorkingPath { get ; }
void Cleanup( ) ;
void Run(IPluginRuntimeSettings settings, IPlugin lastPlugin);
}

When you make a plugin, you need to let MEF know that it's available by Exporting the type:

[Export(typeof(IPlugin))]
public class SomePlugin : IPlugin
{
...
public string Moniker
{
get { return @"newPluginArgument" ; }
}
...
}

Then any plugin in the same directory gets pulled into a list of plugins...

public DiscoverPluginsInAssemblyDirectory( )
{

var catalog = new DirectoryCatalog(disk.DirectoryOfExecutingAssembly);

var container = new CompositionContainer(catalog);

var batch = new CompositionBatch();
batch.AddPart(this);

container.Compose(batch);
}

[Import( typeof( IPlugin ) )]
public IList<IPlugin> Plugins
{
get;
set;
}

The app kicks off this little pipeline by passing the command line args in along with the plugins found:

Trimmer.TrimTree(
new TaskCollection( pluginDiscoverer.DiscoveredPlugins, commandLineArgs ),
path );

...then...

public static void TrimTree(ITaskCollection tasks, string sourceTreeRoot)
{
ITask lastTask = new Task { Plugin = new NullPlugin( sourceTreeRoot ) } ;

foreach ( ITask eachTask in tasks )
{
eachTask.Run( lastTask );

lastTask = eachTask ;
}

IEnumerable<ITask> reversedTasks = tasks.Reverse( ) ;

foreach (ITask eachTask in reversedTasks)
{
eachTask.Cleanup();
}
}

The code is actually very easy to read and is up at TreeTrim on Google Code and check out the FAQ. Plugins are super easy with MEF and Tree Trim has some good examples of a number of things. First, just plugins in general, but also a technique for passing settings to plugins.

Add Context Menus to Explorer

You can easily create context menus in Explorer for this tool (or any tool). Add a Key to the Registry like below.

HKEY_CLASSES_ROOT\Folder\shell\<WHATEVER TEXT YOU WANT>\command

Then in the (Default) string value, put it something like this (for example):

"C:\Program Files (x86)\Tree Trim\TreeTrim.Gui.exe" "%1"  -workingcopy -deletefromdisk -zip:writeTo:"c:\users\scott\desktop\justzipped.zip"+dontCleanUp

Here's how it looks in registry:

Registry Editor (2)

Steve is also starting to setup tests using XUnit. He's starting to use the ContextSpecification Pattern for his tests, so it'll be interesting to see if he completes the tests. That part is pretty basic so far. Check out the TaskCollectionSpecs.cs as an example.

All in all, fun to read, and an interesting tool I'll use to quickly clean and send code samples around. I may extend it with a plugin to upload to my blog, then put the link in the clipboard. That could make blogging samples easier.



Wednesday, May 20, 2009 4:18:56 AM (Pacific Standard Time, UTC-08:00)
I really like the simplicity of the plugin framework. It just reinforces my theory that a well thought out design will typically result in clean and elegant code. Good post.
Wednesday, May 20, 2009 7:16:11 AM (Pacific Standard Time, UTC-08:00)
You might also like:

http://msmvps.com/blogs/peterritchie/archive/2006/10/02/Add-Visual-Studio-2005-Intermediate-Files-to-Windows-Disk-Cleanup.aspx
Wednesday, May 20, 2009 1:53:36 PM (Pacific Standard Time, UTC-08:00)
Nice to see how simply the MEF functionality fits in.
Friday, May 22, 2009 1:16:35 AM (Pacific Standard Time, UTC-08:00)
You shouldn't add your registry key to Folder, but to Directory. Folder includes non-file system folders, such as control panel and the recycle bin, and the tool won't work on those. So, just register it under:

HKEY_CLASSES_ROOT\Directory\shell\<WHATEVER TEXT YOU WANT>\command

Cheers
Matt
Sunday, May 24, 2009 5:11:41 PM (Pacific Standard Time, UTC-08:00)
I like plug-in (add-on) very much, it really save me lots of time!

If the plug-in occupy less resource, it will be better.
Comments are closed.

Contact

Sponsors

Hosting By

Hot Topics

Tags

Calendar

<November 2009>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Archives

November, 2009 (5)
October, 2009 (19)
September, 2009 (11)
August, 2009 (12)
July, 2009 (21)
June, 2009 (26)
May, 2009 (16)
April, 2009 (13)
March, 2009 (17)
February, 2009 (17)
January, 2009 (18)
December, 2008 (32)
November, 2008 (17)
October, 2008 (22)
September, 2008 (16)
August, 2008 (14)
July, 2008 (25)
June, 2008 (19)
May, 2008 (17)
April, 2008 (17)
March, 2008 (26)
February, 2008 (21)
January, 2008 (28)
December, 2007 (19)
November, 2007 (17)
October, 2007 (31)
September, 2007 (39)
August, 2007 (37)
July, 2007 (43)
June, 2007 (37)
May, 2007 (32)
April, 2007 (38)
March, 2007 (29)
February, 2007 (46)
January, 2007 (31)
December, 2006 (27)
November, 2006 (31)
October, 2006 (32)
September, 2006 (39)
August, 2006 (34)
July, 2006 (40)
June, 2006 (18)
May, 2006 (31)
April, 2006 (34)
March, 2006 (30)
February, 2006 (38)
January, 2006 (44)
December, 2005 (19)
November, 2005 (34)
October, 2005 (24)
September, 2005 (37)
August, 2005 (20)
July, 2005 (24)
June, 2005 (33)
May, 2005 (16)
April, 2005 (22)
March, 2005 (34)
February, 2005 (15)
January, 2005 (37)
December, 2004 (28)
November, 2004 (30)
October, 2004 (34)
September, 2004 (22)
August, 2004 (34)
July, 2004 (18)
June, 2004 (64)
May, 2004 (49)
April, 2004 (21)
March, 2004 (29)
February, 2004 (29)
January, 2004 (36)
December, 2003 (25)
November, 2003 (24)
October, 2003 (59)
September, 2003 (42)
August, 2003 (24)
July, 2003 (44)
June, 2003 (29)
May, 2003 (21)
April, 2003 (30)
March, 2003 (27)
February, 2003 (47)
January, 2003 (50)
December, 2002 (31)
November, 2002 (38)
October, 2002 (44)
September, 2002 (15)
May, 2002 (2)
April, 2002 (4)

Google Ads