Sync changes done directly in scope/tools

Applies tools changes from:

commit 7f46b90e27
Author: Krzesimir Nowak <krzesimir@kinvolk.io>
Date:   Thu Jul 21 11:55:08 2016 +0200

    Make LatestMap "generic"

    This commit makes the LatestMap type a sort of a base class, that
    should not be used directly. This also adds a generator for LatestMap
    "concrete" types with a specific data type in the LatestEntry.

commit 0f1cb82084
Author: Krzesimir Nowak <krzesimir@kinvolk.io>
Date:   Thu Jul 28 14:26:08 2016 +0200

    Allow testing only a subset of directories

    This can be done by calling TESTDIRS="./report ./probe" make tests

commit 97eb8d033d
Author: Krzesimir Nowak <krzesimir@kinvolk.io>
Date:   Thu Aug 4 11:44:21 2016 +0200

    Do not spell check Makefiles and JSON files

    Spell check does not handle JSON files very well. It finds misspelled
    words in hexadecimal hashes (like misspelled "dead" in "123daed456").

    Ignore Makefiles too - there is not so much free text to spell check
    and the spell check complains about words it was told by Makefile to
This commit is contained in:
Alfonso Acosta
2016-08-26 11:55:12 +00:00
parent 45dcdd584d
commit 48beb60bbe
3 changed files with 187 additions and 4 deletions

176
generate_latest_map Normal file
View File

@@ -0,0 +1,176 @@
#!/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}"
local json_timestamp='`json:"timestamp"`'
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}"

4
lint
View File

@@ -40,11 +40,11 @@ function spell_check {
filename="$1"
local lint_result=0
# we don't want to spell check tar balls or binaries
# we don't want to spell check tar balls, binaries, Makefile and json files
if file "$filename" | grep executable >/dev/null 2>&1; then
return $lint_result
fi
if [[ $filename == *".tar" || $filename == *".gz" ]]; then
if [[ $filename == *".tar" || $filename == *".gz" || $filename == *".json" || $(basename "$filename") == "Makefile" ]]; then
return $lint_result
fi

11
test
View File

@@ -47,8 +47,15 @@ fi
fail=0
# NB: Relies on paths being prefixed with './'.
TESTDIRS=( $(git ls-files -- '*_test.go' | grep -vE '^(vendor|prog|experimental)/' | xargs -n1 dirname | sort -u | sed -e 's|^|./|') )
if [ -z "$TESTDIRS" ]; then
# NB: Relies on paths being prefixed with './'.
TESTDIRS=( $(git ls-files -- '*_test.go' | grep -vE '^(vendor|prog|experimental)/' | xargs -n1 dirname | sort -u | sed -e 's|^|./|') )
else
# TESTDIRS on the right side is not really an array variable, it
# is just a string with spaces, but it is written like that to
# shut up the shellcheck tool.
TESTDIRS=( $(for d in ${TESTDIRS[*]}; do echo "$d"; done) )
fi
# If running on circle, use the scheduler to work out what tests to run on what shard
if [ -n "$CIRCLECI" ] && [ -z "$NO_SCHEDULER" ] && [ -x "$DIR/sched" ]; then