Skip to content

Commit e4a8338

Browse files
committed
Allow adding namespaces and refrences to script executor without having to create a script pack
Issue scriptcs#327
1 parent c4e3096 commit e4a8338

3 files changed

Lines changed: 122 additions & 13 deletions

File tree

src/ScriptCs.Core/Repl.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public override ScriptResult Execute(string script)
4747
{
4848
var assemblyName = PreProcessorUtil.GetPath(PreProcessorUtil.RString, script);
4949
var assemblyPath = FileSystem.GetFullPath(Path.Combine(Constants.BinFolder, assemblyName));
50-
References = References.Union(FileSystem.FileExists(assemblyPath) ? new[] { assemblyPath } : new[] { assemblyName });
50+
AddReference(FileSystem.FileExists(assemblyPath) ? assemblyPath : assemblyName);
5151

5252
return new ScriptResult();
5353
}
@@ -87,10 +87,7 @@ public override ScriptResult Execute(string script)
8787
}
8888
catch (FileNotFoundException fileEx)
8989
{
90-
if (References != null && References.Any(i => i == fileEx.FileName))
91-
{
92-
References = References.Except(new[] {fileEx.FileName});
93-
}
90+
RemoveReference(fileEx.FileName);
9491
Console.ForegroundColor = ConsoleColor.Red;
9592
Console.WriteLine("\r\n" + fileEx + "\r\n");
9693
return new ScriptResult { CompileException = fileEx };

src/ScriptCs.Core/ScriptExecutor.cs

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
24
using System.IO;
35
using System.Linq;
46
using Common.Logging;
@@ -15,20 +17,90 @@ public class ScriptExecutor : IScriptExecutor
1517
public IFilePreProcessor FilePreProcessor { get; private set; }
1618
public IScriptEngine ScriptEngine { get; private set; }
1719
public ILog Logger { get; private set; }
18-
public IEnumerable<string> References { get; protected set; }
20+
public Collection<string> References { get; private set; }
21+
public Collection<string> Namespaces { get; private set; }
1922
public ScriptPackSession ScriptPackSession { get; protected set; }
2023

2124
public ScriptExecutor(IFileSystem fileSystem, IFilePreProcessor filePreProcessor, IScriptEngine scriptEngine, ILog logger)
2225
{
26+
References = new Collection<string>();
27+
AddReferences(DefaultReferences);
28+
Namespaces = new Collection<string>();
29+
AddNamespaces(DefaultNamespaces);
2330
FileSystem = fileSystem;
2431
FilePreProcessor = filePreProcessor;
2532
ScriptEngine = scriptEngine;
2633
Logger = logger;
2734
}
2835

36+
public void AddNamespaces(IEnumerable<string> namespaces)
37+
{
38+
Guard.AgainstNullArgument("namespaces", namespaces);
39+
40+
foreach(var @namespace in namespaces)
41+
{
42+
AddNamespace(@namespace);
43+
}
44+
}
45+
46+
public void AddNamespace(string @namespace)
47+
{
48+
Guard.AgainstNullArgument("namespace", @namespace);
49+
50+
Namespaces.Add(@namespace);
51+
}
52+
53+
public void AddNamespaceByType(Type typeFromReferencedAssembly)
54+
{
55+
Guard.AgainstNullArgument("typeFromReferencedAssembly", typeFromReferencedAssembly);
56+
57+
AddNamespace(typeFromReferencedAssembly.Namespace);
58+
}
59+
60+
public void AddNamespaceByType<T>()
61+
{
62+
AddNamespaceByType(typeof(T));
63+
}
64+
65+
public void AddReferences(IEnumerable<string> paths)
66+
{
67+
Guard.AgainstNullArgument("paths", paths);
68+
69+
foreach(var path in paths)
70+
{
71+
AddReference(path);
72+
}
73+
}
74+
75+
public void AddReferenceByType(Type typeFromReferencedAssembly)
76+
{
77+
Guard.AgainstNullArgument("typeFromReferencedAssembly", typeFromReferencedAssembly);
78+
79+
AddReference(typeFromReferencedAssembly.Assembly.Location);
80+
}
81+
82+
public void AddReferenceByType<T>()
83+
{
84+
AddReferenceByType(typeof(T));
85+
}
86+
87+
public void AddReference(string path)
88+
{
89+
Guard.AgainstNullArgument("path", path);
90+
91+
References.Add(path);
92+
}
93+
94+
public void RemoveReference(string path)
95+
{
96+
Guard.AgainstNullArgument("path", path);
97+
98+
References.Remove(path);
99+
}
100+
29101
public virtual void Initialize(IEnumerable<string> paths, IEnumerable<IScriptPack> scriptPacks)
30102
{
31-
References = DefaultReferences.Union(paths);
103+
AddReferences(paths);
32104
var bin = Path.Combine(FileSystem.CurrentDirectory, "bin");
33105

34106
ScriptEngine.BaseDirectory = bin;
@@ -56,9 +128,10 @@ public virtual ScriptResult Execute(string script, string[] scriptArgs)
56128
var path = Path.IsPathRooted(script) ? script : Path.Combine(FileSystem.CurrentDirectory, script);
57129
var result = FilePreProcessor.ProcessFile(path);
58130
var references = References.Union(result.References);
131+
var namespaces = Namespaces.Union(result.UsingStatements);
59132

60133
Logger.Debug("Starting execution in engine");
61-
return ScriptEngine.Execute(result.Code, scriptArgs, references, DefaultNamespaces, ScriptPackSession);
134+
return ScriptEngine.Execute(result.Code, scriptArgs, references, namespaces, ScriptPackSession);
62135
}
63136
}
64137
}

test/ScriptCs.Core.Tests/ScriptExecutorTests.cs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,53 @@ public void ShouldAddReferenceToEachDestinationFile()
219219

220220
var destPaths = new string[] { "System", "System.Core", destinationFilePath1, destinationFilePath2, destinationFilePath3, destinationFilePath4 };
221221

222-
scriptEngine.Setup(e => e.Execute(It.IsAny<string>(), It.IsAny<string[]>(), It.Is<IEnumerable<string>>(x => x.SequenceEqual(defaultReferences.Union(destPaths))), It.IsAny<IEnumerable<string>>(), It.IsAny<ScriptPackSession>()));
222+
scriptEngine.Setup(e => e.Execute(It.IsAny<string>(), It.IsAny<string[]>(), It.IsAny<IEnumerable<string>>(), It.IsAny<IEnumerable<string>>(), It.IsAny<ScriptPackSession>()));
223223

224+
scriptExecutor.AddReference("a");
225+
scriptExecutor.AddReferences(new[]{"b", "c", "d"});
226+
scriptExecutor.AddReferenceByType<FactAttribute>();
227+
scriptExecutor.AddReferenceByType(typeof(TheInitializeMethod));
228+
var explicitReferences = new[] { "a", "b", "c", "d", typeof(FactAttribute).Assembly.Location, typeof(TheInitializeMethod).Assembly.Location };
224229
// act
225-
scriptExecutor.Initialize(paths, Enumerable.Empty<IScriptPack>());
230+
scriptExecutor.Initialize(destPaths, Enumerable.Empty<IScriptPack>());
226231
scriptExecutor.Execute(scriptName);
227232

228233
// assert
229-
scriptEngine.Verify(e => e.Execute(It.IsAny<string>(), It.IsAny<string[]>(), It.Is<IEnumerable<string>>(x => x.SequenceEqual(defaultReferences.Union(destPaths))), It.IsAny<IEnumerable<string>>(), It.IsAny<ScriptPackSession>()), Times.Once());
234+
scriptEngine.Verify(e => e.Execute(It.IsAny<string>(), It.IsAny<string[]>(), It.Is<IEnumerable<string>>(x => x.SequenceEqual(defaultReferences.Union(explicitReferences.Union(destPaths)))), It.IsAny<IEnumerable<string>>(), It.IsAny<ScriptPackSession>()), Times.Once());
235+
}
236+
237+
[Fact]
238+
public void ShouldAddNamespaces()
239+
{
240+
// arrange
241+
var defaultReferences = ScriptExecutor.DefaultReferences;
242+
var fileSystem = new Mock<IFileSystem>();
243+
var scriptEngine = new Mock<IScriptEngine>();
244+
var preProcessor = new Mock<IFilePreProcessor>();
245+
preProcessor.Setup(x => x.ProcessFile(It.IsAny<string>())).Returns(new FilePreProcessorResult());
246+
247+
var scriptExecutor = CreateScriptExecutor(fileSystem, preProcessor, scriptEngine);
248+
249+
var currentDirectory = @"C:\";
250+
251+
var scriptName = "script.csx";
252+
253+
fileSystem.Setup(fs => fs.CurrentDirectory).Returns(currentDirectory);
254+
fileSystem.Setup(fs => fs.GetWorkingDirectory(It.IsAny<string>())).Returns(currentDirectory);
255+
256+
scriptEngine.Setup(e => e.Execute(It.IsAny<string>(), It.IsAny<string[]>(), It.IsAny<IEnumerable<string>>(), It.IsAny<IEnumerable<string>>(), It.IsAny<ScriptPackSession>()));
257+
258+
scriptExecutor.AddNamespace("a");
259+
scriptExecutor.AddNamespaces(new[] { "b", "c", "d" });
260+
scriptExecutor.AddNamespaceByType<FactAttribute>();
261+
scriptExecutor.AddNamespaceByType(typeof(TheInitializeMethod));
262+
var explicitNamespaces = new[] { "a", "b", "c", "d", typeof(FactAttribute).Namespace, typeof(TheInitializeMethod).Namespace };
263+
// act
264+
scriptExecutor.Initialize(new string[0], Enumerable.Empty<IScriptPack>());
265+
scriptExecutor.Execute(scriptName);
266+
267+
// assert
268+
scriptEngine.Verify(e => e.Execute(It.IsAny<string>(), It.IsAny<string[]>(), It.IsAny<IEnumerable<string>>(), It.Is<IEnumerable<string>>(x=>x.SequenceEqual(ScriptExecutor.DefaultNamespaces.Union(explicitNamespaces))), It.IsAny<ScriptPackSession>()), Times.Once());
230269
}
231270

232271
[Fact]
@@ -274,4 +313,4 @@ public void ExecutorShouldPassDefaultReferencesToEngine()
274313
}
275314
}
276315
}
277-
}
316+
}

0 commit comments

Comments
 (0)