- datekeys.SpecVersion ("0.8.2") names the specification the module
implements. A test ties it to the spec file, its title and
spec/README.md, and TestCatalogueMatchesSpec and the vector files use
it (testkit.SpecVersion now aliases it), so the vectors regenerate
unchanged.
- datekeys.Version() is the version of the module as the go command
recorded it. That is a tag, or for a binary built in a checkout the
pseudo-version of its commit (for example
v0.0.0-20260928105528-9ac9cd952f04), or (devel) when it is unknown, as
in tests or under a replace directive to a directory. It works as the
main module and as a dependency, whatever the module path, which it
reads from the root package.
- `datekeys version` (also -version and --version) prints both and the
Go toolchain.
- README.md and README.es.md explain the three versions (format,
specification, module) and what the code on main covers.
traceability §70 and CHANGELOG follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.9
parent
9ac9cd952f
commit
5b342d32dc
@ -0,0 +1,50 @@
|
||||
package datekeys
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
// SpecVersion is the version of the DateKeys Protocol Specification that this
|
||||
// module implements: spec/DateKeys_Protocol_Specification_v0.8.2.md, tagged
|
||||
// spec-v0.8.2 in its repository. It is neither the version of the module
|
||||
// (see Version) nor the framing and schema versions inside the objects,
|
||||
// which are 1 (spec §70).
|
||||
const SpecVersion = "0.8.2"
|
||||
|
||||
// modulePath is the path of this module: the import path of its root
|
||||
// package, whatever the module is called.
|
||||
var modulePath = reflect.TypeFor[Error]().PkgPath()
|
||||
|
||||
// Version returns the version of this module in the running program, as the
|
||||
// go command recorded it: a release tag such as v0.1.0; a pseudo-version,
|
||||
// which names the commit, for a program built in a checkout of the module;
|
||||
// or "(devel)" when it is unknown, as in tests or under a replace directive
|
||||
// that points to a directory.
|
||||
func Version() string {
|
||||
info, ok := debug.ReadBuildInfo()
|
||||
if !ok {
|
||||
return "(devel)"
|
||||
}
|
||||
return versionIn(info)
|
||||
}
|
||||
|
||||
func versionIn(info *debug.BuildInfo) string {
|
||||
m := &info.Main
|
||||
if m.Path != modulePath {
|
||||
m = nil
|
||||
for _, d := range info.Deps {
|
||||
if d.Path == modulePath {
|
||||
m = d
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if m != nil && m.Replace != nil {
|
||||
m = m.Replace
|
||||
}
|
||||
if m == nil || m.Version == "" {
|
||||
return "(devel)"
|
||||
}
|
||||
return m.Version
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package datekeys
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// SpecVersion names the specification of this repository: its file, its
|
||||
// title and its record in spec/README.md.
|
||||
func TestSpecVersionNamesTheSpecification(t *testing.T) {
|
||||
spec, err := os.ReadFile("spec/DateKeys_Protocol_Specification_v" + SpecVersion + ".md")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(spec), "### Borrador normativo v"+SpecVersion+"\n") {
|
||||
t.Error("the specification is not titled v" + SpecVersion)
|
||||
}
|
||||
readme, err := os.ReadFile("spec/README.md")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(readme), "draft v"+SpecVersion+" (") {
|
||||
t.Error("spec/README.md does not record v" + SpecVersion)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModulePath(t *testing.T) {
|
||||
if modulePath != "g.activething.com/go/DateKeys" {
|
||||
t.Fatalf("module path %q", modulePath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
if Version() == "" {
|
||||
t.Fatal("empty version")
|
||||
}
|
||||
other := debug.Module{Path: "example.com/app", Version: "v1.2.3"}
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
info debug.BuildInfo
|
||||
want string
|
||||
}{
|
||||
{"the main module, tagged", debug.BuildInfo{Main: debug.Module{Path: modulePath, Version: "v0.1.0"}}, "v0.1.0"},
|
||||
{"the main module, from a checkout", debug.BuildInfo{Main: debug.Module{Path: modulePath, Version: "v0.0.0-20260928125528-9ac9cd952f04"}},
|
||||
"v0.0.0-20260928125528-9ac9cd952f04"},
|
||||
{"the main module in a test", debug.BuildInfo{Main: debug.Module{Path: modulePath}}, "(devel)"},
|
||||
{"a dependency", debug.BuildInfo{Main: other, Deps: []*debug.Module{{Path: modulePath, Version: "v0.2.0"}}}, "v0.2.0"},
|
||||
{"replaced by another version", debug.BuildInfo{Main: other, Deps: []*debug.Module{
|
||||
{Path: modulePath, Version: "v0.2.0", Replace: &debug.Module{Path: modulePath, Version: "v0.2.1"}}}}, "v0.2.1"},
|
||||
{"replaced by a directory", debug.BuildInfo{Main: other, Deps: []*debug.Module{
|
||||
{Path: modulePath, Version: "v0.2.0", Replace: &debug.Module{Path: "../datekeys-go"}}}}, "(devel)"},
|
||||
{"not in the program", debug.BuildInfo{Main: other}, "(devel)"},
|
||||
} {
|
||||
if got := versionIn(&tc.info); got != tc.want {
|
||||
t.Errorf("%s: %q, want %q", tc.name, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue