Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 15 additions & 41 deletions src/ScriptCs/Argument/ArgumentParser.cs
Original file line number Diff line number Diff line change
@@ -1,64 +1,38 @@
using System;
using System.Linq;
using PowerArgs;
using ScriptCs.Contracts;

namespace ScriptCs.Argument
{
public class ArgumentParser : IArgumentParser
{
private readonly IConsole _console;

public ArgumentParser(IConsole console)
{
_console = console;
}

public ScriptCsArgs Parse(string[] args)
{
//no args initialized REPL
if (args == null || args.Length <= 0)
return new ScriptCsArgs { Repl = true };

var scriptCsArgs = new ScriptCsArgs();
const string unexpectedArgumentMessage = "unexpected named argument: ";

try
var installArgPosition = Array.FindIndex(args, x => x.ToLowerInvariant() == "-install");
string packageVersion = null;
if (installArgPosition == 0 && args.Length > 2 && !args[installArgPosition + 2].StartsWith("-"))
{
var installArgPosition = Array.FindIndex(args, x => x.ToLowerInvariant() == "-install");
string packageVersion = null;
if (installArgPosition == 0 && args.Length > 2 && !args[installArgPosition+2].StartsWith("-"))
{
packageVersion = args[installArgPosition + 2];
var argsList = args.ToList();
argsList.RemoveAt(installArgPosition + 2);
args = argsList.ToArray();
}
packageVersion = args[installArgPosition + 2];
var argsList = args.ToList();
argsList.RemoveAt(installArgPosition + 2);
args = argsList.ToArray();
}

scriptCsArgs = Args.Parse<ScriptCsArgs>(args);
var scriptCsArgs = Args.Parse<ScriptCsArgs>(args);

//if there is only 1 arg and it is a loglevel, it's also REPL
if (args.Length == 2 && args.Any(x => x.ToLowerInvariant() == "-loglevel" || x.ToLowerInvariant() == "-log"))
{
scriptCsArgs.Repl = true;
}

if (!string.IsNullOrWhiteSpace(packageVersion))
scriptCsArgs.PackageVersion = packageVersion;
}
catch(ArgException ex)
//if there is only 1 arg and it is a loglevel, it's also REPL
if (args.Length == 2 && args.Any(x => x.ToLowerInvariant() == "-loglevel" || x.ToLowerInvariant() == "-log"))
{
if(ex.Message.ToLower().StartsWith(unexpectedArgumentMessage))
{
var token = ex.Message.Substring(unexpectedArgumentMessage.Length);
_console.WriteLine(string.Format("Parameter \"{0}\" is not supported!", token));
}
else
{
_console.WriteLine(ex.Message);
}
scriptCsArgs.Repl = true;
}

if (!string.IsNullOrWhiteSpace(packageVersion))
scriptCsArgs.PackageVersion = packageVersion;

return scriptCsArgs;
}
}
Expand Down
37 changes: 22 additions & 15 deletions src/ScriptCs/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Reflection;
using PowerArgs;
using ScriptCs.Argument;
using ScriptCs.Command;
using ScriptCs.Hosting;
Expand All @@ -12,7 +13,27 @@ internal static class Program
private static int Main(string[] args)
{
SetProfile();
var arguments = ParseArguments(args);

ArgumentParseResult arguments;
var console = new ScriptConsole();
try
{
var parser = new ArgumentHandler(new ArgumentParser(), new ConfigFileParser(console), new FileSystem());
arguments = parser.Parse(args);
}
catch(Exception ex)
{
console.WriteLine(ex.Message);
var options = new ArgUsageOptions { ShowPosition = false, ShowType = false };
var usage = ArgUsage.GetUsage<ScriptCsArgs>(options: options);
console.WriteLine(usage);
return 1;
}
finally
{
console.Exit();
}

var scriptServicesBuilder = ScriptServicesBuilderFactory.Create(arguments.CommandArguments, arguments.ScriptArguments);
var factory = new CommandFactory(scriptServicesBuilder);
var command = factory.CreateCommand(arguments.CommandArguments, arguments.ScriptArguments);
Expand All @@ -31,19 +52,5 @@ private static void SetProfile()
startProfile.Invoke(null, new object[] { typeof(Program).Assembly.GetName().Name + ".profile" });
}
}

private static ArgumentParseResult ParseArguments(string[] args)
{
var console = new ScriptConsole();
try
{
var parser = new ArgumentHandler(new ArgumentParser(console), new ConfigFileParser(console), new FileSystem());
return parser.Parse(args);
}
finally
{
console.Exit();
}
}
}
}
33 changes: 33 additions & 0 deletions test/ScriptCs.Tests.Acceptance/CommandLine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace ScriptCs.Tests.Acceptance
{
using System;
using System.Reflection;
using ScriptCs.Tests.Acceptance.Support;
using Should;
using Xbehave;
using Xunit;

public class CommandLine
{
[Scenario]
public static void UnexpectedOption(ScriptDirectory directory, Exception exception)
{
var scenario = MethodBase.GetCurrentMethod().GetFullName();

"Given a script directory"
.f(() => directory = new ScriptDirectory(scenario));

"When I execute scriptcs.exe with an argument of '-unknownoption'"
.f(() => exception = Record.Exception(() => directory.Execute("-unknownoption")));

"Then the process errors"
.f(() => exception.ShouldNotBeNull());

"And an error message is shown regarding 'unknownoption'"
.f(() => exception.Message.ShouldContain("unknownoption"));

"And usage is shown"
.f(() => exception.Message.ShouldContain("Usage:"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<Link>Support\Guard.cs</Link>
</Compile>
<Compile Include="Migration.cs" />
<Compile Include="CommandLine.cs" />
<Compile Include="ScriptPacks.cs" />
<Compile Include="ScriptExecution.cs" />
<Compile Include="Support\ScriptCsExe.cs" />
Expand Down
4 changes: 2 additions & 2 deletions test/ScriptCs.Tests.Acceptance/ScriptExecution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static void HelloWorld(bool debug, ScriptDirectory directory, string outp
.WriteLine("foo.csx", @"Console.WriteLine(""Hello world!"");"));

"When I execute the script with debug set to {0}"
.f(() => output = directory.Execute("foo.csx", debug));
.f(() => output = directory.RunScript("foo.csx", debug));

"Then I see 'Hello world!'"
.f(() => output.ShouldContain("Hello world!"));
Expand All @@ -38,7 +38,7 @@ public static void ScriptThrowsAnException(bool debug, ScriptDirectory directory
.f(() => directory = new ScriptDirectory(scenario).WriteLine("foo.csx", @"throw new Exception(""BOOM!"");"));

"When I execute the script with debug set to {0}"
.f(() => ex = Record.Exception(() => directory.Execute("foo.csx", debug)));
.f(() => ex = Record.Exception(() => directory.RunScript("foo.csx", debug)));

"Then the script fails"
.f(() => ex.ShouldNotBeNull());
Expand Down
2 changes: 1 addition & 1 deletion test/ScriptCs.Tests.Acceptance/ScriptPacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static void UsingAScriptPack(ScriptDirectory directory, string output)
.f(() => directory.Install("ScriptCs.Adder.Local"));

"And execute the script"
.f(() => output = directory.Execute("foo.csx"));
.f(() => output = directory.RunScript("foo.csx"));

"Then I see 6912"
.f(() => output.ShouldContain("6912"));
Expand Down
10 changes: 10 additions & 0 deletions test/ScriptCs.Tests.Acceptance/Support/ScriptCsExe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ public static class ScriptCsExe
{
private static readonly bool isMono = Type.GetType("Mono.Runtime") != null;

public static string Execute(string arg, string logFile, string workingDirectory)
{
return Execute(new[] { arg }, Enumerable.Empty<string>(), logFile, workingDirectory);
}

public static string Execute(IEnumerable<string> args, string logFile, string workingDirectory)
{
return Execute(args, Enumerable.Empty<string>(), logFile, workingDirectory);
}

public static string Execute(
IEnumerable<string> args, IEnumerable<string> scriptArgs, string logFile, string workingDirectory)
{
Expand Down
34 changes: 21 additions & 13 deletions test/ScriptCs.Tests.Acceptance/Support/ScriptDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ public class ScriptDirectory
private readonly string _directory;
private readonly string _log;

[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "They are initialized inline. The constructor does other things.")]
[SuppressMessage(
"Microsoft.Performance",
"CA1810:InitializeReferenceTypeStaticFieldsInline",
Justification = "They are initialized inline. The constructor does other things.")]
static ScriptDirectory()
{
FileSystem.EnsureDirectoryCreated(rootDirectory);
Expand All @@ -27,33 +30,33 @@ public ScriptDirectory(string scenario)
_log = Path.Combine(_directory, string.Concat(scenario, ".log"));
}

public ScriptDirectory WriteLine(string scriptName, string code)
public ScriptDirectory WriteLine(string fileName, string text)
{
using (var writer = new StreamWriter(Path.Combine(_directory, scriptName), true))
using (var writer = new StreamWriter(Path.Combine(_directory, fileName), true))
{
writer.WriteLine(code);
writer.WriteLine(text);
writer.Flush();
}

return this;
}

public string Execute(string scriptName)
public string RunScript(string scriptName)
{
return Execute(scriptName, Enumerable.Empty<string>(), Enumerable.Empty<string>());
return RunScript(scriptName, Enumerable.Empty<string>(), Enumerable.Empty<string>());
}

public string Execute(string scriptName, IEnumerable<string> args, IEnumerable<string> scriptArgs)
public string RunScript(string scriptName, IEnumerable<string> args, IEnumerable<string> scriptArgs)
{
return Execute(scriptName, true, args, scriptArgs);
return RunScript(scriptName, true, args, scriptArgs);
}

public string Execute(string scriptName, bool debug)
public string RunScript(string scriptName, bool debug)
{
return Execute(scriptName, debug, Enumerable.Empty<string>(), Enumerable.Empty<string>());
return RunScript(scriptName, debug, Enumerable.Empty<string>(), Enumerable.Empty<string>());
}

public string Execute(string scriptName,bool debug, IEnumerable<string> args, IEnumerable<string> scriptArgs)
public string RunScript(string scriptName, bool debug, IEnumerable<string> args, IEnumerable<string> scriptArgs)
{
var debugArgs =
debug &&
Expand Down Expand Up @@ -88,12 +91,17 @@ public string Install(string package)
writer.Flush();
}

return ScriptCsExe.Execute(new[] { "-install", package, "-debug" }, new string[0], _log, _directory);
return ScriptCsExe.Execute(new[] { "-install", package, "-debug" }, _log, _directory);
}

public string Migrate()
{
return ScriptCsExe.Execute(new[] { "-migrate" }, new string[0], _log, _directory);
return ScriptCsExe.Execute("-migrate", _log, _directory);
}

public string Execute(string arg)
{
return ScriptCsExe.Execute(arg, _log, _directory);
}

public ScriptDirectory AddDirectory(string path)
Expand Down
2 changes: 1 addition & 1 deletion test/ScriptCs.Tests/ArgumentHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private static IArgumentHandler Setup(string fileContent, string fileName = Cons

var console = new ScriptConsole();

return new ArgumentHandler(new ArgumentParser(console), new ConfigFileParser(console), fs.Object);
return new ArgumentHandler(new ArgumentParser(), new ConfigFileParser(console), fs.Object);
}

[Fact]
Expand Down
29 changes: 8 additions & 21 deletions test/ScriptCs.Tests/ArgumentParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,18 @@ public void ShouldHandleCommandLineArguments()
{
string[] args = { "server.csx", "-log", "error" };

var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(args);

result.ShouldNotBeNull();
result.ScriptName.ShouldEqual("server.csx");
result.LogLevel.ShouldEqual(LogLevel.Error);
}

[Fact]
public void ShouldPrintHelpMessageForUnsupportedArgs()
{
var console = new Mock<IConsole>();
string[] args = { "-foo" };

var parser = new ArgumentParser(console.Object);
var result = parser.Parse(args);

console.Verify(x => x.WriteLine(It.Is<string>(i => i.StartsWith("Parameter \"foo\" is not supported!"))));
result.ShouldNotBeNull();
}

[Fact]
public void ShouldHandleEmptyArray()
{
var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(new string[0]);

result.ShouldNotBeNull();
Expand All @@ -52,7 +39,7 @@ public void ShouldHandleEmptyArray()
[Fact]
public void ShouldHandleNull()
{
var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(null);

result.ShouldNotBeNull();
Expand All @@ -66,7 +53,7 @@ public void ShouldSupportHelp()
{
string[] args = { "-help" };

var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(args);

result.ShouldNotBeNull();
Expand All @@ -80,7 +67,7 @@ public void ShouldGoIntoReplIfOnlyLogLevelIsSet()
{
string[] args = { "-loglevel", "debug" };

var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(args);

result.Repl.ShouldBeTrue();
Expand All @@ -92,7 +79,7 @@ public void ShouldGoIntoReplIfOnlyLogIsSet()
{
string[] args = { "-log", "debug" };

var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(args);

result.Repl.ShouldBeTrue();
Expand All @@ -104,7 +91,7 @@ public void ShouldSetVersionIfPackageVersionNumberFollowsPackageToInstallName()
{
string[] args = { "-install", "glimpse.scriptcs", "1.0.1" };

var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(args);

result.PackageVersion.ShouldEqual("1.0.1");
Expand All @@ -116,7 +103,7 @@ public void ShouldSetVersionIfPackageVersionNumberSpecifiedExplicitly()
{
string[] args = { "-install", "glimpse.scriptcs", "-packageversion", "1.0.1" };

var parser = new ArgumentParser(new ScriptConsole());
var parser = new ArgumentParser();
var result = parser.Parse(args);

result.PackageVersion.ShouldEqual("1.0.1");
Expand Down