Skip to content

Commit

Permalink
refactored blazer.exe to be more useful. added help. version bumped t…
Browse files Browse the repository at this point in the history
…o main archiver version
  • Loading branch information
force-net committed Aug 15, 2016
1 parent aacf192 commit e12d5d6
Show file tree
Hide file tree
Showing 10 changed files with 525 additions and 190 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ packages
.tools
private.snk
sign.cmd
_releases

# todo: check this folders
ipch
Expand Down
5 changes: 4 additions & 1 deletion Blazer.Exe/Blazer.Exe.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CommandLineOptions.cs" />
<Compile Include="CommandLine\BlazerCommandLineOptions.cs" />
<Compile Include="CommandLine\CommandLineParser.cs" />
<Compile Include="CommandLine\CommandLineOptionAttribute.cs" />
<Compile Include="NullStream.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StatStream.cs" />
Expand Down
38 changes: 38 additions & 0 deletions Blazer.Exe/CommandLine/BlazerCommandLineOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace Force.Blazer.Exe.CommandLine
{
public class BlazerCommandLineOptions
{
[CommandLineOption('h', "help", "Display this help")]
public bool Help { get; set; }

[CommandLineOption('d', "decompress", "Decompress archive")]
public bool Decompress { get; set; }

[CommandLineOption('f', "force", "Overwrite target files without confirmation")]
public bool Force { get; set; }

[CommandLineOption("stdin", "Read data from stdin")]
public bool Stdin { get; set; }

[CommandLineOption("stdout", "Write data to stdout")]
public bool Stdout { get; set; }

[CommandLineOption('p', "password", "Archive password")]
public string Password { get; set; }

[CommandLineOption("encyptfull", "Encrypt archive fully (this key required on decompress)")]
public bool EncryptFull { get; set; }

[CommandLineOption("nofilename", "Do not (re)store file name")]
public bool NoFileName { get; set; }

[CommandLineOption("mode", "Compression mode: none, block (default), stream, streamhigh")]
public string Mode { get; set; }

[CommandLineOption("blobonly", "Compress to blob (no header and footer)")]
public bool BlobOnly { get; set; }

[CommandLineOption('t', "test", "Test archive")]
public bool Test { get; set; }
}
}
27 changes: 27 additions & 0 deletions Blazer.Exe/CommandLine/CommandLineOptionAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;

namespace Force.Blazer.Exe.CommandLine
{
[AttributeUsage(AttributeTargets.Property)]
public class CommandLineOptionAttribute : Attribute
{
public char ShortKey { get; set; }

public string LongKey { get; set; }

public string Description { get; set; }

public CommandLineOptionAttribute(char shortKey, string longKey, string description)
{
ShortKey = shortKey;
LongKey = longKey;
Description = description;
}

public CommandLineOptionAttribute(string longKey, string description)
{
LongKey = longKey;
Description = description;
}
}
}
169 changes: 169 additions & 0 deletions Blazer.Exe/CommandLine/CommandLineParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Force.Blazer.Exe.CommandLine
{
public class CommandLineParser<T> where T : new()
{
private T _options;

private List<string> _nonKeyOptions;

public CommandLineParser(string[] args)
{
ParseArgumentsInternal(args);
}

private void ParseArgumentsInternal(string[] args)
{
var t = new T();

var knownOptions =
typeof(T).GetProperties()
.Select(x => new Tuple<PropertyInfo, CommandLineOptionAttribute>(x, (CommandLineOptionAttribute)x.GetCustomAttributes(typeof(CommandLineOptionAttribute), true).FirstOrDefault()))
.Where(x => x.Item2 != null)
.ToArray();

var boolOptions =
knownOptions.Where(x => x.Item1.PropertyType == typeof(bool) || x.Item1.PropertyType == typeof(bool?)).ToArray();

Action<string> throwError = e => { throw new InvalidOperationException("Invalid commandline argument " + e); };
var dict = new Dictionary<string, string>();
var list = new List<string>();
string key = null;
foreach (var arg in args)
{
if (arg.Length > 0)
{
if (arg[0] == '-')
{
if (arg.Length == 1) throwError(arg);
if (arg[1] == '-')
{
if (arg[1] == '-' && arg.Length <= 3) throwError(arg);
if (key != null) dict[key] = string.Empty;
key = arg.Remove(0, 2);
}
else
{
key = arg.Remove(0, 1);
}

dict[key] = string.Empty;
}
else
{
if (boolOptions.Any(x => x.Item2.ShortKey.ToString(CultureInfo.InvariantCulture) == key || x.Item2.LongKey == key)) key = null;
if (key == null)
{
list.Add(arg);
}
else
{
dict[key] = arg;
key = null;
}
}
}
}

_nonKeyOptions = list;

foreach (var v in dict)
{
var option = knownOptions.FirstOrDefault(
x => x.Item2.ShortKey.ToString(CultureInfo.InvariantCulture) == v.Key || x.Item2.LongKey == v.Key);
if (option != null)
{
if (boolOptions.Contains(option))
{
option.Item1.SetValue(t, true, null);
}
else
{
var converted = new TypeConverter().ConvertTo(v.Value, option.Item1.PropertyType);
option.Item1.SetValue(t, converted, null);
}
}
}

_options = t;
}

public T Get()
{
return _options;
}

public string[] GetNonParamOptions()
{
return _nonKeyOptions.ToArray();
}

public string GetNonParamOptions(int idx)
{
if (_nonKeyOptions.Count <= idx) return null;
return _nonKeyOptions[idx];
}

public string GenerateHelp()
{
var options = typeof(T).GetProperties()
.Select(x => (CommandLineOptionAttribute)x.GetCustomAttributes(typeof(CommandLineOptionAttribute), true).FirstOrDefault())
.Where(x => x != null)
.ToArray();

var maxParamLen = 0;

foreach (var option in options)
{
var cnt = 0;
if (option.ShortKey != default(char) && option.LongKey != null) cnt = 6 + option.LongKey.Length;
else if (option.ShortKey != default(char)) cnt = 2;
else cnt = 2 + option.LongKey.Length;
maxParamLen = Math.Max(maxParamLen, cnt);
}

var b = new StringBuilder();
foreach (var option in options)
{
b.Append("\t");
string str;
if (option.ShortKey != default(char) && option.LongKey != null)
{
str = string.Format("-{0}, --{1}", option.ShortKey, option.LongKey);
}
else if (option.ShortKey != default(char))
{
str = string.Format("-{0}", option.ShortKey);
}
else
{
str = string.Format("--{0}", option.LongKey);
}

b.Append(str);
b.Append(new string(' ', maxParamLen - str.Length));
b.Append("\t");
b.Append(option.Description);
b.AppendLine();
}

return b.ToString();
}

public string GenerateHeader()
{
var title = (AssemblyTitleAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), true).First();
var copy = (AssemblyCopyrightAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), true).First();
var version = (AssemblyFileVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true).First();

return string.Format("{0} {2} {1}", title.Title, copy.Copyright, version.Version);
}
}
}
75 changes: 0 additions & 75 deletions Blazer.Exe/CommandLineOptions.cs

This file was deleted.

Loading

0 comments on commit e12d5d6

Please sign in to comment.