UltimateZoneBuilder/Source/Tools/ChangelogMaker/Program.cs
2017-01-15 00:35:40 +02:00

161 lines
4.9 KiB
C#
Executable file

#region ======================== Namespaces
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
#endregion
namespace mxd.ChangelogMaker
{
class Program
{
#region ======================== Constants
private const string SEPARATOR = "--------------------------------------------------------------------------------";
#endregion
#region ======================== Main
static int Main(string[] args)
{
Console.WriteLine("Changelog Maker v03 by MaxED");
if(args.Length != 4)
{
return Fail("USAGE: ChangelogMaker.exe input output author revision_number\n" +
"input: xml file generated by MakeRelese.bat\\MakeGITRelese.bat\n" +
"output: directory to store Changelog.txt in\n" +
"renameauthor: commit authors rename scheme. For example, \"m-x-d>MaxED|biwa>Boris\"\n" +
"revision_number: latest revision number", 1);
}
string input = args[0];
string output = args[1];
string renameauthor = args[2]; // m-x-d>MaxED|biwa>Boris
int revnum;
if(!int.TryParse(args[3], out revnum)) return Fail("Unable to parse revision number from string '" + revnum + "'.", 4);
if(!File.Exists(input)) return Fail("Input file '" + input + "' does not exist.", 2);
if(!Directory.Exists(output)) return Fail("Output folder '" + output + "' does not exist.", 3);
// Create author rename array, because git log can't decide how to call me...
Dictionary<string, string> authorrename = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
string[] parts = renameauthor.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
foreach(string ren in parts)
{
string[] rename = ren.Split(new[] { '>' }, StringSplitOptions.RemoveEmptyEntries);
if(rename.Length == 2 && !string.IsNullOrEmpty(rename[0].Trim()) && !string.IsNullOrEmpty(rename[1].Trim()))
{
authorrename[rename[0].Trim()] = rename[1].Trim();
}
else
{
Console.WriteLine("Invalid rename scheme: \"" + ren + "\"");
}
}
//Replace bracket placeholders, because git log command doesn't escape xml-unfriendly chars like < or >...
string inputtext = File.ReadAllText(input);
inputtext = inputtext.Replace("<", "&lt;").Replace(">", "&gt;").Replace("&", "&amp;").Replace("[OB]", "<").Replace("[CB]", ">");
XmlDocument log = new XmlDocument();
using(MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(inputtext)))
{
log.Load(stream);
}
StringBuilder result = new StringBuilder(1000);
char[] messagetrim = {' ', '\r', '\n' };
foreach(XmlNode node in log.ChildNodes)
{
if(node.ChildNodes.Count == 0) continue;
foreach (XmlNode logentry in node.ChildNodes)
{
string commit = (logentry.Attributes != null ? logentry.Attributes.GetNamedItem("commit").Value : "unknown");
DateTime date = DateTime.Now;
string message = string.Empty;
string author = string.Empty;
// Add revision info...
if(logentry.Attributes != null)
{
var revinfo = log.CreateAttribute("revision");
revinfo.Value = revnum.ToString();
logentry.Attributes.SetNamedItem(revinfo);
}
foreach(XmlNode value in logentry.ChildNodes)
{
switch(value.Name)
{
case "author":
if(authorrename.ContainsKey(value.InnerText))
{
author = authorrename[value.InnerText];
value.InnerText = author; // save author
}
else
{
author = value.InnerText;
}
break;
case "date":
date = Convert.ToDateTime(value.InnerText);
break;
case "msg":
message = value.InnerText.Trim(messagetrim);
value.InnerText = message; // also save trimmed message
break;
}
}
result.Append("R" + revnum)
.Append(" | ")
.Append(commit)
.Append(" | ")
.Append(author)
.Append(" | ")
.Append(date.ToShortDateString())
.Append(", ")
.Append(date.ToShortTimeString())
.Append(Environment.NewLine)
.AppendLine(SEPARATOR)
.Append(message)
.Append(Environment.NewLine)
.Append(Environment.NewLine)
.Append(Environment.NewLine);
// Decrease revision number...
revnum--;
}
break;
}
// Save modified xml
log.Save(input);
//Save result
string outputpath = Path.Combine(output, "Changelog.txt");
File.WriteAllText(outputpath, result.ToString());
Console.WriteLine("Saved '" + outputpath + "'");
//All done
return 0;
}
#endregion
private static int Fail(string message, int exitcode)
{
Console.WriteLine(message + "\nPress any key to quit");
Console.ReadKey();
return exitcode;
}
}
}