Skip to content

Commit e31b194

Browse files
authored
Adds new -e and -eval options which will immediately execute a script (#1129)
1 parent ffcd2ff commit e31b194

15 files changed

Lines changed: 541 additions & 70 deletions

src/ScriptCs/Command/CommandFactory.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ public ICommand CreateCommand(Config config, string[] scriptArgs)
7373
return explicitReplCommand;
7474
}
7575

76+
if (config.Eval != null)
77+
{
78+
var executeLooseScriptCommand = new ExecuteLooseScriptCommand(
79+
config.Eval,
80+
scriptArgs,
81+
scriptServices.FileSystem,
82+
scriptServices.Executor,
83+
scriptServices.ScriptPackResolver,
84+
scriptServices.LogProvider,
85+
scriptServices.AssemblyResolver,
86+
scriptServices.FileSystemMigrator,
87+
scriptServices.ScriptLibraryComposer);
88+
89+
return executeLooseScriptCommand;
90+
}
91+
7692
if (config.ScriptName != null)
7793
{
7894
var currentDirectory = _fileSystem.CurrentDirectory;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using ScriptCs.Contracts;
5+
6+
namespace ScriptCs.Command
7+
{
8+
internal class ExecuteLooseScriptCommand : ExecuteScriptCommandBase, IExecuteLooseScriptCommand
9+
{
10+
public ExecuteLooseScriptCommand(
11+
string script, string[] scriptArgs,
12+
IFileSystem fileSystem, IScriptExecutor scriptExecutor,
13+
IScriptPackResolver scriptPackResolver,
14+
ILogProvider logProvider,
15+
IAssemblyResolver assemblyResolver,
16+
IFileSystemMigrator fileSystemMigrator,
17+
IScriptLibraryComposer composer) :
18+
base(script, scriptArgs, fileSystem, scriptExecutor, scriptPackResolver, logProvider, assemblyResolver, fileSystemMigrator, composer)
19+
{
20+
}
21+
22+
public override CommandResult Execute()
23+
{
24+
try
25+
{
26+
_fileSystemMigrator.Migrate();
27+
28+
var assemblyPaths = Enumerable.Empty<string>();
29+
var workingDirectory = _fileSystem.CurrentDirectory;
30+
assemblyPaths = _assemblyResolver.GetAssemblyPaths(workingDirectory);
31+
_composer.Compose(workingDirectory);
32+
33+
_scriptExecutor.Initialize(assemblyPaths, _scriptPackResolver.GetPacks());
34+
35+
// HACK: This is a (dirty) fix for #1086. This might be a temporary solution until some further refactoring can be done.
36+
_scriptExecutor.ScriptEngine.CacheDirectory = Path.Combine(workingDirectory ?? _fileSystem.CurrentDirectory, _fileSystem.DllCacheFolder);
37+
var scriptResult = _scriptExecutor.ExecuteScript(_script, ScriptArgs);
38+
var commandResult = Inspect(scriptResult);
39+
_scriptExecutor.Terminate();
40+
return commandResult;
41+
}
42+
catch (Exception ex)
43+
{
44+
_logger.ErrorException("Error executing script '{0}'", ex, _script);
45+
return CommandResult.Error;
46+
}
47+
}
48+
}
49+
}

src/ScriptCs/Command/ExecuteScriptCommand.cs

Lines changed: 11 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,21 @@
55

66
namespace ScriptCs.Command
77
{
8-
internal class ExecuteScriptCommand : IScriptCommand
8+
internal class ExecuteScriptCommand : ExecuteScriptCommandBase, IScriptCommand
99
{
10-
private readonly string _script;
11-
private readonly IFileSystem _fileSystem;
12-
private readonly IScriptExecutor _scriptExecutor;
13-
private readonly IScriptPackResolver _scriptPackResolver;
14-
private readonly ILog _logger;
15-
private readonly IAssemblyResolver _assemblyResolver;
16-
private readonly IFileSystemMigrator _fileSystemMigrator;
17-
private readonly IScriptLibraryComposer _composer;
18-
1910
public ExecuteScriptCommand(
20-
string script,
21-
string[] scriptArgs,
22-
IFileSystem fileSystem,
23-
IScriptExecutor scriptExecutor,
24-
IScriptPackResolver scriptPackResolver,
25-
ILogProvider logProvider,
26-
IAssemblyResolver assemblyResolver,
27-
IFileSystemMigrator fileSystemMigrator,
28-
IScriptLibraryComposer composer
29-
)
11+
string script, string[] scriptArgs,
12+
IFileSystem fileSystem, IScriptExecutor scriptExecutor,
13+
IScriptPackResolver scriptPackResolver,
14+
ILogProvider logProvider,
15+
IAssemblyResolver assemblyResolver,
16+
IFileSystemMigrator fileSystemMigrator,
17+
IScriptLibraryComposer composer) :
18+
base(script, scriptArgs, fileSystem, scriptExecutor, scriptPackResolver, logProvider, assemblyResolver, fileSystemMigrator, composer)
3019
{
31-
Guard.AgainstNullArgument("fileSystem", fileSystem);
32-
Guard.AgainstNullArgument("scriptExecutor", scriptExecutor);
33-
Guard.AgainstNullArgument("scriptPackResolver", scriptPackResolver);
34-
Guard.AgainstNullArgument("logProvider", logProvider);
35-
Guard.AgainstNullArgument("assemblyResolver", assemblyResolver);
36-
Guard.AgainstNullArgument("fileSystemMigrator", fileSystemMigrator);
37-
Guard.AgainstNullArgument("composer", composer);
38-
39-
_script = script;
40-
ScriptArgs = scriptArgs;
41-
_fileSystem = fileSystem;
42-
_scriptExecutor = scriptExecutor;
43-
_scriptPackResolver = scriptPackResolver;
44-
_logger = logProvider.ForCurrentType();
45-
_assemblyResolver = assemblyResolver;
46-
_fileSystemMigrator = fileSystemMigrator;
47-
_composer = composer;
4820
}
4921

50-
public string[] ScriptArgs { get; private set; }
51-
52-
public CommandResult Execute()
22+
public override CommandResult Execute()
5323
{
5424
try
5525
{
@@ -69,6 +39,7 @@ public CommandResult Execute()
6939
// HACK: This is a (dirty) fix for #1086. This might be a temporary solution until some further refactoring can be done.
7040
_scriptExecutor.ScriptEngine.CacheDirectory = Path.Combine(workingDirectory ?? _fileSystem.CurrentDirectory, _fileSystem.DllCacheFolder);
7141
var scriptResult = _scriptExecutor.Execute(_script, ScriptArgs);
42+
7243
var commandResult = Inspect(scriptResult);
7344
_scriptExecutor.Terminate();
7445
return commandResult;
@@ -79,35 +50,5 @@ public CommandResult Execute()
7950
return CommandResult.Error;
8051
}
8152
}
82-
83-
private CommandResult Inspect(ScriptResult result)
84-
{
85-
if (result == null)
86-
{
87-
return CommandResult.Error;
88-
}
89-
90-
if (result.CompileExceptionInfo != null)
91-
{
92-
var ex = result.CompileExceptionInfo.SourceException;
93-
_logger.ErrorException("Script compilation failed.", ex);
94-
return CommandResult.Error;
95-
}
96-
97-
if (result.ExecuteExceptionInfo != null)
98-
{
99-
var ex = result.ExecuteExceptionInfo.SourceException;
100-
_logger.ErrorException("Script execution failed.", ex);
101-
return CommandResult.Error;
102-
}
103-
104-
if (!result.IsCompleteSubmission)
105-
{
106-
_logger.Error("The script is incomplete.");
107-
return CommandResult.Error;
108-
}
109-
110-
return CommandResult.Success;
111-
}
11253
}
11354
}

src/ScriptCs/Command/ICommand.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ public interface IExecuteReplCommand : IScriptCommand
1111
{
1212
}
1313

14+
public interface IExecuteLooseScriptCommand : ICommand
15+
{
16+
}
17+
1418
public interface ISaveCommand : ICommand
1519
{
1620
}

src/ScriptCs/Config.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public string[] Modules
5252

5353
public bool Watch { get; set; }
5454

55+
public string Eval { get; set; }
56+
5557
public static Config Create(ScriptCsArgs commandArgs)
5658
{
5759
Guard.AgainstNullArgument("commandArgs", commandArgs);
@@ -96,6 +98,7 @@ public Config Apply(ConfigMask mask)
9698
Debug = mask.Debug ?? Debug,
9799
Repl = mask.Repl ?? Repl,
98100
ScriptName = scriptName ?? ScriptName,
101+
Eval = mask.Eval ?? Eval,
99102
Watch = mask.Watch ?? Watch,
100103
};
101104
}

src/ScriptCs/ConfigMask.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public class ConfigMask
3535

3636
public string ScriptName { get; set; }
3737

38+
public string Eval { get; set; }
39+
3840
public bool? Watch { get; set; }
3941

4042
public static ConfigMask Create(ScriptCsArgs args)
@@ -56,6 +58,7 @@ public static ConfigMask Create(ScriptCsArgs args)
5658
Repl = args.Repl ? (bool?)true : null,
5759
Save = args.Save ? (bool?)true : null,
5860
ScriptName = args.ScriptName,
61+
Eval = args.Eval,
5962
Watch = args.Watch ? (bool?)true : null,
6063
};
6164
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using ScriptCs.Command;
8+
using ScriptCs.Contracts;
9+
10+
namespace ScriptCs
11+
{
12+
public abstract class ExecuteScriptCommandBase
13+
{
14+
protected readonly string _script;
15+
protected readonly IFileSystem _fileSystem;
16+
protected readonly IScriptExecutor _scriptExecutor;
17+
protected readonly IScriptPackResolver _scriptPackResolver;
18+
protected readonly ILog _logger;
19+
protected readonly IAssemblyResolver _assemblyResolver;
20+
protected readonly IFileSystemMigrator _fileSystemMigrator;
21+
protected readonly IScriptLibraryComposer _composer;
22+
23+
public ExecuteScriptCommandBase(
24+
string script,
25+
string[] scriptArgs,
26+
IFileSystem fileSystem,
27+
IScriptExecutor scriptExecutor,
28+
IScriptPackResolver scriptPackResolver,
29+
ILogProvider logProvider,
30+
IAssemblyResolver assemblyResolver,
31+
IFileSystemMigrator fileSystemMigrator,
32+
IScriptLibraryComposer composer
33+
)
34+
{
35+
Guard.AgainstNullArgument("fileSystem", fileSystem);
36+
Guard.AgainstNullArgument("scriptExecutor", scriptExecutor);
37+
Guard.AgainstNullArgument("scriptPackResolver", scriptPackResolver);
38+
Guard.AgainstNullArgument("logProvider", logProvider);
39+
Guard.AgainstNullArgument("assemblyResolver", assemblyResolver);
40+
Guard.AgainstNullArgument("fileSystemMigrator", fileSystemMigrator);
41+
Guard.AgainstNullArgument("composer", composer);
42+
43+
_script = script;
44+
ScriptArgs = scriptArgs;
45+
_fileSystem = fileSystem;
46+
_scriptExecutor = scriptExecutor;
47+
_scriptPackResolver = scriptPackResolver;
48+
_logger = logProvider.ForCurrentType();
49+
_assemblyResolver = assemblyResolver;
50+
_fileSystemMigrator = fileSystemMigrator;
51+
_composer = composer;
52+
}
53+
54+
public string[] ScriptArgs { get; private set; }
55+
56+
public abstract CommandResult Execute();
57+
58+
protected CommandResult Inspect(ScriptResult result)
59+
{
60+
if (result == null)
61+
{
62+
return CommandResult.Error;
63+
}
64+
65+
if (result.CompileExceptionInfo != null)
66+
{
67+
var ex = result.CompileExceptionInfo.SourceException;
68+
_logger.ErrorException("Script compilation failed.", ex);
69+
return CommandResult.Error;
70+
}
71+
72+
if (result.ExecuteExceptionInfo != null)
73+
{
74+
var ex = result.ExecuteExceptionInfo.SourceException;
75+
_logger.ErrorException("Script execution failed.", ex);
76+
return CommandResult.Error;
77+
}
78+
79+
if (!result.IsCompleteSubmission)
80+
{
81+
_logger.Error("The script is incomplete.");
82+
return CommandResult.Error;
83+
}
84+
85+
return CommandResult.Success;
86+
}
87+
}
88+
}

src/ScriptCs/ScriptCs.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@
8585
<Compile Include="..\ScriptCs.Core\Guard.cs">
8686
<Link>Guard.cs</Link>
8787
</Compile>
88+
<Compile Include="Command\ExecuteLooseScriptCommand.cs" />
8889
<Compile Include="ConfigMask.cs" />
8990
<Compile Include="Config.cs" />
91+
<Compile Include="ExecuteScriptCommandBase.cs" />
9092
<Compile Include="ProfileOptimizationShim.cs" />
9193
<Compile Include="Application.cs" />
9294
<Compile Include="VersionWriter.cs" />

src/ScriptCs/ScriptCsArgs.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public class ScriptCsArgs
1818
[ArgDescription("Script file name, must be specified first")]
1919
public string ScriptName { get; set; }
2020

21+
[ArgShortcut("e")]
22+
[ArgDescription("Code to immediately evaluate")]
23+
public string Eval { get; set; }
24+
2125
[ArgShortcut("?")]
2226
[ArgDescription("Displays help")]
2327
public bool Help { get; set; }

0 commit comments

Comments
 (0)