Instantly share code, notes, and snippets.

Embed
What would you like to do?
Computes the code share stats for the iCircuit project
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;
namespace CodeShareReport
{
class App
{
static void Main (string[] args)
{
var projects = new List<Solution> {
new Solution {
Name = "Mac",
ProjectFiles = new List<string> {
"C:\\Projects\\Circuit\\CircuitMac\\CircuitMac.csproj"
},
},
new Solution {
Name = "WP7",
ProjectFiles = new List<string> {
"C:\\Projects\\Circuit\\CircuitMetro\\CircuitMetro.csproj"
},
},
new Solution {
Name = "iOS",
ProjectFiles = new List<string> {
"C:\\Projects\\Circuit\\CircuitTouch\\CircuitTouch.csproj",
"C:\\Projects\\Circuit\\CircuitLib\\CircuitLib.csproj"
},
},
};
new App().Run(projects);
}
class Solution
{
public string Name = "";
public List<string> ProjectFiles = new List<string>();
public List<FileInfo> CodeFiles = new List<FileInfo>();
public override string ToString ()
{
return Name;
}
public int UniqueLinesOfCode
{
get
{
return (from f in CodeFiles
where f.Solutions.Count == 1
select f.LinesOfCode).Sum();
}
}
public int SharedLinesOfCode
{
get
{
return (from f in CodeFiles
where f.Solutions.Count > 1
select f.LinesOfCode).Sum();
}
}
public int TotalLinesOfCode
{
get
{
return (from f in CodeFiles
select f.LinesOfCode).Sum();
}
}
}
class FileInfo
{
public string Path = "";
public List<Solution> Solutions = new List<Solution>();
public int LinesOfCode = 0;
public override string ToString ()
{
return Path;
}
}
Dictionary<string, FileInfo> _files = new Dictionary<string, FileInfo>();
void AddRef (string path, Solution sln)
{
if (_files.ContainsKey(path)) {
_files[path].Solutions.Add(sln);
sln.CodeFiles.Add(_files[path]);
}
else {
var info = new FileInfo { Path = path, };
info.Solutions.Add(sln);
_files[path] = info;
sln.CodeFiles.Add(info);
}
}
void Run (List<Solution> solutions)
{
//
// Find all the files
//
foreach (var sln in solutions) {
foreach (var projectFile in sln.ProjectFiles) {
var dir = Path.GetDirectoryName(projectFile);
var projectName = Path.GetFileNameWithoutExtension(projectFile);
var doc = XDocument.Load(projectFile);
var q = from x in doc.Descendants()
let e = x as XElement
where e != null
where e.Name.LocalName == "Compile"
where e.Attributes().Any(a => a.Name.LocalName == "Include")
select e.Attribute("Include").Value;
foreach (var inc in q) {
AddRef(Path.GetFullPath(Path.Combine(dir, inc)), sln);
}
}
}
//
// Get the lines of code
//
foreach (var f in _files.Values) {
try {
f.LinesOfCode = File.ReadAllLines(f.Path).Length;
}
catch (Exception) {
}
}
//
// Output
//
Console.WriteLine("app\tt\tu\ts\tu%\ts%");
foreach (var sln in solutions) {
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4:p}\t{5:p}",
sln.Name,
sln.TotalLinesOfCode,
sln.UniqueLinesOfCode,
sln.SharedLinesOfCode,
sln.UniqueLinesOfCode / (double)sln.TotalLinesOfCode,
sln.SharedLinesOfCode / (double)sln.TotalLinesOfCode);
}
Console.WriteLine("DONE");
}
}
}
@Cheesebaron

This comment has been minimized.

Cheesebaron commented Dec 4, 2014

To make it work with shared projects. Instead of adding the shproj file use the projitem one instead. Then add:

const string SharedProjectPrefix = "$(MSBuildThisFileDirectory)";

and modify L128-130 to:

foreach (var inc in q) {
    var inc1 = inc;
    if (inc.StartsWith(SharedProjectPrefix)) {
        inc1 = inc.Remove(0, SharedProjectPrefix.Length);
    }
    AddRef(Path.GetFullPath(Path.Combine(dir, inc1)), sln);
}

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment