Skip to content

Commit c6ce075

Browse files
Merge pull request #221 from akkadotnet/dev
HOCON 2.0 Release
2 parents c22b2fa + cbaf428 commit c6ce075

39 files changed

+2707
-1694
lines changed

RELEASE_NOTES.md

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
#### 1.3.3 January 27 2020 ####
2-
**Bugfix release for HOCON v1.3.0**
1+
### 2.0.0 February 13 2020 ####
32

4-
Key changes include:
5-
6-
* [Make `Config` implement `ISerializable`](https://github.com/akkadotnet/HOCON/pull/207)
7-
* [Implement Akka.NET backwards compatibility fixes](https://github.com/akkadotnet/HOCON/pull/204)
8-
9-
You can [see the full set of changes in the HOCON v1.3.3 milestone](https://github.com/akkadotnet/HOCON/milestone/6).
3+
* [Add JSON serialization by implementing `ISerializable`.](https://github.com/akkadotnet/HOCON/pull/214)
4+
* [Resolve `Config` containing a single empty object as an empty `Config`.](https://github.com/akkadotnet/HOCON/pull/214)
5+
* [Refactor `Hocon.Parser` class to `Hocon.HoconParser` for clarity.](https://github.com/akkadotnet/HOCON/pull/215)
6+
* [Add `IEquitable<Config>` interface implementation to `Config` class.](https://github.com/akkadotnet/HOCON/pull/218)
7+
* [Change `GetString()`, `GetStringList()`, `GetInt()`, and `GetDouble()` throws on failure instead of returning a default value to conform to Hocon spec.](https://github.com/akkadotnet/HOCON/pull/218)
8+
* [Add `TryGet[DataType]()` functions to all getters to eliminate as much Exception throwing as possible to improve performance.](https://github.com/akkadotnet/HOCON/pull/218)
9+
* [Remove as much wrapping functions as possible to improve performance.](https://github.com/akkadotnet/HOCON/pull/218)
10+
* [Move `ConfigurationException` from `Akka.Configuration` to `Hocon`](https://github.com/akkadotnet/HOCON/pull/218)
11+
* [Fix `Config.WithFallback()` with hocon files containing substitution failed to merge the fallbacks correctly..](https://github.com/akkadotnet/HOCON/pull/218)
12+
* [Hocon is now compatible with Hyperion serializer.](https://github.com/akkadotnet/HOCON/pull/218)

build.fsx

+28-48
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,21 @@ let solutionFile = FindFirstMatchingFile "*.sln" __SOURCE_DIRECTORY__ // dynami
2323
let buildNumber = environVarOrDefault "BUILD_NUMBER" "0"
2424
let hasTeamCity = (not (buildNumber = "0")) // check if we have the TeamCity environment variable for build # set
2525
let preReleaseVersionSuffix = "beta" + (if (not (buildNumber = "0")) then (buildNumber) else DateTime.UtcNow.Ticks.ToString())
26+
let releaseNotes =
27+
File.ReadLines (__SOURCE_DIRECTORY__ @@ "RELEASE_NOTES.md")
28+
|> ReleaseNotesHelper.parseReleaseNotes
29+
30+
let versionFromReleaseNotes =
31+
match releaseNotes.SemVer.PreRelease with
32+
| Some r -> r.Origin
33+
| None -> ""
34+
2635
let versionSuffix =
2736
match (getBuildParam "nugetprerelease") with
2837
| "dev" -> preReleaseVersionSuffix
29-
| _ -> ""
30-
31-
let releaseNotes =
32-
File.ReadLines "./RELEASE_NOTES.md"
33-
|> ReleaseNotesHelper.parseReleaseNotes
38+
| "" -> versionFromReleaseNotes
39+
| str -> str
40+
3441

3542
// Directories
3643
let toolsDir = __SOURCE_DIRECTORY__ @@ "tools"
@@ -139,7 +146,7 @@ Target "SignPackages" (fun _ ->
139146
if(canSign) then
140147
log "Signing information is available."
141148

142-
let assemblies = !! (outputNuGet @@ "*.nupkg")
149+
let assemblies = !! (outputNuGet @@ "*.*upkg")
143150

144151
let signPath =
145152
let globalTool = tryFindFileOnPath "SignClient.exe"
@@ -205,48 +212,21 @@ Target "CreateNuget" (fun _ ->
205212
)
206213

207214
Target "PublishNuget" (fun _ ->
208-
let nugetExe = FullName @"./tools/nuget.exe"
209-
let rec publishPackage url accessKey trialsLeft packageFile =
210-
let tracing = enableProcessTracing
211-
enableProcessTracing <- false
212-
let args p =
213-
match p with
214-
| (pack, key, "") -> sprintf "push \"%s\" %s" pack key
215-
| (pack, key, url) -> sprintf "push \"%s\" %s -source %s" pack key url
216-
217-
tracefn "Pushing %s Attempts left: %d" (FullName packageFile) trialsLeft
218-
try
219-
let result = ExecProcess (fun info ->
220-
info.FileName <- nugetExe
221-
info.WorkingDirectory <- (Path.GetDirectoryName (FullName packageFile))
222-
info.Arguments <- args (packageFile, accessKey,url)) (System.TimeSpan.FromMinutes 1.0)
223-
enableProcessTracing <- tracing
224-
if result <> 0 then failwithf "Error during NuGet symbol push. %s %s" nugetExe (args (packageFile, "key omitted",url))
225-
with exn ->
226-
if (trialsLeft > 0) then (publishPackage url accessKey (trialsLeft-1) packageFile)
227-
else raise exn
228-
let shouldPushNugetPackages = hasBuildParam "nugetkey"
229-
let shouldPushSymbolsPackages = (hasBuildParam "symbolspublishurl") && (hasBuildParam "symbolskey")
230-
231-
if (shouldPushNugetPackages || shouldPushSymbolsPackages) then
232-
printfn "Pushing nuget packages"
233-
if shouldPushNugetPackages then
234-
let normalPackages=
235-
!! (outputNuGet @@ "*.nupkg")
236-
-- (outputNuGet @@ "*.symbols.nupkg") |> Seq.sortBy(fun x -> x.ToLower())
237-
for package in normalPackages do
238-
try
239-
publishPackage (getBuildParamOrDefault "nugetpublishurl" "") (getBuildParam "nugetkey") 3 package
240-
with exn ->
241-
printfn "%s" exn.Message
242-
243-
if shouldPushSymbolsPackages then
244-
let symbolPackages= !! (outputNuGet @@ "*.symbols.nupkg") |> Seq.sortBy(fun x -> x.ToLower())
245-
for package in symbolPackages do
246-
try
247-
publishPackage (getBuildParam "symbolspublishurl") (getBuildParam "symbolskey") 3 package
248-
with exn ->
249-
printfn "%s" exn.Message
215+
let projects = !! "./bin/nuget/*.nupkg"
216+
let apiKey = getBuildParamOrDefault "nugetkey" ""
217+
let source = getBuildParamOrDefault "nugetpublishurl" ""
218+
let symbolSource = source
219+
let shouldPublishSymbolsPackages = not (symbolSource = "")
220+
221+
if (not (source = "") && not (apiKey = "") && shouldPublishSymbolsPackages) then
222+
let runSingleProject project =
223+
DotNetCli.RunCommand
224+
(fun p ->
225+
{ p with
226+
TimeOut = TimeSpan.FromMinutes 10. })
227+
(sprintf "nuget push %s --api-key %s --source %s" project apiKey source)
228+
229+
projects |> Seq.iter (runSingleProject)
250230
)
251231

252232
//--------------------------------------------------------------------------------

src/HOCON.Tests/Extensions/IsStringTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class IsStringTests
2424
}
2525
";
2626

27-
public HoconRoot TestHocon => Parser.Parse(RawTestHocon);
27+
public HoconRoot TestHocon => HoconParser.Parse(RawTestHocon);
2828

2929
[Fact]
3030
public void IsString_should_detect_String_literals()

src/HOCON.Tests/QuotedString.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void Bugfix_190_should_unquote_quotedstrings_on_parse()
2525
}
2626
";
2727

28-
var parsed = Parser.Parse(hocon);
28+
var parsed = HoconParser.Parse(hocon);
2929
var unwrapped = parsed.GetObject("adapters").ToDictionary(x => x.Key, v => v.Value.GetString());
3030

3131
// check to make sure these strings aren't quoted

src/Hocon.Configuration.Test/ConfigurationSpec.cs

+66-7
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ public void CanMergeObjects()
9595
}
9696
";
9797

98-
var root1 = Parser.Parse(hocon1);
99-
var root2 = Parser.Parse(hocon2);
98+
var root1 = HoconParser.Parse(hocon1);
99+
var root2 = HoconParser.Parse(hocon2);
100100

101101
var obj1 = root1.Value.GetObject();
102102
var obj2 = root2.Value.GetObject();
@@ -246,7 +246,7 @@ public void Fallback_should_not_be_modified()
246246
}
247247
}");
248248

249-
var merged = config1.WithFallback(config2).Root.GetObject(); // Perform values loading
249+
var merged = config1.WithFallback(config2).Value.GetObject(); // Perform values loading
250250

251251
config1.GetInt("a.b.c").Should().Be(5);
252252
config1.GetInt("a.b.e").Should().Be(7);
@@ -456,7 +456,7 @@ public void Config_will_not_throw_on_duplicate_fallbacks()
456456

457457
// normal fallback
458458
var f1 = c1.WithFallback(c2).WithFallback(Config.Empty);
459-
c1.Fallback.Should().BeNull(); // original copy should not have been modified.
459+
c1.Fallbacks.Count.Should().Be(0); // original copy should not have been modified.
460460

461461
// someone adds the same fallback again with realizing it
462462
f1.WithFallback(Config.Empty).GetString("bar.biz").Should().Be("fuber"); // shouldn't throw
@@ -480,7 +480,7 @@ public void Quoted_key_should_be_parsed()
480480
}
481481
");
482482

483-
var megred = config2.WithFallback(config1).Root;
483+
var megred = config2.WithFallback(config1).Value;
484484
// Is throwing at "/weird/*" key parsing
485485
megred.Invoking(r => r.GetObject()).Should().NotThrow();
486486
}
@@ -501,7 +501,7 @@ public void Quoted_key_with_dot_should_be_parsed()
501501
}"
502502
);
503503

504-
var megred = config2.WithFallback(config1).Root;
504+
var megred = config2.WithFallback(config1).Value;
505505
// Is throwing at "System.Byte[]" key parsing
506506
megred.Invoking(r => r.GetObject()).Should().NotThrow();
507507
}
@@ -526,7 +526,7 @@ public void HoconValue_GetObject_should_use_fallback_values_with_complex_objects
526526
var configWithFallback = config1.WithFallback(config2);
527527

528528
var config = configWithFallback.GetConfig("akka.actor.deployment");
529-
var rootObj = config.Root.GetObject();
529+
var rootObj = config.Value.GetObject();
530530
rootObj.Unwrapped.Should().ContainKeys("/worker1", "/worker2");
531531
rootObj["/worker1.router"].Raw.Should().Be("round-robin-group1");
532532
rootObj["/worker1.router"].Raw.Should().Be("round-robin-group1");
@@ -577,6 +577,65 @@ public void ShouldSerializeFallbackValues()
577577

578578
}
579579

580+
[Fact]
581+
public void WithFallback_ShouldNotChangeOriginalConfig()
582+
{
583+
var a = ConfigurationFactory.ParseString(@" akka : {
584+
some-key : value
585+
}");
586+
var b = ConfigurationFactory.ParseString(@"akka : {
587+
other-key : 42
588+
}");
589+
590+
var oldA = a;
591+
var oldAContent = new Config(a);
592+
593+
a.WithFallback(b);
594+
a.WithFallback(b);
595+
596+
a.Fallbacks.Count.Should().Be(0);
597+
a.GetString("akka.other-key", null).Should().BeNull();
598+
ReferenceEquals(oldA, a).Should().BeTrue();
599+
oldAContent.Should().Equals(a);
600+
}
601+
602+
[Fact]
603+
public void WithFallback_ShouldMergeSubstitutionProperly()
604+
{
605+
var a = ConfigurationFactory.ParseString("{ executor : fork-join-executor }");
606+
var subbed = ConfigurationFactory.ParseString(@"
607+
mystring = substring
608+
myapp{
609+
my-fork-join-dispatcher {
610+
type = ForkJoinDispatcher
611+
dedicated-thread-pool.thread-count = 4
612+
dedicated-thread-pool.substring = ${mystring}
613+
}
614+
}
615+
akka.actor.deployment{
616+
/pool1 {
617+
router = random-pool
618+
pool-dispatcher = ${myapp.my-fork-join-dispatcher}
619+
}
620+
}");
621+
var combined = a
622+
.WithFallback(subbed.GetConfig("akka.actor.deployment./pool1.pool-dispatcher"));
623+
624+
var expectedConfig = ConfigurationFactory.ParseString(@"
625+
executor : fork-join-executor
626+
type = ForkJoinDispatcher
627+
dedicated-thread-pool.thread-count = 4
628+
dedicated-thread-pool.substring = substring
629+
");
630+
631+
var result = combined.Root.ToString(1, 2);
632+
var expected = expectedConfig.Root.ToString(1, 2);
633+
634+
expected.Should().BeEquivalentTo(result);
635+
combined.GetInt("dedicated-thread-pool.thread-count").Should().Be(4);
636+
combined.GetString("dedicated-thread-pool.substring").Should().Be("substring");
637+
}
638+
580639
/// <summary>
581640
/// Source issue: https://github.com/akkadotnet/HOCON/issues/175
582641
/// </summary>

src/Hocon.Configuration.Test/Hocon.Configuration.Tests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="FluentAssertions" Version="5.10.0" />
9+
<PackageReference Include="FluentAssertions" Version="5.10.2" />
1010
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
1111
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
1212
<PackageReference Include="xunit" Version="$(XunitVersion)" />

src/Hocon.Configuration.Test/SerializationSpecs.cs

+19-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static IEnumerable<object[]> HoconGenerator()
2626
};
2727
}
2828

29-
[Theory(Skip = "Doesn't work right now")]
29+
[Theory]
3030
[MemberData(nameof(HoconGenerator))]
3131
public void ShouldSerializeHocon(string hocon, string fallback1, string fallback2)
3232
{
@@ -42,8 +42,25 @@ public void ShouldSerializeHocon(string hocon, string fallback1, string fallback
4242
private void VerifySerialization(Config config)
4343
{
4444
var serialized = JsonConvert.SerializeObject(config);
45-
var deserialized = (Config)JsonConvert.DeserializeObject(serialized);
45+
var deserialized = JsonConvert.DeserializeObject<Config>(serialized);
4646
config.DumpConfig().Should().Be(deserialized.DumpConfig());
4747
}
48+
49+
[Fact]
50+
public void CanSerializeEmptyConfig()
51+
{
52+
var config = Config.Empty;
53+
var serialized = JsonConvert.SerializeObject(config);
54+
var deserialized = JsonConvert.DeserializeObject<Config>(serialized);
55+
deserialized.IsEmpty.Should().BeTrue();
56+
}
57+
58+
[Fact]
59+
public void ShouldResolveEmptyToEmpty()
60+
{
61+
ConfigurationFactory.Empty.IsEmpty.Should().BeTrue();
62+
ConfigurationFactory.ParseString("{}").IsEmpty.Should().BeTrue();
63+
Config.Empty.IsEmpty.Should().BeTrue();
64+
}
4865
}
4966
}

0 commit comments

Comments
 (0)