The Weekly Source Code 42 - Tree Trim, Plugins, and MEF
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:
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.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
http://msmvps.com/blogs/peterritchie/archive/2006/10/02/Add-Visual-Studio-2005-Intermediate-Files-to-Windows-Disk-Cleanup.aspx
HKEY_CLASSES_ROOT\Directory\shell\<WHATEVER TEXT YOU WANT>\command
Cheers
Matt
If the plug-in occupy less resource, it will be better.
Comments are closed.