Skip to content

Commit

Permalink
Re-add generate_latest_map script
Browse files Browse the repository at this point in the history
It was removed from the build-tools repository. Add it to extra/ and fix
a couple of linter errors.
  • Loading branch information
iaguis committed Jan 9, 2017
1 parent 3522a3f commit d5b864c
Showing 1 changed file with 178 additions and 0 deletions.
178 changes: 178 additions & 0 deletions extras/generate_latest_map
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#!/usr/bin/env bash
#
# Generate concrete implementations of LatestMap.
#
# e.g.
# $ generate_latest_map ./report/out.go string NodeControlData ...
#
# Depends on:
# - gofmt

function generate_header {
local out_file="${1}"
local cmd="${2}"

cat << EOF >"${out_file}"
// Generated file, do not edit.
// To regenerate, run ${cmd}
package report
import (
"time"
"github.com/ugorji/go/codec"
)
EOF
}

function generate_latest_map {
local out_file="$1"
local data_type="$2"
local uppercase_data_type="${data_type^}"
local lowercase_data_type="${data_type,}"
local wire_entry_type="wire${uppercase_data_type}LatestEntry"
local decoder_type="${lowercase_data_type}LatestEntryDecoder"
local iface_decoder_variable="${uppercase_data_type}LatestEntryDecoder"
local latest_map_type="${uppercase_data_type}LatestMap"
local empty_latest_map_variable="Empty${latest_map_type}"
local make_function="Make${latest_map_type}"

# shellcheck disable=SC2016
local json_timestamp='`json:"timestamp"`'
# shellcheck disable=SC2016
local json_value='`json:"value"`'

cat << EOF >>"${out_file}"
type ${wire_entry_type} struct {
Timestamp time.Time ${json_timestamp}
Value ${data_type} ${json_value}
}
type ${decoder_type} struct {}
func (d *${decoder_type}) Decode(decoder *codec.Decoder, entry *LatestEntry) {
wire := ${wire_entry_type}{}
decoder.Decode(&wire)
entry.Timestamp = wire.Timestamp
entry.Value = wire.Value
}
// ${iface_decoder_variable} is an implementation of LatestEntryDecoder
// that decodes the LatestEntry instances having a ${data_type} value.
var ${iface_decoder_variable} LatestEntryDecoder = &${decoder_type}{}
// ${latest_map_type} holds latest ${data_type} instances.
type ${latest_map_type} LatestMap
// ${empty_latest_map_variable} is an empty ${latest_map_type}. Start with this.
var ${empty_latest_map_variable} = (${latest_map_type})(MakeLatestMapWithDecoder(${iface_decoder_variable}))
// ${make_function} makes an empty ${latest_map_type}.
func ${make_function}() ${latest_map_type} {
return ${empty_latest_map_variable}
}
// Copy is a noop, as ${latest_map_type}s are immutable.
func (m ${latest_map_type}) Copy() ${latest_map_type} {
return (${latest_map_type})((LatestMap)(m).Copy())
}
// Size returns the number of elements.
func (m ${latest_map_type}) Size() int {
return (LatestMap)(m).Size()
}
// Merge produces a fresh ${latest_map_type} containing the keys from both inputs.
// When both inputs contain the same key, the newer value is used.
func (m ${latest_map_type}) Merge(other ${latest_map_type}) ${latest_map_type} {
return (${latest_map_type})((LatestMap)(m).Merge((LatestMap)(other)))
}
// Lookup the value for the given key.
func (m ${latest_map_type}) Lookup(key string) (${data_type}, bool) {
v, ok := (LatestMap)(m).Lookup(key)
if !ok {
var zero ${data_type}
return zero, false
}
return v.(${data_type}), true
}
// LookupEntry returns the raw entry for the given key.
func (m ${latest_map_type}) LookupEntry(key string) (${data_type}, time.Time, bool) {
v, timestamp, ok := (LatestMap)(m).LookupEntry(key)
if !ok {
var zero ${data_type}
return zero, timestamp, false
}
return v.(${data_type}), timestamp, true
}
// Set the value for the given key.
func (m ${latest_map_type}) Set(key string, timestamp time.Time, value ${data_type}) ${latest_map_type} {
return (${latest_map_type})((LatestMap)(m).Set(key, timestamp, value))
}
// Delete the value for the given key.
func (m ${latest_map_type}) Delete(key string) ${latest_map_type} {
return (${latest_map_type})((LatestMap)(m).Delete(key))
}
// ForEach executes fn on each key value pair in the map.
func (m ${latest_map_type}) ForEach(fn func(k string, timestamp time.Time, v ${data_type})) {
(LatestMap)(m).ForEach(func(key string, ts time.Time, value interface{}) {
fn(key, ts, value.(${data_type}))
})
}
// String returns the ${latest_map_type}'s string representation.
func (m ${latest_map_type}) String() string {
return (LatestMap)(m).String()
}
// DeepEqual tests equality with other ${latest_map_type}.
func (m ${latest_map_type}) DeepEqual(n ${latest_map_type}) bool {
return (LatestMap)(m).DeepEqual((LatestMap)(n))
}
// CodecEncodeSelf implements codec.Selfer.
func (m *${latest_map_type}) CodecEncodeSelf(encoder *codec.Encoder) {
(*LatestMap)(m).CodecEncodeSelf(encoder)
}
// CodecDecodeSelf implements codec.Selfer.
func (m *${latest_map_type}) CodecDecodeSelf(decoder *codec.Decoder) {
bm := (*LatestMap)(m)
bm.decoder = ${iface_decoder_variable}
bm.CodecDecodeSelf(decoder)
}
// MarshalJSON shouldn't be used, use CodecEncodeSelf instead.
func (${latest_map_type}) MarshalJSON() ([]byte, error) {
panic("MarshalJSON shouldn't be used, use CodecEncodeSelf instead")
}
// UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead.
func (*${latest_map_type}) UnmarshalJSON(b []byte) error {
panic("UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead")
}
EOF
}

if [ -z "${1}" ]; then
echo "No output file given"
exit 1
fi

out="${1}"
outtmp="${out}.tmp"

generate_header "${outtmp}" "${0} ${*}"
shift
for t in "${@}"; do
generate_latest_map "${outtmp}" "${t}"
done

gofmt -s -w "${outtmp}"
mv "${outtmp}" "${out}"

0 comments on commit d5b864c

Please sign in to comment.