Skip to content

Commit 92d6ead

Browse files
committed
re-wrote Config and ConfigMask, fixing the handling of log level, REPL and file extension
1 parent 09ccc38 commit 92d6ead

6 files changed

Lines changed: 134 additions & 52 deletions

File tree

src/ScriptCs/Config.cs

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
using System;
2-
using System.IO;
3-
using Newtonsoft.Json;
4-
using Newtonsoft.Json.Converters;
52
using ScriptCs.Contracts;
3+
using System.IO;
64

75
namespace ScriptCs
86
{
9-
// NOTE (Adam): passed across app domains as a property of CrossAppDomainExecuteScriptCommand
7+
// NOTE (Adam): passed across app domains as a property of CrossAppDomainExecuteScriptCommand
108
[Serializable]
119
public class Config
1210
{
@@ -15,34 +13,38 @@ public Config()
1513
LogLevel = LogLevel.Info;
1614
}
1715

18-
public bool Repl { get; set; }
16+
// global
17+
public LogLevel LogLevel { get; set; }
1918

20-
public string ScriptName { get; set; }
19+
public string Modules { get; set; }
2120

22-
public bool Debug { get; set; }
21+
public string Output { get; set; }
2322

24-
public bool Cache { get; set; }
23+
// clean command
24+
public bool Clean { get; set; }
2525

26-
[JsonConverter(typeof(StringEnumConverter))]
27-
public LogLevel LogLevel { get; set; }
26+
// install command
27+
public bool AllowPreRelease { get; set; }
28+
29+
public bool Global { get; set; }
2830

2931
public string Install { get; set; }
3032

31-
public bool Global { get; set; }
33+
public string PackageVersion { get; set; }
3234

35+
// save command
3336
public bool Save { get; set; }
3437

35-
public bool Clean { get; set; }
36-
37-
public bool AllowPreRelease { get; set; }
38+
// run command
39+
public string ScriptName { get; set; }
3840

39-
public bool Watch { get; set; }
41+
public bool Cache { get; set; }
4042

41-
public string Modules { get; set; }
43+
public bool Debug { get; set; }
4244

43-
public string PackageVersion { get; set; }
45+
public bool Repl { get; set; }
4446

45-
public string Output { get; set; }
47+
public bool Watch { get; set; }
4648

4749
public Config Apply(ConfigMask mask)
4850
{
@@ -51,27 +53,29 @@ public Config Apply(ConfigMask mask)
5153
return this;
5254
}
5355

54-
var scriptName = mask.ScriptName ?? ScriptName;
55-
if (scriptName != null && !Path.HasExtension(scriptName))
56-
{
57-
scriptName += ".csx";
58-
}
56+
var logLevel = mask.Debug.GetValueOrDefault() && !mask.LogLevel.HasValue && LogLevel != LogLevel.Trace
57+
? LogLevel.Debug
58+
: mask.LogLevel;
59+
60+
var scriptName = mask.ScriptName != null && !Path.GetFileName(mask.ScriptName).Contains(".")
61+
? Path.ChangeExtension(mask.ScriptName, "csx")
62+
: mask.ScriptName;
5963

6064
return new Config
6165
{
62-
AllowPreRelease = mask.AllowPreRelease ?? AllowPreRelease,
63-
Cache = mask.Cache ?? Cache,
66+
LogLevel = logLevel ?? LogLevel,
67+
Modules = mask.Modules ?? Modules,
68+
Output = mask.Output ?? Output,
6469
Clean = mask.Clean ?? Clean,
65-
Debug = mask.Debug ?? Debug,
70+
AllowPreRelease = mask.AllowPreRelease ?? AllowPreRelease,
6671
Global = mask.Global ?? Global,
6772
Install = mask.Install ?? Install,
68-
LogLevel = mask.Debug.HasValue && mask.Debug.Value ? LogLevel.Debug : mask.LogLevel ?? LogLevel,
69-
Modules = mask.Modules ?? Modules,
70-
Output = mask.Output ?? Output,
7173
PackageVersion = mask.PackageVersion ?? PackageVersion,
72-
Repl = mask.Repl ?? Repl,
7374
Save = mask.Save ?? Save,
74-
ScriptName = scriptName,
75+
Cache = mask.Cache ?? Cache,
76+
Debug = mask.Debug ?? Debug,
77+
Repl = mask.Repl ?? Repl,
78+
ScriptName = scriptName ?? ScriptName,
7579
Watch = mask.Watch ?? Watch,
7680
};
7781
}

src/ScriptCs/ConfigMask.cs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,33 @@ namespace ScriptCs
88
{
99
public class ConfigMask
1010
{
11-
private ConfigMask()
12-
{
13-
}
11+
public bool? AllowPreRelease { get; set; }
1412

15-
public bool? Repl { get; set; }
13+
public bool? Cache { get; set; }
1614

17-
public string ScriptName { get; set; }
15+
public bool? Clean { get; set; }
1816

1917
public bool? Debug { get; set; }
2018

21-
public bool? Cache { get; set; }
22-
23-
public LogLevel? LogLevel { get; set; }
19+
public bool? Global { get; set; }
2420

2521
public string Install { get; set; }
2622

27-
public bool? Global { get; set; }
23+
public LogLevel? LogLevel { get; set; }
2824

29-
public bool? Save { get; set; }
25+
public string Modules { get; set; }
3026

31-
public bool? Clean { get; set; }
27+
public string Output { get; set; }
3228

33-
public bool? AllowPreRelease { get; set; }
29+
public string PackageVersion { get; set; }
3430

35-
public bool? Watch { get; set; }
31+
public bool? Repl { get; set; }
3632

37-
public string Modules { get; set; }
33+
public bool? Save { get; set; }
3834

39-
public string PackageVersion { get; set; }
35+
public string ScriptName { get; set; }
4036

41-
public string Output { get; set; }
37+
public bool? Watch { get; set; }
4238

4339
public static ConfigMask Create(ScriptCsArgs args)
4440
{
@@ -63,11 +59,32 @@ public static ConfigMask Create(ScriptCsArgs args)
6359
};
6460
}
6561

66-
public static ConfigMask ReadOrDefault(string path)
62+
public static ConfigMask ReadGlobalOrDefault()
63+
{
64+
return Read(new FileSystem().GlobalOptsFile, true);
65+
}
66+
67+
public static ConfigMask ReadLocalOrDefault()
6768
{
69+
return Read(Constants.ConfigFilename, true);
70+
}
71+
72+
public static ConfigMask Read(string path)
73+
{
74+
return Read(path, false);
75+
}
76+
77+
private static ConfigMask Read(string path, bool defaultIfNotExists)
78+
{
79+
if (defaultIfNotExists && !File.Exists(path))
80+
{
81+
return null;
82+
}
83+
84+
var json = File.ReadAllText(path);
6885
try
6986
{
70-
return File.Exists(path) ? JsonConvert.DeserializeObject<ConfigMask>(File.ReadAllText(path)) : null;
87+
return JsonConvert.DeserializeObject<ConfigMask>(json);
7188
}
7289
catch (Exception ex)
7390
{

src/ScriptCs/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ private static int Main(string[] args)
4747
}
4848

4949
var config = new Config()
50-
.Apply(ConfigMask.ReadOrDefault(new FileSystem().GlobalOptsFile))
51-
.Apply(ConfigMask.ReadOrDefault(commandArgs.Config ?? Constants.ConfigFilename))
50+
.Apply(ConfigMask.ReadGlobalOrDefault())
51+
.Apply(commandArgs.Config == null ? ConfigMask.ReadLocalOrDefault() : ConfigMask.Read(commandArgs.Config))
5252
.Apply(ConfigMask.Create(commandArgs));
5353

5454
var scriptServicesBuilder = ScriptServicesBuilderFactory.Create(config, scriptArgs);

src/ScriptCs/ScriptServicesBuilderFactory.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,20 @@ public static IScriptServicesBuilder Create(Config config, string[] scriptArgs)
2626
var initializationServices = new InitializationServices(logger);
2727
initializationServices.GetAppDomainAssemblyResolver().Initialize();
2828

29+
// NOTE (adamralph): this is a hideous assumption about what happens inside the CommandFactory.
30+
// It is a result of the ScriptServicesBuilderFactory also having to know what is going to happen inside the
31+
// Command Factory so that it builds the builder(:-p) correctly in advance.
32+
// This demonstrates the technical debt that exists with the ScriptServicesBuilderFactory and CommandFactory
33+
// in their current form. We have a separate refactoring task raised to address this.
34+
var repl = config.Repl ||
35+
(!config.Clean && config.Install == null && !config.Save && config.ScriptName == null);
36+
2937
var scriptServicesBuilder = new ScriptServicesBuilder(console, logger, null, null, initializationServices)
3038
.Cache(config.Cache)
3139
.Debug(config.Debug)
3240
.LogLevel(config.LogLevel)
3341
.ScriptName(config.ScriptName)
34-
.Repl(config.Repl);
42+
.Repl(repl);
3543

3644
var modules = config.Modules == null
3745
? new string[0]

test/ScriptCs.Tests/ConfigTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using ScriptCs.Contracts;
2+
using Should;
3+
using Xunit.Extensions;
4+
5+
namespace ScriptCs.Tests
6+
{
7+
public class ConfigTests
8+
{
9+
public class TheApplyMethod
10+
{
11+
[Theory]
12+
[InlineData(true, null, LogLevel.Error, LogLevel.Debug)]
13+
[InlineData(false, null, LogLevel.Error, LogLevel.Error)]
14+
[InlineData(true, LogLevel.Error, LogLevel.Trace, LogLevel.Error)]
15+
[InlineData(true, null, LogLevel.Trace, LogLevel.Trace)]
16+
public void CalculatesTheLogLevel(
17+
bool debug, LogLevel? logLevel, LogLevel currentLogLevel, LogLevel expectedLogLevel)
18+
{
19+
// arrange
20+
var mask = new ConfigMask { Debug = debug, LogLevel = logLevel };
21+
var config = new Config { LogLevel = currentLogLevel };
22+
23+
// act
24+
config = config.Apply(mask);
25+
26+
// assert
27+
config.LogLevel.ShouldEqual(expectedLogLevel);
28+
}
29+
30+
[Theory]
31+
[InlineData(null, null)]
32+
[InlineData(".csx", ".csx")]
33+
[InlineData(".fsx", ".fsx")]
34+
[InlineData("a", "a.csx")] // :eyes: here it is!
35+
[InlineData("a.", "a.")]
36+
[InlineData("a.csx", "a.csx")]
37+
[InlineData("a.fsx", "a.fsx")]
38+
public void AddsTheDefaultExtension(string scriptName, string expectedScriptName)
39+
{
40+
// arrange
41+
var mask = new ConfigMask { ScriptName = scriptName };
42+
var config = new Config();
43+
44+
// act
45+
config = config.Apply(mask);
46+
47+
// assert
48+
config.ScriptName.ShouldEqual(expectedScriptName);
49+
}
50+
}
51+
}
52+
}

test/ScriptCs.Tests/ScriptCs.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<Compile Include="..\TestLogger.cs">
5050
<Link>TestLogger.cs</Link>
5151
</Compile>
52+
<Compile Include="ConfigTests.cs" />
5253
<Compile Include="ScriptCsArgsTests.cs" />
5354
<Compile Include="CleanCommandTests.cs" />
5455
<Compile Include="CommandFactoryTests.cs" />

0 commit comments

Comments
 (0)