Skip to content

Commit

Permalink
Add option to sort keys on dump
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit e3b379d
Author: Robert (Jamie) Munro <rjmunro@arjam.net>
Date:   Fri May 8 16:10:54 2015 +0100

    Add some tests

commit febe465
Author: Robert (Jamie) Munro <rjmunro@arjam.net>
Date:   Fri May 8 15:35:14 2015 +0100

    Document options.sortKeys for dumper

commit 70e7e3d
Author: Robert (Jamie) Munro <rjmunro@arjam.net>
Date:   Fri May 8 15:33:20 2015 +0100

    Allow sortKeys option in dumper

    Can be `false` (no sorting), `true` (default sorting), or a function
    (passed to `array.sort(function)` to allow custom ordering

commit dee34b1
Author: Robert (Jamie) Munro <rjmunro@arjam.net>
Date:   Fri May 8 09:43:03 2015 +0100

    Sort keys so that the output is deterministic
  • Loading branch information
rjmunro authored and ixti committed May 13, 2015
1 parent ad21884 commit ce0161c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Unreleased
----------

- Allow options.sortKeys to specify that keys should be sorted when dumping, to
enable deterministic output.

3.3.0 / 2015-04-26
------------------

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ options:
block to flow style for collections. -1 means block style everwhere
- `styles` - "tag" => "style" map. Each tag may have own set of styles.
- `schema` _(default: `DEFAULT_SAFE_SCHEMA`)_ specifies a schema to use.
- `sortKeys` _(default: `false`)_ - if `true`, sort keys when dumping YAML. If a
function, use the function to sort the keys.

styles:

Expand Down
13 changes: 13 additions & 0 deletions lib/js-yaml/dumper.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ function State(options) {
this.skipInvalid = options['skipInvalid'] || false;
this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
this.styleMap = compileStyleMap(this.schema, options['styles'] || null);
this.sortKeys = options['sortKeys'] || false;

this.implicitTypes = this.schema.compiledImplicit;
this.explicitTypes = this.schema.compiledExplicit;
Expand Down Expand Up @@ -599,6 +600,18 @@ function writeBlockMapping(state, level, object, compact) {
explicitPair,
pairBuffer;

// Allow sorting keys so that the output file is deterministic
if (state.sortKeys === true) {
// Default sorting
objectKeyList.sort();
} else if (typeof state.sortKeys === 'function') {
// Custom sort function
objectKeyList.sort(state.sortKeys);
} else if (state.sortKeys) {
// Something is wrong
throw new YAMLException('sortKeys must be a boolean or a function');
}

for (index = 0, length = objectKeyList.length; index < length; index += 1) {
pairBuffer = '';

Expand Down
26 changes: 26 additions & 0 deletions test/units/sort-keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';


var assert = require('assert');
var yaml = require('../../');

var sample = { b: 1, a: 2, c: 3 };
var unsortedExpected = 'b: 1\na: 2\nc: 3\n';
var simpleExpected = 'a: 2\nb: 1\nc: 3\n';
var reverseExpected = 'c: 3\nb: 1\na: 2\n';

test('Dumper should sort preserve key insertion order', function () {
assert.deepEqual(yaml.safeDump(sample, { sortKeys: false }), unsortedExpected);
});

test('Dumper should sort keys when sortKeys is true', function () {
assert.deepEqual(yaml.safeDump(sample, { sortKeys: true }), simpleExpected);
});

test('Dumper should sort keys by sortKeys function when specified', function () {
assert.deepEqual(yaml.safeDump(sample, {
sortKeys: function (a, b) {
return a < b ? 1 : a > b ? -1 : 0;
}
}), reverseExpected);
});

0 comments on commit ce0161c

Please sign in to comment.