Skip to content

sunriax/argument

Repository files navigation

Version: 1.0 Release NuGet Build Status codecov License: GPL v3

Argument Reader

Description:

With Argument Reader command line arguments can be passed into a .net standard/core application. The standard project can handle 4 types of arguments:

  • Boolean
  • Strings (*)
  • Integers (#)
  • Doubles (##)

Own argument types can be build with own classes. They need to inherit from the MarshalerLib. Libraries are getting loaded dynamically on startup. It is not necessary to recompile the complete solution if a new marshaler is added.


Installation

To install ArgumentReader it is possible to download necessary libraries [zip | tar.gz] or install the library via nuget.

PM> Install-Package RaGae.Argument

After adding/installing the ArgumentsLib in a project it is necessary to add the required marshalers to a directory in your project or install via nuget. For installing the marshalers manually, it is possible to use the copy scripts in this repository to download the marshalers. Each file can also be downloaded directly (see Available Marshalers).

Installation with download script

Windows

C:\Users\...\Solution\Project> mkdir Marshaler

# It is necessary to move the copy.bat script in that directory

C:\Users\...\Solution\Project> mkdir Marshaler
C:\Users\...\Solution\Project> cd Marshaler
C:\Users\...\Solution\Project> copy.bat
# ...
#BooleanMarshalerLib
Download [Y/N]? y
#IntegerMarshalerLib
Download [Y/N]? y
#StringMarshalerLib
Download [Y/N]? y
#DoubleMarshalerLib
Download [Y/N]? y
#End of downloading
C:\Users\...\Solution\Project>

Linux

~/Solution/Project/: mkdir Marshaler

# It is necessary to move the copy.sh script in that directory

~/Solution/Project $: cd Marshaler
~/Solution/Project $: chmod 0700 ./copy.sh
~/Solution/Project $: ./copy.sh
# ...
#BooleanMarshalerLib
Download [Y/N]? y
#IntegerMarshalerLib
Download [Y/N]? y
#StringMarshalerLib
Download [Y/N]? y
#DoubleMarshalerLib
Download [Y/N]? y
#End of downloading
~/Solution/Project $:

Installed Marshalers

To copy the Marshalers to output folder setup the *.csproj file.

*.csproj

<Project Sdk="Microsoft.NET.Sdk">
  // ...

  <ItemGroup>
    <LibraryFiles Include="$(ProjectDir)Marshaler\*" />
  </ItemGroup>

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Copy SourceFiles="@(LibraryFiles)" DestinationFolder="$(TargetDir)Marshaler" SkipUnchangedFiles="true" />
  </Target>
  
  // ...
</Project>

Directly download Marshalers (Standard)

Configuration setup after download or manual installation

{
  "ReflectionConfig": [
    {
      "ReflectionPath": "Marshaler",
      "FileSpecifier": "*MarshalerLib.dll"
    }
  ]
}

NuGet installation

Marshaler Downloads
Boolean Marshaler NuGet
String Marshaler NuGet
Integer Marshaler NuGet
Double Marshaler NuGet
PM> Install-Package RaGae.Argument.BooleanMarshaler
PM> Install-Package RaGae.Argument.StringMarshaler
PM> Install-Package RaGae.Argument.IntegerMarshaler
PM> Install-Package RaGae.Argument.DoubleMarshaler

Configuration setup after nuget installation

{
  "ReflectionConfig": [
    {
      "Files": [
        "RaGae.ArgumentLib.BooleanMarshalerLib.dll",
        "RaGae.ArgumentLib.StringMarshalerLib.dll",
        "RaGae.ArgumentLib.IntegerMarshalerLib.dll",
        "RaGae.ArgumentLib.DoubleMarshalerLib.dll"
      ]
    }
  ]
}

An example project howto use the ArgumentReader can be found within this repository in the ReadArgument project


Structure

Initialize with schema in constructor

IEnumerable<ArgumentSchema> schema = new List<ArgumentSchema>()
{
    new ArgumentSchema()
    {
        Argument = new List<string>()
        {
            "string",
            "text",
            "data"
        },
        Marshaler = "*",
        Required = true
    }
    // ...
};

Argument argument = new Argument("ArgumentLib.json", "Arguments from command line", schema);

ArgumentLib.json

{
  "ReflectionConfig": [
    {
        "ReflectionPath": "Marshaler",
        "FileSpecifier": "*MarshalerLib.dll"
    }
  ],
  "ArgumentConfig": {
    "Delimiter": "-:/"
  }
}

Initialize with schema in *.json file

Argument argument = new Argument("ArgumentLib.json", "Arguments from command line");

ArgumentsLib.json

{
  "ReflectionConfig": [
    {
        "ReflectionPath": "Marshaler",
        "FileSpecifier": "*MarshalerLib.dll"
    }
  ],
  "ArgumentConfig": {
    "Schema": [
        {
            "Argument": [
                "string",
                "text",
                "data"
            ],
            "Marshaler": "*",
            "Required": true
    }
    ],
    "Delimiter": "-:/"
  }
}

Arguments parameter

ConfigFile

Path to *.json file where the necessary parameters can be changed.

Argument argument = new Argument("ArgumentLib.json", "...", "...");

Args[] from CLI

Arguments that are passed from the command line as array

Program.exe -StRiNg "Test string" -string2 "Test string2" -InT 1234 -number2 5678 -DoUbLe 123,456 -decimal2 456,123 -BoOl
string[] args = {
    "-StRiNg",
    "Test string"
    "-string2",
    "Test string2",
    "-InT",
    "1234",
    "-number2",
    "5678",
    "-DoUbLe",
    "123,456",
    "-decimal2",
    "456,123",
    "-BoOl"
};
Argument argument = new Argument("...", args, "...");
// or
Argument argument = new Argument("...", args);

Schema

This parameter can be null.

IEnumerable<ArgumentSchema> schema = new List<ArgumentSchema>()
{
    new ArgumentSchema()
    {
        Argument = new List<string>()
        {
            "string",
            "text",
            "data"
        },
        Marshaler = "*",
        Required = true
    }
    // ...
};

Argument argument = new Argument("...", "...", schema);

If null configuration is necessary in ArgumentsLib.json file

Argument argument = new Argument("...", "...");

*ArgumentsLib.json*

{
  "ArgumentConfig": {
      "Schema": [
        {
          "Argument": [
            "string",
            "text",
            "data"
          ],
          "Marshaler": "*",
          "Required": true
        }
      ]
  }
}

Parse Arguments


Build your own Marshaler

  1. Create a new VisualStudio .NET Standard Classlibrary (??MarshalerLib)
  2. Link a new project reference to RaGae.ArgumentLib.MarshalerLib.dll (in this repository) or install as nuget (see below)
  3. Write Marshaler (See example code below)
  4. Copy the TestMarshalerLib.dll to Marshaler directory in your executeable project
  5. Implement the ? in your schema
PM> Install-Package RaGae.Argument.Marshaler
using System;
using RaGae.ArgumentLib.MarshalerLib;

namespace RaGae.ArgumentLib.TestMarshalerLib
{
    public class TestMarshalerLib : Marshaler
    {
        // Only schemas allowed that are not used (string.Empty, *, #, ## are already used from standard marshalers)
        public override string Schema => "?";

        public override void Set(Iterator<string> currentArgument)
        {
            try
            {
                // If implementation should use an argument behind the command (e.g. -a "??"),
                // it is necessary to move the Iterator to the next position.
                Value = currentArgument.Next();
            }
            catch (ArgumentOutOfRangeException)
            {
                throw new TestMarshalerException(ErrorCode.MISSING);
            }

            // If no argument behind the command is used just add your value
            Value = "This is my personal marshaler";
        }

        public class TestMarshalerException : BaseArgumentException
        {
            public TestMarshalerException(ErrorCode errorCode) : base(errorCode) { }

            public TestMarshalerException(ErrorCode errorCode, string message) : base(errorCode, message) { }

            public override string ErrorMessage()
            {
                switch (ErrorCode)
                {
                    case ErrorCode.MISSING:
                        return $"Could not find test parameter for -{base.ErrorArgumentId}";
                    default:
                        return string.Empty;
                }
            }
        }
    }
}

References

The original Argument Marshaler was written in Java and published by Robert C. Martin in his book Clean Code. This project adapt his implementations and extends it dynamically.


R. Gächter