Skip to content

Instantly share code, notes, and snippets.

@chilversc
Created January 26, 2015 11:57
Show Gist options
  • Save chilversc/03da811ccc973794f961 to your computer and use it in GitHub Desktop.
Save chilversc/03da811ccc973794f961 to your computer and use it in GitHub Desktop.
Sorting visual studio project files
static XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
static XName ItemGroup = ns + "ItemGroup";
static XName Reference = ns + "Reference";
static XName ProjectReference = ns + "ProjectReference";
static XName Condition = "Condition";
static XName Include = "Include";
void Main(string[] args)
{
if (args.Length != 1) {
Console.WriteLine ("Syntax: lprun SortProject.linq Core\\Core.csproj");
return;
}
XDocument doc = XDocument.Load (args [0]);
var root = doc.Root;
var groups = root
.Elements (ItemGroup)
.Where (group => !group.HasAttributes)
.ToList ();
foreach (var g in groups) {
g.Remove ();
}
var items = GroupItems (groups.SelectMany (g => g.Elements ()));
root.Add (GroupItems (items.Elements (Reference)));
root.Add (GroupItems (items.Elements (ProjectReference)));
root.Add (GroupItems (items.Elements ()));
doc.Save (args [0]);
}
private XElement GroupItems (IEnumerable<XElement> elements)
{
var container = new XElement (ItemGroup);
MoveElements (container, elements);
return container;
}
private void MoveElements (XElement container, IEnumerable<XElement> elements)
{
foreach (var element in elements.OrderBy (e => e, new ItemComparer ()).ToList ()) {
element.Remove ();
container.Add (element);
}
}
class ItemComparer : IComparer<XElement>
{
public int Compare (XElement e1, XElement e2)
{
var a1 = e1.Attribute (Include);
var a2 = e2.Attribute (Include);
if (a1 == null && a2 == null) return 0;
if (a1 == null) return 1;
if (a2 == null) return -1;
var v1 = a1.Value;
var v2 = a2.Value;
try {
var d1 = Path.GetDirectoryName (v1);
var d2 = Path.GetDirectoryName (v2);
var result = string.Compare (d1, d2, StringComparison.OrdinalIgnoreCase);
if (result != 0) return result;
var f1 = Path.GetFileName (v1);
var f2 = Path.GetFileName (v2);
result = string.Compare (f1, f2, StringComparison.OrdinalIgnoreCase);
return result;
} catch {
return string.Compare (v1, v2, StringComparison.OrdinalIgnoreCase);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment