[pm] Sort the list of blobs in package_manifest.json.

Emitting the blobs in sorted order makes the contents of
package_manifest.json deterministic for a given set of
inputs. Determinism allows the build to skip steps that
depend on intermediate files unaffected by a change,
even if those files were re-generated.

Bug: 61368
Change-Id: I52dd768f586ae03eb42c8df405d2d07ad560faa3
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/436574
Testability-Review: Kevin Wells <kevinwells@google.com>
Commit-Queue: Wez . <wez@google.com>
Reviewed-by: Clayton Wilkinson <wilkinsonclay@google.com>
Reviewed-by: George Kulakowski <kulakowski@google.com>
Reviewed-by: James Tucker <raggi@google.com>
Reviewed-by: Kevin Wells <kevinwells@google.com>
diff --git a/src/sys/pkg/bin/pm/build/config.go b/src/sys/pkg/bin/pm/build/config.go
index e67131a..4312b4f 100644
--- a/src/sys/pkg/bin/pm/build/config.go
+++ b/src/sys/pkg/bin/pm/build/config.go
@@ -10,6 +10,7 @@
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"sort"
 
 	"go.fuchsia.dev/fuchsia/src/sys/pkg/bin/pm/pkg"
 )
@@ -167,7 +168,14 @@
 		return nil, err
 	}
 
-	for path, merkle := range contents {
+	contentsKeys := make([]string, 0, len(contents))
+	for k := range contents {
+		contentsKeys = append(contentsKeys, k)
+	}
+	sort.Strings(contentsKeys)
+
+	for _, path := range contentsKeys {
+		merkle := contents[path]
 		info, err := os.Stat(manifest.Paths[path])
 		if err != nil {
 			return nil, err
diff --git a/src/sys/pkg/bin/pm/build/config_test.go b/src/sys/pkg/bin/pm/build/config_test.go
index 1858f0b..a03466f 100644
--- a/src/sys/pkg/bin/pm/build/config_test.go
+++ b/src/sys/pkg/bin/pm/build/config_test.go
@@ -8,7 +8,6 @@
 	"os"
 	"path/filepath"
 	"reflect"
-	"sort"
 	"testing"
 )
 
@@ -31,9 +30,6 @@
 		actualPaths = append(actualPaths, blob.Path)
 	}
 
-	// FIXME(61368) Remove this sort once the paths are actually sorted by BlobInfo().
-	sort.Strings(actualPaths[1:])
-
 	if !reflect.DeepEqual(actualPaths, expectedPaths) {
 		t.Errorf("got %v, want %v", actualPaths, expectedPaths)
 	}