summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2022-02-06 13:15:49 +0700
committerShulhan <ms@kilabit.info>2022-02-06 13:17:37 +0700
commitbc9beab883833279580319eb7670cbbc21cd628f (patch)
tree562934aabc9c54e0b58d75b20c8ca7ee71125f96
parentf7f2230c7794c0cb110ff94d4c502661e171d85c (diff)
downloadpakakeh.go-bc9beab883833279580319eb7670cbbc21cd628f.tar.xz
lib/ini: make the Marshal on map field sorted by keys
Given the following struct, type ADT struct { Amap map[string]string `ini:"section:sub"` } and ini text, [test "map"] c = 3 b = 2 a = 1 Unmarshal-ing the text into ADT and then Marshal-ing it again will result in unpredictable keys order. This changes fix this issue by sorting the keys on ADT.Amap on Marshal-ing, to make the written output predictable.
-rw-r--r--CHANGELOG.adoc29
-rw-r--r--_doc/CHANGELOG.html186
-rw-r--r--lib/ini/ini.go10
-rw-r--r--lib/ini/ini_test.go42
4 files changed, 195 insertions, 72 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 1490194a..fba4573c 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -30,6 +30,35 @@ following file input extension:
The input file will be removed on success.
--
+=== Enhancements
+
+* lib/ini: make the Marshal on map field sorted by keys
++
+--
+Given the following struct,
+
+----
+type ADT struct {
+ Amap map[string]string `ini:"section:sub"`
+}
+----
+
+and ini text,
+
+----
+[test "map"]
+c = 3
+b = 2
+a = 1
+----
+
+Unmarshal-ing the text into ADT and then Marshal-ing it again will
+result in unpredictable keys order.
+
+This changes fix this issue by sorting the keys on ADT.Amap on
+Marshal-ing, to make the written output predictable.
+--
+
== share v0.34.0 (2022-02-05)
diff --git a/_doc/CHANGELOG.html b/_doc/CHANGELOG.html
index b5bef4d8..14ff9a02 100644
--- a/_doc/CHANGELOG.html
+++ b/_doc/CHANGELOG.html
@@ -239,13 +239,14 @@ dd {
<li><a href="#_share_v0_35_0_2022_0x_xx">share v0.35.0 (2022-0x-xx)</a>
<ul class="sectlevel2">
<li><a href="#_new_features">New features</a></li>
+<li><a href="#_enhancements">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_34_0_2022_02_05">share v0.34.0 (2022-02-05)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes">Breaking changes</a></li>
<li><a href="#_new_features_1">New features</a></li>
-<li><a href="#_enhancements">Enhancements</a></li>
+<li><a href="#_enhancements_1">Enhancements</a></li>
<li><a href="#_chores">Chores</a></li>
</ul>
</li>
@@ -254,7 +255,7 @@ dd {
<li><a href="#_new_features_2">New features</a></li>
<li><a href="#_breaking_changes_1">Breaking changes</a></li>
<li><a href="#_bug_fixes">Bug fixes</a></li>
-<li><a href="#_enhancements_1">Enhancements</a></li>
+<li><a href="#_enhancements_2">Enhancements</a></li>
<li><a href="#_chores_1">Chores</a></li>
</ul>
</li>
@@ -263,7 +264,7 @@ dd {
<li><a href="#_breaking_changes_2">Breaking changes</a></li>
<li><a href="#_new_features_3">New features</a></li>
<li><a href="#_bug_fixes_1">Bug fixes</a></li>
-<li><a href="#_enhancements_2">Enhancements</a></li>
+<li><a href="#_enhancements_3">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_31_0_2021_11_04">share v0.31.0 (2021-11-04)</a>
@@ -279,14 +280,14 @@ dd {
<li><a href="#_breaking_changes_4">Breaking changes</a></li>
<li><a href="#_new_features_5">New features</a></li>
<li><a href="#_bug_fixes_3">Bug fixes</a></li>
-<li><a href="#_enhancements_3">Enhancements</a></li>
+<li><a href="#_enhancements_4">Enhancements</a></li>
<li><a href="#_chores_3">Chores</a></li>
</ul>
</li>
<li><a href="#_share_v0_29_2_2021_09_06">share v0.29.2 (2021-09-06)</a>
<ul class="sectlevel2">
<li><a href="#_bug_fixes_4">Bug fixes</a></li>
-<li><a href="#_enhancements_4">Enhancements</a></li>
+<li><a href="#_enhancements_5">Enhancements</a></li>
<li><a href="#_chores_4">Chores</a></li>
</ul>
</li>
@@ -295,28 +296,28 @@ dd {
<ul class="sectlevel2">
<li><a href="#_new_feature">New feature</a></li>
<li><a href="#_breaking_changes_5">Breaking changes</a></li>
-<li><a href="#_enhancements_5">Enhancements</a></li>
+<li><a href="#_enhancements_6">Enhancements</a></li>
<li><a href="#_bug_fix">Bug fix</a></li>
</ul>
</li>
<li><a href="#_share_v0_28_0_2021_07_06">share v0.28.0 (2021-07-06)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes_6">Breaking changes</a></li>
-<li><a href="#_enhancements_6">Enhancements</a></li>
+<li><a href="#_enhancements_7">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_27_0_2021_06_05">share v0.27.0 (2021-06-05)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes_7">Breaking changes</a></li>
<li><a href="#_new_features_6">New features</a></li>
-<li><a href="#_enhancements_7">Enhancements</a></li>
+<li><a href="#_enhancements_8">Enhancements</a></li>
<li><a href="#_bug_fixes_5">Bug fixes</a></li>
</ul>
</li>
<li><a href="#_share_v0_26_0_2021_05_03">share v0.26.0 (2021-05-03)</a>
<ul class="sectlevel2">
<li><a href="#_new_features_7">New features</a></li>
-<li><a href="#_enhancements_8">Enhancements</a></li>
+<li><a href="#_enhancements_9">Enhancements</a></li>
<li><a href="#_chores_5">Chores</a></li>
</ul>
</li>
@@ -325,14 +326,14 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_8">Breaking changes</a></li>
<li><a href="#_new_features_8">New features</a></li>
-<li><a href="#_enhancements_9">Enhancements</a></li>
+<li><a href="#_enhancements_10">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_24_0_2021_03_06">share v0.24.0 (2021-03-06)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes_9">Breaking changes</a></li>
<li><a href="#_new_features_9">New features</a></li>
-<li><a href="#_enhancements_10">Enhancements</a></li>
+<li><a href="#_enhancements_11">Enhancements</a></li>
<li><a href="#_bug_fixes_6">Bug fixes</a></li>
</ul>
</li>
@@ -340,7 +341,7 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_10">Breaking changes</a></li>
<li><a href="#_new_features_10">New features</a></li>
-<li><a href="#_enhancements_11">Enhancements</a></li>
+<li><a href="#_enhancements_12">Enhancements</a></li>
<li><a href="#_bug_fixes_7">Bug fixes</a></li>
</ul>
</li>
@@ -348,7 +349,7 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_11">Breaking changes</a></li>
<li><a href="#_new_features_11">New features</a></li>
-<li><a href="#_enhancements_12">Enhancements</a></li>
+<li><a href="#_enhancements_13">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_21_0_2020_12_06">share v0.21.0 (2020-12-06)</a>
@@ -356,21 +357,21 @@ dd {
<li><a href="#_breaking_changes_12">Breaking changes</a></li>
<li><a href="#_new_features_12">New features</a></li>
<li><a href="#_bug_fixes_8">Bug fixes</a></li>
-<li><a href="#_enhancements_13">Enhancements</a></li>
+<li><a href="#_enhancements_14">Enhancements</a></li>
<li><a href="#_chores_6">Chores</a></li>
</ul>
</li>
<li><a href="#_share_v0_20_1_2020_11_08">share v0.20.1 (2020-11-08)</a>
<ul class="sectlevel2">
<li><a href="#_bug_fixes_9">Bug fixes</a></li>
-<li><a href="#_enhancements_14">Enhancements</a></li>
+<li><a href="#_enhancements_15">Enhancements</a></li>
<li><a href="#_chores_7">Chores</a></li>
</ul>
</li>
<li><a href="#_share_v0_20_0_2020_10_05">share v0.20.0 (2020-10-05)</a>
<ul class="sectlevel2">
<li><a href="#_new_features_13">New features</a></li>
-<li><a href="#_enhancements_15">Enhancements</a></li>
+<li><a href="#_enhancements_16">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_19_0_2020_09_08">share v0.19.0 (2020-09-08)</a>
@@ -384,14 +385,14 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_14">Breaking changes</a></li>
<li><a href="#_bug_fixes_11">Bug fixes</a></li>
-<li><a href="#_enhancements_16">Enhancements</a></li>
+<li><a href="#_enhancements_17">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_17_0_2020_07_05">share v0.17.0 (2020-07-05)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes_15">Breaking changes</a></li>
<li><a href="#_bug_fixes_12">Bug fixes</a></li>
-<li><a href="#_enhancements_17">Enhancements</a></li>
+<li><a href="#_enhancements_18">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_16_0_2020_06_05">share v0.16.0 (2020-06-05)</a>
@@ -399,14 +400,14 @@ dd {
<li><a href="#_breaking_changes_16">Breaking changes</a></li>
<li><a href="#_bug_fixes_13">Bug fixes</a></li>
<li><a href="#_new_features_15">New features</a></li>
-<li><a href="#_enhancements_18">Enhancements</a></li>
+<li><a href="#_enhancements_19">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_15_0_2020_05_04">share v0.15.0 (2020-05-04)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes_17">Breaking changes</a></li>
<li><a href="#_new_features_16">New features</a></li>
-<li><a href="#_enhancements_19">Enhancements</a></li>
+<li><a href="#_enhancements_20">Enhancements</a></li>
<li><a href="#_bug_fixes_14">Bug fixes</a></li>
</ul>
</li>
@@ -414,7 +415,7 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_18">Breaking changes</a></li>
<li><a href="#_new_features_17">New features</a></li>
-<li><a href="#_enhancements_20">Enhancements</a></li>
+<li><a href="#_enhancements_21">Enhancements</a></li>
<li><a href="#_bug_fixes_15">Bug fixes</a></li>
</ul>
</li>
@@ -422,7 +423,7 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_19">Breaking changes</a></li>
<li><a href="#_new_features_18">New features</a></li>
-<li><a href="#_enhancements_21">Enhancements</a></li>
+<li><a href="#_enhancements_22">Enhancements</a></li>
<li><a href="#_bug_fixes_16">Bug Fixes</a></li>
</ul>
</li>
@@ -430,7 +431,7 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_20">Breaking changes</a></li>
<li><a href="#_new_features_19">New features</a></li>
-<li><a href="#_enhancements_22">Enhancements</a></li>
+<li><a href="#_enhancements_23">Enhancements</a></li>
<li><a href="#_bug_fixes_17">Bug fixes</a></li>
</ul>
</li>
@@ -438,7 +439,7 @@ dd {
<ul class="sectlevel2">
<li><a href="#_breaking_changes_21">Breaking changes</a></li>
<li><a href="#_new_features_20">New features</a></li>
-<li><a href="#_enhancements_23">Enhancements</a></li>
+<li><a href="#_enhancements_24">Enhancements</a></li>
<li><a href="#_bug_fixes_18">Bug fixes</a></li>
</ul>
</li>
@@ -450,14 +451,14 @@ dd {
<li><a href="#_share_v0_10_1_2019_12_05">share v0.10.1 (2019-12-05)</a>
<ul class="sectlevel2">
<li><a href="#_bug_fixes_20">Bug Fixes</a></li>
-<li><a href="#_enhancements_24">Enhancements</a></li>
+<li><a href="#_enhancements_25">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_10_0_2019_11_05">share v0.10.0 (2019-11-05)</a>
<ul class="sectlevel2">
<li><a href="#_new_features_21">New Features</a></li>
<li><a href="#_breaking_changes_22">Breaking Changes</a></li>
-<li><a href="#_enhancements_25">Enhancements</a></li>
+<li><a href="#_enhancements_26">Enhancements</a></li>
<li><a href="#_bug_fixes_21">Bug Fixes</a></li>
</ul>
</li>
@@ -466,31 +467,31 @@ dd {
<li><a href="#_new_features_22">New Features</a></li>
<li><a href="#_breaking_changes_23">Breaking Changes</a></li>
<li><a href="#_bug_fixes_22">Bug Fixes</a></li>
-<li><a href="#_enhancements_26">Enhancements</a></li>
+<li><a href="#_enhancements_27">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_8_2_2019_09_05">share v0.8.2 (2019-09-05)</a>
<ul class="sectlevel2">
-<li><a href="#_enhancements_27">Enhancements</a></li>
+<li><a href="#_enhancements_28">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_8_1_2019_08_05">share v0.8.1 (2019-08-05)</a>
<ul class="sectlevel2">
-<li><a href="#_enhancements_28">Enhancements</a></li>
+<li><a href="#_enhancements_29">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_8_0_2019_07_09">share v0.8.0 (2019-07-09)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes_24">Breaking changes</a></li>
<li><a href="#_new_features_23">New Features</a></li>
-<li><a href="#_enhancements_29">Enhancements</a></li>
+<li><a href="#_enhancements_30">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_7_0_2019_06_14">share v0.7.0 (2019-06-14)</a>
<ul class="sectlevel2">
<li><a href="#_breaking_changes_25">Breaking Changes</a></li>
<li><a href="#_new_features_24">New Features</a></li>
-<li><a href="#_enhancements_30">Enhancements</a></li>
+<li><a href="#_enhancements_31">Enhancements</a></li>
<li><a href="#_bug_fixes_23">Bug Fixes</a></li>
</ul>
</li>
@@ -506,27 +507,27 @@ dd {
<li><a href="#_share_v0_5_0_2019_04_02">share v0.5.0 (2019-04-02)</a>
<ul class="sectlevel2">
<li><a href="#_new_features_26">New Features</a></li>
-<li><a href="#_enhancements_31">Enhancements</a></li>
+<li><a href="#_enhancements_32">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_4_0_2019_03_01">share v0.4.0 (2019-03-01)</a>
<ul class="sectlevel2">
<li><a href="#_new_features_27">New Features</a></li>
-<li><a href="#_enhancements_32">Enhancements</a></li>
+<li><a href="#_enhancements_33">Enhancements</a></li>
<li><a href="#_fixes">Fixes</a></li>
</ul>
</li>
<li><a href="#_share_v0_3_0_2019_02_01">share v0.3.0 (2019-02-01)</a>
<ul class="sectlevel2">
<li><a href="#_features_changes">Features Changes</a></li>
-<li><a href="#_enhancements_33">Enhancements</a></li>
+<li><a href="#_enhancements_34">Enhancements</a></li>
<li><a href="#_fixes_1">Fixes</a></li>
</ul>
</li>
<li><a href="#_share_v0_2_0_2019_01_02">share v0.2.0 (2019-01-02)</a>
<ul class="sectlevel2">
<li><a href="#_new_features_28">New Features</a></li>
-<li><a href="#_enhancements_34">Enhancements</a></li>
+<li><a href="#_enhancements_35">Enhancements</a></li>
</ul>
</li>
<li><a href="#_share_v0_1_0_2018_11_29">share v0.1.0 (2018-11-29)</a></li>
@@ -594,6 +595,49 @@ following file input extension:</p>
</ul>
</div>
</div>
+<div class="sect2">
+<h3 id="_enhancements">Enhancements</h3>
+<div class="ulist">
+<ul>
+<li>
+<p>lib/ini: make the Marshal on map field sorted by keys</p>
+<div class="openblock">
+<div class="content">
+<div class="paragraph">
+<p>Given the following struct,</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>type ADT struct {
+ Amap map[string]string `ini:"section:sub"`
+}</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>and ini text,</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>[test "map"]
+c = 3
+b = 2
+a = 1</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Unmarshal-ing the text into ADT and then Marshal-ing it again will
+result in unpredictable keys order.</p>
+</div>
+<div class="paragraph">
+<p>This changes fix this issue by sorting the keys on ADT.Amap on
+Marshal-ing, to make the written output predictable.</p>
+</div>
+</div>
+</div>
+</li>
+</ul>
+</div>
+</div>
</div>
</div>
<div class="sect1">
@@ -685,7 +729,7 @@ DownloadRequest.Output (a io.Writer).</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements">Enhancements</h3>
+<h3 id="_enhancements_1">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -907,7 +951,7 @@ and we need to check it to make the migration can run without an error.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_1">Enhancements</h3>
+<h3 id="_enhancements_2">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -1306,7 +1350,7 @@ zero value and return nil immediately.
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_2">Enhancements</h3>
+<h3 id="_enhancements_3">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -1874,7 +1918,7 @@ directory and return immediately.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_3">Enhancements</h3>
+<h3 id="_enhancements_4">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -2090,7 +2134,7 @@ is escaped using backslash.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_4">Enhancements</h3>
+<h3 id="_enhancements_5">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -2271,7 +2315,7 @@ implementing "sftp" subsystem using the ssh.Client connection.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_5">Enhancements</h3>
+<h3 id="_enhancements_6">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -2412,7 +2456,7 @@ duplicate Memfs, so this field is removed in favor of Options.Memfs.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_6">Enhancements</h3>
+<h3 id="_enhancements_7">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -2581,7 +2625,7 @@ trace returned by debug.Stack.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_7">Enhancements</h3>
+<h3 id="_enhancements_8">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -2676,7 +2720,7 @@ values using NewInt().</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_8">Enhancements</h3>
+<h3 id="_enhancements_9">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -2903,7 +2947,7 @@ NewClient to make it works.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_9">Enhancements</h3>
+<h3 id="_enhancements_10">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3125,7 +3169,7 @@ field = value</pre>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_10">Enhancements</h3>
+<h3 id="_enhancements_11">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3345,7 +3389,7 @@ value from fraction.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_11">Enhancements</h3>
+<h3 id="_enhancements_12">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3433,7 +3477,7 @@ secret key.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_12">Enhancements</h3>
+<h3 id="_enhancements_13">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3517,7 +3561,7 @@ method always return "b, 0" on the last line.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_13">Enhancements</h3>
+<h3 id="_enhancements_14">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3583,7 +3627,7 @@ not look like a TLS handshake".</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_14">Enhancements</h3>
+<h3 id="_enhancements_15">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3642,7 +3686,7 @@ handled and filled automatically.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_15">Enhancements</h3>
+<h3 id="_enhancements_16">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3818,7 +3862,7 @@ if the library always set the response type to None.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_16">Enhancements</h3>
+<h3 id="_enhancements_17">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -3880,7 +3924,7 @@ if the library always set the response type to None.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_17">Enhancements</h3>
+<h3 id="_enhancements_18">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4030,7 +4074,7 @@ file name that has been executed and the timestamp.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_18">Enhancements</h3>
+<h3 id="_enhancements_19">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4128,7 +4172,7 @@ to iterate each node in the tree from top to bottom.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_19">Enhancements</h3>
+<h3 id="_enhancements_20">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4220,7 +4264,7 @@ single space ' '.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_20">Enhancements</h3>
+<h3 id="_enhancements_21">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4284,7 +4328,7 @@ word.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_21">Enhancements</h3>
+<h3 id="_enhancements_22">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4359,7 +4403,7 @@ word.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_22">Enhancements</h3>
+<h3 id="_enhancements_23">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4413,7 +4457,7 @@ word.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_23">Enhancements</h3>
+<h3 id="_enhancements_24">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4511,7 +4555,7 @@ word.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_24">Enhancements</h3>
+<h3 id="_enhancements_25">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4585,7 +4629,7 @@ word.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_25">Enhancements</h3>
+<h3 id="_enhancements_26">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4728,7 +4772,7 @@ no DNS queries forwarded to parent server.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_26">Enhancements</h3>
+<h3 id="_enhancements_27">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4753,7 +4797,7 @@ to Search the content.</p>
<h2 id="_share_v0_8_2_2019_09_05">share v0.8.2 (2019-09-05)</h2>
<div class="sectionbody">
<div class="sect2">
-<h3 id="_enhancements_27">Enhancements</h3>
+<h3 id="_enhancements_28">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4803,7 +4847,7 @@ in directory.</p>
<h2 id="_share_v0_8_1_2019_08_05">share v0.8.1 (2019-08-05)</h2>
<div class="sectionbody">
<div class="sect2">
-<h3 id="_enhancements_28">Enhancements</h3>
+<h3 id="_enhancements_29">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4862,7 +4906,7 @@ package to <code>ascii</code> package.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_29">Enhancements</h3>
+<h3 id="_enhancements_30">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -4913,7 +4957,7 @@ simple API.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_30">Enhancements</h3>
+<h3 id="_enhancements_31">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -5254,7 +5298,7 @@ server and client API to make it easy and extensible. The websocket is now
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_31">Enhancements</h3>
+<h3 id="_enhancements_32">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -5319,7 +5363,7 @@ testsuite</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_32">Enhancements</h3>
+<h3 id="_enhancements_33">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -5514,7 +5558,7 @@ testsuite</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_33">Enhancements</h3>
+<h3 id="_enhancements_34">Enhancements</h3>
<div class="ulist">
<ul>
<li>
@@ -5568,7 +5612,7 @@ system and simplified routing handler.</p>
</div>
</div>
<div class="sect2">
-<h3 id="_enhancements_34">Enhancements</h3>
+<h3 id="_enhancements_35">Enhancements</h3>
<div class="paragraph">
<p>Fix warnings from linters.</p>
</div>
@@ -5606,7 +5650,7 @@ and several libraries.</p>
</div>
<div id="footer">
<div id="footer-text">
-Last updated 2022-02-06 01:37:08 +0700
+Last updated 2022-02-06 13:17:08 +0700
</div>
</div>
</div>
diff --git a/lib/ini/ini.go b/lib/ini/ini.go
index 50b700ca..fdaf4abc 100644
--- a/lib/ini/ini.go
+++ b/lib/ini/ini.go
@@ -10,6 +10,7 @@ import (
"io"
"os"
"reflect"
+ "sort"
"strings"
"time"
@@ -190,13 +191,20 @@ func (in *Ini) marshalStruct(
}
case reflect.Map:
+ amap := map[string]string{}
+ keys := make([]string, 0)
iter := fvalue.MapRange()
for iter.Next() {
mk := iter.Key()
mv := iter.Value()
key = strings.ToLower(fmt.Sprintf("%v", mk))
value = fmt.Sprintf("%v", mv)
- in.Set(sec, sub, key, value)
+ amap[key] = value
+ keys = append(keys, key)
+ }
+ sort.Strings(keys)
+ for _, key = range keys {
+ in.Set(sec, sub, key, amap[key])
}
case reflect.Ptr:
diff --git a/lib/ini/ini_test.go b/lib/ini/ini_test.go
index 16b7d4d3..45f807c6 100644
--- a/lib/ini/ini_test.go
+++ b/lib/ini/ini_test.go
@@ -654,6 +654,48 @@ xx = 4
test.Assert(t, "TestMarshal_embedded", exp, string(got))
}
+// Make sure that variables loaded into a map, will be stored in
+// alphabetically orders by keys on Marshal.
+func TestMarshal_map_stable(t *testing.T) {
+ type ADT struct {
+ Amap map[string]string `ini:"test:map"`
+ }
+
+ var (
+ logp = "TestMarshal_map_stable"
+ adt ADT
+ text []byte
+ exp []byte
+ got []byte
+ err error
+ )
+
+ text = []byte(`
+[test "map"]
+c = 3
+b = 2
+a = 1
+`)
+
+ exp = []byte(`[test "map"]
+a = 1
+b = 2
+c = 3
+`)
+
+ err = Unmarshal(text, &adt)
+ if err != nil {
+ t.Fatalf("%s: %s", logp, err)
+ }
+
+ got, err = Marshal(&adt)
+ if err != nil {
+ t.Fatalf("%s: %s", logp, err)
+ }
+
+ test.Assert(t, "Marshal map stable", string(exp), string(got))
+}
+
func TestUnmarshal_embedded(t *testing.T) {
got := &C{}
content := []byte(`[a]